Compare commits
5 Commits
5c3428da56
...
0088fd64de
Author | SHA1 | Date |
---|---|---|
|
0088fd64de | |
|
18064ddf3c | |
|
d8a84f6881 | |
|
44a1eba4de | |
|
16de3bb70e |
|
@ -17,6 +17,7 @@ void init_engine(GameEngine_t* engine, Vector2 starting_win_size)
|
|||
engine->intended_window_size = starting_win_size;
|
||||
InitWindow(starting_win_size.x, starting_win_size.y, "raylib");
|
||||
engine->base_canvas = LoadRenderTexture(starting_win_size.x, starting_win_size.y);
|
||||
engine->last_input_key = KEY_NULL;
|
||||
}
|
||||
|
||||
void deinit_engine(GameEngine_t* engine)
|
||||
|
@ -47,24 +48,46 @@ int get_keybind_or_default(GameEngine_t* engine, ActionType_t action, int defaul
|
|||
return key;
|
||||
}
|
||||
|
||||
void remap_scene_keys(GameEngine_t* engine)
|
||||
{
|
||||
// Assume all scene to be init'd
|
||||
for(size_t i = 0; i < engine->max_scenes; ++i)
|
||||
{
|
||||
if (engine->scenes[i]->action_remap_function != NULL)
|
||||
{
|
||||
engine->scenes[i]->action_remap_function(engine->scenes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_inputs(GameEngine_t* engine, Scene_t* scene)
|
||||
{
|
||||
engine->last_input_key = KEY_NULL;
|
||||
Vector2 raw_mouse_pos = GetMousePosition();
|
||||
scene->mouse_pos = raw_mouse_pos;
|
||||
|
||||
// For flexibility, key that are not mapped to an action are still recorded
|
||||
// pay a little performance to do two checks.
|
||||
|
||||
unsigned int sz = sc_queue_size(&engine->key_buffer);
|
||||
// Process any existing pressed key
|
||||
for (size_t i = 0; i < sz; i++)
|
||||
{
|
||||
int button = sc_queue_del_first(&engine->key_buffer);
|
||||
ActionType_t action = sc_map_get_64(&scene->action_map, button);
|
||||
if (IsKeyReleased(button))
|
||||
bool pressed = !IsKeyReleased(button);
|
||||
if (!pressed)
|
||||
{
|
||||
do_action(scene, action, false);
|
||||
engine->last_input_key = button;
|
||||
}
|
||||
else
|
||||
|
||||
ActionType_t action = sc_map_get_64(&scene->action_map, button);
|
||||
if (sc_map_found(&scene->action_map))
|
||||
{
|
||||
do_action(scene, action, pressed);
|
||||
}
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
do_action(scene, action, true);
|
||||
sc_queue_add_last(&engine->key_buffer, button);
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +98,10 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene)
|
|||
int button = GetKeyPressed();
|
||||
if (button == 0) break;
|
||||
ActionType_t action = sc_map_get_64(&scene->action_map, button);
|
||||
if (!sc_map_found(&scene->action_map)) continue;
|
||||
if (sc_map_found(&scene->action_map))
|
||||
{
|
||||
do_action(scene, action, true);
|
||||
}
|
||||
sc_queue_add_last(&engine->key_buffer, button);
|
||||
}
|
||||
|
||||
|
@ -108,6 +133,17 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene)
|
|||
}
|
||||
}
|
||||
|
||||
Scene_t* change_scene_ext(GameEngine_t* engine, unsigned int idx, bool reset)
|
||||
{
|
||||
|
||||
Scene_t * scene = change_active_scene(engine, idx);
|
||||
if (reset && scene->reset_function != NULL)
|
||||
{
|
||||
scene->reset_function(scene);
|
||||
}
|
||||
return scene;
|
||||
}
|
||||
|
||||
Scene_t* change_scene(GameEngine_t* engine, unsigned int idx)
|
||||
{
|
||||
// Backwards compat
|
||||
|
@ -188,6 +224,7 @@ void init_scene(Scene_t* scene, action_func_t action_func, uint32_t subsystem_in
|
|||
scene->bg_colour = WHITE;
|
||||
|
||||
scene->action_function = action_func;
|
||||
scene->reset_function = NULL;
|
||||
scene->state = SCENE_COMPLETE_ACTIVE;
|
||||
scene->time_scale = 1.0f;
|
||||
}
|
||||
|
@ -435,6 +472,8 @@ void remove_child_scene(GameEngine_t* engine, unsigned int idx)
|
|||
|
||||
Scene_t* change_active_scene(GameEngine_t* engine, unsigned int idx)
|
||||
{
|
||||
assert(idx < engine->max_scenes);
|
||||
|
||||
engine->scenes[engine->curr_scene]->state = 0;
|
||||
engine->curr_scene = idx;
|
||||
engine->scenes[engine->curr_scene]->state = SCENE_COMPLETE_ACTIVE;
|
||||
|
|
|
@ -31,7 +31,10 @@ typedef struct GameEngine {
|
|||
SFXList_t sfx_list;
|
||||
// Maintain own queue to handle key presses
|
||||
Scene_t* focused_scene; // The one scene to receive key inputs
|
||||
struct sc_map_64 keybinds; // Global action -> key mapping
|
||||
|
||||
// Global action->key map. Does not hold previous key
|
||||
struct sc_map_64 keybinds;
|
||||
|
||||
struct sc_queue_32 key_buffer;
|
||||
struct sc_queue_ptr scene_stack;
|
||||
struct sc_heap scenes_render_order;
|
||||
|
@ -40,6 +43,9 @@ typedef struct GameEngine {
|
|||
// an absolute reference
|
||||
Vector2 intended_window_size;
|
||||
RenderTexture2D base_canvas;
|
||||
|
||||
// ad-hoc addition. Next version should be a configurable key buffer
|
||||
int last_input_key;
|
||||
} GameEngine_t;
|
||||
|
||||
#define SCENE_ACTIVE_BIT (1 << 0) // Systems Active
|
||||
|
@ -67,9 +73,12 @@ struct Scene {
|
|||
EntityManager_t ent_manager;
|
||||
Scene_t* parent_scene;
|
||||
struct sc_map_64 action_map; // key -> actions
|
||||
|
||||
struct sc_array_systems systems;
|
||||
SceneRenderLayers_t layers;
|
||||
Color bg_colour;
|
||||
system_func_t reset_function;
|
||||
system_func_t action_remap_function;
|
||||
action_func_t action_function;
|
||||
float delta_time;
|
||||
float time_scale;
|
||||
|
@ -88,14 +97,22 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene);
|
|||
|
||||
// Register a key bind. If already exists, will override.
|
||||
// Does not support multi key to an action
|
||||
// Register keybind should be done before scene inits. This lets the engine
|
||||
// know what are the available keybinds for the game runtime.
|
||||
//
|
||||
void register_keybind(GameEngine_t* engine, int key, ActionType_t action);
|
||||
int get_keybind_or_default(GameEngine_t* engine, ActionType_t action, int default_key);
|
||||
|
||||
// If a key bind gets changed, this must be called to update the
|
||||
// key -> action mapping for all scene
|
||||
void remap_scene_keys(GameEngine_t* engine);
|
||||
|
||||
void process_active_scene_inputs(GameEngine_t* engine);
|
||||
void update_curr_scene(GameEngine_t* engine);
|
||||
void render_curr_scene(GameEngine_t* engine);
|
||||
|
||||
Scene_t* change_scene(GameEngine_t* engine, unsigned int idx);
|
||||
Scene_t* change_scene_ext(GameEngine_t* engine, unsigned int idx, bool reset);
|
||||
Scene_t* change_active_scene(GameEngine_t* engine, unsigned int idx);
|
||||
void change_focused_scene(GameEngine_t* engine, unsigned int idx);
|
||||
bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx);
|
||||
|
|
1
main.c
1
main.c
|
@ -44,6 +44,7 @@ int main(void)
|
|||
register_keybind(&engine, KEY_SPACE, ACTION_JUMP);
|
||||
register_keybind(&engine, KEY_Q, ACTION_EXIT);
|
||||
register_keybind(&engine, KEY_Z, ACTION_LOOKAHEAD);
|
||||
register_keybind(&engine, KEY_R, ACTION_RESTART);
|
||||
|
||||
load_sfx(&engine, "snd_jump", PLAYER_JMP_SFX);
|
||||
load_sfx(&engine, "snd_land", PLAYER_LAND_SFX);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "tracy/TracyC.h"
|
||||
|
||||
#include "keymaps.h"
|
||||
#include "scene_impl.h"
|
||||
#include "game_systems.h"
|
||||
#include "water_flow.h"
|
||||
|
@ -62,9 +63,10 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
air_pos.x -= 32;
|
||||
}
|
||||
}
|
||||
if (sc_map_size_64v(&scene->ent_manager.entities_map[PLAYER_ENT_TAG]) == 0)
|
||||
if (data->sm.state == LEVEL_STATE_DEAD)
|
||||
{
|
||||
DrawTextEx(*menu_font, "Press R to Try Again", (Vector2){32, data->game_rec.height/2 - 64}, 64, 4, WHITE);
|
||||
sprintf(buffer, "Press %s to Try Again", data->restart_keyname);
|
||||
DrawTextEx(*menu_font, buffer, (Vector2){32, data->game_rec.height/2 - 64}, 64, 4, WHITE);
|
||||
}
|
||||
// For DEBUG
|
||||
int gui_x = 5;
|
||||
|
@ -73,7 +75,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
|
||||
DrawRectangle(0, 0, data->game_rec.width, 32, (Color){0,0,0,128});
|
||||
{
|
||||
DrawText("Z", 300, 5, 24, RED);
|
||||
DrawText(data->look_keyname, 300, 5, 24, RED);
|
||||
Sprite_t* spr = get_sprite(&scene->engine->assets, "eye");
|
||||
if (data->camera.mode == CAMERA_RANGED_MOVEMENT)
|
||||
{
|
||||
|
@ -518,6 +520,30 @@ static void at_level_complete(Scene_t* scene)
|
|||
}
|
||||
}
|
||||
|
||||
static void game_action_remap_func(Scene_t* scene)
|
||||
{
|
||||
sc_map_clear_64(&scene->action_map);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_JUMP, KEY_ENTER), ACTION_JUMP);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
{
|
||||
int restart_key = get_keybind_or_default(scene->engine, ACTION_RESTART, KEY_R);
|
||||
data->restart_keyname = ExtGetKeyName(restart_key);
|
||||
sc_map_put_64(&scene->action_map, restart_key, ACTION_RESTART);
|
||||
}
|
||||
|
||||
{
|
||||
int look_key = get_keybind_or_default(scene->engine, ACTION_LOOKAHEAD, KEY_Z);
|
||||
data->look_keyname = ExtGetKeyName(look_key);
|
||||
sc_map_put_64(&scene->action_map, look_key, ACTION_LOOKAHEAD);
|
||||
}
|
||||
}
|
||||
|
||||
void init_game_scene(LevelScene_t* scene)
|
||||
{
|
||||
init_scene(&scene->scene, &level_do_action, ENABLE_ENTITY_MANAGEMENT_SYSTEM | ENABLE_PARTICLE_SYSTEM);
|
||||
|
@ -526,6 +552,7 @@ void init_game_scene(LevelScene_t* scene)
|
|||
init_entity_tag_map(&scene->scene.ent_manager, LEVEL_END_TAG, 16);
|
||||
init_entity_tag_map(&scene->scene.ent_manager, DYNMEM_ENT_TAG, 16);
|
||||
|
||||
scene->scene.action_remap_function = &game_action_remap_func;
|
||||
scene->data.tilemap.tiles = all_tiles;
|
||||
scene->data.tilemap.render_nodes = all_tile_rendernodes;
|
||||
init_level_scene_data(
|
||||
|
@ -549,6 +576,7 @@ void init_game_scene(LevelScene_t* scene)
|
|||
scene->data.sm.state_functions[LEVEL_STATE_RUNNING] = NULL;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_DEAD] = NULL;
|
||||
scene->data.sm.state_functions[LEVEL_STATE_COMPLETE] = at_level_complete;
|
||||
scene->data.sm.state = LEVEL_STATE_STARTING;
|
||||
|
||||
scene->scene.bg_colour = LIGHTGRAY;
|
||||
add_scene_layer(
|
||||
|
@ -600,15 +628,7 @@ void init_game_scene(LevelScene_t* scene)
|
|||
// This avoid graphical glitch, not essential
|
||||
//sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_JUMP);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LOOKAHEAD, KEY_Z), ACTION_LOOKAHEAD);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART);
|
||||
game_action_remap_func(&scene->scene);
|
||||
}
|
||||
|
||||
void free_game_scene(LevelScene_t* scene)
|
||||
|
|
|
@ -245,6 +245,18 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
|
|||
}
|
||||
}
|
||||
|
||||
static void level_select_action_remap_func(Scene_t* scene)
|
||||
{
|
||||
sc_map_clear_64(&scene->action_map);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
|
||||
sc_map_put_64(&scene->action_map, KEY_BACKSPACE, ACTION_EXIT);
|
||||
sc_map_put_64(&scene->action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
}
|
||||
|
||||
#define FONT_SIZE 22
|
||||
#define TEXT_PADDING 3
|
||||
#define SCROLL_TOTAL_HEIGHT 800
|
||||
|
@ -253,6 +265,7 @@ void init_level_select_scene(LevelSelectScene_t* scene)
|
|||
init_scene(&scene->scene, &level_select_do_action, 0);
|
||||
scene->data.preview = LoadRenderTexture(LEVEL_PREVIEW_SIZE, LEVEL_PREVIEW_SIZE);
|
||||
scene->data.update_preview = true;
|
||||
scene->scene.action_remap_function = level_select_action_remap_func;
|
||||
add_scene_layer(
|
||||
&scene->scene, scene->scene.engine->intended_window_size.x,
|
||||
scene->scene.engine->intended_window_size.y,
|
||||
|
@ -298,13 +311,7 @@ void init_level_select_scene(LevelSelectScene_t* scene)
|
|||
sc_array_add(&scene->scene.systems, &level_preview_render_func);
|
||||
sc_array_add(&scene->scene.systems, &level_select_render_func);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_BACKSPACE, ACTION_EXIT);
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
level_select_action_remap_func(&scene->scene);
|
||||
}
|
||||
void free_level_select_scene(LevelSelectScene_t* scene)
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ static void exec_component_function(Scene_t* scene, int sel)
|
|||
change_scene(scene->engine, LEVEL_SELECT_SCENE);
|
||||
break;
|
||||
case 1:
|
||||
change_scene(scene->engine, OPTIONS_SCENE);
|
||||
change_scene_ext(scene->engine, OPTIONS_SCENE, true);
|
||||
break;
|
||||
case 2:
|
||||
scene->state = 0;
|
||||
|
@ -162,9 +162,24 @@ static void gui_loop(Scene_t* scene)
|
|||
}
|
||||
}
|
||||
|
||||
static void menu_action_remap_func(Scene_t* scene)
|
||||
{
|
||||
sc_map_clear_64(&scene->action_map);
|
||||
|
||||
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
// Guarantee a enter key for selection
|
||||
sc_map_put_64(&scene->action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
}
|
||||
|
||||
void init_menu_scene(MenuScene_t* scene)
|
||||
{
|
||||
init_scene(&scene->scene, &menu_do_action, 0);
|
||||
scene->scene.action_remap_function = &menu_action_remap_func;
|
||||
|
||||
sc_array_add(&scene->scene.systems, &gui_loop);
|
||||
sc_array_add(&scene->scene.systems, &menu_scene_render_func);
|
||||
|
@ -205,14 +220,7 @@ void init_menu_scene(MenuScene_t* scene)
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
// Guarantee a enter key for selection
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
menu_action_remap_func(&scene->scene);
|
||||
}
|
||||
|
||||
void free_menu_scene(MenuScene_t* scene)
|
||||
|
|
|
@ -37,6 +37,8 @@ static const char* get_action_name(ActionType_t action) {
|
|||
return "Return";
|
||||
case ACTION_LOOKAHEAD:
|
||||
return "Look";
|
||||
case ACTION_RESTART:
|
||||
return "Restart";
|
||||
default:
|
||||
return "Undefined";
|
||||
}
|
||||
|
@ -48,55 +50,119 @@ static void options_scene_render_func(Scene_t* scene)
|
|||
|
||||
KeyBindInfo_t keybind_info;
|
||||
char buffer[64];
|
||||
int y_offset = 16;
|
||||
int y_offset = 32;
|
||||
uint16_t line = 0;
|
||||
|
||||
Sprite_t* level_board = get_sprite(&scene->engine->assets, "lvl_board");
|
||||
#define TITLE_FONT_SIZE 40
|
||||
#define FONT_SIZE 24
|
||||
#define FONT_COLOUR BLACK
|
||||
float start_x = scene->engine->intended_window_size.x / 2;
|
||||
start_x -= level_board->frame_size.x / 2;
|
||||
Font* menu_font = get_font(&scene->engine->assets, "MenuFont");
|
||||
|
||||
BeginTextureMode(scene->layers.render_layers[0].layer_tex);
|
||||
ClearBackground((Color){0,0,0,0});
|
||||
draw_sprite(level_board, 0, (Vector2){start_x,0},0, false);
|
||||
Vector2 title_size = MeasureTextEx(*menu_font, "Options", TITLE_FONT_SIZE, 4);
|
||||
DrawTextEx(*menu_font, "Options", (Vector2){start_x + title_size.x/2,y_offset}, TITLE_FONT_SIZE, 4, BLACK);
|
||||
y_offset += TITLE_FONT_SIZE;
|
||||
|
||||
start_x += 32;
|
||||
if (line == data->curr_selection)
|
||||
{
|
||||
DrawText(">>", 0, y_offset, 12, WHITE);
|
||||
DrawTextEx(*menu_font, ">>", (Vector2){start_x,y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
float vol = GetMasterVolume();
|
||||
sprintf(buffer, "Volume : %.1f", vol);
|
||||
DrawText(buffer, 32, y_offset, 12, WHITE);
|
||||
y_offset += 12;
|
||||
DrawTextEx(*menu_font, buffer, (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
y_offset += FONT_SIZE;
|
||||
line++;
|
||||
|
||||
sc_array_foreach(&data->keybinds_info, keybind_info) {
|
||||
if (line == data->curr_selection)
|
||||
{
|
||||
DrawText(">>", 0, y_offset, 12, WHITE);
|
||||
DrawTextEx(*menu_font, ">>", (Vector2){start_x,y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
sprintf(buffer, "%s : %s %d", keybind_info.action_name, keybind_info.key_name, keybind_info.key);
|
||||
DrawText(buffer, 32, y_offset, 12, WHITE);
|
||||
y_offset += 12;
|
||||
if (keybind_info.key == keybind_info.original_key)
|
||||
{
|
||||
sprintf(buffer, "%s : %s", keybind_info.action_name, keybind_info.key_name);
|
||||
DrawTextEx(*menu_font, buffer, (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s : %s => %s", keybind_info.action_name, keybind_info.original_key_name, keybind_info.key_name);
|
||||
DrawTextEx(*menu_font, buffer, (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLUE);
|
||||
}
|
||||
y_offset += FONT_SIZE;
|
||||
line++;
|
||||
}
|
||||
|
||||
y_offset += FONT_SIZE;
|
||||
if (line == data->curr_selection)
|
||||
{
|
||||
DrawText(">>", 0, y_offset, 12, WHITE);
|
||||
DrawTextEx(*menu_font, ">>", (Vector2){start_x, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
DrawText("OK", 32, y_offset, 12, WHITE);
|
||||
y_offset += 12;
|
||||
DrawTextEx(*menu_font, "Apply", (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
y_offset += FONT_SIZE;
|
||||
line++;
|
||||
|
||||
if (line == data->curr_selection)
|
||||
{
|
||||
DrawText(">>", 0, y_offset, 12, WHITE);
|
||||
DrawTextEx(*menu_font, ">>", (Vector2){start_x,y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
DrawText("Cancel", 32, y_offset, 12, WHITE);
|
||||
y_offset += 12;
|
||||
DrawTextEx(*menu_font, "Return", (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
y_offset += FONT_SIZE;
|
||||
line++;
|
||||
|
||||
if (data->mode == OPTIONS_KEYBIND_MODE)
|
||||
{
|
||||
y_offset += FONT_SIZE;
|
||||
DrawTextEx(*menu_font, "Press a Key...", (Vector2){start_x+32, y_offset}, FONT_SIZE, 4, BLACK);
|
||||
}
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
static void wait_for_keymap_input(Scene_t* scene)
|
||||
{
|
||||
/**
|
||||
* Due to engine design limitation, I canot remove
|
||||
* the system when placed into the array
|
||||
* So, this will have to run as part of the loop
|
||||
* Even though it is only used in a particular mode
|
||||
* It's a small performance penalty for unfortunate design
|
||||
*/
|
||||
|
||||
OptionSceneData_t* data = &(CONTAINER_OF(scene, OptionScene_t, scene)->data);
|
||||
if (data->mode == OPTIONS_NORMAL_MODE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->mode == OPTIONS_KEYBIND_READY_MODE)
|
||||
{
|
||||
// Keys are processed before system Update
|
||||
// Need to skip the current frame to get the next key
|
||||
// This state is to do just that.
|
||||
data->mode = OPTIONS_KEYBIND_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (scene->engine->last_input_key == KEY_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data->keybinds_info.elems[data->curr_selection - 1].key = scene->engine->last_input_key;
|
||||
data->keybinds_info.elems[data->curr_selection - 1].key_name = ExtGetKeyName(scene->engine->last_input_key);
|
||||
|
||||
data->mode = OPTIONS_NORMAL_MODE;
|
||||
}
|
||||
|
||||
static void exec_component_function(Scene_t* scene, uint16_t sel)
|
||||
{
|
||||
printf("Sel: %u\n", sel);
|
||||
OptionSceneData_t* data = &(CONTAINER_OF(scene, OptionScene_t, scene)->data);
|
||||
if (sel == 0)
|
||||
{
|
||||
// Volume option, does nothing
|
||||
|
@ -109,16 +175,31 @@ static void exec_component_function(Scene_t* scene, uint16_t sel)
|
|||
{
|
||||
// Either OK or Cancel
|
||||
// Both will return to menu scene
|
||||
// OK does nothing since the keybinds are already modified
|
||||
sel -= n_binds;
|
||||
// TODO: add check to save keybinds
|
||||
|
||||
change_scene(scene->engine, MAIN_MENU_SCENE);
|
||||
if (sel == 0)
|
||||
{
|
||||
// OK will propagate to the engine
|
||||
KeyBindInfo_t info;
|
||||
sc_array_foreach(&data->keybinds_info, info)
|
||||
{
|
||||
register_keybind(scene->engine, info.key, info.action);
|
||||
}
|
||||
remap_scene_keys(scene->engine);
|
||||
scene->reset_function(scene);
|
||||
data->curr_selection = sel + n_binds + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keybind options
|
||||
// TODO: This should change the scene mode
|
||||
// Engine need to record last key released
|
||||
// Need to reset action map, otherwise will preserve over scene change
|
||||
scene->action_remap_function(scene);
|
||||
change_scene(scene->engine, MAIN_MENU_SCENE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keybind options, but need to wait one frame
|
||||
data->mode = OPTIONS_KEYBIND_READY_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,15 +254,56 @@ static void options_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OPTIONS_KEYBIND_MODE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_options_scene(Scene_t* scene)
|
||||
{
|
||||
OptionSceneData_t* data = &(CONTAINER_OF(scene, OptionScene_t, scene)->data);
|
||||
sc_array_clear(&data->keybinds_info);
|
||||
{
|
||||
int key;
|
||||
ActionType_t action;
|
||||
sc_map_foreach(&scene->engine->keybinds, action, key)
|
||||
{
|
||||
KeyBindInfo_t keybind = {
|
||||
.action_name = get_action_name(action),
|
||||
.key_name = ExtGetKeyName(key),
|
||||
.original_key_name = ExtGetKeyName(key),
|
||||
.action = action,
|
||||
.original_key = key,
|
||||
.key = key,
|
||||
};
|
||||
sc_array_add(&data->keybinds_info, keybind);
|
||||
}
|
||||
}
|
||||
data->curr_selection = 0;
|
||||
data->mode = OPTIONS_NORMAL_MODE;
|
||||
}
|
||||
|
||||
static void options_action_remap_func(Scene_t* scene)
|
||||
{
|
||||
sc_map_clear_64(&scene->action_map);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->action_map, get_keybind_or_default(scene->engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
|
||||
sc_map_put_64(&scene->action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->action_map, KEY_BACKSPACE, ACTION_EXIT);
|
||||
}
|
||||
|
||||
void init_options_scene(OptionScene_t* scene)
|
||||
{
|
||||
init_scene(&scene->scene, &options_do_action, 0);
|
||||
scene->scene.bg_colour = BLACK;
|
||||
scene->scene.reset_function = &reset_options_scene;
|
||||
scene->scene.action_remap_function = &options_action_remap_func;
|
||||
|
||||
add_scene_layer(
|
||||
&scene->scene, scene->scene.engine->intended_window_size.x,
|
||||
scene->scene.engine->intended_window_size.y,
|
||||
|
@ -201,35 +323,10 @@ void init_options_scene(OptionScene_t* scene)
|
|||
|
||||
sc_array_init(&scene->data.keybinds_info);
|
||||
|
||||
{
|
||||
int key;
|
||||
ActionType_t action;
|
||||
sc_map_foreach(&scene->scene.engine->keybinds, action, key)
|
||||
{
|
||||
KeyBindInfo_t keybind = {
|
||||
.action_name = get_action_name(action),
|
||||
.key_name = ExtGetKeyName(key),
|
||||
.action = action,
|
||||
.key = key,
|
||||
};
|
||||
sc_array_add(&scene->data.keybinds_info, keybind);
|
||||
}
|
||||
}
|
||||
|
||||
// The number of actions that can be key-binds is constant.
|
||||
// So can just init once.
|
||||
|
||||
sc_array_add(&scene->scene.systems, &wait_for_keymap_input);
|
||||
sc_array_add(&scene->scene.systems, &options_scene_render_func);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_UP, KEY_UP), ACTION_UP);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_DOWN, KEY_DOWN), ACTION_DOWN);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_LEFT, KEY_LEFT), ACTION_LEFT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_RIGHT, KEY_RIGHT), ACTION_RIGHT);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_JUMP, KEY_ENTER), ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->scene.action_map, get_keybind_or_default(scene->scene.engine, ACTION_EXIT, KEY_Q), ACTION_EXIT);
|
||||
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM);
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_BACKSPACE, ACTION_EXIT);
|
||||
options_action_remap_func(&scene->scene);
|
||||
}
|
||||
|
||||
void free_options_scene(OptionScene_t* scene)
|
||||
|
|
|
@ -72,6 +72,8 @@ typedef struct LevelSceneData {
|
|||
Sprite_t* solid_tile_sprites;
|
||||
uint8_t selected_solid_tilemap;
|
||||
LevelPack_t* level_pack;
|
||||
const char* restart_keyname;
|
||||
const char* look_keyname;
|
||||
unsigned int current_level;
|
||||
CoinCounter_t coins;
|
||||
bool show_grid;
|
||||
|
@ -137,14 +139,17 @@ typedef struct LevelSelectScene {
|
|||
|
||||
typedef enum OptionSceneMode {
|
||||
OPTIONS_NORMAL_MODE,
|
||||
OPTIONS_KEYBIND_READY_MODE,
|
||||
OPTIONS_KEYBIND_MODE,
|
||||
}OptionSceneMode_t;
|
||||
|
||||
typedef struct KeyBindInfo {
|
||||
const char* action_name;
|
||||
const char* key_name;
|
||||
const char* original_key_name;
|
||||
int action;
|
||||
int key;
|
||||
int original_key;
|
||||
}KeyBindInfo_t;
|
||||
sc_array_def(KeyBindInfo_t, keybinds);
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
|||
scene->data.tilemap.n_tiles = n_tiles;
|
||||
scene->data.coins.current = 0;
|
||||
scene->data.coins.total = lvl_map.n_chests;
|
||||
scene->data.sm.state = LEVEL_STATE_STARTING;
|
||||
|
||||
#define N_SOLID_TILESETS 4
|
||||
static const char* SOLID_TILE_SELECTIONS[N_SOLID_TILESETS] = {
|
||||
|
|
Loading…
Reference in New Issue