💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Tetris › files › 2237c8a2f4424ab096d5bc4d495… captured on 2023-12-28 at 15:48:36. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-09-08)
-=-=-=-=-=-=-
0 /* See LICENSE file for copyright and license details. */
1 #include "config.h"
2 #include "backend.h"
3 #include "util.h"
4 #include <X11/Xutil.h>
5
6 Atom WM_DELETE_WINDOW;
7 Display* dis;
8 int screen;
9 Window win;
10 Pixmap buffer;
11 GC gc;
12 int backend_width = 640;
13 int backend_height = 480;
14
15 unsigned int palette[] = {
16 /* blocks */
17 0x056060,
18 0x10165D,
19 0x5D3F08,
20 0x5D5D04,
21 0x5D0501,
22 0x3D0A5F,
23 0x055C0A,
24 /* borders */
25 0x003030,
26 0x00003D,
27 0x2D0f00,
28 0x2D2D00,
29 0x2D0000,
30 0x00003F,
31 0x002C00,
32 0x404040, /* background */
33 0xEEEEEE, /* text */
34 };
35
36 int backend_init() {
37
38 dis = XOpenDisplay((char*)0);
39 if (!dis) return -1;
40 screen = DefaultScreen(dis);
41 win = XCreateSimpleWindow(dis, DefaultRootWindow(dis), 0, 0,
42 backend_width, backend_height, 0,
43 WhitePixel(dis, screen),
44 BlackPixel(dis, screen));
45 XSetStandardProperties(dis, win, "Tetris", "Tetris",
46 None, NULL, 0, NULL);
47 XSelectInput(dis, win, ExposureMask | ButtonPressMask |
48 KeyPressMask | ButtonReleaseMask);
49 gc = XCreateGC(dis, win, 0, 0);
50 XSetBackground(dis, gc, 0);
51 XSetForeground(dis, gc, 0);
52 XClearWindow(dis, win);
53 XMapRaised(dis, win);
54
55 WM_DELETE_WINDOW = XInternAtom(dis, "WM_DELETE_WINDOW", 0);
56 XSetWMProtocols(dis, win, &WM_DELETE_WINDOW, 1);
57 buffer = XCreatePixmap(dis, win, backend_width, backend_height, 24);
58 return 0;
59 }
60
61 void backend_fill(int x, int y, int w, int h, int color) {
62 XSetForeground(dis, gc, palette[color]);
63 XFillRectangle(dis, buffer, gc, x, y, w, h);
64 }
65
66 void backend_draw(int x, int y, int w, int h, int color) {
67 XSetForeground(dis, gc, palette[color]);
68 XDrawRectangle(dis, buffer, gc, x, y, w, h);
69 }
70
71 uint8 backend_input() {
72 XEvent event;
73 XWindowAttributes attr;
74 uint8 state = 0;
75 while (XPending(dis)) {
76 XNextEvent(dis, &event);
77 switch (event.type) {
78 case ClientMessage:
79 if ((Atom)event.xclient.data.l[0] == WM_DELETE_WINDOW)
80 state |= QUIT;
81 break;
82 case Expose:
83 XClearWindow(dis, win);
84 XGetWindowAttributes(dis, win, &attr);
85 backend_width = attr.width;
86 backend_height = attr.height;
87 XFreePixmap(dis, buffer);
88 buffer = XCreatePixmap(dis, win, backend_width,
89 backend_height, 24);
90 break;
91 case KeyPress:
92 switch (XLookupKeysym(&event.xkey, 0)) {
93 case XK_Escape:
94 state |= QUIT;
95 break;
96 case XK_r:
97 case XK_space:
98 state |= ROTATE;
99 break;
100 case XK_a:
101 case XK_Left:
102 state |= LEFT;
103 break;
104 case XK_d:
105 case XK_Right:
106 state |= RIGHT;
107 break;
108 case XK_s:
109 case XK_Down:
110 state |= DOWN;
111 break;
112 }
113 break;
114 }
115 }
116
117 return state;
118 }
119
120 void backend_refresh() {
121 XCopyArea(dis, buffer, win, gc, 0, 0,
122 backend_width, backend_height, 0, 0);
123 XSetForeground(dis, gc, 0);
124 XFillRectangle(dis, buffer, gc, 0, 0, backend_width, backend_height);
125
126 ansi_sleep(1000 * 1000 / FPS);
127 }
128
129 void backend_clean() {
130 XFreeGC(dis, gc);
131 XDestroyWindow(dis, win);
132 XCloseDisplay(dis);
133 }
134