commit 8ec65dc6ae9a9321d2451aea4657fa46bdb11958 Author: Simon Gellis Date: Tue Oct 15 00:24:13 2024 -0400 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57dffd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/shrooms-vb +/shrooms-vb.exe +.vscode \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d683365 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "shrooms-vb-core"] + path = shrooms-vb-core + url = https://git.virtual-boy.com/PVB/shrooms-vb-core.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..e1bc941 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Shrooms VB (native) + +An SDL-based implementation of shrooms-vb. + +## Setup + +Install the following dependencies: + - `gcc` (or MinGW on Windows) (or whatever, just set `CC`) + - `pkg-config` + - sdl2 + +Run +```sh +make build +``` \ No newline at end of file diff --git a/cli.c b/cli.c new file mode 100644 index 0000000..7328a09 --- /dev/null +++ b/cli.c @@ -0,0 +1,11 @@ +#include +#include + +int parseCLIArgs(int argc, char **argv, CLIArgs *args) { + if (argc != 2) { + fprintf(stderr, "usage: %s /path/to/rom.vb\n", argv[0]); + return 1; + } + args->filename = argv[1]; + return 0; +} \ No newline at end of file diff --git a/cli.h b/cli.h new file mode 100644 index 0000000..580265d --- /dev/null +++ b/cli.h @@ -0,0 +1,10 @@ +#ifndef SHROOMS_VB_NATIVE_CLI_ +#define SHROOMS_VB_NATIVE_CLI_ + +typedef struct { + char *filename; +} CLIArgs; + +int parseCLIArgs(int argc, char **argv, CLIArgs *args); + +#endif \ No newline at end of file diff --git a/game.c b/game.c new file mode 100644 index 0000000..08e5afd --- /dev/null +++ b/game.c @@ -0,0 +1,28 @@ +#include +#include +#include + +int sleepNanos(long int ns) { + struct timespec time; + time.tv_sec = ns / 1000000000; + time.tv_nsec = ns % 1000000000; + return nanosleep(&time, NULL); +} + +#define MAX_STEP_CLOCKS 20000 + +int runGame(VB *sim) { + uint32_t clocks; + SDL_Event event; + + while (1) { + clocks = MAX_STEP_CLOCKS; + vbEmulate(sim, &clocks); + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + return 0; + } + } + sleepNanos((MAX_STEP_CLOCKS - clocks) * 50); + } +} \ No newline at end of file diff --git a/game.h b/game.h new file mode 100644 index 0000000..39a1125 --- /dev/null +++ b/game.h @@ -0,0 +1,8 @@ +#ifndef SHROOMS_VB_NATIVE_GAME_ +#define SHROOMS_VB_NATIVE_GAME_ + +#include + +int runGame(VB *sim); + +#endif \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..d7569d0 --- /dev/null +++ b/main.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include "shrooms-vb-core/core/vb.h" +#include + +uint8_t *readROM(char *filename, uint32_t *size) { + FILE *file = fopen(filename, "rb"); + uint8_t *rom; + long filesize; + + if (!file) { + perror("could not open file"); + return NULL; + } + + if (fseek(file, 0, SEEK_END)) { + perror("could not seek file end"); + return NULL; + } + filesize = ftell(file); + if (filesize == -1) { + perror("could not read file size"); + return NULL; + } + if (fseek(file, 0, SEEK_SET)) { + perror("could not seek file start"); + return NULL; + } + + *size = (uint32_t) filesize; + rom = malloc(*size); + if (!rom) { + perror("could not allocate ROM"); + return NULL; + } + fread(rom, 1, *size, file); + if (ferror(file)) { + perror("could not read file"); + return NULL; + } + if (fclose(file)) { + perror("could not close file"); + return NULL; + } + + return rom; +} + +int main(int argc, char **argv) { + VB *sim; + uint8_t *rom; + uint32_t romSize; + SDL_Surface *winSurface; + SDL_Window *window; + CLIArgs args; + int status; + + if (parseCLIArgs(argc, argv, &args)) { + return 1; + } + + rom = readROM(args.filename, &romSize); + if (!rom) { + return 1; + } + + sim = malloc(vbSizeOf()); + vbInit(sim); + vbSetCartROM(sim, rom, romSize); + + if (SDL_Init(SDL_INIT_EVERYTHING)) { + fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError()); + return 1; + } + + window = SDL_CreateWindow("Shrooms VB", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + 384, 224, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + if (!window) { + fprintf(stderr, "Error creating window: %s\n", SDL_GetError()); + return 1; + } + + winSurface = SDL_GetWindowSurface(window); + if (!winSurface) { + fprintf(stderr, "Error getting surface: %s\n", SDL_GetError()); + return 1; + } + + SDL_FillRect(winSurface, NULL, SDL_MapRGB(winSurface->format, 255, 0, 0)); + SDL_UpdateWindowSurface(window); + + status = runGame(sim); + + SDL_DestroyWindow(window); + SDL_Quit(); + + return status; +} \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..1ed9007 --- /dev/null +++ b/makefile @@ -0,0 +1,18 @@ +CC?=gcc +SHROOMSFLAGS=shrooms-vb-core/core/vb.c -I shrooms-vb-core/core +SDL2FLAGS=$(shell pkg-config sdl2 --cflags --libs) + +.PHONY: clean +clean: +ifeq ($(OS),WINDOWS_NT) + @del shrooms-vb.exe +else + @rm -f shrooms-vb +endif + +build: + @$(CC) cli.c game.c main.c -I . \ + $(SHROOMSFLAGS) $(SDL2FLAGS) \ + -D POSIX_C_SOURCE=199309L \ + -o shrooms-vb \ + -Werror -std=c90 -Wall -Wextra -Wpedantic \ No newline at end of file