From 2d9b24f07c78c36becf41d89db30fa99863463e5 Mon Sep 17 00:00:00 2001 From: ozkl Date: Sun, 28 Feb 2021 20:44:35 +0300 Subject: [PATCH] soso nano-x port --- doomgeneric/Makefile.sosox | 54 +++++++ doomgeneric/doomgeneric_sosox.c | 259 ++++++++++++++++++++++++++++++++ 2 files changed, 313 insertions(+) create mode 100644 doomgeneric/Makefile.sosox create mode 100644 doomgeneric/doomgeneric_sosox.c diff --git a/doomgeneric/Makefile.sosox b/doomgeneric/Makefile.sosox new file mode 100644 index 0000000..0d404a0 --- /dev/null +++ b/doomgeneric/Makefile.sosox @@ -0,0 +1,54 @@ +################################################################ +# +# $Id:$ +# +# $Log:$ +# + +ifeq ($(V),1) + VB='' +else + VB=@ +endif + + +CC=soso-clang # gcc or g++ +CFLAGS+=-O3 +LDFLAGS+=$(SOSO_ROOT)/lib/crt1.o $(SOSO_ROOT)/lib/crti.o $(SOSO_ROOT)/lib/crtn.o +CFLAGS+=-I$(SOSO_ROOT)/include/nano-x -Wall -DNORMALUNIX -DLINUX -DSNDSERV -D_DEFAULT_SOURCE # -DUSEASM +LIBS+=-lnano-X -lm -lc /usr/lib/llvm-10/lib/clang/10.0.0/lib/linux/libclang_rt.builtins-i386.a + +# subdirectory for objects +OBJDIR=build +OUTPUT=doom + +SRC_DOOM = i_main.o dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_sosox.o +OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM)) + +all: $(OUTPUT) + +clean: + rm -rf $(OBJDIR) + rm -f $(OUTPUT) + rm -f $(OUTPUT).gdb + rm -f $(OUTPUT).map + +$(OUTPUT): $(OBJS) + @echo [Linking $@] + i386-soso-ld -v $(LDFLAGS) $(OBJS) -o $(OUTPUT) $(LIBS) + @echo [Size] + -$(CROSS_COMPILE)size $(OUTPUT) + cp $(OUTPUT) ~/git/soso/userspace/bin/ + +$(OBJS): | $(OBJDIR) + +$(OBJDIR): + mkdir -p $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @echo [Compiling $<] + $(VB)$(CC) $(CFLAGS) -c $< -o $@ + +print: + @echo OBJS: $(OBJS) + diff --git a/doomgeneric/doomgeneric_sosox.c b/doomgeneric/doomgeneric_sosox.c new file mode 100644 index 0000000..ff527d0 --- /dev/null +++ b/doomgeneric/doomgeneric_sosox.c @@ -0,0 +1,259 @@ +//doomgeneric for soso os (nano-x version) +//TODO: get keys from X, not using direct keyboard access! + +#include "doomkeys.h" +#include "m_argv.h" +#include "doomgeneric.h" + +#include +#include +#include +#include + +#include + +#include + +#include + +#include + + +static int g_keyboard_fd = -1; + +#define KEYQUEUE_SIZE 16 + +static unsigned short g_key_queue[KEYQUEUE_SIZE]; +static unsigned int g_key_queue_write_index = 0; +static unsigned int g_key_queue_read_index = 0; + + +static GR_WINDOW_ID wid; +static GR_GC_ID gc; +static unsigned char* windowBuffer = 0; +static const int winSizeX = DOOMGENERIC_RESX; +static const int winSizeY = DOOMGENERIC_RESY; +static int button_down = 0; + + +static unsigned char convert_to_doom_key(unsigned char scancode) +{ + unsigned char key = 0; + + switch (scancode) + { + case 0x9C: + case 0x1C: + key = KEY_ENTER; + break; + case 0x01: + key = KEY_ESCAPE; + break; + case 0xCB: + case 0x4B: + key = KEY_LEFTARROW; + break; + case 0xCD: + case 0x4D: + key = KEY_RIGHTARROW; + break; + case 0xC8: + case 0x48: + key = KEY_UPARROW; + break; + case 0xD0: + case 0x50: + key = KEY_DOWNARROW; + break; + case 0x1D: + key = KEY_FIRE; + break; + case 0x39: + key = KEY_USE; + break; + case 0x2A: + case 0x36: + key = KEY_RSHIFT; + break; + case 0x15: + key = 'y'; + break; + default: + break; + } + + return key; +} + +static void add_key_to_queue(int pressed, unsigned char key_code) +{ + unsigned char key = convert_to_doom_key(key_code); + + unsigned short key_data = (pressed << 8) | key; + + g_key_queue[g_key_queue_write_index] = key_data; + g_key_queue_write_index++; + g_key_queue_write_index %= KEYQUEUE_SIZE; +} + + +struct termios orig_termios; + +void disable_raw_mode() +{ + tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); +} + +void enable_raw_mode() +{ + tcgetattr(STDIN_FILENO, &orig_termios); + atexit(disable_raw_mode); + struct termios raw = orig_termios; + raw.c_lflag &= ~(ECHO); + raw.c_cc[VMIN] = 0; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); +} + +void DG_Init() +{ + if (GrOpen() < 0) + { + GrError("GrOpen failed"); + return; + } + + gc = GrNewGC(); + GrSetGCUseBackground(gc, GR_FALSE); + GrSetGCForeground(gc, MWRGB( 255, 0, 0 )); + + wid = GrNewBufferedWindow(GR_WM_PROPS_APPFRAME | + GR_WM_PROPS_CAPTION | + GR_WM_PROPS_CLOSEBOX | + GR_WM_PROPS_BUFFER_MMAP | + GR_WM_PROPS_BUFFER_BGRA, + "Doom", + GR_ROOT_WINDOW_ID, + 50, 50, winSizeX, winSizeY, MWRGB( 255, 255, 255 )); + + GrSelectEvents(wid, GR_EVENT_MASK_EXPOSURE | + GR_EVENT_MASK_TIMER | + GR_EVENT_MASK_CLOSE_REQ | + GR_EVENT_MASK_BUTTON_DOWN | + GR_EVENT_MASK_BUTTON_UP); + + GrMapWindow (wid); + + windowBuffer = GrOpenClientFramebuffer(wid); + + enable_raw_mode(); + + g_keyboard_fd = open("/dev/keyboard", 0); + + if (g_keyboard_fd >= 0) + { + //enter non-blocking mode + ioctl(g_keyboard_fd, 1, (void*)1); + } +} + +static void handle_key_input() +{ + if (g_keyboard_fd < 0) + { + return; + } + + unsigned char scancode = 0; + + if (read(g_keyboard_fd, &scancode, 1) > 0) + { + unsigned char keyRelease = (0x80 & scancode); + + scancode = (0x7F & scancode); + + //printf("scancode:%x pressed:%d\n", scancode, 0 == keyRelease); + + if (0 == keyRelease) + { + add_key_to_queue(1, scancode); + } + else + { + add_key_to_queue(0, scancode); + } + } +} + +void DG_DrawFrame() +{ + GR_EVENT event; + while (GrPeekEvent(&event)) + { + GrGetNextEvent(&event); + + switch (event.type) + { + case GR_EVENT_TYPE_BUTTON_DOWN: + button_down = 1; + break; + case GR_EVENT_TYPE_BUTTON_UP: + button_down = 0; + break; + + case GR_EVENT_TYPE_CLOSE_REQ: + GrClose(); + exit (0); + break; + case GR_EVENT_TYPE_EXPOSURE: + break; + case GR_EVENT_TYPE_TIMER: + + break; + } + } + + //if (button_down == 0) + { + memcpy(windowBuffer, DG_ScreenBuffer, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4); + + GrFlushWindow(wid); + } + + handle_key_input(); +} + +void DG_SleepMs(uint32_t ms) +{ + sleep_ms(ms); +} + +uint32_t DG_GetTicksMs() +{ + return get_uptime_ms(); +} + +int DG_GetKey(int* pressed, unsigned char* doomKey) +{ + if (g_key_queue_read_index == g_key_queue_write_index) + { + //key queue is empty + + return 0; + } + else + { + unsigned short keyData = g_key_queue[g_key_queue_read_index]; + g_key_queue_read_index++; + g_key_queue_read_index %= KEYQUEUE_SIZE; + + *pressed = keyData >> 8; + *doomKey = keyData & 0xFF; + + return 1; + } +} + +void DG_SetWindowTitle(const char * title) +{ + GrSetWindowTitle(wid, title); +}