Annotation of brogue-ce/src/platform/curses-platform.c, Revision 1.1.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