From 631450e88a0c62c0748ed8b9d1531cbdd9ff6b9a Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Tue, 10 Mar 2026 20:46:43 -0700 Subject: [PATCH 1/2] proper inputs, and saving --- .gitignore | 1 + main.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 3619521..0066a6e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.zip *.gb milskoboy +*.sav \ No newline at end of file diff --git a/main.c b/main.c index ee870d9..d5de822 100644 --- a/main.c +++ b/main.c @@ -17,6 +17,9 @@ struct priv_t { uint8_t *cart_ram; uint8_t fb[LCD_WIDTH * LCD_HEIGHT * 4]; + size_t save_size; + char *save_file_name; + MwWidget *win; MwWidget *fb_widget; MwLLPixmap *px; @@ -33,10 +36,10 @@ int mfb_open(const char *title, int width, int height) { MwLibraryInit(); priv.win = MwCreateWidget(MwWindowClass, title, NULL, MwDEFAULT, MwDEFAULT, - width, height); + width * 2, height * 2); priv.fb_widget = - MwCreateWidget(MwImageClass, "fb", priv.win, 0, 0, width, height); + MwCreateWidget(MwImageClass, "fb", priv.win, 0, 0, width * 2, height * 2); MwAddUserHandler(priv.win, MwNkeyHandler, key_pressed, NULL); MwAddUserHandler(priv.win, MwNkeyReleaseHandler, key_released, NULL); @@ -161,6 +164,49 @@ uint8_t gb_cart_ram_read(struct gb_s *gb, const uint_fast32_t addr) { return p->cart_ram[addr]; } +void read_cart_ram_file(const char *save_file_name, uint8_t **dest, + const size_t len) { + FILE *f; + + /* If save file not required. */ + if (len == 0) { + *dest = NULL; + return; + } + + /* Allocate enough memory to hold save file. */ + *dest = malloc(len); + + printf("%s\n", save_file_name); + if ((f = fopen(save_file_name, "rb")) == NULL) { + printf("Unable to open save file for reading: %s\n", strerror(errno)); + return; + } + + /* Read save file to allocated memory. */ + fread(*dest, sizeof(uint8_t), len, f); + fclose(f); +} + +void write_cart_ram_file(const char *save_file_name, uint8_t **dest, + const size_t len) { + FILE *f; + + if (len == 0 || *dest == NULL) + return; + + if ((f = fopen(save_file_name, "wb")) == NULL) { + printf("Unable to open save file for writing: %s\n", strerror(errno)); + return; + } + + /* Record save file. */ + fwrite(*dest, sizeof(uint8_t), len, f); + fclose(f); + + return; +} + /** * Writes a given byte to the cartridge RAM at the given address. */ @@ -168,6 +214,8 @@ void gb_cart_ram_write(struct gb_s *gb, const uint_fast32_t addr, const uint8_t val) { const struct priv_t *const p = gb->direct.priv; p->cart_ram[addr] = val; + + write_cart_ram_file(priv.save_file_name, &priv.cart_ram, priv.save_size); } /** @@ -237,9 +285,11 @@ void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[160], } int main(int argc, char **argv) { - /* Must be freed */ + int save_timer = 0; char *rom_file_name = NULL; enum gb_init_error_e ret; + char *str_replace; + const char extension[] = ".sav"; switch (argc) { case 2: @@ -265,11 +315,27 @@ int main(int argc, char **argv) { printf("Error: %d\n", ret); exit(EXIT_FAILURE); } + /* Load Save File. */ + gb_get_save_size_s(&gb, &priv.save_size); - priv.cart_ram = malloc(gb_get_save_size(&gb)); + printf("%ld\n", priv.save_size); + + priv.cart_ram = malloc(priv.save_size); + + /* rom save name */ + priv.save_file_name = malloc(strlen(rom_file_name) + strlen(extension) + 1); + strcpy(priv.save_file_name, rom_file_name); + if ((str_replace = strrchr(priv.save_file_name, '.')) == NULL || + str_replace == priv.save_file_name) + str_replace = priv.save_file_name + strlen(priv.save_file_name); + for (unsigned int i = 0; i <= strlen(extension); i++) + *(str_replace++) = extension[i]; + + /* Only attempt to load a save file if the ROM actually supports saves.*/ + if (priv.save_size > 0) + read_cart_ram_file(priv.save_file_name, &priv.cart_ram, priv.save_size); gb_init_lcd(&gb, &lcd_draw_line); - // gb.direct.interlace = true; if (!mfb_open("Peanut-minifb", LCD_WIDTH, LCD_HEIGHT)) return EXIT_FAILURE; @@ -307,6 +373,9 @@ int main(int argc, char **argv) { continue; usleep(delay); + if (save_timer++ >= 60) { + } + save_timer++; } mfb_close(); From 7b0bb0ad5c7678c05d487eaf2e2da61c133b66af Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Tue, 10 Mar 2026 20:52:35 -0700 Subject: [PATCH 2/2] update readme, use only Mw/Milsko.h --- README.md | 3 +++ main.c | 60 +++++++++++++++++++++-------------------------------- peanut_gb.h | 10 +++------ 3 files changed, 30 insertions(+), 43 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c008e77 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# milskoboy + +Basic Gameboy emulator written using PeanutGB and [Milsko](https://gitea.nishi.boats/pyrite-dev/milsko). Not meant to be used seriously, instead meant to be portable enough to be usable as a test across any platforms Milsko supports. \ No newline at end of file diff --git a/main.c b/main.c index d5de822..4ea7b38 100644 --- a/main.c +++ b/main.c @@ -2,22 +2,14 @@ #include "peanut_gb.h" -#include -#include -#include -#include -#include -#include -#include - #include struct priv_t { - uint8_t *rom; - uint8_t *cart_ram; - uint8_t fb[LCD_WIDTH * LCD_HEIGHT * 4]; + MwU8 *rom; + MwU8 *cart_ram; + MwU8 fb[LCD_WIDTH * LCD_HEIGHT * 4]; - size_t save_size; + MwU64 save_size; char *save_file_name; MwWidget *win; @@ -151,7 +143,7 @@ static void key_released(MwWidget handle, void *user, void *client) { /** * Returns a byte from the ROM file at the given address. */ -uint8_t gb_rom_read(struct gb_s *gb, const uint_fast32_t addr) { +MwU8 gb_rom_read(struct gb_s *gb, const uint_fast32_t addr) { const struct priv_t *const p = gb->direct.priv; return p->rom[addr]; } @@ -159,13 +151,13 @@ uint8_t gb_rom_read(struct gb_s *gb, const uint_fast32_t addr) { /** * Returns a byte from the cartridge RAM at the given address. */ -uint8_t gb_cart_ram_read(struct gb_s *gb, const uint_fast32_t addr) { +MwU8 gb_cart_ram_read(struct gb_s *gb, const uint_fast32_t addr) { const struct priv_t *const p = gb->direct.priv; return p->cart_ram[addr]; } -void read_cart_ram_file(const char *save_file_name, uint8_t **dest, - const size_t len) { +void read_cart_ram_file(const char *save_file_name, MwU8 **dest, + const MwU64 len) { FILE *f; /* If save file not required. */ @@ -177,31 +169,32 @@ void read_cart_ram_file(const char *save_file_name, uint8_t **dest, /* Allocate enough memory to hold save file. */ *dest = malloc(len); - printf("%s\n", save_file_name); if ((f = fopen(save_file_name, "rb")) == NULL) { - printf("Unable to open save file for reading: %s\n", strerror(errno)); + printf("Unable to open save file (%s) for reading: %s\n", save_file_name, + strerror(errno)); return; } /* Read save file to allocated memory. */ - fread(*dest, sizeof(uint8_t), len, f); + fread(*dest, sizeof(MwU8), len, f); fclose(f); } -void write_cart_ram_file(const char *save_file_name, uint8_t **dest, - const size_t len) { +void write_cart_ram_file(const char *save_file_name, MwU8 **dest, + const MwU64 len) { FILE *f; if (len == 0 || *dest == NULL) return; if ((f = fopen(save_file_name, "wb")) == NULL) { - printf("Unable to open save file for writing: %s\n", strerror(errno)); + printf("Unable to open save file (%s) for writing: %s\n", save_file_name, + strerror(errno)); return; } /* Record save file. */ - fwrite(*dest, sizeof(uint8_t), len, f); + fwrite(*dest, sizeof(MwU8), len, f); fclose(f); return; @@ -211,7 +204,7 @@ void write_cart_ram_file(const char *save_file_name, uint8_t **dest, * Writes a given byte to the cartridge RAM at the given address. */ void gb_cart_ram_write(struct gb_s *gb, const uint_fast32_t addr, - const uint8_t val) { + const MwU8 val) { const struct priv_t *const p = gb->direct.priv; p->cart_ram[addr] = val; @@ -221,10 +214,10 @@ void gb_cart_ram_write(struct gb_s *gb, const uint_fast32_t addr, /** * Returns a pointer to the allocated space containing the ROM. Must be freed. */ -uint8_t *read_rom_to_ram(const char *file_name) { +MwU8 *read_rom_to_ram(const char *file_name) { FILE *rom_file = fopen(file_name, "rb"); - size_t rom_size; - uint8_t *rom = NULL; + MwU64 rom_size; + MwU8 *rom = NULL; if (rom_file == NULL) return NULL; @@ -234,7 +227,7 @@ uint8_t *read_rom_to_ram(const char *file_name) { rewind(rom_file); rom = malloc(rom_size); - if (fread(rom, sizeof(uint8_t), rom_size, rom_file) != rom_size) { + if (fread(rom, sizeof(MwU8), rom_size, rom_file) != rom_size) { free(rom); fclose(rom_file); return NULL; @@ -266,7 +259,7 @@ void gb_error(struct gb_s *gb, const enum gb_error_e gb_err, /** * Draws scanline into framebuffer. */ -void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[160], +void lcd_draw_line(struct gb_s *gb, const MwU8 pixels[160], const uint_fast8_t line) { struct priv_t *priv = gb->direct.priv; const uint16_t palette[3][4] = {{0xFF, 0xA5, 0x52, 0x00}, @@ -318,8 +311,6 @@ int main(int argc, char **argv) { /* Load Save File. */ gb_get_save_size_s(&gb, &priv.save_size); - printf("%ld\n", priv.save_size); - priv.cart_ram = malloc(priv.save_size); /* rom save name */ @@ -347,9 +338,7 @@ int main(int argc, char **argv) { struct timeval timecheck; int state; - gettimeofday(&timecheck, NULL); - start = (long)timecheck.tv_sec * 1000000 + (long)timecheck.tv_usec; - + start = MwTimeGetTick(); /* Execute CPU cycles until the screen has to be redrawn. */ gb_run_frame(&gb); @@ -359,8 +348,7 @@ int main(int argc, char **argv) { if (state < 0) break; - gettimeofday(&timecheck, NULL); - end = (long)timecheck.tv_sec * 1000000 + (long)timecheck.tv_usec; + end = MwTimeGetTick(); delay = target_speed_us - (end - start); diff --git a/peanut_gb.h b/peanut_gb.h index de5d519..f83c67c 100644 --- a/peanut_gb.h +++ b/peanut_gb.h @@ -41,11 +41,7 @@ #define __has_include(x) 0 #endif -#include /* Required for bool types */ -#include /* Required for int types */ -#include /* Required for abort */ -#include /* Required for memset */ -#include /* Required for tm struct */ +#include /** * If PEANUT_GB_IS_LITTLE_ENDIAN is positive, then Peanut-GB will be configured @@ -3364,7 +3360,7 @@ void gb_run_frame(struct gb_s *gb) { __gb_step_cpu(gb); } -int gb_get_save_size_s(struct gb_s *gb, size_t *ram_size) { +int gb_get_save_size_s(struct gb_s *gb, MwU64 *ram_size) { const uint_fast16_t ram_size_location = 0x0149; const uint_fast32_t ram_sizes[] = { /* 0, 2KiB, 8KiB, 32KiB, 128KiB, 64KiB */ @@ -3769,7 +3765,7 @@ void gb_init_serial(struct gb_s *gb, * set. * \returns 0 on success, or -1 if the RAM size is invalid or unknown. */ -int gb_get_save_size_s(struct gb_s *gb, size_t *ram_size); +int gb_get_save_size_s(struct gb_s *gb, MwU64 *ram_size); /** * Deprecated. Use gb_get_save_size_s() instead.