Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / apps / pacman / main.c
blob6d7cc7a8cf5f81e6588c4df3c3f25ec7d4f62893
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <fcntl.h>
24 #include <libx/base.h>
25 #include <libx/object.h>
26 #include <libx/image.h>
27 #include <libx/cursor.h>
28 #include <libx/text.h>
30 #define ESC 1
31 #define ARROWLEFT 75
32 #define ARROWRIGHT 77
33 #define ARROWUP 72
34 #define ARROWDOWN 80
36 #define MAXBEASTS 5
38 unsigned short *img_pacman;
39 unsigned short *img_wall;
40 unsigned short *img_beast;
42 int pacman_x;
43 int pacman_y;
44 int pacman_rot;
45 int pacman_rotn;
46 int pacman_points;
47 int pacman_maxpoints;
49 int scancode;
51 char *level_data;
53 unsigned char level_num;
55 typedef struct {
56 unsigned short x;
57 unsigned short y;
58 unsigned char rot;
59 } beast_t;
61 beast_t beasts[MAXBEASTS];
62 unsigned char beasts_count;
65 /** INIT **/
66 unsigned short *init_bitmap (char *str)
68 /* FOLDER bitmap */
69 unsigned short *bitmap = (unsigned short *) malloc (2120);
71 if (!bitmap)
72 return 0;
74 memset (bitmap, 0, 2048+70);
76 // html web page
77 int fd = open (str, O_RDONLY);
79 if (!fd) {
80 puts ("error -> file not found\n");
81 return 0;
84 if (!read (fd, (unsigned char *) bitmap, 2048+70)) {
85 puts ("error -> something was wrong !\n");
86 return 0;
89 //close (fd);
91 return bitmap;
94 int init_level ()
96 level_data = (char *) malloc (26 * 18 + 1);
98 if (!level_data)
99 return 0;
101 memset (level_data, 0, 26 * 18);
103 int fd = open ("level", O_RDONLY);
105 if (!fd) {
106 puts ("error -> file 'level' not found\n");
107 return 0;
110 if (!read (fd, (char *) level_data, 26 * 18)) {
111 puts ("error -> something was wrong !\n");
112 return 0;
115 //close (fd);
117 img_wall = init_bitmap ("imgwall");
119 if (!img_wall)
120 return 0;
122 level_num = 1;
124 return 1;
127 int init_pacman ()
129 /* Try open image */
130 img_pacman = init_bitmap ("imgpac");
132 if (!img_pacman)
133 return 0;
135 pacman_x = 32;
136 pacman_y = 32;
138 pacman_rot = -1;
140 pacman_points = 0;
142 return 1;
145 void init_beast ()
147 /* Try open image */
148 img_beast = init_bitmap ("imgobl");
150 if (!img_beast)
151 return;
153 beasts_count = 1;
155 pacman_maxpoints = 0;
157 unsigned char x;
158 unsigned char y;
159 unsigned char i = 0;
161 for (x = 0; x < 25; x ++) {
162 for (y = 0; y < 18; y ++) {
163 if (level_data[x + y * 26] == '3') {
164 if (i >= beasts_count)
165 continue;
167 beasts[i].x = x * 32;
168 beasts[i].y = y * 32;
169 beasts[i].rot = 0;
171 i ++;
172 } else
173 if (level_data[x + y * 26] == '0')
174 pacman_maxpoints ++;
180 int init ()
182 init_pacman ();
183 init_level ();
184 init_beast ();
186 /* Switch to VGA graphics mode */
187 xinit ();
189 /* Clean screen */
190 xcls (0);
192 scancode = 0;
194 return 1;
197 /** DRAW **/
198 void draw_bitmap (unsigned short *bitmap, unsigned short x, unsigned short y)
200 unsigned i = 0;
201 unsigned j = 0;
202 unsigned k = 0;
203 unsigned pix = 0;
205 for (i = 0; i < 32*32; i ++) {
206 if (k >= 32) {
207 j ++;
208 k = 0;
211 pix = (1024-i)+35;
213 if (pix >= 1059)
214 continue;
216 if (bitmap[pix] != (unsigned short) 0)
217 if (k <= 32 && j <= 32)
218 xpixel ((unsigned) x+k, (unsigned) y+j, bitmap[pix]);
220 k ++;
225 void draw_field (unsigned char x, unsigned char y)
227 draw_bitmap (img_wall, x * 32, y * 32);
230 void draw_point (unsigned char x, unsigned char y)
232 xline (x * 32 + 11, y * 32 + 10, x * 32 + 20, y * 32 + 10, ~0);
233 xrectfill (x * 32 + 10, y * 32 + 11, x * 32 + 21, y * 32 + 20, ~0);
234 xline (x * 32 + 11, y * 32 + 21, x * 32 + 20, y * 32 + 21, ~0);
237 void draw_beasts ()
239 unsigned char i;
240 for (i = 0; i < beasts_count; i ++)
241 draw_bitmap (img_beast, beasts[i].x, beasts[i].y);
244 void draw_level ()
246 unsigned char x;
247 unsigned char y;
249 for (x = 0; x < 25; x ++) {
250 for (y = 0; y < 18; y ++) {
251 if (level_data[x + y * 26] == '1')
252 draw_field (x, y);
253 else
254 if (level_data[x + y * 26] == '0')
255 draw_point (x, y);
260 void draw_pacman ()
262 /* Draw image to vga buffer */
263 draw_bitmap (img_pacman, pacman_x, pacman_y);
265 if (pacman_points % 2) {
266 if (pacman_rot == 0) {
267 xrectfill (pacman_x, pacman_y+11, pacman_x+3, pacman_y+20, 0);
268 xrectfill (pacman_x+4, pacman_y+13, pacman_x+7, pacman_y+18, 0);
269 xrectfill (pacman_x+8, pacman_y+15, pacman_x+11, pacman_y+16, 0);
270 } else if (pacman_rot == 1) {
271 xrectfill (pacman_x+29, pacman_y+11, pacman_x+32, pacman_y+20, 0);
272 xrectfill (pacman_x+25, pacman_y+13, pacman_x+28, pacman_y+18, 0);
273 xrectfill (pacman_x+21, pacman_y+15, pacman_x+24, pacman_y+16, 0);
274 } else if (pacman_rot == 2) {
275 xrectfill (pacman_x+11, pacman_y, pacman_x+20, pacman_y+3, 0);
276 xrectfill (pacman_x+13, pacman_y+4, pacman_x+18, pacman_y+7, 0);
277 xrectfill (pacman_x+15, pacman_y+8, pacman_x+16, pacman_y+11, 0);
278 } else if (pacman_rot == 3) {
279 xrectfill (pacman_x+11, pacman_y+29, pacman_x+20, pacman_y+32, 0);
280 xrectfill (pacman_x+13, pacman_y+25, pacman_x+18, pacman_y+28, 0);
281 xrectfill (pacman_x+15, pacman_y+21, pacman_x+16, pacman_y+24, 0);
286 int draw ()
288 draw_pacman ();
289 draw_level ();
290 draw_beasts ();
292 char buf_pts[5];
293 itoa (pacman_points, buf_pts, 10);
295 xtext_puts (20, 585, ~0, "Points:");
296 xtext_puts (80, 585, ~0, buf_pts);
298 itoa (pacman_maxpoints, buf_pts, 10);
300 xtext_puts (100, 585, ~0, "/");
301 xtext_puts (110, 585, ~0, buf_pts);
303 itoa (level_num, buf_pts, 10);
305 xtext_puts (200, 585, ~0, "Level:");
306 xtext_puts (250, 585, ~0, buf_pts);
308 return 1;
311 /** UPDATE **/
312 void level_next ()
314 level_num ++;
316 beasts_count ++;
318 pacman_points = 0;
320 unsigned char x;
321 unsigned char y;
322 unsigned char i = 0;
324 for (x = 0; x < 25; x ++) {
325 for (y = 0; y < 18; y ++) {
326 if (level_data[x + y * 26] == '3') {
327 if (i >= beasts_count)
328 continue;
330 beasts[i].x = x * 32;
331 beasts[i].y = y * 32;
332 beasts[i].rot = 0;
334 i ++;
335 } else
336 if (level_data[x + y * 26] == '2')
337 level_data[x + y * 26] = '0';
342 void level_gameover ()
344 level_num = 1;
346 beasts_count = 1;
348 pacman_points = 0;
350 unsigned char x;
351 unsigned char y;
352 unsigned char i = 0;
354 for (x = 0; x < 25; x ++) {
355 for (y = 0; y < 18; y ++) {
356 if (level_data[x + y * 26] == '3') {
357 if (i >= beasts_count)
358 continue;
360 beasts[i].x = x * 32;
361 beasts[i].y = y * 32;
362 beasts[i].rot = 0;
364 i ++;
365 } else
366 if (level_data[x + y * 26] == '2')
367 level_data[x + y * 26] = '0';
372 void beast_stop (unsigned char i)
374 if (beasts[i].rot == 0) {
375 beasts[i].x ++;
376 } else if (beasts[i].rot == 1) {
377 beasts[i].x -= 2;
378 } else if (beasts[i].rot == 2) {
379 beasts[i].y ++;
380 } else if (beasts[i].rot == 3) {
381 beasts[i].y -= 2;
385 void pacman_stop ()
387 if (pacman_rot == 0) {
388 pacman_x ++;
389 } else if (pacman_rot == 1) {
390 pacman_x -= 2;
391 } else if (pacman_rot == 2) {
392 pacman_y ++;
393 } else if (pacman_rot == 3) {
394 pacman_y -= 2;
397 pacman_rot = -1;
400 int update_pacman ()
402 if (scancode == ARROWLEFT)
403 pacman_rotn = 0;
404 else if (scancode == ARROWRIGHT)
405 pacman_rotn = 1;
406 else if (scancode == ARROWUP)
407 pacman_rotn = 2;
408 else if (scancode == ARROWDOWN)
409 pacman_rotn = 3;
411 if (pacman_rot == 0) {
412 if (pacman_x > 0)
413 pacman_x --;
414 } else if (pacman_rot == 1) {
415 if (pacman_x < 800-32)
416 pacman_x ++;
417 } else if (pacman_rot == 2) {
418 if (pacman_y > 0)
419 pacman_y --;
420 } else if (pacman_rot == 3) {
421 if (pacman_y < 600-32)
422 pacman_y ++;
425 if (!(pacman_x % 32) && !(pacman_y % 32))
426 pacman_rot = pacman_rotn;
428 return 1;
432 int update_beasts ()
434 unsigned char i;
435 for (i = 0; i < beasts_count; i ++) {
436 if (beasts[i].rot == 0) {
437 if (beasts[i].x > 0)
438 beasts[i].x --;
439 } else if (beasts[i].rot == 1) {
440 if (beasts[i].x < 800-32)
441 beasts[i].x ++;
442 } else if (beasts[i].rot == 2) {
443 if (beasts[i].y > 0)
444 beasts[i].y --;
445 } else if (beasts[i].rot == 3) {
446 if (beasts[i].y < 600-32)
447 beasts[i].y ++;
450 /* collision with pacman and beasts */
451 if (beasts[i].x/32 == pacman_x/32 && beasts[i].y/32 == pacman_y/32)
452 level_gameover ();
455 return 1;
459 int update ()
461 scancode = getkey ();
463 if (scancode == ESC)
464 return -1;
466 /* Flip double buffer - show image */
467 xfbswap ();
469 /* collision */
470 unsigned char x;
471 unsigned char y;
473 for (x = 0; x < 25; x ++) {
474 for (y = 0; y < 18; y ++) {
475 if (level_data[x + y * 26] == '1') {
476 if (pacman_x > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
477 pacman_stop ();
478 else if (pacman_x+31 > x*32 && pacman_y+31 > y*32 && pacman_x+31 < x*32+32 && pacman_y+31 < y*32+32)
479 pacman_stop ();
480 else if (pacman_x+31 > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
481 pacman_stop ();
482 else if (pacman_x > x*32 && pacman_y+31 > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
483 pacman_stop ();
485 unsigned char i;
486 for (i = 0; i < beasts_count; i ++) {
487 if (beasts[i].x > x*32 && beasts[i].y > y*32 && beasts[i].x < x*32+32 && beasts[i].y < y*32+32) {
488 beast_stop (i);
489 beasts[i].rot = rand () % 4;
490 } else if (beasts[i].x+31 > x*32 && beasts[i].y+31 > y*32 && beasts[i].x+31 < x*32+32 && beasts[i].y+31 < y*32+32) {
491 beast_stop (i);
492 beasts[i].rot = rand () % 4;
493 } else if (beasts[i].x+31 > x*32 && beasts[i].y > y*32 && beasts[i].x < x*32+32 && beasts[i].y < y*32+32) {
494 beast_stop (i);
495 beasts[i].rot = rand () % 4;
496 } else if (beasts[i].x > x*32 && beasts[i].y+31 > y*32 && beasts[i].x < x*32+32 && beasts[i].y < y*32+32) {
497 beast_stop (i);
498 beasts[i].rot = rand () % 4;
501 } else
502 if (level_data[x + y * 26] == '0') {
503 unsigned p = 0;
505 if (pacman_x > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
506 p = 1;
507 if (pacman_x+31 > x*32 && pacman_y+31 > y*32 && pacman_x+31 < x*32+32 && pacman_y+31 < y*32+32)
508 p = 1;
509 if (pacman_x+31 > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
510 p = 1;
511 if (pacman_x > x*32 && pacman_y+31 > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
512 p = 1;
514 if (p) {
515 pacman_points ++;
516 level_data[x + y * 26] = '2';
522 update_pacman ();
523 update_beasts ();
525 if (pacman_points == pacman_maxpoints)
526 level_next ();
528 return 1;
531 int main (int argc, char **argv)
533 init ();
535 while (1) {
536 draw ();
538 if (update () == -1)
539 break;
542 free (img_pacman);
543 free (img_wall);
544 free (img_beast);
546 /* Go back to textual mode */
547 xexit ();
549 /* Exit app */
550 return 0;