From ee83b7986c30d775f37b58ca59db53bfe35b1ab3 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Thu, 23 Dec 2021 15:54:44 +0100 Subject: [PATCH] playback demo --- inc/input.h | 9 ++++--- src/input.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--------- src/main.c | 9 ++++++- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/inc/input.h b/inc/input.h index 4495338..d2536e1 100644 --- a/inc/input.h +++ b/inc/input.h @@ -14,22 +14,25 @@ enum Key { K_SCROLL_UP, K_SCROLL_DOWN, K_DEBUG, + K_SAVE_REPLAY, + K_PLAYBACK, K_COUNT }; enum KeyState { KS_UP, KS_DOWN, KS_PRESS }; -typedef unsigned char PackedFrame; +typedef short PackedFrame; struct Input { enum Key keys[K_COUNT]; enum KeyState states[K_COUNT]; - int replay_cursor; + int replay_cursor, replay_end, playback; PackedFrame replay[REPLAY_SIZE]; }; void input_init(void); void input_update(void); -void input_write_replay(void); +void input_dump_replay(void); +void input_load_replay(void); int input_down(enum Key); int input_pressed(enum Key); diff --git a/src/input.c b/src/input.c index 17ede90..e345aec 100644 --- a/src/input.c +++ b/src/input.c @@ -6,10 +6,13 @@ static struct Input input; static const int default_map[K_COUNT] = { - KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_SHIFT, KEY_ALPHA, - KEY_EXIT, KEY_TAN, KEY_F3, KEY_F2, KEY_F1, KEY_F6}; + KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_SHIFT, KEY_ALPHA, KEY_EXIT, + KEY_TAN, KEY_F3, KEY_F2, KEY_F1, KEY_F4, KEY_F5, KEY_F6}; +static const char *replay_path = "jtmm2.fls"; +static void next_state(int i, int kdown); static PackedFrame pack_frame(void); +static void unpack_frame(PackedFrame); void input_init(void) @@ -22,6 +25,7 @@ input_init(void) } i = REPLAY_SIZE; input.replay_cursor = 0; + input.playback = 0; } void @@ -29,21 +33,32 @@ input_update(void) { int i = K_COUNT; clearevents(); - while (i-- > 0) { + while (i-- > K_EXIT) { const int kdown = keydown(input.keys[i]); - input.states[i] = (input.states[i] == KS_UP) - ? (kdown ? KS_PRESS : KS_UP) - : (kdown ? KS_DOWN : KS_UP); + next_state(i, kdown); + } + if (input.playback) { + unpack_frame(input.replay[input.replay_cursor++]); + if (input.replay_cursor >= input.replay_end || + input.replay_cursor >= REPLAY_SIZE) { + input.replay_cursor--; + input.playback = 0; + } + } else { + i++; + while (i-- > 0) { + const int kdown = keydown(input.keys[i]); + next_state(i, kdown); + } + input.replay[input.replay_cursor++] = pack_frame(); + if (input.replay_cursor >= REPLAY_SIZE) input.replay_cursor--; } - input.replay[input.replay_cursor++] = pack_frame(); - if (input.replay_cursor >= REPLAY_SIZE) - input.replay_cursor = REPLAY_SIZE - 1; } void -input_write_replay(void) +input_dump_replay(void) { - const int fd = open("jtmm2.rep", O_WRONLY | O_CREAT | O_TRUNC); + const int fd = open(replay_path, O_WRONLY | O_CREAT | O_TRUNC); if (fd != -1) { write(fd, input.replay, input.replay_cursor * sizeof(PackedFrame)); @@ -51,6 +66,20 @@ input_write_replay(void) } } +void +input_load_replay(void) +{ + const int fd = open(replay_path, O_RDONLY); + if (fd != -1) { + input.playback = 1; + input.replay_cursor = 0; + input.replay_end = + read(fd, input.replay, REPLAY_SIZE) / sizeof(PackedFrame); + if (!input.replay_end) input.replay_cursor = REPLAY_SIZE; + close(fd); + } +} + int input_down(enum Key k) { @@ -69,6 +98,14 @@ input_up(enum Key k) return input.states[k] == KS_UP; } +static void +next_state(int i, int kdown) +{ + input.states[i] = (input.states[i] == KS_UP) + ? (kdown ? KS_PRESS : KS_UP) + : (kdown ? KS_DOWN : KS_UP); +} + static PackedFrame pack_frame(void) { @@ -78,3 +115,11 @@ pack_frame(void) r |= input_down(i) << i; return r; } + +static void +unpack_frame(PackedFrame f) +{ + int i = K_EXIT; + while (i-- > 0) + next_state(i, (f & (1 << i)) != 0); +} diff --git a/src/main.c b/src/main.c index 4937703..2ec235a 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,6 @@ deinit(void) { level_deinit(); missile_manager_free(); - gint_world_switch(GINT_CALL(input_write_replay)); timer_stop(timer); } @@ -86,6 +85,14 @@ update(void) player_update(&player); /* enter editor */ if (input_pressed(K_EDITOR)) editor(); + /* save replay */ + if (input_pressed(K_SAVE_REPLAY)) { + gint_world_switch(GINT_CALL(input_dump_replay)); + has_ticked = 0; + } + /* playback */ + if (input_pressed(K_PLAYBACK)) + gint_world_switch(GINT_CALL(input_load_replay)); } static void