Skip to content

Commit

Permalink
Demo Record + Replay (#150) (#152)
Browse files Browse the repository at this point in the history
* Added demo

* Added default demo file
  • Loading branch information
JohnathonNow authored Nov 3, 2020
1 parent cbd4322 commit a2800fe
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 7 deletions.
40 changes: 34 additions & 6 deletions src/core/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
#include <stdlib.h>
#include <time.h>
#include "args.h"

#include "demo.h"
static unsigned long seed;
void parse_args(int argc, char **argv)
{
srand(time(NULL));
int demo_started = 0;
set_seed(time(NULL));

while (1) {
struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "seed", required_argument, NULL, 's' },
{ "play", optional_argument, NULL, 'r' },
{ "record", optional_argument, NULL, 'w' },
{ 0, 0, 0, 0 }
};
int c = getopt_long(argc, argv, "hs:", long_options, NULL);
unsigned long seed;
int c = getopt_long(argc, argv, "hs:r?w?", long_options, NULL);

if (c == -1) {
break;
Expand All @@ -29,7 +32,10 @@ void parse_args(int argc, char **argv)
("hag, an ncurses procedurally-generated dungeon crawler.\n\n");
printf("Usage: %s [options]\n", argv[0]);
printf("-h, --help Show this help message\n");
printf("-s, --seed <seed> RNG seed to use\n");
printf("-s, --seed <seed> RNG seed to use\n");
printf("-r, --play [file] demo file to replay\n");
printf("-w, --record [file] file to save demo to\n");
printf("\n\n--play and --record take an optional file - if these flags are used but no file is given, .demo.hag is used instead.\n");
exit(EXIT_SUCCESS);
case 's':
seed = strtoul(optarg, NULL, 10);
Expand All @@ -39,10 +45,32 @@ void parse_args(int argc, char **argv)
exit(EXIT_FAILURE);
}

srand(seed);
set_seed(seed);
break;
case 'r':
demo_start(DEMO_REPLAY, optarg);
demo_started = 1;
break;
case 'w':
demo_start(DEMO_RECORD, optarg);
demo_started = 1;
break;
default:
exit(EXIT_FAILURE);
}
}
if (!demo_started) {
demo_start(DEMO_NONE, 0);
}
}

void set_seed(unsigned long s)
{
seed = s;
srand(s);
}

unsigned long get_seed(void)
{
return seed;
}
2 changes: 2 additions & 0 deletions src/core/args.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#ifndef ARGS_H
#define ARGS_H
void parse_args(int argc, char **argv);
unsigned long get_seed(void);
void set_seed(unsigned long seed);
#endif
75 changes: 75 additions & 0 deletions src/core/demo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <curses.h>
#include <unistd.h>
#include "demo.h"
#include "args.h"

static void demo_write_header(void);
static void demo_read_header(void);

static FILE* read_from = 0;
static FILE* write_to = 0;

void usleep(long); /* needed because headers are big sad */

int demo_next(void)
{
int move = 0;
if (read_from) {
fread(&move, sizeof(move), 1, read_from);
usleep(1000 /*ms to us*/ * 300 /*ms*/);
}
if (!move) {
move = getch();
}
if (write_to) {
fwrite(&move, sizeof(move), 1, write_to);
}
return move;
}

static void demo_read_header()
{
int demo_version;
unsigned long s;
fread(&demo_version, sizeof(demo_version), 1, read_from);
fread(&s, sizeof(s), 1, read_from);
/* TODO: fail if demo version is wrong */
set_seed(s);
}


static void demo_write_header(void)
{
unsigned long s = get_seed();
int demo_version = DEMO_VERSION;
fwrite(&demo_version, sizeof(demo_version), 1, write_to);
fwrite(&s, sizeof(s), 1, write_to);
}

void demo_start(int mode, char* fname)
{
if (!fname) {
fname = DEMO_DEFAULT_FILE;
}
if (read_from) {
fclose(read_from);
read_from = 0;
}
if (write_to) {
fclose(write_to);
write_to = 0;
}
switch (mode) {
default:
break;
case DEMO_REPLAY:
read_from = fopen(fname, "r");
demo_read_header();
break;
case DEMO_RECORD:
write_to = fopen(fname, "w");
demo_write_header();
break;
}
}
11 changes: 11 additions & 0 deletions src/core/demo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef DEMO_H
#define DEMO_H
int demo_next(void);
void demo_start(int mode, char* fname);
#define DEMO_NONE 0
#define DEMO_REPLAY 1
#define DEMO_RECORD 2
#define DEMO_VERSION 0
#define DEMO_DEFAULT_FILE ".demo.hag"
/* TODO: do we need a demo_close? */
#endif
3 changes: 2 additions & 1 deletion src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <unistd.h>
#include <ctype.h>

#include "demo.h"
#include "args.h"
#include "player.h"
#include "colors.h"
Expand Down Expand Up @@ -126,7 +127,7 @@ int main(int argc, char **argv)
xn = xp = player->x;
yn = yp = player->y;
ch = ERR;
if ((ch = repeat_act) || (ch = getch(), ch != ERR)) {
if ((ch = repeat_act) || (ch = demo_next(), ch != ERR)) {
if (rand() % player->luck) {
switch (ch) {
case KEY_FIGHT:
Expand Down

0 comments on commit a2800fe

Please sign in to comment.