summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-07-19 09:57:54 -0700
committer3gg <3gg@shellblade.net>2025-07-19 09:57:54 -0700
commitf14c43d6c08253a98a781e65067288a578d1115c (patch)
tree482ad61f0a88eda6a9c7c9a04f46eeef6a1798c7
parenteaf394f1de8f6bbaf761e96212ccf0eabc0f36ce (diff)
Add Screen struct
-rw-r--r--src/isogfx.c78
1 files changed, 41 insertions, 37 deletions
diff --git a/src/isogfx.c b/src/isogfx.c
index b715ca8..e182dff 100644
--- a/src/isogfx.c
+++ b/src/isogfx.c
@@ -32,7 +32,11 @@ typedef struct vec2 {
32// Renderer state. 32// Renderer state.
33// ----------------------------------------------------------------------------- 33// -----------------------------------------------------------------------------
34 34
35// TODO: Define a struct Screen with width, height and pixels. 35typedef struct Screen {
36 int width;
37 int height;
38 Pixel* pixels;
39} Screen;
36 40
37typedef struct SpriteInstance { 41typedef struct SpriteInstance {
38 struct SpriteInstance* next; 42 struct SpriteInstance* next;
@@ -43,11 +47,9 @@ typedef struct SpriteInstance {
43} SpriteInstance; 47} SpriteInstance;
44 48
45typedef struct IsoGfx { 49typedef struct IsoGfx {
46 int screen_width; 50 Screen screen;
47 int screen_height;
48 double last_animation_time; 51 double last_animation_time;
49 Tile next_tile; // For procedurally-generated tiles. 52 Tile next_tile; // For procedurally-generated tiles.
50 Pixel* screen;
51 Tm_Map* map; 53 Tm_Map* map;
52 Ts_TileSet* tileset; 54 Ts_TileSet* tileset;
53 SpriteInstance* head_sprite; // Head of sprites list. 55 SpriteInstance* head_sprite; // Head of sprites list.
@@ -90,21 +92,21 @@ static inline vec2 cart2iso(vec2 cart, int s, int t, int w) {
90} 92}
91 93
92static inline const Pixel* screen_xy_const_ref( 94static inline const Pixel* screen_xy_const_ref(
93 const IsoGfx* iso, int x, int y) { 95 const Screen* screen, int x, int y) {
94 assert(iso); 96 assert(screen);
95 assert(x >= 0); 97 assert(x >= 0);
96 assert(y >= 0); 98 assert(y >= 0);
97 assert(x < iso->screen_width); 99 assert(x < screen->width);
98 assert(y < iso->screen_height); 100 assert(y < screen->height);
99 return &iso->screen[y * iso->screen_width + x]; 101 return &screen->pixels[y * screen->width + x];
100} 102}
101 103
102static inline Pixel screen_xy(IsoGfx* iso, int x, int y) { 104static inline Pixel screen_xy(Screen* screen, int x, int y) {
103 return *screen_xy_const_ref(iso, x, y); 105 return *screen_xy_const_ref(screen, x, y);
104} 106}
105 107
106static inline Pixel* screen_xy_mut(IsoGfx* iso, int x, int y) { 108static inline Pixel* screen_xy_mut(Screen* screen, int x, int y) {
107 return (Pixel*)screen_xy_const_ref(iso, x, y); 109 return (Pixel*)screen_xy_const_ref(screen, x, y);
108} 110}
109 111
110// ----------------------------------------------------------------------------- 112// -----------------------------------------------------------------------------
@@ -126,16 +128,17 @@ IsoGfx* isogfx_new(const IsoGfxDesc* desc) {
126 memstack_alloc_aligned(&tmp.stack, sizeof(IsoGfx), alignof(IsoGfx)); 128 memstack_alloc_aligned(&tmp.stack, sizeof(IsoGfx), alignof(IsoGfx));
127 *iso = tmp; 129 *iso = tmp;
128 130
129 iso->screen_width = desc->screen_width;
130 iso->screen_height = desc->screen_height;
131 iso->last_animation_time = 0.0;
132
133 const size_t screen_size_bytes = 131 const size_t screen_size_bytes =
134 desc->screen_width * desc->screen_height * sizeof(Pixel); 132 desc->screen_width * desc->screen_height * sizeof(Pixel);
135 iso->screen = 133 Pixel* screen =
136 memstack_alloc_aligned(&iso->stack, screen_size_bytes, alignof(Pixel)); 134 memstack_alloc_aligned(&iso->stack, screen_size_bytes, alignof(Pixel));
137 135
138 iso->watermark = memstack_watermark(&iso->stack); 136 iso->screen = (Screen){.width = desc->screen_width,
137 .height = desc->screen_height,
138 .pixels = screen};
139
140 iso->last_animation_time = 0.0;
141 iso->watermark = memstack_watermark(&iso->stack);
139 142
140 return iso; 143 return iso;
141 144
@@ -469,7 +472,7 @@ typedef struct CoordSystem {
469/// expressed in the Cartesian system. 472/// expressed in the Cartesian system.
470static CoordSystem make_iso_coord_system(const IsoGfx* iso) { 473static CoordSystem make_iso_coord_system(const IsoGfx* iso) {
471 assert(iso); 474 assert(iso);
472 const ivec2 o = {iso->screen_width / 2, 0}; 475 const ivec2 o = {iso->screen.width / 2, 0};
473 const ivec2 x = { 476 const ivec2 x = {
474 .x = iso->map->base_tile_width / 2, .y = iso->map->base_tile_height / 2}; 477 .x = iso->map->base_tile_width / 2, .y = iso->map->base_tile_height / 2};
475 const ivec2 y = { 478 const ivec2 y = {
@@ -517,9 +520,9 @@ static Pixel alpha_blend(Pixel src, Pixel dst) {
517/// 'pixels' is the palette and 'indices' the pixel indices. Otherwise, the 520/// 'pixels' is the palette and 'indices' the pixel indices. Otherwise, the
518/// image is assumed to be in plain RGBA format. 521/// image is assumed to be in plain RGBA format.
519static void draw_rect( 522static void draw_rect(
520 IsoGfx* iso, ivec2 top_left, int rect_width, int rect_height, 523 Screen* screen, ivec2 top_left, int rect_width, int rect_height,
521 const Pixel* pixels, const uint8_t* indices) { 524 const Pixel* pixels, const uint8_t* indices) {
522 assert(iso); 525 assert(screen);
523 526
524#define rect_pixel(X, Y) \ 527#define rect_pixel(X, Y) \
525 (indices ? pixels[indices[Y * rect_width + X]] : pixels[Y * rect_width + X]) 528 (indices ? pixels[indices[Y * rect_width + X]] : pixels[Y * rect_width + X])
@@ -532,16 +535,16 @@ static void draw_rect(
532 535
533 // Rect can exceed screen bounds, so clip along Y and X as we draw. 536 // Rect can exceed screen bounds, so clip along Y and X as we draw.
534 for (int py = py_offset; 537 for (int py = py_offset;
535 (py < rect_height) && (top_left.y + py < iso->screen_height); ++py) { 538 (py < rect_height) && (top_left.y + py < screen->height); ++py) {
536 const int sy = top_left.y + py; 539 const int sy = top_left.y + py;
537 for (int px = px_offset; 540 for (int px = px_offset;
538 (px < rect_width) && (top_left.x + px < iso->screen_width); ++px) { 541 (px < rect_width) && (top_left.x + px < screen->width); ++px) {
539 const Pixel colour = rect_pixel(px, py); 542 const Pixel colour = rect_pixel(px, py);
540 if (colour.a > 0) { 543 if (colour.a > 0) {
541 const int sx = top_left.x + px; 544 const int sx = top_left.x + px;
542 const Pixel dst = screen_xy(iso, sx, sy); 545 const Pixel dst = screen_xy(screen, sx, sy);
543 const Pixel final = alpha_blend(colour, dst); 546 const Pixel final = alpha_blend(colour, dst);
544 *screen_xy_mut(iso, sx, sy) = final; 547 *screen_xy_mut(screen, sx, sy) = final;
545 } 548 }
546 } 549 }
547 } 550 }
@@ -567,16 +570,17 @@ static void draw_tile(IsoGfx* iso, ivec2 screen_origin, Tile tile) {
567 pTile->height - iso->map->base_tile_height}; 570 pTile->height - iso->map->base_tile_height};
568 const ivec2 top_left = ivec2_add(screen_origin, offset); 571 const ivec2 top_left = ivec2_add(screen_origin, offset);
569 572
570 draw_rect(iso, top_left, pTile->width, pTile->height, pixels, 0); 573 draw_rect(
574 &iso->screen, top_left, pTile->width, pTile->height, pixels, nullptr);
571} 575}
572 576
573static void draw_world(IsoGfx* iso) { 577static void draw_world(IsoGfx* iso) {
574 assert(iso); 578 assert(iso);
575 579
576 const int W = iso->screen_width; 580 const int W = iso->screen.width;
577 const int H = iso->screen_height; 581 const int H = iso->screen.height;
578 582
579 memset(iso->screen, 0, W * H * sizeof(Pixel)); 583 memset(iso->screen.pixels, 0, W * H * sizeof(Pixel));
580 584
581 const CoordSystem iso_space = make_iso_coord_system(iso); 585 const CoordSystem iso_space = make_iso_coord_system(iso);
582 586
@@ -609,7 +613,7 @@ static void draw_sprite(
609 const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); 613 const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation);
610 const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); 614 const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame);
611 draw_rect( 615 draw_rect(
612 iso, origin, sheet->sprite_width, sheet->sprite_height, 616 &iso->screen, origin, sheet->sprite_width, sheet->sprite_height,
613 sheet->palette.colours, frame); 617 sheet->palette.colours, frame);
614} 618}
615 619
@@ -651,13 +655,13 @@ void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) {
651 assert(iso); 655 assert(iso);
652 assert(width); 656 assert(width);
653 assert(height); 657 assert(height);
654 *width = iso->screen_width; 658 *width = iso->screen.width;
655 *height = iso->screen_height; 659 *height = iso->screen.height;
656} 660}
657 661
658const Pixel* isogfx_get_screen_buffer(const IsoGfx* iso) { 662const Pixel* isogfx_get_screen_buffer(const IsoGfx* iso) {
659 assert(iso); 663 assert(iso);
660 return iso->screen; 664 return iso->screen.pixels;
661} 665}
662 666
663void isogfx_pick_tile( 667void isogfx_pick_tile(
@@ -668,7 +672,7 @@ void isogfx_pick_tile(
668 672
669 const vec2 xy_iso = cart2iso( 673 const vec2 xy_iso = cart2iso(
670 (vec2){.x = xcart, .y = ycart}, iso->map->base_tile_width, 674 (vec2){.x = xcart, .y = ycart}, iso->map->base_tile_width,
671 iso->map->base_tile_height, iso->screen_width); 675 iso->map->base_tile_height, iso->screen.width);
672 676
673 if ((0 <= xy_iso.x) && (xy_iso.x < iso->map->world_width) && 677 if ((0 <= xy_iso.x) && (xy_iso.x < iso->map->world_width) &&
674 (0 <= xy_iso.y) && (xy_iso.y < iso->map->world_height)) { 678 (0 <= xy_iso.y) && (xy_iso.y < iso->map->world_height)) {