From 72be66414d82495b28637f1f248aed50879c41ba Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Thu, 23 May 2019 15:54:39 -0500 Subject: [PATCH 01/11] libretro: jni: Switch stl to c++ in preparation for ndk r20 --- libretro/jni/Application.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro/jni/Application.mk b/libretro/jni/Application.mk index 219fdf2..a169e74 100644 --- a/libretro/jni/Application.mk +++ b/libretro/jni/Application.mk @@ -1,2 +1,2 @@ -APP_STL := gnustl_static +APP_STL := c++_static APP_ABI := all From eb95f1de5598807b07d5ee59771515d6aacc1d6e Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Tue, 16 Jul 2019 23:14:26 +0300 Subject: [PATCH 02/11] Fixed a bug where the SDL port loaded the incorrect boot ROM for SGB2. Made SameBoy compatible with older SDL versions. --- SDL/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SDL/main.c b/SDL/main.c index df6837f..ba2a5fb 100755 --- a/SDL/main.c +++ b/SDL/main.c @@ -23,6 +23,11 @@ #define AUDIO_FREQUENCY 48000 #endif +/* Compatibility with older SDL versions */ +#ifndef SDL_AUDIO_ALLOW_SAMPLES_CHANGE +#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0 +#endif + GB_gameboy_t gb; static bool paused = false; static uint32_t pixel_buffer_1[256 * 224], pixel_buffer_2[256 * 224]; @@ -464,7 +469,7 @@ restart: start_capturing_logs(); const char * const boot_roms[] = {"dmg_boot.bin", "cgb_boot.bin", "agb_boot.bin", "sgb_boot.bin"}; const char *boot_rom = boot_roms[configuration.model]; - if (configuration.model == GB_MODEL_SGB && configuration.sgb_revision == SGB_2) { + if (configuration.model == MODEL_SGB && configuration.sgb_revision == SGB_2) { boot_rom = "sgb2_boot.bin"; } error = GB_load_boot_rom(&gb, resource_path(boot_rom)); From 11a9f1df21288e2d46cbcb224e60fc4ff8816fd2 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Tue, 16 Jul 2019 23:27:35 +0300 Subject: [PATCH 03/11] Silence some GCC warnings --- Core/gb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index dec32a9..94e4d57 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -21,7 +21,7 @@ void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args) { char *string = NULL; - vasprintf(&string, fmt, args); + (void)vasprintf(&string, fmt, args); if (string) { if (gb->log_callback) { gb->log_callback(gb, string, attributes); @@ -158,9 +158,12 @@ int GB_load_boot_rom(GB_gameboy_t *gb, const char *path) GB_log(gb, "Could not open boot ROM: %s.\n", strerror(errno)); return errno; } - fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f); + int ret = 0; + if (fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f) != 1) { + ret = -1; + } fclose(f); - return 0; + return ret; } void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer, size_t size) @@ -193,7 +196,7 @@ int GB_load_rom(GB_gameboy_t *gb, const char *path) } gb->rom = malloc(gb->rom_size); memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */ - fread(gb->rom, gb->rom_size, 1, f); + (void) fread(gb->rom, gb->rom_size, 1, f); fclose(f); GB_configure_cart(gb); From 9efd20d7cd17eb9b9d1756998f360b6f01b9cc90 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Tue, 16 Jul 2019 23:33:07 +0300 Subject: [PATCH 04/11] Revert "Silence some GCC warnings" This reverts commit 11a9f1df21288e2d46cbcb224e60fc4ff8816fd2. --- Core/gb.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index 94e4d57..dec32a9 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -21,7 +21,7 @@ void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args) { char *string = NULL; - (void)vasprintf(&string, fmt, args); + vasprintf(&string, fmt, args); if (string) { if (gb->log_callback) { gb->log_callback(gb, string, attributes); @@ -158,12 +158,9 @@ int GB_load_boot_rom(GB_gameboy_t *gb, const char *path) GB_log(gb, "Could not open boot ROM: %s.\n", strerror(errno)); return errno; } - int ret = 0; - if (fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f) != 1) { - ret = -1; - } + fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f); fclose(f); - return ret; + return 0; } void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer, size_t size) @@ -196,7 +193,7 @@ int GB_load_rom(GB_gameboy_t *gb, const char *path) } gb->rom = malloc(gb->rom_size); memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */ - (void) fread(gb->rom, gb->rom_size, 1, f); + fread(gb->rom, gb->rom_size, 1, f); fclose(f); GB_configure_cart(gb); From 1bf5fb208f20b4338a75d58d278515c038f23138 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Tue, 16 Jul 2019 23:41:05 +0300 Subject: [PATCH 05/11] Silence an unwanted GCC warning --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 401fa3a..a835470 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ OPEN_DIALOG = OpenDialog/cocoa.m endif -CFLAGS += -Werror -Wall -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES +CFLAGS += -Werror -Wall -Wno-unused-result -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES SDL_LDFLAGS := -lSDL2 -lGL ifeq ($(PLATFORM),windows32) CFLAGS += -IWindows -Drandom=rand From 4504de828a188b520a324687a1181af6c45a7e3a Mon Sep 17 00:00:00 2001 From: Damian Yerrick Date: Tue, 16 Jul 2019 16:58:16 -0400 Subject: [PATCH 06/11] cgb_boot: Compress logo with PB8 The logo is compressed using PB8, a form of RLE with unary-coded run lengths. Each block representing 8 bytes consists of a control byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat previous, followed by the literals in that block. PB8 compression is also used in a few NES games. A variant called PB16, where 1 means repeat 2 bytes back, is used in the Game Boy port of 240p Test Suite and in Libbet and the Magic Floor. Switching from logo-compress RLE to PB8 decreases the compressed logo data size from 287 bytes to 253 bytes, saving 34 bytes. The decompression code is also about 10 bytes smaller. --- BootROMs/cgb_boot.asm | 78 ++++++---- BootROMs/pb8.c | 330 ++++++++++++++++++++++++++++++++++++++++++ Makefile | 24 +-- 3 files changed, 389 insertions(+), 43 deletions(-) create mode 100644 BootROMs/pb8.c diff --git a/BootROMs/cgb_boot.asm b/BootROMs/cgb_boot.asm index 0472cbe..6ae869b 100644 --- a/BootROMs/cgb_boot.asm +++ b/BootROMs/cgb_boot.asm @@ -532,7 +532,7 @@ TrademarkSymbol: db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c SameBoyLogo: - incbin "SameBoyLogo.rle" + incbin "SameBoyLogo.pb8" AnimationColors: dw $7FFF ; White @@ -634,41 +634,55 @@ ReadCGBLogoHalfTile: ld a, e ret +; LoadTileset using PB8 codec, 2019 Damian Yerrick +; +; The logo is compressed using PB8, a form of RLE with unary-coded +; run lengths. Each block representing 8 bytes consists of a control +; byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat +; previous, followed by the literals in that block. + +SameBoyLogo_dst = $8080 +SameBoyLogo_length = (128 * 24) / 64 + LoadTileset: -; Copy SameBoy Logo - ld de, SameBoyLogo - ld hl, $8080 -.sameboyLogoLoop - ld a, [de] - inc de - - ld b, a - and $0f - jr z, .skipLiteral - ld c, a - -.literalLoop - ld a, [de] - ldi [hl], a + ld hl, SameBoyLogo + ld de, SameBoyLogo_dst + ld c, SameBoyLogo_length +.pb8BlockLoop: + ; Register map for PB8 decompression + ; HL: source address in boot ROM + ; DE: destination address in VRAM + ; A: Current literal value + ; B: Repeat bits, terminated by 1000... + ; C: Number of 8-byte blocks left in this block + ; Source address in HL lets the repeat bits go straight to B, + ; bypassing A and avoiding spilling registers to the stack. + ld b, [hl] inc hl - inc de - dec c - jr nz, .literalLoop -.skipLiteral - swap b - ld a, b - and $0f - jr z, .sameboyLogoEnd - ld c, a - ld a, [de] - inc de -.repeatLoop - ldi [hl], a - inc hl + ; Shift a 1 into lower bit of shift value. Once this bit + ; reaches the carry, B becomes 0 and the byte is over + scf + rl b + +.pb8BitLoop: + ; If not a repeat, load a literal byte + jr c,.pb8Repeat + ld a, [hli] +.pb8Repeat: + ; Decompressed data uses colors 0 and 1, so write once, inc twice + ld [de], a + inc de + inc de + sla b + jr nz, .pb8BitLoop + dec c - jr nz, .repeatLoop - jr .sameboyLogoLoop + jr nz, .pb8BlockLoop + +; End PB8 decoding. The rest uses HL as the destination + ld h, d + ld l, e .sameboyLogoEnd ; Copy (unresized) ROM logo diff --git a/BootROMs/pb8.c b/BootROMs/pb8.c new file mode 100644 index 0000000..03a196e --- /dev/null +++ b/BootROMs/pb8.c @@ -0,0 +1,330 @@ +/* + +PB8 compressor and decompressor + +Copyright 2019 Damian Yerrick + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +*/ + +#include +#include +#include +#include +#include +#include + +// For setting stdin/stdout to binary mode +#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) +#include +#define fd_isatty isatty +#elif defined (_WIN32) +#include +#include +#define fd_isatty _isatty +#endif + +/* + +; The logo is compressed using PB8, a form of RLE with unary-coded +; run lengths. Each block representing 8 bytes consists of a control +; byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat +; previous, followed by the literals in that block. + +SameBoyLogo_dst = $8080 +SameBoyLogo_length = (128 * 24) / 64 + +LoadTileset: + ld hl, SameBoyLogo + ld de, SameBoyLogo_dst + ld c, SameBoyLogo_length +.pb8BlockLoop: + ; Register map for PB8 decompression + ; HL: source address in boot ROM + ; DE: destination address in VRAM + ; A: Current literal value + ; B: Repeat bits, terminated by 1000... + ; C: Number of 8-byte blocks left in this block + ; Source address in HL lets the repeat bits go straight to B, + ; bypassing A and avoiding spilling registers to the stack. + ld b, [hl] + inc hl + + ; Shift a 1 into lower bit of shift value. Once this bit + ; reaches the carry, B becomes 0 and the byte is over + scf + rl b + +.pb8BitLoop: + ; If not a repeat, load a literal byte + jr c,.pb8Repeat + ld a, [hli] +.pb8Repeat: + ; Decompressed data uses colors 0 and 1, so write once, inc twice + ld [de], a + inc de + inc de + sla b + jr nz, .pb8BitLoop + + dec c + jr nz, .pb8BlockLoop + ret + +*/ + +/* Compressor and decompressor *************************************/ + +/** + * Compresses an input stream to PB8 data on an output stream. + * @param infp input stream + * @param outfp output stream + * @param blocklength size of an independent input block in bytes + * @return 0 for reaching infp end of file, or EOF for error + */ +int pb8(FILE *infp, FILE *outfp, size_t blocklength) { + blocklength >>= 3; // convert bytes to blocks + assert(blocklength > 0); + while (1) { + int last_byte = EOF; // value that never occurs in a file + for (size_t blkleft = blocklength; blkleft > 0; --blkleft) { + unsigned int control_byte = 0x0001; + unsigned char literals[8]; + size_t nliterals = 0; + while (control_byte < 0x100) { + int c = fgetc(infp); + if (c == EOF) break; + + control_byte <<= 1; + if (c == last_byte) { + control_byte |= 0x01; + } else { + literals[nliterals++] = last_byte = c; + } + } + if (control_byte > 1) { + // Fill partial block with repeats + while (control_byte < 0x100) { + control_byte = (control_byte << 1) | 1; + } + + // Write control byte and check for write failure + int ok = fputc(control_byte & 0xFF, outfp); + if (ok == EOF) return EOF; + size_t ok2 = fwrite(literals, 1, nliterals, outfp); + if (ok2 < nliterals) return EOF; + } + + // If finished, return success or failure + if (ferror(infp) || ferror(outfp)) return EOF; + if (feof(infp)) return 0; + } // End 8-byte block + } // End packet, resetting last_byte +} + +/** + * Decompresses PB8 data on an input stream to an output stream. + * @param infp input stream + * @param outfp output stream + * @return 0 for reaching infp end of file, or EOF for error + */ +int unpb8(FILE *infp, FILE *outfp) { + int last_byte = 0; + while (1) { + int control_byte = fgetc(infp); + if (control_byte == EOF) { + return feof(infp) ? 0 : EOF; + } + control_byte &= 0xFF; + for (size_t bytesleft = 8; bytesleft > 0; --bytesleft) { + if (!(control_byte & 0x80)) { + last_byte = fgetc(infp); + if (last_byte == EOF) return EOF; // read error + } + control_byte <<= 1; + int ok = fputc(last_byte, outfp); + if (ok == EOF) return EOF; + } + } +} + +/* CLI frontend ****************************************************/ + +static inline void set_fd_binary(unsigned int fd) { +#ifdef _WIN32 + _setmode(fd, _O_BINARY); +#else + (void) fd; +#endif +} + +static const char *usage_msg = +"usage: pb8 [-d] [-l blocklength] [infile [outfile]]\n" +"Compresses a file using RLE with unary run and literal lengths.\n" +"\n" +"options:\n" +" -d decompress\n" +" -l blocklength allow RLE packets to span up to blocklength\n" +" input bytes (multiple of 8; default 8)\n" +" -h, -?, --help show this usage page\n" +" --version show copyright info\n" +"\n" +"If infile is - or missing, it is standard input.\n" +"If outfile is - or missing, it is standard output.\n" +"You cannot compress to or decompress from a terminal.\n" +; +static const char *version_msg = +"PB8 compressor (C version) v0.01\n" +"Copyright 2019 Damian Yerrick \n" +"This software is provided 'as-is', without any express or implied\n" +"warranty.\n" +; +static const char *toomanyfilenames_msg = +"pb8: too many filenames; try pb8 --help\n"; + +int main(int argc, char **argv) { + const char *infilename = NULL; + const char *outfilename = NULL; + bool decompress = false; + size_t blocklength = 8; + + for (int i = 1; i < argc; ++i) { + if (argv[i][0] == '-' && argv[i][1] != 0) { + if (!strcmp(argv[i], "--help")) { + fputs(usage_msg, stdout); + return 0; + } + if (!strcmp(argv[i], "--version")) { + fputs(version_msg, stdout); + return 0; + } + + // -t1 or -t 1 + int argtype = argv[i][1]; + switch (argtype) { + case 'h': + case '?': + fputs(usage_msg, stdout); + return 0; + + case 'd': + decompress = true; + break; + + case 'l': { + const char *argvalue = argv[i][2] ? argv[i] + 2 : argv[++i]; + const char *endptr = NULL; + + unsigned long tvalue = strtoul(argvalue, (char **)&endptr, 10); + if (endptr == argvalue || tvalue == 0 || tvalue > SIZE_MAX) { + fprintf(stderr, "pb8: block length %s not a positive integer\n", + argvalue); + return EXIT_FAILURE; + } + if (tvalue % 8 != 0) { + fprintf(stderr, "pb8: block length %s not a multiple of 8\n", + argvalue); + return EXIT_FAILURE; + } + blocklength = tvalue; + } break; + + default: + fprintf(stderr, "pb8: unknown option -%c\n", argtype); + return EXIT_FAILURE; + } + } else if (!infilename) { + infilename = argv[i]; + } else if (!outfilename) { + outfilename = argv[i]; + } else { + fputs(toomanyfilenames_msg, stderr); + return EXIT_FAILURE; + } + } + if (infilename && !strcmp(infilename, "-")) { + infilename = NULL; + } + if (!infilename && decompress && fd_isatty(0)) { + fputs("pb8: cannot decompress from terminal; try redirecting stdin\n", + stderr); + return EXIT_FAILURE; + } + if (outfilename && !strcmp(outfilename, "-")) { + outfilename = NULL; + } + if (!outfilename && !decompress && fd_isatty(1)) { + fputs("pb8: cannot compress to terminal; try redirecting stdout or pb8 --help\n", + stderr); + return EXIT_FAILURE; + } + + FILE *infp = NULL; + if (infilename) { + infp = fopen(infilename, "rb"); + if (!infp) { + fprintf(stderr, "pb8: error opening %s ", infilename); + perror("for reading"); + return EXIT_FAILURE; + } + } else { + infp = stdin; + set_fd_binary(0); + } + + FILE *outfp = NULL; + if (outfilename) { + outfp = fopen(outfilename, "wb"); + if (!outfp) { + fprintf(stderr, "pb8: error opening %s ", outfilename); + perror("for writing"); + fclose(infp); + return EXIT_FAILURE; + } + } else { + outfp = stdout; + set_fd_binary(1); + } + + int compfailed = 0; + int has_ferror = 0; + if (decompress) { + compfailed = unpb8(infp, outfp); + } else { + compfailed = pb8(infp, outfp, blocklength); + } + fflush(outfp); + if (ferror(infp)) { + fprintf(stderr, "pb8: error reading %s\n", + infilename ? infilename : ""); + has_ferror = EOF; + } + fclose(infp); + if (ferror(outfp)) { + fprintf(stderr, "pb8: error writing %s\n", + outfilename ? outfilename : ""); + has_ferror = EOF; + } + fclose(outfp); + + if (compfailed && !has_ferror) { + fputs("pb8: unknown compression failure\n", stderr); + } + + return (compfailed || has_ferror) ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/Makefile b/Makefile index 401fa3a..5db8c42 100644 --- a/Makefile +++ b/Makefile @@ -13,13 +13,15 @@ ifneq ($(findstring MSYS,$(PLATFORM)),) PLATFORM := windows32 endif -LOGO_COMPRESS := build/logo-compress - ifeq ($(PLATFORM),windows32) _ := $(shell chcp 65001) -LOGO_COMPRESS := build/logo-compress.exe +EXESUFFIX:=.exe +else +EXESUFFIX:= endif +PB8_COMPRESS := build/pb8$(EXESUFFIX) + ifeq ($(PLATFORM),Darwin) DEFAULT := cocoa else @@ -302,11 +304,11 @@ $(BIN)/tester/sameboy_tester.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(BIN)/SDL/%.bin $(BIN)/tester/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SameBoy.app/Contents/Resources/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SDL/LICENSE: LICENSE -@$(MKDIR) -p $(dir $@) cp -f $^ $@ @@ -314,7 +316,7 @@ $(BIN)/SDL/LICENSE: LICENSE $(BIN)/SDL/registers.sym: Misc/registers.sym -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SDL/background.bmp: SDL/background.bmp -@$(MKDIR) -p $(dir $@) cp -f $^ $@ @@ -329,17 +331,17 @@ $(OBJ)/%.1bpp: %.png -@$(MKDIR) -p $(dir $@) rgbgfx -d 1 -h -o $@ $< -$(OBJ)/BootROMs/SameBoyLogo.rle: $(OBJ)/BootROMs/SameBoyLogo.1bpp $(LOGO_COMPRESS) - $(realpath $(LOGO_COMPRESS)) < $< > $@ +$(OBJ)/BootROMs/SameBoyLogo.pb8: $(OBJ)/BootROMs/SameBoyLogo.1bpp $(PB8_COMPRESS) + $(realpath $(PB8_COMPRESS)) -l 384 $< $@ -$(LOGO_COMPRESS): BootROMs/logo-compress.c +$(PB8_COMPRESS): BootROMs/pb8.c $(CC) $< -o $@ $(BIN)/BootROMs/agb_boot.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/cgb_boot_fast.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/sgb2_boot: BootROMs/sgb_boot.asm -$(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.rle +$(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.pb8 -@$(MKDIR) -p $(dir $@) rgbasm -i $(OBJ)/BootROMs/ -i BootROMs/ -o $@.tmp $< rgblink -o $@.tmp2 $@.tmp @@ -349,7 +351,7 @@ $(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.rle # Libretro Core (uses its own build system) libretro: $(MAKE) -C libretro - + # Clean clean: rm -rf build From 26cf9707137971dee988c69d0b5cd09a3f8f8673 Mon Sep 17 00:00:00 2001 From: Damian Yerrick Date: Tue, 16 Jul 2019 17:04:23 -0400 Subject: [PATCH 07/11] don't need logo-compress.c anymore --- BootROMs/logo-compress.c | 62 ---------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 BootROMs/logo-compress.c diff --git a/BootROMs/logo-compress.c b/BootROMs/logo-compress.c deleted file mode 100644 index 2274eb2..0000000 --- a/BootROMs/logo-compress.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#ifdef _WIN32 -#include -#include -#endif - -void pair(size_t count, uint8_t byte) -{ - static size_t unique_count = 0; - static uint8_t unique_data[15]; - if (count == 1) { - unique_data[unique_count++] = byte; - assert(unique_count <= 15); - } - else { - assert(count <= 15); - uint8_t control = (count << 4) | unique_count; - putchar(control); - - for (size_t i = 0; i < unique_count; i++) { - putchar(unique_data[i]); - } - - if (count != 0) { - putchar(byte); - } - else { - assert(control == 0); - } - - unique_count = 0; - } -} - -int main(int argc, char *argv[]) -{ - size_t count = 1; - uint8_t byte = getchar(); - int new; - size_t position = 0; - -#ifdef _WIN32 - _setmode(0,_O_BINARY); - _setmode(1,_O_BINARY); -#endif - - while ((new = getchar()) != EOF) { - if (byte == new) { - count++; - } - else { - pair(count, byte); - byte = new; - count = 1; - } - } - - pair(count, byte); - pair(0, 0); -} From 23ca39720626cf50ae90183ae3a50921d371ec55 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Wed, 17 Jul 2019 00:52:01 +0300 Subject: [PATCH 08/11] Remove unused flag --- libretro/jni/Application.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/libretro/jni/Application.mk b/libretro/jni/Application.mk index a169e74..a252a72 100644 --- a/libretro/jni/Application.mk +++ b/libretro/jni/Application.mk @@ -1,2 +1 @@ -APP_STL := c++_static APP_ABI := all From 597dc72e460f3e95caad40b8c557fb01f53f18ee Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Thu, 18 Jul 2019 00:13:41 +0300 Subject: [PATCH 09/11] Fix audio issues with some RetroArch audio drivers. Fixes #189 --- libretro/libretro.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libretro/libretro.c b/libretro/libretro.c index 1dd411c..bd93e97 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -84,7 +84,7 @@ static struct retro_log_callback logging; static retro_log_printf_t log_cb; static retro_video_refresh_t video_cb; -static retro_audio_sample_batch_t audio_batch_cb; +static retro_audio_sample_t audio_sample_cb; static retro_input_poll_t input_poll_cb; static retro_input_state_t input_state_cb; @@ -152,7 +152,7 @@ static void audio_callback(GB_gameboy_t *gb, GB_sample_t *sample) { if ((audio_out == GB_1 && gb == &gameboy[0]) || (audio_out == GB_2 && gb == &gameboy[1])) { - audio_batch_cb((void*)sample, 1); + audio_sample_cb(sample->left, sample->right); } } @@ -772,11 +772,11 @@ void retro_set_environment(retro_environment_t cb) void retro_set_audio_sample(retro_audio_sample_t cb) { + audio_sample_cb = cb; } void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { - audio_batch_cb = cb; } void retro_set_input_poll(retro_input_poll_t cb) @@ -850,8 +850,7 @@ void retro_run(void) } else { - int x = GB_run_frame(&gameboy[0]); - log_cb(RETRO_LOG_DEBUG, "%d\n", x); + GB_run_frame(&gameboy[0]); } if (emulated_devices == 2) From f0809a667fe1369809233589e17455d9599f4804 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 19 Jul 2019 15:50:36 +0300 Subject: [PATCH 10/11] Fixed a potential Cocoa crash when closing a window --- Cocoa/Document.m | 1 + Cocoa/GBViewMetal.m | 1 + 2 files changed, 2 insertions(+) diff --git a/Cocoa/Document.m b/Cocoa/Document.m index b99e4c8..a520d62 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -389,6 +389,7 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample) - (void)dealloc { [cameraSession stopRunning]; + self.view.gb = NULL; GB_free(&gb); if (cameraImage) { CVBufferRelease(cameraImage); diff --git a/Cocoa/GBViewMetal.m b/Cocoa/GBViewMetal.m index 9acb11e..94b4975 100644 --- a/Cocoa/GBViewMetal.m +++ b/Cocoa/GBViewMetal.m @@ -131,6 +131,7 @@ static const vector_float2 rect[] = - (void)drawInMTKView:(nonnull MTKView *)view { if (!(view.window.occlusionState & NSWindowOcclusionStateVisible)) return; + if (!self.gb) return; if (texture.width != GB_get_screen_width(self.gb) || texture.height != GB_get_screen_height(self.gb)) { [self allocateTextures]; From 33198fc7b7b800087f2a5e43bef49c4fa38f224b Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 19 Jul 2019 15:50:49 +0300 Subject: [PATCH 11/11] Give SGB its own conflict map --- Core/sm83_cpu.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index 12ca670..77248b5 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -33,6 +33,7 @@ static const GB_conflict_t cgb_conflict_map[0x80] = { /* Todo: most values not verified, and probably differ between revisions */ }; +/* Todo: verify on an MGB */ static const GB_conflict_t dmg_conflict_map[0x80] = { [GB_IO_IF] = GB_CONFLICT_WRITE_CPU, [GB_IO_LYC] = GB_CONFLICT_READ_OLD, @@ -40,7 +41,6 @@ static const GB_conflict_t dmg_conflict_map[0x80] = { [GB_IO_SCY] = GB_CONFLICT_READ_NEW, [GB_IO_STAT] = GB_CONFLICT_STAT_DMG, - /* Todo: these are GB_CONFLICT_READ_NEW on MGB/SGB2 */ [GB_IO_BGP] = GB_CONFLICT_PALETTE_DMG, [GB_IO_OBP0] = GB_CONFLICT_PALETTE_DMG, [GB_IO_OBP1] = GB_CONFLICT_PALETTE_DMG, @@ -51,6 +51,24 @@ static const GB_conflict_t dmg_conflict_map[0x80] = { [GB_IO_SCX] = GB_CONFLICT_READ_NEW, }; +/* Todo: Verify on an SGB1 */ +static const GB_conflict_t sgb_conflict_map[0x80] = { + [GB_IO_IF] = GB_CONFLICT_WRITE_CPU, + [GB_IO_LYC] = GB_CONFLICT_READ_OLD, + [GB_IO_LCDC] = GB_CONFLICT_READ_NEW, + [GB_IO_SCY] = GB_CONFLICT_READ_NEW, + [GB_IO_STAT] = GB_CONFLICT_STAT_DMG, + + [GB_IO_BGP] = GB_CONFLICT_READ_NEW, + [GB_IO_OBP0] = GB_CONFLICT_READ_NEW, + [GB_IO_OBP1] = GB_CONFLICT_READ_NEW, + + /* Todo: these were not verified at all */ + [GB_IO_WY] = GB_CONFLICT_READ_NEW, + [GB_IO_WX] = GB_CONFLICT_READ_NEW, + [GB_IO_SCX] = GB_CONFLICT_READ_NEW, +}; + static uint8_t cycle_read(GB_gameboy_t *gb, uint16_t addr) { if (gb->pending_cycles) { @@ -92,7 +110,17 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value) assert(gb->pending_cycles); GB_conflict_t conflict = GB_CONFLICT_READ_OLD; if ((addr & 0xFF80) == 0xFF00) { - conflict = (GB_is_cgb(gb)? cgb_conflict_map : dmg_conflict_map)[addr & 0x7F]; + const GB_conflict_t *map = NULL; + if (GB_is_cgb(gb)) { + map = cgb_conflict_map; + } + else if (GB_is_sgb(gb)) { + map = sgb_conflict_map; + } + else { + map = dmg_conflict_map; + } + conflict = map[addr & 0x7F]; } switch (conflict) { case GB_CONFLICT_READ_OLD: