feat(gpu): impl simple gpu, screen and keyboard
This commit is contained in:
@@ -58,7 +58,10 @@ fn compileRaylib(b: *std.Build, os: std.Target.Os.Tag, buildOpts: LibBuildOpts,
|
|||||||
|
|
||||||
const targetArg = std.fmt.allocPrint(b.allocator, "-Dtarget={s}", .{targetStr}) catch unreachable;
|
const targetArg = std.fmt.allocPrint(b.allocator, "-Dtarget={s}", .{targetStr}) catch unreachable;
|
||||||
defer b.allocator.free(targetArg);
|
defer b.allocator.free(targetArg);
|
||||||
const raylib = b.addSystemCommand(&.{ "zig", "build", targetArg });
|
|
||||||
|
// passing it breaks it for some reason?
|
||||||
|
// TODO: make it not break
|
||||||
|
const raylib = b.addSystemCommand(&.{ "zig", "build"});
|
||||||
raylib.setCwd(b.path("foreign/raylib/"));
|
raylib.setCwd(b.path("foreign/raylib/"));
|
||||||
raylib.stdio = .inherit;
|
raylib.stdio = .inherit;
|
||||||
|
|
||||||
|
|||||||
208
src/main.c
208
src/main.c
@@ -323,207 +323,6 @@ double ne_energy_accumulator(void *state, nn_Computer *c, double n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef NN_WINDOWS
|
|
||||||
// Quick self-tests for Windows-specific fixes
|
|
||||||
// These run before anything else so failures are caught early
|
|
||||||
|
|
||||||
static jmp_buf nn_test_jmpbuf;
|
|
||||||
static volatile int nn_test_caught;
|
|
||||||
|
|
||||||
static void nn_test_crash_handler(int sig) {
|
|
||||||
nn_test_caught = 1;
|
|
||||||
longjmp(nn_test_jmpbuf, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nn_test_try(void (*func)(void *), void *arg) {
|
|
||||||
nn_test_caught = 0;
|
|
||||||
signal(SIGSEGV, nn_test_crash_handler);
|
|
||||||
signal(SIGABRT, nn_test_crash_handler);
|
|
||||||
if(setjmp(nn_test_jmpbuf) == 0) {
|
|
||||||
func(arg);
|
|
||||||
}
|
|
||||||
signal(SIGSEGV, SIG_DFL);
|
|
||||||
signal(SIGABRT, SIG_DFL);
|
|
||||||
return nn_test_caught;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nn_test_failed = 0;
|
|
||||||
static int nn_test_passed = 0;
|
|
||||||
|
|
||||||
static void nn_test_report(const char *name, int crashed, int expected_crash) {
|
|
||||||
if(crashed && !expected_crash) {
|
|
||||||
printf("[CRASH] %s\n", name);
|
|
||||||
nn_test_failed++;
|
|
||||||
} else if(!crashed && expected_crash) {
|
|
||||||
printf("[FAIL] %s (expected crash)\n", name);
|
|
||||||
nn_test_failed++;
|
|
||||||
} else {
|
|
||||||
printf("[OK] %s\n", name);
|
|
||||||
nn_test_passed++;
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- realloc tests ---
|
|
||||||
|
|
||||||
static void nn_test_realloc_null(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
void *p = nn_realloc(ctx, NULL, 0, 64);
|
|
||||||
if(p == NULL) { nn_test_failed++; return; }
|
|
||||||
nn_free(ctx, p, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_realloc_grow(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
void *a = nn_alloc(ctx, 64);
|
|
||||||
if(a == NULL) return;
|
|
||||||
void *b = nn_realloc(ctx, a, 64, 128);
|
|
||||||
if(b != NULL) nn_free(ctx, b, 128);
|
|
||||||
else nn_free(ctx, a, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_realloc_free(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
void *c = nn_alloc(ctx, 64);
|
|
||||||
if(c == NULL) return;
|
|
||||||
nn_realloc(ctx, c, 64, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- lock tests ---
|
|
||||||
|
|
||||||
static void nn_test_lock_create_destroy(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
nn_Lock *lock = nn_createLock(ctx);
|
|
||||||
if(lock == NULL) { nn_test_failed++; return; }
|
|
||||||
nn_destroyLock(ctx, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_lock_cycle(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
nn_Lock *lock = nn_createLock(ctx);
|
|
||||||
if(lock == NULL) { nn_test_failed++; return; }
|
|
||||||
// lock and unlock 100 times to stress it
|
|
||||||
for(int i = 0; i < 100; i++) {
|
|
||||||
nn_lock(ctx, lock);
|
|
||||||
nn_unlock(ctx, lock);
|
|
||||||
}
|
|
||||||
nn_destroyLock(ctx, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_lock_two(void *arg) {
|
|
||||||
nn_Context *ctx = arg;
|
|
||||||
// two locks at the same time, make sure they dont interfere
|
|
||||||
nn_Lock *a = nn_createLock(ctx);
|
|
||||||
nn_Lock *b = nn_createLock(ctx);
|
|
||||||
if(a == NULL || b == NULL) { nn_test_failed++; return; }
|
|
||||||
nn_lock(ctx, a);
|
|
||||||
nn_lock(ctx, b);
|
|
||||||
nn_unlock(ctx, b);
|
|
||||||
nn_unlock(ctx, a);
|
|
||||||
nn_destroyLock(ctx, a);
|
|
||||||
nn_destroyLock(ctx, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- VFS tests ---
|
|
||||||
|
|
||||||
static void nn_test_vfs_stat(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
// stat current directory, should always work
|
|
||||||
ncl_Stat s;
|
|
||||||
bool ok = ncl_stat(ncl_defaultFS, ".", &s);
|
|
||||||
if(!ok) nn_test_failed++;
|
|
||||||
if(!s.isDirectory) nn_test_failed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_vfs_dir(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
void *dir = ncl_opendir(ncl_defaultFS, ".");
|
|
||||||
if(dir == NULL) { nn_test_failed++; return; }
|
|
||||||
char name[NN_MAX_PATH];
|
|
||||||
// just read one entry, dont care what it is
|
|
||||||
ncl_readdir(ncl_defaultFS, dir, name);
|
|
||||||
ncl_closedir(ncl_defaultFS, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_vfs_mkdir_remove(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
const char *testdir = "nn_test_tmpdir";
|
|
||||||
ncl_mkdir(ncl_defaultFS, testdir);
|
|
||||||
ncl_Stat s;
|
|
||||||
bool ok = ncl_stat(ncl_defaultFS, testdir, &s);
|
|
||||||
if(!ok || !s.isDirectory) nn_test_failed++;
|
|
||||||
ncl_remove(ncl_defaultFS, testdir);
|
|
||||||
// should be gone now
|
|
||||||
ok = ncl_stat(ncl_defaultFS, testdir, &s);
|
|
||||||
if(ok) nn_test_failed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_test_vfs_seek(void *arg) {
|
|
||||||
(void)arg;
|
|
||||||
// write a small file, seek around, read back
|
|
||||||
const char *path = "nn_test_seekfile";
|
|
||||||
const char *data = "abcdefghij";
|
|
||||||
void *f = ncl_openfile(ncl_defaultFS, path, "w");
|
|
||||||
if(f == NULL) { nn_test_failed++; return; }
|
|
||||||
ncl_writefile(ncl_defaultFS, f, data, 10);
|
|
||||||
ncl_closefile(ncl_defaultFS, f);
|
|
||||||
|
|
||||||
f = ncl_openfile(ncl_defaultFS, path, "r");
|
|
||||||
if(f == NULL) { nn_test_failed++; ncl_remove(ncl_defaultFS, path); return; }
|
|
||||||
// seek to offset 5 from start
|
|
||||||
int off = 5;
|
|
||||||
bool ok = ncl_seekfile(ncl_defaultFS, f, NN_SEEK_SET, &off);
|
|
||||||
if(!ok || off != 5) nn_test_failed++;
|
|
||||||
// read from there
|
|
||||||
char buf[5];
|
|
||||||
size_t len = 5;
|
|
||||||
ok = ncl_readfile(ncl_defaultFS, f, buf, &len);
|
|
||||||
if(!ok || len != 5) nn_test_failed++;
|
|
||||||
// should be "fghij"
|
|
||||||
if(buf[0] != 'f' || buf[4] != 'j') nn_test_failed++;
|
|
||||||
ncl_closefile(ncl_defaultFS, f);
|
|
||||||
ncl_remove(ncl_defaultFS, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nn_run_selftests(nn_Context *ctx) {
|
|
||||||
printf("--- nn self tests ---\n");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
nn_test_report("realloc(NULL)",
|
|
||||||
nn_test_try(nn_test_realloc_null, ctx), 0);
|
|
||||||
nn_test_report("realloc(ptr, grow)",
|
|
||||||
nn_test_try(nn_test_realloc_grow, ctx), 0);
|
|
||||||
nn_test_report("realloc(ptr, free)",
|
|
||||||
nn_test_try(nn_test_realloc_free, ctx), 0);
|
|
||||||
|
|
||||||
nn_test_report("lock create/destroy",
|
|
||||||
nn_test_try(nn_test_lock_create_destroy, ctx), 0);
|
|
||||||
nn_test_report("lock 100 cycles",
|
|
||||||
nn_test_try(nn_test_lock_cycle, ctx), 0);
|
|
||||||
nn_test_report("two locks interleaved",
|
|
||||||
nn_test_try(nn_test_lock_two, ctx), 0);
|
|
||||||
|
|
||||||
nn_test_report("vfs stat cwd",
|
|
||||||
nn_test_try(nn_test_vfs_stat, NULL), 0);
|
|
||||||
nn_test_report("vfs readdir cwd",
|
|
||||||
nn_test_try(nn_test_vfs_dir, NULL), 0);
|
|
||||||
nn_test_report("vfs mkdir/remove",
|
|
||||||
nn_test_try(nn_test_vfs_mkdir_remove, NULL), 0);
|
|
||||||
nn_test_report("vfs seek",
|
|
||||||
nn_test_try(nn_test_vfs_seek, NULL), 0);
|
|
||||||
|
|
||||||
printf("--- %d passed, %d failed ---\n\n", nn_test_passed, nn_test_failed);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if(nn_test_failed > 0) {
|
|
||||||
printf("self tests failed, aborting\n");
|
|
||||||
fflush(stdout);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
const char *player = getenv("USER");
|
const char *player = getenv("USER");
|
||||||
#ifdef NN_WINDOWS
|
#ifdef NN_WINDOWS
|
||||||
@@ -608,7 +407,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]);
|
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]);
|
||||||
nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]);
|
nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]);
|
||||||
|
nn_Component *keyboard = nn_createComponent(
|
||||||
|
u, "mainKB", "keyboard");
|
||||||
|
|
||||||
|
ncl_ScreenState *scrstate = nn_getComponentState(screen);
|
||||||
|
ncl_mountKeyboard(scrstate, "mainKB");
|
||||||
{
|
{
|
||||||
// draw test
|
// draw test
|
||||||
const char *s = "hello there";
|
const char *s = "hello there";
|
||||||
@@ -638,7 +441,7 @@ restart:;
|
|||||||
nn_mountComponent(c, eepromCard, 0);
|
nn_mountComponent(c, eepromCard, 0);
|
||||||
nn_mountComponent(c, managedfs, 1);
|
nn_mountComponent(c, managedfs, 1);
|
||||||
nn_mountComponent(c, gpuCard, 2);
|
nn_mountComponent(c, gpuCard, 2);
|
||||||
|
nn_mountComponent(c, keyboard, -1);
|
||||||
while(true) {
|
while(true) {
|
||||||
if(WindowShouldClose()) break;
|
if(WindowShouldClose()) break;
|
||||||
|
|
||||||
@@ -773,6 +576,7 @@ cleanup:;
|
|||||||
nn_dropComponent(managedfs);
|
nn_dropComponent(managedfs);
|
||||||
nn_dropComponent(screen);
|
nn_dropComponent(screen);
|
||||||
nn_dropComponent(gpuCard);
|
nn_dropComponent(gpuCard);
|
||||||
|
nn_dropComponent(keyboard);
|
||||||
// rip the universe
|
// rip the universe
|
||||||
nn_destroyUniverse(u);
|
nn_destroyUniverse(u);
|
||||||
UnloadFont(font);
|
UnloadFont(font);
|
||||||
|
|||||||
1084
src/ncomplib.c
1084
src/ncomplib.c
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "neonucleus.h"
|
#include "neonucleus.h"
|
||||||
|
|
||||||
|
#define NCL_PREFIX "ncl-"
|
||||||
|
|
||||||
#define NCL_EEPROM "ncl-eeprom"
|
#define NCL_EEPROM "ncl-eeprom"
|
||||||
#define NCL_FS "ncl-filesystem"
|
#define NCL_FS "ncl-filesystem"
|
||||||
#define NCL_DRIVE "ncl-drive"
|
#define NCL_DRIVE "ncl-drive"
|
||||||
@@ -194,9 +196,6 @@ size_t ncl_getLabel(nn_Component *c, char buf[NN_MAX_LABEL]);
|
|||||||
size_t ncl_setLabel(nn_Component *c, const char *label, size_t len);
|
size_t ncl_setLabel(nn_Component *c, const char *label, size_t len);
|
||||||
|
|
||||||
nn_Component *ncl_createFilesystem(nn_Universe *universe, const char *address, const char *path, const nn_Filesystem *fs, bool isReadonly);
|
nn_Component *ncl_createFilesystem(nn_Universe *universe, const char *address, const char *path, const nn_Filesystem *fs, bool isReadonly);
|
||||||
nn_Component *ncl_createDrive(nn_Universe *universe, const char *address, const char *path, const nn_Drive *drive, bool isReadonly);
|
|
||||||
// data is stored interally
|
|
||||||
nn_Component *ncl_createEEPROM(nn_Universe *universe, const char *address, const char *path, bool isReadonly);
|
|
||||||
|
|
||||||
#define NCL_VFS_NAMEMAX 32
|
#define NCL_VFS_NAMEMAX 32
|
||||||
|
|
||||||
@@ -207,13 +206,17 @@ nn_Component *ncl_createEEPROM(nn_Universe *universe, const char *address, const
|
|||||||
// and tmpfs.
|
// and tmpfs.
|
||||||
nn_Component *ncl_createTmpFS(nn_Universe *universe, const nn_Filesystem *fs);
|
nn_Component *ncl_createTmpFS(nn_Universe *universe, const nn_Filesystem *fs);
|
||||||
|
|
||||||
// creates a temporary EEPROM, with some initial code
|
nn_Component *ncl_createDrive(nn_Universe *universe, const char *address, const char *path, const nn_Drive *drive, bool isReadonly);
|
||||||
// the data is stored internally
|
|
||||||
nn_Component *ncl_createTmpEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const char *code, size_t codelen);
|
|
||||||
|
|
||||||
// creates a temporary drive, with some initial data
|
// creates a temporary drive, with some initial data
|
||||||
nn_Component *ncl_createTmpDrive(nn_Universe *universe, const nn_EEPROM *eeprom, const char *data, size_t datalen);
|
nn_Component *ncl_createTmpDrive(nn_Universe *universe, const nn_EEPROM *eeprom, const char *data, size_t datalen);
|
||||||
|
|
||||||
|
// data is stored interally
|
||||||
|
nn_Component *ncl_createEEPROM(nn_Universe *universe, const char *address, const char *path, bool isReadonly);
|
||||||
|
// creates a temporary EEPROM, with some initial code
|
||||||
|
// the data is stored internally
|
||||||
|
nn_Component *ncl_createTmpEEPROM(nn_Universe *universe, const nn_EEPROM *eeprom, const char *code, size_t codelen);
|
||||||
|
|
||||||
// Gets the VFS bound to a filesystem, drive or eeprom.
|
// Gets the VFS bound to a filesystem, drive or eeprom.
|
||||||
// Returns the default FS if the component is not recognized.
|
// Returns the default FS if the component is not recognized.
|
||||||
ncl_VFS ncl_getVFS(nn_Component *component);
|
ncl_VFS ncl_getVFS(nn_Component *component);
|
||||||
@@ -293,11 +296,18 @@ typedef struct ncl_ComponentStat {
|
|||||||
};
|
};
|
||||||
} ncl_ComponentStat;
|
} ncl_ComponentStat;
|
||||||
|
|
||||||
|
bool ncl_isNCLID(const char *type);
|
||||||
|
bool ncl_isNCLComponent(nn_Component *component);
|
||||||
void ncl_statComponent(nn_Component *component, ncl_ComponentStat *stat);
|
void ncl_statComponent(nn_Component *component, ncl_ComponentStat *stat);
|
||||||
// For EEPROMs, filesystems, drives
|
// For EEPROMs, filesystems, drives
|
||||||
// Returns whether it was successful or not.
|
// Returns whether it was successful or not.
|
||||||
bool ncl_makeReadonly(nn_Component *component);
|
bool ncl_makeReadonly(nn_Component *component);
|
||||||
|
|
||||||
|
// Returns the amount of data written.
|
||||||
|
// The capacity MUST be at least the data size of the EEPROM.
|
||||||
|
size_t ncl_getEEPROMData(nn_Component *component, char *buf);
|
||||||
|
void ncl_setEEPROMData(nn_Component *component, const char *data, size_t len);
|
||||||
|
|
||||||
void ncl_lockScreen(ncl_ScreenState *state);
|
void ncl_lockScreen(ncl_ScreenState *state);
|
||||||
void ncl_unlockScreen(ncl_ScreenState *state);
|
void ncl_unlockScreen(ncl_ScreenState *state);
|
||||||
void ncl_resetScreen(ncl_ScreenState *state);
|
void ncl_resetScreen(ncl_ScreenState *state);
|
||||||
|
|||||||
1117
src/neonucleus.c
1117
src/neonucleus.c
File diff suppressed because it is too large
Load Diff
185
src/neonucleus.h
185
src/neonucleus.h
@@ -1229,24 +1229,8 @@ typedef struct nn_ScreenConfig {
|
|||||||
// OC has 3 tiers, NN adds a 4th one as well.
|
// OC has 3 tiers, NN adds a 4th one as well.
|
||||||
extern const nn_ScreenConfig nn_defaultScreens[4];
|
extern const nn_ScreenConfig nn_defaultScreens[4];
|
||||||
|
|
||||||
typedef enum nn_ScreenAction {
|
|
||||||
NN_SCREEN_DROP,
|
|
||||||
} nn_ScreenAction;
|
|
||||||
|
|
||||||
typedef struct nn_ScreenRequest {
|
|
||||||
nn_Context *ctx;
|
|
||||||
nn_Computer *computer;
|
|
||||||
void *state;
|
|
||||||
const nn_ScreenConfig *screen;
|
|
||||||
nn_ScreenAction action;
|
|
||||||
} nn_ScreenRequest;
|
|
||||||
|
|
||||||
typedef nn_Exit (nn_ScreenHandler)(nn_ScreenRequest *req);
|
|
||||||
|
|
||||||
nn_Component *nn_createScreen(nn_Universe *universe, const char *address, const nn_ScreenConfig *scrconf, void *state, nn_ScreenHandler *handler);
|
|
||||||
|
|
||||||
// GPU class
|
// GPU class
|
||||||
|
|
||||||
typedef struct nn_GPU {
|
typedef struct nn_GPU {
|
||||||
// the minimum between these and the screen's
|
// the minimum between these and the screen's
|
||||||
// are the maximum width/height/depth supported.
|
// are the maximum width/height/depth supported.
|
||||||
@@ -1275,20 +1259,175 @@ typedef struct nn_GPU {
|
|||||||
extern const nn_GPU nn_defaultGPUs[4];
|
extern const nn_GPU nn_defaultGPUs[4];
|
||||||
|
|
||||||
typedef enum nn_GPUAction {
|
typedef enum nn_GPUAction {
|
||||||
NN_GPU_DROP,
|
NN_GPU_DROP,
|
||||||
|
NN_GPU_BIND,
|
||||||
|
NN_GPU_GETSCREEN,
|
||||||
|
NN_GPU_GETBG,
|
||||||
|
NN_GPU_SETBG,
|
||||||
|
NN_GPU_GETFG,
|
||||||
|
NN_GPU_SETFG,
|
||||||
|
NN_GPU_GETPALETTE,
|
||||||
|
NN_GPU_SETPALETTE,
|
||||||
|
NN_GPU_MAXDEPTH,
|
||||||
|
NN_GPU_GETDEPTH,
|
||||||
|
NN_GPU_SETDEPTH,
|
||||||
|
NN_GPU_MAXRES,
|
||||||
|
NN_GPU_GETRES,
|
||||||
|
NN_GPU_SETRES,
|
||||||
|
NN_GPU_GETVIEWPORT,
|
||||||
|
NN_GPU_SETVIEWPORT,
|
||||||
|
NN_GPU_GET,
|
||||||
|
NN_GPU_SET,
|
||||||
|
NN_GPU_COPY,
|
||||||
|
NN_GPU_FILL,
|
||||||
|
NN_GPU_GETACTIVEBUF,
|
||||||
|
NN_GPU_SETACTIVEBUF,
|
||||||
|
NN_GPU_BUFFERS,
|
||||||
|
NN_GPU_ALLOCBUF,
|
||||||
|
NN_GPU_FREEBUF,
|
||||||
|
NN_GPU_FREEALLBUFS,
|
||||||
|
NN_GPU_FREEMEM,
|
||||||
|
NN_GPU_GETBUFSIZE,
|
||||||
|
NN_GPU_BITBLT,
|
||||||
} nn_GPUAction;
|
} nn_GPUAction;
|
||||||
|
|
||||||
typedef struct nn_GPURequest {
|
typedef struct nn_GPURequest {
|
||||||
nn_Context *ctx;
|
nn_Context *ctx;
|
||||||
nn_Computer *computer;
|
nn_Computer *computer;
|
||||||
void *state;
|
void *state;
|
||||||
const nn_GPU *gpu;
|
const nn_GPU *gpu;
|
||||||
nn_GPUAction action;
|
nn_GPUAction action;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
const char *address;
|
||||||
|
bool reset;
|
||||||
|
} bind;
|
||||||
|
// GETSCREEN result
|
||||||
|
char screenAddr[NN_MAX_ADDRESS];
|
||||||
|
// GET/SET BG/FG
|
||||||
|
struct {
|
||||||
|
int color;
|
||||||
|
bool isPalette;
|
||||||
|
int oldColor;
|
||||||
|
bool wasPalette;
|
||||||
|
int oldPaletteIdx; // -1 if none
|
||||||
|
} color;
|
||||||
|
// GET/SET PALETTE
|
||||||
|
struct {
|
||||||
|
int index;
|
||||||
|
int color;
|
||||||
|
int oldColor;
|
||||||
|
} palette;
|
||||||
|
// MAXDEPTH / GETDEPTH / SETDEPTH
|
||||||
|
struct {
|
||||||
|
char depth;
|
||||||
|
char oldDepth;
|
||||||
|
} depth;
|
||||||
|
// MAXRES/GETRES/SETRES/GETVIEWPORT/SETVIEWPORT
|
||||||
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} resolution;
|
||||||
|
// GET pixel
|
||||||
|
struct {
|
||||||
|
int x, y;
|
||||||
|
nn_codepoint codepoint;
|
||||||
|
int fg, bg;
|
||||||
|
int fgIdx, bgIdx; // -1 if not palette
|
||||||
|
} get;
|
||||||
|
// SET string
|
||||||
|
struct {
|
||||||
|
int x, y;
|
||||||
|
const char *value;
|
||||||
|
size_t len;
|
||||||
|
bool vertical;
|
||||||
|
} set;
|
||||||
|
// COPY
|
||||||
|
struct {
|
||||||
|
int x, y, w, h, tx, ty;
|
||||||
|
} copy;
|
||||||
|
// FILL
|
||||||
|
struct {
|
||||||
|
int x, y, w, h;
|
||||||
|
nn_codepoint codepoint;
|
||||||
|
} fill;
|
||||||
|
// GET/SET ACTIVE BUFFER, FREE BUFFER
|
||||||
|
struct {
|
||||||
|
int index;
|
||||||
|
} buffer;
|
||||||
|
// ALLOCATE BUFFER
|
||||||
|
struct {
|
||||||
|
int w, h, index;
|
||||||
|
} allocBuf;
|
||||||
|
// TOTALMEM / FREEMEM
|
||||||
|
size_t memory;
|
||||||
|
// GETBUFSIZE
|
||||||
|
struct {
|
||||||
|
int index, w, h;
|
||||||
|
} bufSize;
|
||||||
|
// BITBLT
|
||||||
|
struct {
|
||||||
|
int dst, col, row, w, h;
|
||||||
|
int src, fromCol, fromRow;
|
||||||
|
} bitblt;
|
||||||
|
// BUFFERS / count returned here, indices
|
||||||
|
// pushed on stack by handler
|
||||||
|
size_t bufCount;
|
||||||
|
};
|
||||||
} nn_GPURequest;
|
} nn_GPURequest;
|
||||||
|
|
||||||
typedef nn_Exit (nn_GPUHandler)(nn_GPURequest *req);
|
typedef nn_Exit (nn_GPUHandler)(nn_GPURequest *req);
|
||||||
|
|
||||||
nn_Component *nn_createGPU(nn_Universe *universe, const char *address, const nn_GPU *gpu, void *state, nn_GPUHandler *handler);
|
nn_Component *nn_createGPU(
|
||||||
|
nn_Universe *universe, const char *address,
|
||||||
|
const nn_GPU *gpu, void *state,
|
||||||
|
nn_GPUHandler *handler);
|
||||||
|
|
||||||
|
typedef enum nn_ScreenAction {
|
||||||
|
NN_SCREEN_DROP,
|
||||||
|
NN_SCREEN_ISON,
|
||||||
|
NN_SCREEN_TURNON,
|
||||||
|
NN_SCREEN_TURNOFF,
|
||||||
|
NN_SCREEN_GETASPECTRATIO,
|
||||||
|
NN_SCREEN_GETKEYBOARDS,
|
||||||
|
NN_SCREEN_SETPRECISE,
|
||||||
|
NN_SCREEN_ISPRECISE,
|
||||||
|
NN_SCREEN_SETTOUCHINVERTED,
|
||||||
|
NN_SCREEN_ISTOUCHINVERTED,
|
||||||
|
} nn_ScreenAction;
|
||||||
|
|
||||||
|
typedef struct nn_ScreenRequest {
|
||||||
|
nn_Context *ctx;
|
||||||
|
nn_Computer *computer;
|
||||||
|
void *state;
|
||||||
|
const nn_ScreenConfig *screen;
|
||||||
|
nn_ScreenAction action;
|
||||||
|
union {
|
||||||
|
// turnOn / turnOff / isOn
|
||||||
|
struct {
|
||||||
|
bool wasOn;
|
||||||
|
bool isOn;
|
||||||
|
} power;
|
||||||
|
// getAspectRatio
|
||||||
|
struct {
|
||||||
|
int w, h;
|
||||||
|
} aspect;
|
||||||
|
// getKeyboards — addresses pushed on stack by
|
||||||
|
// handler; count returned here
|
||||||
|
size_t kbCount;
|
||||||
|
// setPrecise / isPrecise /
|
||||||
|
// setTouchModeInverted / isTouchModeInverted
|
||||||
|
bool flag;
|
||||||
|
};
|
||||||
|
} nn_ScreenRequest;
|
||||||
|
|
||||||
|
typedef nn_Exit (nn_ScreenHandler)(nn_ScreenRequest *req);
|
||||||
|
|
||||||
|
nn_Component *nn_createScreen(
|
||||||
|
nn_Universe *universe, const char *address,
|
||||||
|
const nn_ScreenConfig *scrconf, void *state,
|
||||||
|
nn_ScreenHandler *handler
|
||||||
|
);
|
||||||
|
|
||||||
// Colors and palettes.
|
// Colors and palettes.
|
||||||
// Do note that the
|
// Do note that the
|
||||||
|
|||||||
Reference in New Issue
Block a user