ref: 1df732ab78cb0ff08104e67dedf57cbd1d176f28
dir: /textscreen/txt_main.c/
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id: txt_main.c 490 2006-05-20 16:34:34Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 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. // // $Log$ // Revision 1.5 2006/01/13 23:56:00 fraggle // Add text-mode I/O functions. // Use text-mode screen for the waiting screen. // // Revision 1.4 2006/01/13 18:23:28 fraggle // Textscreen getchar() function; remove SDL code from I_Endoom. // // Revision 1.3 2005/10/09 20:19:21 fraggle // Handle blinking text in ENDOOM lumps properly. // // Revision 1.2 2005/10/09 16:42:46 fraggle // Cannot do arithmetic on void pointers in standard C // // Revision 1.1 2005/10/02 03:16:03 fraggle // Text mode emulation code // // //----------------------------------------------------------------------------- // // Text mode emulation in SDL // //----------------------------------------------------------------------------- #include <SDL.h> #include <stdlib.h> #include <string.h> #include "doomkeys.h" #include "txt_main.h" #include "txt_font.h" #define CHAR_W 8 #define CHAR_H 16 static SDL_Surface *screen; static unsigned char *screendata; static SDL_Color ega_colors[] = { {0x00, 0x00, 0x00}, // 0: Black {0x00, 0x00, 0xa8}, // 1: Blue {0x00, 0xa8, 0x00}, // 2: Green {0x00, 0xa8, 0xa8}, // 3: Cyan {0xa8, 0x00, 0x00}, // 4: Red {0xa8, 0x00, 0xa8}, // 5: Magenta {0xa8, 0x54, 0x00}, // 6: Brown {0xa8, 0xa8, 0xa8}, // 7: Grey {0x54, 0x54, 0x54}, // 8: Dark grey {0x54, 0x54, 0xfe}, // 9: Bright blue {0x54, 0xfe, 0x54}, // 10: Bright green {0x54, 0xfe, 0xfe}, // 11: Bright cyan {0xfe, 0x54, 0x54}, // 12: Bright red {0xfe, 0x54, 0xfe}, // 13: Bright magenta {0xfe, 0xfe, 0x54}, // 14: Yellow {0xfe, 0xfe, 0xfe}, // 15: Bright white }; // // 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); 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() % 500 < 250) 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; y1<CHAR_H; ++y1) { s1 = s; for (x1=0; x1<CHAR_W; ++x1) { if (*p & (1 << (7-x1))) { *s1++ = fg; } else { *s1++ = bg; } } ++p; s += screen->pitch; } } void TXT_UpdateScreenArea(int x, int y, int w, int h) { int x1, y1; for (y1=y; y1<y+h; ++y1) { for (x1=x; x1<x+w; ++x1) { UpdateCharacter(x1, y1); } } SDL_UpdateRect(screen, x * CHAR_W, y * CHAR_H, w * CHAR_W, h * CHAR_H); } void TXT_UpdateScreen(void) { TXT_UpdateScreenArea(0, 0, TXT_SCREEN_W, TXT_SCREEN_H); } // // Translates the SDL key // static int TranslateKey(SDL_keysym *sym) { switch(sym->sym) { 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_EQUALS: case SDLK_KP_EQUALS: return KEY_EQUALS; case SDLK_MINUS: return KEY_MINUS; 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: 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; }