This commit is contained in:
2026-04-20 21:53:28 +08:00
parent a4f2c8eb89
commit d7e1cb62ee
19 changed files with 2154 additions and 15 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
#ifndef CLEONOS_DOOM_SHIM_H
#define CLEONOS_DOOM_SHIM_H
/* Redirect stdio-family APIs that clash with cleonos/c/src/stdio.c signatures. */
#define fopen dg_fopen
#define fclose dg_fclose
#define fread dg_fread
#define fwrite dg_fwrite
#define fseek dg_fseek
#define ftell dg_ftell
#define fflush dg_fflush
#define fgets dg_fgets
#define fprintf dg_fprintf
#define vfprintf dg_vfprintf
#define feof dg_feof
#define fileno dg_fileno
#define perror dg_perror
#define sscanf dg_sscanf
#endif

View File

@@ -0,0 +1,197 @@
#include "doomgeneric.h"
#include "doomkeys.h"
#include "../../include/cleonos_syscall.h"
#define CLEONOS_KEY_LEFT 0x01U
#define CLEONOS_KEY_RIGHT 0x02U
#define CLEONOS_KEY_UP 0x03U
#define CLEONOS_KEY_DOWN 0x04U
#define DG_KEY_QUEUE_CAP 256U
struct dg_key_event {
int pressed;
unsigned char key;
};
static struct dg_key_event g_key_queue[DG_KEY_QUEUE_CAP];
static u64 g_key_r = 0ULL;
static u64 g_key_w = 0ULL;
static cleonos_fb_info g_fb_info;
static cleonos_fb_blit_req g_blit_req;
static u64 g_scale = 1ULL;
static u64 g_dst_x = 0ULL;
static u64 g_dst_y = 0ULL;
static void dg_push_key(int pressed, unsigned char key) {
u64 next = (g_key_w + 1ULL) % DG_KEY_QUEUE_CAP;
if (next == g_key_r) {
return;
}
g_key_queue[g_key_w].pressed = pressed;
g_key_queue[g_key_w].key = key;
g_key_w = next;
}
static int dg_pop_key(int *pressed, unsigned char *key) {
if (g_key_r == g_key_w || pressed == (int *)0 || key == (unsigned char *)0) {
return 0;
}
*pressed = g_key_queue[g_key_r].pressed;
*key = g_key_queue[g_key_r].key;
g_key_r = (g_key_r + 1ULL) % DG_KEY_QUEUE_CAP;
return 1;
}
static unsigned char dg_translate_key(u64 code) {
if (code == (u64)CLEONOS_KEY_LEFT) {
return KEY_LEFTARROW;
}
if (code == (u64)CLEONOS_KEY_RIGHT) {
return KEY_RIGHTARROW;
}
if (code == (u64)CLEONOS_KEY_UP) {
return KEY_UPARROW;
}
if (code == (u64)CLEONOS_KEY_DOWN) {
return KEY_DOWNARROW;
}
if (code == (u64)'\r' || code == (u64)'\n') {
return KEY_ENTER;
}
if (code == (u64)8U || code == (u64)127U) {
return KEY_BACKSPACE;
}
if (code == (u64)27U) {
return KEY_ESCAPE;
}
if (code == (u64)'\t') {
return KEY_TAB;
}
if (code >= 32ULL && code <= 126ULL) {
return (unsigned char)(code & 0xFFULL);
}
return 0U;
}
static void dg_poll_keyboard(void) {
for (;;) {
u64 code = cleonos_sys_kbd_get_char();
unsigned char key;
if (code == (u64)-1) {
break;
}
key = dg_translate_key(code);
if (key == 0U) {
continue;
}
dg_push_key(1, key);
dg_push_key(0, key);
}
}
void DG_Init(void) {
u64 sx;
u64 sy;
g_key_r = 0ULL;
g_key_w = 0ULL;
g_fb_info.width = 0ULL;
g_fb_info.height = 0ULL;
g_fb_info.pitch = 0ULL;
g_fb_info.bpp = 0ULL;
if (cleonos_sys_fb_info(&g_fb_info) == 0ULL || g_fb_info.width == 0ULL || g_fb_info.height == 0ULL ||
g_fb_info.bpp != 32ULL) {
return;
}
sx = g_fb_info.width / (u64)DOOMGENERIC_RESX;
sy = g_fb_info.height / (u64)DOOMGENERIC_RESY;
g_scale = (sx < sy) ? sx : sy;
if (g_scale == 0ULL) {
g_scale = 1ULL;
}
if (g_scale > 4ULL) {
g_scale = 4ULL;
}
g_dst_x = (g_fb_info.width > ((u64)DOOMGENERIC_RESX * g_scale)) ? ((g_fb_info.width - ((u64)DOOMGENERIC_RESX * g_scale)) / 2ULL) : 0ULL;
g_dst_y = (g_fb_info.height > ((u64)DOOMGENERIC_RESY * g_scale)) ? ((g_fb_info.height - ((u64)DOOMGENERIC_RESY * g_scale)) / 2ULL) : 0ULL;
g_blit_req.pixels_ptr = 0ULL;
g_blit_req.src_width = (u64)DOOMGENERIC_RESX;
g_blit_req.src_height = (u64)DOOMGENERIC_RESY;
g_blit_req.src_pitch_bytes = (u64)DOOMGENERIC_RESX * 4ULL;
g_blit_req.dst_x = g_dst_x;
g_blit_req.dst_y = g_dst_y;
g_blit_req.scale = g_scale;
(void)cleonos_sys_fb_clear(0x00000000ULL);
}
void DG_DrawFrame(void) {
dg_poll_keyboard();
if (g_fb_info.width == 0ULL || g_fb_info.height == 0ULL || DG_ScreenBuffer == (pixel_t *)0) {
return;
}
g_blit_req.pixels_ptr = (u64)(void *)DG_ScreenBuffer;
(void)cleonos_sys_fb_blit(&g_blit_req);
}
void DG_SleepMs(uint32_t ms) {
u64 ticks = ((u64)ms + 9ULL) / 10ULL;
if (ticks == 0ULL && ms != 0U) {
ticks = 1ULL;
}
if (ticks > 0ULL) {
(void)cleonos_sys_sleep_ticks(ticks);
}
}
uint32_t DG_GetTicksMs(void) {
return (uint32_t)(cleonos_sys_timer_ticks() * 10ULL);
}
int DG_GetKey(int *pressed, unsigned char *key) {
dg_poll_keyboard();
return dg_pop_key(pressed, key);
}
void DG_SetWindowTitle(const char *title) {
(void)title;
}
int cl_doom_run_main(int argc, char **argv) {
doomgeneric_Create(argc, argv);
for (;;) {
doomgeneric_Tick();
}
}

View File

@@ -0,0 +1,87 @@
#include <stdio.h>
#include <string.h>
#include <cleonos_syscall.h>
int cl_doom_run_main(int argc, char **argv);
static const char *cl_doom_pick_default_wad(void) {
static const char *candidates[] = {
"/doom1.wad",
"/DOOM1.WAD",
"/temp/doom1.wad",
"/temp/DOOM1.WAD",
"/shell/doom1.wad",
"/shell/DOOM1.WAD",
};
u64 i;
for (i = 0ULL; i < (u64)(sizeof(candidates) / sizeof(candidates[0])); i++) {
if (cleonos_sys_fs_stat_size(candidates[i]) != (u64)-1) {
return candidates[i];
}
}
return (const char *)0;
}
int cleonos_app_main(int argc, char **argv, char **envp) {
char *run_argv[32];
int run_argc = 0;
int i;
const char *auto_wad = (const char *)0;
int has_iwad = 0;
(void)envp;
if (argc <= 0 || argv == (char **)0 || argv[0] == (char *)0) {
(void)printf("doom: invalid argv\n");
return 1;
}
for (i = 1; i < argc; i++) {
if (argv[i] != (char *)0 && strcmp(argv[i], "-iwad") == 0) {
has_iwad = 1;
break;
}
}
run_argv[run_argc++] = argv[0];
if (has_iwad == 0) {
if (argc > 1 && argv[1] != (char *)0 && argv[1][0] != '-') {
run_argv[run_argc++] = "-iwad";
run_argv[run_argc++] = argv[1];
for (i = 2; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
run_argv[run_argc++] = argv[i];
}
} else {
auto_wad = cl_doom_pick_default_wad();
if (auto_wad != (const char *)0) {
run_argv[run_argc++] = "-iwad";
run_argv[run_argc++] = (char *)auto_wad;
}
for (i = 1; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
run_argv[run_argc++] = argv[i];
}
}
} else {
for (i = 1; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
run_argv[run_argc++] = argv[i];
}
}
run_argv[run_argc] = (char *)0;
if (has_iwad == 0 && auto_wad == (const char *)0 && (argc <= 1 || argv[1] == (char *)0 || argv[1][0] == '-')) {
(void)printf("doom: no WAD provided\n");
(void)printf("doom: usage: doom /doom1.wad\n");
(void)printf("doom: or: doom -iwad /doom1.wad\n");
return 1;
}
(void)printf("doom: launching doomgeneric\n");
return cl_doom_run_main(run_argc, run_argv);
}

View File

@@ -15,6 +15,7 @@ static int ush_cmd_help(void) {
ush_writeln(" ansi / ansitest / color");
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
ush_writeln(" fastfetch [--plain]");
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
ush_writeln(" tty [index]");
ush_writeln(" dmesg [n]");

View File

@@ -137,6 +137,7 @@ static int ush_cmd_help(void) {
ush_writeln(" ansi / ansitest / color");
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
ush_writeln(" fastfetch [--plain]");
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
ush_writeln(" tty [index]");
ush_writeln(" dmesg [n]");