The input scroll system currently is hard coded in i_input.
This is likely not where it should remain but for now it works just
fine. Changed docs for commands to explicitly mention commands should
*only* affect gameplay and not contain anything related to menus or
camera movement.
}
lrts_bool i_input_just_pressed(enum i_input_actions action) {
- LRTS_UNUSED(action);
- return LRTS_FALSE;
+ struct i_input_map_ent *e = &i_input_map.inputs[action];
+ return e->pressed == 1 && !i_input_is_delayed(action);
}
lrts_bool i_input_held(enum i_input_actions action) {
- LRTS_UNUSED(action);
- return LRTS_FALSE;
+ struct i_input_map_ent *e = &i_input_map.inputs[action];
+ return (e->pressed & 1) > 0 && !i_input_is_delayed(action);
}
lrts_bool i_input_double_press(enum i_input_actions action) {
return LRTS_FALSE;
}
+void i_input_delay_ticks(enum i_input_actions action, u32 tick_count) {
+ struct i_input_map_ent *e = &i_input_map.inputs[action];
+ struct lrts_state *s = lrts_state();
+
+ e->delay_until_tick = s->tick_count + tick_count;
+}
+
+lrts_bool i_input_is_delayed(enum i_input_actions action) {
+ struct lrts_state *s = lrts_state();
+ struct i_input_map_ent *e = &i_input_map.inputs[action];
+
+ if (s->tick_count >= e->delay_until_tick) {
+ return LRTS_FALSE;
+ }
+ return LRTS_TRUE;
+}
+
void i_input_poll(void) {
u32 i;
struct i_input_map_ent *e;
p_poll_events();
i_input_update();
- /* translate inputs
- * to command queue
+ /*
+ * handle inputs
+ * either directly or
+ * by translating to a commnad
*/
for (i = 0; i < I_INPUT_ACTION_LEN; i++) {
e = &i_input_map.inputs[i];
LRTS_UNUSED(e);
switch (i) {
case I_INPUT_ACTION_CAMERA_UP:
+ if (i_input_held(i)) {
+ t_camera_scroll(&t_main_camera, 0, -10);
+ i_input_delay_ticks(i, 1);
+ }
+ break;
case I_INPUT_ACTION_CAMERA_DOWN:
+ if (i_input_held(i)) {
+ t_camera_scroll(&t_main_camera, 0, 10);
+ i_input_delay_ticks(i, 1);
+ }
+ break;
case I_INPUT_ACTION_CAMERA_LEFT:
+ if (i_input_held(i)) {
+ t_camera_scroll(&t_main_camera, -10, 0);
+ i_input_delay_ticks(i, 1);
+ }
+ break;
case I_INPUT_ACTION_CAMERA_RIGHT:
+ if (i_input_held(i)) {
+ t_camera_scroll(&t_main_camera, 10, 0);
+ i_input_delay_ticks(i, 1);
+ }
+ break;
case I_INPUT_ACTION_CURSOR_CLICK:
case I_INPUT_ACTION_CURSOR_ACTION:
case I_INPUT_ACTION_CURSOR_DRAG:
* the most recent state is in the rightmost bit
*/
u16 pressed;
+
+ /* do not run again until the tick counter
+ * has reached this number */
+ u32 delay_until_tick;
};
/* map of all input actions to scanscodes */
*/
void i_input_poll(void);
+/* delays this action from beign treated as pressed for n ticks */
+void i_input_delay_ticks(enum i_input_actions action, u32 tick_count);
+
+/* tests if the input is delayed */
+lrts_bool i_input_is_delayed(enum i_input_actions action);
/* inits the default for a keybind */
void i_input_map_init_default(enum i_input_actions action,
}
void p_draw_begin(void) {
- SDL_FillSurfaceRect(r_target, NULL, 0x000000);
+ SDL_FillSurfaceRect(r_target, NULL, 0x0000FF);
}
void p_draw_end(void) {
}
void r_draw_solid_isometric_tile(i32 x, i32 y, r_color color) {
+ struct lrts_state *s = lrts_state();
u32 i = 0;
u32 j = 0;
r_color final_color;
struct u_vec2 t = u_tile_to_screen(x, y);
+ t = u_screen_to_camera(&t_main_camera, t);
/* converted origin point in isometric space */
r_draw_pixel(&r_framebuffer, t.x + i, t.y + j, final_color);
}
}
+
+ if (s->debug) {
+ u_debug_draw_text(t.x, t.y, "%d/%d", x, y);
+ }
}
void r_draw_tile(struct t_tile *t, i32 x, i32 y) {
+
switch (t->type) {
case T_TILE_TYPE_NONE:
break;
void t_camera_scroll(struct t_camera *c, i32 by_x, i32 by_y) {
c->x += by_x;
c->y += by_y;
- U_CLAMP(c->x, 0, c->viewport_x);
- U_CLAMP(c->y, 0, c->viewport_y);
+
+ /* TODO: calculate max viewport based on map */
+ U_CLAMP(c->x, -4096, 4096);
+ U_CLAMP(c->y, -4096, 4096);
}
+
+struct u_vec2 u_screen_to_camera(struct t_camera *c, struct u_vec2 v) {
+ v.x -= c->x;
+ v.y -= c->y;
+
+ return v;
+}
void t_camera_scroll(struct t_camera *c, i32 by_x, i32 by_y);
+/* adjusts a screen coodrinate by the camera offset */
+struct u_vec2 u_screen_to_camera(struct t_camera *c, struct u_vec2 v);
+
#endif
u32 t_command_queue_process(void) {
u32 i = 0;
+ u32 n_exec = 0;
struct t_command *c;
struct lrts_state *state = lrts_state();
if (c->type == T_COMMAND_NONE || c->run_at_tick > state->tick_count) {
break;
}
- t_command_exec(c);
+ if (t_command_exec(c)) {
+ n_exec++;
+ }
}
- return 0;
+ return n_exec;
}
lrts_bool t_command_exec(struct t_command *c) {
if (c->type == T_COMMAND_NONE) {
u_log(U_LOG_WARN, "Command of type none was passed to exec\n");
- return LRTS_TRUE;
+ return LRTS_FALSE;
}
c->type = T_COMMAND_NONE;
#include "u_defs.h"
/**
- * A command is an order for a unit.
- * each unit has a command queue.
+ * A command is a serializable action.
+ * Commands must have the following properties:
+ * - they must be unique
+ * - they must be sorted by type, player and tick number
+ * - commands are executed as soon as tick number >= current tick
+ * - commands must represent all changes to the game state
+ * - commands are sent over the network for multiplayer
+ * - all coordinates inside the command buffer must be in world-space
+ * - commands must not include client-side only interactions such as menus or camera
*/
#define T_COMMANDS_MAX 0x4FF
enum t_command_type {
T_COMMAND_NONE = 0,
/* no-op command */
- T_COMMAND_NOOP,
- /* moves camera in the direction of a
- * provided vector
- */
- T_COMMAND_MOVE_CAMERA
+ T_COMMAND_NOOP
};
enum t_command_flags {
end.x = ((t_main_camera.x + t_main_camera.viewport_x) / R_TILE_W) * 2;
end.y = ((t_main_camera.y + t_main_camera.viewport_y) / R_TILE_H) * 2;
+ start.x = 0;
+ start.y = 0;
+
for (i = start.x; i < end.x; i++) {
for (j = start.y; j < end.y; j++) {
r_draw_tile(&m->tiles[j * m->width + i], i, j);
struct t_command t;
u32 i = 0;
- t.type = T_COMMAND_MOVE_CAMERA;
+ t.type = T_COMMAND_NONE;
t_command_push(t);
T_ASSERT(t_command_queue.idx == 1, ("write index moved\n"));
- T_ASSERT(t_command_queue.buffer[0].type == T_COMMAND_MOVE_CAMERA, ("command written\n"));
+ T_ASSERT(t_command_queue.buffer[0].type == T_COMMAND_NONE, ("command written\n"));
for (i = 0; i < T_COMMANDS_MAX+1; i++) {
t_command_push(t);
struct u_vec2 u_tile_to_screen(i32 x, i32 y) {
struct u_vec2 r;
- r.x = (x * R_TILE_W / 2) + (y * R_TILE_W / 2);;
+ r.x = (x * R_TILE_W / 2) + (y * R_TILE_W / 2);
r.y = (y * R_TILE_H / 2) - (x * R_TILE_H / 2);
return r;