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