diff --git a/README.md b/README.md
index b4851f7..86f8e9b 100644
--- a/README.md
+++ b/README.md
@@ -113,7 +113,7 @@ The following must be installed and added to your **PATH**:
## Building on Linux (Debian)
-The following must be added to your **PATH**:
+The following must be installed and added to your **PATH**:
>gcc
>g++
diff --git a/linux/makefile b/linux/makefile
index 349ce69..6f3a62c 100644
--- a/linux/makefile
+++ b/linux/makefile
@@ -62,7 +62,9 @@ SDL_LIB = ../external/sdl/build/lib/libSDL2-2.0.so.0
# Generated headers
LICENSE_HEADER = ../shared/license.h
BOOTROM_HEADER = ../shared/bootrom.h
-BOOTROM_SOURCE = ../roms/Kiwi8_logo_2.ch8
+
+# ROM Profiles database (source of truth)
+PROFILES_INI = ../shared/profiles.ini
OBJS = audio.o \
chip8.o \
@@ -79,11 +81,8 @@ OBJS = audio.o \
imgui_impl_sdl.o \
sha256.o
-DEPS = $(OBJS:.o=.d)
-
-PROFILES_INI = ../shared/profiles.ini
-
# Include auto-generated dependency files (must be before targets)
+DEPS = $(OBJS:.o=.d)
-include $(DEPS)
.DEFAULT_GOAL := all
@@ -100,11 +99,11 @@ $(SDL_LIB):
# Generate license header from LICENSE file
$(LICENSE_HEADER): ../LICENSE
- python3 ../tools/generate_license_header.py ../LICENSE $(LICENSE_HEADER)
+ python3 ../tools/generate_license_header.py $< $@
# Generate bootrom header from ROM file
-$(BOOTROM_HEADER): $(BOOTROM_SOURCE)
- python3 ../tools/generate_bootrom_header.py $(BOOTROM_SOURCE) $(BOOTROM_HEADER)
+$(BOOTROM_HEADER): ../roms/Kiwi8_logo_2.ch8
+ python3 ../tools/generate_bootrom_header.py $< $@
# Pattern rules for incremental compilation
%.o: src/%.cc
@@ -127,11 +126,11 @@ $(BOOTROM_HEADER): $(BOOTROM_SOURCE)
debug/profiles.ini: $(PROFILES_INI)
mkdir -p debug
- cp $(PROFILES_INI) debug/profiles.ini
+ cp $(PROFILES_INI) $@
release/profiles.ini: $(PROFILES_INI)
mkdir -p release
- cp $(PROFILES_INI) release/profiles.ini
+ cp $(PROFILES_INI) $@
# debug executable
debug/$(APP_EXE): $(SDL_LIB) $(OBJS)
@@ -145,10 +144,10 @@ release/$(APP_EXE): $(SDL_LIB) $(OBJS)
cp $(SDL_LIB) release/libSDL2-2.0.so.0
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) $(OBJS) -o $@ $(LDFLAGS)
-run-debug: debug/$(APP_EXE)
+run-debug: debug/$(APP_EXE) debug/profiles.ini
./debug/$(APP_EXE)
-run-release: release/$(APP_EXE)
+run-release: release/$(APP_EXE) release/profiles.ini
./release/$(APP_EXE)
# Removes build artifacts (objects, executables) but keeps SDL
diff --git a/linux/src/open_file_dialog.cc b/linux/src/open_file_dialog.cc
index bb9d2fa..5f4706d 100644
--- a/linux/src/open_file_dialog.cc
+++ b/linux/src/open_file_dialog.cc
@@ -70,6 +70,8 @@ std::vector open_file_dialog(const std::string &title, const std::s
}
int open_file_dialog(char *rom_filepath, size_t size) {
+ if (rom_filepath == nullptr || size == 0) return -1;
+
std::vector fileTypes = {"ch8", "CH8", "chip-8", "CHIP-8", "Chip-8"};
const char* defaultDir = ""; // unify behavior: let OS choose last-used/home
std::vector files = open_file_dialog("Chip8", defaultDir, fileTypes);
diff --git a/macos/makefile b/macos/makefile
index ac828f0..67565e4 100644
--- a/macos/makefile
+++ b/macos/makefile
@@ -43,7 +43,9 @@ SDL_LIB = ../external/sdl/build/lib/libSDL2-2.0.0.dylib
# Generated headers
LICENSE_HEADER = ../shared/license.h
BOOTROM_HEADER = ../shared/bootrom.h
-BOOTROM_SOURCE = ../roms/Kiwi8_logo_2.ch8
+
+# ROM Profiles database (source of truth)
+PROFILES_INI = ../shared/profiles.ini
OBJS = audio.o \
chip8.o \
@@ -60,11 +62,8 @@ OBJS = audio.o \
imgui_impl_sdl.o \
sha256.o
-DEPS = $(OBJS:.o=.d)
-
-PROFILES_INI = ../shared/profiles.ini
-
# Include auto-generated dependency files (must be before targets)
+DEPS = $(OBJS:.o=.d)
-include $(DEPS)
.DEFAULT_GOAL := all
@@ -81,14 +80,14 @@ $(SDL_LIB):
# Generate license header from LICENSE file
$(LICENSE_HEADER): ../LICENSE
- python3 ../tools/generate_license_header.py ../LICENSE $(LICENSE_HEADER)
+ python3 ../tools/generate_license_header.py $< $@
# Generate bootrom header from ROM file
-$(BOOTROM_HEADER): $(BOOTROM_SOURCE)
- python3 ../tools/generate_bootrom_header.py $(BOOTROM_SOURCE) $(BOOTROM_HEADER)
+$(BOOTROM_HEADER): ../roms/Kiwi8_logo_2.ch8
+ python3 ../tools/generate_bootrom_header.py $< $@
# Generate Info.plist from template with version substitution
-$(APP_MANIFEST): $(APP_MANIFEST).in
+$(APP_MANIFEST): src/Info.plist.in
sed -e 's/@APP_NAME@/$(APP_NAME)/g' -e 's/@VERSION@/$(VERSION)/g' -e 's/@SUB_VERSION@/$(SUB_VERSION)/g' $< > $@
# Pattern rules for incremental compilation
@@ -110,13 +109,16 @@ $(APP_MANIFEST): $(APP_MANIFEST).in
%.o: ../shared/%.cc $(LICENSE_HEADER) $(BOOTROM_HEADER)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) -c $< -o $@
+%.i: %.c $(LICENSE_HEADER) $(BOOTROM_HEADER)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) -E $< -o $@
+
debug/profiles.ini: $(PROFILES_INI)
mkdir -p debug
- cp $(PROFILES_INI) debug/profiles.ini
+ cp $(PROFILES_INI) $@
release/$(APP_BUNDLE)/Contents/Resources/profiles.ini: $(PROFILES_INI)
mkdir -p release/$(APP_BUNDLE)/Contents/Resources
- cp $(PROFILES_INI) release/$(APP_BUNDLE)/Contents/Resources/profiles.ini
+ cp $(PROFILES_INI) $@
# debug executable
debug/$(APP_EXE): $(SDL_LIB) $(OBJS)
@@ -161,10 +163,10 @@ release/$(APP_BUNDLE)/Contents/Frameworks/libSDL2-2.0.0.dylib: $(SDL_LIB)
# .app bundle
release/$(APP_BUNDLE): release/$(APP_BUNDLE)/Contents/MacOS/$(APP_EXE) release/$(APP_BUNDLE)/Contents/Info.plist release/$(APP_BUNDLE)/Contents/Resources/Kiwi8.icns release/$(APP_BUNDLE)/Contents/Frameworks/libSDL2-2.0.0.dylib
-run-debug: debug/$(APP_EXE)
+run-debug: debug/$(APP_EXE) debug/profiles.ini
./debug/$(APP_EXE)
-run-release: release/$(APP_BUNDLE)
+run-release: release/$(APP_BUNDLE) release/$(APP_BUNDLE)/Contents/Resources/profiles.ini
open release/$(APP_BUNDLE)
# Removes build artifacts (objects, app bundle) but keeps SDL
diff --git a/macos/src/open_file_dialog.mm b/macos/src/open_file_dialog.mm
index cbabe66..a44dd6b 100644
--- a/macos/src/open_file_dialog.mm
+++ b/macos/src/open_file_dialog.mm
@@ -45,6 +45,8 @@
}
int open_file_dialog(char *rom_filepath, size_t size) {
+ if (rom_filepath == nullptr || size == 0) return -1;
+
std::vector fileTypes = {"ch8", "CH8", "chip-8", "CHIP-8", "Chip-8"};
const char* defaultDir = ""; // unify behavior: let OS choose last-used/home
std::vector files = open_file_dialog("Chip8", defaultDir, fileTypes);
diff --git a/shared/chip8.c b/shared/chip8.c
index 65c0b48..99284f6 100644
--- a/shared/chip8.c
+++ b/shared/chip8.c
@@ -119,7 +119,7 @@ int chip8_load_bootrom() {
memcpy(chip8.memory + ENTRY_POINT, bootrom, BOOTROM_SIZE);
/* Mark as bootrom (not user ROM) */
- chip8.rom_loaded = 0;
+ chip8.rom_loaded = false;
chip8.rom_filename[0] = '\0';
return 0;
@@ -174,7 +174,7 @@ int chip8_load_rom(const char *rom_filepath) {
chip8.rom_filename[sizeof(chip8.rom_filename) - 1] = '\0';
/* Mark as user ROM (not bootrom) */
- chip8.rom_loaded = 1;
+ chip8.rom_loaded = true;
char notif_msg[TOAST_MSG_MAX];
snprintf(notif_msg, sizeof(notif_msg), "ROM loaded: %s", chip8.rom_filename);
toast_show(TOAST_SUCCESS, notif_msg);
diff --git a/shared/chip8.h b/shared/chip8.h
index 9c8fcaa..e25bcee 100644
--- a/shared/chip8.h
+++ b/shared/chip8.h
@@ -18,7 +18,7 @@ extern "C" {
#define FONTS_SIZE 80
#define CYCLES_PER_STEP 12 /* ~720 inst/sec if ticking at 60hz */
#define MIN_CYCLES_PER_STEP 1
-#define MAX_CYCLES_PER_STEP 50
+#define MAX_CYCLES_PER_STEP 150 /* You've reached level 9000! */
#define TICKS 60 /* hz - Timer count down rate */
static const unsigned char chip8_fontset[FONTS_SIZE] = {
@@ -46,7 +46,7 @@ struct chip8 {
/* whether or not cpu is currently halted by opcode FX0A */
bool cpu_halt;
- /* whether or not emulation is currently paused. */
+ /* whether or not emulation is currently paused via user. */
bool paused;
/* All quirk toggles */
@@ -64,7 +64,7 @@ struct chip8 {
/* rom profile tracking */
char rom_filename[PATH_MAX]; /* basename of currently loaded ROM */
- int rom_loaded; /* 1 if user ROM loaded, 0 if bootrom */
+ bool rom_loaded;
/* registers */
unsigned char V[NUM_REGISTERS];
diff --git a/shared/gui.cc b/shared/gui.cc
index 098b6df..a23324b 100644
--- a/shared/gui.cc
+++ b/shared/gui.cc
@@ -64,7 +64,7 @@ static void gui_help_windows(void) {
"A cross-platform Chip-8 interpreter written\n"
"in C-Style C++ using SDL2, ImGui, and OpenGL.\n"
"\n"
- "\n"
+ "https://github.com/Diesel-Net/kiwi-8\n"
);
ImGui::End();
diff --git a/shared/open_file_dialog.h b/shared/open_file_dialog.h
index 5c5a565..b09d0bd 100644
--- a/shared/open_file_dialog.h
+++ b/shared/open_file_dialog.h
@@ -10,7 +10,7 @@ extern "C" {
/* Opens a file dialog to select a ROM file.
* The selected file path is copied to `rom_filepath`.
* The `size` parameter specifies the size of the `rom_filepath` buffer.
- * Returns 1 if a file was selected, 0 if cancelled, or -1 on error.
+ * Returns 0 if a file was selected, 1 if cancelled, or -1 on error.
*/
int open_file_dialog(char *rom_filepath, size_t size);
diff --git a/shared/profiles.c b/shared/profiles.c
index 1669295..ab046f7 100644
--- a/shared/profiles.c
+++ b/shared/profiles.c
@@ -229,7 +229,7 @@ const struct profile* profile_lookup(const sha256_hash_t *sha256) {
char matched_hash_hex[65];
bytes_to_hex(profile_map[idx].key.bytes, matched_hash_hex, sizeof(matched_hash_hex));
- printf("Lookup result: found idx=%td name=%s\n", idx, matched_hash_hex, profile_map[idx].value.rom_name);
+ printf("Lookup result: found idx=%td name=%s\n", idx, profile_map[idx].value.rom_name);
quirks_print(&profile_map[idx].value.quirks, "Lookup quirks:");
return &profile_map[idx].value;
}
diff --git a/windows/makefile b/windows/makefile
index ea7ecbc..70ad718 100644
--- a/windows/makefile
+++ b/windows/makefile
@@ -66,7 +66,9 @@ SDL_LIB = ..\external\sdl\build\lib\SDL2.lib
# Generated headers
LICENSE_HEADER = ..\shared\license.h
BOOTROM_HEADER = ..\shared\bootrom.h
-BOOTROM_SOURCE = ..\roms\Kiwi8_logo_2.ch8
+
+# ROM Profiles database (source of truth)
+PROFILES_INI = ..\shared\profiles.ini
OBJS = audio.obj \
chip8.obj \
@@ -83,12 +85,9 @@ OBJS = audio.obj \
imgui_draw.obj \
sha256.obj
-PROFILES_INI = ..\shared\profiles.ini
-
# Default target
all: debug\profiles.ini debug\$(APP_EXE) release\profiles.ini release\$(APP_EXE)
-
# Build SDL (force rebuild with: nmake sdl)
sdl:
powershell -ExecutionPolicy Bypass -File build_sdl.ps1 -ARCH $(SDL_ARCH)
@@ -99,11 +98,11 @@ $(SDL_LIB):
# Generate license header from LICENSE file
$(LICENSE_HEADER): ..\LICENSE
- python3 ..\tools\generate_license_header.py ..\LICENSE $(LICENSE_HEADER)
+ python3 ..\tools\generate_license_header.py ..\LICENSE $@
# Generate bootrom header from ROM file
-$(BOOTROM_HEADER): $(BOOTROM_SOURCE)
- python3 ..\tools\generate_bootrom_header.py $(BOOTROM_SOURCE) $(BOOTROM_HEADER)
+$(BOOTROM_HEADER): ..\roms\Kiwi8_logo_2.ch8
+ python3 ..\tools\generate_bootrom_header.py ..\roms\Kiwi8_logo_2.ch8 $@
# Inference rules for incremental compilation
{src}.cc{}.obj:
@@ -137,11 +136,11 @@ $(APP_RES): src\Kiwi8.rc resources\Kiwi8.ico
debug\profiles.ini: $(PROFILES_INI)
IF NOT EXIST debug MKDIR debug
- COPY $(PROFILES_INI) debug\profiles.ini
+ COPY $(PROFILES_INI) $@
release\profiles.ini: $(PROFILES_INI)
IF NOT EXIST release MKDIR release
- COPY $(PROFILES_INI) release\profiles.ini
+ COPY $(PROFILES_INI) $@
debug\$(APP_EXE): $(SDL_LIB) $(OBJS) $(APP_RES)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) /Zi /Fe$(APP_NAME) $(INCLUDE_DIRS) $(OBJS) $(APP_RES) $(LDFLAGS) /SUBSYSTEM:CONSOLE
@@ -155,10 +154,10 @@ release\$(APP_EXE): $(SDL_LIB) $(OBJS) $(APP_RES)
COPY ..\external\sdl\build\bin\SDL2.dll release\SDL2.dll
MOVE $(APP_EXE) $@
-run-debug:
+run-debug: debug\$(APP_EXE) debug\profiles.ini
debug\$(APP_EXE)
-run-release:
+run-release: release\$(APP_EXE) release\profiles.ini
release\$(APP_EXE)
# Clean any leftover build files (keeps SDL)
diff --git a/windows/src/open_file_dialog.cc b/windows/src/open_file_dialog.cc
index 0a9cfa5..5e52e4e 100644
--- a/windows/src/open_file_dialog.cc
+++ b/windows/src/open_file_dialog.cc
@@ -4,24 +4,33 @@
#include
#include
#include
+#include
+
+int open_file_dialog(char *rom_filepath, size_t size, const char *filters) {
+ if (rom_filepath == NULL || size == 0 || size > MAXDWORD) {
+ return -1;
+ }
+
+ const DWORD buffer_size = (DWORD)size;
-int open_file_dialog(char *rom_filepath, char *filters, size_t size) {
/* open file dialogue */
- char cwd[PATH_MAX];
- GetCurrentDirectory(PATH_MAX, cwd);
+ std::vector cwd(MAX_PATH, '\0');
+ if (GetCurrentDirectoryA((DWORD)cwd.size(), cwd.data()) == 0) {
+ return -1;
+ }
OPENFILENAME ofn;
- char szFile[PATH_MAX];
+ std::vector szFile(buffer_size, '\0');
/* open a file name */
ZeroMemory( &ofn , sizeof( ofn));
ofn.lStructSize = sizeof ( ofn );
ofn.hwndOwner = NULL ;
- ofn.lpstrFile = szFile ;
+ ofn.lpstrFile = szFile.data() ;
ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = sizeof( szFile );
- ofn.lpstrFilter = "Chip8\0*.ch8\0All\0*.*\0";
+ ofn.nMaxFile = buffer_size;
+ ofn.lpstrFilter = filters;
ofn.nFilterIndex =1;
ofn.lpstrFileTitle = NULL ;
ofn.nMaxFileTitle = 0 ;
@@ -29,17 +38,17 @@ int open_file_dialog(char *rom_filepath, char *filters, size_t size) {
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
/* change current working directory back to location of executable */
- SetCurrentDirectory(cwd);
+ SetCurrentDirectoryA(cwd.data());
if (!GetOpenFileName( &ofn)) {
/* user hit cancel */
return 1;
}
- strncpy(rom_filepath, szFile, size);
+ snprintf(rom_filepath, size, "%s", szFile.data());
return 0;
}
int open_file_dialog(char *rom_filepath, size_t size) {
- return open_file_dialog(rom_filepath, "Chip8\0*.ch8\0All\0*.*\0", size);
+ return open_file_dialog(rom_filepath, size, "Chip8\0*.ch8\0All\0*.*\0");
}