diff --git a/field.c b/field.c index 84ba68f..6dd701a 100644 --- a/field.c +++ b/field.c @@ -1,5 +1,6 @@ #include "field.h" +#include "picture.h" #include #define SWAP(a, b) ({ \ @@ -8,54 +9,67 @@ (b) = tmp; \ }) -void Field_init(Field *f, SDL_Renderer *rend, int w, int h) { - f->tl = Picture_new(rend, 0, 0, w, h, 0xffffffff /*0xff7fffff*/); - f->tr = Picture_new(rend, w, 0, w, h, 0xffffffff /*0xffff7fff*/); - f->bl = Picture_new(rend, 0, h, w, h, 0xffffffff /*0xffffff7f*/); - f->br = Picture_new(rend, w, h, w, h, 0xffffffff /*0xff7fff7f*/); - f->offset = (struct int2){ 0, 0 }; +void Field_init(Field *f, int w, int h) { + f->tl = Picture_new(0, 0, w, h, 0xffffffff /*0xff7fffff*/); + f->tr = Picture_new(w, 0, w, h, 0xffffffff /*0xffff7fff*/); + f->bl = Picture_new(0, h, w, h, 0xffffffff /*0xffffff7f*/); + f->br = Picture_new(w, h, w, h, 0xffffffff /*0xff7fff7f*/); + f->offset = (struct int2) { 0, 0 }; + f->size = (struct int2) { w, h }; } -void Field_scroll(Field *f, SDL_Renderer *rend) { - int w = f->pics[0]->w; - int h = f->pics[0]->h; +void Field_scroll(Field *f) { + int w = f->size.x; + int h = f->size.y; if (f->offset.y < f->tl->y) { SWAP(f->tl, f->bl); SWAP(f->tr, f->br); Picture_move(f->tl, 0, -2*h); Picture_move(f->tr, 0, -2*h); - Picture_render(f->tl, rend); - Picture_render(f->tr, rend); } if (f->offset.x < f->tl->x) { SWAP(f->tl, f->tr); SWAP(f->bl, f->br); Picture_move(f->tl, -2*w, 0); Picture_move(f->bl, -2*w, 0); - Picture_render(f->tl, rend); - Picture_render(f->bl, rend); } if (f->offset.y >= f->br->y) { SWAP(f->tl, f->bl); SWAP(f->tr, f->br); Picture_move(f->bl, 0, 2*h); Picture_move(f->br, 0, 2*h); - Picture_render(f->bl, rend); - Picture_render(f->br, rend); } if (f->offset.x >= f->br->x) { SWAP(f->tl, f->tr); SWAP(f->bl, f->br); Picture_move(f->tr, 2*w, 0); Picture_move(f->br, 2*w, 0); - Picture_render(f->tr, rend); - Picture_render(f->br, rend); } } +void Field_resize(Field *f, int w, int h) { + + w = (w + 7) / 8 * 8; + h = (h + 7) / 8 * 8; + + Picture_delete(f->tl); + Picture_delete(f->tr); + Picture_delete(f->bl); + Picture_delete(f->br); + + f->tl = Picture_new(0, 0, w, h, 0xffffffff /*0xff7fffff*/); + f->tr = Picture_new(w, 0, w, h, 0xffffffff /*0xffff7fff*/); + f->bl = Picture_new(0, h, w, h, 0xffffffff /*0xffffff7f*/); + f->br = Picture_new(w, h, w, h, 0xffffffff /*0xff7fff7f*/); + + f->size = (struct int2) { w, h }; +} + void Field_draw(Field *f, SDL_Renderer *rend) { for (int i = 0; i < 4; i++) { Picture *p = f->pics[i]; + Picture_render(p, rend); + SDL_FRect dst = { p->x - f->offset.x, p->y - f->offset.y, p->w, p->h, }; diff --git a/field.h b/field.h index 6381b3f..849b505 100644 --- a/field.h +++ b/field.h @@ -14,10 +14,13 @@ typedef struct { Picture *pics[4]; }; struct int2 offset; + struct int2 size; } Field; -void Field_init(Field *f, SDL_Renderer *rend, int w, int h); +void Field_init(Field *f, int w, int h); -void Field_scroll(Field *f, SDL_Renderer *rend); +void Field_scroll(Field *f); + +void Field_resize(Field *f, int w, int h); void Field_draw(Field *f, SDL_Renderer *rend); diff --git a/picture.c b/picture.c index 463fcc6..8172e1d 100644 --- a/picture.c +++ b/picture.c @@ -2,9 +2,9 @@ #include #include "picture.h" +#include "SDL3/SDL_render.h" -Picture *Picture_new(SDL_Renderer *rend, - int x, int y, int w, int h, uint32_t color) { +Picture *Picture_new(int x, int y, int w, int h, uint32_t color) { Picture *p = calloc(1, sizeof(Picture)); @@ -14,6 +14,7 @@ Picture *Picture_new(SDL_Renderer *rend, p->h = h; p->color = color; p->s = (w * sizeof(uint32_t) + 7) / 8 * 8; + p->dirty = 1; p->pixels = malloc(p->s * h); p->surface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, p->pixels, p->s); @@ -21,13 +22,21 @@ Picture *Picture_new(SDL_Renderer *rend, fprintf(stderr, "Can't create surface: %s\n", SDL_GetError()); exit(-1); } - Picture_render(p, rend); return p; } +void Picture_delete(Picture *p) { + if (p->texture != NULL) SDL_DestroyTexture(p->texture); + SDL_DestroySurface(p->surface); + free(p->pixels); + free(p); +} + typedef uint32_t uint32_8 __attribute__ ((vector_size (8 * sizeof(uint32_t)))); void Picture_render(Picture *p, SDL_Renderer *rend) { + if (!p->dirty) return; + int w = p->w, h = p->h; uint32_8 c = { p->color, p->color, p->color, p->color, @@ -51,10 +60,12 @@ void Picture_render(Picture *p, SDL_Renderer *rend) { exit(-1); } SDL_SetTextureBlendMode(p->texture, SDL_BLENDMODE_NONE); + p->dirty = 0; } void Picture_move(Picture *p, int x, int y) { p->x += x; p->y += y; + p->dirty = 1; } diff --git a/picture.h b/picture.h index f434625..7961ffd 100644 --- a/picture.h +++ b/picture.h @@ -13,11 +13,12 @@ typedef struct { SDL_Texture *texture; uint32_t *pixels; uint32_t color; + int dirty; } Picture; void Picture_render(Picture *p, SDL_Renderer *rend); -Picture *Picture_new(SDL_Renderer *rend, - int x, int y, int w, int h, uint32_t color); +Picture *Picture_new(int x, int y, int w, int h, uint32_t color); +void Picture_delete(Picture *p); void Picture_render(Picture *p, SDL_Renderer *rend); void Picture_move(Picture *p, int x, int y); diff --git a/xormod.c b/xormod.c index 51bf802..f18d1b2 100644 --- a/xormod.c +++ b/xormod.c @@ -18,7 +18,7 @@ int main() { return -1; } - SDL_Window *window = SDL_CreateWindow("xormod", w, h, ACCEL_PLATFORM); + SDL_Window *window = SDL_CreateWindow("xormod", w, h, ACCEL_PLATFORM | SDL_WINDOW_RESIZABLE); if (window == NULL) { fprintf(stderr, "Can't open window: %s\n", SDL_GetError()); return -1; @@ -29,7 +29,7 @@ int main() { SDL_Renderer *rend = SDL_CreateRenderer(window, NULL); Field f; - Field_init(&f, rend, w, h); + Field_init(&f, w, h); struct float2 mouse_prev = { -1, -1 }; Uint64 last = SDL_GetTicks(); @@ -68,11 +68,14 @@ int main() { mouse_prev = (struct float2) { -1, -1 }; } - Field_scroll(&f, rend); + SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); + SDL_RenderFillRect(rend, &(SDL_FRect) { 0, 0, w, h}); + + Field_scroll(&f); Field_draw(&f, rend); if (debug) { - char buf[52]; + char buf[72]; SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); SDL_RenderFillRect(rend, &(SDL_FRect) { 0, 0, sizeof(buf)*font_w, 8*font_h @@ -81,13 +84,14 @@ int main() { draw_text(rend, ACCEL_PLATFORM_STR, sizeof(ACCEL_PLATFORM_STR), RC(1,1), 255, 255, 255); size_t len = snprintf(buf, sizeof(buf), - "off.x: %d, off.y: %d, \xEBT: %" PRIu64, f.offset.x, f.offset.y, delta); + "off.x: %d, off.y: %d, \xEBT: %02" PRIu64, f.offset.x, f.offset.y, delta); draw_text(rend, buf, len, RC(2, 1), 255, 255, 255); char *q[] = {"TL", "TR", "BL", "BR"}; for (int i = 0; i < 4; i++) { Picture *p = f.pics[i]; - len = snprintf(buf, sizeof(buf), "%s \xB3 x: %05d, y: %05d, p: %p", q[i], p->x, p->y, p); + len = snprintf(buf, sizeof(buf), "%s \xB3 x: %05d, y: %05d, w: %d, h: %d, p: %p", + q[i], p->x, p->y, p->w, p->h, p); draw_text(rend, buf, len, RC(3+i, 1), 255, 255, 255); } } @@ -99,7 +103,11 @@ int main() { switch (event.type) { case SDL_EVENT_QUIT: running = 0; break; case SDL_EVENT_WINDOW_RESIZED: { - } break; + w = event.window.data1; + h = event.window.data2; + Field_resize(&f, w, h); + break; + } case SDL_EVENT_KEY_DOWN: { if (event.key.repeat) break; switch (event.key.key) { @@ -107,7 +115,7 @@ int main() { case SDLK_Q: running = 0; break; case SDLK_G: debug ^= 1; break; } - } break; + } } }