Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# OFFICIAL MAKEFILE FOR GB-EMU
# BY LINUS TORVALDS... JK BANDIT AND NICK HEYER
# BY LINUS TORVALDS... JK BANDIT AND NICK HEYER

CC := gcc
RM := rm -rf
Expand All @@ -10,17 +10,15 @@ SRC_DIR := src
BUILD_DIR := build
BIN_DIR := bin
ROM_DIR := roms
RM := rm -rf
EXE :=
LOG_DIR := logs
INCLUDE_DIR := include
EXE :=

# BASE FLAGS
BASE_CFLAGS := -Wall -Wextra -std=c11
INCLUDES := -I $(INCLUDE_DIR)
INCLUDES := -I $(INCLUDE_DIR) -I lib/nuklear
LDFLAGS :=


# OS SPECIFIC FLAGS AND LIBS
ifeq ($(OS),Windows_NT)
RM = del
Expand All @@ -29,19 +27,19 @@ ifeq ($(OS),Windows_NT)
LDFLAGS += -L./lib/$(PLATFORM_DIR) -lmingw32 -lSDL2main -lSDL2 -mwindows -lsetupapi -lwinmm -lversion
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
PLATFORM_DIR = macos
LDFLAGS += -L./lib/$(PLATFORM_DIR) -lSDL2main -lSDL2 \
-framework AudioToolbox -framework CoreAudio \
-framework CoreHaptics -framework CoreServices \
-framework Carbon -framework ForceFeedback \
-framework GameController -framework IOKit \
-framework Cocoa -framework OpenGL -framework Metal \
-framework CoreVideo -framework CoreFoundation \
-liconv
ifeq ($(UNAME_S),Darwin)
PLATFORM_DIR = macos
LDFLAGS += -L./lib/$(PLATFORM_DIR) -lSDL2main -lSDL2 \
-framework AudioToolbox -framework CoreAudio \
-framework CoreHaptics -framework CoreServices \
-framework Carbon -framework ForceFeedback \
-framework GameController -framework IOKit \
-framework Cocoa -framework OpenGL -framework Metal \
-framework CoreVideo -framework CoreFoundation \
-liconv
else
PLATFORM_DIR = linux
LDFLAGS += -L./lib/$(PLATFORM_DIR) -lSDL2main -lSDL2
LDFLAGS += -L./lib/$(PLATFORM_DIR) -lSDL2main -lSDL2 -lm
BASE_CFLAGS += -D_POSIX_C_SOURCE=199309L
endif
endif
Expand Down
Binary file added docs/gbshell_ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions include/apu.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@

void apu_init(void);
void apu_cleanup(void);
void apu_reset(void); // CHANNEL STATE ONLY; KEEPS AUDIO DEVICE OPEN
void apu_tick(void); // CALLED ONCE PER M-CYCLE (4 T-CYCLES)
u8 apu_read(u16 addr);
void apu_write(u16 addr, u8 val);

// USER CONTROLS
void apu_set_master_volume(float v); // 0.0..1.0
float apu_get_master_volume(void);
void apu_set_channel_enabled(int ch, bool on); // ch IN 0..3
bool apu_get_channel_enabled(int ch);

void apu_save_state(FILE* fp);
void apu_load_state(FILE* fp);

#endif
4 changes: 4 additions & 0 deletions include/bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,14 @@
#define WX_REG (IO_START + IO_WX)

void init_bus(void);
void bus_reset(void); // PRESERVES BOOTROM
u8 read_from_bus(u16 addr);
void write_to_bus(u16 addr, u8 val);
u8* get_memory_ptr(u16 addr);
void debug_dump_bootrom(u8 num_bytes);
void load_bootrom_data(u8* data, u32 size);

void bus_save_state(FILE* fp);
void bus_load_state(FILE* fp);

#endif
20 changes: 16 additions & 4 deletions include/cart.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,19 @@ struct cartridge {
bool ram_enabled;
bool has_battery;
bool has_rtc;
u8 current_rom_bank;
u8 current_ram_bank;
u16 current_rom_bank; // u16 - MBC5 USES 9 BITS (UP TO 512 BANKS)
u8 current_ram_bank;
u8 banking_mode;

// RTC STATE (MBC3)
u8 rtc_reg[5]; // S,M,H,DL,DH - NO IDEA WHAT THESE ARE USED FOR
// RTC STATE (MBC3 with timer)
// rtc_reg[0..4]: SEC, MIN, HOUR, DAY_LO, DAY_HI
// DAY_HI bit 0 = day MSB, bit 6 = halt, bit 7 = day-counter carry.
// rtc_reg IS THE LATCHED/VISIBLE VIEW; rtc_last IS THE HOST CLOCK AT THE
// LAST LATCH SO WE CAN ADVANCE BY THE DELTA NEXT TIME.
u8 rtc_reg[5];
bool rtc_latched;
time_t rtc_last;
u8 rtc_latch_last; // LAST VALUE WRITTEN TO THE 0x6000-0x7FFF LATCH REG

// TODO: DYNAMICALLY SET RENDERING CLOCK MODES BASED ON COLOR MODE
// CGB
Expand Down Expand Up @@ -100,6 +105,13 @@ bool load_battery(void);
// FREES ROM/RAM AND PERSISTS BATTERY-BACKED SAVE
void cart_cleanup(void);

// RESET BANKING STATE; ROM/RAM ALLOCATIONS UNTOUCHED
void cart_reset(void);

// SAVE STATE: BANKING STATE + CART RAM CONTENTS (NOT ROM, NOT FILENAME)
void cart_save_state(FILE* fp);
void cart_load_state(FILE* fp);

// GETTERS/SETTERS
// get_cart_mode(void);

Expand Down
8 changes: 8 additions & 0 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,20 @@ typedef int32_t i32;

// EMULATOR SETTINGS
#define EMU_TITLE "GBEmu"
// USED FOR WAYLAND APP-ID AND X11 WM_CLASS. SHOULD MATCH .desktop FILE BASENAME.
#define EMU_APP_ID "gbemu"
#define WINDOW_MULTI 5
#define SCREEN_WIDTH 160
#define SCREEN_HEIGHT 144
#define EMU_WIDTH (SCREEN_WIDTH * WINDOW_MULTI)
#define EMU_HEIGHT (SCREEN_HEIGHT * WINDOW_MULTI)

// WINDOW BEHAVIOR
#define WINDOW_RESIZABLE 1 // 1 = USER CAN RESIZE; LETTERBOX MAINTAINS ASPECT
#define WINDOW_FULLSCREEN 0 // 1 = LAUNCH IN FULLSCREEN
#define WINDOW_VSYNC 1 // 1 = SDL VSYNC (TEARING OFF, COSTS A FEW MS)
#define KEY_TOGGLE_FULLSCREEN SDLK_F11

// LOGGING
#define LOG_TO_FILE 0 // 1 = MIRROR LOGS INTO logs/<component>.log
#define LOG_TO_STDOUT 0 // 1 = ECHO LOGS TO STDOUT
Expand Down
4 changes: 4 additions & 0 deletions include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ void cpu_step(void);
u8 get_cpu_cycles(void);
void reset_cpu_cycles(void);

// SAVE STATE
void cpu_save_state(FILE* fp);
void cpu_load_state(FILE* fp);

// CPU STATE ACCESS
registers* get_registers();
bool get_ime(void);
Expand Down
2 changes: 2 additions & 0 deletions include/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ struct dma {
void dma_start(u8 val);
void dma_tick();
bool get_dma_active();
void dma_save_state(FILE* fp);
void dma_load_state(FILE* fp);

#endif
6 changes: 6 additions & 0 deletions include/gameboy.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ gameboy* get_gb();
void set_bootrom_enable(bool enable);
bool get_bootrom_enable();

// UI ACTIONS - ALL RETURN TRUE ON SUCCESS
bool gameboy_save_state(int slot); // slot 1..4, writes <rom>.s<slot>
bool gameboy_load_state(int slot);
bool gameboy_reset(void); // RE-INIT FOR CURRENTLY-LOADED CART
bool gameboy_load_rom(const char* path); // LOAD A NEW CART, RESET

#endif
5 changes: 5 additions & 0 deletions include/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ typedef struct {
// INITIALIZATION
void graphics_init();
void graphics_cleanup();
void graphics_reset(); // PPU STATE ONLY; KEEPS SDL HANDLES

// MAIN RENDERING PIPELINE
void graphics_tick();
Expand All @@ -121,4 +122,8 @@ void lcd_write(u16 addr, u8 val);
void update_debug_window();
void dump_frame_buffer_sample();

// SAVE STATE (SDL HANDLES ARE SKIPPED; FRAMEBUFFER REGENERATES)
void graphics_save_state(FILE* fp);
void graphics_load_state(FILE* fp);

#endif
2 changes: 2 additions & 0 deletions include/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ u8 get_interrupt_flags();
void set_interrupt_flags(u8 flags);
u8 get_interrupt_enable();
void set_interrupt_enable(u8 enable);
void interrupt_save_state(FILE* fp);
void interrupt_load_state(FILE* fp);

#endif
8 changes: 8 additions & 0 deletions include/joypad.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ void joypad_init(void);
void joypad_press(gb_button b);
void joypad_release(gb_button b);

// TRUE IF ANY GB BUTTON IS CURRENTLY DOWN, REGARDLESS OF P14/P15 SELECTION.
// CPU STOP USES THIS TO WAKE - REAL HARDWARE WAKES STOP ON ANY KEY DOWN,
// NOT JUST WHEN A COLUMN IS SELECTED.
bool joypad_any_pressed(void);

// P1 REGISTER (FF00) I/O FROM THE BUS
u8 joypad_read(void);
void joypad_write(u8 val);

void joypad_save_state(FILE* fp);
void joypad_load_state(FILE* fp);

#endif
2 changes: 2 additions & 0 deletions include/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ void timer_init(void);
void timer_tick(void);
u8 timer_read(u16 addr);
void timer_write(u16 addr, u8 val);
void timer_save_state(FILE* fp);
void timer_load_state(FILE* fp);

#endif
38 changes: 38 additions & 0 deletions include/ui.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef UI_H
#define UI_H

#include "config.h"
#include <SDL2/SDL.h>

#ifdef __cplusplus
extern "C" {
#endif

void ui_init(SDL_Window* window, SDL_Renderer* renderer);
void ui_shutdown(void);

void ui_input_begin(void);
void ui_input_end(void);
bool ui_handle_event(const SDL_Event* event);

void ui_new_frame(void);
void ui_render(void);

bool ui_wants_keyboard(void);
bool ui_wants_mouse(void);

int ui_menu_height(void);
SDL_Rect ui_screen_rect(int win_w, int win_h);
void ui_draw_chrome_under(SDL_Renderer* r, int win_w, int win_h);
void ui_draw_chrome_over(SDL_Renderer* r, int win_w, int win_h);
void ui_draw_splash(SDL_Renderer* r, SDL_Rect screen);
void ui_default_window_size(int* w, int* h);
void ui_min_window_size(int* w, int* h);

SDL_HitTestResult ui_hit_test(int x, int y, int win_w, int win_h);

#ifdef __cplusplus
}
#endif

#endif
Loading
Loading