From 46bdb724b1fac2335e67b6f08b633a1a63aad552 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Wed, 14 Feb 2024 17:08:55 +0100 Subject: Begin implementing an SDL2 frontend --- make.c | 11 ++++++++- src/ahoy/emulator.c | 14 ++++++----- src/ahoy/emulator.h | 3 ++- src/ahoy/gui.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ahoy/gui.h | 7 ++++++ src/ahoy/main.c | 5 +++- 6 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 src/ahoy/gui.c create mode 100644 src/ahoy/gui.h diff --git a/make.c b/make.c index 6a03765..53860cd 100644 --- a/make.c +++ b/make.c @@ -165,7 +165,7 @@ build_ahoy(void) glob_t g; char **objs; cmd_t c = {0}; - struct strv sv = {0}; + struct strv sv = {0}, pc = {0}; build_librune(); @@ -187,6 +187,8 @@ build_ahoy(void) else env_or_default(&sv, "CFLAGS", CFLAGS_DBG); + (void)pcquery(&pc, "sdl2", PKGC_CFLAGS); + for (size_t i = 0; i < g.gl_pathc; i++) { if (!FLAGSET('f') && !foutdated(objs[i], g.gl_pathv[i])) continue; @@ -196,6 +198,7 @@ build_ahoy(void) if (FLAGSET('l')) cmdadd(&c, "-flto"); cmdadd(&c, "-Isrc/common", "-Ivendor/da", "-Ivendor/librune/include"); + cmdaddv(&c, pc.buf, pc.len); cmdadd(&c, "-c", g.gl_pathv[i], "-o", objs[i]); CMDPRC2(c); } @@ -204,6 +207,7 @@ build_ahoy(void) goto out; strvfree(&sv); + strvfree(&pc); env_or_default(&sv, "CC", CC); env_or_default(&sv, "LDFLAGS", nullptr); @@ -211,6 +215,10 @@ build_ahoy(void) cmdaddv(&c, sv.buf, sv.len); if (FLAGSET('l')) cmdadd(&c, "-flto"); + if (pcquery(&pc, "sdl2", PKGC_LIBS)) + cmdaddv(&c, pc.buf, pc.len); + else + cmdadd(&c, "-lSDL2"); cmdadd(&c, "-o", c.dst); cmdaddv(&c, objs, g.gl_pathc); cmdadd(&c, "src/common/cerr.o", "vendor/librune/librune.a"); @@ -219,6 +227,7 @@ build_ahoy(void) out: globfree(&g); strvfree(&sv); + strvfree(&pc); for (size_t i = 0; i < g.gl_pathc; i++) free(objs[i]); } diff --git a/src/ahoy/emulator.c b/src/ahoy/emulator.c index 1298ea0..b04e2ef 100644 --- a/src/ahoy/emulator.c +++ b/src/ahoy/emulator.c @@ -72,7 +72,7 @@ scrdrw(void) } void -emulate(struct u8view prog) +emuinit(struct u8view prog) { struct timespec tp; @@ -87,12 +87,14 @@ emulate(struct u8view prog) if (clock_gettime(CLOCK_REALTIME, &tp) == -1) die("clock_gettime"); srand(tp.tv_sec ^ tp.tv_nsec); +} - for (;; PC += 2) { - uint16_t op = (mem[PC] << 8) | mem[PC + 1]; - opexec(op); - scrdrw(); - } +void +emutick(void) +{ + opexec((mem[PC] << 8) | mem[PC + 1]); + scrdrw(); + PC += 2; } void diff --git a/src/ahoy/emulator.h b/src/ahoy/emulator.h index 31d596c..e9ba11f 100644 --- a/src/ahoy/emulator.h +++ b/src/ahoy/emulator.h @@ -3,6 +3,7 @@ #include -void emulate(struct u8view); +void emuinit(struct u8view); +void emutick(void); #endif /* !AHOY_AHOY_EMULATOR_H */ diff --git a/src/ahoy/gui.c b/src/ahoy/gui.c new file mode 100644 index 0000000..1f3b748 --- /dev/null +++ b/src/ahoy/gui.c @@ -0,0 +1,71 @@ +#include + +#include + +#include "cerr.h" + +#define SCR_SCALE 10 +#define SCR_WDTH 64 +#define SCR_HIGH 32 + +#define diesx(fmt, ...) \ + diex(fmt ": %s" __VA_OPT__(,) __VA_ARGS__, SDL_GetError()) + +SDL_Window *win; +SDL_Renderer *rndr; +SDL_Texture *txtr; +SDL_AudioDeviceID adev; +unsigned long asmpcnt; +struct { + void *p; + size_t sz; +} abuf; + +void +wininit(void) +{ + SDL_AudioSpec have; + SDL_AudioSpec want = { + .freq = 64 * 60, + .format = AUDIO_F32, + .channels = 1, + .samples = 64, + }; + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) + diesx("failed to initialize SDL"); + + win = SDL_CreateWindow("Ahoy!", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, SCR_WDTH * SCR_SCALE, + SCR_HIGH * SCR_SCALE, SDL_WINDOW_RESIZABLE); + if (!win) + diesx("failed to create window"); + + rndr = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED + | SDL_RENDERER_PRESENTVSYNC); + if (!rndr) + diesx("failed to create renderer"); + + txtr = SDL_CreateTexture(rndr, SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_STREAMING, SCR_WDTH, SCR_HIGH); + if (!txtr) + diesx("failed to create texture"); + + adev = SDL_OpenAudioDevice(nullptr, 0, &want, &have, + SDL_AUDIO_ALLOW_FORMAT_CHANGE); + if (!adev) { + warnx("failed to open audio device: %s", SDL_GetError()); + return; + } + + asmpcnt = have.samples * have.channels; + abuf.sz = asmpcnt * 4; + if (!(abuf.p = malloc(abuf.sz))) + die("malloc"); + SDL_PauseAudioDevice(adev, 0); +} + +void +winfree(void) +{ +} diff --git a/src/ahoy/gui.h b/src/ahoy/gui.h new file mode 100644 index 0000000..251045e --- /dev/null +++ b/src/ahoy/gui.h @@ -0,0 +1,7 @@ +#ifndef AHOY_AHOY_GUI_H +#define AHOY_AHOY_GUI_H + +void wininit(void); +void winfree(void); + +#endif /* !AHOY_AHOY_GUI_H */ diff --git a/src/ahoy/main.c b/src/ahoy/main.c index ae7d5a1..dbc75f0 100644 --- a/src/ahoy/main.c +++ b/src/ahoy/main.c @@ -11,6 +11,7 @@ #include "cerr.h" #include "emulator.h" +#include "gui.h" #include "macros.h" [[noreturn]] static void usage(void); @@ -100,6 +101,8 @@ run(int fd, const char *fn) die("read: %s", fn); free(buf); - emulate(u8strtou8(sb)); + wininit(); + emuinit(u8strtou8(sb)); u8strfree(sb); + winfree(); } -- cgit v1.2.3