From 2edf798f79a2ebfcbb3268c0ce6b2076b9a8c22a Mon Sep 17 00:00:00 2001 From: UNSTOP4BLE Date: Thu, 4 Apr 2024 22:44:11 +0200 Subject: [PATCH] wip pc stuff --- CMakePresets.json | 12 ++- src/app.h | 2 + src/main.cpp | 51 ++++--------- src/menu/mainmenu.cpp | 8 +- src/menu/title.cpp | 4 +- src/playstate.cpp | 21 +++--- src/psp/gfx.cpp | 13 +++- src/psp/gfx.h | 5 ++ src/psp/input.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++ src/psp/input.h | 78 +++++++++++++++++++ src/psp/pad.cpp | 115 ---------------------------- src/psp/pad.h | 27 ------- 12 files changed, 306 insertions(+), 202 deletions(-) create mode 100644 src/psp/input.cpp create mode 100644 src/psp/input.h delete mode 100644 src/psp/pad.cpp delete mode 100644 src/psp/pad.h diff --git a/CMakePresets.json b/CMakePresets.json index c517f0b..1d40852 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,8 +1,8 @@ { - "version": 6, + "version": 2, "cmakeMinimumRequired": { "major": 3, - "minor": 25, + "minor": 20, "patch": 0 }, "configurePresets": [ @@ -10,6 +10,7 @@ "name": "pc-debug", "displayName": "Debug (PC)", "binaryDir": "${sourceDir}/build", + "generator": "Ninja", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } @@ -18,6 +19,7 @@ "name": "pc-release", "displayName": "Release (PC)", "binaryDir": "${sourceDir}/build", + "generator": "Ninja", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } @@ -26,8 +28,9 @@ "name": "psp-debug", "displayName": "Debug (PSP)", "binaryDir": "${sourceDir}/build", - "toolchainFile": "$env{PSPDEV}/psp/share/pspdev.cmake", + "generator": "Unix Makefiles", "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{PSPDEV}/psp/share/pspdev.cmake", "CMAKE_BUILD_TYPE": "Debug" } }, @@ -35,8 +38,9 @@ "name": "psp-release", "displayName": "Release (PSP)", "binaryDir": "${sourceDir}/build", - "toolchainFile": "$env{PSPDEV}/psp/share/pspdev.cmake", + "generator": "Unix Makefiles", "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{PSPDEV}/psp/share/pspdev.cmake", "CMAKE_BUILD_TYPE": "Release" } } diff --git a/src/app.h b/src/app.h index 2865bce..a5c7f3c 100644 --- a/src/app.h +++ b/src/app.h @@ -4,6 +4,7 @@ #include "chartparser.h" #include "timer.h" #include "screen.h" +#include "psp/input.h" //#ifndef PSP #include @@ -16,6 +17,7 @@ class PSPFunkin SDL_Window *window; SDL_Renderer *renderer; SDL_Surface *screenSurface; + Input::Event event; //#endif Timer timer; Audio::Mixer *audioMixer; diff --git a/src/main.cpp b/src/main.cpp index 95f6531..81a691e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,7 @@ #include "psp/audio_streamed_file.h" #include "psp/font.h" #include "psp/font.h" -#include "psp/pad.h" +#include "psp/input.h" #include "psp/tween.h" #include "menu/title.h" @@ -60,54 +60,33 @@ int main() //#else ASSERTFUNC(SDL_Init(SDL_INIT_EVERYTHING) >= 0, "failed to init sdl"); //#endif - Pad_Init(); app->audioMixer = new Audio::Mixer(); app->audioMixer->start(); GFX::init(); FntInit(); setScreenCol(0xFF00FF00); + Input::KeyboardDevice inputDevice; + app->timer.start(); setScreen(new TitleScreen()); while(1) { auto last = std::chrono::high_resolution_clock::now(); - - if (Pad_Held(PSP_CTRL_CROSS)) - printf("press\n"); -#ifndef PSP - SDL_Event event; - while(SDL_PollEvent(&event)) - { - switch (event.type) { - case SDL_WINDOWEVENT: - - switch (event.window.event) { - - case SDL_WINDOWEVENT_CLOSE: // exit game - - SDL_DestroyWindow(app->window); - app->window = NULL; - app->screenSurface = NULL; - SDL_Quit(); - abort(); - break; - default: - break; - } - break; - default: - break; - } - } -#endif - #ifdef DEBUG - if (Pad_Pressed(PSP_CTRL_SELECT)) - break; - #endif GFX::clear(app->screenCol); - Pad_Update(); + SDL_PumpEvents(); + + if (Input::windowClosed()) { + // all this should probably be moved to app->quit() or a similar function + SDL_DestroyWindow(app->window); + app->window = NULL; + app->screenSurface = NULL; + SDL_Quit(); + abort(); + } + + inputDevice.getEvent(app->event); ASSERTFUNC(app->currentScreen, "screen is NULL"); app->currentScreen->update(); app->currentScreen->draw(); diff --git a/src/menu/mainmenu.cpp b/src/menu/mainmenu.cpp index 6b190c0..9b762fa 100644 --- a/src/menu/mainmenu.cpp +++ b/src/menu/mainmenu.cpp @@ -2,7 +2,7 @@ #include "../main.h" #include "../screen.h" #include "../psp/font.h" -#include "../psp/pad.h" +#include "../app.h" #include "../playstate.h" @@ -20,14 +20,14 @@ MainMenuScreen::MainMenuScreen(void) { void MainMenuScreen::update(void) { - if (Pad_Pressed(PSP_CTRL_DOWN)) + if (app->event.isPressed(Input::MENU_DOWN)) { selection -= 1; if (selection < 0) selection = 0; backgroundy.setValue(0, 1.0); } - else if (Pad_Pressed(PSP_CTRL_UP)) + else if (app->event.isPressed(Input::MENU_UP)) { selection += 1; if (selection > static_cast(COUNT_OF(songs)-1)) @@ -36,7 +36,7 @@ void MainMenuScreen::update(void) } selectedsong = songs[selection]; - if (Pad_Pressed(PSP_CTRL_CROSS | PSP_CTRL_START)) + if (app->event.isPressed(Input::MENU_ENTER)) setScreen(new PlayStateScreen(selectedsong)); } diff --git a/src/menu/title.cpp b/src/menu/title.cpp index 7d19326..d0f415f 100644 --- a/src/menu/title.cpp +++ b/src/menu/title.cpp @@ -6,7 +6,7 @@ #include "../chartparser.h" #include "../psp/animation.h" #include "../psp/audio_file_readers.h" -#include "../psp/pad.h" +#include "../psp/input.h" #include #include "mainmenu.h" @@ -64,7 +64,7 @@ void TitleScreen::update(void) // AnimOBJECT_SetAnim(&titleGF, 1, -1); } // AnimOBJECT_Tick(&titleGF); - if (Pad_Pressed(PSP_CTRL_CROSS | PSP_CTRL_START)) + if (app->event.isPressed(Input::MENU_ENTER)) { if (state != Title) state = Title; diff --git a/src/playstate.cpp b/src/playstate.cpp index c2ccfe2..a0fdd30 100644 --- a/src/playstate.cpp +++ b/src/playstate.cpp @@ -3,7 +3,7 @@ #include "main.h" #include "screen.h" #include "psp/font.h" -#include "psp/pad.h" +#include "psp/input.h" #include "chartparser.h" #include "character.h" #include "app.h" @@ -98,7 +98,7 @@ void PlayStateScreen::initscr(std::string song) { notePos.opponent[1] = { 67, 14}; notePos.opponent[2] = {107, 14}; notePos.opponent[3] = {147, 14}; - + //set up ratings and timings (kinda stolen off of psych engine lmao) //setRating(Rating &rating, std::string name, int score, bool splash, float ratingmod, int hitwindow) ratingData.emplace_back("sick", 350, true, 1, 45); @@ -298,15 +298,14 @@ void PlayStateScreen::missedNote() { void PlayStateScreen::updateInput(void) { - checkPad[0] = Pad_Pressed(PSP_CTRL_LEFT | PSP_CTRL_SQUARE); - checkPad[1] = Pad_Pressed(PSP_CTRL_DOWN | PSP_CTRL_CROSS | PSP_CTRL_LTRIGGER); - checkPad[2] = Pad_Pressed(PSP_CTRL_UP | PSP_CTRL_TRIANGLE | PSP_CTRL_RTRIGGER); - checkPad[3] = Pad_Pressed(PSP_CTRL_RIGHT | PSP_CTRL_CIRCLE); - checkPadHeld[0] = Pad_Held(PSP_CTRL_LEFT | PSP_CTRL_SQUARE); - checkPadHeld[1] = Pad_Held(PSP_CTRL_DOWN | PSP_CTRL_CROSS | PSP_CTRL_LTRIGGER); - checkPadHeld[2] = Pad_Held(PSP_CTRL_UP | PSP_CTRL_TRIANGLE | PSP_CTRL_RTRIGGER); - checkPadHeld[3] = Pad_Held(PSP_CTRL_RIGHT | PSP_CTRL_CIRCLE); - + checkPad[0] = app->event.isPressed(Input::GAME_LEFT); + checkPad[1] = app->event.isPressed(Input::GAME_DOWN); + checkPad[2] = app->event.isPressed(Input::GAME_UP); + checkPad[3] = app->event.isPressed(Input::GAME_RIGHT); + checkPadHeld[0] = app->event.isHeld(Input::GAME_LEFT); + checkPadHeld[1] = app->event.isHeld(Input::GAME_DOWN); + checkPadHeld[2] = app->event.isHeld(Input::GAME_UP); + checkPadHeld[3] = app->event.isHeld(Input::GAME_RIGHT); //handle note hits here? why not lol //opponent diff --git a/src/psp/gfx.cpp b/src/psp/gfx.cpp index 96890d9..cc2f290 100644 --- a/src/psp/gfx.cpp +++ b/src/psp/gfx.cpp @@ -3,15 +3,13 @@ #include "../app.h" #include "../screen.h" #include -#define PCSCALE 1 // works by multiplying psp screen res by this number - #include "memory.h" namespace GFX { void init(void) { - app->window = SDL_CreateWindow("PSPFunkin", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH * PCSCALE, SCREEN_HEIGHT * PCSCALE, SDL_WINDOW_SHOWN); + app->window = SDL_CreateWindow("PSPFunkin", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); app->renderer = SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED); app->screenSurface = SDL_GetWindowSurface(app->window); } @@ -43,6 +41,15 @@ template void drawTex(Texture* tex, GFX::RECT *Img, GFX::RECT(Img->x), static_cast(Img->y), static_cast(Img->w), static_cast(Img->h)}; SDL_Rect _disp = {static_cast(Disp->x), static_cast(Disp->y), static_cast(Disp->w), static_cast(Disp->h)}; +#ifndef PSP + float factorw = (SCREEN_WIDTH/480); + float factorh = (SCREEN_HEIGHT/272); + _disp.x *= factorw; + _disp.y *= factorh; + _disp.w *= factorw; + _disp.h *= factorh; +#endif + SDL_SetTextureAlphaMod(tex, alpha); ASSERTFUNC(SDL_RenderCopyEx(app->renderer, tex, &_img, &_disp, static_cast(angle), NULL, SDL_FLIP_NONE) >= 0, "failed to display sprite"); } diff --git a/src/psp/gfx.h b/src/psp/gfx.h index d26eae3..4215a52 100644 --- a/src/psp/gfx.h +++ b/src/psp/gfx.h @@ -4,8 +4,13 @@ namespace GFX { +#ifdef PSP constexpr int SCREEN_WIDTH = 480; constexpr int SCREEN_HEIGHT = 272; +#else +constexpr int SCREEN_WIDTH = 1280; +constexpr int SCREEN_HEIGHT = 720; +#endif template struct RECT { public: diff --git a/src/psp/input.cpp b/src/psp/input.cpp new file mode 100644 index 0000000..1f4926b --- /dev/null +++ b/src/psp/input.cpp @@ -0,0 +1,172 @@ + +#include +#include "input.h" + +#ifdef PSP +#include +#else +#include +#endif + +namespace Input { + +static const SDL_Scancode keyboardMapping[NUM_BUTTONS]{ + SDL_SCANCODE_UP, // GAME_UP + SDL_SCANCODE_DOWN, // GAME_DOWN + SDL_SCANCODE_LEFT, // GAME_LEFT + SDL_SCANCODE_RIGHT, // GAME_RIGHT + SDL_SCANCODE_ESCAPE, // GAME_PAUSE + + SDL_SCANCODE_UP, // MENU_UP + SDL_SCANCODE_DOWN, // MENU_DOWN + SDL_SCANCODE_LEFT, // MENU_LEFT + SDL_SCANCODE_RIGHT, // MENU_RIGHT + SDL_SCANCODE_RETURN, // MENU_ENTER + SDL_SCANCODE_ESCAPE, // MENU_ESCAPE + SDL_SCANCODE_TAB // MENU_OPTION +}; + +#ifdef PSP +static const uint32_t pspMapping[NUM_BUTTONS]{ + PSP_CTRL_UP | PSP_CTRL_TRIANGLE, // GAME_UP + PSP_CTRL_DOWN | PSP_CTRL_CROSS, // GAME_DOWN + PSP_CTRL_LEFT | PSP_CTRL_SQUARE, // GAME_LEFT + PSP_CTRL_RIGHT | PSP_CTRL_CIRCLE, // GAME_RIGHT + PSP_CTRL_START, // GAME_PAUSE + + PSP_CTRL_UP, // MENU_UP + PSP_CTRL_DOWN, // MENU_DOWN + PSP_CTRL_LEFT, // MENU_LEFT + PSP_CTRL_RIGHT, // MENU_RIGHT + PSP_CTRL_CROSS, // MENU_ENTER + PSP_CTRL_CIRCLE, // MENU_ESCAPE + PSP_CTRL_SQUARE // MENU_OPTION +}; +#else +static const int controllerMapping[NUM_BUTTONS][2]{ + { SDL_CONTROLLER_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_Y }, // GAME_UP + { SDL_CONTROLLER_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_A }, // GAME_DOWN + { SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_X }, // GAME_LEFT + { SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_B }, // GAME_RIGHT + { SDL_CONTROLLER_BUTTON_START, -1 }, // GAME_PAUSE + + { SDL_CONTROLLER_BUTTON_DPAD_UP, -1 }, // MENU_UP + { SDL_CONTROLLER_BUTTON_DPAD_DOWN, -1 }, // MENU_DOWN + { SDL_CONTROLLER_BUTTON_DPAD_LEFT, -1 }, // MENU_LEFT + { SDL_CONTROLLER_BUTTON_DPAD_RIGHT, -1 }, // MENU_RIGHT + { SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_BUTTON_START }, // MENU_ENTER + { SDL_CONTROLLER_BUTTON_B, -1 }, // MENU_ESCAPE + { SDL_CONTROLLER_BUTTON_X -1 } // MENU_OPTION +}; +#endif + +bool KeyboardDevice::getEvent(Event &output) { + output.reset(); + +#ifdef PSP + // PSP has no keyboard + return false; +#else + SDL_Event event; + bool valid = false; + + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_KEYDOWN, SDL_KEYUP) > 0) { + for (int i = 0; i < NUM_BUTTONS; i++) { + uint32_t bits = 1 << i; + + if (event.key.keysym.scancode != keyboardMapping[i]) + continue; + //if (event.key.repeat) + //continue; + + if (event.type == SDL_KEYDOWN) { + output.buttonsPressed |= bits; + _buttonsHeld |= bits; + } else { + output.buttonsReleased |= bits; + _buttonsHeld &= ~bits; + } + + output.timestamp = event.key.timestamp; + output.buttonsHeld = _buttonsHeld; + valid = true; + printf("%d %d\n", i, output.buttonsHeld); + } + } + + return valid; +#endif +} + +bool ControllerDevice::getEvent(Event &output) { + output.reset(); + +#ifdef PSP + SceCtrlData state; + SceCtrlLatch events; + + if (sceCtrlReadBufferPositive(&state) <= 0) + return false; + if (sceCtrlReadLatch(&events) <= 0) + return false; + + output.timestamp = state.TimeStamp; + + for (int i = 0; i < NUM_BUTTONS; i++) { + uint32_t bits = 1 << i; + + if (events.uiMake & pspMapping[i]) + output.buttonsPressed |= bits; + if (events.uiBreak & pspMapping[i]) + output.buttonsReleased |= bits; + if (events.uiPress & pspMapping[i]) + output.buttonsHeld |= bits; + } + + return true; +#else + SDL_Event event; + bool valid = false; + + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONUP) > 0) { + for (int i = 0; i < NUM_BUTTONS; i++) { + uint32_t bits = 1 << i; + + if ( + (event.cbutton.button != controllerMapping[i][0]) && + (event.cbutton.button != controllerMapping[i][1]) + ) + continue; + + if (event.type == SDL_CONTROLLERAXISMOTION) { + // ignore analog sticks + } else if (event.type == SDL_CONTROLLERBUTTONDOWN) { + output.buttonsPressed |= bits; + _buttonsHeld |= bits; + } else { + output.buttonsReleased |= bits; + _buttonsHeld &= ~bits; + } + + output.timestamp = event.cbutton.timestamp; + output.buttonsHeld = _buttonsHeld; + valid = true; + } + } + + return valid; +#endif +} + +bool windowClosed(void) { + SDL_Event event; + + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT) > 0) { + if (event.window.event == SDL_WINDOWEVENT_CLOSE) + return true; + } + + return false; +} + +} diff --git a/src/psp/input.h b/src/psp/input.h new file mode 100644 index 0000000..4e781e1 --- /dev/null +++ b/src/psp/input.h @@ -0,0 +1,78 @@ +#pragma once +#include +#include + +namespace Input { + +static constexpr int NUM_BUTTONS = 12; + +enum Button { + // In-game controls + GAME_UP, + GAME_DOWN, + GAME_LEFT, + GAME_RIGHT, + GAME_PAUSE, + + // Menu controls + MENU_UP, + MENU_DOWN, + MENU_LEFT, + MENU_RIGHT, + MENU_ENTER, + MENU_ESCAPE, + MENU_OPTION +}; +struct Event { +public: + uint32_t timestamp; + uint32_t buttonsPressed, buttonsReleased, buttonsHeld; + + inline void reset(void) { + timestamp = 0; + buttonsPressed = 0; + buttonsReleased = 0; + buttonsHeld = 0; + } + inline bool isPressed(Button button) { + return (buttonsPressed >> button) & 1; + } + inline bool isReleased(Button button) { + return (buttonsReleased >> button) & 1; + } + inline bool isHeld(Button button) { + printf("isHeld %d\n",buttonsHeld); + return (buttonsHeld >> button) & 1; + } +}; + +class Device { +public: + virtual bool getEvent(Event &output) { (void)output; return false; } +}; + +class KeyboardDevice : public Device { +private: + uint32_t _buttonsHeld; + +public: + inline KeyboardDevice(void) + : _buttonsHeld(0) {} + + bool getEvent(Event &output); +}; + +class ControllerDevice : public Device { +private: + uint32_t _buttonsHeld; + +public: + inline ControllerDevice(void) + : _buttonsHeld(0) {} + + bool getEvent(Event &output); +}; + + +bool windowClosed(void); +} diff --git a/src/psp/pad.cpp b/src/psp/pad.cpp deleted file mode 100644 index 6c3e912..0000000 --- a/src/psp/pad.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "../main.h" -#include -#ifdef PSP -#include -#else -#include -#include -#endif -#include - -#include "pad.h" - -struct Input -{ -#ifdef PSP - SceCtrlData Input; -#endif - unsigned long Pressed; - unsigned long Held; -}; - -static Input Pad; - -#ifndef PSP -std::map keyboard; -#endif - -bool Pad_Init (void) -{ -#ifdef PSP - memset (&Pad, 0, sizeof(Input)); - - sceCtrlSetSamplingCycle (0); - - sceCtrlSetSamplingMode (PSP_CTRL_MODE_ANALOG); - -#endif - return 1; -} - -bool Pad_Pressed (int Button) -{ -#ifdef PSP - if (((Pad.Pressed & Button) != 0)) // Pressed is TRUE - { - Pad.Pressed &= ~Button; // so set it to FALSE - return 1; // and return TRUE - } - - return 0; -#else - return keyboard[Button]; -#endif -} - -bool Pad_Held (int Button) -{ -#ifdef PSP - return ((Pad.Held & Button) != 0); -#else - return keyboard[Button]; -#endif -} - -static void AddInput (const unsigned long Button) -{ -#ifdef PSP - if ((Pad.Input.Buttons & Button) != 0) // Button is down - { - if ((Pad.Held & Button) == 0) // Held is not TRUE - { - Pad.Pressed |= Button; // so set both Pressed - Pad.Held |= Button; // and Held to TRUE - } - } - else // Button is up - { - Pad.Pressed &= ~Button; // so set Presses - Pad.Held &= ~Button; // and Held to FALSE - } -#endif -} - -void Pad_Update (void) -{ -#ifdef PSP - sceCtrlPeekBufferPositive (&Pad.Input, 1); - AddInput (PSP_CTRL_SELECT); - AddInput (PSP_CTRL_START); - AddInput (PSP_CTRL_UP); - AddInput (PSP_CTRL_RIGHT); - AddInput (PSP_CTRL_DOWN); - AddInput (PSP_CTRL_LEFT); - AddInput (PSP_CTRL_LTRIGGER); - AddInput (PSP_CTRL_RTRIGGER); - AddInput (PSP_CTRL_TRIANGLE); - AddInput (PSP_CTRL_CIRCLE); - AddInput (PSP_CTRL_CROSS); - AddInput (PSP_CTRL_SQUARE); -#else - SDL_Event event; - while(SDL_PollEvent(&event)) - { - switch(event.type) - { - case SDL_KEYDOWN: //key pressed - keyboard[event.key.keysym.sym] = true; - break; - case SDL_KEYUP: //key released - keyboard[event.key.keysym.sym] = false; - break; - } - } -#endif -} diff --git a/src/psp/pad.h b/src/psp/pad.h deleted file mode 100644 index 28ca42e..0000000 --- a/src/psp/pad.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "../main.h" -#ifdef PSP -#include -#endif -#include - -#ifndef PSP -#define PSP_CTRL_SELECT SDLK_BACKSPACE -#define PSP_CTRL_START SDLK_RETURN -#define PSP_CTRL_UP SDLK_w -#define PSP_CTRL_RIGHT SDLK_d -#define PSP_CTRL_DOWN SDLK_s -#define PSP_CTRL_LEFT SDLK_a -#define PSP_CTRL_LTRIGGER SDLK_q -#define PSP_CTRL_RTRIGGER SDLK_e -#define PSP_CTRL_TRIANGLE SDLK_UP -#define PSP_CTRL_CIRCLE SDLK_LEFT -#define PSP_CTRL_CROSS SDLK_DOWN -#define PSP_CTRL_SQUARE SDLK_RIGHT -#endif - -extern bool Pad_Init (void); -extern void Pad_Shutdown (void); -extern void Pad_Update (void); -extern bool Pad_Pressed (int Button); -extern bool Pad_Held (int Button);