187 lines
5.8 KiB
C++
187 lines
5.8 KiB
C++
#include "game_input.h"
|
|
|
|
#include <bitset>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
|
|
#include "consts.h"
|
|
|
|
bool handle_input_frame(InputContext &ctx) {
|
|
scanKeys();
|
|
const uint32_t keys = keysDown();
|
|
|
|
if ((keys != 0U) && *ctx.internals) {
|
|
consoleSelect(ctx.topScreen);
|
|
std::string key_str = "\x1b[6;0Hkeys = " + std::bitset<16>(keys).to_string();
|
|
puts(key_str.c_str());
|
|
}
|
|
|
|
if (((keys & KEY_START) != 0U) && ((keys & KEY_L) != 0U)) {
|
|
return false;
|
|
}
|
|
|
|
if ((keys != 0U) && ((keys & KEY_SELECT) != 0U)) {
|
|
*ctx.internals = !(*ctx.internals);
|
|
if (*ctx.internals) {
|
|
setBackdropColor(RGB15(0, 0, 7));
|
|
} else {
|
|
setBackdropColor(RGB15(0, 0, 0));
|
|
consoleSelect(ctx.topScreen);
|
|
consoleClear();
|
|
invalidate_hud(*ctx.renderAssets);
|
|
}
|
|
}
|
|
|
|
if (ctx.state->scene == Scene::Menu) {
|
|
if ((keys != 0U) && ((keys & (KEY_UP | KEY_DOWN)) != 0U)) {
|
|
const int delta = ((keys & KEY_UP) != 0U) ? -1 : 1;
|
|
ctx.state->menuSelection = (ctx.state->menuSelection + delta + MENU_ITEM_COUNT) % MENU_ITEM_COUNT;
|
|
draw_menu(*ctx.state, *ctx.renderAssets, audio_is_music_enabled(*ctx.audio));
|
|
}
|
|
|
|
if ((keys != 0U) && (((keys & KEY_A) != 0U) || ((keys & KEY_START) != 0U))) {
|
|
switch (ctx.state->menuSelection) {
|
|
case 0:
|
|
ctx.state->scene = Scene::Playing;
|
|
ctx.init_game();
|
|
draw_game(*ctx.state, *ctx.renderAssets);
|
|
break;
|
|
case 1:
|
|
ctx.state->hardMode = !ctx.state->hardMode;
|
|
draw_menu(*ctx.state, *ctx.renderAssets, audio_is_music_enabled(*ctx.audio));
|
|
break;
|
|
case 2:
|
|
audio_toggle_music(*ctx.audio);
|
|
draw_menu(*ctx.state, *ctx.renderAssets, audio_is_music_enabled(*ctx.audio));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if ((ctx.state->paused || ctx.state->gameOver) && (keys != 0U) && ((keys & KEY_B) != 0U)) {
|
|
ctx.state->scene = Scene::Menu;
|
|
ctx.state->paused = false;
|
|
draw_menu(*ctx.state, *ctx.renderAssets, audio_is_music_enabled(*ctx.audio));
|
|
return true;
|
|
}
|
|
|
|
if (!ctx.state->paused && !ctx.state->gameOver) {
|
|
const bool cursed = ctx.state->curseTicksRemaining > 0;
|
|
uint16_t requested_dir = 0;
|
|
bool has_dir_input = false;
|
|
|
|
if ((keys != 0U) && ((keys & KEY_UP) != 0U)) {
|
|
requested_dir = cursed ? 2 : 0;
|
|
has_dir_input = true;
|
|
} else if ((keys != 0U) && ((keys & KEY_RIGHT) != 0U)) {
|
|
requested_dir = cursed ? 3 : 1;
|
|
has_dir_input = true;
|
|
} else if ((keys != 0U) && ((keys & KEY_DOWN) != 0U)) {
|
|
requested_dir = cursed ? 0 : 2;
|
|
has_dir_input = true;
|
|
} else if ((keys != 0U) && ((keys & KEY_LEFT) != 0U)) {
|
|
requested_dir = cursed ? 1 : 3;
|
|
has_dir_input = true;
|
|
}
|
|
|
|
if (has_dir_input) {
|
|
bool is_reversing = false;
|
|
|
|
if (ctx.state->snake.size() >= 2) {
|
|
const auto &head = ctx.state->snake.front();
|
|
const auto &neck = ctx.state->snake.at(1);
|
|
int next_x = head[0];
|
|
int next_y = head[1];
|
|
|
|
switch (requested_dir) {
|
|
case 0:
|
|
next_y--;
|
|
break;
|
|
case 1:
|
|
next_x++;
|
|
break;
|
|
case 2:
|
|
next_y++;
|
|
break;
|
|
case 3:
|
|
next_x--;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (next_x > X_MAX) {
|
|
next_x = 0;
|
|
} else if (next_x < 0) {
|
|
next_x = X_MAX;
|
|
}
|
|
|
|
if (next_y > Y_MAX) {
|
|
next_y = 0;
|
|
} else if (next_y < 0) {
|
|
next_y = Y_MAX;
|
|
}
|
|
|
|
if (next_x == neck[0] && next_y == neck[1]) {
|
|
is_reversing = true;
|
|
}
|
|
} else {
|
|
if ((ctx.state->snakeDirection + 2) % 4 == requested_dir) {
|
|
is_reversing = true;
|
|
}
|
|
}
|
|
|
|
if (is_reversing) {
|
|
audio_play_denied(*ctx.audio);
|
|
} else if (ctx.state->snakeDirection != requested_dir) {
|
|
ctx.state->snakeDirection = requested_dir;
|
|
draw_game(*ctx.state, *ctx.renderAssets);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ctx.state->paused) {
|
|
if ((keys != 0U) && ((keys & KEY_X) != 0U)) {
|
|
audio_toggle_music(*ctx.audio);
|
|
}
|
|
|
|
if ((keys != 0U) && ((keys & KEY_Y) != 0U)) {
|
|
ctx.state->hardMode = !ctx.state->hardMode;
|
|
ctx.init_game();
|
|
draw_game(*ctx.state, *ctx.renderAssets);
|
|
}
|
|
}
|
|
|
|
if ((keys != 0U) && ((keys & KEY_R) != 0U)) {
|
|
lcdSwap();
|
|
}
|
|
|
|
if ((keys != 0U) && ((keys & KEY_START) != 0U)) {
|
|
if (!ctx.state->gameOver) {
|
|
ctx.state->paused = !ctx.state->paused;
|
|
|
|
if (ctx.state->paused) {
|
|
consoleSelect(ctx.topScreen);
|
|
audio_play_pause(*ctx.audio);
|
|
audio_pause_music_if_enabled(*ctx.audio);
|
|
puts("\x1b[11;12HPaused");
|
|
invalidate_hud(*ctx.renderAssets);
|
|
} else {
|
|
audio_resume_music_if_enabled(*ctx.audio);
|
|
audio_play_unpause(*ctx.audio);
|
|
consoleSelect(ctx.topScreen);
|
|
consoleClear();
|
|
invalidate_hud(*ctx.renderAssets);
|
|
}
|
|
} else {
|
|
ctx.init_game();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|