Improve DMG & Pocket color palettes + reset the RTC of the game cartridge

This commit is contained in:
Vincent Mistler
2023-02-16 15:21:24 +01:00
parent 9a8c00eeb4
commit 971a811730
4 changed files with 2794 additions and 31 deletions
-1
View File
@@ -1,3 +1,2 @@
build build
uf2 uf2
src/rom.c
+36 -28
View File
@@ -46,7 +46,7 @@ typedef uint16_t palette_t[3][4];
*/ */
void get_colour_palette(palette_t selected_palette,uint8_t table_entry,uint8_t shuffling_flags) void get_colour_palette(palette_t selected_palette,uint8_t table_entry,uint8_t shuffling_flags)
{ {
printf("get_colour_palette: table_entry=0x%02X,shuffling_flags=0x%02X\n", printf("I get_colour_palette(table_entry=0x%02X,shuffling_flags=0x%02X)\n",
table_entry, table_entry,
shuffling_flags); shuffling_flags);
if(table_entry==0x00 && shuffling_flags==0x01) if(table_entry==0x00 && shuffling_flags==0x01)
@@ -472,9 +472,9 @@ void get_colour_palette(palette_t selected_palette,uint8_t table_entry,uint8_t s
if(table_entry==0x16 && shuffling_flags==0x00) if(table_entry==0x16 && shuffling_flags==0x00)
{ {
const palette_t palette = { const palette_t palette = {
{ 0xFFFF, 0xA534, 0x528A, 0x0000 }, /* OBJ0 */ { 0xB634, 0x8CCF, 0x63AA, 0x31C4 }, /* OBJ0 */
{ 0xFFFF, 0xA534, 0x528A, 0x0000 }, /* OBJ1 */ { 0xB634, 0x8CCF, 0x63AA, 0x31C4 }, /* OBJ1 */
{ 0xFFFF, 0xA534, 0x528A, 0x0000 } /* BG */ { 0xB634, 0x8CCF, 0x63AA, 0x31C4 } /* BG */
}; };
memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES); memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES);
return; return;
@@ -563,24 +563,24 @@ void get_colour_palette(palette_t selected_palette,uint8_t table_entry,uint8_t s
{ {
/* Game Boy DMG palette (4 shades of green) */ /* Game Boy DMG palette (4 shades of green) */
const palette_t palette = { const palette_t palette = {
{ 0x7C02, 0x5BC8, 0x3AC9, 0x2A07 }, /* OBJ0 */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 }, /* OBJ0 */
{ 0x7C02, 0x5BC8, 0x3AC9, 0x2A07 }, /* OBJ1 */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 }, /* OBJ1 */
{ 0x7C02, 0x5BC8, 0x3AC9, 0x2A07 } /* BG */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 } /* BG */
}; };
memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES); memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES);
return; return;
} }
/* default palette */ /* default palette */
printf("get_colour_palette: No palette found for table_entry=0x%02X shuffling_flags=0x%02X\n", printf("E get_colour_palette: No palette found for table_entry=0x%02X shuffling_flags=0x%02X\n",
table_entry, table_entry,
shuffling_flags); shuffling_flags);
/* Game Boy DMG palette (4 shades of green) */
const palette_t palette = { const palette_t palette = {
{ 0xFFFF, 0xFC30, 0x91C7, 0x0000 }, /* OBJ0 */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 }, /* OBJ0 */
{ 0xFFFF, 0xFC30, 0x91C7, 0x0000 }, /* OBJ1 */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 }, /* OBJ1 */
{ 0xFFFF, 0x7FE6, 0x0318, 0x0000 } /* BG */ { 0xDFEA, 0xAE68, 0x74E6, 0x4388 } /* BG */
}; };
memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES); memcpy(selected_palette, palette, PALETTE_SIZE_IN_BYTES);
return;
} }
/** /**
@@ -600,6 +600,7 @@ void get_colour_palette(palette_t selected_palette,uint8_t table_entry,uint8_t s
void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const char *game_title) void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const char *game_title)
{ {
char disambiguation_character=game_title[3]; /* e.g. 'METROID' -> R */ char disambiguation_character=game_title[3]; /* e.g. 'METROID' -> R */
printf("I auto_assign_palette(0x%02X,%s)\n", game_checksum,game_title);
switch(game_checksum) switch(game_checksum)
{ {
case 0x00: case 0x00:
@@ -731,6 +732,12 @@ void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const ch
get_colour_palette(palette,0x0F,0x05); get_colour_palette(palette,0x0F,0x05);
break; break;
} }
case 0x2B:
{
/* Mega Man V (USA) */
get_colour_palette(palette,0x0F,0x05);
break;
}
case 0x34: case 0x34:
{ {
/* Game Boy Gallery (Japan) */ /* Game Boy Gallery (Japan) */
@@ -819,6 +826,12 @@ void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const ch
get_colour_palette(palette,0x0B,0x05); get_colour_palette(palette,0x0B,0x05);
break; break;
} }
case 0x50:
{
/* Castlevania II - Belmont's Revenge (USA, Europe) */
get_colour_palette(palette,0x0C,0x05);
break;
}
case 0x52: case 0x52:
{ {
/* Street Fighter II (USA, Europe) (Rev A) */ /* Street Fighter II (USA, Europe) (Rev A) */
@@ -913,6 +926,7 @@ void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const ch
} }
case 0x6B: case 0x6B:
{ {
/* Castlevania Adventure, The (USA) */
/* Donkey Kong Land III (USA, Europe) */ /* Donkey Kong Land III (USA, Europe) */
/* Donkey Kong Land III (USA, Europe) (Rev A) */ /* Donkey Kong Land III (USA, Europe) (Rev A) */
get_colour_palette(palette,0x0C,0x05); get_colour_palette(palette,0x0C,0x05);
@@ -1214,9 +1228,9 @@ void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const ch
} }
default: default:
{ {
printf("auto_assign_palette: No palette found for checksum 0x%02X.\n", game_checksum); printf("E auto_assign_palette: No palette found for checksum 0x%02X.\n", game_checksum);
/* B + Left (Game Boy Pocket Palette, monochrome, 4 shades of white) */ /* Original Game Boy DMG color palette (monochrome 4-shades of green!) */
get_colour_palette(palette,0x16,0x00); get_colour_palette(palette,0xFF,0xFF);
break; break;
} }
} }
@@ -1238,7 +1252,7 @@ void auto_assign_palette(uint16_t palette[3][4], uint8_t game_checksum, const ch
*/ */
void manual_assign_palette(palette_t palette, uint8_t selection) void manual_assign_palette(palette_t palette, uint8_t selection)
{ {
printf("manual_assign_palette(%d)\n", selection); printf("I manual_assign_palette(%d)\n", selection);
switch(selection) switch(selection)
{ {
case 0: case 0:
@@ -1267,7 +1281,7 @@ void manual_assign_palette(palette_t palette, uint8_t selection)
} }
case 4: case 4:
{ {
/* B + Left (DMG Palette) */ /* B + Left Game Boy Pocket (monochrome 4-shades of white) */
get_colour_palette(palette,0x16,0x00); get_colour_palette(palette,0x16,0x00);
break; break;
} }
@@ -1315,21 +1329,15 @@ void manual_assign_palette(palette_t palette, uint8_t selection)
} }
case 12: case 12:
{ {
/* Original Game Boy DMG color palette (monochrome 4-shades of green!) */ /* A + B Original Game Boy DMG color palette (monochrome 4-shades of green!) */
const palette_t selected_palette = get_colour_palette(palette,0xFF,0xFF);
{
{ 0x9DE1, 0x8D61, 0x3306, 0x09C1 }, // OBJ0
{ 0x9DE1, 0x8D61, 0x3306, 0x09C1 }, // OBJ1
{ 0x9DE1, 0x8D61, 0x3306, 0x09C1 } // BG
};
memcpy(palette, selected_palette, PALETTE_SIZE_IN_BYTES);
break; break;
} }
default: default:
{ {
/* B + Left (Game Boy Pocket Palette, monochrome, 4 shades of white) */ /* Original Game Boy DMG color palette (monochrome 4-shades of green!) */
get_colour_palette(palette,0x16,0x00); get_colour_palette(palette,0xFF,0xFF);
break; break;
} }
} }
} }
+25 -2
View File
@@ -16,6 +16,7 @@
// Peanut-GB emulator settings // Peanut-GB emulator settings
#define ENABLE_LCD 1 #define ENABLE_LCD 1
#define ENABLE_SOUND 1 #define ENABLE_SOUND 1
#define ENABLE_SDCARD 1
#define PEANUT_GB_HIGH_LCD_ACCURACY 1 #define PEANUT_GB_HIGH_LCD_ACCURACY 1
#define PEANUT_GB_USE_BIOS 0 #define PEANUT_GB_USE_BIOS 0
@@ -370,12 +371,14 @@ void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[LCD_WIDTH],
} }
#endif #endif
#if ENABLE_SDCARD
void read_cart_ram_file(struct gb_s *gb) { void read_cart_ram_file(struct gb_s *gb) {
/* Load Save File. */ /* Load Save File. */
char filename[16]; char filename[16];
uint_fast32_t save_size; uint_fast32_t save_size;
UINT bw; UINT bw;
gb_get_rom_name(gb,filename);
save_size=gb_get_save_size(gb); save_size=gb_get_save_size(gb);
if(save_size>0) { if(save_size>0) {
sd_card_t *pSD=sd_get_by_num(0); sd_card_t *pSD=sd_get_by_num(0);
@@ -385,7 +388,6 @@ void read_cart_ram_file(struct gb_s *gb) {
return; return;
} }
gb_get_rom_name(gb,filename);
FIL fil; FIL fil;
fr=f_open(&fil,filename,FA_READ); fr=f_open(&fil,filename,FA_READ);
if (fr==FR_OK) { if (fr==FR_OK) {
@@ -400,6 +402,22 @@ void read_cart_ram_file(struct gb_s *gb) {
} }
f_unmount(pSD->pcName); f_unmount(pSD->pcName);
} }
/** Set the RTC of the game cartridge. Only used by games that support it.
* You could potentially force the game to allow the player to
* reset the time by setting the RTC to invalid values.
*
* Using memset(&gb->cart_rtc, 0xFF, sizeof(gb->cart_rtc)) for
* example causes Pokemon Gold/Silver to say "TIME NOT SET",
* allowing the player to set the time without having some dumb
* password.
*
* The memset has to be done directly to gb->cart_rtc because
* gb_set_rtc() processes the input values, which may cause
* games to not detect invalid values.
*/
memset(gb->cart_rtc, 0xFF, sizeof(gb->cart_rtc));
printf("read_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size); printf("read_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size);
} }
@@ -434,6 +452,7 @@ void write_cart_ram_file(struct gb_s *gb) {
} }
printf("write_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size); printf("write_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size);
} }
#endif
int main(void) int main(void)
{ {
@@ -454,7 +473,7 @@ int main(void)
/* Initialise USB serial connection for debugging. */ /* Initialise USB serial connection for debugging. */
stdio_init_all(); stdio_init_all();
time_init(); time_init();
sleep_ms(500); // sleep_ms(5000);
putstdio("INIT: "); putstdio("INIT: ");
/* Initialise GPIO pins. */ /* Initialise GPIO pins. */
@@ -517,8 +536,10 @@ int main(void)
goto sleep; goto sleep;
} }
#if ENABLE_SDCARD
/* Load Save File. */ /* Load Save File. */
read_cart_ram_file(&gb); read_cart_ram_file(&gb);
#endif
/* Update buttons state */ /* Update buttons state */
gb.direct.joypad_bits.up=gpio_get(GPIO_UP); gb.direct.joypad_bits.up=gpio_get(GPIO_UP);
@@ -669,7 +690,9 @@ int main(void)
} }
#endif #endif
if(!gb.direct.joypad_bits.start && prev_joypad_bits.start) { if(!gb.direct.joypad_bits.start && prev_joypad_bits.start) {
#if ENABLE_SDCARD
write_cart_ram_file(&gb); write_cart_ram_file(&gb);
#endif
gb_reset(&gb); gb_reset(&gb);
} }
} }
+2733
View File
File diff suppressed because it is too large Load Diff