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 219c0ca..0000000 Binary files a/test/test and /dev/null differ