// Audio demo: starts an embedded .MOD on entry, triggers a short // digital SFX every time SPACE is tapped, and exits on ESC. The MOD // and SFX bytes live in test_assets.h, generated from assets/test.mod // and assets/test.sfx by the audio-asset build pipeline. // // On platforms where the audio HAL is still a stub (DOS / ST / IIgs // at the moment), joeyAudioInit returns false, every audio call is a // quiet no-op, and the demo runs as a silent input loop -- you can // confirm the build links and the input plumbing still works without // hearing anything. #include #include #include "test_assets.h" #define SFX_SLOT 0 #define SFX_RATE_HZ 8000 #define COLOR_BG 0 #define COLOR_HINT 1 #define COLOR_BAR 2 #define BAR_X 16 #define BAR_Y 88 #define BAR_W (SURFACE_WIDTH - 32) #define BAR_H 16 static void buildPalette(SurfaceT *screen) { uint16_t colors[SURFACE_COLORS_PER_PALETTE]; uint16_t i; for (i = 0; i < SURFACE_COLORS_PER_PALETTE; i++) { colors[i] = 0x0000; } colors[COLOR_BG] = 0x0000; colors[COLOR_HINT] = 0x0444; colors[COLOR_BAR] = 0x00F0; paletteSet(screen, 0, colors); } // Visual feedback for "audio is running, but you cannot tell on a // stub HAL": pulse a horizontal bar between the hint color and the // active color whenever SFX has fired this frame. static void initialPaint(SurfaceT *screen, bool audioOk) { surfaceClear(screen, COLOR_BG); fillRect(screen, BAR_X, BAR_Y, BAR_W, BAR_H, audioOk ? COLOR_HINT : COLOR_BG); surfacePresent(screen); } int main(void) { JoeyConfigT config; SurfaceT *screen; bool audioOk; int16_t flashFrames; config.hostMode = HOST_MODE_TAKEOVER; config.codegenBytes = 8 * 1024; config.maxSurfaces = 4; config.audioBytes = 64 * 1024; config.assetBytes = 128 * 1024; if (!joeyInit(&config)) { fprintf(stderr, "joeyInit failed: %s\n", joeyLastError()); return 1; } screen = surfaceGetScreen(); if (screen == NULL) { fprintf(stderr, "surfaceGetScreen returned NULL\n"); joeyShutdown(); return 1; } audioOk = joeyAudioInit(); if (audioOk) { joeyAudioPlayMod(gTestMod, gTestMod_len, true); } buildPalette(screen); scbSetRange(screen, 0, SURFACE_HEIGHT - 1, 0); initialPaint(screen, audioOk); flashFrames = 0; for (;;) { joeyWaitVBL(); joeyInputPoll(); joeyAudioFrameTick(); if (joeyKeyPressed(KEY_ESCAPE)) { break; } if (joeyKeyPressed(KEY_SPACE)) { joeyAudioPlaySfx(SFX_SLOT, gTestSfx, gTestSfx_len, SFX_RATE_HZ); flashFrames = 8; } if (flashFrames > 0) { fillRect(screen, BAR_X, BAR_Y, BAR_W, BAR_H, COLOR_BAR); surfacePresentRect(screen, BAR_X, BAR_Y, BAR_W, BAR_H); flashFrames--; if (flashFrames == 0) { fillRect(screen, BAR_X, BAR_Y, BAR_W, BAR_H, COLOR_HINT); surfacePresentRect(screen, BAR_X, BAR_Y, BAR_W, BAR_H); } } } if (audioOk) { joeyAudioStopMod(); joeyAudioShutdown(); } joeyShutdown(); return 0; }