pizza: change internal rendering pipeline to 32 bit colors
This commit is contained in:
parent
04d4880564
commit
a4c6d04a18
|
@ -37,24 +37,24 @@ typedef struct gpu_oam_s
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
uint8_t pattern;
|
uint8_t pattern;
|
||||||
|
|
||||||
uint8_t palette_cgb:3;
|
uint8_t palette_cgb : 3;
|
||||||
uint8_t vram_bank:1;
|
uint8_t vram_bank : 1;
|
||||||
uint8_t palette:1;
|
uint8_t palette : 1;
|
||||||
uint8_t x_flip:1;
|
uint8_t x_flip : 1;
|
||||||
uint8_t y_flip:1;
|
uint8_t y_flip : 1;
|
||||||
uint8_t priority:1;
|
uint8_t priority : 1;
|
||||||
|
|
||||||
} gpu_oam_t;
|
} gpu_oam_t;
|
||||||
|
|
||||||
/* Gameboy Color additional tile attributes */
|
/* Gameboy Color additional tile attributes */
|
||||||
typedef struct gpu_cgb_bg_tile_s
|
typedef struct gpu_cgb_bg_tile_s
|
||||||
{
|
{
|
||||||
uint8_t palette:3;
|
uint8_t palette : 3;
|
||||||
uint8_t vram_bank:1;
|
uint8_t vram_bank : 1;
|
||||||
uint8_t spare:1;
|
uint8_t spare : 1;
|
||||||
uint8_t x_flip:1;
|
uint8_t x_flip : 1;
|
||||||
uint8_t y_flip:1;
|
uint8_t y_flip : 1;
|
||||||
uint8_t priority:1;
|
uint8_t priority : 1;
|
||||||
|
|
||||||
} gpu_cgb_bg_tile_t;
|
} gpu_cgb_bg_tile_t;
|
||||||
|
|
||||||
|
@ -76,7 +76,8 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
uint8_t frame_y, uint8_t line);
|
uint8_t frame_y, uint8_t line);
|
||||||
|
|
||||||
/* 2 bit to 8 bit color lookup */
|
/* 2 bit to 8 bit color lookup */
|
||||||
static uint16_t gpu_color_lookup[] = { 0xFFFF, 0xAD55, 0x52AA, 0x0000 };
|
// TODO: hook these up to the same color logic that that the other GB core uses
|
||||||
|
static const uint32_t gpu_color_lookup[] = {0xffffffff, 0xffaaaaaa, 0xff555555, 0xff000000};
|
||||||
|
|
||||||
/* function to call when frame is ready */
|
/* function to call when frame is ready */
|
||||||
gpu_frame_ready_cb_t gpu_frame_ready_cb;
|
gpu_frame_ready_cb_t gpu_frame_ready_cb;
|
||||||
|
@ -84,15 +85,14 @@ gpu_frame_ready_cb_t gpu_frame_ready_cb;
|
||||||
/* global state of GPU */
|
/* global state of GPU */
|
||||||
gpu_t gpu;
|
gpu_t gpu;
|
||||||
|
|
||||||
|
|
||||||
void gpu_dump_oam()
|
void gpu_dump_oam()
|
||||||
{
|
{
|
||||||
/* make it point to the first OAM object */
|
/* make it point to the first OAM object */
|
||||||
gpu_oam_t *oam = (gpu_oam_t *) mmu_addr(0xFE00);
|
gpu_oam_t *oam = (gpu_oam_t *)mmu_addr(0xFE00);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<40; i++)
|
for (i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
if (oam[i].x != 0 && oam[i].y != 0)
|
if (oam[i].x != 0 && oam[i].y != 0)
|
||||||
printf("OAM X %d Y %d VRAM %d PATTERN %d\n", oam[i].x, oam[i].y,
|
printf("OAM X %d Y %d VRAM %d PATTERN %d\n", oam[i].x, oam[i].y,
|
||||||
|
@ -101,7 +101,6 @@ void gpu_dump_oam()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* init pointers */
|
/* init pointers */
|
||||||
void gpu_init_pointers()
|
void gpu_init_pointers()
|
||||||
{
|
{
|
||||||
|
@ -123,7 +122,6 @@ void gpu_reset()
|
||||||
/* init counters */
|
/* init counters */
|
||||||
gpu.next = 456 << global_cpu_double_speed;
|
gpu.next = 456 << global_cpu_double_speed;
|
||||||
gpu.frame_counter = 0;
|
gpu.frame_counter = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init GPU states */
|
/* init GPU states */
|
||||||
|
@ -143,9 +141,9 @@ void gpu_init(gpu_frame_ready_cb_t cb)
|
||||||
gpu.step = 4;
|
gpu.step = 4;
|
||||||
|
|
||||||
/* init palette */
|
/* init palette */
|
||||||
memcpy(gpu.bg_palette, gpu_color_lookup, sizeof(uint16_t) * 4);
|
memcpy(gpu.bg_palette, gpu_color_lookup, sizeof(uint32_t) * 4);
|
||||||
memcpy(gpu.obj_palette_0, gpu_color_lookup, sizeof(uint16_t) * 4);
|
memcpy(gpu.obj_palette_0, gpu_color_lookup, sizeof(uint32_t) * 4);
|
||||||
memcpy(gpu.obj_palette_1, gpu_color_lookup, sizeof(uint16_t) * 4);
|
memcpy(gpu.obj_palette_1, gpu_color_lookup, sizeof(uint32_t) * 4);
|
||||||
|
|
||||||
/* set callback */
|
/* set callback */
|
||||||
gpu_frame_ready_cb = cb;
|
gpu_frame_ready_cb = cb;
|
||||||
|
@ -185,48 +183,9 @@ void gpu_draw_frame()
|
||||||
(gpu.frame_counter & 0x0003) != 0))
|
(gpu.frame_counter & 0x0003) != 0))
|
||||||
return;*/
|
return;*/
|
||||||
|
|
||||||
uint_fast32_t i,r,g,b,r2,g2,b2,res;
|
|
||||||
|
|
||||||
/* simulate shitty gameboy response time of LCD */
|
|
||||||
/* by calculating an average between current and previous frame */
|
|
||||||
//for (i=0; i<(144*160); i++)
|
|
||||||
for (i=0; i<(144 * 160); i++)
|
|
||||||
{
|
|
||||||
/* r = gpu.frame_buffer[i] & 0x1F;
|
|
||||||
g = gpu.frame_buffer[i] >> 5 & 0x3F;
|
|
||||||
b = gpu.frame_buffer[i] >> 11 & 0x1F;
|
|
||||||
|
|
||||||
r2 = gpu.frame_buffer_prev[i] & 0x1F;
|
|
||||||
g2 = gpu.frame_buffer_prev[i] >> 5 & 0x3F;
|
|
||||||
b2 = gpu.frame_buffer_prev[i] >> 11 & 0x1F;
|
|
||||||
|
|
||||||
gpu.frame_buffer_prev[i] = gpu.frame_buffer[i];
|
|
||||||
|
|
||||||
gpu.frame_buffer[i] = (uint16_t) ((r + r2) >> 1) |
|
|
||||||
(((g + g2) >> 1) << 5) |
|
|
||||||
(((b + b2) >> 1) << 11);*/
|
|
||||||
|
|
||||||
r = gpu.frame_buffer[i] & 0x001F;
|
|
||||||
g = gpu.frame_buffer[i] & 0x07E0;
|
|
||||||
b = gpu.frame_buffer[i] & 0xF800;
|
|
||||||
|
|
||||||
r2 = gpu.frame_buffer_prev[i] & 0x001F;
|
|
||||||
g2 = gpu.frame_buffer_prev[i] & 0x07E0;
|
|
||||||
b2 = gpu.frame_buffer_prev[i] & 0xF800;
|
|
||||||
|
|
||||||
// gpu.frame_buffer_prev[i] = gpu.frame_buffer[i];
|
|
||||||
|
|
||||||
res = ((r + r2) >> 1) |
|
|
||||||
(((g + g2) >> 1) & 0x07E0) |
|
|
||||||
(((b + b2) >> 1) & 0xF800);
|
|
||||||
|
|
||||||
gpu.frame_buffer_prev[i] = gpu.frame_buffer[i];
|
|
||||||
gpu.frame_buffer[i] = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* call the callback */
|
/* call the callback */
|
||||||
if (gpu_frame_ready_cb)
|
if (gpu_frame_ready_cb)
|
||||||
(*gpu_frame_ready_cb) ();
|
(*gpu_frame_ready_cb)();
|
||||||
|
|
||||||
/* reset priority matrix */
|
/* reset priority matrix */
|
||||||
bzero(gpu.priority, 160 * 144);
|
bzero(gpu.priority, 160 * 144);
|
||||||
|
@ -235,12 +194,6 @@ void gpu_draw_frame()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get pointer to frame buffer */
|
|
||||||
uint16_t *gpu_get_frame_buffer()
|
|
||||||
{
|
|
||||||
return gpu.frame_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw a single line */
|
/* draw a single line */
|
||||||
void gpu_draw_line(uint8_t line)
|
void gpu_draw_line(uint8_t line)
|
||||||
{
|
{
|
||||||
|
@ -265,17 +218,15 @@ void gpu_draw_line(uint8_t line)
|
||||||
{
|
{
|
||||||
gpu_cgb_bg_tile_t *tiles_map_cgb = NULL;
|
gpu_cgb_bg_tile_t *tiles_map_cgb = NULL;
|
||||||
uint8_t *tiles = NULL;
|
uint8_t *tiles = NULL;
|
||||||
uint16_t *palette;
|
uint32_t *palette;
|
||||||
|
|
||||||
if (global_cgb)
|
if (global_cgb)
|
||||||
{
|
{
|
||||||
/* CGB tile map into VRAM0 */
|
/* CGB tile map into VRAM0 */
|
||||||
tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).bg_tiles_map ?
|
tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).bg_tiles_map ? 0x1C00 : 0x1800);
|
||||||
0x1C00 : 0x1800);
|
|
||||||
|
|
||||||
/* additional attribute table is into VRAM1 */
|
/* additional attribute table is into VRAM1 */
|
||||||
tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).bg_tiles_map ?
|
tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).bg_tiles_map ? 0x1C00 : 0x1800);
|
||||||
0x1C00 : 0x1800);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -283,8 +234,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
x_flip = 0;
|
x_flip = 0;
|
||||||
|
|
||||||
/* get tile map offset */
|
/* get tile map offset */
|
||||||
tiles_map = mmu_addr((*gpu.lcd_ctrl).bg_tiles_map ?
|
tiles_map = mmu_addr((*gpu.lcd_ctrl).bg_tiles_map ? 0x9C00 : 0x9800);
|
||||||
0x9C00 : 0x9800);
|
|
||||||
|
|
||||||
if ((*gpu.lcd_ctrl).bg_tiles)
|
if ((*gpu.lcd_ctrl).bg_tiles)
|
||||||
tiles_addr = 0x8000;
|
tiles_addr = 0x8000;
|
||||||
|
@ -319,11 +269,11 @@ void gpu_draw_line(uint8_t line)
|
||||||
tile_subline = tile_y % 8;
|
tile_subline = tile_y % 8;
|
||||||
|
|
||||||
/* walk through different tiles */
|
/* walk through different tiles */
|
||||||
for (t=0; t<21; t++)
|
for (t = 0; t < 21; t++)
|
||||||
{
|
{
|
||||||
/* resolv tile data memory area */
|
/* resolv tile data memory area */
|
||||||
if ((*gpu.lcd_ctrl).bg_tiles == 0)
|
if ((*gpu.lcd_ctrl).bg_tiles == 0)
|
||||||
tile_n = (int8_t) tiles_map[tile_idx];
|
tile_n = (int8_t)tiles_map[tile_idx];
|
||||||
else
|
else
|
||||||
tile_n = (tiles_map[tile_idx] & 0x00FF);
|
tile_n = (tiles_map[tile_idx] & 0x00FF);
|
||||||
|
|
||||||
|
@ -334,8 +284,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
palette_idx = tiles_map_cgb[tile_idx].palette;
|
palette_idx = tiles_map_cgb[tile_idx].palette;
|
||||||
|
|
||||||
/* get palette pointer to 4 (16bit) colors */
|
/* get palette pointer to 4 (16bit) colors */
|
||||||
palette =
|
palette = &gpu.cgb_palette_bg_rgb888[palette_idx * 4];
|
||||||
(uint16_t *) &gpu.cgb_palette_bg_rgb565[palette_idx * 4];
|
|
||||||
|
|
||||||
/* get priority of the tile */
|
/* get priority of the tile */
|
||||||
priority = tiles_map_cgb[tile_idx].priority;
|
priority = tiles_map_cgb[tile_idx].priority;
|
||||||
|
@ -369,7 +318,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
uint8_t b1 = *(tiles + tile_ptr);
|
uint8_t b1 = *(tiles + tile_ptr);
|
||||||
uint8_t b2 = *(tiles + tile_ptr + 1);
|
uint8_t b2 = *(tiles + tile_ptr + 1);
|
||||||
|
|
||||||
for (y=0; y<8; y++)
|
for (y = 0; y < 8; y++)
|
||||||
{
|
{
|
||||||
if (x_flip)
|
if (x_flip)
|
||||||
shft = (1 << (7 - y));
|
shft = (1 << (7 - y));
|
||||||
|
@ -389,7 +338,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
px_drawn = 8 - px_start;
|
px_drawn = 8 - px_start;
|
||||||
|
|
||||||
/* set n pixels */
|
/* set n pixels */
|
||||||
for (i=0; i<px_drawn; i++)
|
for (i = 0; i < px_drawn; i++)
|
||||||
{
|
{
|
||||||
pos = pos_fb + (px_drawn - i - 1);
|
pos = pos_fb + (px_drawn - i - 1);
|
||||||
|
|
||||||
|
@ -403,7 +352,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
px_drawn = *(gpu.scroll_x) % 8;
|
px_drawn = *(gpu.scroll_x) % 8;
|
||||||
|
|
||||||
/* set n pixels */
|
/* set n pixels */
|
||||||
for (i=0; i<px_drawn; i++)
|
for (i = 0; i < px_drawn; i++)
|
||||||
{
|
{
|
||||||
pos = pos_fb + (px_drawn - i - 1);
|
pos = pos_fb + (px_drawn - i - 1);
|
||||||
|
|
||||||
|
@ -415,7 +364,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* set 8 pixels */
|
/* set 8 pixels */
|
||||||
for (i=0; i<8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
pos = pos_fb + (7 - i);
|
pos = pos_fb + (7 - i);
|
||||||
|
|
||||||
|
@ -443,7 +392,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
if ((*gpu.lcd_ctrl).sprites)
|
if ((*gpu.lcd_ctrl).sprites)
|
||||||
{
|
{
|
||||||
/* make it point to the first OAM object */
|
/* make it point to the first OAM object */
|
||||||
gpu_oam_t *oam = (gpu_oam_t *) mmu_addr(0xFE00);
|
gpu_oam_t *oam = (gpu_oam_t *)mmu_addr(0xFE00);
|
||||||
|
|
||||||
/* calc sprite height */
|
/* calc sprite height */
|
||||||
uint8_t h = ((*gpu.lcd_ctrl).sprites_size + 1) * 8;
|
uint8_t h = ((*gpu.lcd_ctrl).sprites_size + 1) * 8;
|
||||||
|
@ -452,10 +401,10 @@ void gpu_draw_line(uint8_t line)
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
/* prepare sorted list of oams */
|
/* prepare sorted list of oams */
|
||||||
for (i=0; i<40; i++)
|
for (i = 0; i < 40; i++)
|
||||||
sort[i] = -1;
|
sort[i] = -1;
|
||||||
|
|
||||||
for (i=0; i<40; i++)
|
for (i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
/* the sprite intersects the current line? */
|
/* the sprite intersects the current line? */
|
||||||
if (oam[i].x != 0 && oam[i].y != 0 &&
|
if (oam[i].x != 0 && oam[i].y != 0 &&
|
||||||
|
@ -471,7 +420,7 @@ void gpu_draw_line(uint8_t line)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find its position on sort array */
|
/* find its position on sort array */
|
||||||
for (j=0; j<40; j++)
|
for (j = 0; j < 40; j++)
|
||||||
{
|
{
|
||||||
if (sort[j] == -1)
|
if (sort[j] == -1)
|
||||||
{
|
{
|
||||||
|
@ -488,8 +437,8 @@ void gpu_draw_line(uint8_t line)
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
|
|
||||||
for (z=40; z>j; z--)
|
for (z = 40; z > j; z--)
|
||||||
sort[z] = sort[z-1];
|
sort[z] = sort[z - 1];
|
||||||
|
|
||||||
sort[j] = i;
|
sort[j] = i;
|
||||||
break;
|
break;
|
||||||
|
@ -499,10 +448,9 @@ void gpu_draw_line(uint8_t line)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw ordered sprite list */
|
/* draw ordered sprite list */
|
||||||
for (i=0; i<40 && sort[i] != -1; i++)
|
for (i = 0; i < 40 && sort[i] != -1; i++)
|
||||||
gpu_draw_sprite_line(&oam[sort[i]],
|
gpu_draw_sprite_line(&oam[sort[i]],
|
||||||
(*gpu.lcd_ctrl).sprites_size, line);
|
(*gpu.lcd_ctrl).sprites_size, line);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wanna show window? */
|
/* wanna show window? */
|
||||||
|
@ -529,9 +477,11 @@ void gpu_draw_line(uint8_t line)
|
||||||
|
|
||||||
/* calc the first interesting tile */
|
/* calc the first interesting tile */
|
||||||
first_z = ((line - *(gpu.window_y) -
|
first_z = ((line - *(gpu.window_y) -
|
||||||
gpu.window_skipped_lines) >> 3) << 5;
|
gpu.window_skipped_lines) >>
|
||||||
|
3)
|
||||||
|
<< 5;
|
||||||
|
|
||||||
for (z=first_z; z<first_z + 21; z++)
|
for (z = first_z; z < first_z + 21; z++)
|
||||||
{
|
{
|
||||||
/* calc tile coordinates on frame buffer */
|
/* calc tile coordinates on frame buffer */
|
||||||
tile_pos_x = ((z & 0x1F) << 3) + *(gpu.window_x) - 7;
|
tile_pos_x = ((z & 0x1F) << 3) + *(gpu.window_x) - 7;
|
||||||
|
@ -555,14 +505,12 @@ void gpu_draw_line(uint8_t line)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* put tile on frame buffer */
|
/* put tile on frame buffer */
|
||||||
gpu_draw_window_line(z, (uint8_t) tile_pos_x,
|
gpu_draw_window_line(z, (uint8_t)tile_pos_x,
|
||||||
(uint8_t) tile_pos_y, line);
|
(uint8_t)tile_pos_y, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* draw a tile in x,y coordinates */
|
/* draw a tile in x,y coordinates */
|
||||||
void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
uint8_t frame_y, uint8_t line)
|
uint8_t frame_y, uint8_t line)
|
||||||
|
@ -572,24 +520,22 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
uint8_t *tiles_map;
|
uint8_t *tiles_map;
|
||||||
gpu_cgb_bg_tile_t *tiles_map_cgb = NULL;
|
gpu_cgb_bg_tile_t *tiles_map_cgb = NULL;
|
||||||
uint8_t *tiles, x_flip;
|
uint8_t *tiles, x_flip;
|
||||||
uint16_t *palette;
|
uint32_t *palette;
|
||||||
|
|
||||||
if (global_cgb)
|
if (global_cgb)
|
||||||
{
|
{
|
||||||
/* CGB tile map into VRAM0 */
|
/* CGB tile map into VRAM0 */
|
||||||
tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).window_tiles_map ?
|
tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).window_tiles_map ? 0x1C00 : 0x1800);
|
||||||
0x1C00 : 0x1800);
|
|
||||||
|
|
||||||
/* additional attribute table is into VRAM1 */
|
/* additional attribute table is into VRAM1 */
|
||||||
tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).window_tiles_map ?
|
tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).window_tiles_map ? 0x1C00 : 0x1800);
|
||||||
0x1C00 : 0x1800);
|
|
||||||
|
|
||||||
/* get palette index */
|
/* get palette index */
|
||||||
uint8_t palette_idx = tiles_map_cgb[tile_idx].palette;
|
uint8_t palette_idx = tiles_map_cgb[tile_idx].palette;
|
||||||
x_flip = tiles_map_cgb[tile_idx].x_flip;
|
x_flip = tiles_map_cgb[tile_idx].x_flip;
|
||||||
|
|
||||||
/* get palette pointer to 4 (16bit) colors */
|
/* get palette pointer to 4 (16bit) colors */
|
||||||
palette = (uint16_t *) &gpu.cgb_palette_bg_rgb565[palette_idx * 4];
|
palette = &gpu.cgb_palette_bg_rgb888[palette_idx * 4];
|
||||||
|
|
||||||
/* attribute table will tell us where is the tile */
|
/* attribute table will tell us where is the tile */
|
||||||
if (tiles_map_cgb[tile_idx].vram_bank)
|
if (tiles_map_cgb[tile_idx].vram_bank)
|
||||||
|
@ -598,13 +544,11 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
else
|
else
|
||||||
tiles = mmu_addr_vram0() +
|
tiles = mmu_addr_vram0() +
|
||||||
((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000);
|
((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* get tile map offset */
|
/* get tile map offset */
|
||||||
tiles_map = mmu_addr((*gpu.lcd_ctrl).window_tiles_map ?
|
tiles_map = mmu_addr((*gpu.lcd_ctrl).window_tiles_map ? 0x9C00 : 0x9800);
|
||||||
0x9C00 : 0x9800);
|
|
||||||
|
|
||||||
/* get tile offset */
|
/* get tile offset */
|
||||||
if ((*gpu.lcd_ctrl).bg_tiles)
|
if ((*gpu.lcd_ctrl).bg_tiles)
|
||||||
|
@ -621,7 +565,7 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
|
|
||||||
/* obtain tile number */
|
/* obtain tile number */
|
||||||
if ((*gpu.lcd_ctrl).bg_tiles == 0)
|
if ((*gpu.lcd_ctrl).bg_tiles == 0)
|
||||||
tile_n = (int8_t) tiles_map[tile_idx];
|
tile_n = (int8_t)tiles_map[tile_idx];
|
||||||
else
|
else
|
||||||
tile_n = (tiles_map[tile_idx] & 0x00ff);
|
tile_n = (tiles_map[tile_idx] & 0x00ff);
|
||||||
|
|
||||||
|
@ -641,7 +585,7 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
uint8_t pxa[8];
|
uint8_t pxa[8];
|
||||||
uint8_t shft;
|
uint8_t shft;
|
||||||
|
|
||||||
for (y=0; y<8; y++)
|
for (y = 0; y < 8; y++)
|
||||||
{
|
{
|
||||||
//uint8_t shft = (1 << y);
|
//uint8_t shft = (1 << y);
|
||||||
|
|
||||||
|
@ -655,7 +599,7 @@ void gpu_draw_window_line(int tile_idx, uint8_t frame_x,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set 8 pixels (full tile line) */
|
/* set 8 pixels (full tile line) */
|
||||||
for (i=0; i<8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
/* over the last column? */
|
/* over the last column? */
|
||||||
uint8_t x = frame_x + (7 - i);
|
uint8_t x = frame_x + (7 - i);
|
||||||
|
@ -679,7 +623,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
||||||
uint_fast16_t p, i, j;
|
uint_fast16_t p, i, j;
|
||||||
uint8_t sprite_bytes;
|
uint8_t sprite_bytes;
|
||||||
int16_t tile_ptr;
|
int16_t tile_ptr;
|
||||||
uint16_t *palette;
|
uint32_t *palette;
|
||||||
uint8_t *tiles;
|
uint8_t *tiles;
|
||||||
|
|
||||||
/* REMEMBER! position of sprites is relative to the visible screen area */
|
/* REMEMBER! position of sprites is relative to the visible screen area */
|
||||||
|
@ -699,7 +643,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
||||||
uint8_t palette_idx = oam->palette_cgb;
|
uint8_t palette_idx = oam->palette_cgb;
|
||||||
|
|
||||||
/* get palette pointer to 4 (16bit) colors */
|
/* get palette pointer to 4 (16bit) colors */
|
||||||
palette = (uint16_t *) &gpu.cgb_palette_oam_rgb565[palette_idx * 4];
|
palette = &gpu.cgb_palette_oam_rgb888[palette_idx * 4];
|
||||||
|
|
||||||
/* tiles are into vram0 */
|
/* tiles are into vram0 */
|
||||||
if (oam->vram_bank)
|
if (oam->vram_bank)
|
||||||
|
@ -723,7 +667,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
||||||
|
|
||||||
/* walk through 8x8 pixels (2bit per pixel -> 4 pixels per byte) */
|
/* walk through 8x8 pixels (2bit per pixel -> 4 pixels per byte) */
|
||||||
/* 1 line is 8 pixels -> 2 bytes per line */
|
/* 1 line is 8 pixels -> 2 bytes per line */
|
||||||
for (p=0; p<sprite_bytes; p+=2)
|
for (p = 0; p < sprite_bytes; p += 2)
|
||||||
{
|
{
|
||||||
uint8_t tile_y = p / 2;
|
uint8_t tile_y = p / 2;
|
||||||
|
|
||||||
|
@ -745,7 +689,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
||||||
|
|
||||||
uint8_t pxa[8];
|
uint8_t pxa[8];
|
||||||
|
|
||||||
for (j=0; j<8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
uint8_t shft = (1 << j);
|
uint8_t shft = (1 << j);
|
||||||
|
|
||||||
|
@ -754,7 +698,7 @@ void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set 8 pixels (full tile line) */
|
/* set 8 pixels (full tile line) */
|
||||||
for (i=0; i<8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (oam->x_flip)
|
if (oam->x_flip)
|
||||||
off = i;
|
off = i;
|
||||||
|
@ -825,7 +769,7 @@ void gpu_step()
|
||||||
char mode_changed = 0;
|
char mode_changed = 0;
|
||||||
|
|
||||||
/* take different action based on current state */
|
/* take different action based on current state */
|
||||||
switch((*gpu.lcd_status).mode)
|
switch ((*gpu.lcd_status).mode)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* during HBLANK (CPU can access VRAM)
|
* during HBLANK (CPU can access VRAM)
|
||||||
|
@ -873,7 +817,6 @@ void gpu_step()
|
||||||
/* mode 2 needs 80 cycles */
|
/* mode 2 needs 80 cycles */
|
||||||
gpu.next = cycles.cnt +
|
gpu.next = cycles.cnt +
|
||||||
(80 << global_cpu_double_speed);
|
(80 << global_cpu_double_speed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify mode has changed */
|
/* notify mode has changed */
|
||||||
|
@ -882,7 +825,7 @@ void gpu_step()
|
||||||
/* inc current line */
|
/* inc current line */
|
||||||
(*gpu.ly)++;
|
(*gpu.ly)++;
|
||||||
|
|
||||||
// cycles_hblank(*gpu.ly);
|
// cycles_hblank(*gpu.ly);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -949,7 +892,7 @@ void gpu_step()
|
||||||
gpu_draw_line(*gpu.ly);
|
gpu_draw_line(*gpu.ly);
|
||||||
|
|
||||||
/* notify cycles */
|
/* notify cycles */
|
||||||
// cycles_hblank(*gpu.ly);
|
// cycles_hblank(*gpu.ly);
|
||||||
|
|
||||||
//printf("COLLA %d\n", *gpu.ly);
|
//printf("COLLA %d\n", *gpu.ly);
|
||||||
|
|
||||||
|
@ -1006,7 +949,8 @@ uint8_t gpu_read_reg(uint16_t a)
|
||||||
0x00ff;
|
0x00ff;
|
||||||
else
|
else
|
||||||
return (gpu.cgb_palette_bg[gpu.cgb_palette_bg_idx / 2] &
|
return (gpu.cgb_palette_bg[gpu.cgb_palette_bg_idx / 2] &
|
||||||
0xff00) >> 8;
|
0xff00) >>
|
||||||
|
8;
|
||||||
|
|
||||||
case 0xFF6A:
|
case 0xFF6A:
|
||||||
|
|
||||||
|
@ -1019,57 +963,54 @@ uint8_t gpu_read_reg(uint16_t a)
|
||||||
0x00ff;
|
0x00ff;
|
||||||
else
|
else
|
||||||
return (gpu.cgb_palette_oam[gpu.cgb_palette_oam_idx / 2] &
|
return (gpu.cgb_palette_oam[gpu.cgb_palette_oam_idx / 2] &
|
||||||
0xff00) >> 8;
|
0xff00) >>
|
||||||
|
8;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t makecol(uint16_t c)
|
||||||
|
{
|
||||||
|
// TODO: hook this up to the same color logic that the other cores use
|
||||||
|
return c >> 7 & 0xf8 | c >> 12 & 0x07
|
||||||
|
| c << 6 & 0xf800 | c << 1 & 0x0700
|
||||||
|
| c << 19 & 0xf80000 | c << 14 & 0x070000
|
||||||
|
| 0xff000000;
|
||||||
|
}
|
||||||
|
|
||||||
void gpu_write_reg(uint16_t a, uint8_t v)
|
void gpu_write_reg(uint16_t a, uint8_t v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t r,g,b;
|
|
||||||
|
|
||||||
switch (a)
|
switch (a)
|
||||||
{
|
{
|
||||||
case 0xFF47:
|
case 0xFF47:
|
||||||
|
|
||||||
gpu.bg_palette[0] = gpu_color_lookup[v & 0x03];
|
gpu.bg_palette[0] = gpu_color_lookup[v & 0x03];
|
||||||
gpu.bg_palette[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
gpu.bg_palette[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
||||||
gpu.bg_palette[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
gpu.bg_palette[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
||||||
gpu.bg_palette[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
gpu.bg_palette[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF48:
|
case 0xFF48:
|
||||||
|
|
||||||
gpu.obj_palette_0[0] = gpu_color_lookup[v & 0x03];
|
gpu.obj_palette_0[0] = gpu_color_lookup[v & 0x03];
|
||||||
gpu.obj_palette_0[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
gpu.obj_palette_0[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
||||||
gpu.obj_palette_0[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
gpu.obj_palette_0[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
||||||
gpu.obj_palette_0[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
gpu.obj_palette_0[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF49:
|
case 0xFF49:
|
||||||
|
|
||||||
gpu.obj_palette_1[0] = gpu_color_lookup[v & 0x03];
|
gpu.obj_palette_1[0] = gpu_color_lookup[v & 0x03];
|
||||||
gpu.obj_palette_1[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
gpu.obj_palette_1[1] = gpu_color_lookup[(v & 0x0c) >> 2];
|
||||||
gpu.obj_palette_1[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
gpu.obj_palette_1[2] = gpu_color_lookup[(v & 0x30) >> 4];
|
||||||
gpu.obj_palette_1[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
gpu.obj_palette_1[3] = gpu_color_lookup[(v & 0xc0) >> 6];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF68:
|
case 0xFF68:
|
||||||
|
|
||||||
gpu.cgb_palette_bg_idx = (v & 0x3f);
|
gpu.cgb_palette_bg_idx = (v & 0x3f);
|
||||||
gpu.cgb_palette_bg_autoinc = ((v & 0x80) == 0x80);
|
gpu.cgb_palette_bg_autoinc = ((v & 0x80) == 0x80);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF69:
|
case 0xFF69:
|
||||||
|
|
||||||
i = gpu.cgb_palette_bg_idx / 2;
|
i = gpu.cgb_palette_bg_idx / 2;
|
||||||
|
|
||||||
if ((gpu.cgb_palette_bg_idx & 0x01) == 0x00)
|
if ((gpu.cgb_palette_bg_idx & 0x01) == 0x00)
|
||||||
|
@ -1083,29 +1024,19 @@ void gpu_write_reg(uint16_t a, uint8_t v)
|
||||||
gpu.cgb_palette_bg[i] |= (v << 8);
|
gpu.cgb_palette_bg[i] |= (v << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = gpu.cgb_palette_bg[i] & 0x1F;
|
gpu.cgb_palette_bg_rgb888[i] = makecol(gpu.cgb_palette_bg[i]);
|
||||||
g = gpu.cgb_palette_bg[i] >> 5 & 0x1F;
|
|
||||||
b = gpu.cgb_palette_bg[i] >> 10 & 0x1F;
|
|
||||||
|
|
||||||
gpu.cgb_palette_bg_rgb565[i] =
|
|
||||||
(((r * 13 + g * 2 + b + 8) << 7) & 0xF800) |
|
|
||||||
((g * 3 + b + 1) >> 1) << 5 |
|
|
||||||
((r * 3 + g * 2 + b * 11 + 8) >> 4);
|
|
||||||
|
|
||||||
if (gpu.cgb_palette_bg_autoinc)
|
if (gpu.cgb_palette_bg_autoinc)
|
||||||
gpu.cgb_palette_bg_idx = ((gpu.cgb_palette_bg_idx + 1) & 0x3f);
|
gpu.cgb_palette_bg_idx = (gpu.cgb_palette_bg_idx + 1) & 0x3f;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF6A:
|
case 0xFF6A:
|
||||||
|
|
||||||
gpu.cgb_palette_oam_idx = v & 0x3f;
|
gpu.cgb_palette_oam_idx = v & 0x3f;
|
||||||
gpu.cgb_palette_oam_autoinc = ((v & 0x80) == 0x80);
|
gpu.cgb_palette_oam_autoinc = ((v & 0x80) == 0x80);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF6B:
|
case 0xFF6B:
|
||||||
|
|
||||||
i = gpu.cgb_palette_oam_idx / 2;
|
i = gpu.cgb_palette_oam_idx / 2;
|
||||||
|
|
||||||
if ((gpu.cgb_palette_oam_idx & 0x01) == 0x00)
|
if ((gpu.cgb_palette_oam_idx & 0x01) == 0x00)
|
||||||
|
@ -1119,21 +1050,12 @@ void gpu_write_reg(uint16_t a, uint8_t v)
|
||||||
gpu.cgb_palette_oam[i] |= (v << 8);
|
gpu.cgb_palette_oam[i] |= (v << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = gpu.cgb_palette_oam[i] & 0x1F;
|
gpu.cgb_palette_oam_rgb888[i] = makecol(gpu.cgb_palette_oam[i]);
|
||||||
g = gpu.cgb_palette_oam[i] >> 5 & 0x1F;
|
|
||||||
b = gpu.cgb_palette_oam[i] >> 10 & 0x1F;
|
|
||||||
|
|
||||||
gpu.cgb_palette_oam_rgb565[i] =
|
|
||||||
(((r * 13 + g * 2 + b + 8) << 7) & 0xF800) |
|
|
||||||
((g * 3 + b + 1) >> 1) << 5 |
|
|
||||||
((r * 3 + g * 2 + b * 11 + 8) >> 4);
|
|
||||||
|
|
||||||
if (gpu.cgb_palette_oam_autoinc)
|
if (gpu.cgb_palette_oam_autoinc)
|
||||||
gpu.cgb_palette_oam_idx =
|
gpu.cgb_palette_oam_idx = (gpu.cgb_palette_oam_idx + 1) & 0x3f;
|
||||||
((gpu.cgb_palette_oam_idx + 1) & 0x3f);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ typedef void (*gpu_frame_ready_cb_t) ();
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
void gpu_dump_oam();
|
void gpu_dump_oam();
|
||||||
uint16_t *gpu_get_frame_buffer();
|
|
||||||
void gpu_init(gpu_frame_ready_cb_t cb);
|
void gpu_init(gpu_frame_ready_cb_t cb);
|
||||||
void gpu_reset();
|
void gpu_reset();
|
||||||
void gpu_set_speed(char speed);
|
void gpu_set_speed(char speed);
|
||||||
|
@ -105,27 +104,26 @@ typedef struct gpu_s
|
||||||
uint_fast16_t frame_counter;
|
uint_fast16_t frame_counter;
|
||||||
|
|
||||||
/* BG palette */
|
/* BG palette */
|
||||||
uint16_t bg_palette[4];
|
uint32_t bg_palette[4];
|
||||||
|
|
||||||
/* Obj palette 0/1 */
|
/* Obj palette 0/1 */
|
||||||
uint16_t obj_palette_0[4];
|
uint32_t obj_palette_0[4];
|
||||||
uint16_t obj_palette_1[4];
|
uint32_t obj_palette_1[4];
|
||||||
|
|
||||||
/* CGB palette for background */
|
/* CGB palette for background */
|
||||||
uint16_t cgb_palette_bg_rgb565[0x20];
|
uint32_t cgb_palette_bg_rgb888[0x20];
|
||||||
uint16_t cgb_palette_bg[0x20];
|
uint16_t cgb_palette_bg[0x20];
|
||||||
uint8_t cgb_palette_bg_idx;
|
uint8_t cgb_palette_bg_idx;
|
||||||
uint8_t cgb_palette_bg_autoinc;
|
uint8_t cgb_palette_bg_autoinc;
|
||||||
|
|
||||||
/* CGB palette for sprites */
|
/* CGB palette for sprites */
|
||||||
uint16_t cgb_palette_oam_rgb565[0x20];
|
uint32_t cgb_palette_oam_rgb888[0x20];
|
||||||
uint16_t cgb_palette_oam[0x20];
|
uint16_t cgb_palette_oam[0x20];
|
||||||
uint8_t cgb_palette_oam_idx;
|
uint8_t cgb_palette_oam_idx;
|
||||||
uint8_t cgb_palette_oam_autoinc;
|
uint8_t cgb_palette_oam_autoinc;
|
||||||
|
|
||||||
/* frame buffer */
|
/* frame buffer */
|
||||||
uint16_t frame_buffer_prev[160 * 144];
|
uint32_t frame_buffer[160 * 144];
|
||||||
uint16_t frame_buffer[160 * 144];
|
|
||||||
uint8_t priority[160 * 144];
|
uint8_t priority[160 * 144];
|
||||||
uint8_t palette_idx[160 * 144];
|
uint8_t palette_idx[160 * 144];
|
||||||
} gpu_t;
|
} gpu_t;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
//
|
|
||||||
// Created by DVDN on 14/07/2016.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef PIZZABOY_TESTONE_H
|
|
||||||
#define PIZZABOY_TESTONE_H
|
|
||||||
|
|
||||||
#endif //PIZZABOY_TESTONE_H
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "sound_output.h"
|
#include "sound_output.h"
|
||||||
|
|
||||||
/* proto */
|
/* proto */
|
||||||
void cb();
|
void frame_cb();
|
||||||
void connected_cb();
|
void connected_cb();
|
||||||
void disconnected_cb();
|
void disconnected_cb();
|
||||||
void rumble_cb(uint8_t rumble);
|
void rumble_cb(uint8_t rumble);
|
||||||
|
@ -46,12 +46,6 @@ void network_send_data(uint8_t v);
|
||||||
void *start_thread(void *args);
|
void *start_thread(void *args);
|
||||||
void *start_thread_network(void *args);
|
void *start_thread_network(void *args);
|
||||||
|
|
||||||
/* frame buffer pointer */
|
|
||||||
uint16_t *fb;
|
|
||||||
|
|
||||||
/* magnify rate */
|
|
||||||
float magnify_rate = 1.f;
|
|
||||||
|
|
||||||
/* cartridge name */
|
/* cartridge name */
|
||||||
char cart_name[64];
|
char cart_name[64];
|
||||||
|
|
||||||
|
@ -73,21 +67,16 @@ EXPORT int Init(const void *rom, int romlen)
|
||||||
gameboy_init();
|
gameboy_init();
|
||||||
|
|
||||||
/* init GPU */
|
/* init GPU */
|
||||||
gpu_init(&cb);
|
gpu_init(frame_cb);
|
||||||
|
|
||||||
/* set rumble cb */
|
/* set rumble cb */
|
||||||
mmu_set_rumble_cb(&rumble_cb);
|
mmu_set_rumble_cb(&rumble_cb);
|
||||||
|
|
||||||
/* get frame buffer reference */
|
|
||||||
fb = gpu_get_frame_buffer();
|
|
||||||
|
|
||||||
sound_output_init(2 * 1024 * 1024, 44100);
|
sound_output_init(2 * 1024 * 1024, 44100);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t fb32[160 * 144];
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t* vbuff;
|
uint32_t* vbuff;
|
||||||
|
@ -97,15 +86,17 @@ typedef struct
|
||||||
uint16_t keys; // keypad input
|
uint16_t keys; // keypad input
|
||||||
} frameinfo_t;
|
} frameinfo_t;
|
||||||
|
|
||||||
|
static uint32_t* current_vbuff;
|
||||||
|
|
||||||
EXPORT void FrameAdvance(frameinfo_t* frame)
|
EXPORT void FrameAdvance(frameinfo_t* frame)
|
||||||
{
|
{
|
||||||
input_set_keys(frame->keys);
|
input_set_keys(frame->keys);
|
||||||
uint64_t current = cycles.sampleclock;
|
uint64_t current = cycles.sampleclock;
|
||||||
|
current_vbuff = frame->vbuff;
|
||||||
gameboy_run(current + frame->clocks);
|
gameboy_run(current + frame->clocks);
|
||||||
frame->clocks = cycles.sampleclock - current;
|
frame->clocks = cycles.sampleclock - current;
|
||||||
memcpy(frame->vbuff, fb32, 160 * 144 * sizeof(uint32_t));
|
|
||||||
frame->samples = sound_output_read(frame->sbuff);
|
frame->samples = sound_output_read(frame->sbuff);
|
||||||
|
current_vbuff = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int IsCGB(void)
|
EXPORT int IsCGB(void)
|
||||||
|
@ -113,20 +104,9 @@ EXPORT int IsCGB(void)
|
||||||
return global_cgb;
|
return global_cgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cb()
|
void frame_cb()
|
||||||
{
|
{
|
||||||
// frame received into fb
|
memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer));
|
||||||
uint16_t *src = fb;
|
|
||||||
uint8_t *dst = (uint8_t *)fb32;
|
|
||||||
|
|
||||||
for (int i = 0; i < 160 * 144; i++)
|
|
||||||
{
|
|
||||||
uint16_t c = *src++;
|
|
||||||
*dst++ = c << 3 & 0xf8 | c >> 2 & 7;
|
|
||||||
*dst++ = c >> 3 & 0xfa | c >> 9 & 3;
|
|
||||||
*dst++ = c >> 8 & 0xf8 | c >> 13 & 7;
|
|
||||||
*dst++ = 0xff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void connected_cb()
|
void connected_cb()
|
||||||
|
|
Loading…
Reference in New Issue