コード例 #1
0
ファイル: tcod-platform.c プロジェクト: lunixbochs/brogue
static void tcod_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance)
{
	boolean tryAgain;
	TCOD_key_t key;
	TCOD_mouse_t mouse;
	uint32 theTime, waitTime;
	short x, y;
	
	TCOD_console_flush();

	key.vk = TCODK_NONE;

	if (noMenu && rogue.nextGame == NG_NOTHING) rogue.nextGame = NG_NEW_GAME;
	
	for (;;) {
		theTime = TCOD_sys_elapsed_milli();
		
		if (TCOD_console_is_window_closed()) {
			rogue.gameHasEnded = true; // causes the game loop to terminate quickly
			rogue.nextGame = NG_QUIT; // causes the menu to drop out immediately
			returnEvent->eventType = KEYSTROKE;
			returnEvent->param1 = ESCAPE_KEY;
			return;
		}
		
		tryAgain = false;
		
		if (bufferedKey.vk != TCODK_NONE) {
			rewriteKey(&bufferedKey, textInput);
			if (processKeystroke(bufferedKey, returnEvent, textInput)) {
				bufferedKey.vk = TCODK_NONE;
				return;
			} else {
				bufferedKey.vk = TCODK_NONE;
			}
		}
		
		if (missedMouse.lmb) {
			returnEvent->eventType = missedMouse.lmb;

			returnEvent->param1 = missedMouse.x;
			returnEvent->param2 = missedMouse.y;
			if (TCOD_console_is_key_pressed(TCODK_CONTROL)) {
				returnEvent->controlKey = true;
			}
			if (TCOD_console_is_key_pressed(TCODK_SHIFT)) {
				returnEvent->shiftKey = true;
			}
			
			missedMouse.lmb = missedMouse.lmb == MOUSE_DOWN ? MOUSE_UP : 0;
			return;
		}

		if (missedMouse.rmb) {
			returnEvent->eventType = missedMouse.rmb == MOUSE_DOWN ? RIGHT_MOUSE_DOWN : RIGHT_MOUSE_UP;

			returnEvent->param1 = missedMouse.x;
			returnEvent->param2 = missedMouse.y;
			if (TCOD_console_is_key_pressed(TCODK_CONTROL)) {
				returnEvent->controlKey = true;
			}
			if (TCOD_console_is_key_pressed(TCODK_SHIFT)) {
				returnEvent->shiftKey = true;
			}
			
			missedMouse.rmb = missedMouse.rmb == MOUSE_DOWN ? MOUSE_UP : 0;
			return;
		}
		
		if (!(serverMode || (SDL_GetAppState() & SDL_APPACTIVE))) {
			TCOD_sys_sleep_milli(100);
		} else {
			if (colorsDance) {
				shuffleTerrainColors(3, true);
				commitDraws();
			}
			TCOD_console_flush();
		}

		#ifdef USE_NEW_TCOD_API
		TCOD_sys_check_for_event(TCOD_EVENT_KEY_PRESS | TCOD_EVENT_MOUSE, &key, &mouse);
		#else
		key = TCOD_console_check_for_keypress(TCOD_KEY_PRESSED);
		#endif

		rewriteKey(&key, textInput);
		if (processKeystroke(key, returnEvent, textInput)) {
			return;
		}

		mouse = TCOD_mouse_get_status();

		if (serverMode || (SDL_GetAppState() & SDL_APPACTIVE)) {
			x = mouse.cx;
			y = mouse.cy;
		} else {
			x = 0;
			y = 0;
		}

		if (
			mouse.lbutton_pressed || mouse.rbutton_pressed
			|| mouse.lbutton != brogueMouse.lmb || mouse.rbutton != brogueMouse.rmb
			|| brogueMouse.x !=x || brogueMouse.y != y) {

			returnEvent->param1 = x;
			returnEvent->param2 = y;

			getModifiers(returnEvent);

			if (mouse.lbutton_pressed) {
				if (!brogueMouse.lmb) {
					// we missed a mouseDown event -- better make up for it!
					missedMouse.x = x;
					missedMouse.y = y;
					missedMouse.lmb = MOUSE_UP;
					returnEvent->eventType = MOUSE_DOWN;
				} else {
					returnEvent->eventType = MOUSE_UP;
				}
			} else if (mouse.lbutton && !brogueMouse.lmb) {
				returnEvent->eventType = MOUSE_DOWN;
			} else {
				returnEvent->eventType = MOUSE_ENTERED_CELL;
			}

			if (mouse.rbutton_pressed) {
				if (!brogueMouse.rmb) {
					// we missed a mouseDown event -- better make up for it!
					missedMouse.x = x;
					missedMouse.y = y;
					missedMouse.rmb = MOUSE_UP;
					returnEvent->eventType = RIGHT_MOUSE_DOWN;
				} else {
					returnEvent->eventType = RIGHT_MOUSE_UP;
				}
			} else if (mouse.rbutton && !brogueMouse.rmb) {
				returnEvent->eventType = RIGHT_MOUSE_DOWN;
			}

			brogueMouse.x = x;
			brogueMouse.y = y;
			brogueMouse.lmb = mouse.lbutton;
			brogueMouse.rmb = mouse.rbutton;

			if (returnEvent->eventType == MOUSE_ENTERED_CELL && !hasMouseMoved) {
				hasMouseMoved = true;
			} else {
				return;
			}
		}

		waitTime = PAUSE_BETWEEN_EVENT_POLLING + theTime - TCOD_sys_elapsed_milli();
		
		if (waitTime > 0 && waitTime <= PAUSE_BETWEEN_EVENT_POLLING) {
			TCOD_sys_sleep_milli(waitTime);
		}
	}
}
コード例 #2
0
ファイル: curses-platform.c プロジェクト: kipraske/web-brogue
static void curses_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) {
	int key;
	// TCOD_mouse_t mouse;
	uint32_t theTime, waitTime;
	// short x, y;
	
	Term.refresh();

	if (noMenu && rogue.nextGame == NG_NOTHING) rogue.nextGame = NG_NEW_GAME;
	
	for (;;) {
		theTime = getTime(); //TCOD_sys_elapsed_milli();
		
		/*if (TCOD_console_is_window_closed()) {
			rogue.gameHasEnded = true; // causes the game loop to terminate quickly
			returnEvent->eventType = KEYSTROKE;
			returnEvent->param1 = ACKNOWLEDGE_KEY;
			return;
		}*/
		
		if (colorsDance) {
			shuffleTerrainColors(3, true);
			commitDraws();
		}	
		
		
		key = Term.getkey();
		if (key == TERM_MOUSE) {
			if (Term.mouse.x > 0 && Term.mouse.y > 0 && Term.mouse.x < COLS && Term.mouse.y < ROWS) {
				returnEvent->param1 = Term.mouse.x;
				returnEvent->param2 = Term.mouse.y;
				returnEvent->eventType = KEYSTROKE;
				if (Term.mouse.justReleased) returnEvent->eventType = MOUSE_UP;
				if (Term.mouse.justPressed) returnEvent->eventType = MOUSE_DOWN;
				if (Term.mouse.justMoved) returnEvent->eventType = MOUSE_ENTERED_CELL;
				returnEvent->controlKey = Term.mouse.control;
				returnEvent->shiftKey = Term.mouse.shift;
				if (returnEvent->eventType != KEYSTROKE) return;
			}
		} else if (key != TERM_NONE) {
			key = rewriteKey(key, textInput);

			returnEvent->eventType = KEYSTROKE;
			returnEvent->controlKey = 0; //(key.rctrl || key.lctrl);
			returnEvent->shiftKey = 0; //key.shift;
			returnEvent->param1 = key;

			if (key == Term.keys.backspace || key == Term.keys.del) returnEvent->param1 = DELETE_KEY;
			else if (key == Term.keys.up) returnEvent->param1 = UP_ARROW;
			else if (key == Term.keys.down) returnEvent->param1 = DOWN_ARROW;
			else if (key == Term.keys.left) returnEvent->param1 = LEFT_ARROW;
			else if (key == Term.keys.right) returnEvent->param1 = RIGHT_ARROW;
			else if (key == Term.keys.quit) {
				rogue.gameHasEnded = true;
				rogue.nextGame = NG_QUIT; // causes the menu to drop out immediately
			} 
			else if ((key >= 'A' && key <= 'Z')) {
				returnEvent->shiftKey = 1;
				// returnEvent->param1 += 'a' - 'A';
			}
			// we could try to catch control keys, where possible, but we'll catch keys we mustn't
			/* else if ((key >= 'A'-'@' && key <= 'Z'-'@')) {
				returnEvent->controlKey = 1;
				returnEvent->param1 += 'a' - ('A'-'@');
			} */

			return;
		}

		waitTime = PAUSE_BETWEEN_EVENT_POLLING + theTime - getTime();
		
		if (waitTime > 0 && waitTime <= PAUSE_BETWEEN_EVENT_POLLING) {
			curses_pauseForMilliseconds(waitTime);
		}
	}
}
コード例 #3
0
static void sodna_nextKeyOrMouseEvent(
        rogueEvent *returnEvent, boolean textInput, boolean colorsDance) {
    int time, waitTime;
    boolean mouseMoved = false;
    for (;;) {
        time = sodna_ms_elapsed();
        if (colorsDance) {
            shuffleTerrainColors(3, true);
            commitDraws();
        }
        sodna_flush();

        sodna_Event e = get_event(true);

        // We get lots of mouse events, loop to flush out several consecutive
        // ones. Do break at some point though.
        if (e.type == SODNA_EVENT_MOUSE_MOVED) {
            for (;;) {
                if (mouse_pos_changed())
                    mouseMoved = true;
                // Peek at the future event, try to stop this loop at the last
                // mouse moved event of the sequence.
                if (get_event(false).type != SODNA_EVENT_MOUSE_MOVED)
                    break;
                if (sodna_ms_elapsed() - time > PAUSE_BETWEEN_EVENT_POLLING)
                    break;
                e = get_event(true);
            }
        }

        returnEvent->controlKey = ctrl_pressed;
        returnEvent->shiftKey = shift_pressed;

        if (e.type == SODNA_EVENT_CLOSE_WINDOW) {
            rogue.gameHasEnded = true;
            rogue.nextGame = NG_QUIT; // causes the menu to drop out immediately
            returnEvent->eventType = KEYSTROKE;
            returnEvent->param1 = ESCAPE_KEY;
            return;
        }


        if (e.type == SODNA_EVENT_MOUSE_DOWN) {
            returnEvent->param1 = mouse_x;
            returnEvent->param2 = mouse_y;
            if (e.button.id == SODNA_LEFT_BUTTON) {
                returnEvent->eventType = MOUSE_DOWN;
                return;
            }
            if (e.button.id == SODNA_RIGHT_BUTTON) {
                returnEvent->eventType = RIGHT_MOUSE_DOWN;
                return;
            }
        }

        if (e.type == SODNA_EVENT_MOUSE_UP) {
            returnEvent->param1 = mouse_x;
            returnEvent->param2 = mouse_y;
            if (e.button.id == SODNA_LEFT_BUTTON) {
                returnEvent->eventType = MOUSE_UP;
                return;
            }
            if (e.button.id == SODNA_RIGHT_BUTTON) {
                returnEvent->eventType = RIGHT_MOUSE_UP;
                return;
            }
        }

        // Reverse the effect of caps lock if it's on.
        if (e.type == SODNA_EVENT_CHARACTER) {
            // XXX: Due to a bug in SDL2, used as backend by Sodna, caps lock
            // state isn't maintained robustly. So we can't rely on the
            // modifier. Look at shift state and the character case instead.
            //if (caps_lock) {
            if ((isupper(e.ch.code) && !shift_pressed) || (islower(e.ch.code) && shift_pressed)) {
                if (isupper(e.ch.code)) {
                    e.ch.code = tolower(e.ch.code);
                } else if (islower(e.ch.code)) {
                    e.ch.code = toupper(e.ch.code);
                }
            }
        }

        // Keymap translation.
        if (e.type == SODNA_EVENT_CHARACTER && e.ch.code < 128) {
            int km = printable_mappings[e.ch.code];
            if (km > 0) {
                e.ch.code = km;
            } else if (km < 0) {
                e.type = SODNA_EVENT_KEY_DOWN;
                e.key.layout = -km;
            }
        } else if (e.type == SODNA_EVENT_KEY_DOWN && e.key.layout < 128) {
            int km = unprintable_mappings[e.key.layout];
            if (km > 0) {
                e.key.layout = km;
            } else if (km < 0) {
                e.type = SODNA_EVENT_CHARACTER;
                e.ch.code = -km;
            }
        }

        // Back to event handling.
        if (e.type == SODNA_EVENT_CHARACTER) {
            returnEvent->param1 = e.ch.code;
            returnEvent->eventType = KEYSTROKE;
            return;
        }

        if (e.type == SODNA_EVENT_KEY_DOWN) {
            returnEvent->eventType = KEYSTROKE;

            switch (e.key.layout) {
#define K(sodna, brogue) case sodna: returnEvent->param1 = brogue; return;
                K(SODNA_KEY_UP, UP_ARROW)
                K(SODNA_KEY_DOWN, DOWN_ARROW)
                K(SODNA_KEY_LEFT, LEFT_ARROW)
                K(SODNA_KEY_RIGHT, RIGHT_ARROW)
                K(SODNA_KEY_KP_1, NUMPAD_1)
                K(SODNA_KEY_KP_2, NUMPAD_2)
                K(SODNA_KEY_KP_3, NUMPAD_3)
                K(SODNA_KEY_KP_4, NUMPAD_4)
                K(SODNA_KEY_KP_5, NUMPAD_5)
                K(SODNA_KEY_KP_6, NUMPAD_6)
                K(SODNA_KEY_KP_7, NUMPAD_7)
                K(SODNA_KEY_KP_8, NUMPAD_8)
                K(SODNA_KEY_KP_9, NUMPAD_9)
                K(SODNA_KEY_KP_0, NUMPAD_0)
                K(SODNA_KEY_TAB, TAB_KEY)
                K(SODNA_KEY_ENTER, RETURN_KEY)
                K(SODNA_KEY_KP_ENTER, ENTER_KEY)
                K(SODNA_KEY_BACKSPACE, DELETE_KEY)
                K(SODNA_KEY_ESCAPE, ESCAPE_KEY)
#undef K
                    break;
            }
        }

        if (mouseMoved) {
            returnEvent->eventType = MOUSE_ENTERED_CELL;
            returnEvent->param1 = mouse_x;
            returnEvent->param2 = mouse_y;
            return;
        }

        waitTime = time + PAUSE_BETWEEN_EVENT_POLLING - sodna_ms_elapsed();
        if (waitTime > 0 && waitTime <= PAUSE_BETWEEN_EVENT_POLLING) {
            sodna_sleep_ms(waitTime);
        }
    }