Annotation of brogue-ce/src/platform/curses-platform.c, Revision 1.1
1.1 ! rubenllo 1: #include <stdio.h>
! 2: #include <string.h>
! 3: #include <stdint.h>
! 4: #include <signal.h>
! 5: #include <sys/time.h>
! 6: #include "platform.h"
! 7: #include "term.h"
! 8:
! 9: static void gameLoop() {
! 10: signal(SIGINT, SIG_DFL); // keep SDL from overriding the default ^C handler when it's linked
! 11:
! 12: if (!Term.start()) {
! 13: return;
! 14: }
! 15: Term.title("Brogue");
! 16: Term.resize(COLS, ROWS);
! 17:
! 18: rogueMain();
! 19:
! 20: Term.end();
! 21: }
! 22:
! 23: static char glyphToAscii(enum displayGlyph glyph) {
! 24: unsigned int ch;
! 25:
! 26: switch (glyph) {
! 27: case G_UP_ARROW: return '^';
! 28: case G_DOWN_ARROW: return 'v';
! 29: case G_FLOOR: return '.';
! 30: case G_CHASM: return ':';
! 31: case G_TRAP: return '%';
! 32: case G_FIRE: return '^';
! 33: case G_FOLIAGE: return '&';
! 34: case G_AMULET: return ',';
! 35: case G_SCROLL: return '?';
! 36: case G_RING: return '=';
! 37: case G_WEAPON: return '(';
! 38: case G_GEM: return '+';
! 39: case G_TOTEM: return '0'; // zero
! 40: case G_GOOD_MAGIC: return '$';
! 41: case G_BAD_MAGIC: return '+';
! 42: case G_DOORWAY: return '<';
! 43: case G_CHARM: return '7';
! 44: case G_GUARDIAN: return '5';
! 45: case G_WINGED_GUARDIAN: return '5';
! 46: case G_EGG: return 'o';
! 47: case G_BLOODWORT_STALK: return '&';
! 48: case G_FLOOR_ALT: return '.';
! 49: case G_UNICORN: return 'U';
! 50: case G_TURRET: return '*';
! 51: case G_CARPET: return '.';
! 52: case G_STATUE: return '5';
! 53: case G_CRACKED_STATUE: return '5';
! 54: case G_MAGIC_GLYPH: return ':';
! 55: case G_ELECTRIC_CRYSTAL: return '$';
! 56:
! 57: default:
! 58: ch = glyphToUnicode(glyph);
! 59: brogueAssert(ch < 0x80); // assert ascii
! 60: return ch;
! 61: }
! 62: }
! 63:
! 64: static void curses_plotChar(enum displayGlyph ch,
! 65: short xLoc, short yLoc,
! 66: short foreRed, short foreGreen, short foreBlue,
! 67: short backRed, short backGreen, short backBlue) {
! 68:
! 69: fcolor fore;
! 70: fcolor back;
! 71:
! 72: fore.r = (float) foreRed / 100;
! 73: fore.g = (float) foreGreen / 100;
! 74: fore.b = (float) foreBlue / 100;
! 75: back.r = (float) backRed / 100;
! 76: back.g = (float) backGreen / 100;
! 77: back.b = (float) backBlue / 100;
! 78:
! 79: ch = glyphToAscii(ch);
! 80:
! 81: if (ch < ' ' || ch > 127) ch = ' ';
! 82: Term.put(xLoc, yLoc, ch, &fore, &back);
! 83: }
! 84:
! 85:
! 86: struct mapsymbol {
! 87: int in_c, out_c;
! 88: struct mapsymbol *next;
! 89: };
! 90:
! 91: static struct mapsymbol *keymap = NULL;
! 92:
! 93: static int rewriteKey(int key, boolean text) {
! 94: if (text) return key;
! 95:
! 96: struct mapsymbol *s = keymap;
! 97: while (s != NULL) {
! 98: if (s->in_c == key) {
! 99: return s->out_c;
! 100: }
! 101:
! 102: s = s->next;
! 103: }
! 104: return key;
! 105: }
! 106:
! 107:
! 108: #define PAUSE_BETWEEN_EVENT_POLLING 34//17
! 109:
! 110: static uint64_t getTime() {
! 111: struct timeval tv;
! 112: gettimeofday(&tv, NULL);
! 113: return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
! 114: }
! 115:
! 116: static boolean curses_pauseForMilliseconds(short milliseconds) {
! 117: Term.refresh();
! 118: Term.wait(milliseconds);
! 119:
! 120: // hasKey returns true if we have a mouse event, too.
! 121: return Term.hasKey();
! 122: }
! 123:
! 124: static void curses_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) {
! 125: int key;
! 126: // TCOD_mouse_t mouse;
! 127: uint64_t theTime, waitTime;
! 128: // short x, y;
! 129:
! 130: Term.refresh();
! 131:
! 132: for (;;) {
! 133: theTime = getTime(); //TCOD_sys_elapsed_milli();
! 134:
! 135: /*if (TCOD_console_is_window_closed()) {
! 136: rogue.gameHasEnded = true; // causes the game loop to terminate quickly
! 137: returnEvent->eventType = KEYSTROKE;
! 138: returnEvent->param1 = ACKNOWLEDGE_KEY;
! 139: return;
! 140: }*/
! 141:
! 142: if (colorsDance) {
! 143: shuffleTerrainColors(3, true);
! 144: commitDraws();
! 145: }
! 146:
! 147:
! 148: key = Term.getkey();
! 149: if (key == TERM_MOUSE) {
! 150: if (Term.mouse.x > 0 && Term.mouse.y > 0 && Term.mouse.x < COLS && Term.mouse.y < ROWS) {
! 151: returnEvent->param1 = Term.mouse.x;
! 152: returnEvent->param2 = Term.mouse.y;
! 153: returnEvent->eventType = KEYSTROKE;
! 154: if (Term.mouse.justReleased) returnEvent->eventType = MOUSE_UP;
! 155: if (Term.mouse.justPressed) returnEvent->eventType = MOUSE_DOWN;
! 156: if (Term.mouse.justMoved) returnEvent->eventType = MOUSE_ENTERED_CELL;
! 157: returnEvent->controlKey = Term.mouse.control;
! 158: returnEvent->shiftKey = Term.mouse.shift;
! 159: if (returnEvent->eventType != KEYSTROKE) return;
! 160: }
! 161: } else if (key != TERM_NONE) {
! 162: key = rewriteKey(key, textInput);
! 163:
! 164: returnEvent->eventType = KEYSTROKE;
! 165: returnEvent->controlKey = 0; //(key.rctrl || key.lctrl);
! 166: returnEvent->shiftKey = 0; //key.shift;
! 167: returnEvent->param1 = key;
! 168:
! 169: if (key == Term.keys.backspace || key == Term.keys.del) returnEvent->param1 = DELETE_KEY;
! 170: else if (key == Term.keys.up) returnEvent->param1 = UP_ARROW;
! 171: else if (key == Term.keys.down) returnEvent->param1 = DOWN_ARROW;
! 172: else if (key == Term.keys.left) returnEvent->param1 = LEFT_ARROW;
! 173: else if (key == Term.keys.right) returnEvent->param1 = RIGHT_ARROW;
! 174: else if (key == Term.keys.quit) {
! 175: rogue.gameHasEnded = true;
! 176: rogue.nextGame = NG_QUIT; // causes the menu to drop out immediately
! 177: }
! 178: else if ((key >= 'A' && key <= 'Z')) {
! 179: returnEvent->shiftKey = 1;
! 180: // returnEvent->param1 += 'a' - 'A';
! 181: }
! 182: // we could try to catch control keys, where possible, but we'll catch keys we mustn't
! 183: /* else if ((key >= 'A'-'@' && key <= 'Z'-'@')) {
! 184: returnEvent->controlKey = 1;
! 185: returnEvent->param1 += 'a' - ('A'-'@');
! 186: } */
! 187:
! 188: return;
! 189: }
! 190:
! 191: waitTime = PAUSE_BETWEEN_EVENT_POLLING + theTime - getTime();
! 192:
! 193: if (waitTime > 0 && waitTime <= PAUSE_BETWEEN_EVENT_POLLING) {
! 194: curses_pauseForMilliseconds(waitTime);
! 195: }
! 196: }
! 197: }
! 198:
! 199: static void curses_remap(const char *input_name, const char *output_name) {
! 200: struct mapsymbol *sym = malloc(sizeof(*sym));
! 201:
! 202: if (sym == NULL) return; // out of memory? seriously?
! 203:
! 204: sym->in_c = Term.keycodeByName(input_name);
! 205: sym->out_c = Term.keycodeByName(output_name);
! 206:
! 207: sym->next = keymap;
! 208: keymap = sym;
! 209: }
! 210:
! 211: static boolean modifier_held(int modifier) {
! 212: return 0;
! 213: }
! 214:
! 215: struct brogueConsole cursesConsole = {
! 216: gameLoop,
! 217: curses_pauseForMilliseconds,
! 218: curses_nextKeyOrMouseEvent,
! 219: curses_plotChar,
! 220: curses_remap,
! 221: modifier_held,
! 222: NULL,
! 223: NULL,
! 224: NULL
! 225: };
CVSweb