-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.c
More file actions
112 lines (91 loc) · 3.37 KB
/
render.c
File metadata and controls
112 lines (91 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "render.h"
#include <SDL2/SDL.h>
#include "config.h"
#include "st7789.h"
static SDL_Window* win = NULL;
static SDL_Renderer* ren = NULL;
static SDL_Texture* tex = NULL;
static uint32_t mirror_rgba[ST7789_TFTWIDTH * ST7789_TFTHEIGHT];
static uint32_t rgb565_to_rgba8888(uint16_t c) { // RGB565를 ARGB8888로 변환 TFT -> 미러링
uint8_t r = (c >> 11) & 0x1F;
uint8_t g = (c >> 5) & 0x3F;
uint8_t b = (c >> 0) & 0x1F;
r = (r << 3) | (r >> 2);
g = (g << 2) | (g >> 4);
b = (b << 3) | (b >> 2);
return (0xFFu << 24) | (r << 16) | (g << 8) | b;
}
static int mirror_init(void) { // SDL 미러 렌더러 초기화
if (SDL_Init(SDL_INIT_VIDEO) != 0) return 0;
win = SDL_CreateWindow("SNAKE MIRROR",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
ST7789_TFTWIDTH * 2, ST7789_TFTHEIGHT * 2, 0);
if (!win) return 0;
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
if (!ren) return 0;
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
ST7789_TFTWIDTH, ST7789_TFTHEIGHT);
if (!tex) return 0;
return 1;
}
static void mirror_quit(void) { // 렌더러 종료
if (tex) SDL_DestroyTexture(tex);
if (ren) SDL_DestroyRenderer(ren);
if (win) SDL_DestroyWindow(win);
SDL_Quit();
}
static void mirror_fillRect(int x, int y, int w, int h, uint16_t color) { // 미러링에 사각형 그리기
if (x < 0 || y < 0) return;
if (x + w > ST7789_TFTWIDTH) w = ST7789_TFTWIDTH - x;
if (y + h > ST7789_TFTHEIGHT) h = ST7789_TFTHEIGHT - y;
uint32_t rgba = rgb565_to_rgba8888(color);
for (int yy = y; yy < y + h; yy++) {
uint32_t* row = &mirror_rgba[yy * ST7789_TFTWIDTH];
for (int xx = x; xx < x + w; xx++) row[xx] = rgba;
}
}
static void mirror_fillScreen(uint16_t color) { // 미러링에 화면 전체 채우기
uint32_t rgba = rgb565_to_rgba8888(color);
for (int i = 0; i < ST7789_TFTWIDTH * ST7789_TFTHEIGHT; i++) {
mirror_rgba[i] = rgba;
}
}
int render_init(void) {
if (!mirror_init()) return 0;
return 1;
}
void render_quit(void) {
mirror_quit();
}
int render_present(void) { // 1이면 계속, 0이면 종료 요청
SDL_Event e;
while (SDL_PollEvent(&e)) { // q 또는 ESC 누르면 종료
if (e.type == SDL_QUIT) return 0;
if (e.type == SDL_KEYDOWN) {
SDL_Keycode k = e.key.keysym.sym;
if (k == SDLK_q || k == SDLK_ESCAPE) return 0;
}
}
SDL_UpdateTexture(tex, NULL, mirror_rgba, ST7789_TFTWIDTH * sizeof(uint32_t));
SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
return 1;
}
void fill_screen_both(uint16_t color) {
st7789_fillScreen(color);
mirror_fillScreen(color);
}
void draw_rect_both(int x, int y, int w, int h, uint16_t color) {
st7789_fillRect((uint16_t)x, (uint16_t)y, (uint16_t)w, (uint16_t)h, color);
mirror_fillRect(x, y, w, h, color);
}
void draw_cell(uint8_t gx, uint8_t gy, uint16_t color) {
int px = gx * CELL; // 격자 좌표를 픽셀 좌표로 변환
int py = gy * CELL;
draw_rect_both(px, py, CELL, CELL, color);
}
void dot(int x, int y, int s, uint16_t color) { // 폰트는 5*7 픽셀인데 s배 확대해서 그리기
draw_rect_both(x, y, s, s, color);
}