--- /dev/null
+//doomgeneric for soso os
+
+#include "doomkeys.h"
+
+#include "doomgeneric.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sosousdk.h>
+#include "../kernel/termios.h"
+
+static int FrameBufferFd = -1;
+static int* FrameBuffer = 0;
+
+static int KeyboardFd = -1;
+
+#define KEYQUEUE_SIZE 16
+
+static unsigned short s_KeyQueue[KEYQUEUE_SIZE];
+static unsigned int s_KeyQueueWriteIndex = 0;
+static unsigned int s_KeyQueueReadIndex = 0;
+
+static unsigned char convertToDoomKey(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;
+ default:
+ break;
+ }
+
+ return key;
+}
+
+static void addKeyToQueue(int pressed, unsigned char keyCode)
+{
+ unsigned char key = convertToDoomKey(keyCode);
+
+ unsigned short keyData = (pressed << 8) | key;
+
+ s_KeyQueue[s_KeyQueueWriteIndex] = keyData;
+ s_KeyQueueWriteIndex++;
+ s_KeyQueueWriteIndex %= KEYQUEUE_SIZE;
+}
+
+
+struct termios orig_termios;
+
+void disableRawMode() {
+ //printf("returning original termios\n");
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+ tcgetattr(STDIN_FILENO, &orig_termios);
+ atexit(disableRawMode);
+ struct termios raw = orig_termios;
+ raw.c_lflag &= ~(ECHO | ICANON);
+ //raw.c_lflag &= ~(ECHO);
+ raw.c_cc[VMIN] = 0;
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+void DG_Init()
+{
+ FrameBufferFd = open("/dev/fb0", 0);
+
+ if (FrameBufferFd >= 0)
+ {
+ FrameBuffer = mmap(NULL, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4, 0, FrameBufferFd, 0);
+
+ if (FrameBuffer != (int*)-1)
+ {
+ printf("mmap success\n");
+ }
+ else
+ {
+ printf("mmap failed\n");
+ }
+ }
+ else
+ {
+ printf("opening device failed!\n");
+ }
+
+ enableRawMode();
+
+ KeyboardFd = open("/dev/keyboard", 0);
+
+ if (KeyboardFd >= 0)
+ {
+ //enter non-blocking mode
+ syscall_ioctl(KeyboardFd, 1, (void*)1);
+ }
+}
+
+static void handleKeyInput()
+{
+ if (KeyboardFd < 0)
+ {
+ return;
+ }
+
+ unsigned char scancode = 0;
+
+ if (read(KeyboardFd, &scancode, 1) > 0)
+ {
+ unsigned char keyRelease = (0x80 & scancode);
+
+ scancode = (0x7F & scancode);
+
+ //printf("scancode:%x pressed:%d\n", scancode, 0 == keyRelease);
+
+ if (0 == keyRelease)
+ {
+ addKeyToQueue(1, scancode);
+ }
+ else
+ {
+ addKeyToQueue(0, scancode);
+ }
+ }
+}
+
+void DG_DrawFrame()
+{
+ if (FrameBuffer)
+ {
+ //memcpy(FrameBuffer, DG_ScreenBuffer, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
+
+ const int screenWidth = 1024;
+
+ for (int i = 0; i < DOOMGENERIC_RESY; ++i)
+ {
+ memcpy(FrameBuffer + i * screenWidth, DG_ScreenBuffer + i * DOOMGENERIC_RESX, DOOMGENERIC_RESX * 4);
+ }
+ }
+
+ handleKeyInput();
+}
+
+void DG_SleepMs(uint32_t ms)
+{
+ sleepMilliseconds(ms);
+}
+
+uint32_t DG_GetTicksMs()
+{
+ return getUptimeMilliseconds();
+}
+
+int DG_GetKey(int* pressed, unsigned char* doomKey)
+{
+ if (s_KeyQueueReadIndex == s_KeyQueueWriteIndex)
+ {
+ //key queue is empty
+
+ return 0;
+ }
+ else
+ {
+ unsigned short keyData = s_KeyQueue[s_KeyQueueReadIndex];
+ s_KeyQueueReadIndex++;
+ s_KeyQueueReadIndex %= KEYQUEUE_SIZE;
+
+ *pressed = keyData >> 8;
+ *doomKey = keyData & 0xFF;
+
+ return 1;
+ }
+}