0.6.1 final release; pacman game added; irc improved (IPv6 support); websrv fixed...
[ZeXOS.git] / apps / pacman / main.c
blob1b0e33a9391a8c2214550a4fa63fd23a365aa368
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
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;
64 void *ptr;
66 /** INIT **/
67 unsigned short *init_bitmap (char *str)
69 /* FOLDER bitmap */
70 unsigned short *bitmap = (unsigned short *) ptr;
72 if (!bitmap)
73 return 0;
75 ptr += 2100;
77 memset (bitmap, 0, 2048+70);
79 // html web page
80 int fd = open (str, O_RDONLY);
82 if (!fd) {
83 puts ("error -> file not found\n");
84 return 0;
87 if (!read (fd, (unsigned char *) bitmap, 2048+70)) {
88 puts ("error -> something was wrong !\n");
89 return 0;
92 //close (fd);
94 return bitmap;
97 int init_level ()
99 level_data = (char *) malloc (26 * 18 + 1);
101 if (!level_data)
102 return 0;
104 memset (level_data, 0, 26 * 18);
106 int fd = open ("level", O_RDONLY);
108 if (!fd) {
109 puts ("error -> file 'level' not found\n");
110 return 0;
113 if (!read (fd, (char *) level_data, 26 * 18)) {
114 puts ("error -> something was wrong !\n");
115 return 0;
118 //close (fd);
120 img_wall = init_bitmap ("imgwall");
122 if (!img_wall)
123 return 0;
125 level_num = 1;
127 return 1;
130 int init_pacman ()
132 /* Try open image */
133 img_pacman = init_bitmap ("imgpac");
135 if (!img_pacman)
136 return 0;
138 pacman_x = 32;
139 pacman_y = 32;
141 pacman_rot = -1;
143 pacman_points = 0;
145 return 1;
148 void init_beast ()
150 /* Try open image */
151 img_beast = init_bitmap ("imgobl");
153 if (!img_beast)
154 return;
156 beasts_count = 1;
158 pacman_maxpoints = 0;
160 unsigned char x;
161 unsigned char y;
162 unsigned char i = 0;
164 for (x = 0; x < 25; x ++) {
165 for (y = 0; y < 18; y ++) {
166 if (level_data[x + y * 26] == '3') {
167 if (i >= beasts_count)
168 continue;
170 beasts[i].x = x * 32;
171 beasts[i].y = y * 32;
172 beasts[i].rot = 0;
174 i ++;
175 } else
176 if (level_data[x + y * 26] == '0')
177 pacman_maxpoints ++;
183 int init ()
185 /* HACK: errrrrr,very ugly */
186 ptr = (void *) 0x300000;
188 init_pacman ();
189 init_level ();
190 init_beast ();
192 /* Switch to VGA graphics mode */
193 xinit ();
195 /* Clean screen */
196 xcls (0);
198 scancode = 0;
200 return 1;
203 /** DRAW **/
204 void draw_bitmap (unsigned short *bitmap, unsigned short x, unsigned short y)
206 unsigned i = 0;
207 unsigned j = 0;
208 unsigned k = 0;
209 unsigned pix = 0;
211 for (i = 0; i < 32*32; i ++) {
212 if (k >= 32) {
213 j ++;
214 k = 0;
217 pix = (1024-i)+35;
219 if (pix >= 1059)
220 continue;
222 if (bitmap[pix] != (unsigned short) 0)
223 if (k <= 32 && j <= 32)
224 xpixel ((unsigned) x+k, (unsigned) y+j, bitmap[pix]);
226 k ++;
231 void draw_field (unsigned char x, unsigned char y)
233 draw_bitmap (img_wall, x * 32, y * 32);
236 void draw_point (unsigned char x, unsigned char y)
238 xline (x * 32 + 11, y * 32 + 10, x * 32 + 20, y * 32 + 10, ~0);
239 xrectfill (x * 32 + 10, y * 32 + 11, x * 32 + 21, y * 32 + 20, ~0);
240 xline (x * 32 + 11, y * 32 + 21, x * 32 + 20, y * 32 + 21, ~0);
243 void draw_beasts ()
245 unsigned char i;
246 for (i = 0; i < beasts_count; i ++)
247 draw_bitmap (img_beast, beasts[i].x, beasts[i].y);
250 void draw_level ()
252 unsigned char x;
253 unsigned char y;
255 for (x = 0; x < 25; x ++) {
256 for (y = 0; y < 18; y ++) {
257 if (level_data[x + y * 26] == '1')
258 draw_field (x, y);
259 else
260 if (level_data[x + y * 26] == '0')
261 draw_point (x, y);
266 void draw_pacman ()
268 /* Draw image to vga buffer */
269 draw_bitmap (img_pacman, pacman_x, pacman_y);
271 if (pacman_points % 2) {
272 if (pacman_rot == 0) {
273 xrectfill (pacman_x, pacman_y+11, pacman_x+3, pacman_y+20, 0);
274 xrectfill (pacman_x+4, pacman_y+13, pacman_x+7, pacman_y+18, 0);
275 xrectfill (pacman_x+8, pacman_y+15, pacman_x+11, pacman_y+16, 0);
276 } else if (pacman_rot == 1) {
277 xrectfill (pacman_x+29, pacman_y+11, pacman_x+32, pacman_y+20, 0);
278 xrectfill (pacman_x+25, pacman_y+13, pacman_x+28, pacman_y+18, 0);
279 xrectfill (pacman_x+21, pacman_y+15, pacman_x+24, pacman_y+16, 0);
280 } else if (pacman_rot == 2) {
281 xrectfill (pacman_x+11, pacman_y, pacman_x+20, pacman_y+3, 0);
282 xrectfill (pacman_x+13, pacman_y+4, pacman_x+18, pacman_y+7, 0);
283 xrectfill (pacman_x+15, pacman_y+8, pacman_x+16, pacman_y+11, 0);
284 } else if (pacman_rot == 3) {
285 xrectfill (pacman_x+11, pacman_y+29, pacman_x+20, pacman_y+32, 0);
286 xrectfill (pacman_x+13, pacman_y+25, pacman_x+18, pacman_y+28, 0);
287 xrectfill (pacman_x+15, pacman_y+21, pacman_x+16, pacman_y+24, 0);
292 int draw ()
294 draw_pacman ();
295 draw_level ();
296 draw_beasts ();
298 char buf_pts[5];
299 itoa (pacman_points, buf_pts, 10);
301 xtext_puts (20, 585, ~0, "Points:");
302 xtext_puts (80, 585, ~0, buf_pts);
304 itoa (pacman_maxpoints, buf_pts, 10);
306 xtext_puts (100, 585, ~0, "/");
307 xtext_puts (110, 585, ~0, buf_pts);
309 itoa (level_num, buf_pts, 10);
311 xtext_puts (200, 585, ~0, "Level:");
312 xtext_puts (250, 585, ~0, buf_pts);
314 return 1;
317 /** UPDATE **/
318 void level_next ()
320 level_num ++;
322 beasts_count ++;
324 pacman_points = 0;
326 unsigned char x;
327 unsigned char y;
328 unsigned char i = 0;
330 for (x = 0; x < 25; x ++) {
331 for (y = 0; y < 18; y ++) {
332 if (level_data[x + y * 26] == '3') {
333 if (i >= beasts_count)
334 continue;
336 beasts[i].x = x * 32;
337 beasts[i].y = y * 32;
338 beasts[i].rot = 0;
340 i ++;
341 } else
342 if (level_data[x + y * 26] == '2')
343 level_data[x + y * 26] = '0';
348 void level_gameover ()
350 level_num = 1;
352 beasts_count = 1;
354 pacman_points = 0;
356 unsigned char x;
357 unsigned char y;
358 unsigned char i = 0;
360 for (x = 0; x < 25; x ++) {
361 for (y = 0; y < 18; y ++) {
362 if (level_data[x + y * 26] == '3') {
363 if (i >= beasts_count)
364 continue;
366 beasts[i].x = x * 32;
367 beasts[i].y = y * 32;
368 beasts[i].rot = 0;
370 i ++;
371 } else
372 if (level_data[x + y * 26] == '2')
373 level_data[x + y * 26] = '0';
378 void beast_stop (unsigned char i)
380 if (beasts[i].rot == 0) {
381 beasts[i].x ++;
382 } else if (beasts[i].rot == 1) {
383 beasts[i].x -= 2;
384 } else if (beasts[i].rot == 2) {
385 beasts[i].y ++;
386 } else if (beasts[i].rot == 3) {
387 beasts[i].y -= 2;
391 void pacman_stop ()
393 if (pacman_rot == 0) {
394 pacman_x ++;
395 } else if (pacman_rot == 1) {
396 pacman_x -= 2;
397 } else if (pacman_rot == 2) {
398 pacman_y ++;
399 } else if (pacman_rot == 3) {
400 pacman_y -= 2;
403 pacman_rot = -1;
406 int update_pacman ()
408 if (scancode == ARROWLEFT)
409 pacman_rotn = 0;
410 else if (scancode == ARROWRIGHT)
411 pacman_rotn = 1;
412 else if (scancode == ARROWUP)
413 pacman_rotn = 2;
414 else if (scancode == ARROWDOWN)
415 pacman_rotn = 3;
417 if (pacman_rot == 0) {
418 if (pacman_x > 0)
419 pacman_x --;
420 } else if (pacman_rot == 1) {
421 if (pacman_x < 800-32)
422 pacman_x ++;
423 } else if (pacman_rot == 2) {
424 if (pacman_y > 0)
425 pacman_y --;
426 } else if (pacman_rot == 3) {
427 if (pacman_y < 600-32)
428 pacman_y ++;
431 if (!(pacman_x % 32) && !(pacman_y % 32))
432 pacman_rot = pacman_rotn;
434 return 1;
438 int update_beasts ()
440 unsigned char i;
441 for (i = 0; i < beasts_count; i ++) {
442 if (beasts[i].rot == 0) {
443 if (beasts[i].x > 0)
444 beasts[i].x --;
445 } else if (beasts[i].rot == 1) {
446 if (beasts[i].x < 800-32)
447 beasts[i].x ++;
448 } else if (beasts[i].rot == 2) {
449 if (beasts[i].y > 0)
450 beasts[i].y --;
451 } else if (beasts[i].rot == 3) {
452 if (beasts[i].y < 600-32)
453 beasts[i].y ++;
456 /* collision with pacman and beasts */
457 if (beasts[i].x/32 == pacman_x/32 && beasts[i].y/32 == pacman_y/32)
458 level_gameover ();
461 return 1;
465 int update ()
467 scancode = getkey ();
469 if (scancode == ESC)
470 return -1;
472 /* Flip double buffer - show image */
473 xfbswap ();
475 /* collision */
476 unsigned char x;
477 unsigned char y;
479 for (x = 0; x < 25; x ++) {
480 for (y = 0; y < 18; y ++) {
481 if (level_data[x + y * 26] == '1') {
482 if (pacman_x > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
483 pacman_stop ();
484 else if (pacman_x+31 > x*32 && pacman_y+31 > y*32 && pacman_x+31 < x*32+32 && pacman_y+31 < y*32+32)
485 pacman_stop ();
486 else if (pacman_x+31 > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
487 pacman_stop ();
488 else if (pacman_x > x*32 && pacman_y+31 > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
489 pacman_stop ();
491 unsigned char i;
492 for (i = 0; i < beasts_count; i ++) {
493 if (beasts[i].x > 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+31 > x*32 && beasts[i].y+31 > y*32 && beasts[i].x+31 < x*32+32 && beasts[i].y+31 < y*32+32) {
497 beast_stop (i);
498 beasts[i].rot = rand () % 4;
499 } 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) {
500 beast_stop (i);
501 beasts[i].rot = rand () % 4;
502 } 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) {
503 beast_stop (i);
504 beasts[i].rot = rand () % 4;
507 } else
508 if (level_data[x + y * 26] == '0') {
509 unsigned p = 0;
511 if (pacman_x > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
512 p = 1;
513 if (pacman_x+31 > x*32 && pacman_y+31 > y*32 && pacman_x+31 < x*32+32 && pacman_y+31 < y*32+32)
514 p = 1;
515 if (pacman_x+31 > x*32 && pacman_y > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
516 p = 1;
517 if (pacman_x > x*32 && pacman_y+31 > y*32 && pacman_x < x*32+32 && pacman_y < y*32+32)
518 p = 1;
520 if (p) {
521 pacman_points ++;
522 level_data[x + y * 26] = '2';
528 update_pacman ();
529 update_beasts ();
531 if (pacman_points == pacman_maxpoints)
532 level_next ();
534 return 1;
537 int main (int argc, char **argv)
539 init ();
541 while (1) {
542 draw ();
544 if (update () == -1)
545 break;
548 free (img_pacman);
549 free (img_wall);
550 free (img_beast);
552 /* Go back to textual mode */
553 xexit ();
555 /* Exit app */
556 return 0;