playback demo
This commit is contained in:
parent
e2b532c956
commit
ee83b7986c
|
@ -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);
|
||||
|
|
67
src/input.c
67
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue