💾 Archived View for gemini.rmf-dev.com › repo › Vaati › RTetris › files › 1b5389bec44e609434bd76bc36… captured on 2022-07-16 at 17:08:45. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 /* See LICENSE for license details. */
1 #include <stdio.h>
2 #include <time.h>
3 #include <math.h>
4 #include <SDL2/SDL.h>
5 #include "config.h"
6
7 unsigned char number[10][7] = {
8 {1,1,1,0,1,1,1}, // 0
9 {0,0,1,0,0,1,0}, // 1
10 {1,0,1,1,1,0,1}, // 2
11 {1,0,1,1,0,1,1}, // 3
12 {0,1,1,1,0,1,0}, // 4
13 {1,1,0,1,0,1,1}, // 5
14 {1,1,0,1,1,1,1}, // 6
15 {1,0,1,0,0,1,0}, // 7
16 {1,1,1,1,1,1,1}, // 8
17 {1,1,1,1,0,1,1} // 9
18 };
19
20 SDL_Rect offset[8] = {
21 {0, 0, WIDTHX,THICK},
22 {0, 0, THICK, WIDTHY},
23 {WIDTHX-THICK, 0, THICK, WIDTHY},
24 {0, WIDTHY, WIDTHX,THICK},
25 {0, WIDTHY, THICK, WIDTHY},
26 {WIDTHX-THICK, WIDTHY, THICK, WIDTHY},
27 {0, WIDTHY*2, WIDTHX,THICK},
28 };
29
30 SDL_Renderer* render;
31 SDL_Rect gameRect;
32
33 int pieceX = SIZEX/2;
34 int pieceY = 0;
35 int pieceId = 0;
36 int rotation = 0;
37
38 unsigned char pLen[7][2] = {
39 {4,0},
40 {3,3},
41 {3,3},
42 {2,2},
43 {3,3},
44 {3,3},
45 {3,3}
46 };
47
48 char pieces[7][2][4] = {
49 {
50 { 1, 1, 1, 1 },
51 },
52 {
53 { 1, 0, 0 },
54 { 1, 1, 1 }
55 },
56 {
57 { 0, 0, 1 },
58 { 1, 1, 1 }
59 },
60 {
61 { 1, 1 },
62 { 1, 1 }
63 },
64 {
65 { 0, 1, 1 },
66 { 1, 1, 0 }
67 },
68 {
69 { 0, 1, 0 },
70 { 1, 1, 1 }
71 },
72 {
73 { 1, 1, 0 },
74 { 0, 1, 1 }
75 }
76 };
77
78 unsigned char game[SIZEY*SIZEX];
79
80 void drawDigit(int x, int y, int n) {
81 if (n>=10) return;
82 for (int i=0; i<7; i++) {
83 if (number[n][i]) {
84 SDL_SetRenderDrawColor(render, text.r, text.g, text.b, text.a);
85 SDL_Rect r = offset[i];
86 r.x+=x;
87 r.y+=y;
88 SDL_RenderDrawRect(render, &r);
89 }
90 }
91 }
92
93 void drawNumber(int x, int y, unsigned int n) {
94 if (n==0) {
95 drawDigit(x,y,0);
96 }
97 int j=0;
98 for(int i=n; i>0; i/=10) {
99 j++;
100 }
101 for(int i=n; i>0; i/=10) {
102 j--;
103 drawDigit(x+j*(WIDTHX+THICK*2),y,i%!)(MISSING);
104 }
105 }
106
107 void drawBlock(int x, int y, int c) {
108 float s = ceil((float)gameRect.w/SIZEX);
109 SDL_Rect rect = {gameRect.x+x*s, gameRect.y+y*s, s, s};
110 SDL_SetRenderDrawColor(render, color[c].r, color[c].g, color[c].b, color[c].a);
111 SDL_RenderFillRect(render, &rect);
112 SDL_SetRenderDrawColor(render, color[c].r*0.75, color[c].g*0.75, color[c].b*0.75, color[c].a);
113 SDL_RenderDrawRect(render, &rect);
114 }
115
116 int blocks[6][2];
117 int bLen = 0;
118 void getBlocks(int x, int y, int c, int r) {
119 bLen = 0;
120 int h = c==0?1:2;
121 for(unsigned char i=0; i<h; i++) {
122 for(unsigned char j=0; j<pLen[c][i]; j++) {
123 if(pieces[c][i][j]!=0) {
124 switch(r) {
125 case 0:
126 blocks[bLen][0] = x+i;
127 blocks[bLen][1] = y+j;
128 break;
129 case 1:
130 blocks[bLen][0] = x+j;
131 blocks[bLen][1] = y+i;
132 break;
133 case 2:
134 blocks[bLen][0] = x+h-i-1;
135 blocks[bLen][1] = y+j;
136 break;
137 case 3:
138 blocks[bLen][0] = x+j;
139 blocks[bLen][1] = y+h-i-1;
140 break;
141 }
142 bLen++;
143 }
144 }
145 }
146 }
147
148 void setPiece() {
149 getBlocks(pieceX,pieceY,pieceId,rotation);
150 for (int i=0; i<bLen; i++)
151 game[blocks[i][0]+blocks[i][1]*SIZEX]=pieceId+1;
152 }
153
154 void drawPiece() {
155 getBlocks(pieceX,pieceY,pieceId,rotation);
156 for (int i=0; i<bLen; i++)
157 drawBlock(blocks[i][0],blocks[i][1],pieceId);
158 }
159
160 int rotate(int r) {
161 getBlocks(pieceX,pieceY,pieceId,r);
162 for (int i=0; i<bLen; i++)
163 if(blocks[i][1]>=SIZEY||blocks[i][0]<0||blocks[i][0]>=SIZEX||game[SIZEX*blocks[i][1]+blocks[i][0]]!=0)
164 return 0;
165 if (r)
166 rotation = (rotation+1)%!;(MISSING)
167 return 1;
168 }
169
170 int movePiece(int x, int y, int m) {
171 getBlocks(x,y,pieceId,rotation);
172 for (int i=0; i<bLen; i++)
173 if(blocks[i][1]>=SIZEY||blocks[i][0]<0||blocks[i][0]>=SIZEX||game[SIZEX*(blocks[i][1])+(blocks[i][0])]!=0)
174 return 0;
175 if (m!=0) {
176 pieceX = x;
177 pieceY = y;
178 }
179 return 1;
180 }
181
182 void dropLine(int y) {
183 for(int i=y; i>0; i--) {
184 for(int j=0; j<SIZEX; j++)
185 game[i*SIZEX+j]=game[(i-1)*SIZEX+j];
186 }
187 }
188
189 int checkLine() {
190 int l=0;
191 for(int i=0; i<SIZEY; i++) {
192 int t=1;
193 for(int j=0; j<SIZEX; j++)
194 if(game[i*SIZEX+j]==0) t=0;
195 if(t==1) {
196 dropLine(i);
197 l++;
198 }
199 }
200 return l;
201 }
202
203 int main() {
204
205 srand(time(0));
206
207 int winW=640;
208 int winH=480;
209
210 memset(game,0,SIZEY*SIZEX);
211
212 if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
213 printf("Failed to initialize SDL: %!s(MISSING)\n", SDL_GetError());
214 }
215 SDL_Window* win = SDL_CreateWindow("Tetris", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, winW, winH, SDL_WINDOW_RESIZABLE);
216 render = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
217
218 int close = 0;
219 int tick = 0;
220 int score = 0;
221 while (!close) {
222 SDL_Event event;
223 while (SDL_PollEvent(&event)) {
224 switch (event.type) {
225 case SDL_WINDOWEVENT:
226 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
227 winW=event.window.data1;
228 winH=event.window.data2;
229 }
230 break;
231 case SDL_QUIT:
232 close = 1;
233 break;
234 case SDL_KEYDOWN:
235 switch (event.key.keysym.scancode) {
236 case SDL_SCANCODE_R:
237 case SDL_SCANCODE_SPACE:
238 rotate(1);
239 break;
240 case SDL_SCANCODE_A:
241 case SDL_SCANCODE_LEFT:
242 movePiece(pieceX-1,pieceY,1);
243 break;
244 case SDL_SCANCODE_S:
245 case SDL_SCANCODE_DOWN:
246 while(movePiece(pieceX,pieceY+1,1)) ;
247 break;
248 case SDL_SCANCODE_D:
249 case SDL_SCANCODE_RIGHT:
250 movePiece(pieceX+1,pieceY,1);
251 break;
252 default:
253 break;
254 }
255 }
256 }
257
258 tick++;
259 if (tick==30) {
260 tick = 0;
261 movePiece(pieceX,pieceY+1,1);
262 }
263
264 if (movePiece(pieceX,pieceY+1,0)==0) {
265 setPiece();
266 score+=5;
267 int l = checkLine();
268 score+=l*l*15;
269 pieceX = SIZEX/2-1;
270 pieceY = 0;
271 pieceId = rand()%!;(MISSING)
272 if (movePiece(pieceX,pieceY,0)==0) {
273 score = 0;
274 memset(game,0,SIZEX*SIZEY);
275 }
276 }
277
278 SDL_SetRenderDrawColor(render, 0, 0, 0, 0);
279 SDL_RenderClear(render);
280
281 SDL_SetRenderDrawColor(render, background.r, background.g, background.b, background.a);
282
283 SDL_Rect rect = gameRect;
284 if (winH*SIZEX/SIZEY-winW<0) {
285 SDL_Rect r = {(winW-winH*SIZEX/SIZEY)/2, 0, winH*SIZEX/SIZEY, winH*SIZEY/SIZEX/2};
286 rect = gameRect = r;
287 rect.w = ceil((float)gameRect.w/SIZEX)*SIZEX;
288 } else {
289 SDL_Rect r = {0, (winH-winW*SIZEY/SIZEX)/2, winW*SIZEY/SIZEX/2, winW*SIZEY/SIZEX};
290 rect = gameRect = r;
291 rect.h = ceil((float)gameRect.w/SIZEX)*SIZEY;
292 }
293
294 SDL_RenderFillRect(render, &rect);
295
296 drawPiece();
297
298 for (int i=0; i<SIZEX*SIZEY; i++) {
299 if(game[i]!=0)
300 drawBlock(i%!S(MISSING)IZEX,i/SIZEX,game[i]-1);
301 }
302
303 drawNumber(rect.x+THICK*2,rect.y+THICK*2,score);
304
305 SDL_RenderPresent(render);
306 SDL_Delay(1000 / 60);
307 }
308
309 SDL_DestroyRenderer(render);
310 SDL_DestroyWindow(win);
311 SDL_Quit();
312
313 return 0;
314 }
315