diff options
author | Ian McFarlane <i.mcfarlane2002@gmail.com> | 2025-05-02 03:30:34 -0400 |
---|---|---|
committer | Ian McFarlane <i.mcfarlane2002@gmail.com> | 2025-05-02 03:30:34 -0400 |
commit | d1585727866ed003f3f1ae964a7cbfdf7b80c334 (patch) | |
tree | 9ba5fe4903d8d7aacc5fd9f6524fdcd0ac48e672 | |
parent | added keypoll syscall and synchronization for forkman (diff) | |
download | comus-d1585727866ed003f3f1ae964a7cbfdf7b80c334.tar.gz comus-d1585727866ed003f3f1ae964a7cbfdf7b80c334.tar.bz2 comus-d1585727866ed003f3f1ae964a7cbfdf7b80c334.zip |
drawing some tiles and things
-rw-r--r-- | user/forkman.c | 171 |
1 files changed, 166 insertions, 5 deletions
diff --git a/user/forkman.c b/user/forkman.c index 69bff7e..32dbeb8 100644 --- a/user/forkman.c +++ b/user/forkman.c @@ -7,16 +7,28 @@ */ #include <stdlib.h> -#include <string.h> #include <unistd.h> #include <stdio.h> #include <unistd.h> #include "../kernel/include/comus/keycodes.h" +#define DBG + #define GAME_WIDTH 480 #define GAME_HEIGHT 360 #define SHARED_PAGES 10 #define PAGE_SIZE 4096 +#define TILE_WIDTH 16 +#define TILE_HEIGHT 16 +#define GAME_WIDTH_TILES (GAME_WIDTH / TILE_WIDTH) +#define GAME_HEIGHT_TILES (GAME_HEIGHT / TILE_HEIGHT) +#define PLAYER_WIDTH 10 +#define PLAYER_HEIGHT 10 + +typedef struct { + double x; + double y; +} vec; typedef struct { uint32_t *mapped_memory; @@ -27,6 +39,16 @@ typedef struct { size_t size; } framebuffer; +enum tile_type { + TILE_AIR, + TILE_SOLID, + TILE_GRATE, +}; + +typedef struct { + enum tile_type type; +} tile; + typedef struct { volatile size_t frame; volatile size_t dummy_counter; @@ -34,18 +56,23 @@ typedef struct { volatile uint8_t client_barrier; volatile uint8_t server_barrier; volatile uint8_t key_status[255]; + volatile vec player_pos; + volatile vec player_vel; + volatile tile tiles[GAME_HEIGHT_TILES * GAME_WIDTH_TILES]; volatile uint8_t mem[PAGE_SIZE * (SHARED_PAGES - 1)]; } sharedmem; static int display_server_entry(sharedmem *); static int client_entry(sharedmem *); static void barrier_wait(sharedmem *, int isclient); +static volatile tile *tile_at(sharedmem *, size_t x, size_t y); +static long abs(long); int main(void) { - uint8_t *current_break = sbrk(0); - if (!current_break) { - fprintf(stderr, "sbrk failure\n"); + // static_assert where are you :( + if (SHARED_PAGES * 4096 < sizeof(sharedmem)) { + fprintf(stderr, "bad memory configuration"); return 1; } @@ -76,7 +103,90 @@ int main(void) static void set_pixel(framebuffer *fb, size_t x, size_t y, int state) // state is 0 or 1 { - fb->mapped_memory[x + y * fb->width] = state * (0x00010101); + const size_t idx = x + y * fb->width; +#ifdef DBG + if (idx > fb->size) { + printf("overflow?\n"); + exit(0); + } +#endif + fb->mapped_memory[idx] = state * (uint32_t)-1; +} + +static void draw_filled(framebuffer *fb, const size_t x, const size_t y, + int state) +{ + for (size_t rx = x * TILE_WIDTH; rx < (x + 1) * TILE_WIDTH; ++rx) { + for (size_t ry = y * TILE_HEIGHT; ry < (y + 1) * TILE_HEIGHT; ++ry) { + set_pixel(fb, rx, ry, state); + } + } +} + +static void draw_grate(framebuffer *fb, const size_t x, const size_t y) +{ + for (size_t rx = x * TILE_WIDTH; rx < (x + 1) * TILE_WIDTH; ++rx) { + for (size_t ry = y * TILE_HEIGHT; ry < (y + 1) * TILE_HEIGHT; ++ry) { + int state; + if (x == y) { + state = 1; + } else { + state = 0; + } + set_pixel(fb, rx, ry, state); + } + } +} + +static void draw_tiles(sharedmem *shared, framebuffer *fb) +{ + for (size_t x = 0; x < GAME_WIDTH_TILES; ++x) { + for (size_t y = 0; y < GAME_HEIGHT_TILES; ++y) { + volatile tile *tile = tile_at(shared, x, y); + switch (tile->type) { + case TILE_AIR: + draw_filled(fb, x, y, 0); + break; + case TILE_SOLID: + draw_filled(fb, x, y, 1); + break; + case TILE_GRATE: + draw_grate(fb, x, y); + break; + } + } + } +} + +static void draw_player(framebuffer *fb, vec pos) +{ + for (size_t x = pos.x; x < ((size_t)pos.x + PLAYER_WIDTH); ++x) { + for (size_t y = pos.y; y < ((size_t)pos.y + PLAYER_WIDTH); ++y) { + set_pixel(fb, x, y, 1); + } + } +} + +static void init_level(sharedmem *shared) +{ + for (size_t i = 0; i < GAME_WIDTH_TILES; ++i) { + tile_at(shared, i, 10)->type = TILE_GRATE; + } + + shared->player_pos = (vec){ .x = 5 * TILE_WIDTH, .y = 5 * TILE_HEIGHT }; +} + +static long abs(long i) +{ + if (i < 0) + return i * -1; + return i; +} + +static size_t get_total_time(size_t tick_start) // arbitrary units +{ + // 60 is arbitrary pretend fps + return ((ticks() - tick_start) / (1000 / 60)); } static int display_server_entry(sharedmem *shared) @@ -108,6 +218,9 @@ static int display_server_entry(sharedmem *shared) } } + draw_tiles(shared, &fb); + draw_player(&fb, shared->player_pos); + last_frame += 1; shared->frame = last_frame; } @@ -117,12 +230,48 @@ static int display_server_entry(sharedmem *shared) static int client_entry(sharedmem *shared) { + init_level(shared); + size_t last_frame = shared->frame; + + size_t start_ticks = ticks(); + + double last_time = get_total_time(start_ticks); + barrier_wait(shared, 1); do { if (last_frame == shared->frame) continue; + double time = get_total_time(start_ticks); + double delta_time = time - last_time; + + shared->player_vel.y -= 9.8 * delta_time; + + // framerate dependent... + const vec drag = { + .x = shared->player_vel.x * 0.1, + .y = shared->player_vel.y * 0.1, + }; + shared->player_vel.x -= drag.x; + shared->player_vel.y -= drag.y; + + for (size_t i = 0; i < shared->player_vel.x; ++i) { + size_t x = shared->player_pos.x + 1; + size_t y = shared->player_pos.y + 1; + if (tile_at(shared, x, y)->type != TILE_AIR) { + break; + } + shared->player_pos.x += 1; + shared->player_pos.y += 1; + } + + if (shared->key_status[KEY_SPACE]) { + shared->player_vel.y = 10; + } else if (shared->key_status[KEY_B]) { + shared->player_vel.y = -10; + } + last_frame += 1; shared->frame = last_frame; } while (1); @@ -130,6 +279,18 @@ static int client_entry(sharedmem *shared) return 0; } +static volatile tile *tile_at(sharedmem *shared, size_t x, size_t y) +{ + const size_t idx = x + (y * GAME_WIDTH_TILES); +#ifdef DBG + if (idx > GAME_WIDTH_TILES * GAME_HEIGHT_TILES) { + printf("out of bounds"); + exit(0); + } +#endif + return shared->tiles + idx; +} + static void barrier_wait(sharedmem *shared, int isclient) { if (isclient) { |