From e376bbe4e02c4773399fb6d35ae2866c461304f7 Mon Sep 17 00:00:00 2001 From: Henri Vasserman Date: Mon, 12 Apr 2021 22:15:41 +0300 Subject: [PATCH] refactor objects --- CMakeLists.txt | 6 +- field.c | 65 ++++++++++++++++++++++ field.h | 23 ++++++++ picture.c | 51 +++++++++++++++++ picture.h | 25 +++++++++ types.h | 3 + xormod.c | 145 ++----------------------------------------------- 7 files changed, 175 insertions(+), 143 deletions(-) create mode 100644 field.c create mode 100644 field.h create mode 100644 picture.c create mode 100644 picture.h create mode 100644 types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fa000a7..0b9bf90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,9 +17,11 @@ configure_file("platform.h.in" "config/platform.h") include_directories("${CMAKE_BINARY_DIR}/config") add_executable(xormod - "xormod.c" - "font.c" "EGA8x8.c" + "field.c" + "font.c" + "picture.c" + "xormod.c" ) target_link_libraries(xormod SDL2::SDL2) diff --git a/field.c b/field.c new file mode 100644 index 0000000..76fa14c --- /dev/null +++ b/field.c @@ -0,0 +1,65 @@ + +#include "field.h" +#include + +#define SWAP(a, b) ({ \ + __typeof(a) tmp = (a); \ + (a) = (b); \ + (b) = tmp; \ +}) + +void Field_init(Field *f, SDL_Renderer *rend, int w, int h) { + f->tl = Picture_new(rend, 0, 0, w, h, 0xff7fffff); + f->tr = Picture_new(rend, w, 0, w, h, 0xffff7fff); + f->bl = Picture_new(rend, 0, h, w, h, 0xffffff7f); + f->br = Picture_new(rend, w, h, w, h, 0xff7fff7f); + f->offset = (struct int2){ 0, 0 }; +} + +void Field_scroll(Field *f, SDL_Renderer *rend) { + int w = f->pics[0]->w; + int h = f->pics[0]->h; + if (f->offset.y < f->tl->y1) { + 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->x1) { + 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->y1) { + 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->x1) { + 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_draw(Field *f, SDL_Renderer *rend) { + for (int i = 0; i < 4; i++) { + Picture *p = f->pics[i]; + SDL_Rect dst = { + p->x1 - f->offset.x, p->y1 - f->offset.y, p->w, p->h, + }; + SDL_RenderCopy(rend, p->texture, NULL, &dst); + } +} + diff --git a/field.h b/field.h new file mode 100644 index 0000000..6381b3f --- /dev/null +++ b/field.h @@ -0,0 +1,23 @@ +#pragma once + +#include "types.h" +#include "picture.h" + +typedef struct { + union { + struct { + Picture *tl; + Picture *tr; + Picture *bl; + Picture *br; + }; + Picture *pics[4]; + }; + struct int2 offset; +} Field; + +void Field_init(Field *f, SDL_Renderer *rend, int w, int h); + +void Field_scroll(Field *f, SDL_Renderer *rend); + +void Field_draw(Field *f, SDL_Renderer *rend); diff --git a/picture.c b/picture.c new file mode 100644 index 0000000..b4c6587 --- /dev/null +++ b/picture.c @@ -0,0 +1,51 @@ +#include "picture.h" + +Picture *Picture_new(SDL_Renderer *rend, + int x, int y, int w, int h, uint32_t color) { + + Picture *p = calloc(1, sizeof(Picture)); + + p->x1 = x; + p->x2 = x + w; + p->y1 = y; + p->y2 = y + h; + p->w = w; + p->h = h; + p->color = color; + p->s = (w + 7) / 8 * 8; + + p->pixels = malloc(p->s * h * sizeof(uint32_t)); + p->surface = SDL_CreateRGBSurfaceWithFormatFrom( + p->pixels, w, h, 32, p->s * sizeof(uint32_t), + SDL_PIXELFORMAT_RGBA32); + + Picture_render(p, rend); + return p; +} + +typedef uint32_t uint32_8 __attribute__ ((vector_size (8 * sizeof(uint32_t)))); + +void Picture_render(Picture *p, SDL_Renderer *rend) { + int w = p->w, h = p->h; + uint32_8 c = p->color - (uint32_8){}; + uint32_8 y = p->y1 - (uint32_8){}; + for (int j = 0, r = 0; j < h; j++, y += 1) { + uint32_8 x = p->x1 + (uint32_8){0, 1, 2, 3, 4, 5, 6, 7}; + for (int i = 0; i < w; i += 8,r += 8, x += 8) { + uint32_8 z = (x ^ y) % 9; + uint32_8 f = (z==0) & c; + memcpy(&p->pixels[r], (uint32_t*)&f, sizeof(f)); + } + } + if (p->texture) SDL_DestroyTexture(p->texture); + p->texture = SDL_CreateTextureFromSurface(rend, p->surface); + SDL_SetTextureBlendMode(p->texture, SDL_BLENDMODE_NONE); +} + +void Picture_move(Picture *p, int x, int y) { + p->x1 += x; + p->x2 += x; + p->y1 += y; + p->y2 += y; +} + diff --git a/picture.h b/picture.h new file mode 100644 index 0000000..f36e257 --- /dev/null +++ b/picture.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +typedef struct { + int x1; + int y1; + int x2; + int y2; + int w; + int h; + int s; + SDL_Surface *surface; + SDL_Texture *texture; + uint32_t *pixels; + uint32_t color; +} 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); + +void Picture_render(Picture *p, SDL_Renderer *rend); +void Picture_move(Picture *p, int x, int y); diff --git a/types.h b/types.h new file mode 100644 index 0000000..9bae821 --- /dev/null +++ b/types.h @@ -0,0 +1,3 @@ +#pragma once + +struct int2 { int x; int y; }; diff --git a/xormod.c b/xormod.c index e1fdce5..6789ace 100644 --- a/xormod.c +++ b/xormod.c @@ -1,150 +1,13 @@ -#include "font.h" #include "EGA8x8.h" +#include "field.h" +#include "font.h" +#include "picture.h" #include "platform.h" +#include "types.h" #include #include -#define SWAP(a, b) ({ \ - __typeof(a) tmp = (a); \ - (a) = (b); \ - (b) = tmp; \ -}) - -typedef struct { - int x1; - int y1; - int x2; - int y2; - int w; - int h; - int s; - SDL_Surface *surface; - SDL_Texture *texture; - uint32_t *pixels; - uint32_t color; -} Picture; - -static void Picture_render(Picture *p, SDL_Renderer *rend); -static Picture *Picture_new(SDL_Renderer *rend, - int x, int y, int w, int h, uint32_t color) { - - Picture *p = calloc(1, sizeof(Picture)); - - p->x1 = x; - p->x2 = x + w; - p->y1 = y; - p->y2 = y + h; - p->w = w; - p->h = h; - p->color = color; - p->s = (w + 7) / 8 * 8; - - p->pixels = malloc(p->s * h * sizeof(uint32_t)); - p->surface = SDL_CreateRGBSurfaceWithFormatFrom( - p->pixels, w, h, 32, p->s * sizeof(uint32_t), - SDL_PIXELFORMAT_RGBA32); - - Picture_render(p, rend); - return p; -} - -typedef uint32_t uint32_8 __attribute__ ((vector_size (8 * sizeof(uint32_t)))); - -static void Picture_render(Picture *p, SDL_Renderer *rend) { - int w = p->w, h = p->h; - uint32_8 c = p->color - (uint32_8){}; - uint32_8 y = p->y1 - (uint32_8){}; - for (int j = 0, r = 0; j < h; j++, y += 1) { - uint32_8 x = p->x1 + (uint32_8){0, 1, 2, 3, 4, 5, 6, 7}; - for (int i = 0; i < w; i += 8,r += 8, x += 8) { - uint32_8 z = (x ^ y) % 9; - uint32_8 f = (z==0) & c; - memcpy(&p->pixels[r], (uint32_t*)&f, sizeof(f)); - } - } - if (p->texture) SDL_DestroyTexture(p->texture); - p->texture = SDL_CreateTextureFromSurface(rend, p->surface); - SDL_SetTextureBlendMode(p->texture, SDL_BLENDMODE_NONE); -} - -static void Picture_move(Picture *p, int x, int y) { - p->x1 += x; - p->x2 += x; - p->y1 += y; - p->y2 += y; -} - -struct int2 { int x; int y; }; - -typedef struct { - union { - struct { - Picture *tl; - Picture *tr; - Picture *bl; - Picture *br; - }; - Picture *pics[4]; - }; - struct int2 offset; -} Field; - -void Field_init(Field *f, SDL_Renderer *rend, int w, int h) { - f->tl = Picture_new(rend, 0, 0, w, h, 0xff7fffff); - f->tr = Picture_new(rend, w, 0, w, h, 0xffff7fff); - f->bl = Picture_new(rend, 0, h, w, h, 0xffffff7f); - f->br = Picture_new(rend, w, h, w, h, 0xff7fff7f); - f->offset = (struct int2){ 0, 0 }; -} - -void Field_scroll(Field *f, SDL_Renderer *rend) { - int w = f->pics[0]->w; - int h = f->pics[0]->h; - if (f->offset.y < f->tl->y1) { - 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->x1) { - 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->y1) { - 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->x1) { - 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_draw(Field *f, SDL_Renderer *rend) { - for (int i = 0; i < 4; i++) { - Picture *p = f->pics[i]; - SDL_Rect dst = { - p->x1 - f->offset.x, p->y1 - f->offset.y, p->w, p->h, - }; - SDL_RenderCopy(rend, p->texture, NULL, &dst); - } -} - int main() { int w = 1280, h = 720;