#include "font.h" #include "EGA8x8.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; 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->pixels = malloc(w * h * sizeof(uint32_t)); p->color = color; p->surface = SDL_CreateRGBSurfaceWithFormatFrom( p->pixels, w, h, 32, w * 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) { uint32_8 c = p->color - (uint32_8){}; uint32_8 y = 0 - (uint32_8){}; for (int j = p->y1, r = 0; j < p->y2; j++, y+=1) { uint32_8 x = {0, 1, 2, 3, 4, 5, 6, 7}; for (int i = p->x1; i < p->x2; 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; }; int main() { int w = 1280, h = 720; if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "Can't init: %s\n", SDL_GetError()); return -1; } SDL_Window *window = SDL_CreateWindow("xormod", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL /*SDL_WINDOW_FULLSCREEN */); if (window == NULL) { fprintf(stderr, "Can't open window: %s\n", SDL_GetError()); return -1; } SDL_GetWindowSize(window, &w, &h); SDL_Renderer *rend = SDL_CreateRenderer(window, -1, /*SDL_RENDERER_PRESENTVSYNC | */SDL_RENDERER_ACCELERATED); SDL_Texture *font = load_font(rend); Picture *pictures[4]; enum { P_TOPLEFT, P_TOPRGHT, P_BOTLEFT, P_BOTRGHT }; pictures[P_TOPLEFT] = Picture_new(rend, 0, 0, w, h, 0xff7fffff); pictures[P_TOPRGHT] = Picture_new(rend, w, 0, w, h, 0xffff7fff); pictures[P_BOTLEFT] = Picture_new(rend, 0, h, w, h, 0xffffff7f); pictures[P_BOTRGHT] = Picture_new(rend, w, h, w, h, 0xff7fff7f); struct int2 off = { 0, 0 }; struct int2 mouse_prev = { -1, -1 }; int running = 1; while (running) { const uint8_t *keys = SDL_GetKeyboardState(NULL); if (keys[SDL_SCANCODE_ESCAPE] || keys[SDL_SCANCODE_Q]) { break; } if (keys[SDL_SCANCODE_LEFT]) { off.x -= 5; } if (keys[SDL_SCANCODE_RIGHT]) { off.x += 5; } if (keys[SDL_SCANCODE_UP]) { off.y -= 5; } if (keys[SDL_SCANCODE_DOWN]) { off.y += 5; } struct int2 mouse; if (SDL_GetMouseState(&mouse.x, &mouse.y) & SDL_BUTTON(SDL_BUTTON_LEFT)) { if (mouse_prev.x != -1 ) { off.x -= mouse.x - mouse_prev.x; off.y -= mouse.y - mouse_prev.y; } mouse_prev = mouse; } else if (mouse_prev.x != -1) { mouse_prev = (struct int2) { -1, -1 }; } if (off.y < pictures[P_TOPLEFT]->y1) { SWAP(pictures[P_TOPLEFT], pictures[P_BOTLEFT]); SWAP(pictures[P_TOPRGHT], pictures[P_BOTRGHT]); Picture_move(pictures[P_TOPLEFT], 0, -2*h); Picture_move(pictures[P_TOPRGHT], 0, -2*h); Picture_render(pictures[P_TOPLEFT], rend); Picture_render(pictures[P_TOPRGHT], rend); } if (off.x < pictures[P_TOPLEFT]->x1) { SWAP(pictures[P_TOPLEFT], pictures[P_TOPRGHT]); SWAP(pictures[P_BOTLEFT], pictures[P_BOTRGHT]); Picture_move(pictures[P_TOPLEFT], -2*w, 0); Picture_move(pictures[P_BOTLEFT], -2*w, 0); Picture_render(pictures[P_TOPLEFT], rend); Picture_render(pictures[P_BOTLEFT], rend); } if (off.y > pictures[P_BOTRGHT]->y1) { SWAP(pictures[P_TOPLEFT], pictures[P_BOTLEFT]); SWAP(pictures[P_TOPRGHT], pictures[P_BOTRGHT]); Picture_move(pictures[P_BOTLEFT], 0, 2*h); Picture_move(pictures[P_BOTRGHT], 0, 2*h); Picture_render(pictures[P_BOTLEFT], rend); Picture_render(pictures[P_BOTRGHT], rend); } if (off.x > pictures[P_BOTRGHT]->x1) { SWAP(pictures[P_TOPLEFT], pictures[P_TOPRGHT]); SWAP(pictures[P_BOTLEFT], pictures[P_BOTRGHT]); Picture_move(pictures[P_TOPRGHT], 2*w, 0); Picture_move(pictures[P_BOTRGHT], 2*w, 0); Picture_render(pictures[P_TOPRGHT], rend); Picture_render(pictures[P_BOTRGHT], rend); } //SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); //SDL_RenderClear(rend); for (int i = 0; i < 4; i++) { Picture *p = pictures[i]; SDL_Rect dst = { p->x1 - off.x, p->y1 - off.y, w, h, }; SDL_RenderCopy(rend, p->texture, NULL, &dst); } //char buf[72]; //SDL_SetRenderDrawColor(rend, 0, 0, 0, 255); //SDL_RenderFillRect(rend, &(SDL_Rect) { 0, 0, sizeof(buf)*font_w, 7*font_h }); //size_t len = snprintf(buf, sizeof(buf), "off.x: %d, off.y: %d", off.x, off.y); //draw_text(rend, font, buf, len, RC(1, 1), 255, 255, 255); //char *q[] = {"TL", "TR", "BL", "BR"}; //for (int i = 0; i < 4; i++) { // Picture *p = pictures[i]; // len = snprintf(buf, sizeof(buf), "%s| x1: %05d, x2: %05d, y1: %05d, y2: %05d, p: %p", // q[i], p->x1, p->x2, p->y1, p->y2, p); // draw_text(rend, font, buf, len, RC(2+i, 1), 255, 255, 255); //} SDL_RenderPresent(rend); SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { running = 0; } } } SDL_DestroyRenderer(rend); SDL_DestroyWindow(window); SDL_Quit(); return 0; }