Skip to content

Instantly share code, notes, and snippets.

@lipx1508
Last active October 30, 2023 21:55
Show Gist options
  • Save lipx1508/cb0ed0ef0dbdd27690f2ca6ff25974e9 to your computer and use it in GitHub Desktop.
Save lipx1508/cb0ed0ef0dbdd27690f2ca6ff25974e9 to your computer and use it in GitHub Desktop.
Simple auto-tiler in C++
// Libraries
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <SDL2/SDL.h>
// SDL
SDL_Window * window;
SDL_Renderer * renderer;
// Game
struct Tile {
Tile(char c = ' ') {
if (c != ' ') this->visible = true;
}
union {
struct {
int top_l : 1;
int top_m : 1;
int top_r : 1;
int mid_l : 1;
int mid_r : 1;
int bot_l : 1;
int bot_m : 1;
int bot_r : 1;
};
char bitmask = 0;
};
bool visible = false;
};
void draw_pt(int x, int y, SDL_Color col) {
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
SDL_RenderDrawPoint(renderer, x, y);
}
void draw_rec(int x, int y, int w, int h, SDL_Color col) {
SDL_Rect rect = { x, y, w, h };
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
SDL_RenderFillRect(renderer, &rect);
}
void init() {
// SDL
window = SDL_CreateWindow("doom", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, 0);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!window || !renderer)
fprintf(stderr, "[error]: failed to initialize SDL: %s", SDL_GetError());
SDL_RenderSetScale(renderer, 12, 12);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
// Game
std::vector<Tile> tiles = {
' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',
};
auto get = [&](int x, int y) -> Tile {
if (x >= 0 && x < 6 && y >= 0 && y < 6) {
return tiles[x + y * 6];
}
return Tile(' ');
};
auto check_tile = [&](int i) {
tiles[i].bitmask = 0;
if (!tiles[i].visible) return;
int x = i % 6;
int y = i / 6;
// Sides
if (!get(x, y - 1).visible) tiles[i].top_m = 1;
if (!get(x, y + 1).visible) tiles[i].bot_m = 1;
if (!get(x - 1, y).visible) tiles[i].mid_l = 1;
if (!get(x + 1, y).visible) tiles[i].mid_r = 1;
// Diagonal
if (!get(x - 1, y - 1).visible || !get(x, y - 1).visible || !get(x - 1, y).visible)
tiles[i].top_l = 1;
if (!get(x + 1, y - 1).visible || !get(x, y - 1).visible || !get(x + 1, y).visible)
tiles[i].top_r = 1;
if (!get(x - 1, y + 1).visible || !get(x, y + 1).visible || !get(x - 1, y).visible)
tiles[i].bot_l = 1;
if (!get(x + 1, y + 1).visible || !get(x, y + 1).visible || !get(x + 1, y).visible)
tiles[i].bot_r = 1;
};
auto check = [&]() {
for (int i = 0; i < tiles.size(); ++i) {
check_tile(i);
}
};
// Loop
int mx, my;
bool running = true;
while (running) {
bool btn = false;
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT: {
running = false;
break;
}
case SDL_MOUSEBUTTONDOWN: {
btn = true;
mx = event.motion.x / 12;
my = event.motion.y / 12;
break;
}
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for (int i = 0; i < tiles.size(); ++i) {
int x = 8 * (i % 6);
int y = 8 * (i / 6);
SDL_Rect r1 = { x, y, 8, 8 };
SDL_Rect r2 = { mx, my, 1, 1 };
if (SDL_HasIntersection(&r1, &r2) && btn) {
tiles[i].visible = !tiles[i].visible;
}
if (!tiles[i].visible) continue;
draw_rec(x, y, 8, 8, { 0, 255, 0, 255 });
if (tiles[i].top_l) draw_pt(x, y, { 255, 0, 255, 255 });
if (tiles[i].top_m) draw_pt(x + 4, y, { 255, 0, 255, 255 });
if (tiles[i].top_r) draw_pt(x + 7, y, { 255, 0, 255, 255 });
if (tiles[i].mid_l) draw_pt(x, y + 4, { 255, 0, 255, 255 });
if (tiles[i].mid_r) draw_pt(x + 7, y + 4, { 255, 0, 255, 255 });
if (tiles[i].bot_l) draw_pt(x, y + 7, { 255, 0, 255, 255 });
if (tiles[i].bot_m) draw_pt(x + 4, y + 7, { 255, 0, 255, 255 });
if (tiles[i].bot_r) draw_pt(x + 7, y + 7, { 255, 0, 255, 255 });
}
if (btn) check();
draw_pt(mx, my, { 255, 255, 0, 255 });
SDL_RenderPresent(renderer);
}
// Cleanup
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
// Main
int main(int argc, char *argv[]) {
init();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment