From 9d7126c11b5f1577b00987b8d5f0f7f761b012d7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 4 Jun 2007 18:32:50 +0000 Subject: Rename txt_main.c to txt_sdl.c; add txt_sdl.h for SDL-specific API functions, while keeping txt_main.h for the common API. Add TXT_SDL_SetEventCallback to allow programs to intercept SDL events in the textscreen main loop. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 892 --- textscreen/Makefile.am | 3 +- textscreen/txt_desktop.c | 1 + textscreen/txt_main.c | 525 --------------------------------------------- textscreen/txt_main.h | 8 +- textscreen/txt_sdl.c | 548 +++++++++++++++++++++++++++++++++++++++++++++++ textscreen/txt_sdl.h | 50 +++++ 6 files changed, 605 insertions(+), 530 deletions(-) delete mode 100644 textscreen/txt_main.c create mode 100644 textscreen/txt_sdl.c create mode 100644 textscreen/txt_sdl.h diff --git a/textscreen/Makefile.am b/textscreen/Makefile.am index 71989c3b..752e6361 100644 --- a/textscreen/Makefile.am +++ b/textscreen/Makefile.am @@ -15,12 +15,13 @@ libtextscreen_a_SOURCES = \ txt_gui.c txt_gui.h \ txt_inputbox.c txt_inputbox.h \ txt_io.c txt_io.h \ - txt_main.c txt_main.h \ + txt_main.h \ txt_button.c txt_button.h \ txt_label.c txt_label.h \ txt_radiobutton.c txt_radiobutton.h \ txt_separator.c txt_separator.h \ txt_spinctrl.c txt_spinctrl.h \ + txt_sdl.c txt_sdl.h \ txt_strut.c txt_strut.h \ txt_table.c txt_table.h \ txt_widget.c txt_widget.h \ diff --git a/textscreen/txt_desktop.c b/textscreen/txt_desktop.c index ee6c1671..4b90ed66 100644 --- a/textscreen/txt_desktop.c +++ b/textscreen/txt_desktop.c @@ -19,6 +19,7 @@ // 02111-1307, USA. // +#include #include #include diff --git a/textscreen/txt_main.c b/textscreen/txt_main.c deleted file mode 100644 index f184ce0f..00000000 --- a/textscreen/txt_main.c +++ /dev/null @@ -1,525 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright(C) 2005,2006 Simon Howard -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// -//----------------------------------------------------------------------------- -// -// Text mode emulation in SDL -// -//----------------------------------------------------------------------------- - -#include "SDL.h" - -#include -#include -#include - -#include "doomkeys.h" - -#include "txt_main.h" -#include "txt_font.h" - -#define CHAR_W 8 -#define CHAR_H 16 - -// Time between character blinks in ms - -#define BLINK_PERIOD 250 - -static SDL_Surface *screen; -static unsigned char *screendata; -static int key_mapping = 1; - -//#define TANGO - -#ifndef TANGO - -static SDL_Color ega_colors[] = -{ - {0x00, 0x00, 0x00, 0x00}, // 0: Black - {0x00, 0x00, 0xa8, 0x00}, // 1: Blue - {0x00, 0xa8, 0x00, 0x00}, // 2: Green - {0x00, 0xa8, 0xa8, 0x00}, // 3: Cyan - {0xa8, 0x00, 0x00, 0x00}, // 4: Red - {0xa8, 0x00, 0xa8, 0x00}, // 5: Magenta - {0xa8, 0x54, 0x00, 0x00}, // 6: Brown - {0xa8, 0xa8, 0xa8, 0x00}, // 7: Grey - {0x54, 0x54, 0x54, 0x00}, // 8: Dark grey - {0x54, 0x54, 0xfe, 0x00}, // 9: Bright blue - {0x54, 0xfe, 0x54, 0x00}, // 10: Bright green - {0x54, 0xfe, 0xfe, 0x00}, // 11: Bright cyan - {0xfe, 0x54, 0x54, 0x00}, // 12: Bright red - {0xfe, 0x54, 0xfe, 0x00}, // 13: Bright magenta - {0xfe, 0xfe, 0x54, 0x00}, // 14: Yellow - {0xfe, 0xfe, 0xfe, 0x00}, // 15: Bright white -}; - -#else - -// Colors that fit the Tango desktop guidelines: see -// http://tango.freedesktop.org/ also -// http://uwstopia.nl/blog/2006/07/tango-terminal - -static SDL_Color ega_colors[] = -{ - {0x2e, 0x34, 0x36, 0x00}, // 0: Black - {0x34, 0x65, 0xa4, 0x00}, // 1: Blue - {0x4e, 0x9a, 0x06, 0x00}, // 2: Green - {0x06, 0x98, 0x9a, 0x00}, // 3: Cyan - {0xcc, 0x00, 0x00, 0x00}, // 4: Red - {0x75, 0x50, 0x7b, 0x00}, // 5: Magenta - {0xc4, 0xa0, 0x00, 0x00}, // 6: Brown - {0xd3, 0xd7, 0xcf, 0x00}, // 7: Grey - {0x55, 0x57, 0x53, 0x00}, // 8: Dark grey - {0x72, 0x9f, 0xcf, 0x00}, // 9: Bright blue - {0x8a, 0xe2, 0x34, 0x00}, // 10: Bright green - {0x34, 0xe2, 0xe2, 0x00}, // 11: Bright cyan - {0xef, 0x29, 0x29, 0x00}, // 12: Bright red - {0x34, 0xe2, 0xe2, 0x00}, // 13: Bright magenta - {0xfc, 0xe9, 0x4f, 0x00}, // 14: Yellow - {0xee, 0xee, 0xec, 0x00}, // 15: Bright white -}; - -#endif - -// -// Initialise text mode screen -// -// Returns 1 if successful, 0 if an error occurred -// - -int TXT_Init(void) -{ - SDL_InitSubSystem(SDL_INIT_VIDEO); - - screen = SDL_SetVideoMode(TXT_SCREEN_W * CHAR_W, TXT_SCREEN_H * CHAR_H, 8, 0); - - if (screen == NULL) - return 0; - - SDL_SetColors(screen, ega_colors, 0, 16); - SDL_EnableUNICODE(1); - - screendata = malloc(TXT_SCREEN_W * TXT_SCREEN_H * 2); - memset(screendata, 0, TXT_SCREEN_W * TXT_SCREEN_H * 2); - - // Ignore all mouse motion events - - SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); - - // Repeat key presses so we can hold down arrows to scroll down the - // menu, for example. This is what setup.exe does. - - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - - return 1; -} - -void TXT_Shutdown(void) -{ - free(screendata); - SDL_QuitSubSystem(SDL_INIT_VIDEO); -} - -unsigned char *TXT_GetScreenData(void) -{ - return screendata; -} - -static inline void UpdateCharacter(int x, int y) -{ - unsigned char character; - unsigned char *p; - unsigned char *s, *s1; - int bg, fg; - int x1, y1; - - p = &screendata[(y * TXT_SCREEN_W + x) * 2]; - character = p[0]; - - fg = p[1] & 0xf; - bg = (p[1] >> 4) & 0xf; - - if (bg & 0x8) - { - // blinking - - bg &= ~0x8; - - if (((SDL_GetTicks() / BLINK_PERIOD) % 2) == 0) - { - fg = bg; - } - } - - p = &int10_font_16[character * CHAR_H]; - - s = ((unsigned char *) screen->pixels) - + (y * CHAR_H * screen->pitch) + (x * CHAR_W); - - for (y1=0; y1pitch; - } -} - -void TXT_UpdateScreenArea(int x, int y, int w, int h) -{ - int x1, y1; - - for (y1=y; y1sym) - { - case SDLK_LEFT: return KEY_LEFTARROW; - case SDLK_RIGHT: return KEY_RIGHTARROW; - case SDLK_DOWN: return KEY_DOWNARROW; - case SDLK_UP: return KEY_UPARROW; - case SDLK_ESCAPE: return KEY_ESCAPE; - case SDLK_RETURN: return KEY_ENTER; - case SDLK_TAB: return KEY_TAB; - case SDLK_F1: return KEY_F1; - case SDLK_F2: return KEY_F2; - case SDLK_F3: return KEY_F3; - case SDLK_F4: return KEY_F4; - case SDLK_F5: return KEY_F5; - case SDLK_F6: return KEY_F6; - case SDLK_F7: return KEY_F7; - case SDLK_F8: return KEY_F8; - case SDLK_F9: return KEY_F9; - case SDLK_F10: return KEY_F10; - case SDLK_F11: return KEY_F11; - case SDLK_F12: return KEY_F12; - - case SDLK_BACKSPACE: return KEY_BACKSPACE; - case SDLK_DELETE: return KEY_DEL; - - case SDLK_PAUSE: return KEY_PAUSE; - - case SDLK_KP_EQUALS: return KEY_EQUALS; - - case SDLK_LSHIFT: - case SDLK_RSHIFT: - return KEY_RSHIFT; - - case SDLK_LCTRL: - case SDLK_RCTRL: - return KEY_RCTRL; - - case SDLK_LALT: - case SDLK_LMETA: - case SDLK_RALT: - case SDLK_RMETA: - return KEY_RALT; - - case SDLK_CAPSLOCK: return KEY_CAPSLOCK; - case SDLK_SCROLLOCK: return KEY_SCRLCK; - - case SDLK_KP0: return KEYP_0; - case SDLK_KP1: return KEYP_1; - case SDLK_KP2: return KEYP_2; - case SDLK_KP3: return KEYP_3; - case SDLK_KP4: return KEYP_4; - case SDLK_KP5: return KEYP_5; - case SDLK_KP6: return KEYP_6; - case SDLK_KP7: return KEYP_7; - case SDLK_KP8: return KEYP_8; - case SDLK_KP9: return KEYP_9; - - case SDLK_HOME: return KEY_HOME; - case SDLK_INSERT: return KEY_INS; - case SDLK_END: return KEY_END; - case SDLK_PAGEUP: return KEY_PGUP; - case SDLK_PAGEDOWN: return KEY_PGDN; - case SDLK_KP_MULTIPLY: return KEYP_MULTIPLY; - case SDLK_KP_PLUS: return KEYP_PLUS; - case SDLK_KP_MINUS: return KEYP_MINUS; - case SDLK_KP_DIVIDE: return KEYP_DIVIDE; - - default: break; - } - - // Returned value is different, depending on whether key mapping is - // enabled. Key mapping is preferable most of the time, for typing - // in text, etc. However, when we want to read raw keyboard codes - // for the setup keyboard configuration dialog, we want the raw - // key code. - - if (key_mapping) - { - return sym->unicode; - } - else - { - return tolower(sym->sym); - } -} - - -signed int TXT_GetChar(void) -{ - SDL_Event ev; - - while (SDL_PollEvent(&ev)) - { - switch (ev.type) - { - case SDL_MOUSEBUTTONDOWN: - if (ev.button.button == SDL_BUTTON_LEFT) - return TXT_MOUSE_LEFT; - else if (ev.button.button == SDL_BUTTON_RIGHT) - return TXT_MOUSE_RIGHT; - else if (ev.button.button == SDL_BUTTON_MIDDLE) - return TXT_MOUSE_MIDDLE; - break; - - case SDL_KEYDOWN: - return TranslateKey(&ev.key.keysym); - - case SDL_QUIT: - // Quit = escape - return 27; - - default: - break; - } - } - - return -1; -} - -static char *SpecialKeyName(int key) -{ - switch (key) - { - case ' ': return "SPACE"; - case KEY_RIGHTARROW: return "RIGHT"; - case KEY_LEFTARROW: return "LEFT"; - case KEY_UPARROW: return "UP"; - case KEY_DOWNARROW: return "DOWN"; - case KEY_ESCAPE: return "ESC"; - case KEY_ENTER: return "ENTER"; - case KEY_TAB: return "TAB"; - case KEY_F1: return "F1"; - case KEY_F2: return "F2"; - case KEY_F3: return "F3"; - case KEY_F4: return "F4"; - case KEY_F5: return "F5"; - case KEY_F6: return "F6"; - case KEY_F7: return "F7"; - case KEY_F8: return "F8"; - case KEY_F9: return "F9"; - case KEY_F10: return "F10"; - case KEY_F11: return "F11"; - case KEY_F12: return "F12"; - case KEY_BACKSPACE: return "BKSP"; - case KEY_PAUSE: return "PAUSE"; - case KEY_EQUALS: return "EQUALS"; - case KEY_MINUS: return "MINUS"; - case KEY_RSHIFT: return "SHIFT"; - case KEY_RCTRL: return "CTRL"; - case KEY_RALT: return "ALT"; - case KEY_CAPSLOCK: return "CAPS"; - case KEY_SCRLCK: return "SCRLCK"; - case KEY_HOME: return "HOME"; - case KEY_END: return "END"; - case KEY_PGUP: return "PGUP"; - case KEY_PGDN: return "PGDN"; - case KEY_INS: return "INS"; - case KEY_DEL: return "DEL"; - /* - case KEYP_0: return "PAD0"; - case KEYP_1: return "PAD1"; - case KEYP_2: return "PAD2"; - case KEYP_3: return "PAD3"; - case KEYP_4: return "PAD4"; - case KEYP_5: return "PAD5"; - case KEYP_6: return "PAD6"; - case KEYP_7: return "PAD7"; - case KEYP_8: return "PAD8"; - case KEYP_9: return "PAD9"; - case KEYP_UPARROW: return "PAD_U"; - case KEYP_DOWNARROW: return "PAD_D"; - case KEYP_LEFTARROW: return "PAD_L"; - case KEYP_RIGHTARROW: return "PAD_R"; - case KEYP_MULTIPLY: return "PAD*"; - case KEYP_PLUS: return "PAD+"; - case KEYP_MINUS: return "PAD-"; - case KEYP_DIVIDE: return "PAD/"; - */ - default: return NULL; - } -} - -void TXT_GetKeyDescription(int key, char *buf) -{ - char *keyname; - - keyname = SpecialKeyName(key); - - if (keyname != NULL) - { - strcpy(buf, keyname); - } - else if (isprint(key)) - { - sprintf(buf, "%c", toupper(key)); - } - else - { - sprintf(buf, "??%i", key); - } -} - -// Searches the desktop screen buffer to determine whether there are any -// blinking characters. - -int TXT_ScreenHasBlinkingChars(void) -{ - int x, y; - unsigned char *p; - - // Check all characters in screen buffer - - for (y=0; y time_to_next_blink) - { - // Add one so it is always positive - - timeout = time_to_next_blink + 1; - } - } - - if (timeout == 0) - { - // We can just wait forever until an event occurs - - SDL_WaitEvent(NULL); - } - else - { - // Sit in a busy loop until the timeout expires or we have to - // redraw the blinking screen - - start_time = SDL_GetTicks(); - - while (SDL_GetTicks() < start_time + timeout) - { - if (SDL_PollEvent(NULL) != 0) - { - // Received an event, so stop waiting - - break; - } - - // Don't hog the CPU - - SDL_Delay(1); - } - } -} - -void TXT_EnableKeyMapping(int enable) -{ - key_mapping = enable; -} - -void TXT_SetWindowTitle(char *title) -{ - SDL_WM_SetCaption(title, NULL); -} - diff --git a/textscreen/txt_main.h b/textscreen/txt_main.h index 13c38537..7978c8b7 100644 --- a/textscreen/txt_main.h +++ b/textscreen/txt_main.h @@ -20,17 +20,17 @@ // //----------------------------------------------------------------------------- // -// Text mode emulation in SDL +// Base interface that abstracts the text mode screen. // //----------------------------------------------------------------------------- #ifndef TXT_MAIN_H #define TXT_MAIN_H -// The textscreen API itself doesn't need SDL; however, SDL needs its -// headers included where main() is defined. +// For the moment, txt_sdl.c is the only implementation of the base +// text mode screen API: -#include "SDL.h" +#include "txt_sdl.h" // Special keypress values that correspond to mouse button clicks // diff --git a/textscreen/txt_sdl.c b/textscreen/txt_sdl.c new file mode 100644 index 00000000..a7e08e1d --- /dev/null +++ b/textscreen/txt_sdl.c @@ -0,0 +1,548 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2005,2006 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- +// +// Text mode emulation in SDL +// +//----------------------------------------------------------------------------- + +#include "SDL.h" + +#include +#include +#include + +#include "doomkeys.h" + +#include "txt_main.h" +#include "txt_sdl.h" +#include "txt_font.h" + +#define CHAR_W 8 +#define CHAR_H 16 + +// Time between character blinks in ms + +#define BLINK_PERIOD 250 + +static SDL_Surface *screen; +static unsigned char *screendata; +static int key_mapping = 1; + +static TxtSDLEventCallbackFunc event_callback; +static void *event_callback_data; + +//#define TANGO + +#ifndef TANGO + +static SDL_Color ega_colors[] = +{ + {0x00, 0x00, 0x00, 0x00}, // 0: Black + {0x00, 0x00, 0xa8, 0x00}, // 1: Blue + {0x00, 0xa8, 0x00, 0x00}, // 2: Green + {0x00, 0xa8, 0xa8, 0x00}, // 3: Cyan + {0xa8, 0x00, 0x00, 0x00}, // 4: Red + {0xa8, 0x00, 0xa8, 0x00}, // 5: Magenta + {0xa8, 0x54, 0x00, 0x00}, // 6: Brown + {0xa8, 0xa8, 0xa8, 0x00}, // 7: Grey + {0x54, 0x54, 0x54, 0x00}, // 8: Dark grey + {0x54, 0x54, 0xfe, 0x00}, // 9: Bright blue + {0x54, 0xfe, 0x54, 0x00}, // 10: Bright green + {0x54, 0xfe, 0xfe, 0x00}, // 11: Bright cyan + {0xfe, 0x54, 0x54, 0x00}, // 12: Bright red + {0xfe, 0x54, 0xfe, 0x00}, // 13: Bright magenta + {0xfe, 0xfe, 0x54, 0x00}, // 14: Yellow + {0xfe, 0xfe, 0xfe, 0x00}, // 15: Bright white +}; + +#else + +// Colors that fit the Tango desktop guidelines: see +// http://tango.freedesktop.org/ also +// http://uwstopia.nl/blog/2006/07/tango-terminal + +static SDL_Color ega_colors[] = +{ + {0x2e, 0x34, 0x36, 0x00}, // 0: Black + {0x34, 0x65, 0xa4, 0x00}, // 1: Blue + {0x4e, 0x9a, 0x06, 0x00}, // 2: Green + {0x06, 0x98, 0x9a, 0x00}, // 3: Cyan + {0xcc, 0x00, 0x00, 0x00}, // 4: Red + {0x75, 0x50, 0x7b, 0x00}, // 5: Magenta + {0xc4, 0xa0, 0x00, 0x00}, // 6: Brown + {0xd3, 0xd7, 0xcf, 0x00}, // 7: Grey + {0x55, 0x57, 0x53, 0x00}, // 8: Dark grey + {0x72, 0x9f, 0xcf, 0x00}, // 9: Bright blue + {0x8a, 0xe2, 0x34, 0x00}, // 10: Bright green + {0x34, 0xe2, 0xe2, 0x00}, // 11: Bright cyan + {0xef, 0x29, 0x29, 0x00}, // 12: Bright red + {0x34, 0xe2, 0xe2, 0x00}, // 13: Bright magenta + {0xfc, 0xe9, 0x4f, 0x00}, // 14: Yellow + {0xee, 0xee, 0xec, 0x00}, // 15: Bright white +}; + +#endif + +// +// Initialise text mode screen +// +// Returns 1 if successful, 0 if an error occurred +// + +int TXT_Init(void) +{ + SDL_InitSubSystem(SDL_INIT_VIDEO); + + screen = SDL_SetVideoMode(TXT_SCREEN_W * CHAR_W, TXT_SCREEN_H * CHAR_H, 8, 0); + + if (screen == NULL) + return 0; + + SDL_SetColors(screen, ega_colors, 0, 16); + SDL_EnableUNICODE(1); + + screendata = malloc(TXT_SCREEN_W * TXT_SCREEN_H * 2); + memset(screendata, 0, TXT_SCREEN_W * TXT_SCREEN_H * 2); + + // Ignore all mouse motion events + + SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); + + // Repeat key presses so we can hold down arrows to scroll down the + // menu, for example. This is what setup.exe does. + + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + + return 1; +} + +void TXT_Shutdown(void) +{ + free(screendata); + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + +unsigned char *TXT_GetScreenData(void) +{ + return screendata; +} + +static inline void UpdateCharacter(int x, int y) +{ + unsigned char character; + unsigned char *p; + unsigned char *s, *s1; + int bg, fg; + int x1, y1; + + p = &screendata[(y * TXT_SCREEN_W + x) * 2]; + character = p[0]; + + fg = p[1] & 0xf; + bg = (p[1] >> 4) & 0xf; + + if (bg & 0x8) + { + // blinking + + bg &= ~0x8; + + if (((SDL_GetTicks() / BLINK_PERIOD) % 2) == 0) + { + fg = bg; + } + } + + p = &int10_font_16[character * CHAR_H]; + + s = ((unsigned char *) screen->pixels) + + (y * CHAR_H * screen->pitch) + (x * CHAR_W); + + for (y1=0; y1pitch; + } +} + +void TXT_UpdateScreenArea(int x, int y, int w, int h) +{ + int x1, y1; + + for (y1=y; y1sym) + { + case SDLK_LEFT: return KEY_LEFTARROW; + case SDLK_RIGHT: return KEY_RIGHTARROW; + case SDLK_DOWN: return KEY_DOWNARROW; + case SDLK_UP: return KEY_UPARROW; + case SDLK_ESCAPE: return KEY_ESCAPE; + case SDLK_RETURN: return KEY_ENTER; + case SDLK_TAB: return KEY_TAB; + case SDLK_F1: return KEY_F1; + case SDLK_F2: return KEY_F2; + case SDLK_F3: return KEY_F3; + case SDLK_F4: return KEY_F4; + case SDLK_F5: return KEY_F5; + case SDLK_F6: return KEY_F6; + case SDLK_F7: return KEY_F7; + case SDLK_F8: return KEY_F8; + case SDLK_F9: return KEY_F9; + case SDLK_F10: return KEY_F10; + case SDLK_F11: return KEY_F11; + case SDLK_F12: return KEY_F12; + + case SDLK_BACKSPACE: return KEY_BACKSPACE; + case SDLK_DELETE: return KEY_DEL; + + case SDLK_PAUSE: return KEY_PAUSE; + + case SDLK_KP_EQUALS: return KEY_EQUALS; + + case SDLK_LSHIFT: + case SDLK_RSHIFT: + return KEY_RSHIFT; + + case SDLK_LCTRL: + case SDLK_RCTRL: + return KEY_RCTRL; + + case SDLK_LALT: + case SDLK_LMETA: + case SDLK_RALT: + case SDLK_RMETA: + return KEY_RALT; + + case SDLK_CAPSLOCK: return KEY_CAPSLOCK; + case SDLK_SCROLLOCK: return KEY_SCRLCK; + + case SDLK_KP0: return KEYP_0; + case SDLK_KP1: return KEYP_1; + case SDLK_KP2: return KEYP_2; + case SDLK_KP3: return KEYP_3; + case SDLK_KP4: return KEYP_4; + case SDLK_KP5: return KEYP_5; + case SDLK_KP6: return KEYP_6; + case SDLK_KP7: return KEYP_7; + case SDLK_KP8: return KEYP_8; + case SDLK_KP9: return KEYP_9; + + case SDLK_HOME: return KEY_HOME; + case SDLK_INSERT: return KEY_INS; + case SDLK_END: return KEY_END; + case SDLK_PAGEUP: return KEY_PGUP; + case SDLK_PAGEDOWN: return KEY_PGDN; + case SDLK_KP_MULTIPLY: return KEYP_MULTIPLY; + case SDLK_KP_PLUS: return KEYP_PLUS; + case SDLK_KP_MINUS: return KEYP_MINUS; + case SDLK_KP_DIVIDE: return KEYP_DIVIDE; + + default: break; + } + + // Returned value is different, depending on whether key mapping is + // enabled. Key mapping is preferable most of the time, for typing + // in text, etc. However, when we want to read raw keyboard codes + // for the setup keyboard configuration dialog, we want the raw + // key code. + + if (key_mapping) + { + return sym->unicode; + } + else + { + return tolower(sym->sym); + } +} + + +signed int TXT_GetChar(void) +{ + SDL_Event ev; + + while (SDL_PollEvent(&ev)) + { + // If there is an event callback, allow it to intercept this + // event. + + if (event_callback != NULL) + { + if (event_callback(&ev, event_callback_data)) + { + continue; + } + } + + // Process the event. + + switch (ev.type) + { + case SDL_MOUSEBUTTONDOWN: + if (ev.button.button == SDL_BUTTON_LEFT) + return TXT_MOUSE_LEFT; + else if (ev.button.button == SDL_BUTTON_RIGHT) + return TXT_MOUSE_RIGHT; + else if (ev.button.button == SDL_BUTTON_MIDDLE) + return TXT_MOUSE_MIDDLE; + break; + + case SDL_KEYDOWN: + return TranslateKey(&ev.key.keysym); + + case SDL_QUIT: + // Quit = escape + return 27; + + default: + break; + } + } + + return -1; +} + +static char *SpecialKeyName(int key) +{ + switch (key) + { + case ' ': return "SPACE"; + case KEY_RIGHTARROW: return "RIGHT"; + case KEY_LEFTARROW: return "LEFT"; + case KEY_UPARROW: return "UP"; + case KEY_DOWNARROW: return "DOWN"; + case KEY_ESCAPE: return "ESC"; + case KEY_ENTER: return "ENTER"; + case KEY_TAB: return "TAB"; + case KEY_F1: return "F1"; + case KEY_F2: return "F2"; + case KEY_F3: return "F3"; + case KEY_F4: return "F4"; + case KEY_F5: return "F5"; + case KEY_F6: return "F6"; + case KEY_F7: return "F7"; + case KEY_F8: return "F8"; + case KEY_F9: return "F9"; + case KEY_F10: return "F10"; + case KEY_F11: return "F11"; + case KEY_F12: return "F12"; + case KEY_BACKSPACE: return "BKSP"; + case KEY_PAUSE: return "PAUSE"; + case KEY_EQUALS: return "EQUALS"; + case KEY_MINUS: return "MINUS"; + case KEY_RSHIFT: return "SHIFT"; + case KEY_RCTRL: return "CTRL"; + case KEY_RALT: return "ALT"; + case KEY_CAPSLOCK: return "CAPS"; + case KEY_SCRLCK: return "SCRLCK"; + case KEY_HOME: return "HOME"; + case KEY_END: return "END"; + case KEY_PGUP: return "PGUP"; + case KEY_PGDN: return "PGDN"; + case KEY_INS: return "INS"; + case KEY_DEL: return "DEL"; + /* + case KEYP_0: return "PAD0"; + case KEYP_1: return "PAD1"; + case KEYP_2: return "PAD2"; + case KEYP_3: return "PAD3"; + case KEYP_4: return "PAD4"; + case KEYP_5: return "PAD5"; + case KEYP_6: return "PAD6"; + case KEYP_7: return "PAD7"; + case KEYP_8: return "PAD8"; + case KEYP_9: return "PAD9"; + case KEYP_UPARROW: return "PAD_U"; + case KEYP_DOWNARROW: return "PAD_D"; + case KEYP_LEFTARROW: return "PAD_L"; + case KEYP_RIGHTARROW: return "PAD_R"; + case KEYP_MULTIPLY: return "PAD*"; + case KEYP_PLUS: return "PAD+"; + case KEYP_MINUS: return "PAD-"; + case KEYP_DIVIDE: return "PAD/"; + */ + default: return NULL; + } +} + +void TXT_GetKeyDescription(int key, char *buf) +{ + char *keyname; + + keyname = SpecialKeyName(key); + + if (keyname != NULL) + { + strcpy(buf, keyname); + } + else if (isprint(key)) + { + sprintf(buf, "%c", toupper(key)); + } + else + { + sprintf(buf, "??%i", key); + } +} + +// Searches the desktop screen buffer to determine whether there are any +// blinking characters. + +int TXT_ScreenHasBlinkingChars(void) +{ + int x, y; + unsigned char *p; + + // Check all characters in screen buffer + + for (y=0; y time_to_next_blink) + { + // Add one so it is always positive + + timeout = time_to_next_blink + 1; + } + } + + if (timeout == 0) + { + // We can just wait forever until an event occurs + + SDL_WaitEvent(NULL); + } + else + { + // Sit in a busy loop until the timeout expires or we have to + // redraw the blinking screen + + start_time = SDL_GetTicks(); + + while (SDL_GetTicks() < start_time + timeout) + { + if (SDL_PollEvent(NULL) != 0) + { + // Received an event, so stop waiting + + break; + } + + // Don't hog the CPU + + SDL_Delay(1); + } + } +} + +void TXT_EnableKeyMapping(int enable) +{ + key_mapping = enable; +} + +void TXT_SetWindowTitle(char *title) +{ + SDL_WM_SetCaption(title, NULL); +} + +void TXT_SDL_SetEventCallback(TxtSDLEventCallbackFunc callback, void *user_data) +{ + event_callback = callback; + event_callback_data = user_data; +} + diff --git a/textscreen/txt_sdl.h b/textscreen/txt_sdl.h new file mode 100644 index 00000000..ed131970 --- /dev/null +++ b/textscreen/txt_sdl.h @@ -0,0 +1,50 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2005,2006 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- +// +// Text mode emulation in SDL +// +//----------------------------------------------------------------------------- + +#ifndef TXT_SDL_H +#define TXT_SDL_H + +// The textscreen API itself doesn't need SDL; however, SDL needs its +// headers included where main() is defined. + +#include "SDL.h" + +// Event callback function type: a function of this type can be used +// to intercept events in the textscreen event processing loop. +// Returning 1 will cause the event to be eaten; the textscreen code +// will not see it. + +typedef int (*TxtSDLEventCallbackFunc)(SDL_Event *event, void *user_data); + +// Set a callback function to call in the SDL event loop. Useful for +// intercepting events. Pass callback=NULL to clear an existing +// callback function. +// user_data is a void pointer to be passed to the callback function. + +void TXT_SDL_SetEventCallback(TxtSDLEventCallbackFunc callback, void *user_data); + +#endif /* #ifndef TXT_SDL_H */ + -- cgit v1.2.3