add gamepad menu support
This commit is contained in:
parent
fb3c8b7a04
commit
6bfe25ee07
@ -12,11 +12,16 @@ namespace renpy {
|
||||
constexpr int yStride = 100;
|
||||
};
|
||||
|
||||
extern int lastGamepadItem;
|
||||
extern bool lastUseGamepad;
|
||||
|
||||
bool overlap(int menuWidth, int menuHeight,
|
||||
int x, int y,
|
||||
int mx, int my,
|
||||
int windowWidth, int windowHeight);
|
||||
void update(interpreter & state,
|
||||
int mx, int my, bool mLeft,
|
||||
bool gUp, bool gDown, bool gAccept,
|
||||
bool useGamepad,
|
||||
int windowWidth, int windowHeight);
|
||||
}
|
||||
|
||||
24
src/main.cpp
24
src/main.cpp
@ -1023,6 +1023,9 @@ int main()
|
||||
audio::init();
|
||||
audio::load(renpy::script::audio, renpy::script::audio_length);
|
||||
|
||||
bool useGamepad = false;
|
||||
uint32_t whichGamepad = 0;
|
||||
|
||||
while (quit == false) {
|
||||
audio::update();
|
||||
|
||||
@ -1063,6 +1066,7 @@ int main()
|
||||
}
|
||||
}
|
||||
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
||||
useGamepad = false;
|
||||
if (event.motion.state & SDL_BUTTON_LMASK) {
|
||||
//collada_state.mouse_motion(cameraIndex, cameraTargetIndex, event.motion.xrel, event.motion.yrel, 0);
|
||||
}
|
||||
@ -1079,6 +1083,11 @@ int main()
|
||||
if (event.type == SDL_EVENT_GAMEPAD_REMOVED) {
|
||||
remove_gamepad(event.gdevice.which);
|
||||
}
|
||||
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
|
||||
whichGamepad = event.gbutton.which;
|
||||
useGamepad = true;
|
||||
fprintf(stderr, "use gamepad: which %d\n", whichGamepad);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -1089,7 +1098,22 @@ int main()
|
||||
float my;
|
||||
uint32_t mouseFlags = SDL_GetMouseState(&mx, &my);
|
||||
bool mLeft = (mouseFlags & SDL_BUTTON_LMASK) != 0;
|
||||
bool gUp = false;
|
||||
bool gDown = false;
|
||||
bool gAccept = false;
|
||||
if (useGamepad) {
|
||||
for (int i = 0; i < gamepad_count; i++) {
|
||||
if (SDL_GetGamepadID(gamepads[i]) == whichGamepad) {
|
||||
gUp = SDL_GetGamepadButton(gamepads[i], SDL_GAMEPAD_BUTTON_DPAD_UP);
|
||||
gDown = SDL_GetGamepadButton(gamepads[i], SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||
gAccept = SDL_GetGamepadButton(gamepads[i], SDL_GAMEPAD_BUTTON_SOUTH) || SDL_GetGamepadButton(gamepads[i], SDL_GAMEPAD_BUTTON_EAST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renpy::update(interpreter_state, mx, my, mLeft,
|
||||
gUp, gDown, gAccept, useGamepad,
|
||||
surfaceCapabilities.currentExtent.width,
|
||||
surfaceCapabilities.currentExtent.height);
|
||||
|
||||
|
||||
@ -30,34 +30,84 @@ namespace renpy {
|
||||
return mxf >= minX && mxf <= maxX && myf >= minY && myf <= maxY;
|
||||
}
|
||||
|
||||
static bool lastMenuPause = false;
|
||||
static bool lastmLeft = false;
|
||||
int lastGamepadItem = 0;
|
||||
bool lastUseGamepad = false;
|
||||
|
||||
static bool lastgUp = false;
|
||||
static bool lastgDown = false;
|
||||
static bool lastgAccept = false;
|
||||
|
||||
static void jumpToMenuItem(interpreter & state, int i)
|
||||
{
|
||||
// jump to menu item
|
||||
uint32_t optionIndex = state.menu.optionIndex + i;
|
||||
assert(optionIndex < (uint32_t)script::options_length);
|
||||
uint32_t next_pc = script::options[optionIndex].statementIndex;
|
||||
fprintf(stderr, "interact[%d]: menu jump %d\n", state.pc, next_pc);
|
||||
state.pc = next_pc;
|
||||
state.pause.menu = false;
|
||||
}
|
||||
|
||||
void update(interpreter & state,
|
||||
int mx, int my, bool mLeft,
|
||||
bool _gUp, bool _gDown, bool _gAccept,
|
||||
bool useGamepad,
|
||||
int windowWidth, int windowHeight)
|
||||
{
|
||||
lastUseGamepad = useGamepad;
|
||||
|
||||
bool mDown = mLeft && (!lastmLeft);
|
||||
lastmLeft = mLeft;
|
||||
//if (mDown) {
|
||||
//state.pause.voice = false;
|
||||
//}
|
||||
|
||||
if (!state.pause.menu || !mDown)
|
||||
bool pauseTransition = state.pause.menu && (!lastMenuPause);
|
||||
lastMenuPause = state.pause.menu;
|
||||
|
||||
bool gUp = _gUp && (!lastgUp);
|
||||
bool gDown = _gDown && (!lastgDown);
|
||||
bool gAccept = _gAccept && (!lastgAccept);
|
||||
lastgUp = _gUp;
|
||||
lastgDown = _gDown;
|
||||
lastgAccept = _gAccept;
|
||||
|
||||
if (!state.pause.menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < state.menu.count; i++) {
|
||||
int y = menu::yStride * i + menu::y;
|
||||
if (pauseTransition) {
|
||||
fprintf(stderr, "interact::update: menu pause transition\n");
|
||||
lastGamepadItem = 0;
|
||||
}
|
||||
|
||||
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
|
||||
if (overlap) {
|
||||
// jump to menu item
|
||||
uint32_t optionIndex = state.menu.optionIndex + i;
|
||||
assert(optionIndex < (uint32_t)script::options_length);
|
||||
uint32_t next_pc = script::options[optionIndex].statementIndex;
|
||||
fprintf(stderr, "interact[%d]: menu jump %d\n", state.pc, next_pc);
|
||||
state.pc = next_pc;
|
||||
state.pause.menu = false;
|
||||
break;
|
||||
if (useGamepad) {
|
||||
//printf("useGamepad %d %d\n", gUp, _gAccept);
|
||||
if (gUp) {
|
||||
lastGamepadItem -= 1;
|
||||
if (lastGamepadItem < 0)
|
||||
lastGamepadItem = state.menu.count - 1;
|
||||
}
|
||||
if (gDown) {
|
||||
lastGamepadItem += 1;
|
||||
if (lastGamepadItem >= (int)state.menu.count)
|
||||
lastGamepadItem = 0;
|
||||
}
|
||||
if (gAccept) {
|
||||
jumpToMenuItem(state, lastGamepadItem);
|
||||
}
|
||||
} else {
|
||||
// use mouse
|
||||
for (uint32_t i = 0; i < state.menu.count; i++) {
|
||||
int y = menu::yStride * i + menu::y;
|
||||
|
||||
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
|
||||
if (overlap) {
|
||||
lastGamepadItem = i;
|
||||
if (mDown) {
|
||||
jumpToMenuItem(state, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,7 +534,12 @@ namespace renpy {
|
||||
for (uint32_t i = 0; i < state.menu.count; i++) {
|
||||
int y = menu::yStride * i + menu::y;
|
||||
|
||||
bool overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
|
||||
bool overlap = false;
|
||||
if (renpy::lastUseGamepad) {
|
||||
overlap = (i == (uint32_t)lastGamepadItem);
|
||||
} else {
|
||||
overlap = renpy::overlap(menu::width, menu::height, menu::x, y, mx, my, windowWidth, windowHeight);
|
||||
}
|
||||
instanceMappedData[maximumImageCount * frameIndex + outputIndex++] = {
|
||||
.size = {menu::width, menu::height},
|
||||
.topLeft = {menu::x, (int16_t)(y)},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user