/* input.cpp - Don Yang (uguu.org) No input is processed in system (initial calibration) state. 12/21/00 */ #include"global.h" #include"game.h" #include"input.h" #include"resource.h" #include"term.h" static int FrameLeft = -1; static int FrameRight = -1; static int FrameUp = -1; static int FrameDown = -1; static void PopupMenu(void); /***************************************************************** InitInput Initialize input devices. */ BOOL InitInput(void) { // Initialize joystick if( JoystickCaptured ) UninitInput(); JoystickCaptured = FALSE; FrameLeft = FrameRight = FrameUp = FrameDown = -1; if( joySetCapture(AppWindow, JoystickID = JOYSTICKID1, JOYSTICK_PERIOD, FALSE) != JOYERR_NOERROR ) { // Can not capture joystick 1, try joystick 2 if( joySetCapture(AppWindow, JoystickID = JOYSTICKID2, JOYSTICK_PERIOD, FALSE) != JOYERR_NOERROR ) { JoystickAvailable = FALSE; return TRUE; } } JoystickCaptured = JoystickAvailable = TRUE; return TRUE; } // InitInput() /******************************************************************* JoyMove Process joystick movement. */ void JoyMove(int x, int y) { if( GameState < 0 ) return; // Horizontal if( x <= 12 ) { // Left if( FrameLeft < 0 ) { // Press FrameLeft = CurrentPlayer.data[HISTORY_TIME]; FrameRight = -1; MoveBlockLeft(); // (game.cpp) } else if( (int)(CurrentPlayer.data[HISTORY_TIME] - FrameLeft) > (ExpectedFPS / JOYSTICK_REPEAT_DELAY) ) { // Repeat MoveBlockLeft(); } } else if( x >= 20 ) { // Right if( FrameRight < 0 ) { // Press FrameRight = CurrentPlayer.data[HISTORY_TIME]; FrameLeft = -1; MoveBlockRight(); // (game.cpp) } else if( (int)(CurrentPlayer.data[HISTORY_TIME] - FrameRight) > (ExpectedFPS / JOYSTICK_REPEAT_DELAY) ) { // Repeat MoveBlockRight(); } } else { // Release FrameLeft = FrameRight = -1; } // Vertical if( y <= 12 ) { // Up if( FrameUp < 0 ) { // Press FrameUp = CurrentPlayer.data[HISTORY_TIME]; RotateBlock(); // (game.cpp) } else if( (int)(CurrentPlayer.data[HISTORY_TIME] - FrameUp) > (ExpectedFPS / JOYSTICK_REPEAT_DELAY) ) { // Repeat RotateBlock(); } } else if( y >= 20 ) { // Down if( FrameDown < 0 ) { // Press FrameDown = CurrentPlayer.data[HISTORY_TIME]; DropBlock(); // (game.cpp) } else if( (int)(CurrentPlayer.data[HISTORY_TIME] - FrameDown) > (ExpectedFPS / JOYSTICK_REPEAT_DELAY) ) { // Repeat DropBlock(); } } else { // Release FrameUp = FrameDown = -1; } } // JoyMove() /******************************************************************* KeyDown Key pressed (windows standard virtual keys). */ void KeyDown(int key) { if( key == VK_ESCAPE || key == VK_APPS ) { PopupMenu(); } else if( key == VK_SHIFT || key == VK_CONTROL ) { ShiftState = TRUE; } else if( key == KEY_TERMINAL && GameState >= 0 ) { // Switch to terminal state (on key release) } else { switch( GameState ) { case GAME_STATE_WAIT_START: if( key != KEY_EXIT ) StartGame(); // (game.cpp) break; case GAME_STATE_SHOW_HISTORY: case GAME_STATE_SHOW_STATS: if( key != KEY_EXIT ) { GameStateTime = ExpectedFPS * 5; GameState = GAME_STATE_WAIT_START; RedrawAll = TRUE; } break; case GAME_STATE_GENERATE_BLOCK: case GAME_STATE_INPUT_LOOP: case GAME_STATE_CLEAR_SPECIAL: case GAME_STATE_REMOVE_CLUSTER: case GAME_STATE_MARK_CLUSTER: switch( key ) { case KEY_ROTATE: if( AppPaused ) { AppPaused = FALSE; RedrawAll = TRUE; } else { RotateBlock(); // (game.cpp) } break; case KEY_DROP: if( AppPaused ) { AppPaused = FALSE; RedrawAll = TRUE; } else { DropBlock(); // (game.cpp) } break; case KEY_LEFT: if( AppPaused ) { AppPaused = FALSE; RedrawAll = TRUE; } else { FrameLeft = CurrentPlayer.data[HISTORY_TIME]; MoveBlockLeft(); // (game.cpp) } break; case KEY_RIGHT: if( AppPaused ) { AppPaused = FALSE; RedrawAll = TRUE; } else { FrameRight = CurrentPlayer.data[HISTORY_TIME]; MoveBlockRight(); // (game.cpp) } break; case KEY_CAPTURE: case KEY_FRAMERATE: case KEY_RESET: case KEY_EXIT: case KEY_SOUND: break; case KEY_PAUSE: case VK_PAUSE: AppPaused = !AppPaused; RedrawAll = TRUE; break; case '1': FixColumn = GRID_WIDTH / 10; break; case '2': FixColumn = (2 * GRID_WIDTH) / 10; break; case '3': FixColumn = (3 * GRID_WIDTH) / 10; break; case '4': FixColumn = (4 * GRID_WIDTH) / 10; break; case '5': FixColumn = (5 * GRID_WIDTH) / 10; break; case '6': FixColumn = (6 * GRID_WIDTH) / 10; break; case '7': FixColumn = (7 * GRID_WIDTH) / 10; break; case '8': FixColumn = (8 * GRID_WIDTH) / 10; break; case '9': FixColumn = (9 * GRID_WIDTH) / 10; break; case '0': FixSpecial = TRUE; break; default: break; } break; case GAME_STATE_GAME_OVER0: case GAME_STATE_GAME_OVER1: case GAME_STATE_GAME_OVER2: case GAME_STATE_GAME_OVER3: break; case GAME_STATE_ENTER_NAME: case TERMINAL_STATE: break; default: break; } } } // KeyDown() /********************************************************************* KeyUp Key released (windows standard virtual keys). */ void KeyUp(int key) { size_t s; if( key != VK_ESCAPE && key != VK_APPS ) { if( key == KEY_TERMINAL && GameState != TERMINAL_STATE ) { ResumeState = GameState >= 0 ? GameState : SYS_STATE_INIT; GameState = TERMINAL_STATE; RedrawAll = TRUE; return; } else if( key == VK_SHIFT || key == VK_CONTROL ) { ShiftState = FALSE; return; } switch( GameState ) { case GAME_STATE_WAIT_START: case GAME_STATE_SHOW_HISTORY: case GAME_STATE_SHOW_STATS: if( key == KEY_EXIT ) DestroyWindow(AppWindow); ShiftState = FALSE; break; case GAME_STATE_GENERATE_BLOCK: case GAME_STATE_INPUT_LOOP: case GAME_STATE_CLEAR_SPECIAL: case GAME_STATE_REMOVE_CLUSTER: switch( key ) { case KEY_LEFT: FrameLeft = -1; break; case KEY_RIGHT: FrameRight = -1; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': FixColumn = -1; break; case '0': FixSpecial = FALSE; break; case KEY_CAPTURE: PostMessage(AppWindow, WM_COMMAND, APP_MENU_CAPTURE, 0); break; case KEY_FRAMERATE: PostMessage(AppWindow, WM_COMMAND, APP_MENU_FRAMERATE, 0); break; case KEY_SOUND: if( GameOptions & OPTION_SND_ALL ) GameOptions &= ~OPTION_SND_ALL; else GameOptions |= OPTION_SND; break; case KEY_RESET: PostMessage(AppWindow, WM_COMMAND, APP_MENU_RESET, 0); break; case KEY_EXIT: DestroyWindow(AppWindow); break; default: break; } ShiftState = FALSE; break; case GAME_STATE_GAME_OVER0: case GAME_STATE_GAME_OVER1: case GAME_STATE_GAME_OVER2: case GAME_STATE_GAME_OVER3: if( key == KEY_EXIT ) DestroyWindow(AppWindow); ShiftState = FALSE; break; case GAME_STATE_ENTER_NAME: s = strlen(CurrentPlayer.n.name); if( key == VK_BACK ) { if( s > 0 ) CurrentPlayer.n.name[s - 1] = 0; } else if( key == VK_RETURN ) { EnterName(); // (game.cpp) } else if( key == VK_DELETE ) { CurrentPlayer.n.data[0] = 0; } else { if( s >= MAX_NAME_LENGTH ) break; // Translate VK codes to ASCII codes key = Vk2Ascii(key); CurrentPlayer.n.name[s] = (char)key; CurrentPlayer.n.name[s + 1] = 0; } break; case TERMINAL_STATE: TermKeyRelease(key); // (term.cpp) break; default: ShiftState = FALSE; break; } } } // KeyUp() /*************************************************************** MouseButton Mouse button press / release. */ void MouseButton(int x, int y, int flags) { POINT pt; pt.x = x; pt.y = y; ClientToScreen(AppWindow, &pt); MouseX = pt.x; MouseY = pt.y; MouseB = flags; SetCursor(LoadCursor(NULL, IDC_ARROW)); if( GameState >= 0 ) { if( MouseB & MK_RBUTTON ) PopupMenu(); else if( MouseB & MK_LBUTTON ) SetCursor(LoadCursor(NULL, IDC_SIZEALL)); } } // MouseButton() /***************************************************************** MouseMove Mouse move. */ void MouseMove(int x, int y, int flags) { POINT pt; int dx, dy; pt.x = x; pt.y = y; ClientToScreen(AppWindow, &pt); dx = pt.x - MouseX; dy = pt.y - MouseY; MouseX = pt.x; MouseY = pt.y; MouseB = flags; // Move window if( (MouseB & MK_LBUTTON) && GameState >= 0 && (dx != 0 || dy != 0) ) { WindowX += dx; WindowY += dy; if( WindowX < 0 ) WindowX = 0; if( WindowX + APP_WIDTH > ScreenWidth ) WindowX = ScreenWidth - APP_WIDTH; if( WindowY < 0 ) WindowY = 0; if( WindowY + APP_HEIGHT > ScreenHeight ) WindowY = ScreenHeight - APP_HEIGHT; MoveWindow(AppWindow, WindowX, WindowY, APP_WIDTH, APP_HEIGHT, TRUE); RedrawAll = TRUE; } } // MouseMove() /*************************************************************** UninitInput Release input objects. */ void UninitInput(void) { FrameLeft = FrameRight = FrameUp = FrameDown = -1; if( JoystickCaptured ) { joyReleaseCapture(JoystickID); JoystickCaptured = FALSE; } } // UninitInput() /****************************************************************** Vk2Ascii Convert virtual keys to ASCII code. */ int Vk2Ascii(int key) { // Translate key code key &= 0x7f; switch( key ) { case VK_NUMPAD0: key = '0'; break; case VK_NUMPAD1: key = '1'; break; case VK_NUMPAD2: key = '2'; break; case VK_NUMPAD3: key = '3'; break; case VK_NUMPAD4: key = '4'; break; case VK_NUMPAD5: key = '5'; break; case VK_NUMPAD6: key = '6'; break; case VK_NUMPAD7: key = '7'; break; case VK_NUMPAD8: key = '8'; break; case VK_NUMPAD9: key = '9'; break; case VK_MULTIPLY: key = '*'; break; case VK_ADD: key = '+'; break; case VK_SEPARATOR: key = '|'; break; case VK_SUBTRACT: key = '-'; break; case VK_DECIMAL: key = '.'; break; case VK_DIVIDE: key = '/'; break; case '@': key = '`'; break; case '=': key = '-'; break; case ';': key = '='; break; case '<': key = ','; break; case '>': key = '.'; break; case '?': key = '/'; break; case ':': key = ';'; break; case '^': key = '\''; break; case '\t': key = ' '; break; default: break; } if( ShiftState ) { // Translate shift codes switch( key ) { case '`': key = '~'; break; case '1': key = '!'; break; case '2': key = '@'; break; case '3': key = '#'; break; case '4': key = '$'; break; case '5': key = '%'; break; case '6': key = '^'; break; case '7': key = '&'; break; case '8': key = '*'; break; case '9': key = '('; break; case '0': key = ')'; break; case '-': key = '_'; break; case '=': key = '+'; break; case ';': key = ':'; break; case ',': key = '<'; break; case '.': key = '>'; break; case '/': key = '?'; break; case '\\': key = '|'; break; case '\'': key = '\"'; break; default: break; } } return key; } // Vk2Ascii() /***************************************************************** PopupMenu Create popup menu. */ static void PopupMenu(void) { HMENU menu, popup; if( (menu = LoadMenu(AppInstance, MAKEINTRESOURCE(APP_MENU))) == 0 ) return; // (resource.h) popup = GetSubMenu(menu, 0); if( GameState == TERMINAL_STATE ) { EnableMenuItem(popup, APP_MENU_PAUSE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(popup, APP_MENU_HELP, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(popup, APP_MENU_FRAMERATE, MF_BYCOMMAND | MF_GRAYED); } if( GameState > GAME_STATE_SHOW_HISTORY && GameState < GAME_STATE_GAME_OVER0 ) { CheckMenuItem(popup, APP_MENU_PAUSE, MF_BYCOMMAND | (AppPaused ? MF_CHECKED : 0)); } else { EnableMenuItem(popup, APP_MENU_PAUSE, MF_BYCOMMAND | MF_GRAYED); } CheckMenuItem(popup, APP_MENU_NOISE, MF_BYCOMMAND | ((GameOptions & OPTION_SND_ALL) ? MF_CHECKED : 0)); CheckMenuItem(popup, APP_MENU_TRANSPARENT, MF_BYCOMMAND | ((GameOptions & OPTION_SPR_TRANSPARENT) ? MF_CHECKED : 0)); CheckMenuItem(popup, APP_MENU_TRANSLUCENT, MF_BYCOMMAND | ((GameOptions & OPTION_SPR_TRANSLUCENT) ? MF_CHECKED : 0)); CheckMenuItem(popup, APP_MENU_BACKGROUND, MF_BYCOMMAND | ((GameOptions & OPTION_BG_BACKGROUND) ? MF_CHECKED : 0)); switch( GameOptions & OPTION_BG_FX ) { case OPTION_BG_FRACTAL: CheckMenuItem(popup, APP_MENU_FRACTAL, MF_BYCOMMAND | MF_CHECKED); break; case OPTION_BG_DUST: CheckMenuItem(popup, APP_MENU_DUST, MF_BYCOMMAND | MF_CHECKED); break; case OPTION_BG_SWARM: CheckMenuItem(popup, APP_MENU_SWARM, MF_BYCOMMAND | MF_CHECKED); break; default: break; } CheckMenuItem(popup, APP_MENU_WHITE_PARTICLE, MF_BYCOMMAND | ((GameOptions & OPTION_BG_WHITE_PARTICLE) ? MF_CHECKED : 0)); if( JoystickAvailable ) { CheckMenuItem(popup, APP_MENU_JOYSTICK, MF_BYCOMMAND | (JoystickCaptured ? MF_CHECKED : 0)); } else { EnableMenuItem(popup, APP_MENU_JOYSTICK, MF_BYCOMMAND | MF_GRAYED); } TrackPopupMenu(popup, 0, MouseX, MouseY, 0, AppWindow, NULL); DestroyMenu(menu); } // PopupMenu() char *InputObjTime = __TIME__ " " __DATE__; int InputObjLines = __LINE__;