Logging API can now mark log lines as logical errors or warning

This commit is contained in:
Lior Halphon
2026-10-04 23:51:39 +03:00
parent 557e84b883
commit b9672952d6
12 changed files with 54 additions and 45 deletions
+3 -3
View File
@@ -122,7 +122,7 @@ void GB_set_camera_update_request_callback(GB_gameboy_t *gb, GB_camera_update_re
GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
}
if (gb->camera_countdown > 0 && callback) {
GB_log(gb, "Camera update request callback set while camera was proccessing, clearing camera countdown.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "Camera update request callback set while camera was proccessing, clearing camera countdown.\n");
gb->camera_countdown = 0;
GB_camera_updated(gb);
}
@@ -154,7 +154,7 @@ void GB_camera_write_register(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
if (!(value & 1) && (gb->camera_registers[GB_CAMERA_SHOOT_AND_1D_FLAGS] & 1)) {
/* We don't support cancelling a camera shoot */
GB_log(gb, "ROM attempted to cancel camera shoot, which is currently not supported. The camera shoot will not be cancelled.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM attempted to cancel camera shoot, which is currently not supported. The camera shoot will not be cancelled.\n");
value |= 1;
}
@@ -162,7 +162,7 @@ void GB_camera_write_register(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
}
else {
if (addr >= 0x36) {
GB_log(gb, "Wrote invalid camera register %02x: %2x\n", addr, value);
GB_attributed_log(gb, GB_LOG_WARNING, "Wrote invalid camera register %02x: %2x\n", addr, value);
return;
}
gb->camera_registers[addr] = value;
+3 -3
View File
@@ -296,12 +296,12 @@ int GB_load_cheats(GB_gameboy_t *gb, const char *path, bool replace_existing)
goto error;
}
if (magic != LE32(CHEAT_MAGIC) && magic != BE32(CHEAT_MAGIC)) {
GB_log(gb, "The file is not a SameBoy cheat database");
GB_attributed_log(gb, GB_LOG_ERROR, "The file is not a SameBoy cheat database");
goto error;
}
if (struct_size != sizeof(GB_cheat_t)) {
GB_log(gb, "This cheat database is not compatible with this version of SameBoy");
GB_attributed_log(gb, GB_LOG_ERROR, "This cheat database is not compatible with this version of SameBoy");
goto error;
}
@@ -333,7 +333,7 @@ int GB_save_cheats(GB_gameboy_t *gb, const char *path)
if (!gb->cheat_count) return 0; // Nothing to save.
FILE *f = fopen(path, "wb");
if (!f) {
GB_log(gb, "Could not dump cheat database: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not dump cheat database: %s.\n", strerror(errno));
return errno;
}
+1 -1
View File
@@ -1717,7 +1717,7 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force)
display9: {
// TODO: Timing of things in this scenario is almost completely untested
if (gb->current_line < LINES && !GB_is_sgb(gb) && !gb->disable_rendering) {
GB_log(gb, "The ROM is preventing line %d from fully rendering, this could damage a real device's LCD display.\n", gb->current_line);
GB_attributed_log(gb, GB_LOG_WARNING, "The ROM is preventing line %d from fully rendering, this could damage a real device's LCD display.\n", gb->current_line);
uint32_t *dest = NULL;
if (gb->border_mode != GB_BORDER_ALWAYS) {
dest = gb->screen + gb->lcd_x + gb->current_line * WIDTH;
+5 -5
View File
@@ -256,7 +256,7 @@ int GB_load_boot_rom(GB_gameboy_t *gb, const char *path)
{
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open boot ROM: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open boot ROM: %s.\n", strerror(errno));
return errno;
}
fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f);
@@ -334,7 +334,7 @@ int GB_load_rom(GB_gameboy_t *gb, const char *path)
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open ROM: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open ROM: %s.\n", strerror(errno));
return errno;
}
fseek(f, 0, SEEK_END);
@@ -508,7 +508,7 @@ int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open GBS: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open GBS: %s.\n", strerror(errno));
return errno;
}
fseek(f, 0, SEEK_END);
@@ -529,7 +529,7 @@ int GB_load_isx(GB_gameboy_t *gb, const char *path)
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open ISX file: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open ISX file: %s.\n", strerror(errno));
return errno;
}
char magic[4];
@@ -901,7 +901,7 @@ int GB_save_battery(GB_gameboy_t *gb, const char *path)
if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
FILE *f = fopen(path, "wb");
if (!f) {
GB_log(gb, "Could not open battery save: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open battery save: %s.\n", strerror(errno));
return errno;
}
+5 -3
View File
@@ -235,10 +235,12 @@ enum {
static const typeof(GB_IO_PGB) __attribute__((deprecated("Use GB_IO_PGB instead"))) GB_IO_UNKNOWN5 = GB_IO_PGB;
typedef enum {
GB_LOG_BOLD = 1,
GB_LOG_BOLD = 1,
GB_LOG_DASHED_UNDERLINE = 2,
GB_LOG_UNDERLINE = 4,
GB_LOG_UNDERLINE_MASK = GB_LOG_DASHED_UNDERLINE | GB_LOG_UNDERLINE
GB_LOG_UNDERLINE = 4,
GB_LOG_UNDERLINE_MASK = GB_LOG_DASHED_UNDERLINE | GB_LOG_UNDERLINE,
GB_LOG_ERROR = 8, // This log line represents an error message for the currently executing API
GB_LOG_WARNING = 0x10, // This log line represents an warning message for the currently executing API
} GB_log_attributes_t;
typedef enum {
+5 -5
View File
@@ -172,7 +172,7 @@ void GB_configure_cart(GB_gameboy_t *gb)
gb->cartridge_type = maybe_mmm01_type;
}
else if (gb->rom[gb->rom_size - 0x8000 + 0x147] == 0x11) {
GB_log(gb, "ROM header reports MBC3, but it appears to be an MMM01 ROM. Assuming cartridge uses MMM01.");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM header reports MBC3, but it appears to be an MMM01 ROM. Assuming cartridge uses MMM01.");
gb->cartridge_type = &GB_cart_defs[0xB];
}
}
@@ -188,11 +188,11 @@ void GB_configure_cart(GB_gameboy_t *gb)
if (gb->cartridge_type->mbc_type != GB_MMM01) {
if (gb->rom[0x147] == 0 && gb->rom_size > 0x8000) {
GB_log(gb, "ROM header reports no MBC, but file size is over 32Kb. Assuming cartridge uses MBC3.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM header reports no MBC, but file size is over 32Kb. Assuming cartridge uses MBC3.\n");
gb->cartridge_type = &GB_cart_defs[0x11];
}
else if (gb->rom[0x147] != 0 && memcmp(gb->cartridge_type, &GB_cart_defs[0], sizeof(GB_cart_defs[0])) == 0) {
GB_log(gb, "Cartridge type %02x is not yet supported.\n", gb->rom[0x147]);
GB_attributed_log(gb, GB_LOG_WARNING, "Cartridge type %02x is not yet supported.\n", gb->rom[0x147]);
}
}
@@ -200,7 +200,7 @@ void GB_configure_cart(GB_gameboy_t *gb)
gb->cartridge_type->mbc_type != GB_NO_MBC &&
gb->cartridge_type->mbc_type != GB_TPP1 &&
gb->rom[0x149]) {
GB_log(gb, "ROM header reports no RAM, but also reports a non-zero RAM size. Assuming cartridge has RAM.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM header reports no RAM, but also reports a non-zero RAM size. Assuming cartridge has RAM.\n");
gb->cartridge_type++;
}
@@ -232,7 +232,7 @@ void GB_configure_cart(GB_gameboy_t *gb)
if (gb->mbc_ram_size && gb->mbc_ram_size < 0x2000 &&
gb->cartridge_type->mbc_type != GB_MBC2 &&
gb->cartridge_type->mbc_type != GB_MBC7) {
GB_log(gb, "This ROM requests a RAM size smaller than a bank, it may misbehave if this was not done intentionally.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "This ROM requests a RAM size smaller than a bank, it may misbehave if this was not done intentionally.\n");
}
if (gb->mbc_ram && old_mbc_ram_size != gb->mbc_ram_size) {
+1 -1
View File
@@ -370,7 +370,7 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
case 0xE: // IR mode
return gb->effective_ir_input; // TODO: What are the other bits?
default:
GB_log(gb, "Unsupported HuC-3 mode %x read: %04x\n", gb->huc3.mode, addr);
GB_attributed_log(gb, GB_LOG_WARNING, "Unsupported HuC-3 mode %x read: %04x\n", gb->huc3.mode, addr);
return 1; // TODO: What happens in this case?
case 0: // TODO: R/O RAM? (or is it disabled?)
case 0xA: // RAM
+16 -16
View File
@@ -310,33 +310,33 @@ static bool verify_and_update_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t
*attempt_bess = false;
if (gb->version != save->version) {
GB_log(gb, "The save state is for a different version of SameBoy.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state is for a different version of SameBoy.\n");
*attempt_bess = true;
return false;
}
if (GB_is_cgb(gb) != GB_is_cgb(save) || GB_is_hle_sgb(gb) != GB_is_hle_sgb(save)) {
GB_log(gb, "The save state is for a different Game Boy model. Try changing the emulated model.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state is for a different Game Boy model. Try changing the emulated model.\n");
return false;
}
if (gb->mbc_ram_size < save->mbc_ram_size) {
GB_log(gb, "The save state has non-matching MBC RAM size.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state has non-matching MBC RAM size.\n");
return false;
}
if (gb->vram_size != save->vram_size) {
GB_log(gb, "The save state has non-matching VRAM size. Try changing the emulated model.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state has non-matching VRAM size. Try changing the emulated model.\n");
return false;
}
if (GB_is_hle_sgb(gb) != GB_is_hle_sgb(save)) {
GB_log(gb, "The save state is %sfor a Super Game Boy. Try changing the emulated model.\n", GB_is_hle_sgb(save)? "" : "not ");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state is %sfor a Super Game Boy. Try changing the emulated model.\n", GB_is_hle_sgb(save)? "" : "not ");
return false;
}
if (gb->ram_size != save->ram_size) {
GB_log(gb, "The save state has non-matching RAM size. Try changing the emulated model.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state has non-matching RAM size. Try changing the emulated model.\n");
return false;
}
@@ -367,7 +367,7 @@ static bool verify_and_update_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t
return true;
}
GB_log(gb, "This save state is for an unknown Game Boy model\n");
GB_attributed_log(gb, GB_LOG_ERROR, "This save state is for an unknown Game Boy model\n");
return false;
}
@@ -865,7 +865,7 @@ int GB_save_state(GB_gameboy_t *gb, const char *path)
GB_ASSERT_NOT_RUNNING(gb)
FILE *f = fopen(path, "wb");
if (!f) {
GB_log(gb, "Could not open save state: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open save state: %s.\n", strerror(errno));
return errno;
}
virtual_file_t file = {
@@ -951,7 +951,7 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
if (footer.magic != BE32('BESS')) {
// Not a BESS file
if (!is_sameboy) {
GB_log(gb, "The file is not a save state, or is from an incompatible operating system.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The file is not a save state, or is from an incompatible operating system.\n");
}
return -1;
}
@@ -981,7 +981,7 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
}
if (core.major != LE16(1)) {
GB_log(gb, "This save state uses an incompatible version of the BESS specification");
GB_attributed_log(gb, GB_LOG_ERROR, "This save state uses an incompatible version of the BESS specification");
GB_free(&save);
return -1;
}
@@ -998,7 +998,7 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
break;
default:
wrong_model:
GB_log(gb, "The save state is for a different model. Try changing the emulated model.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "The save state is for a different model. Try changing the emulated model.\n");
GB_free(&save);
return -1;
}
@@ -1108,10 +1108,10 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
if (bess_info.title[i] < 0x20 || bess_info.title[i] > 0x7E) break;
ascii_title[i] = bess_info.title[i];
}
GB_log(gb, "Save state was made on another ROM: '%s'\n", ascii_title);
GB_attributed_log(gb, GB_LOG_ERROR, "Save state was made on another ROM: '%s'\n", ascii_title);
}
else if (memcmp(bess_info.checksum, bank + 0x14E, 2)) {
GB_log(gb, "Save state was potentially made on another revision of the same ROM.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "Save state was potentially made on another revision of the same ROM.\n");
}
break;
}
@@ -1294,10 +1294,10 @@ parse_error:
errno = -1;
error:
if (emulator_name[0]) {
GB_log(gb, "Attempted to import a save state from %s, but the save state is invalid.\n", emulator_name);
GB_attributed_log(gb, GB_LOG_ERROR, "Attempted to import a save state from %s, but the save state is invalid.\n", emulator_name);
}
else {
GB_log(gb, "Attempted to import a save state from a different emulator or incompatible version, but the save state is invalid.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "Attempted to import a save state from a different emulator or incompatible version, but the save state is invalid.\n");
}
GB_free(&save);
sanitize_state(gb);
@@ -1375,7 +1375,7 @@ int GB_load_state(GB_gameboy_t *gb, const char *path)
GB_ASSERT_NOT_RUNNING(gb)
FILE *f = fopen(path, "rb");
if (!f) {
GB_log(gb, "Could not open save state: %s.\n", strerror(errno));
GB_attributed_log(gb, GB_LOG_ERROR, "Could not open save state: %s.\n", strerror(errno));
return errno;
}
virtual_file_t file = {
+1 -1
View File
@@ -157,7 +157,7 @@ static void command_ready(GB_gameboy_t *gb)
checksum += gb->sgb->command[i];
}
if (checksum != gb->sgb->command[1]) {
GB_log(gb, "Failed checksum for SGB header command, disabling SGB features\n");
GB_attributed_log(gb, GB_LOG_WARNING, "Failed checksum for SGB header command, disabling SGB features\n");
gb->sgb->disable_commands = true;
return;
}
+3 -3
View File
@@ -345,7 +345,7 @@ static void flush_pending_cycles(GB_gameboy_t *gb)
static void ill(GB_gameboy_t *gb, uint8_t opcode)
{
GB_log(gb, "Illegal Opcode. Halting.\n");
GB_attributed_log(gb, GB_LOG_ERROR, "Illegal Opcode. Halting.\n");
gb->interrupt_enable = 0;
gb->halted = true;
}
@@ -410,7 +410,7 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
flush_pending_cycles(gb);
if (gb->io_registers[GB_IO_LCDC] & GB_LCDC_ENABLE && gb->cgb_double_speed) {
GB_log(gb, "ROM triggered a PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM triggered a PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
if (gb->double_speed_alignment & 7) {
gb->speed_switch_freeze = 2;
}
@@ -419,7 +419,7 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
GB_log(gb, "ROM triggered an APU odd mode, which is currently not tested.\n");
}
if (gb->cartridge_type->mbc_type == GB_CAMERA && (gb->camera_registers[GB_CAMERA_SHOOT_AND_1D_FLAGS] & 1) && !gb->cgb_double_speed) {
GB_log(gb, "ROM entered double speed mode with a camera cartridge, this could damage a real cartridge's camera.\n");
GB_attributed_log(gb, GB_LOG_WARNING, "ROM entered double speed mode with a camera cartridge, this could damage a real cartridge's camera.\n");
}
if (gb->cgb_double_speed) {
-1
View File
@@ -776,7 +776,6 @@ static void vblank(GB_gameboy_t *gb, GB_vblank_type_t type)
if (battery_dirty && !GB_get_battery_dirty(gb)) {
GB_save_battery(gb, battery_save_path_ptr);
GB_log(gb, "Saved\n");
}
battery_dirty = GB_get_battery_dirty(gb);
+11 -3
View File
@@ -132,15 +132,23 @@ static void gb_log_callback(GB_gameboy_t *gb, const char *string, GB_log_attribu
memcpy(gb_log_buffer + gb_log_buffer_length, string, length + 1);
gb_log_buffer_length += length;
enum retro_log_level level = RETRO_LOG_INFO;
if (attributes & GB_LOG_ERROR) {
level = RETRO_LOG_ERROR;
}
else if (attributes & GB_LOG_WARNING) {
level = RETRO_LOG_WARN;
}
if (length && string[length - 1] == '\n') {
if (emulated_devices == 1) {
log_cb(RETRO_LOG_INFO, "%s", gb_log_buffer);
log_cb(level, "%s", gb_log_buffer);
}
else if (gb == &gameboy[0]) {
log_cb(RETRO_LOG_INFO, "[Game Boy 1] %s", gb_log_buffer);
log_cb(level, "[Game Boy 1] %s", gb_log_buffer);
}
else {
log_cb(RETRO_LOG_INFO, "[Game Boy 2] %s", gb_log_buffer);
log_cb(level, "[Game Boy 2] %s", gb_log_buffer);
}
gb_log_buffer_length = 0;
free(gb_log_buffer);