//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 <fcntl.h>
#include <unistd.h>
#include <string.h>
-
+#include <sys/time.h>
#include <sys/ioctl.h>
#include <termios.h>
-#include <soso.h>
-
-#include <nano-X.h>
-
+#include "nano-X.h"
-static int g_keyboard_fd = -1;
#define KEYQUEUE_SIZE 16
static unsigned int g_key_queue_write_index = 0;
static unsigned int g_key_queue_read_index = 0;
+static unsigned char g_key_states[256];
+
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)
+static void add_key_to_queue(int pressed, unsigned char key)
{
- 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 %= KEYQUEUE_SIZE;
}
-
struct termios orig_termios;
void disable_raw_mode()
50, 50, winSizeX, winSizeY, MWRGB( 255, 255, 255 ));
GrSelectEvents(wid, GR_EVENT_MASK_EXPOSURE |
+ GR_EVENT_MASK_KEY_UP |
+ GR_EVENT_MASK_KEY_DOWN |
GR_EVENT_MASK_TIMER |
- GR_EVENT_MASK_CLOSE_REQ |
- GR_EVENT_MASK_BUTTON_DOWN |
- GR_EVENT_MASK_BUTTON_UP);
+ GR_EVENT_MASK_CLOSE_REQ);
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()
+static unsigned char convert_to_doom_keyx(int wkey)
{
- if (g_keyboard_fd < 0)
+ unsigned char doomkey = 0;
+
+ switch (wkey)
+ {
+ case MWKEY_ENTER: doomkey = KEY_ENTER; break;
+ case MWKEY_ESCAPE: doomkey = KEY_ESCAPE; break;
+ case MWKEY_TAB: doomkey = KEY_TAB; break;
+ case MWKEY_DOWN: case MWKEY_KP2: doomkey = KEY_DOWNARROW; break;
+ case MWKEY_UP: case MWKEY_KP8: doomkey = KEY_UPARROW; break;
+ case MWKEY_LEFT: case MWKEY_KP4: doomkey = KEY_LEFTARROW; break;
+ case MWKEY_RIGHT: case MWKEY_KP6: doomkey = KEY_RIGHTARROW; break;
+ case MWKEY_LCTRL: case MWKEY_RCTRL: doomkey = KEY_FIRE; break;
+ case MWKEY_LSHIFT: case MWKEY_RSHIFT: doomkey = KEY_RSHIFT; break;
+ case ' ': doomkey = KEY_USE; break;
+ case MWKEY_F1: doomkey = KEY_F1; break;
+ case MWKEY_F2: doomkey = KEY_F2; break;
+ case MWKEY_F3: doomkey = KEY_F3; break;
+ case MWKEY_F4: doomkey = KEY_F4; break;
+ case MWKEY_F5: doomkey = KEY_F5; break;
+ case MWKEY_F6: doomkey = KEY_F6; break;
+ case MWKEY_F7: doomkey = KEY_F7; break;
+ case MWKEY_F8: doomkey = KEY_F8; break;
+ case MWKEY_F9: doomkey = KEY_F9; break;
+ case MWKEY_F10: doomkey = KEY_F10; break;
+ case MWKEY_F11: doomkey = KEY_F11; break;
+ case MWKEY_F12: doomkey = KEY_F12; break;
+
+ default:
+ break;
+ }
+
+ if ((wkey >= 'a' && wkey <= 'z') ||
+ (wkey >= 'A' && wkey <= 'Z') ||
+ (wkey >= '0' && wkey <= '9'))
{
- return;
+ doomkey = (uint8_t)wkey;
}
- 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);
- }
- }
+ return doomkey;
}
void DG_DrawFrame()
{
GR_EVENT event;
+ GR_EVENT_KEYSTROKE *kp = NULL;
+
+ unsigned char key = 0;
+
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_KEY_UP:
+ kp = (GR_EVENT_KEYSTROKE*)&event;
+ key = convert_to_doom_keyx(kp->ch);
+ if (key > 0 && key < sizeof(g_key_states))
+ {
+ unsigned char state = g_key_states[key];
+ if (state == 1)
+ {
+ g_key_states[key] = 0;
+ add_key_to_queue(0, key);
+ }
+ }
+ break;
+ case GR_EVENT_TYPE_KEY_DOWN:
+ //this event comes continuously while pressed, so checking for changes only!
+ kp = (GR_EVENT_KEYSTROKE*)&event;
+ key = convert_to_doom_keyx(kp->ch);
+ if (key > 0 && key < sizeof(g_key_states))
+ {
+ unsigned char state = g_key_states[key];
+ if (state == 0)
+ {
+ g_key_states[key] = 1;
+ add_key_to_queue(1, key);
+ }
+ }
+ break;
case GR_EVENT_TYPE_TIMER:
break;
}
}
- //if (button_down == 0)
- {
- memcpy(windowBuffer, DG_ScreenBuffer, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
+ memcpy(windowBuffer, DG_ScreenBuffer, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
- GrFlushWindow(wid);
- }
-
- handle_key_input();
+ GrFlushWindow(wid);
}
void DG_SleepMs(uint32_t ms)
{
- sleep_ms(ms);
+ usleep(ms * 1000);
}
uint32_t DG_GetTicksMs()
{
- return get_uptime_ms();
+ struct timeval tp;
+ struct timezone tzp;
+
+ gettimeofday(&tp, &tzp);
+
+ return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); /* return milliseconds */
}
int DG_GetKey(int* pressed, unsigned char* doomKey)
int main(int argc, char **argv)
{
+ memset(g_key_states, 0, sizeof(g_key_states));
+
doomgeneric_Create(argc, argv);
for (int i = 0; ; i++)
doomgeneric_Tick();
}
-
return 0;
}
\ No newline at end of file