X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fevents.c;h=9bd812373723cef124767d39028f4419dcfbbbdc;hp=619a7f13495fdc76c984724e718cd430d4ba3544;hb=7f77c2e8dcb7ad575fcaf89512f4f616846c8b41;hpb=a85d66e030463ca9cf9700888481ebf2a04f8740 diff --git a/src/events.c b/src/events.c index 619a7f13..9bd81237 100644 --- a/src/events.c +++ b/src/events.c @@ -1,7 +1,7 @@ /*********************************************************** * Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * +* (c) 1995-2006 Artsoft Entertainment * * Holger Schemel * * Detmolder Strasse 189 * * 33604 Bielefeld * @@ -23,10 +23,8 @@ #include "tape.h" #include "network.h" -/* values for key_status */ -#define KEY_NOT_PRESSED FALSE -#define KEY_RELEASED FALSE -#define KEY_PRESSED TRUE + +#define DEBUG_EVENTS 0 static boolean cursor_inside_playfield = FALSE; @@ -58,13 +56,42 @@ int FilterMouseMotionEvents(const Event *event) } /* skip mouse motion events without pressed button outside level editor */ - if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR && - game_status != GAME_MODE_PLAYING) + if (button_status == MB_RELEASED && + game_status != GAME_MODE_EDITOR && game_status != GAME_MODE_PLAYING) return 0; else return 1; } +/* to prevent delay problems, skip mouse motion events if the very next + event is also a mouse motion event (and therefore effectively only + handling the last of a row of mouse motion events in the event queue) */ + +boolean SkipPressedMouseMotionEvent(const Event *event) +{ + /* nothing to do if the current event is not a mouse motion event */ + if (event->type != EVENT_MOTIONNOTIFY) + return FALSE; + + /* only skip motion events with pressed button outside level editor */ + if (button_status == MB_RELEASED || + game_status == GAME_MODE_EDITOR || game_status == GAME_MODE_PLAYING) + return FALSE; + + if (PendingEvent()) + { + Event next_event; + + PeekEvent(&next_event); + + /* if next event is also a mouse motion event, skip the current one */ + if (next_event.type == EVENT_MOTIONNOTIFY) + return TRUE; + } + + return FALSE; +} + /* this is only really needed for non-SDL targets to filter unwanted events; when using SDL with properly installed event filter, this function can be replaced with a simple "NextEvent()" call, but it doesn't hurt either */ @@ -73,9 +100,17 @@ static boolean NextValidEvent(Event *event) { while (PendingEvent()) { + boolean handle_this_event = FALSE; + NextEvent(event); if (FilterMouseMotionEvents(event)) + handle_this_event = TRUE; + + if (SkipPressedMouseMotionEvent(event)) + handle_this_event = FALSE; + + if (handle_this_event) return TRUE; } @@ -84,13 +119,13 @@ static boolean NextValidEvent(Event *event) void EventLoop(void) { - while(1) + while (1) { if (PendingEvent()) /* got event */ { Event event; - if (NextValidEvent(&event)) + while (NextValidEvent(&event)) { switch(event.type) { @@ -117,7 +152,7 @@ void EventLoop(void) else { /* when playing, display a special mouse pointer inside the playfield */ - if (game_status == GAME_MODE_PLAYING) + if (game_status == GAME_MODE_PLAYING && !tape.pausing) { if (!playfield_cursor_set && cursor_inside_playfield && DelayReached(&playfield_cursor_delay, 1000)) @@ -139,7 +174,9 @@ void EventLoop(void) has its own synchronization and is CPU friendly, too */ if (game_status == GAME_MODE_PLAYING) + { HandleGameActions(); + } else { SyncDisplay(); @@ -208,7 +245,11 @@ void ClearEventQueue() break; case EVENT_KEYRELEASE: +#if 1 + ClearPlayerAction(); +#else key_joystick_mapping = 0; +#endif break; default: @@ -224,7 +265,7 @@ void ClearPlayerAction() /* simulate key release events for still pressed keys */ key_joystick_mapping = 0; - for (i=0; ibutton, + event->type == EVENT_BUTTONPRESS ? "pressed" : "released"); +#endif + motion_status = FALSE; if (event->type == EVENT_BUTTONPRESS) @@ -288,7 +334,7 @@ void HandleButtonEvent(ButtonEvent *event) else button_status = MB_RELEASED; - HandleButton(event->x, event->y, button_status); + HandleButton(event->x, event->y, button_status, event->button); } void HandleMotionEvent(MotionEvent *event) @@ -296,14 +342,12 @@ void HandleMotionEvent(MotionEvent *event) if (!PointerInWindow(window)) return; /* window and pointer are on different screens */ -#if 1 if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR) return; -#endif motion_status = TRUE; - HandleButton(event->x, event->y, button_status); + HandleButton(event->x, event->y, button_status, button_status); } void HandleKeyEvent(KeyEvent *event) @@ -311,7 +355,14 @@ void HandleKeyEvent(KeyEvent *event) int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED); boolean with_modifiers = (game_status == GAME_MODE_PLAYING ? FALSE : TRUE); Key key = GetEventKey(event, with_modifiers); + Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key); + +#if DEBUG_EVENTS + printf("::: KEY EVENT: %d %s\n", GetEventKey(event, TRUE), + event->type == EVENT_KEYPRESS ? "pressed" : "released"); +#endif + HandleKeyModState(keymod, key_status); HandleKey(key, key_status); } @@ -350,6 +401,7 @@ void HandleFocusEvent(FocusChangeEvent *event) Delay(100); KeyboardAutoRepeatOffUnlessAutoplay(); } + if (old_joystick_status != -1) joystick.status = old_joystick_status; } @@ -361,7 +413,7 @@ void HandleClientMessageEvent(ClientMessageEvent *event) CloseAllAndExit(0); } -void HandleButton(int mx, int my, int button) +void HandleButton(int mx, int my, int button, int button_nr) { static int old_mx = 0, old_my = 0; @@ -377,12 +429,24 @@ void HandleButton(int mx, int my, int button) old_my = my; } - HandleGadgets(mx, my, button); + if (HandleGadgets(mx, my, button)) + { + /* do not handle this button event anymore */ + mx = my = -32; /* force mouse event to be outside screen tiles */ + } + + /* do not use scroll wheel button events for anything other than gadgets */ + if (IS_WHEEL_BUTTON(button_nr)) + return; - switch(game_status) + switch (game_status) { + case GAME_MODE_TITLE: + HandleTitleScreen(mx, my, 0, 0, button); + break; + case GAME_MODE_MAIN: - HandleMainMenu(mx,my, 0,0, button); + HandleMainMenu(mx, my, 0, 0, button); break; case GAME_MODE_PSEUDO_TYPENAME: @@ -390,52 +454,29 @@ void HandleButton(int mx, int my, int button) break; case GAME_MODE_LEVELS: - HandleChooseLevel(mx,my, 0,0, button); + HandleChooseLevel(mx, my, 0, 0, button); break; case GAME_MODE_SCORES: - HandleHallOfFame(0,0, 0,0, button); + HandleHallOfFame(0, 0, 0, 0, button); break; case GAME_MODE_EDITOR: + HandleLevelEditorIdle(); break; case GAME_MODE_INFO: - HandleHelpScreen(button); + HandleInfoScreen(mx, my, 0, 0, button); break; case GAME_MODE_SETUP: - HandleSetupScreen(mx,my, 0,0, button); + HandleSetupScreen(mx, my, 0, 0, button); break; case GAME_MODE_PLAYING: #ifdef DEBUG - if (button == MB_RELEASED) - { - int sx = (mx - SX) / TILEX; - int sy = (my - SY) / TILEY; - - if (IN_VIS_FIELD(sx,sy)) - { - int x = LEVELX(sx); - int y = LEVELY(sy); - - printf("INFO: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y); - - if (!IN_LEV_FIELD(x, y)) - break; - - printf(" Feld[%d][%d] == %d\n", x,y, Feld[x][y]); - printf(" Store[%d][%d] == %d\n", x,y, Store[x][y]); - printf(" Store2[%d][%d] == %d\n", x,y, Store2[x][y]); - printf(" StorePlayer[%d][%d] == %d\n", x,y, StorePlayer[x][y]); - printf(" MovPos[%d][%d] == %d\n", x,y, MovPos[x][y]); - printf(" MovDir[%d][%d] == %d\n", x,y, MovDir[x][y]); - printf(" MovDelay[%d][%d] == %d\n", x,y, MovDelay[x][y]); - printf(" GfxElement[%d][%d] == %d\n", x,y, GfxElement[x][y]); - printf("\n"); - } - } + if (button == MB_PRESSED && !motion_status && IN_GFX_SCREEN(mx, my)) + DumpTile(LEVELX((mx - SX) / TILEX), LEVELY((my - SY) / TILEY)); #endif break; @@ -444,9 +485,111 @@ void HandleButton(int mx, int my, int button) } } +static boolean is_string_suffix(char *string, char *suffix) +{ + int string_len = strlen(string); + int suffix_len = strlen(suffix); + + if (suffix_len > string_len) + return FALSE; + + return (strEqual(&string[string_len - suffix_len], suffix)); +} + +#define MAX_CHEAT_INPUT_LEN 32 + +static void HandleKeysSpecial(Key key) +{ + static char cheat_input[2 * MAX_CHEAT_INPUT_LEN + 1] = ""; + char letter = getCharFromKey(key); + int cheat_input_len = strlen(cheat_input); + int i; + + if (letter == 0) + return; + + if (cheat_input_len >= 2 * MAX_CHEAT_INPUT_LEN) + { + for (i = 0; i < MAX_CHEAT_INPUT_LEN + 1; i++) + cheat_input[i] = cheat_input[MAX_CHEAT_INPUT_LEN + i]; + + cheat_input_len = MAX_CHEAT_INPUT_LEN; + } + + cheat_input[cheat_input_len++] = letter; + cheat_input[cheat_input_len] = '\0'; + +#if DEBUG_EVENTS + printf("::: '%s' [%d]\n", cheat_input, cheat_input_len); +#endif + + if (game_status == GAME_MODE_MAIN) + { + if (is_string_suffix(cheat_input, ":insert-solution-tape") || + is_string_suffix(cheat_input, ":ist")) + { + InsertSolutionTape(); + } + else if (is_string_suffix(cheat_input, ":reload-graphics") || + is_string_suffix(cheat_input, ":rg")) + { + ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS); + DrawMainMenu(); + } + else if (is_string_suffix(cheat_input, ":reload-sounds") || + is_string_suffix(cheat_input, ":rs")) + { + ReloadCustomArtwork(1 << ARTWORK_TYPE_SOUNDS); + DrawMainMenu(); + } + else if (is_string_suffix(cheat_input, ":reload-music") || + is_string_suffix(cheat_input, ":rm")) + { + ReloadCustomArtwork(1 << ARTWORK_TYPE_MUSIC); + DrawMainMenu(); + } + else if (is_string_suffix(cheat_input, ":reload-artwork") || + is_string_suffix(cheat_input, ":ra")) + { + ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS | + 1 << ARTWORK_TYPE_SOUNDS | + 1 << ARTWORK_TYPE_MUSIC); + DrawMainMenu(); + } + else if (is_string_suffix(cheat_input, ":dump-level") || + is_string_suffix(cheat_input, ":dl")) + { + DumpLevel(&level); + } + else if (is_string_suffix(cheat_input, ":dump-tape") || + is_string_suffix(cheat_input, ":dt")) + { + DumpTape(&tape); + } + } + else if (game_status == GAME_MODE_PLAYING) + { +#ifdef DEBUG + if (is_string_suffix(cheat_input, ".q")) + DEBUG_SetMaximumDynamite(); +#endif + } + else if (game_status == GAME_MODE_EDITOR) + { + if (is_string_suffix(cheat_input, ":dump-brush") || + is_string_suffix(cheat_input, ":DB")) + { + DumpBrush(); + } + else if (is_string_suffix(cheat_input, ":DDB")) + { + DumpBrush_Small(); + } + } +} + void HandleKey(Key key, int key_status) { - int joy = 0; boolean anyTextGadgetActiveOrJustFinished = anyTextGadgetActive(); static struct SetupKeyboardInfo custom_key; static struct @@ -461,19 +604,20 @@ void HandleKey(Key key, int key_status) { &custom_key.up, DEFAULT_KEY_UP, JOY_UP }, { &custom_key.down, DEFAULT_KEY_DOWN, JOY_DOWN }, { &custom_key.snap, DEFAULT_KEY_SNAP, JOY_BUTTON_1 }, - { &custom_key.bomb, DEFAULT_KEY_BOMB, JOY_BUTTON_2 } + { &custom_key.drop, DEFAULT_KEY_DROP, JOY_BUTTON_2 } }; + int joy = 0; + int i; if (game_status == GAME_MODE_PLAYING) { /* only needed for single-step tape recording mode */ static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; - static boolean bomb_placed[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; + static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; int pnr; - for (pnr=0; pnrLevelSolved_GameEnd && + (key == KSYM_Return || key == setup.shortcut.toggle_pause)) +#else + if (game_status == GAME_MODE_PLAYING && AllPlayersGone && + (key == KSYM_Return || key == setup.shortcut.toggle_pause)) +#endif { - CloseDoor(DOOR_CLOSE_1); - game_status = GAME_MODE_MAIN; - DrawMainMenu(); + GameEnd(); + return; } - /* allow quick escape to the main menu with the Escape key */ - if (key == KSYM_Escape && - game_status != GAME_MODE_MAIN && - game_status != GAME_MODE_PLAYING && - game_status != GAME_MODE_EDITOR && - game_status != GAME_MODE_LEVELS && - game_status != GAME_MODE_SETUP) + if (game_status == GAME_MODE_MAIN && + (key == setup.shortcut.toggle_pause || key == KSYM_space)) { - game_status = GAME_MODE_MAIN; - DrawMainMenu(); + StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); + return; } - /* special key shortcuts */ if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING) { if (key == setup.shortcut.save_game) @@ -585,17 +746,37 @@ void HandleKey(Key key, int key_status) TapeTogglePause(TAPE_TOGGLE_MANUAL); } -#if 0 -#ifndef DEBUG + if (game_status == GAME_MODE_PLAYING && !network_playing) + { + int centered_player_nr_next = -999; - if (game_status == GAME_MODE_PLAYING && (tape.playing || tape.pausing)) - return; + if (key == setup.shortcut.focus_player_all) + centered_player_nr_next = -1; + else + for (i = 0; i < MAX_PLAYERS; i++) + if (key == setup.shortcut.focus_player[i]) + centered_player_nr_next = i; -#endif -#endif + if (centered_player_nr_next != -999) + { + game.centered_player_nr_next = centered_player_nr_next; + game.set_centered_player = TRUE; + + if (tape.recording) + { + tape.centered_player_nr_next = game.centered_player_nr_next; + tape.set_centered_player = TRUE; + } + } + } + HandleKeysSpecial(key); - HandleGadgetsKeyInput(key); + if (HandleGadgetsKeyInput(key)) + { + if (key != KSYM_Escape) /* always allow ESC key to be handled */ + key = KSYM_UNDEFINED; + } switch(game_status) { @@ -603,44 +784,68 @@ void HandleKey(Key key, int key_status) HandleTypeName(0, key); break; + case GAME_MODE_TITLE: case GAME_MODE_MAIN: case GAME_MODE_LEVELS: case GAME_MODE_SETUP: + case GAME_MODE_INFO: + case GAME_MODE_SCORES: switch(key) { + case KSYM_space: case KSYM_Return: - if (game_status == GAME_MODE_MAIN) - HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE); + if (game_status == GAME_MODE_TITLE) + HandleTitleScreen(0, 0, 0, 0, MB_MENU_CHOICE); + else if (game_status == GAME_MODE_MAIN) + HandleMainMenu(0, 0, 0, 0, MB_MENU_CHOICE); else if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0,0, MB_MENU_CHOICE); + HandleChooseLevel(0, 0, 0, 0, MB_MENU_CHOICE); else if (game_status == GAME_MODE_SETUP) - HandleSetupScreen(0,0, 0,0, MB_MENU_CHOICE); + HandleSetupScreen(0, 0, 0, 0, MB_MENU_CHOICE); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0, 0, 0, 0, MB_MENU_CHOICE); + else if (game_status == GAME_MODE_SCORES) + HandleHallOfFame(0, 0, 0, 0, MB_MENU_CHOICE); break; case KSYM_Escape: - if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0,0, MB_MENU_LEAVE); + if (game_status == GAME_MODE_TITLE) + HandleTitleScreen(0, 0, 0, 0, MB_MENU_LEAVE); + else if (game_status == GAME_MODE_LEVELS) + HandleChooseLevel(0, 0, 0, 0, MB_MENU_LEAVE); else if (game_status == GAME_MODE_SETUP) - HandleSetupScreen(0,0, 0,0, MB_MENU_LEAVE); + HandleSetupScreen(0, 0, 0, 0, MB_MENU_LEAVE); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0, 0, 0, 0, MB_MENU_LEAVE); + else if (game_status == GAME_MODE_SCORES) + HandleHallOfFame(0, 0, 0, 0, MB_MENU_LEAVE); break; case KSYM_Page_Up: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + HandleChooseLevel(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) - HandleSetupScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + HandleSetupScreen(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_SCORES) + HandleHallOfFame(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); break; case KSYM_Page_Down: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + HandleChooseLevel(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) - HandleSetupScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + HandleSetupScreen(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_SCORES) + HandleHallOfFame(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); break; #ifdef DEBUG - case KSYM_t: - DumpTape(&tape); + case KSYM_0: + GameFrameDelay = (GameFrameDelay == 500 ? GAME_FRAME_DELAY : 500); break; #endif @@ -649,32 +854,6 @@ void HandleKey(Key key, int key_status) } break; - case GAME_MODE_INFO: - HandleHelpScreen(MB_RELEASED); - break; - - case GAME_MODE_SCORES: - switch(key) - { - case KSYM_Return: - game_status = GAME_MODE_MAIN; - DrawMainMenu(); - BackToFront(); - break; - - case KSYM_Page_Up: - HandleHallOfFame(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); - break; - - case KSYM_Page_Down: - HandleHallOfFame(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); - break; - - default: - break; - } - break; - case GAME_MODE_EDITOR: if (!anyTextGadgetActiveOrJustFinished || key == KSYM_Escape) HandleLevelEditorKeyInput(key); @@ -690,6 +869,7 @@ void HandleKey(Key key, int key_status) #ifdef DEBUG case KSYM_0: +#if 0 case KSYM_1: case KSYM_2: case KSYM_3: @@ -699,6 +879,7 @@ void HandleKey(Key key, int key_status) case KSYM_7: case KSYM_8: case KSYM_9: +#endif if (key == KSYM_0) { if (GameFrameDelay == 500) @@ -725,7 +906,7 @@ void HandleKey(Key key, int key_status) } break; - case KSYM_s: + case KSYM_S: if (!global.fps_slowdown) { global.fps_slowdown = TRUE; @@ -745,32 +926,6 @@ void HandleKey(Key key, int key_status) } break; -#if 0 - case KSYM_a: - if (ScrollStepSize == TILEX/8) - ScrollStepSize = TILEX/4; - else - ScrollStepSize = TILEX/8; - printf("ScrollStepSize == %d\n", ScrollStepSize); - break; -#endif - -#if 0 - case KSYM_m: - if (MoveSpeed == 8) - { - MoveSpeed = 4; - ScrollStepSize = TILEX/4; - } - else - { - MoveSpeed = 8; - ScrollStepSize = TILEX/8; - } - printf("MoveSpeed == %d\n", MoveSpeed); - break; -#endif - case KSYM_f: ScrollStepSize = TILEX/8; printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize); @@ -791,32 +946,10 @@ void HandleKey(Key key, int key_status) printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize); break; - case KSYM_Q: - case KSYM_q: - local_player->dynamite = 1000; + case KSYM_v: + printf("::: currently using game engine version %d\n", + game.engine_version); break; - - - -#if 0 - - case KSYM_z: - { - int i; - - for(i=0; iLevelSolved_GameEnd && newbutton) +#else if (AllPlayersGone && newbutton) +#endif { - CloseDoor(DOOR_CLOSE_1); - game_status = GAME_MODE_MAIN; - DrawMainMenu(); + GameEnd(); + return; }