better splits.c
parent
ca2c786c1e
commit
f32b5e76ae
@ -0,0 +1,150 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "splits.h"
|
||||
#include "fmt.h"
|
||||
#include "xml.h"
|
||||
|
||||
struct xml_node *get_node_by_name(struct xml_node *node, char *tag);
|
||||
extern void error(const char *msg); //put this in a header
|
||||
|
||||
typedef struct run_data {
|
||||
char *game_name;
|
||||
char *category_name;
|
||||
char *offset;
|
||||
int attempt_count;
|
||||
} run_data;
|
||||
|
||||
typedef struct xml_run_data {
|
||||
struct xml_node *game_name;
|
||||
struct xml_node *category_name;
|
||||
struct xml_node *attempt_count;
|
||||
struct xml_node *segments;
|
||||
} xml_run_data;
|
||||
|
||||
typedef struct xml_segment_data {
|
||||
struct xml_node *name;
|
||||
struct xml_node *rta;
|
||||
struct xml_node *igt;
|
||||
//can do more data later
|
||||
} xml_segment_data;
|
||||
|
||||
//ignore this for now
|
||||
typedef struct r_segment {
|
||||
char *name;
|
||||
struct {
|
||||
struct {
|
||||
char *rta;
|
||||
char *igt;
|
||||
} split_time;
|
||||
} split_times [];
|
||||
} r_segment;
|
||||
//utils
|
||||
|
||||
static inline int get_file_size(FILE *file) {
|
||||
int size;
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size = ftell(file);
|
||||
fseek(file, 0L, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
//create a segment from xml_segment_data
|
||||
segment segment_from_data(xml_segment_data data) {
|
||||
segment seg;
|
||||
seg.name = xml_easy_content(data.name);
|
||||
seg.realtime = parse_time( xml_easy_content(data.rta) );
|
||||
seg.gametime = parse_time( xml_easy_content(data.igt) );
|
||||
return seg;
|
||||
}
|
||||
|
||||
//create a segment from a <Segment> node
|
||||
segment segment_from_node(struct xml_node *node) {
|
||||
xml_segment_data data;
|
||||
struct xml_node *splittimes = get_node_by_name(node, "SplitTimes");
|
||||
struct xml_node *splittime = get_node_by_name(splittimes, "SplitTime");
|
||||
data.name = get_node_by_name(node, "Name");
|
||||
data.rta = get_node_by_name(splittime, "RealTime");
|
||||
data.igt = get_node_by_name(splittime, "GameTime");
|
||||
return segment_from_data(data);
|
||||
}
|
||||
|
||||
struct xml_node *get_node_by_name(struct xml_node *node, char *tag) {
|
||||
for (int i = 0; i < xml_node_children(node); i++) {
|
||||
struct xml_node *child = xml_node_child(node, i);
|
||||
|
||||
char *name = xml_easy_name(child);
|
||||
if ( strcmp(name, tag) == 0 ) {
|
||||
free(name);
|
||||
return child;
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
xml_run_data get_run_data(struct xml_document *doc) {
|
||||
struct xml_node *root = xml_document_root(doc);
|
||||
|
||||
//all the important stuff
|
||||
xml_run_data data;
|
||||
data.game_name = get_node_by_name(root, "GameName");
|
||||
data.category_name = get_node_by_name(root, "CategoryName");
|
||||
data.attempt_count = get_node_by_name(root, "AttemptCount");
|
||||
data.segments = get_node_by_name(root, "Segments");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
segment_list open_splits_file(const char *path) {
|
||||
FILE *xml_file = fopen(path, "r");
|
||||
if (xml_file == NULL) {
|
||||
error("Could not open file");
|
||||
}
|
||||
|
||||
int xml_file_size = get_file_size(xml_file);
|
||||
uint8_t buffer[xml_file_size]; //no more dirty calloc
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
fread(buffer, sizeof(uint8_t), xml_file_size, xml_file);
|
||||
struct xml_document *xml = xml_parse_document(buffer, xml_file_size);
|
||||
if (xml == NULL) {
|
||||
error("Could not parse XML");
|
||||
}
|
||||
|
||||
xml_run_data data = get_run_data(xml);
|
||||
|
||||
int n = xml_node_children(data.segments);
|
||||
segment *segs = calloc(n, sizeof(segment));
|
||||
for (int i = 0; i < n; i++) {
|
||||
segs[i] = segment_from_node(xml_node_child(data.segments, i));
|
||||
}
|
||||
|
||||
segment_list sl;
|
||||
sl.segments = segs;
|
||||
sl.count = n;
|
||||
return sl;
|
||||
}
|
||||
|
||||
//only for the ruby script
|
||||
char *save_fmt(segment_list *sl) {
|
||||
#define buffer_size 8192
|
||||
static char buffer[buffer_size];
|
||||
char *bfp;
|
||||
bfp = &buffer[0];
|
||||
memset(bfp, 0, buffer_size);
|
||||
|
||||
char unparse_buffer[64];
|
||||
char *unp;
|
||||
|
||||
for (int i = 0; i < sl->count; i++) {
|
||||
unp = time_unparse(unparse_buffer, 64, &sl->segments[i].realtime);
|
||||
sprintf(bfp, "%s=%s%%", sl->segments[i].name, unp);
|
||||
bfp += strlen(bfp);
|
||||
}
|
||||
|
||||
printf("%s\n", buffer);
|
||||
return buffer;
|
||||
#undef buffer_size
|
||||
}
|
||||
Loading…
Reference in New Issue