#include "cat_api.h" #include void bye(void) { printf("bye!\n"); exit(0); } struct keydowns { char k; struct keydowns* next; }; struct keydowns* first_keydown = NULL; void add_keydown(char k) { struct keydowns* new = malloc(sizeof(struct keydowns)); new->k = k; new->next = NULL; if (first_keydown == NULL) first_keydown = new; else { struct keydowns* head; for (head = first_keydown; head->next != NULL; head = head->next) if (head->k == k) return; head->next = new; } } void lit_remove_keydown(struct keydowns* entry) { if (first_keydown == entry) first_keydown = entry->next; else { struct keydowns* head; for (head = first_keydown; head->next != entry; head = head->next) ; head->next = entry->next; } } void remove_keydown(char k) { struct keydowns* head; for (head = first_keydown; head != NULL; head = head->next) if (head->k == k) lit_remove_keydown(head); } int is_held(char k) { struct keydowns* head; for (head = first_keydown; head != NULL; head = head->next) if (head->k == k) return 1; return 0; } struct entity { int is_player; int is_static; int x; int y; int width; int height; unsigned char r; /* replace this with sprite TODO */ unsigned char g; unsigned char b; float vx; float vy; float ax; float ay; struct entity* next; }; struct entity* first_entity = NULL; void add_entity(int is_player, int is_static, int x, int y, int width, int height, unsigned char r, unsigned char g, unsigned char b, float vx, float vy, float ax, float ay) { struct entity* new = malloc(sizeof(struct entity)); new->is_player = is_player; new->is_static = is_static; new->x = x; new->y = y; new->width = width; new->height = height; new->r = r; new->g = g; new->b = b; new->vx = vx; new->vy = vy; new->ax = ax; new->ay = ay; new->next = NULL; if (first_entity == NULL) first_entity = new; else { struct entity* head; for (head = first_entity; head->next != NULL; head = head->next) ; head->next = new; } } struct entity* get_player(void) { struct entity* head; for (head = first_entity; head != NULL; head = head->next) if (head->is_player) return head; return NULL; } void key_down(char k) { add_keydown(k); printf("%c pressed!\n", k); switch (k) { case 'a': get_player()->ax = -2; break; case 'd': get_player()->ax = 2; break; } } void key_up(char k) { remove_keydown(k); printf("%c un-pressed\n", k); switch (k) { case 'a': get_player()->ax = 0; break; case 'd': get_player()->ax = 0; break; } } static int mousex = 0; static int mousey = 0; void mouse_move(int x, int y) { /* clear old mouse icn */ mousex = x; mousey = y; printf("mouse moved! (%d, %d)\n", x, y); } void mouse_down(unsigned char button) { printf("mouse button %02x clicked!\n", button); /* TODO struct for this too?? that seems like a lot. what if we *don't* use mouse for anything... */ } void mouse_up(unsigned char button) { printf("mouse button %02x un-clicked!\n", button); } void process_input(void) { struct cat_event* e = cat_get_event(); if (e == NULL) return; if (e->type == QUIT) bye(); else if (e->type == KEYDOWN) key_down(e->key); else if (e->type == KEYUP) key_up(e->key); else if (e->type == MOUSEMOVE) mouse_move(e->mousex, e->mousey); else if (e->type == MOUSEDOWN) mouse_down(e->mouse_button); else if (e->type == MOUSEUP) mouse_up(e->mouse_button); } void erase_entity(struct entity* e) { /* get sprite info, etc */ /* FIXME */ if (e->x < 0 || e->y < 0 || e->x >= screen_width || e->y >= screen_height) return; cat_fill(1, 0, e->x, e->y, e->width, e->height, 0, 0, 0); } void draw_entity(struct entity* e) { /* get sprite info, etc */ /* FIXME */ if (e->x < 0 || e->y < 0 || e->x >= screen_width || e->y >= screen_height) return; cat_fill(1, 1, e->x, e->y, e->width, e->height, e->r, e->g, e->b); /* if out of bounds do not draw */ } void erase_entities(void) { /* TODO more than just player entity */ erase_entity(get_player()); } void draw_entities(void) { /* TODO more than just player entity */ draw_entity(get_player()); } static long last_sec = 0; static long last_nsec = 0; #define NS_PER_TICK 30000000 void apply_friction(void) /* FIXME */ { struct entity* p = get_player(); if (p->vx > 0) p->vx -= 1; else if (p->vx < 0) p->vx += 1; if (p->vy > 0) p->vy -= 1; else if (p->vy < 0) p->vy += 1; } void tick(void) { /* run every N milliseconds... nanoseconds? idk */ struct timespec t; clock_gettime(CLOCK_REALTIME, &t); if (last_sec == 0) goto yes; else if ((t.tv_sec - last_sec) > 0) goto yes; else if ((t.tv_nsec - last_nsec) > NS_PER_TICK) goto yes; else return; /* do a tick */ yes: last_sec = t.tv_sec; last_nsec = t.tv_nsec; /* code to run every tick goes here */ erase_entities(); struct entity* p = get_player(); if (is_held(' ')) p->ay = -5; else p->ay = 9.81; p->vx += p->ax; p->vy += p->ay; apply_friction(); /* FIXME */ p->x += (int)p->vx; p->y += (int)p->vy; draw_entities(); } void game_loop(void) { cat_render(); process_input(); tick(); } int main(int argc, char** argv) { cat_init(); cat_create_window(1920, 1080); //cat_play_wav("etc/example.wav"); //cat_play_wav("etc/cat_quick.wav"); cat_play_wav("etc/cat_beep_box.wav"); /* layer, visibility, x, y, width, height, r, g, b */ cat_fill(0, 1, 0, 0, screen_width - 1, screen_height - 1, 132, 155, 132); /* create the player */ add_entity(1, 0, 0, 0, 50, 50, 100, 50, 0, 0, 0, 0, 0); while (1) game_loop(); return 0; }