170 lines
4.7 KiB
C
170 lines
4.7 KiB
C
// Save-file demo: a launch counter that persists across runs, plus a free-disk
|
|
// bar -- no text assets. On start it reads SAVES/runs.dat, increments the
|
|
// count, and writes it back; the 16-bit count shows as lit/unlit cells (MSB
|
|
// left) and a lamp reports whether the save succeeded. A bar underneath is
|
|
// scaled to jlDiskFree(). SPACE erases the save (count back to 0), ESC quits.
|
|
//
|
|
// Run it twice: the count comes back one higher each launch (on the IIgs the
|
|
// SAVES/ directory is prestaged on the disk image). Files are opt-in -- reached
|
|
// through <joey/file.h>, which the umbrella <joey/joey.h> does not include.
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <joey/joey.h>
|
|
#include <joey/file.h>
|
|
|
|
#define CELL_W 16
|
|
#define CELL_H 36
|
|
#define CELL_GAP 3
|
|
#define BITS 16
|
|
#define BITS_ORIGIN_X 12
|
|
#define BITS_ORIGIN_Y 28
|
|
|
|
#define LAMP_X 12
|
|
#define LAMP_Y 84
|
|
#define LAMP_W 40
|
|
#define LAMP_H 20
|
|
|
|
#define BAR_X 12
|
|
#define BAR_Y 128
|
|
#define BAR_H 18
|
|
#define BAR_MAX_W 280
|
|
#define BAR_BYTES_PER_PX 4096u // 1 pixel per 4 KB free
|
|
|
|
#define COLOR_BACKGROUND 0
|
|
#define COLOR_BIT_OFF 1
|
|
#define COLOR_BIT_ON 2
|
|
#define COLOR_SAVE_OK 3
|
|
#define COLOR_SAVE_FAIL 4
|
|
#define COLOR_BAR_BG 5
|
|
#define COLOR_BAR_FILL 6
|
|
|
|
#define SAVE_NAME "runs.dat"
|
|
|
|
static void buildPalette(jlSurfaceT *screen);
|
|
static void drawBar(jlSurfaceT *screen, uint32_t freeBytes);
|
|
static void drawBits(jlSurfaceT *screen, uint16_t value);
|
|
static void drawLamp(jlSurfaceT *screen, bool ok);
|
|
static uint16_t loadCount(void);
|
|
static bool storeCount(uint16_t count);
|
|
|
|
|
|
static void buildPalette(jlSurfaceT *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_BACKGROUND] = 0x0000; // black
|
|
colors[COLOR_BIT_OFF] = 0x0114; // dim blue
|
|
colors[COLOR_BIT_ON] = 0x00FF; // bright cyan
|
|
colors[COLOR_SAVE_OK] = 0x00F0; // green
|
|
colors[COLOR_SAVE_FAIL] = 0x0F00; // red
|
|
colors[COLOR_BAR_BG] = 0x0222; // gray
|
|
colors[COLOR_BAR_FILL] = 0x00FA; // teal
|
|
|
|
jlPaletteSet(screen, 0, colors);
|
|
}
|
|
|
|
|
|
static void drawBar(jlSurfaceT *screen, uint32_t freeBytes) {
|
|
uint32_t px;
|
|
|
|
jlFillRect(screen, BAR_X, BAR_Y, BAR_MAX_W, BAR_H, COLOR_BAR_BG);
|
|
px = freeBytes / BAR_BYTES_PER_PX;
|
|
if (px > (uint32_t)BAR_MAX_W) {
|
|
px = (uint32_t)BAR_MAX_W;
|
|
}
|
|
if (px > 0u) {
|
|
jlFillRect(screen, BAR_X, BAR_Y, (int16_t)px, BAR_H, COLOR_BAR_FILL);
|
|
}
|
|
}
|
|
|
|
|
|
static void drawBits(jlSurfaceT *screen, uint16_t value) {
|
|
int16_t i;
|
|
|
|
for (i = 0; i < BITS; i++) {
|
|
int16_t x = (int16_t)(BITS_ORIGIN_X + i * (CELL_W + CELL_GAP));
|
|
bool set = (value & (0x8000u >> i)) != 0u;
|
|
|
|
jlFillRect(screen, x, BITS_ORIGIN_Y, CELL_W, CELL_H, set ? COLOR_BIT_ON : COLOR_BIT_OFF);
|
|
}
|
|
}
|
|
|
|
|
|
static void drawLamp(jlSurfaceT *screen, bool ok) {
|
|
jlFillRect(screen, LAMP_X, LAMP_Y, LAMP_W, LAMP_H, ok ? COLOR_SAVE_OK : COLOR_SAVE_FAIL);
|
|
}
|
|
|
|
|
|
static uint16_t loadCount(void) {
|
|
uint16_t count;
|
|
|
|
count = 0u;
|
|
// A short read (missing file) leaves count at 0 -- first launch.
|
|
jlSaveRead(SAVE_NAME, &count, (uint32_t)sizeof(count));
|
|
return count;
|
|
}
|
|
|
|
|
|
static bool storeCount(uint16_t count) {
|
|
return jlSaveWrite(SAVE_NAME, &count, (uint32_t)sizeof(count));
|
|
}
|
|
|
|
|
|
int main(void) {
|
|
jlConfigT config;
|
|
jlSurfaceT *screen;
|
|
uint16_t count;
|
|
bool saved;
|
|
|
|
config.codegenBytes = 8 * 1024;
|
|
config.audioBytes = 64UL * 1024;
|
|
|
|
if (!jlInit(&config)) {
|
|
fprintf(stderr, "jlInit failed: %s\n", jlLastError());
|
|
return 1;
|
|
}
|
|
|
|
screen = jlStageGet();
|
|
if (screen == NULL) {
|
|
fprintf(stderr, "jlStageGet returned NULL\n");
|
|
jlShutdown();
|
|
return 1;
|
|
}
|
|
|
|
// Persist: read the prior count, bump it, write it back.
|
|
count = (uint16_t)(loadCount() + 1u);
|
|
saved = storeCount(count);
|
|
|
|
buildPalette(screen);
|
|
jlScbSetRange(screen, 0, SURFACE_HEIGHT - 1, 0);
|
|
jlSurfaceClear(screen, COLOR_BACKGROUND);
|
|
drawBits(screen, count);
|
|
drawLamp(screen, saved);
|
|
drawBar(screen, jlDiskFree());
|
|
jlStagePresent();
|
|
jlInputPoll();
|
|
|
|
for (;;) {
|
|
jlInputPoll();
|
|
if (jlKeyPressed(KEY_ESCAPE)) {
|
|
break;
|
|
}
|
|
if (jlKeyPressed(KEY_SPACE)) {
|
|
// Erase the save and reset the counter to zero.
|
|
jlSaveDelete(SAVE_NAME);
|
|
count = 0u;
|
|
saved = storeCount(count);
|
|
drawBits(screen, count);
|
|
drawLamp(screen, saved);
|
|
drawBar(screen, jlDiskFree());
|
|
jlStagePresent();
|
|
}
|
|
}
|
|
|
|
jlShutdown();
|
|
return 0;
|
|
}
|