From e5e287e3e8440a74a8765d7928ffae53e39a0236 Mon Sep 17 00:00:00 2001 From: sandyx86 Date: Sun, 18 Aug 2024 10:02:02 -0500 Subject: [PATCH] migrate to c --- src/controller.h | 28 ++++++++++++++++ src/controller.m | 42 +++++++++++++++++++++++ src/input.h | 29 ++++++++++++++++ src/input.m | 25 ++++++++++++++ src/main.m | 83 ++++++++++++++++++++++++++++++++++++++++++++++ src/renderer.h | 38 +++++++++++++++++++++ src/renderer.m | 62 ++++++++++++++++++++++++++++++++++ src/splits.h | 49 +++++++++++++++++++++++++++ src/splits.m | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/timer.c | 67 +++++++++++++++++++++++++++++++++++++ src/timer.c.h | 28 ++++++++++++++++ src/timer.h | 34 +++++++++++++++++++ src/timer.m | 78 +++++++++++++++++++++++++++++++++++++++++++ src/timeutils.c | 19 +++++++++++ src/timeutils.h | 11 +++++++ 15 files changed, 679 insertions(+) create mode 100644 src/controller.h create mode 100644 src/controller.m create mode 100644 src/input.h create mode 100644 src/input.m create mode 100644 src/main.m create mode 100644 src/renderer.h create mode 100644 src/renderer.m create mode 100644 src/splits.h create mode 100644 src/splits.m create mode 100644 src/timer.c create mode 100644 src/timer.c.h create mode 100644 src/timer.h create mode 100644 src/timer.m create mode 100644 src/timeutils.c create mode 100644 src/timeutils.h diff --git a/src/controller.h b/src/controller.h new file mode 100644 index 0000000..5325763 --- /dev/null +++ b/src/controller.h @@ -0,0 +1,28 @@ +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#import +#import "timer.h" +#import "splits.h" +//#import + +/* + this thing just decouples the timer from the splits + + could have a method to check whether the timer + should stop, like on the last segment +*/ + +@interface Controller : YSObject { +@public + Timer *timer; + Segment *splits; +} + ++(id) new; +-(void) startOrSplit; +-(void) pauseUnpause; + +@end + +#endif \ No newline at end of file diff --git a/src/controller.m b/src/controller.m new file mode 100644 index 0000000..ea74f88 --- /dev/null +++ b/src/controller.m @@ -0,0 +1,42 @@ +#import "controller.h" + +@implementation Controller + ++(id) new { + self = [Controller alloc]; + return [self init]; +} + +-(void) startOrSplit { + if (timer->running) { + [splits setRealtime: [timer time]]; + splits = [splits next]; + + if (timer->paused) { + [timer stop]; + } + + if (splits == NULL) { + [timer pause]; + } + + } else { + [timer start]; + } +} + +-(void) pauseUnpause { + if (!timer->running) { + [timer start]; + return; + } + + if (!timer->paused) { + [timer pause]; + } else { + [timer resume]; + + } +} + +@end \ No newline at end of file diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..d3902b3 --- /dev/null +++ b/src/input.h @@ -0,0 +1,29 @@ +#ifndef INPUT_H +#define INPUT_H + +#import +#import + +/* + the input handler will need a way to know + what to do when what key is pressed. + + im thinking it could call a method and do + a function pointer +*/ + +typedef struct Yep { + id obj; + SEL selector; +} Yep; + +@interface Input : YSObject { + Yep map[256]; +} + ++(id) new; +-(void) handleInput; +-(void) setKey: (int) key toPerform: (SEL) sel on: (id) obj; + +@end +#endif diff --git a/src/input.m b/src/input.m new file mode 100644 index 0000000..7afb123 --- /dev/null +++ b/src/input.m @@ -0,0 +1,25 @@ +#import "input.h" + +@implementation Input + ++(id) new { + self = [Input alloc]; + [self init]; + return self; +} + +-(void) handleInput { + int key = GetKeyPressed(); + + if( IsKeyPressed(key) ) { + [map[key].obj performSelector: map[key].selector]; + printf("%s\n", "t"); + } +} + +-(void) setKey: (int) key toPerform: (SEL) sel on: (id) obj { + map[key].selector = sel; + map[key].obj = obj; +} + +@end \ No newline at end of file diff --git a/src/main.m b/src/main.m new file mode 100644 index 0000000..a64042d --- /dev/null +++ b/src/main.m @@ -0,0 +1,83 @@ +#include +#include +#include +#include "timer.h" +#import "splits.h" +#include "input.h" +#include "controller.h" +#import "renderer.h" + +int main(void) { + + Timer *timer = [[Timer alloc] init]; + Input *input = [Input new]; + SegmentLinker *linker = [SegmentLinker new]; + Segment *segment = [Segment new]; + [segment setName: "cock"]; + Segment *segment2 = [Segment new]; + [segment2 setName: "and"]; + Segment *segment3 = [Segment new]; + [segment3 setName: "ball"]; + Segment *segment4 = [Segment new]; + [segment4 setName: "torture"]; + Renderer *renderer = [Renderer new]; + SegmentRenderer *sr = [SegmentRenderer alloc]; + Controller *control = [Controller new]; + + //testing some strings + printf("%s\n", [@"constant string" CString]); + printf("%s\n", [[@"reversed string" reverse] CString]); + printf("%s\n", [[YSString stringFromString: @"woop"] CString]); + printf("%s\n", [[YSString stringFromCString: "poop"] CString]); + printf("%s\n", [[YSConstantString stringFromCString: "hmmm"] CString]); + YSString *str = [YSString stringFromString: @"ball"]; + + [@"println" println]; + [[str cat: @"cat"] println]; + + [linker addObject: segment]; + [linker addObject: segment2]; + [linker addObject: segment3]; + [linker addObject: segment4]; + [linker link]; + + [sr initWithSegment: segment]; + [renderer addObject: sr]; + + control->timer = timer; + control->splits = segment; + + [input setKey: KEY_SPACE toPerform: @selector(startOrSplit) on: control]; + + InitWindow(400, 400, "ghost"); + SetTargetFPS(60); + + Color theColor = BLACK; + + while (!WindowShouldClose()) { + + [input handleInput]; + + /* + if (IsKeyPressed(KEY_SPACE)) { + if (timer->paused) { + [timer resume]; + theColor = BLACK; + } else { + theColor = RED; + [timer pause]; + } + } + */ + + [timer tick]; + + BeginDrawing(); + ClearBackground(WHITE); + DrawText([timer timeString], 400/2, (400/3) * 2, 100, theColor); + [renderer render]; + EndDrawing(); + } + + CloseWindow(); +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..287ce3a --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,38 @@ +#ifndef RENDERER_H +#define RENDERER_H + +#import +#import +#import "splits.h" +#import "timer.h" +#import "timeutils.h" + +//meant to be subclassed +@interface RenderComponent : YSArray { + Rectangle rect; + id obj; + double fontSize; + double spacing; +} ++(id) new; +-(id) init; + +@end + +@interface SegmentRenderer : RenderComponent { + +} + +-(id) initWithSegment: (id) segment; +-(void) render; +@end + +@interface Renderer : YSArray { + +} + ++(id) new; +-(void) render; +@end + +#endif \ No newline at end of file diff --git a/src/renderer.m b/src/renderer.m new file mode 100644 index 0000000..b6e29c4 --- /dev/null +++ b/src/renderer.m @@ -0,0 +1,62 @@ +#import "renderer.h" + +@implementation RenderComponent + ++(id) new { + return [[RenderComponent alloc] init]; +} + +-(id) init { + self = [super init]; + + if (self) { + rect = (Rectangle){ + .x = 0, + .y = 0, + .height = 20.0, + .width = GetScreenWidth(), + }; + + fontSize = 20; + spacing = 20; + } + + return self; +} +@end + +@class Segment; +@implementation SegmentRenderer + +-(id) initWithSegment: (id) segment { + obj = segment; +} + +-(void) render { + id current = obj; + + int idx = 0; + while( current != NULL) { + DrawText([current name], rect.x + 1, rect.y + (20 * idx), 20.0, BLACK); + DrawText([current realtimeString], 300, rect.y + (20 * idx), 20.0, BLACK); + current = [current next]; + idx++; + } +} + +@end + +@implementation Renderer + ++(id) new { + return [[Renderer alloc] init]; +} + +-(void) render { + int i; + for (i = 0; i < count; i++) { + [array[i] render]; + } +} + +@end \ No newline at end of file diff --git a/src/splits.h b/src/splits.h new file mode 100644 index 0000000..3f8c1cc --- /dev/null +++ b/src/splits.h @@ -0,0 +1,49 @@ +#ifndef SPLITS_H +#define SPLITS_H + +#import +#import +#import +#import +#import + +enum DisplayMode { + REALTIME = 0, + GAMETIME = 1, +}; + +@interface Segment : YSObject { + char *name; + struct timespec realtime; + struct timespec gametime; + Segment *next; +} + ++(id) new; +-(id) init; + +-(Segment *) next; +-(void) setNext: (Segment *) n; + +-(char *) name; +-(void) setName: (char *) n; + +-(struct timespec) realtime; +-(void) setRealtime: (struct timespec) r; + +-(struct timespec) gametime; +-(void) setGametime: (struct timespec) r; + +-(char *) realtimeString; +-(char *) gametimeString; + +@end + + +@interface SegmentLinker : YSArray { + +} ++(id) new; +-(void) link; +@end +#endif \ No newline at end of file diff --git a/src/splits.m b/src/splits.m new file mode 100644 index 0000000..aef648d --- /dev/null +++ b/src/splits.m @@ -0,0 +1,86 @@ +#import "splits.h" +#import "timeutils.h" + +@implementation Segment ++(id) new { + return [[[self class] alloc] init]; +} + +-(id) init { + self = [super init]; + + if (self) { + name = malloc(30); + memcpy(name, "cocks", 6); + } + + return self; +} + +-(Segment *) next { + return next; +} + +-(void) setNext: (Segment *) n { + next = n; +} + +-(void) dealloc { + free(name); + [super dealloc]; +} + +-(char *) name { + return name; +} + +-(void) setName: (char *) n { + name = n; +} + +-(struct timespec) realtime { + return realtime; +} + +-(void) setRealtime: (struct timespec) r { + realtime = r; +} + +-(struct timespec) gametime { + return gametime; +} + +-(void) setGametime: (struct timespec) r { + gametime = r; +} + +-(char *) realtimeString { + static char buffer[100]; + sprintf(buffer, "%.02lf", timespec_to_double(realtime)); + return buffer; +} + +-(char *) gametimeString { + static char buffer[100]; + sprintf(buffer, "%.02lf", timespec_to_double(gametime)); + return buffer; +} +@end + +@implementation SegmentLinker + ++(id) new { + return [[SegmentLinker alloc] init]; +} + +-(void) link { + Segment *current = array[0]; + + int i; + for (i = 1; i < count; i++) { + [current setNext: array[i]]; + current = array[i]; + } +} + +@end \ No newline at end of file diff --git a/src/timer.c b/src/timer.c new file mode 100644 index 0000000..caa0008 --- /dev/null +++ b/src/timer.c @@ -0,0 +1,67 @@ +#include "timer.c.h" + +GHTimer ghtimer_init(void) { + GHTimer timer = {0}; + timer.running = false; + timer.paused = false; + clock_gettime(CLOCK_REALTIME, &timer.pause_start); + clock_gettime(CLOCK_REALTIME, &timer.start); + timer.pause_current = timer.pause_start; + timer.current = timer.start; + return timer; +} + +void ghtimer_start(GHTimer *timer) { + clock_gettime(CLOCK_REALTIME, &timer->start); + timer->running = true; +} + +void ghtimer_pause(GHTimer *timer) { + clock_gettime(CLOCK_REALTIME, &timer->pause_start); + timer->paused = true; +} + +void ghtimer_resume(GHTimer *timer) { + struct timespec t = subts(timer->pause_current, timer->pause_start); + timer->diff = addts(timer->diff, t); + timer->paused = false; +} + +void ghtimer_stop(GHTimer *timer) { + timer->running = false; + timer->paused = false; + clock_gettime(CLOCK_REALTIME, &timer->pause_start); + clock_gettime(CLOCK_REALTIME, &timer->start); + timer->pause_current = timer->pause_start; + timer->current = timer->start; + timer->diff = (struct timespec) {0}; +} + +void ghtimer_reset(GHTimer *timer) { + timer->running = false; + timer->start = (struct timespec) {0}; + timer->current = timer->start; +} + +void ghtimer_tick(GHTimer *timer) { + if (!timer->running) { + return; + } + + if (!timer->paused) { + clock_gettime(CLOCK_REALTIME, &timer->current); + } else { + clock_gettime(CLOCK_REALTIME, &timer->pause_current); + } +} + +struct timespec ghtimer_time(GHTimer *timer) { + struct timespec time = subts(timer->current, timer->start); + return subts(time, timer->diff); +} + +void ghtimer_timestring(GHTimer *timer, char *buffer) { + struct timespec time = ghtimer_time(timer); + double dbl = timespec_to_double(time); + sprintf(buffer, "%.02lf", dbl); +} \ No newline at end of file diff --git a/src/timer.c.h b/src/timer.c.h new file mode 100644 index 0000000..baacc52 --- /dev/null +++ b/src/timer.c.h @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include "timeutils.h" + +//appended GH just incase theres a conflict with anything +//else named "Timer" + +typedef struct GHTimer { + struct timespec start; + struct timespec current; + struct timespec pause_start; + struct timespec pause_current; + struct timespec diff; + int running; + int paused; +} GHTimer; + +void ghtimer_start(GHTimer *timer); +void ghtimer_pause(GHTimer *timer); +void ghtimer_resume(GHTimer *timer); +void ghtimer_stop(GHTimer *timer); +void ghtimer_reset(GHTimer *timer); +void ghtimer_tick(GHTimer *timer); + +struct timespec ghtimer_time(GHTimer *timer); +void ghtimer_timestring(GHTimer *timer); \ No newline at end of file diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..0cc17d3 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,34 @@ +#ifndef TIMER_H +#define TIMER_H + +#include +#include +#include +#include +#include + + +@interface Timer : YSObject { +@public + struct timespec start; + struct timespec current; + struct timespec pause_start; + struct timespec pause_current; + struct timespec diff; + int running; + int paused; +} + +-(void) start; +-(void) pause; +-(void) resume; +-(void) stop; +-(void) tick; + +//returns current minus start; +-(struct timespec) time; +-(char *) timeString; + +@end + +#endif diff --git a/src/timer.m b/src/timer.m new file mode 100644 index 0000000..0fd2b6d --- /dev/null +++ b/src/timer.m @@ -0,0 +1,78 @@ +#import "timer.h" +#import "timeutils.h" + +@implementation Timer +-(id) init { + self = [super init]; + running = false; + paused = false; + clock_gettime(CLOCK_REALTIME, &pause_start); + pause_current = pause_start; + clock_gettime(CLOCK_REALTIME, &start); + current = start; + diff = (struct timespec){0}; + return self; +} + +-(void) start { + clock_gettime(CLOCK_REALTIME, &start); + running = true; +} + +-(void) pause { + clock_gettime(CLOCK_REALTIME, &pause_start); + paused = true; + +} + +-(void) resume { + struct timespec t = subts(pause_current, pause_start); + diff = addts(diff, t); + paused = false; +} + +-(void) stop { + running = false; + paused = false; + clock_gettime(CLOCK_REALTIME, &pause_start); + clock_gettime(CLOCK_REALTIME, &start); + pause_current = pause_start; + current = start; + diff = (struct timespec){0}; +} + +-(void) reset { + running = false; + start = (struct timespec){0}; + current = start; +} + +-(void) tick { + if (!running) + return; + + if (!paused) { + clock_gettime(CLOCK_REALTIME, ¤t); + } else { + clock_gettime(CLOCK_REALTIME, &pause_current); + } +} + +-(struct timespec) time { + struct timespec time = subts(current, start); + return subts(time, diff); +} + +-(char *) timeString { + //super simple format + static char buffer[100]; + struct timespec time = subts(current, start); + time = subts(time, diff); + + double dbl = timespec_to_double(time); + + sprintf(buffer, "%.02lf", dbl); + return buffer; +} + +@end diff --git a/src/timeutils.c b/src/timeutils.c new file mode 100644 index 0000000..1a83da3 --- /dev/null +++ b/src/timeutils.c @@ -0,0 +1,19 @@ +#include "timeutils.h" + +struct timespec subts(struct timespec t1, struct timespec t2) { + return (struct timespec) { + .tv_sec = t1.tv_sec - t2.tv_sec, + .tv_nsec = t1.tv_nsec - t2.tv_nsec, + }; +} + +struct timespec addts(struct timespec t1, struct timespec t2) { + return (struct timespec) { + .tv_sec = t1.tv_sec + t2.tv_sec, + .tv_nsec = t1.tv_nsec + t2.tv_nsec, + }; +} + +double timespec_to_double(struct timespec ts) { + return ((double)(ts.tv_sec) + ((double)(ts.tv_nsec) / NSEC_PER_SEC)); +} \ No newline at end of file diff --git a/src/timeutils.h b/src/timeutils.h new file mode 100644 index 0000000..ab321b8 --- /dev/null +++ b/src/timeutils.h @@ -0,0 +1,11 @@ +#ifndef TIMEUTILS_H +#define TIMEUTILS_H + +#include + +#define NSEC_PER_SEC 1000000000 + +struct timespec subts(struct timespec t1, struct timespec t2); +struct timespec addts(struct timespec t1, struct timespec t2); +double timespec_to_double(struct timespec ts); +#endif \ No newline at end of file