diff --git a/Makefile b/Makefile index 23aa582..bfbfb93 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,42 @@ -CC = gcc +SHORT_PLATFORM = linux +ifeq ($(PLATFORM),win64) + CROSS_COMPILE = x86_64-w64-mingw32- + EXTENSION = .exe + SHORT_PLATFORM = win +else ifeq ($(PLATFORM),win32) + CROSS_COMPILE = i686-w64-mingw32- + EXTENSION = .exe + SHORT_PLATFORM = win +endif + +ifneq ($(PLATFORM),) + DIR_SUFFIX=-$(PLATFORM) +endif + + +CC = $(CROSS_COMPILE)gcc LD = $(CC) PFLAGS = -g -#PFLAGS += -O3 +#PFLAGS += -O3 -s #PFLAGS += -DDEBUG_MAPPER #PFLAGS += -DDEBUG_RENDER #PFLAGS += -DDEBUG_PPU -DDEBUG_VRAM -DDEBUG_OAM -PFLAGS += -DDEBUG_APU +#PFLAGS += -DDEBUG_APU #PFLAGS += -DE6502_DEBUG PFLAGS += -DE6502_ILLEGAL -CFLAGS = $(PFLAGS) -Wall -Werror -Wshadow -Wunused -I.. +CFLAGS = $(PFLAGS) -Wall -Werror -Wshadow -Wunused -I../ -Isrc/ +CFLAGS += -Iinc/$(PLATFORM) -I../inc/$(PLATFORM) LDFLAGS = $(PFLAGS) +LDFLAGS += -Llib/$(PLATFORM) -OBJDIR = obj +OBJDIR = obj$(DIR_SUFFIX) SRCDIR = src -BINDIR = bin +BINDIR = bin$(DIR_SUFFIX) # nese -TARGET_1 = nese +TARGET_1 = nese$(EXTENSION) LDLIBS_1 = -lSDL2 SRC_SRCS_1 = nese.c ines.c @@ -26,22 +44,25 @@ SRC_SRCS_1 += nes.c ppu.c input.c SRC_SRCS_1 += cart.c mapper.c SRC_SRCS_1 += apu.c audio.c SRC_SRCS_1 += sdl_render.c sdl_input.c sdl_audio.c +SRC_SRCS_1 += sdl_timer.c + +PLAT_SRCS_1 = filemap.c MAPDIR = src/map MAP_SRCS_1 = nrom.c mmc1.c uxrom.c cnrom.c mmc3.c EXT_SRCS_1 = e6502/e6502.c e6502/opcodes.c blip-buf/blip_buf.c - SRCS_1 = $(SRC_SRCS_1:%=$(SRCDIR)/%) SRCS_1 += $(MAP_SRCS_1:%=$(MAPDIR)/%) +SRCS_1 += $(PLAT_SRCS_1:%=src/$(SHORT_PLATFORM)/%) SRCS_1 += $(EXT_SRCS_1) OBJS_1 = $(SRCS_1:%.c=$(OBJDIR)/%.o) all: $(BINDIR)/$(TARGET_1) -clean: ; rm -rf $(OBJDIR) $(BINDIR) +clean: ; rm -rf obj*/ bin*/ $(BINDIR)/$(TARGET_1): $(OBJS_1) @mkdir -p $(@D) diff --git a/inc/win32/SDL2 b/inc/win32/SDL2 new file mode 120000 index 0000000..387eb0e --- /dev/null +++ b/inc/win32/SDL2 @@ -0,0 +1 @@ +../../../SDL2-devel-2.30.11-mingw/i686-w64-mingw32/include/SDL2 \ No newline at end of file diff --git a/inc/win64/SDL2 b/inc/win64/SDL2 new file mode 120000 index 0000000..d4a65f0 --- /dev/null +++ b/inc/win64/SDL2 @@ -0,0 +1 @@ +../../../SDL2-devel-2.30.11-mingw/x86_64-w64-mingw32/include/SDL2 \ No newline at end of file diff --git a/lib/win32/SDL2.dll b/lib/win32/SDL2.dll new file mode 120000 index 0000000..f645a45 --- /dev/null +++ b/lib/win32/SDL2.dll @@ -0,0 +1 @@ +../../../SDL2-devel-2.30.11-mingw/i686-w64-mingw32/bin/SDL2.dll \ No newline at end of file diff --git a/lib/win64/SDL2.dll b/lib/win64/SDL2.dll new file mode 120000 index 0000000..8ae15eb --- /dev/null +++ b/lib/win64/SDL2.dll @@ -0,0 +1 @@ +../../../SDL2-devel-2.30.11-mingw/x86_64-w64-mingw32/bin/SDL2.dll \ No newline at end of file diff --git a/src/cart.c b/src/cart.c index cac570a..e422b6f 100644 --- a/src/cart.c +++ b/src/cart.c @@ -1,6 +1,5 @@ -#include - #include "cart.h" +#include "filemap.h" #include "ines.h" #include "mapper.h" @@ -67,7 +66,7 @@ int nes_cart_init_mem(nes_cart* cart, void* mem, int len) { void nes_cart_done(nes_cart* cart) { if (NULL != cart->ines_mem) { - munmap(cart->ines_mem, cart->ines_size); + unmap_file(cart->ines_mem, cart->ines_size); cart->ines_mem = NULL; } } @@ -87,8 +86,7 @@ int nes_cart_init_file(nes_cart* cart, FILE* file) { // Map file if (0 == status) { - mem = mmap(NULL, size, PROT_READ, MAP_PRIVATE, - fileno(file), 0); + mem = map_file(file, size); if (NULL == mem) { INES_ERR("Failed to map file (%d bytes)", size); status = -1; @@ -99,7 +97,7 @@ int nes_cart_init_file(nes_cart* cart, FILE* file) { if (0 == status) { status = nes_cart_init_mem(cart, mem, size); if (0 != status) { - munmap(mem, size); + unmap_file(file, size); } } diff --git a/src/filemap.h b/src/filemap.h new file mode 100644 index 0000000..2a27222 --- /dev/null +++ b/src/filemap.h @@ -0,0 +1,10 @@ +#ifndef NESE_FILEMAP_H_ +#define NESE_FILEMAP_H_ + + +void* map_file(FILE* file, int size); + +void unmap_file(void* mem, int size); + + +#endif // NESE_FILEMAP_H_ diff --git a/src/linux/filemap.c b/src/linux/filemap.c new file mode 100644 index 0000000..7dd2e16 --- /dev/null +++ b/src/linux/filemap.c @@ -0,0 +1,15 @@ +#include + +#include + +#include "filemap.h" + + +void* map_file(FILE* file, int size) { + return mmap(NULL, size, PROT_READ, MAP_PRIVATE, + fileno(file), 0); +} + +void unmap_file(void* mem, int size) { + munmap(mem, size); +} diff --git a/src/nese.c b/src/nese.c index ec7fd42..1afa7e2 100644 --- a/src/nese.c +++ b/src/nese.c @@ -1,9 +1,9 @@ #include #include #include -#include #include "nes.h" +#include "timer.h" #include "render.h" #include "input.h" #include "audio.h" @@ -12,24 +12,6 @@ #define audio_freq (44100U) -#define NS_PER_S (1000U * 1000U * 1000U) - -static inline int t_diff_ns(const struct timespec* b, - const struct timespec* a) { - int sec = (b->tv_sec - a->tv_sec); - int nsec = (b->tv_nsec - a->tv_nsec); - return ((sec * NS_PER_S) + nsec); -} - -static inline void t_add_ns(struct timespec* s, - const struct timespec* a, - int b) { - int nsec = a->tv_nsec + b; - s->tv_sec = a->tv_sec + (nsec / NS_PER_S); - s->tv_nsec = nsec % NS_PER_S; -} - - extern nes_Renderer sdl_renderer; extern nes_Input_Reader sdl_input; @@ -79,7 +61,7 @@ int main(int argc, char* argv[]) { nes_render(rend, &sys.ppu); struct timespec t_target = {0}; - clock_gettime(CLOCK_MONOTONIC, &t_target); + time_get(&t_target); uint64_t cycle_last_frame = 0; uint64_t total_cycles = 0; @@ -103,8 +85,7 @@ int main(int argc, char* argv[]) { t_add_ns(&t_target, &t_target, elapsed_ns); - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, - &t_target, NULL); + time_sleep_until(&t_target); cycle_last_frame = total_cycles; diff --git a/src/sdl_render.c b/src/sdl_render.c index bcc271d..a106ae1 100644 --- a/src/sdl_render.c +++ b/src/sdl_render.c @@ -1,3 +1,5 @@ +#include + #include #include "render.h" diff --git a/src/sdl_timer.c b/src/sdl_timer.c new file mode 100644 index 0000000..b444882 --- /dev/null +++ b/src/sdl_timer.c @@ -0,0 +1,21 @@ +#include + +#include "time.h" + +#include + + +void time_get(struct timespec* ts) { + uint64_t time = SDL_GetTicks64(); + ts->tv_sec = time / 1000U; + ts->tv_nsec = (time % 1000U) * 1000U * 1000U; +} + +void time_sleep_until(const struct timespec* ts) { + uint64_t t_target = ( (ts->tv_sec * 1000ULL) + + (ts->tv_nsec / (1000U * 1000U))); + uint64_t t_now = SDL_GetTicks64(); + if (t_target > t_now) { + SDL_Delay(t_target - t_now); + } +} diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..81669c5 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,31 @@ +#ifndef NESE_TIMER_H_ +#define NESE_TIMER_H_ + +#include + + +#define NS_PER_S (1000U * 1000U * 1000U) + + +static inline int t_diff_ns(const struct timespec* b, + const struct timespec* a) { + int sec = (b->tv_sec - a->tv_sec); + int nsec = (b->tv_nsec - a->tv_nsec); + return ((sec * NS_PER_S) + nsec); +} + +static inline void t_add_ns(struct timespec* s, + const struct timespec* a, + int b) { + int nsec = a->tv_nsec + b; + s->tv_sec = a->tv_sec + (nsec / NS_PER_S); + s->tv_nsec = nsec % NS_PER_S; +} + + +void time_get(struct timespec*); + +void time_sleep_until(const struct timespec*); + + +#endif // NESE_TIME_H_ diff --git a/src/win/filemap.c b/src/win/filemap.c new file mode 100644 index 0000000..2965155 --- /dev/null +++ b/src/win/filemap.c @@ -0,0 +1,29 @@ +#include + + +#include +#include +#include +#include + +#include "filemap.h" + + +// TODO: Support multiple filemaps +static HANDLE hMap; + + +void* map_file(FILE* file, int size) { + HANDLE hFile = (HANDLE)_get_osfhandle(fileno(file)); + + hMap = CreateFileMappingA( + hFile, 0, PAGE_READONLY, 0, size, 0 + ); + + return MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, size); +} + +void unmap_file(void* mem, int size) { + UnmapViewOfFile(mem); + CloseHandle(hMap); +}