pizza: change internal rendering pipeline to 32 bit colors

This commit is contained in:
nattthebear 2017-06-16 09:20:35 -04:00
parent 04d4880564
commit a4c6d04a18
4 changed files with 777 additions and 885 deletions

View File

@ -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,7 +85,6 @@ 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 */
@ -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,45 +183,6 @@ 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)();
@ -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;
@ -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;
@ -502,7 +451,6 @@ void gpu_draw_line(uint8_t line)
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,7 +477,9 @@ 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++)
{ {
@ -561,8 +511,6 @@ void gpu_draw_line(uint8_t 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)
@ -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)
@ -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 */
@ -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;
} }
} }

View File

@ -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;

View File

@ -1,8 +0,0 @@
//
// Created by DVDN on 14/07/2016.
//
#ifndef PIZZABOY_TESTONE_H
#define PIZZABOY_TESTONE_H
#endif //PIZZABOY_TESTONE_H

View File

@ -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()