From 83a92f8675678cd031fd98ac9812d878055e1ba1 Mon Sep 17 00:00:00 2001 From: sandyx Date: Thu, 5 Sep 2024 08:22:22 -0500 Subject: [PATCH] segments --- makefile | 3 +- modules/autosplit.c | 49 +++++++++++++++++++ src/loader.c | 5 ++ src/main.c | 24 +++++++--- src/parser.c | 71 +++++++++++++++++++++++++++- src/parser.h | 4 ++ src/splits.c | 111 ++++++++++++++++++++++++++++++++++++++++++++ src/splits.h | 10 ++++ test/splits.ghs | 22 +++++++++ test/test | Bin 15920 -> 0 bytes 10 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 modules/autosplit.c create mode 100644 src/loader.c create mode 100644 src/splits.c create mode 100644 test/splits.ghs delete mode 100755 test/test diff --git a/makefile b/makefile index 48694d8..edee78a 100755 --- a/makefile +++ b/makefile @@ -1,6 +1,5 @@ SHELL=/bin/sh CC=gcc -AR= APP_NAME=ghost @@ -10,7 +9,7 @@ BUILD=build C_FILES := $(shell find $(SRC) -name '*.c') O_FILES += $(patsubst $(SRC)/%.c, $(BUILD)/%.o, $(C_FILES)) -CFLAGS := -O2 -march=native +CFLAGS := -O0 -march=native INCLUDE := LIB := -lraylib diff --git a/modules/autosplit.c b/modules/autosplit.c new file mode 100644 index 0000000..2f452a4 --- /dev/null +++ b/modules/autosplit.c @@ -0,0 +1,49 @@ +//this file to be compiled as a shared object + +#define _GNU_SOURCE + +//linux +#include +#include +#include +#include + +static void *addr; +static pid_t pid; +static long long value; +struct iovec local[1]; +struct iovec remote[1]; + +void set_pid(pid_t p) { + pid = p; +} + +//value to compare against +void set_value(long long val) { + value = val; +} + +bool scan(void *addr, size_t type) { + long long values[1]; + local[0].iov_base = values; + local[0].iov_len = sizeof(long long); //may or may not get extra values + + remote[0].iov_base = addr; + remote[0].iov_len = local[0].iov_len; + + process_vm_readv(pid, local, 1, remote, 1, 0); + + //write your comparison function here + + //switch on type to trim possible garbage data + switch(type) { + case sizeof(char): + if ((char)value == (char)values[0]) {return true;} break; + if ((short)value == (short)values[0]) {return true;} break; + if ((int)value == (int)values[0]) {return true;} break; + if ((long)value == (long)values[0]) {return true;} break; + } + + return false; +} + diff --git a/src/loader.c b/src/loader.c new file mode 100644 index 0000000..6d064cd --- /dev/null +++ b/src/loader.c @@ -0,0 +1,5 @@ +#include + +void load_module(const char *path) { + +} diff --git a/src/main.c b/src/main.c index c0ba708..052ad26 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,8 @@ #include #include "timer.h" #include "controller.h" -#include "scanner.h" +//#include "scanner.h" +#include "splits.h" #include GHTimer timer = {0}; @@ -10,6 +11,7 @@ char timer_string[50]; int remote_state = 0; +//testing control function void control(void) { static int last_state; if (last_state != remote_state) @@ -19,13 +21,18 @@ void control(void) { last_state = remote_state; } + + int main(int argc, char *argv[]) { - InitWindow(640, 480, "Ghost"); + InitWindow(420, 640, "Ghost"); SetTargetFPS(60); + segment_list segments = open_splits_file("test/splits.ghs"); + printf("%d\n" , segments.cnt); + ghtimer_start(&timer); - set_control_func(control); - set_pid(17329); + //set_control_func(control); + //set_pid(17329); while (!WindowShouldClose()) { ghtimer_tick(&timer); @@ -35,11 +42,16 @@ int main(int argc, char *argv[]) { ctrl_pause(&timer); } - remote_state = watch_memory((void *)0x7ffc517105f4, 0); + //remote_state = watch_memory((void *)0x7ffc517105f4, 0); BeginDrawing(); ClearBackground(RAYWHITE); - DrawText(timer_string , 10, 1, 100, BLACK); + DrawText(timer_string , 200, 550, 100, BLACK); + + for (int i = 0; i < segments.cnt; i++) { + DrawText(segments.list[i]->name, 10, 30 * i, 30, BLACK); + //DrawText(segments.list[i]->realtime, 50, 30 * i, 30, BLACK); + } EndDrawing(); } } diff --git a/src/parser.c b/src/parser.c index dc52261..e7b4004 100644 --- a/src/parser.c +++ b/src/parser.c @@ -38,7 +38,7 @@ char *load_file(const char *path) { } char *get_next_line(char* buffer, bool clear) { - static char* saveptr; + static char *saveptr; static char *line; if (clear) { @@ -84,3 +84,72 @@ char *get_next_token(char *buffer, char *delim, bool clear) { return token; } + +//find first non space char; +//copy that index to beginning of string +//replace last space with null +char *strip(char *str, char c) { + char *idx; + int len = strlen(str); + + //find index of first non space char + for (int i = 0; i < len; i++) { + if (str[i] != c) { + idx = &str[i]; + break; + } + } + + //voodoo math + memcpy(str, idx, len+1 - (idx - str)); + return str; +} + +//cut off the front +char *cut_front(char *str, char c) { + char *idx; + int len = strlen(str); + + //find index of first matching char + for (int i = 0; i < len; i++) { + if (str[i] == c) { + idx = &str[i]; + + break; + } + } + + return idx + 1; +} + +//cut off the back +char *cut_back(char *str, char c) { + char *idx; + char *cpy = strdup(str); + int len = strlen(str); + + //find index of first matching char + for (int i = 0; i < len; i++) { + if (cpy[i] == c) { + cpy[i] = 0; + + break; + } + } + + return cpy; +} + +//strip a string in place +char *strip_all(char *str) { + char *write = str; + char *read = str; + + do { + if (*read != ' ') { + *write++ = *read; + } + } while (*read++ && *read != ' '); + + return str; +} diff --git a/src/parser.h b/src/parser.h index cb3bd9f..ca7d0db 100644 --- a/src/parser.h +++ b/src/parser.h @@ -10,5 +10,9 @@ size_t get_file_len(FILE *file); char *load_file(const char *path); char *get_next_line(char* buffer, bool clear); char *get_next_token(char *buffer, char *delim, bool clear); +char *strip_all(char *str); +char *strip(char *str, char c); +char *cut_front(char *str, char c); +char *cut_back(char *str, char c); #endif diff --git a/src/splits.c b/src/splits.c new file mode 100644 index 0000000..5b4e37e --- /dev/null +++ b/src/splits.c @@ -0,0 +1,111 @@ +#include "splits.h" +#include "parser.h" +#include "timer.h" + +void print_segment(segment *seg) { + printf("%s\n", seg->name); + //printf("%ld.%ld\n", seg->realtime.tv_sec, seg->realtime.tv_nsec); +} + +struct timespec parse_time(char *str) { + struct timespec time; + + time_t hour_t; + time_t min_t; + time_t sec_t; + time_t nsec_t; + + sscanf(str, "%ld:%ld:%ld.%ld", &hour_t, &min_t, &sec_t, &nsec_t); + + time.tv_sec = (hour_t * 3600) + (min_t * 60) + (sec_t); + time.tv_nsec = nsec_t * 1e+7f; + + //printf("%lf\n", timespec_to_double(time)); + //180.500_000_000 + + return time; +} + +segment *read_segment(char *file, char *line) { + segment *seg = calloc(1, sizeof(segment)); + + while (strcmp(line, "end")) { + char *key = strip(cut_back(line, ':'), ' '); + char *value = cut_front(strip(line, ' '), ' '); + + + if (!strcmp(key, "name")) { + seg->name = strdup(value); + } + + if (!strcmp(key, "gametime")) { + seg->gametime = parse_time(value); + } + + if (!strcmp(key, "realtime")) { + seg->realtime = parse_time(value); + } + + if (!strcmp(key, "best")) { + seg->best = parse_time(value); + } + + free(key); + line = get_next_line(file, 0); + } + + return seg; +} + +segment_list open_splits_file(const char *path) { + char *file = load_file(path); + int idx = 0; + int cnt = 0; + segment_list segments = {0}; + + char *line = get_next_line(file, 0); + + //enumerate segments + while (line != NULL) { + if (!strcmp(line, "segment")) { + segments.cnt++; + } + line = get_next_line(file, 0); + } + + //reset strtok_r and create fresh file since it modified it + get_next_line(NULL, 1); + free(file); file = load_file(path); + + //make an extra one so the last segment->next == NULL; + segments.list = calloc(cnt + 1, sizeof(segment *)); + + line = get_next_line(file, 0); + + //create segments + while (line != NULL) { + if (!strcmp(line, "segment")) { + segments.list[idx] = read_segment(file, line); + idx++; + } + + line = get_next_line(file, 0); + } + + for (int i = 0; i < cnt; i++) { + segments.list[i]->next = segments.list[i+1]; + } + + //check + /*for (int i = 0; i < idx; i++) { + printf("%p\n", segments[i]); + }*/ + + //no leaky + free(file); + + return segments; +} + +//probably need a thing to free all the segments + diff --git a/src/splits.h b/src/splits.h index 2fd9c6c..54e5270 100644 --- a/src/splits.h +++ b/src/splits.h @@ -3,12 +3,22 @@ #include +static char *game_name; + typedef struct segment segment; struct segment { struct timespec realtime; struct timespec gametime; struct timespec best; char *name; + segment *next; }; +typedef struct segment_list { + segment **list; + int cnt; +} segment_list; + +segment_list open_splits_file(const char *path); + #endif diff --git a/test/splits.ghs b/test/splits.ghs new file mode 100644 index 0000000..cdca1fc --- /dev/null +++ b/test/splits.ghs @@ -0,0 +1,22 @@ +game: The Game + +segment + name: Segment 1 + gametime: 00:01:00.50 + realtime: 00:02:00.00 + best: 00:01:00.00 +end + +segment + name: Segment 2 + gametime: 00:02:00.57 + realtime: 00:04:00.00 + best: 00:01:00.00 +end + +segment + name: Segment 3 + gametime: 00:03:00.50 + realtime: 00:06:00.00 + best: 00:01:00.00 +end diff --git a/test/test b/test/test deleted file mode 100755 index 219c0ca93771b65590a34b56954ead1e6e40f104..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15920 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