From 89cfdb4d650db3d71cb81baa993aad8537fcfe4d Mon Sep 17 00:00:00 2001 From: Samuel Walker Date: Wed, 19 Feb 2025 10:20:45 -0700 Subject: [PATCH] ppu work --- lib/emu.c | 6 +++--- lib/lcd.c | 2 +- lib/ppu.c | 30 ++++++++++++++++-------------- lib/ppu_pipeline.c | 23 +++++++++++++++++++++-- lib/ui.c | 3 ++- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/lib/emu.c b/lib/emu.c index 2aec343..73edba0 100644 --- a/lib/emu.c +++ b/lib/emu.c @@ -93,10 +93,10 @@ int emu_run(int argc, char **argv) { while(!ctx.die) { sleep_ms(1); ui_handle_events(); - if (prev_frame != ppu_get_context()->current_frame) { + //if (prev_frame != ppu_get_context()->current_frame) { ui_update(); - } - prev_frame = ppu_get_context()->current_frame; + //} + //prev_frame = ppu_get_context()->current_frame; } diff --git a/lib/lcd.c b/lib/lcd.c index 64f64d3..5e4c80a 100644 --- a/lib/lcd.c +++ b/lib/lcd.c @@ -4,7 +4,7 @@ static lcd_context ctx; -static unsigned long colors_default[4] = {0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000}; +static unsigned long colors_default[4] = {0xFF759833, 0xFF588F51, 0xFF3B7560, 0xFF2E615A}; lcd_context *lcd_get_context() { return &ctx; diff --git a/lib/ppu.c b/lib/ppu.c index 552ec35..d1ae9f8 100644 --- a/lib/ppu.c +++ b/lib/ppu.c @@ -40,21 +40,23 @@ void ppu_init() { } void ppu_tick() { - ctx.line_ticks++; + if(LCDC_LCD_ENABLE){ + ctx.line_ticks++; - switch(LCDS_MODE) { - case MODE_OAM: - ppu_mode_oam(); - break; - case MODE_XFER: - ppu_mode_xfer(); - break; - case MODE_VBLANK: - ppu_mode_vblank(); - break; - case MODE_HBLANK: - ppu_mode_hblank(); - break; + switch(LCDS_MODE) { + case MODE_OAM: + ppu_mode_oam(); + break; + case MODE_XFER: + ppu_mode_xfer(); + break; + case MODE_VBLANK: + ppu_mode_vblank(); + break; + case MODE_HBLANK: + ppu_mode_hblank(); + break; + } } } diff --git a/lib/ppu_pipeline.c b/lib/ppu_pipeline.c index c80f0b8..8a214d8 100644 --- a/lib/ppu_pipeline.c +++ b/lib/ppu_pipeline.c @@ -255,6 +255,23 @@ void pipeline_fifo_reset() { ppu_get_context()->pfc.pixel_fifo.head = 0; } +//Rate at wich the screen interpolates between the old and new colors +//Used to simulate the slow response time of the GB's LCD +//A value of zero will always use the exiting screen color, while a 1 will always use the new color +//any value in between will interpolate that percentage between the two +#define INTERPOLATION_RATE 0.5 + +u32 interpolate(u32 first, u32 second) { + u32 final = 0; + for(int c = 0; c < 4; c++) { + u8 c1 = (first >> (c*8)) & 0xFF; + u8 c2 = (second >> (c*8)) & 0xFF; + u8 cf = (u8)(((((float)c2/(float)0xFF) - ((float)c1/(float)0xFF)) * INTERPOLATION_RATE + ((float)c1/(float)0xFF)) * 0xFF); + final |= cf << (c*8); + } + return final; +} + void pipeline_push_pixel() { if (ppu_get_context()->pfc.pixel_fifo.size > 8) { u32 pixel_data = pixel_fifo_pop(); @@ -270,13 +287,15 @@ void pipeline_push_pixel() { } if(ppu_get_context()->rendering_window) { ppu_get_context()->video_buffer[ppu_get_context()->pfc.pushed_x + - (lcd_get_context()->ly * XRES)] = pixel_data; + (lcd_get_context()->ly * XRES)] = interpolate(ppu_get_context()->video_buffer[ppu_get_context()->pfc.pushed_x + + (lcd_get_context()->ly * XRES)], pixel_data); ppu_get_context()->pfc.pushed_x++; }else { if(ppu_get_context()->pfc.line_x >= (lcd_get_context()->scroll_x % 8)) { ppu_get_context()->video_buffer[ppu_get_context()->pfc.pushed_x + - (lcd_get_context()->ly * XRES)] = pixel_data; + (lcd_get_context()->ly * XRES)] = interpolate(ppu_get_context()->video_buffer[ppu_get_context()->pfc.pushed_x + + (lcd_get_context()->ly * XRES)], pixel_data); ppu_get_context()->pfc.pushed_x++; } diff --git a/lib/ui.c b/lib/ui.c index 573d633..14f46c5 100644 --- a/lib/ui.c +++ b/lib/ui.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,7 @@ void ui_init(){ SDL_SetWindowPosition(sdlDebugWindow, x+SCREEN_WIDTH, y); } -static unsigned long tile_colors[4] = {0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000}; +static unsigned long tile_colors[4] = {0xFF759833, 0xFF588F51, 0xFF3B7560, 0xFF2E615A}; void display_tile(SDL_Surface *surface, u16 startLocation, u16 tileNum, int x, int y) { SDL_Rect rc;