diff --git a/Cocoa/Document.m b/Cocoa/Document.m index eef4c7a..e212306 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -1185,6 +1185,23 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @try { if (!cameraSession) { + if (@available(macOS 10.14, *)) { + switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) { + case AVAuthorizationStatusAuthorized: + break; + case AVAuthorizationStatusNotDetermined: { + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { + [self cameraRequestUpdate]; + }]; + return; + } + case AVAuthorizationStatusDenied: + case AVAuthorizationStatusRestricted: + GB_camera_updated(&gb); + return; + } + } + NSError *error; AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice: device error: &error]; diff --git a/Cocoa/Info.plist b/Cocoa/Info.plist index dd801cb..1c7bdb5 100644 --- a/Cocoa/Info.plist +++ b/Cocoa/Info.plist @@ -2,6 +2,8 @@ + CFBundleDisplayName + SameBoy CFBundleDevelopmentRegion en CFBundleDocumentTypes @@ -70,7 +72,7 @@ LSMinimumSystemVersion 10.9 NSHumanReadableCopyright - Copyright © 2015-2019 Lior Halphon + Copyright © 2015-2020 Lior Halphon NSMainNibFile MainMenu NSPrincipalClass @@ -116,6 +118,8 @@ + NSCameraUsageDescription + SameBoy needs to access your camera to emulate the Game Boy Camera NSSupportsAutomaticGraphicsSwitching diff --git a/Cocoa/License.html b/Cocoa/License.html index 49851fd..b21cf8d 100644 --- a/Cocoa/License.html +++ b/Cocoa/License.html @@ -30,7 +30,7 @@

SameBoy

MIT License

-

Copyright © 2015-2019 Lior Halphon

+

Copyright © 2015-2020 Lior Halphon

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Core/apu.c b/Core/apu.c index 3be92d6..9afa5c9 100644 --- a/Core/apu.c +++ b/Core/apu.c @@ -1008,7 +1008,7 @@ void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate) GB_apu_update_cycles_per_sample(gb); } -void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, unsigned cycles_per_sample) +void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, double cycles_per_sample) { if (cycles_per_sample == 0) { diff --git a/Core/apu.h b/Core/apu.h index ee6055b..885e0ce 100644 --- a/Core/apu.h +++ b/Core/apu.h @@ -148,7 +148,7 @@ typedef struct { } GB_apu_output_t; void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate); -void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, unsigned cycles_per_sample); /* Cycles are in 8MHz units */ +void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, double cycles_per_sample); /* Cycles are in 8MHz units */ void GB_set_highpass_filter_mode(GB_gameboy_t *gb, GB_highpass_mode_t mode); void GB_apu_set_sample_callback(GB_gameboy_t *gb, GB_sample_callback_t callback); #ifdef GB_INTERNAL diff --git a/Core/debugger.c b/Core/debugger.c index ab0097f..74be9f7 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -819,7 +819,7 @@ static bool registers(GB_gameboy_t *gb, char *arguments, char *modifiers, const GB_log(gb, "AF = $%04x (%c%c%c%c)\n", gb->registers[GB_REGISTER_AF], /* AF can't really be an address */ (gb->f & GB_CARRY_FLAG)? 'C' : '-', (gb->f & GB_HALF_CARRY_FLAG)? 'H' : '-', - (gb->f & GB_SUBSTRACT_FLAG)? 'N' : '-', + (gb->f & GB_SUBTRACT_FLAG)? 'N' : '-', (gb->f & GB_ZERO_FLAG)? 'Z' : '-'); GB_log(gb, "BC = %s\n", value_to_string(gb, gb->registers[GB_REGISTER_BC], false)); GB_log(gb, "DE = %s\n", value_to_string(gb, gb->registers[GB_REGISTER_DE], false)); diff --git a/Core/gb.c b/Core/gb.c index 93ac9d7..f29d400 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -18,6 +18,13 @@ #define GB_rewind_push(...) #endif + +static inline uint32_t state_magic(void) +{ + if (sizeof(bool) == 1) return 'SAME'; + return 'S4ME'; +} + void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args) { char *string = NULL; @@ -660,7 +667,7 @@ void GB_disconnect_serial(GB_gameboy_t *gb) bool GB_is_inited(GB_gameboy_t *gb) { - return gb->magic == 'SAME'; + return gb->magic == state_magic(); } bool GB_is_cgb(GB_gameboy_t *gb) @@ -929,7 +936,7 @@ void GB_reset(GB_gameboy_t *gb) gb->nontrivial_jump_state = NULL; } - gb->magic = (uintptr_t)'SAME'; + gb->magic = state_magic(); } void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model) diff --git a/Core/gb.h b/Core/gb.h index a66beed..e175667 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -98,7 +98,7 @@ enum { enum { GB_CARRY_FLAG = 16, GB_HALF_CARRY_FLAG = 32, - GB_SUBSTRACT_FLAG = 64, + GB_SUBTRACT_FLAG = 64, GB_ZERO_FLAG = 128, }; @@ -278,10 +278,6 @@ typedef struct { This struct is not packed, but dumped sections exclusively use types that have the same alignment in both 32 and 64 bit platforms. */ -/* We make sure bool is 1 for cross-platform save state compatibility. */ -/* Todo: We might want to typedef our own bool if this prevents SameBoy from working on specific platforms. */ -_Static_assert(sizeof(bool) == 1, "sizeof(bool) != 1"); - #ifdef GB_INTERNAL struct GB_gameboy_s { #else diff --git a/Core/memory.c b/Core/memory.c index 9994343..83c1be0 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -422,6 +422,11 @@ static GB_read_function_t * const read_map[] = read_ram, read_high_memory, /* EXXX FXXX */ }; +void GB_set_read_memory_callback(GB_gameboy_t *gb, GB_read_memory_callback_t callback) +{ + gb->read_memory_callback = callback; +} + uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr) { if (gb->n_watchpoints) { @@ -745,7 +750,11 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) return; case GB_IO_JOYP: - if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) { + if (gb->joyp_write_callback) { + gb->joyp_write_callback(gb, value); + GB_update_joyp(gb); + } + else if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) { GB_sgb_write(gb, value); gb->io_registers[GB_IO_JOYP] = value & 0xF0; GB_update_joyp(gb); diff --git a/Core/sgb.c b/Core/sgb.c index 8539238..7ebeae0 100644 --- a/Core/sgb.c +++ b/Core/sgb.c @@ -385,11 +385,7 @@ static void command_ready(GB_gameboy_t *gb) } void GB_sgb_write(GB_gameboy_t *gb, uint8_t value) -{ - if (gb->joyp_write_callback) { - gb->joyp_write_callback(gb, value); - } - +{ if (!GB_is_sgb(gb)) return; if (!GB_is_hle_sgb(gb)) { /* Notify via callback */ diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index 77248b5..0009a69 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -318,7 +318,7 @@ static void inc_hr(GB_gameboy_t *gb, uint8_t opcode) uint8_t register_id; register_id = ((opcode >> 4) + 1) & 0x03; gb->registers[register_id] += 0x100; - gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); if ((gb->registers[register_id] & 0x0F00) == 0) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; @@ -334,7 +334,7 @@ static void dec_hr(GB_gameboy_t *gb, uint8_t opcode) register_id = ((opcode >> 4) + 1) & 0x03; gb->registers[register_id] -= 0x100; gb->registers[GB_REGISTER_AF] &= ~(GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); - gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; if ((gb->registers[register_id] & 0x0F00) == 0xF00) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; @@ -396,7 +396,7 @@ static void add_hl_rr(GB_gameboy_t *gb, uint8_t opcode) register_id = (opcode >> 4) + 1; rr = gb->registers[register_id]; gb->registers[GB_REGISTER_HL] = hl + rr; - gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_CARRY_FLAG | GB_HALF_CARRY_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_SUBTRACT_FLAG | GB_CARRY_FLAG | GB_HALF_CARRY_FLAG); /* The meaning of the Half Carry flag is really hard to track -_- */ if (((hl & 0xFFF) + (rr & 0xFFF)) & 0x1000) { @@ -432,7 +432,7 @@ static void inc_lr(GB_gameboy_t *gb, uint8_t opcode) value = (gb->registers[register_id] & 0xFF) + 1; gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value; - gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); if ((gb->registers[register_id] & 0x0F) == 0) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; @@ -452,7 +452,7 @@ static void dec_lr(GB_gameboy_t *gb, uint8_t opcode) gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value; gb->registers[GB_REGISTER_AF] &= ~(GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); - gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; if ((gb->registers[register_id] & 0x0F) == 0xF) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; @@ -533,7 +533,7 @@ static void daa(GB_gameboy_t *gb, uint8_t opcode) gb->registers[GB_REGISTER_AF] &= ~(0xFF00 | GB_ZERO_FLAG); - if (gb->registers[GB_REGISTER_AF] & GB_SUBSTRACT_FLAG) { + if (gb->registers[GB_REGISTER_AF] & GB_SUBTRACT_FLAG) { if (gb->registers[GB_REGISTER_AF] & GB_HALF_CARRY_FLAG) { result = (result - 0x06) & 0xFF; } @@ -567,19 +567,19 @@ static void daa(GB_gameboy_t *gb, uint8_t opcode) static void cpl(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] ^= 0xFF00; - gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG | GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG; } static void scf(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] |= GB_CARRY_FLAG; - gb->registers[GB_REGISTER_AF] &= ~(GB_HALF_CARRY_FLAG | GB_SUBSTRACT_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG); } static void ccf(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] ^= GB_CARRY_FLAG; - gb->registers[GB_REGISTER_AF] &= ~(GB_HALF_CARRY_FLAG | GB_SUBSTRACT_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG); } static void ld_dhli_a(GB_gameboy_t *gb, uint8_t opcode) @@ -610,7 +610,7 @@ static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode) value = cycle_read(gb, gb->registers[GB_REGISTER_HL]) + 1; cycle_write(gb, gb->registers[GB_REGISTER_HL], value); - gb->registers[GB_REGISTER_AF] &= ~(GB_SUBSTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); + gb->registers[GB_REGISTER_AF] &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); if ((value & 0x0F) == 0) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; } @@ -627,7 +627,7 @@ static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode) cycle_write(gb, gb->registers[GB_REGISTER_HL], value); gb->registers[GB_REGISTER_AF] &= ~( GB_ZERO_FLAG | GB_HALF_CARRY_FLAG); - gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; if ((value & 0x0F) == 0x0F) { gb->registers[GB_REGISTER_AF] |= GB_HALF_CARRY_FLAG; } @@ -763,7 +763,7 @@ static void sub_a_r(GB_gameboy_t *gb, uint8_t opcode) uint8_t value, a; value = get_src_value(gb, opcode); a = gb->registers[GB_REGISTER_AF] >> 8; - gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBTRACT_FLAG; if (a == value) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; } @@ -781,7 +781,7 @@ static void sbc_a_r(GB_gameboy_t *gb, uint8_t opcode) value = get_src_value(gb, opcode); a = gb->registers[GB_REGISTER_AF] >> 8; carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0; - gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBTRACT_FLAG; if ((uint8_t) (a - value - carry) == 0) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; @@ -833,7 +833,7 @@ static void cp_a_r(GB_gameboy_t *gb, uint8_t opcode) value = get_src_value(gb, opcode); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] &= 0xFF00; - gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; if (a == value) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; } @@ -962,7 +962,7 @@ static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode) uint8_t value, a; value = cycle_read_inc_oam_bug(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; - gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBTRACT_FLAG; if (a == value) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; } @@ -980,7 +980,7 @@ static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode) value = cycle_read_inc_oam_bug(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0; - gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBTRACT_FLAG; if ((uint8_t) (a - value - carry) == 0) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; @@ -1032,7 +1032,7 @@ static void cp_a_d8(GB_gameboy_t *gb, uint8_t opcode) value = cycle_read_inc_oam_bug(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] &= 0xFF00; - gb->registers[GB_REGISTER_AF] |= GB_SUBSTRACT_FLAG; + gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; if (a == value) { gb->registers[GB_REGISTER_AF] |= GB_ZERO_FLAG; } diff --git a/LICENSE b/LICENSE index 94966be..17619e9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2015-2019 Lior Halphon +Copyright (c) 2015-2020 Lior Halphon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index cc6cae4..ca4c313 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ifeq ($(MAKECMDGOALS),) MAKECMDGOALS := $(DEFAULT) endif -VERSION := 0.12.2 +VERSION := 0.12.3 export VERSION CONF ?= debug @@ -51,10 +51,15 @@ endif # Use clang if it's available. ifeq ($(origin CC),default) ifneq (, $(shell which clang)) -CC := clang +CC := clang endif endif +# Find libraries with pkg-config if available. +ifneq (, $(shell which pkg-config)) +PKG_CONFIG := pkg-config +endif + ifeq ($(PLATFORM),windows32) # To force use of the Unix version instead of the Windows version MKDIR := $(shell which mkdir) @@ -71,9 +76,11 @@ endif # Set compilation and linkage flags based on target, platform and configuration OPEN_DIALOG = OpenDialog/gtk.c +NULL := /dev/null ifeq ($(PLATFORM),windows32) OPEN_DIALOG = OpenDialog/windows.c +NULL := NUL endif ifeq ($(PLATFORM),Darwin) @@ -82,21 +89,35 @@ endif 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 (,$(PKG_CONFIG)) +SDL_CFLAGS := $(shell sdl2-config --cflags) +SDL_LDFLAGS := $(shell sdl2-config --libs) +else +SDL_CFLAGS := $(shell $(PKG_CONFIG) --cflags sdl2) +SDL_LDFLAGS := $(shell $(PKG_CONFIG) --libs sdl2) +endif +ifeq (,$(PKG_CONFIG)) +GL_LDFLAGS := -lGL +else +GL_CFLAGS := $(shell $(PKG_CONFIG) --cflags gl) +GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL) +endif ifeq ($(PLATFORM),windows32) CFLAGS += -IWindows -Drandom=rand -LDFLAGS += -lmsvcrt -lcomdlg32 -lSDL2main -Wl,/MANIFESTFILE:NUL -SDL_LDFLAGS := -lSDL2 -lopengl32 +LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lSDL2main -Wl,/MANIFESTFILE:NUL +SDL_LDFLAGS := -lSDL2 +GL_LDFLAGS := -lopengl32 else LDFLAGS += -lc -lm -ldl endif ifeq ($(PLATFORM),Darwin) -SYSROOT := $(shell xcodebuild -sdk macosx -version Path 2> /dev/null) -CFLAGS += -F/Library/Frameworks -OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(SYSROOT) -mmacosx-version-min=10.9 -LDFLAGS += -framework AppKit -framework PreferencePanes -framework Carbon -framework QuartzCore -weak_framework Metal -weak_framework MetalKit -SDL_LDFLAGS := -F/Library/Frameworks -framework SDL2 -framework OpenGL +SYSROOT := $(shell xcodebuild -sdk macosx -version Path 2> $(NULL)) +CFLAGS += -F/Library/Frameworks -mmacosx-version-min=10.9 +OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(SYSROOT) +LDFLAGS += -framework AppKit -framework PreferencePanes -framework Carbon -framework QuartzCore -weak_framework Metal -weak_framework MetalKit -mmacosx-version-min=10.9 +SDL_LDFLAGS := -F/Library/Frameworks -framework SDL2 +GL_LDFLAGS := -framework OpenGL endif CFLAGS += -Wno-deprecated-declarations ifeq ($(PLATFORM),windows32) @@ -108,10 +129,16 @@ ifeq ($(CONF),debug) CFLAGS += -g else ifeq ($(CONF), release) CFLAGS += -O3 -DNDEBUG +STRIP := strip +ifeq ($(PLATFORM),Darwin) +LDFLAGS += -Wl,-exported_symbols_list,$(NULL) +STRIP := -@true +endif ifneq ($(PLATFORM),windows32) LDFLAGS += -flto CFLAGS += -flto endif + else $(error Invalid value for CONF: $(CONF). Use "debug", "release" or "native_release") endif @@ -169,6 +196,10 @@ ifneq ($(filter $(MAKECMDGOALS),cocoa),) endif endif +$(OBJ)/SDL/%.dep: SDL/% + -@$(MKDIR) -p $(dir $@) + $(CC) $(CFLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@ + $(OBJ)/%.dep: % -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@ @@ -179,6 +210,10 @@ $(OBJ)/Core/%.c.o: Core/%.c -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) -DGB_INTERNAL -c $< -o $@ +$(OBJ)/SDL/%.c.o: SDL/%.c + -@$(MKDIR) -p $(dir $@) + $(CC) $(CFLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@ + $(OBJ)/%.c.o: %.c -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) -c $< -o $@ @@ -220,7 +255,7 @@ $(BIN)/SameBoy.app/Contents/MacOS/SameBoy: $(CORE_OBJECTS) $(COCOA_OBJECTS) -@$(MKDIR) -p $(dir $@) $(CC) $^ -o $@ $(LDFLAGS) -framework OpenGL -framework AudioUnit -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework IOKit ifeq ($(CONF), release) - strip $@ + $(STRIP) $@ endif $(BIN)/SameBoy.app/Contents/Resources/Base.lproj/%.nib: Cocoa/%.xib @@ -240,10 +275,7 @@ $(BIN)/SameBoy.qlgenerator: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL # once in the QL Generator. It should probably become a dylib instead. $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL: $(CORE_OBJECTS) $(QUICKLOOK_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) -bundle -framework Cocoa -framework Quicklook -ifeq ($(CONF), release) - strip -u -r -s QuickLook/exports.sym $@ -endif + $(CC) $^ -o $@ $(LDFLAGS) -Wl,-exported_symbols_list,QuickLook/exports.sym -bundle -framework Cocoa -framework Quicklook # cgb_boot_fast.bin is not a standard boot ROM, we don't expect it to exist in the user-provided # boot ROM directory. @@ -256,19 +288,19 @@ $(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs # Unix versions build only one binary $(BIN)/SDL/sameboy: $(CORE_OBJECTS) $(SDL_OBJECTS) -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) + $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) ifeq ($(CONF), release) - strip $@ + $(STRIP) $@ endif # Windows version builds two, one with a conole and one without it $(BIN)/SDL/sameboy.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) -Wl,/subsystem:windows + $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:windows $(BIN)/SDL/sameboy_debugger.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o -@$(MKDIR) -p $(dir $@) - $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) -Wl,/subsystem:console + $(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:console ifneq ($(USE_WINDRES),) $(OBJ)/%.o: %.rc @@ -294,7 +326,7 @@ $(BIN)/tester/sameboy_tester: $(CORE_OBJECTS) $(TESTER_OBJECTS) -@$(MKDIR) -p $(dir $@) $(CC) $^ -o $@ $(LDFLAGS) ifeq ($(CONF), release) - strip $@ + $(STRIP) $@ endif $(BIN)/tester/sameboy_tester.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) @@ -345,7 +377,7 @@ $(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.pb8 -@$(MKDIR) -p $(dir $@) rgbasm -i $(OBJ)/BootROMs/ -i BootROMs/ -o $@.tmp $< rgblink -o $@.tmp2 $@.tmp - dd if=$@.tmp2 of=$@ count=1 bs=$(if $(findstring dmg,$@)$(findstring sgb,$@),256,2304) + dd if=$@.tmp2 of=$@ count=1 bs=$(if $(findstring dmg,$@)$(findstring sgb,$@),256,2304) 2> $(NULL) @rm $@.tmp $@.tmp2 # Libretro Core (uses its own build system) diff --git a/QuickLook/Info.plist b/QuickLook/Info.plist index 9540214..2cff196 100644 --- a/QuickLook/Info.plist +++ b/QuickLook/Info.plist @@ -47,7 +47,7 @@ CFPlugInUnloadFunction NSHumanReadableCopyright - Copyright © 2015-2019 Lior Halphon + Copyright © 2015-2020 Lior Halphon QLNeedsToBeRunInMainThread QLPreviewHeight diff --git a/QuickLook/exports.sym b/QuickLook/exports.sym index 778b203..f979687 100644 --- a/QuickLook/exports.sym +++ b/QuickLook/exports.sym @@ -1,3 +1,3 @@ _DeallocQuickLookGeneratorPluginType _QuickLookGeneratorQueryInterface -_QuickLookGeneratorPluginFactory \ No newline at end of file +_QuickLookGeneratorPluginFactory diff --git a/SDL/gui.c b/SDL/gui.c index 6cffeaf..db72c4d 100644 --- a/SDL/gui.c +++ b/SDL/gui.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include @@ -792,6 +792,7 @@ void connect_joypad(void) void run_gui(bool is_running) { + SDL_ShowCursor(SDL_ENABLE); connect_joypad(); /* Draw the background screen */ @@ -1011,6 +1012,15 @@ void run_gui(bool is_running) } case SDL_KEYDOWN: + if (event.key.keysym.scancode == SDL_SCANCODE_F && event.key.keysym.mod & MODIFIER) { + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == false) { + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + } + else { + SDL_SetWindowFullscreen(window, 0); + } + update_viewport(); + } if (event.key.keysym.scancode == SDL_SCANCODE_O) { if (event.key.keysym.mod & MODIFIER) { char *filename = do_open_rom_dialog(); diff --git a/SDL/gui.h b/SDL/gui.h index 6974849..b22c74f 100644 --- a/SDL/gui.h +++ b/SDL/gui.h @@ -1,7 +1,7 @@ #ifndef gui_h #define gui_h -#include +#include #include #include #include "shader.h" diff --git a/SDL/main.c b/SDL/main.c old mode 100755 new mode 100644 index ba2a5fb..1646d5c --- a/SDL/main.c +++ b/SDL/main.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include "utils.h" #include "gui.h" @@ -12,6 +12,7 @@ #ifndef _WIN32 #define AUDIO_FREQUENCY 96000 #else +#include /* Windows (well, at least my VM) can't handle 96KHz sound well :( */ /* felsqualle says: For SDL 2.0.6+ using the WASAPI driver, the highest freq. @@ -98,6 +99,7 @@ static void open_menu(void) SDL_PauseAudioDevice(device_id, 1); } run_gui(true); + SDL_ShowCursor(SDL_DISABLE); if (audio_playing) { SDL_ClearQueuedAudio(device_id); SDL_PauseAudioDevice(device_id, 0); @@ -123,7 +125,7 @@ static void handle_events(GB_gameboy_t *gb) } case SDL_WINDOWEVENT: { - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { update_viewport(); } break; @@ -273,6 +275,7 @@ static void handle_events(GB_gameboy_t *gb) else { SDL_SetWindowFullscreen(window, 0); } + update_viewport(); } break; @@ -406,14 +409,12 @@ static bool handle_pending_command(void) return false; } - case GB_SDL_RESET_COMMAND: - GB_save_battery(&gb, battery_save_path_ptr); - return true; - case GB_SDL_NO_COMMAND: return false; + case GB_SDL_RESET_COMMAND: case GB_SDL_NEW_FILE_COMMAND: + GB_save_battery(&gb, battery_save_path_ptr); return true; case GB_SDL_QUIT_COMMAND: @@ -425,6 +426,7 @@ static bool handle_pending_command(void) static void run(void) { + SDL_ShowCursor(SDL_DISABLE); GB_model_t model; pending_command = GB_SDL_NO_COMMAND; restart: @@ -550,6 +552,9 @@ static bool get_arg_flag(const char *flag, int *argc, char **argv) int main(int argc, char **argv) { +#ifdef _WIN32 + SetProcessDPIAware(); +#endif #define str(x) #x #define xstr(x) str(x) fprintf(stderr, "SameBoy v" xstr(VERSION) "\n"); diff --git a/SDL/opengl_compat.c b/SDL/opengl_compat.c index aed2a76..af7ce6d 100644 --- a/SDL/opengl_compat.c +++ b/SDL/opengl_compat.c @@ -1,5 +1,5 @@ #define GL_GLEXT_PROTOTYPES -#include +#include #ifndef __APPLE__ #define GL_COMPAT_NAME(func) gl_compat_##func diff --git a/SDL/opengl_compat.h b/SDL/opengl_compat.h index 9fd1ca9..15b2a17 100644 --- a/SDL/opengl_compat.h +++ b/SDL/opengl_compat.h @@ -2,8 +2,8 @@ #define opengl_compat_h #define GL_GLEXT_PROTOTYPES -#include -#include +#include +#include #ifndef __APPLE__ #define GL_COMPAT_NAME(func) gl_compat_##func diff --git a/SDL/utils.c b/SDL/utils.c index eee6ce6..8cdd00b 100644 --- a/SDL/utils.c +++ b/SDL/utils.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include "utils.h" diff --git a/Windows/resources.rc b/Windows/resources.rc index ffa8b3b..73c1213 100644 Binary files a/Windows/resources.rc and b/Windows/resources.rc differ diff --git a/libretro/libretro.c b/libretro/libretro.c index 6c1fcb6..9011233 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -92,6 +92,7 @@ static unsigned emulated_devices = 1; static bool initialized = false; static unsigned screen_layout = 0; static unsigned audio_out = 0; +static unsigned sgb_border = 1; static bool geometry_updated = false; static bool link_cable_emulation = false; @@ -209,6 +210,7 @@ static const struct retro_variable vars_single[] = { { "sameboy_color_correction_mode", "Color correction; off|correct curves|emulate hardware|preserve brightness" }, { "sameboy_high_pass_filter_mode", "High-pass filter; off|accurate|remove dc offset" }, { "sameboy_model", "Emulated model; Auto|Game Boy|Game Boy Color|Game Boy Advance|Super Game Boy|Super Game Boy 2" }, + { "sameboy_border", "Super Game Boy border; enabled|disabled" }, { NULL } }; @@ -430,21 +432,20 @@ static void init_for_current_model(unsigned id) descs[7].len = 0x4000; descs[7].flags = RETRO_MEMDESC_CONST; - descs[8].ptr = GB_get_direct_access(&gameboy[i], GB_DIRECT_ACCESS_OAM, &size, &bank); - descs[8].start = 0xFE00; - descs[8].select = 0xFFFFFF00; - descs[8].len = 0x00A0; + descs[8].ptr = GB_get_direct_access(&gameboy[i], GB_DIRECT_ACCESS_OAM, &size, &bank); + descs[8].start = 0xFE00; + descs[8].len = 0x00A0; + descs[8].select= 0xFFFFFF00; - descs[9].ptr = descs[2].ptr + 0x2000; /* GBC RAM bank 2 */ - descs[9].start = 0x10000; - descs[9].select = 0xFFFF0000; - descs[9].len = GB_is_cgb(&gameboy[i]) ? 0x6000 : 0; /* 0x1000 per bank (2-7), unmapped on GB */ + descs[9].ptr = descs[2].ptr + 0x2000; /* GBC RAM bank 2 */ + descs[9].start = 0x10000; + descs[9].len = GB_is_cgb(&gameboy[i]) ? 0x6000 : 0; /* 0x1000 per bank (2-7), unmapped on GB */ + descs[9].select= 0xFFFF0000; - descs[10].ptr = descs[8].ptr; - descs[10].offset = 0x100; - descs[10].start = 0xFF00; - descs[10].select = 0xFFFFFF00; - descs[10].len = 0x0080; + descs[10].ptr = GB_get_direct_access(&gameboy[i], GB_DIRECT_ACCESS_IO, &size, &bank); + descs[10].start = 0xFF00; + descs[10].len = 0x0080; + descs[10].select= 0xFFFFFF00; struct retro_memory_map mmaps; mmaps.descriptors = descs; @@ -493,7 +494,7 @@ static void check_variables() { var.key = "sameboy_color_correction_mode"; var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && GB_is_cgb(&gameboy[0])) + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "off") == 0) GB_set_color_correction_mode(&gameboy[0], GB_COLOR_CORRECTION_DISABLED); @@ -542,12 +543,22 @@ static void check_variables() init_for_current_model(0); } } + + var.key = "sameboy_border"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + sgb_border = 1; + else if (strcmp(var.value, "disabled") == 0) + sgb_border = 0; + } } else { var.key = "sameboy_color_correction_mode_1"; var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && GB_is_cgb(&gameboy[0])) + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "off") == 0) GB_set_color_correction_mode(&gameboy[0], GB_COLOR_CORRECTION_DISABLED); @@ -561,7 +572,7 @@ static void check_variables() var.key = "sameboy_color_correction_mode_2"; var.value = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && GB_is_cgb(&gameboy[1])) + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "off") == 0) GB_set_color_correction_mode(&gameboy[1], GB_COLOR_CORRECTION_DISABLED); @@ -887,8 +898,15 @@ void retro_run(void) } else { - if (model[0] == MODEL_SGB || model[0] == MODEL_SGB2) - video_cb(frame_buf, SGB_VIDEO_WIDTH, SGB_VIDEO_HEIGHT, SGB_VIDEO_WIDTH * sizeof(uint32_t)); + if (model[0] == MODEL_SGB || model[0] == MODEL_SGB2) { + if (sgb_border == 1) + video_cb(frame_buf, SGB_VIDEO_WIDTH, SGB_VIDEO_HEIGHT, SGB_VIDEO_WIDTH * sizeof(uint32_t)); + else { + int crop = SGB_VIDEO_WIDTH * ((SGB_VIDEO_HEIGHT - VIDEO_HEIGHT) / 2) + ((SGB_VIDEO_WIDTH - VIDEO_WIDTH) / 2); + + video_cb(frame_buf + crop, VIDEO_WIDTH, VIDEO_HEIGHT, SGB_VIDEO_WIDTH * sizeof(uint32_t)); + } + } else video_cb(frame_buf, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_WIDTH * sizeof(uint32_t)); }