when changing settings from the Talk and Voice window also update the main widgets...
[Rockbox.git] / apps / plugins / superdom.c
blob794ea9e8f0d52fa3d784cd5491651bd024d39353
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Will Robertson
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
20 PLUGIN_HEADER
21 static struct plugin_api* rb;
23 extern const fb_data superdom_boarditems[];
24 char buf[255];
26 #define COLOUR_DARK 0
27 #define COLOUR_LIGHT 1
29 #define MARGIN 5
31 #if LCD_WIDTH > LCD_HEIGHT
32 #define BOX_WIDTH ((LCD_WIDTH-(MARGIN*2))/10)
33 #define BOX_HEIGHT ((BOX_WIDTH*2)/3)
35 #else
36 #define BOX_HEIGHT ((LCD_HEIGHT-(MARGIN*2)-15)/10)
37 #define BOX_WIDTH ((BOX_HEIGHT*2)/3)
39 #endif
41 #if LCD_WIDTH == 220 && LCD_HEIGHT == 176
42 #define NUM_BOX_HEIGHT 25
43 #define NUM_BOX_WIDTH 30
44 #define STRIDE 14
45 #define ICON_HEIGHT 7
46 #define ICON_WIDTH 7
48 #elif (LCD_WIDTH == 160 && LCD_HEIGHT == 128) || \
49 (LCD_WIDTH == 176 && LCD_HEIGHT == 132) || \
50 (LCD_WIDTH == 176 && LCD_HEIGHT == 220)
51 #define NUM_BOX_HEIGHT 20
52 #define NUM_BOX_WIDTH 24
53 #define STRIDE 8
54 #define ICON_HEIGHT 4
55 #define ICON_WIDTH 4
57 #elif (LCD_WIDTH == 320 && LCD_HEIGHT == 240)
58 #define NUM_BOX_HEIGHT 25
59 #define NUM_BOX_WIDTH 30
60 #define STRIDE 20
61 #define ICON_HEIGHT 10
62 #define ICON_WIDTH 10
64 #elif (LCD_WIDTH == 240 && LCD_HEIGHT == 320)
65 #define NUM_BOX_HEIGHT 25
66 #define NUM_BOX_WIDTH 30
67 #define STRIDE 18
68 #define ICON_HEIGHT 9
69 #define ICON_WIDTH 9
71 #endif
73 #define NUM_MARGIN_X (LCD_WIDTH-3*NUM_BOX_WIDTH)/2
74 #define NUM_MARGIN_Y (LCD_HEIGHT-4*NUM_BOX_HEIGHT)/2
76 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
77 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
78 #define SUPERDOM_OK BUTTON_SELECT
79 #define SUPERDOM_CANCEL BUTTON_MENU
80 #define SUPERDOM_LEFT BUTTON_LEFT
81 #define SUPERDOM_RIGHT BUTTON_RIGHT
82 #define IPOD_STYLE
84 #elif CONFIG_KEYPAD == IRIVER_H300_PAD || CONFIG_KEYPAD == IRIVER_H100_PAD
85 #define SUPERDOM_OK BUTTON_SELECT
86 #define SUPERDOM_LEFT BUTTON_LEFT
87 #define SUPERDOM_RIGHT BUTTON_RIGHT
88 #define SUPERDOM_UP BUTTON_UP
89 #define SUPERDOM_DOWN BUTTON_DOWN
90 #define SUPERDOM_CANCEL BUTTON_OFF
92 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
93 #define SUPERDOM_OK BUTTON_SELECT
94 #define SUPERDOM_LEFT BUTTON_LEFT
95 #define SUPERDOM_RIGHT BUTTON_RIGHT
96 #define SUPERDOM_UP BUTTON_UP
97 #define SUPERDOM_DOWN BUTTON_DOWN
98 #define SUPERDOM_CANCEL BUTTON_REC
100 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
101 #define SUPERDOM_OK BUTTON_RIGHT
102 #define SUPERDOM_UP BUTTON_SCROLL_UP
103 #define SUPERDOM_DOWN BUTTON_SCROLL_DOWN
104 #define SUPERDOM_CANCEL BUTTON_LEFT
106 #elif CONFIG_KEYPAD == GIGABEAT_PAD
107 #define SUPERDOM_OK BUTTON_SELECT
108 #define SUPERDOM_UP BUTTON_UP
109 #define SUPERDOM_DOWN BUTTON_DOWN
110 #define SUPERDOM_LEFT BUTTON_LEFT
111 #define SUPERDOM_RIGHT BUTTON_RIGHT
112 #define SUPERDOM_CANCEL BUTTON_POWER
114 #elif CONFIG_KEYPAD == SANSA_E200_PAD
115 #define SUPERDOM_OK BUTTON_SELECT
116 #define SUPERDOM_UP BUTTON_SCROLL_BACK
117 #define SUPERDOM_DOWN BUTTON_SCROLL_FWD
118 #define SUPERDOM_LEFT BUTTON_LEFT
119 #define SUPERDOM_RIGHT BUTTON_RIGHT
120 #define SUPERDOM_CANCEL BUTTON_POWER
122 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
123 #define SUPERDOM_OK BUTTON_SELECT
124 #define SUPERDOM_UP BUTTON_UP
125 #define SUPERDOM_DOWN BUTTON_DOWN
126 #define SUPERDOM_LEFT BUTTON_LEFT
127 #define SUPERDOM_RIGHT BUTTON_RIGHT
128 #define SUPERDOM_CANCEL BUTTON_BACK
130 #endif
132 #define SUPERDOM_QUIT 23
134 void gen_interest(void);
135 int production_menu(void);
136 void init_resources(void);
137 int select_square(void);
138 void update_score(void);
139 void gen_resources(void);
140 void draw_cursor(void);
141 int calc_strength(bool colour, int x, int y);
142 void draw_board(void);
144 struct tile{
145 signed int colour; /* -1 = Unset */
146 bool tank;
147 bool plane;
148 bool nuke;
149 bool ind;
150 bool farm;
151 int men;
154 struct resources {
155 int cash;
156 int food;
157 int farms;
158 int inds;
159 int men;
160 int tanks;
161 int planes;
162 int nukes;
163 int bank;
164 int moves;
167 struct settings {
168 int compstartfarms;
169 int compstartinds;
170 int humanstartfarms;
171 int humanstartinds;
172 int startcash;
173 int startfood;
174 int movesperturn;
175 } superdom_settings;
177 struct resources humanres;
178 struct resources compres;
180 struct cursor{
181 int x;
182 int y;
183 } cursor;
185 struct tile board[12][12];
187 void init_board(void) {
188 rb->srand(*rb->current_tick);
189 int i,j;
190 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
191 for(j=0;j<12;j++) {
192 if((i<1)||(j<1)||(i>10)||(j>10))
193 board[i][j].colour = -1; /* Unset */
194 else
195 board[i][j].colour = rb->rand()%2;
196 board[i][j].tank = false;
197 board[i][j].plane = false;
198 board[i][j].nuke = false;
199 board[i][j].ind = false;
200 board[i][j].farm = false;
201 board[i][j].men = 0;
205 while(compres.farms < superdom_settings.compstartfarms) {
206 i = rb->rand()%10 + 1;
207 j = rb->rand()%10 + 1;
208 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
209 board[i][j].farm = true;
210 compres.farms++;
211 break;
214 while(compres.inds < superdom_settings.compstartinds) {
215 i = rb->rand()%10 + 1;
216 j = rb->rand()%10 + 1;
217 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
218 board[i][j].ind = true;
219 compres.inds++;
220 break;
223 while(humanres.farms<superdom_settings.humanstartfarms) {
224 i = rb->rand()%10 + 1;
225 j = rb->rand()%10 + 1;
226 if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
227 board[i][j].farm = true;
228 humanres.farms++;
231 while(humanres.inds<superdom_settings.humanstartfarms) {
232 i = rb->rand()%10 + 1;
233 j = rb->rand()%10 + 1;
234 if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) {
235 board[i][j].ind = true;
236 humanres.inds++;
241 void draw_board(void) {
242 rb->lcd_clear_display();
243 int i,j;
244 for(i=1;i<11;i++) {
245 for(j=1;j<11;j++) {
246 if(board[i][j].colour == COLOUR_DARK) {
247 rb->lcd_set_foreground(LCD_DARKGRAY);
248 } else {
249 rb->lcd_set_foreground(LCD_LIGHTGRAY);
251 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
252 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
253 BOX_HEIGHT);
254 #if LCD_DEPTH != 16
255 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
256 #endif
257 if(board[i][j].ind) {
258 #if (LCD_DEPTH == 16)
259 rb->lcd_bitmap_transparent_part(superdom_boarditems,
260 #else
261 rb->lcd_mono_bitmap_part(superdom_boarditems,
262 #endif
263 board[i][j].colour?ICON_WIDTH:0, 0, STRIDE,
264 #if LCD_WIDTH > LCD_HEIGHT
265 MARGIN+(BOX_WIDTH*(i-1))+1,
266 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
267 #else
268 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
269 MARGIN+(BOX_HEIGHT*(j-1))+1,
270 #endif
271 ICON_WIDTH, ICON_HEIGHT);
273 if(board[i][j].farm) {
274 #if (LCD_DEPTH == 16)
275 rb->lcd_bitmap_transparent_part(superdom_boarditems,
276 #else
277 rb->lcd_mono_bitmap_part(superdom_boarditems,
278 #endif
279 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
280 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
281 MARGIN+(BOX_HEIGHT*(j-1))+1,
282 ICON_WIDTH, ICON_HEIGHT);
284 if(board[i][j].tank) {
285 #if (LCD_DEPTH == 16)
286 rb->lcd_bitmap_transparent_part(superdom_boarditems,
287 #else
288 rb->lcd_mono_bitmap_part(superdom_boarditems,
289 #endif
290 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
291 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
292 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
293 ICON_WIDTH, ICON_HEIGHT);
295 if(board[i][j].men) {
296 #if (LCD_DEPTH == 16)
297 rb->lcd_bitmap_transparent_part(superdom_boarditems,
298 #else
299 rb->lcd_mono_bitmap_part(superdom_boarditems,
300 #endif
301 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
302 #if LCD_WIDTH > LCD_HEIGHT
303 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
304 MARGIN+(BOX_HEIGHT*(j-1))+1,
305 #else
306 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
307 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
308 #endif
309 ICON_WIDTH, ICON_HEIGHT);
311 if(board[i][j].plane) {
312 #if (LCD_DEPTH == 16)
313 rb->lcd_bitmap_transparent_part(superdom_boarditems,
314 #else
315 rb->lcd_mono_bitmap_part(superdom_boarditems,
316 #endif
317 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
318 #if LCD_WIDTH > LCD_HEIGHT
319 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
320 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
321 #else
322 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
323 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
324 #endif
325 ICON_WIDTH, ICON_HEIGHT);
327 if(board[i][j].nuke) {
328 #if (LCD_DEPTH == 16)
329 rb->lcd_bitmap_transparent_part(superdom_boarditems,
330 #else
331 rb->lcd_mono_bitmap_part(superdom_boarditems,
332 #endif
333 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
334 #if LCD_WIDTH > LCD_HEIGHT
335 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
336 MARGIN+(BOX_HEIGHT*(j-1))+1,
337 #else
338 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
339 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
340 #endif
341 ICON_WIDTH, ICON_HEIGHT);
343 #if LCD_DEPTH != 16
344 rb->lcd_set_drawmode(DRMODE_SOLID);
345 #endif
348 rb->lcd_set_foreground(LCD_BLACK);
349 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
350 rb->lcd_drawline(MARGIN, MARGIN+(BOX_HEIGHT*i), MARGIN+(BOX_WIDTH*10),
351 MARGIN+(BOX_HEIGHT*i));
353 for(i=0;i<=10;i++) { /* Draw Vertical lines */
354 rb->lcd_drawline(MARGIN+(BOX_WIDTH*i),MARGIN, MARGIN+(BOX_WIDTH*i),
355 MARGIN+(BOX_HEIGHT*10));
357 rb->lcd_update();
360 int calc_strength(bool colour, int x, int y) {
361 int a, b, score=0;
362 for (a = -1; a < 2; a++){
363 for (b = -1; b < 2; b++){
364 if (b == 0){
365 if(board[x + a][y].colour == colour)
366 score+=10;
367 if(((board[x + a][y].colour == colour) && board[x + a][y].tank) || ((board[x + a][y].colour == colour) && board[x + a][y].farm))
368 score+=30;
369 if(((board[x + a][y].colour == colour) && board[x + a][y].plane) || ((board[x + a][y].colour == colour) && board[x + a][y].ind))
370 score+=40;
371 if((board[x + a][y].colour == colour) && board[x + a][y].nuke)
372 score+=20;
373 if((board[x + a][y].colour == colour) && board[x + a][y].men)
374 score+=(board[x + a][y].men*133/1000);
375 } else if (a == 0){
376 if(board[x][y + b].colour == colour)
377 score+=10;
378 if(((board[x][y + b].colour == colour) && board[x][y + b].tank) || ((board[x][y + b].colour == colour) && board[x][y + b].farm))
379 score+=30;
380 if(((board[x][y + b].colour == colour) && board[x][y + b].plane) || ((board[x][y + b].colour == colour) && board[x][y + b].ind))
381 score+=40;
382 if((board[x][y + b].colour == colour) && board[x][y + b].nuke)
383 score+=20;
384 if((board[x][y + b].colour == colour) && board[x][y + b].men)
385 score+=(board[x][y + b].men*133/1000);
389 return score;
392 void gen_interest(void) {
393 /* Interest should be around 10% */
394 rb->srand(*rb->current_tick);
395 int interest = 7+rb->rand()%6;
396 humanres.bank = humanres.bank+(interest*humanres.bank/100);
399 void draw_cursor(void) {
400 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
401 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
402 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
403 rb->lcd_set_drawmode(DRMODE_SOLID);
404 rb->lcd_update();
407 void gen_resources(void) {
408 gen_interest();
409 int inccash = 0;
410 int incfood = 0;
411 int i;
412 rb->srand(*rb->current_tick);
413 /* Generate Human's resources */
414 for(i=0;i<humanres.inds;i++) {
415 inccash += (300+rb->rand()%200);
417 for(i=0;i<humanres.farms;i++) {
418 incfood += (200+rb->rand()%200);
420 if(inccash/humanres.inds > 450) {
421 if(incfood/humanres.farms > 350) {
422 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
423 " is up this year!");
424 } else {
425 rb->splash(HZ*2, "Factories working at maximum efficiency,"
426 " cash production up this year!");
428 } else if((inccash/humanres.inds>350)&&(inccash/humanres.inds<=450)) {
429 if(incfood/humanres.farms > 350) {
430 rb->splash(HZ*2, "Record crop harvest this year!");
431 } else if((incfood/humanres.farms > 250) &&
432 (incfood/humanres.farms <= 350)) {
433 rb->splash(HZ*2, "Production continues as normal");
434 } else {
435 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
436 " output this year");
438 } else {
439 if(incfood/humanres.farms > 350) {
440 rb->splash(HZ*2, "Record crop harvest this year!");
441 } else if((incfood/humanres.farms > 250) &&
442 (incfood/humanres.farms <= 350)) {
443 rb->splash(HZ*2, "Factory unions introduced. Industrial"
444 " production is down this year.");
445 } else {
446 rb->splash(HZ*2, "Internet created. All production is down"
447 " due to time wasted.");
450 humanres.cash += inccash;
451 humanres.food += incfood;
453 /* Generate Computer's resources */
454 inccash = 0;
455 incfood = 0;
456 for(i=0;i<compres.inds;i++) {
457 inccash += (300+rb->rand()%200);
459 for(i=0;i<compres.farms;i++) {
460 incfood += (200+rb->rand()%200);
462 compres.cash += inccash;
463 compres.food += incfood;
466 void update_score(void) {
467 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
468 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
469 rb->lcd_set_drawmode(DRMODE_SOLID);
470 rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
471 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)/10,
472 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)%10);
473 rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
474 rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
475 calc_strength(COLOUR_DARK, cursor.x, cursor.y)/10,
476 calc_strength(COLOUR_DARK, cursor.x, cursor.y)%10);
477 rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
480 int settings_menu_function(void) {
481 int selection = 0;
483 MENUITEM_STRINGLIST(settings_menu,"Super Domination Settings",NULL,
484 "Computer starting farms","Computer starting factories",
485 "Human starting farms","Human starting factories",
486 "Starting cash","Starting food","Moves per turn");
487 settings_menu:
488 selection=rb->do_menu(&settings_menu,&selection);
489 switch(selection) {
490 case 0:
491 rb->set_int("Computer starting farms", "", UNIT_INT,
492 &superdom_settings.compstartfarms, NULL,
493 1, 0, 5, NULL);
494 goto settings_menu;
495 break;
496 case 1:
497 rb->set_int("Computer starting factories", "", UNIT_INT,
498 &superdom_settings.compstartinds, NULL,
499 1, 0, 5, NULL);
500 goto settings_menu;
501 break;
502 case 2:
503 rb->set_int("Human starting farms", "", UNIT_INT,
504 &superdom_settings.humanstartfarms, NULL,
505 1, 0, 5, NULL);
506 goto settings_menu;
507 break;
508 case 3:
509 superdom_settings.humanstartinds =
510 rb->set_int("Human starting factories", "", UNIT_INT,
511 &superdom_settings.humanstartinds, NULL,
512 1, 0, 5, NULL);
513 goto settings_menu;
514 break;
515 case 4:
516 rb->set_int("Starting cash", "", UNIT_INT,
517 &superdom_settings.startcash, NULL,
518 250, 0, 5000, NULL);
519 goto settings_menu;
520 break;
521 case 5:
522 rb->set_int("Starting food", "", UNIT_INT,
523 &superdom_settings.startfood, NULL,
524 250, 0, 5000, NULL);
525 goto settings_menu;
526 break;
527 case 6:
528 rb->set_int("Moves per turn", "", UNIT_INT,
529 &superdom_settings.movesperturn, NULL,
530 1, 1, 5, NULL);
531 goto settings_menu;
532 break;
533 case MENU_ATTACHED_USB:
534 return PLUGIN_USB_CONNECTED;
535 break;
537 return 0;
540 int do_help(void) {
541 int selection = 0;
543 MENUITEM_STRINGLIST(help_menu,"Help",NULL,"Super domination is a turn",
544 "based strategy game, where the aim is to overpower the",
545 "computer player by taking their territory.",
546 "Each year you are allocated an amount of cash and food,",
547 "depending on how many farms and factories you control."
548 "Use this cash and food to buy and feed your army.",
549 "Each tile has a strength, calculated by the ownership",
550 "of adjacent tiles, and the type and number of troops",
551 "on them.");
552 rb->do_menu(&help_menu,&selection);
553 switch(selection) {
554 case MENU_ATTACHED_USB:
555 return PLUGIN_USB_CONNECTED;
556 break;
558 return 0;
561 int menu(void) {
562 int selection = 0;
564 MENUITEM_STRINGLIST(main_menu,"Super Domination Menu",NULL,
565 "Play Super Domination","Settings","Help","Quit");
567 while(1) {
568 selection=rb->do_menu(&main_menu,&selection);
569 switch(selection) {
570 case 0:
571 return 0; /* start playing */
572 break;
573 case 1:
574 if(settings_menu_function()==PLUGIN_USB_CONNECTED)
575 return PLUGIN_USB_CONNECTED;
576 break;
577 case 2:
578 if(do_help()==PLUGIN_USB_CONNECTED)
579 return PLUGIN_USB_CONNECTED;
580 break;
581 default:
582 return 2; /* quit program */
583 break;
587 return 3;
590 int save_game(void) {
591 int fd;
592 char savepath[MAX_PATH];
594 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
595 if(rb->kbd_input(savepath, MAX_PATH)) {
596 DEBUGF("Keyboard input failed\n");
597 return -1;
600 fd = rb->open(savepath, O_WRONLY|O_CREAT);
601 DEBUGF("savepath: %s\n", savepath);
602 if(fd < 0) {
603 DEBUGF("Couldn't create/open file\n");
604 return -1;
607 rb->write(fd, "SSGv2", 5);
608 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
609 rb->write(fd, &humanres.food, sizeof(humanres.food));
610 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
611 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
612 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
613 rb->write(fd, &humanres.men, sizeof(humanres.men));
614 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
615 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
616 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
617 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
618 rb->write(fd, &compres.cash, sizeof(compres.cash));
619 rb->write(fd, &compres.food, sizeof(compres.food));
620 rb->write(fd, &compres.bank, sizeof(compres.bank));
621 rb->write(fd, &compres.planes, sizeof(compres.planes));
622 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
623 rb->write(fd, &compres.men, sizeof(compres.men));
624 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
625 rb->write(fd, &compres.inds, sizeof(compres.inds));
626 rb->write(fd, &compres.farms, sizeof(compres.farms));
627 rb->write(fd, &compres.moves, sizeof(compres.moves));
628 rb->write(fd, board, sizeof(board));
629 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
630 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
631 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
632 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
633 rb->write(fd, &superdom_settings.startcash, sizeof(int));
634 rb->write(fd, &superdom_settings.startfood, sizeof(int));
635 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
636 rb->close(fd);
637 return 0;
640 int ingame_menu(void) {
641 int selection = 0;
643 MENUITEM_STRINGLIST(ingame_menu,"Super Domination Menu",NULL,
644 "Return to game","Save Game", "Quit");
646 selection=rb->do_menu(&ingame_menu,&selection);
647 switch(selection) {
648 case 0:
649 return 0;
650 break;
651 case 1:
652 if(!save_game())
653 rb->splash(HZ, "Game saved");
654 else
655 rb->splash(HZ, "Error in save");
656 break;
657 case 2:
658 return SUPERDOM_QUIT;
659 break;
660 case MENU_ATTACHED_USB:
661 return PLUGIN_USB_CONNECTED;
662 break;
664 return 0;
667 int get_number(char* param, int* value) {
668 //int numbers[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
669 int numbers[3][3];
670 numbers[0][0] = 1;
671 numbers[0][1] = 2;
672 numbers[0][2] = 3;
673 numbers[1][0] = 4;
674 numbers[1][1] = 5;
675 numbers[1][2] = 6;
676 numbers[2][0] = 7;
677 numbers[2][1] = 8;
678 numbers[2][2] = 9;
679 rb->lcd_clear_display();
680 /* Draw a 3x4 grid */
681 int i,j,x=0,y=0;
682 for(i=0;i<=3;i++) { /* Vertical lines */
683 rb->lcd_drawline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
684 NUM_MARGIN_X+(NUM_BOX_WIDTH*i),
685 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
687 for(i=0;i<=4;i++) { /* Horizontal lines */
688 rb->lcd_drawline(NUM_MARGIN_X, NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT),
689 NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
690 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
692 int temp = 1;
693 for(i=0;i<3;i++) {
694 for(j=0;j<3;j++) {
695 rb->snprintf(buf, sizeof(buf), "%d", temp);
696 rb->lcd_putsxy(NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+10,
697 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+8, buf);
698 temp++;
701 rb->lcd_putsxy(NUM_MARGIN_X+5, NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "CLR");
702 rb->lcd_putsxy(NUM_MARGIN_X+NUM_BOX_WIDTH+10,
703 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "0");
704 rb->lcd_putsxy(NUM_MARGIN_X+2*NUM_BOX_WIDTH+8,
705 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "OK");
706 rb->snprintf(buf,sizeof(buf), "%d", *value);
707 rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
708 int height, width;
709 rb->lcd_getstringsize(param, &width, &height);
710 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
711 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
712 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
713 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y), NUM_BOX_WIDTH+1,
714 NUM_BOX_HEIGHT+1);
715 rb->lcd_set_drawmode(DRMODE_SOLID);
716 int button = 0;
717 rb->lcd_update();
718 while(1) {
719 button = rb->button_get(true);
720 switch(button) {
721 case SUPERDOM_OK:
722 *value *= 10;
723 if(y!=3) {
724 *value += numbers[y][x];
725 } else if(y==3 && x==0) {
726 *value /= 100;
727 } else if(y==3 && x==2) {
728 *value /= 10;
729 return 0;
731 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
732 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
733 LCD_WIDTH, 30);
734 rb->lcd_set_drawmode(DRMODE_SOLID);
735 rb->snprintf(buf,sizeof(buf), "%d", *value);
736 rb->lcd_putsxy(NUM_MARGIN_X+10,
737 NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
738 break;
739 case SUPERDOM_CANCEL:
740 return 0;
741 break;
742 #if CONFIG_KEYPAD != IRIVER_H10_PAD
743 case SUPERDOM_LEFT:
744 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
745 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
746 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
747 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
748 rb->lcd_set_drawmode(DRMODE_SOLID);
749 if(x==0) {
750 #ifdef IPOD_STYLE
751 if(y>0)
752 y--;
753 else
754 y=3;
755 #endif
756 x=2;
757 } else {
758 x--;
760 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
761 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
762 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
763 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
764 rb->lcd_set_drawmode(DRMODE_SOLID);
765 break;
766 case SUPERDOM_RIGHT:
767 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
768 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
769 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
770 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
771 rb->lcd_set_drawmode(DRMODE_SOLID);
772 if(x==2) {
773 #ifdef IPOD_STYLE
774 if(y==3)
775 y=0;
776 else
777 y++;
778 #endif
779 x=0;
780 } else {
781 x++;
783 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
784 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
785 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
786 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
787 rb->lcd_set_drawmode(DRMODE_SOLID);
788 break;
789 #endif
790 #ifndef IPOD_STYLE
791 case SUPERDOM_UP:
792 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
793 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
794 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
795 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
796 rb->lcd_set_drawmode(DRMODE_SOLID);
797 if(y==0) {
798 #if CONFIG_KEYPAD == IRIVER_H10_PAD
799 if(x > 0)
800 x--;
801 else
802 x=2;
803 #endif
804 y=3;
805 } else {
806 y--;
808 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
809 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
810 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
811 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
812 rb->lcd_set_drawmode(DRMODE_SOLID);
813 break;
814 case SUPERDOM_DOWN:
815 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
816 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
817 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
818 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
819 rb->lcd_set_drawmode(DRMODE_SOLID);
820 if(y==3) {
821 #if CONFIG_KEYPAD == IRIVER_H10_PAD
822 if(x < 2)
823 x++;
824 else
825 x=0;
826 #endif
827 y=0;
828 } else {
829 y++;
831 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
832 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
833 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
834 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
835 rb->lcd_set_drawmode(DRMODE_SOLID);
836 break;
837 #endif
838 default:
839 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
841 return PLUGIN_USB_CONNECTED;
843 break;
845 rb->lcd_update();
847 return 0;
850 int buy_resources_menu(void) {
851 int selection,tempmenu,nummen;
853 MENUITEM_STRINGLIST(res_menu, "Buy Resources", NULL, "Buy men ($1)",
854 "Buy tank ($300)", "Buy plane ($600)", "Buy Farm ($1150)",
855 "Buy Factory ($1300)", "Buy Nuke ($2000)",
856 "Finish buying", "Game menu");
858 resources_menu:
859 selection=rb->do_menu(&res_menu,&selection);
860 switch(selection) {
861 case 0:
862 nummen = 0;
863 if(get_number("How many men would you like?", &nummen)
864 == PLUGIN_USB_CONNECTED)
865 return PLUGIN_USB_CONNECTED;
866 if(humanres.cash>=nummen) {
867 rb->splash(HZ, "Where do you want to place them?");
868 tempmenu = select_square();
869 switch(tempmenu) {
870 case 0:
871 rb->splash(HZ, "Cancelled");
872 break;
873 case 2:
874 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
875 humanres.men += nummen;
876 board[cursor.x][cursor.y].men += nummen;
877 humanres.cash -= nummen;
878 } else {
879 rb->splash(HZ,"Can't place men on enemy territory");
881 break;
882 case PLUGIN_USB_CONNECTED:
883 return PLUGIN_USB_CONNECTED;
884 break;
886 } else {
887 rb->splash(HZ, "Not enough money!");
889 goto resources_menu;
890 break;
891 case 1:
892 if(humanres.cash>=300) {
893 rb->splash(HZ, "Where do you want to place the tank?");
894 tempmenu = select_square();
895 switch(tempmenu) {
896 case 0:
897 rb->splash(HZ, "Cancelled");
898 goto resources_menu;
899 break;
900 case PLUGIN_USB_CONNECTED:
901 return PLUGIN_USB_CONNECTED;
902 break;
904 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
905 if(board[cursor.x][cursor.y].tank) {
906 rb->splash(HZ, "There is already a tank there");
907 } else {
908 board[cursor.x][cursor.y].tank = true;
909 humanres.cash -= 300;
910 humanres.tanks++;
912 } else {
913 rb->splash(HZ, "Can't place men on enemy territory");
915 } else {
916 rb->splash(HZ, "Not enough money!");
918 goto resources_menu;
919 break;
920 case 2:
921 if(humanres.cash>=600) {
922 rb->splash(HZ, "Where do you want to place the plane?");
923 tempmenu = select_square();
924 switch(tempmenu) {
925 case 0:
926 rb->splash(HZ, "Cancelled");
927 goto resources_menu;
928 break;
929 case PLUGIN_USB_CONNECTED:
930 return PLUGIN_USB_CONNECTED;
931 break;
933 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
934 if(board[cursor.x][cursor.y].plane) {
935 rb->splash(HZ, "There is already a plane there");
936 } else {
937 board[cursor.x][cursor.y].plane = true;
938 humanres.cash -= 600;
939 humanres.planes++;
941 } else {
942 rb->splash(HZ, "Can't place men on enemy territory");
944 } else {
945 rb->splash(HZ, "Not enough money!");
947 goto resources_menu;
948 break;
949 case 3:
950 if(humanres.cash>=1150) {
951 rb->splash(HZ, "Where do you want to place the farm?");
952 tempmenu = select_square();
953 switch(tempmenu) {
954 case 0:
955 rb->splash(HZ, "Cancelled");
956 goto resources_menu;
957 break;
958 case PLUGIN_USB_CONNECTED:
959 return PLUGIN_USB_CONNECTED;
960 break;
962 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
963 if(board[cursor.x][cursor.y].farm) {
964 rb->splash(HZ, "There is already a farm there");
965 } else {
966 board[cursor.x][cursor.y].farm = true;
967 humanres.cash -= 1150;
968 humanres.farms++;
970 } else {
971 rb->splash(HZ, "Can't build on enemy territory");
973 } else {
974 rb->splash(HZ, "Not enough money!");
976 goto resources_menu;
977 break;
978 case 4:
979 if(humanres.cash>=1300) {
980 rb->splash(HZ, "Where do you want to place the industrial"
981 " plant?");
982 tempmenu = select_square();
983 switch(tempmenu) {
984 case 0:
985 rb->splash(HZ, "Cancelled");
986 goto resources_menu;
987 break;
988 case PLUGIN_USB_CONNECTED:
989 return PLUGIN_USB_CONNECTED;
990 break;
992 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
993 if(board[cursor.x][cursor.y].ind) {
994 rb->splash(HZ, "There is already an industrial"
995 " plant there");
996 } else {
997 board[cursor.x][cursor.y].ind = true;
998 humanres.cash -= 1300;
999 humanres.inds++;
1001 } else {
1002 rb->splash(HZ, "Can't build on enemy territory");
1004 } else {
1005 rb->splash(HZ, "Not enough money!");
1007 goto resources_menu;
1008 break;
1009 case 5:
1010 if(humanres.cash>=2000) {
1011 rb->splash(HZ, "Where do you want to place the nuke?");
1012 tempmenu = select_square();
1013 switch(tempmenu) {
1014 case 0:
1015 rb->splash(HZ, "Cancelled");
1016 goto resources_menu;
1017 break;
1018 case PLUGIN_USB_CONNECTED:
1019 return PLUGIN_USB_CONNECTED;
1020 break;
1022 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1023 if(board[cursor.x][cursor.y].nuke) {
1024 rb->splash(HZ, "There is already a nuke there");
1025 } else {
1026 board[cursor.x][cursor.y].nuke = true;
1027 humanres.cash -= 2000;
1028 humanres.nukes++;
1030 } else {
1031 rb->splash(HZ, "Can't place a nuke on enemy territory");
1033 } else {
1034 rb->splash(HZ, "Not enough money!");
1036 goto resources_menu;
1037 break;
1038 case 6:
1039 return 0;
1040 break;
1041 case MENU_ATTACHED_USB:
1042 return PLUGIN_USB_CONNECTED;
1043 break;
1045 return 0;
1048 int move_unit(void) {
1049 int selection, nummen;
1050 struct cursor from;
1052 MENUITEM_STRINGLIST(move_unit_menu, "Move unit", NULL, "Move men",
1053 "Move tank", "Move plane");
1054 selection=rb->do_menu(&move_unit_menu,&selection);
1055 switch(selection) {
1056 case 0:
1057 rb->splash(HZ, "Select where to move troops from");
1058 if(select_square() == PLUGIN_USB_CONNECTED)
1059 return PLUGIN_USB_CONNECTED;
1060 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1061 if(board[cursor.x][cursor.y].men) {
1062 from.x = cursor.x;
1063 from.y = cursor.y;
1064 nummen = board[from.x][from.y].men;
1065 if(get_number("How many men do you want to move?",
1066 &nummen) == PLUGIN_USB_CONNECTED)
1067 return PLUGIN_USB_CONNECTED;
1068 if(nummen > board[from.x][from.y].men) {
1069 rb->splash(HZ, "You don't have that many troops.");
1070 } else {
1071 rb->splash(HZ,"Select where to move the troops to");
1072 if(select_square() == PLUGIN_USB_CONNECTED)
1073 return PLUGIN_USB_CONNECTED;
1074 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT) &&
1075 (abs(cursor.x - from.x) <= 1) &&
1076 abs(cursor.y - from.y) <= 1) {
1077 board[from.x][from.y].men -= nummen;
1078 board[cursor.x][cursor.y].men += nummen;
1079 humanres.moves--;
1080 return 0;
1083 } else {
1084 rb->splash(HZ, "You don't have any troops there");
1086 } else {
1087 rb->splash(HZ, "Can't move enemy troops");
1089 break;
1090 case 1:
1091 rb->splash(HZ, "Select where you want to move the tank from");
1092 if(select_square() == PLUGIN_USB_CONNECTED)
1093 return PLUGIN_USB_CONNECTED;
1094 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1095 if(board[cursor.x][cursor.y].tank) {
1096 from.x = cursor.x;
1097 from.y = cursor.y;
1098 rb->splash(HZ, "Select where you want"
1099 " to move the tank to");
1100 if(select_square() == PLUGIN_USB_CONNECTED)
1101 return PLUGIN_USB_CONNECTED;
1102 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT)&&
1103 (abs(cursor.x-from.x) <= 1) &&
1104 (abs(cursor.y-from.y) <= 1)) {
1105 if(board[cursor.x][cursor.y].tank) {
1106 rb->splash(HZ, "There is already a tank there");
1107 } else {
1108 board[from.x][from.y].tank = false;
1109 board[cursor.x][cursor.y].tank = true;
1110 humanres.moves--;
1111 return 0;
1113 } else {
1114 rb->splash(HZ, "Invalid move");
1116 } else {
1117 rb->splash(HZ, "You don't have a tank there");
1119 } else {
1120 rb->splash(HZ, "That isn't your territory");
1122 break;
1123 case 2:
1124 rb->splash(HZ, "Select where you want"
1125 " to move the plane from");
1126 if(select_square() == PLUGIN_USB_CONNECTED)
1127 return PLUGIN_USB_CONNECTED;
1128 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1129 if(board[cursor.x][cursor.y].plane) {
1130 from.x = cursor.x;
1131 from.y = cursor.y;
1132 rb->splash(HZ, "Select where you want"
1133 " to move the plane to");
1134 if(select_square() == PLUGIN_USB_CONNECTED)
1135 return PLUGIN_USB_CONNECTED;
1136 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1137 if(board[cursor.x][cursor.y].plane) {
1138 rb->splash(HZ,"There is already a plane there");
1139 } else {
1140 board[from.x][from.y].plane = false;
1141 board[cursor.x][cursor.y].plane = true;
1142 humanres.moves--;
1143 return 0;
1145 } else {
1146 rb->splash(HZ, "Invalid move");
1148 } else {
1149 rb->splash(HZ, "You don't have a plane there");
1151 } else {
1152 rb->splash(HZ, "That isn't your territory");
1154 break;
1156 return 0;
1159 int movement_menu(void) {
1160 int selection, tempmenu;
1161 bool menu_quit = false;
1163 MENUITEM_STRINGLIST(move_menu, "Movement", NULL, "Move unit",
1164 "Buy additional moves ($100)", "Launch nuclear missile",
1165 "Check map", "Finish moving", "Game menu");
1167 while(!menu_quit) {
1168 selection=rb->do_menu(&move_menu,&selection);
1169 switch(selection) {
1170 case 0:
1171 if(humanres.moves) {
1172 if(move_unit()==PLUGIN_USB_CONNECTED)
1173 return PLUGIN_USB_CONNECTED;
1174 } else {
1175 rb->splash(HZ, "You have no more moves left."
1176 " You can buy more for $100 each.");
1178 break;
1179 case 1:
1180 if(humanres.cash > 100) {
1181 humanres.moves++;
1182 humanres.cash -= 100;
1183 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1184 humanres.moves);
1185 rb->splash(HZ, buf);
1187 break;
1188 case 2:
1189 if(humanres.nukes==0) {
1190 rb->splash(HZ, "You do not have any nukes to launch");
1191 } else {
1192 rb->splash(HZ, "Select place to launch nuke from");
1193 if(select_square() == PLUGIN_USB_CONNECTED) {
1194 return PLUGIN_USB_CONNECTED;
1196 if(board[cursor.x][cursor.y].nuke) {
1197 rb->splash(HZ, "Select place to target with nuke");
1198 if(select_square() == PLUGIN_USB_CONNECTED) {
1199 return PLUGIN_USB_CONNECTED;
1201 board[cursor.x][cursor.y].men = 0;
1202 board[cursor.x][cursor.y].tank = 0;
1203 board[cursor.x][cursor.y].plane = 0;
1204 board[cursor.x][cursor.y].ind = 0;
1205 board[cursor.x][cursor.y].nuke = 0;
1206 board[cursor.x][cursor.y].farm = 0;
1207 /* TODO: Fallout carried by wind */
1210 break;
1211 case 3:
1212 if(select_square() == PLUGIN_USB_CONNECTED)
1213 return PLUGIN_USB_CONNECTED;
1214 break;
1215 case 4:
1216 return 0;
1217 break;
1218 case 5:
1219 tempmenu = ingame_menu();
1220 switch(tempmenu) {
1221 case PLUGIN_USB_CONNECTED:
1222 return PLUGIN_USB_CONNECTED;
1223 break;
1224 case SUPERDOM_QUIT:
1225 return SUPERDOM_QUIT;
1226 break;
1228 break;
1229 case MENU_ATTACHED_USB:
1230 return PLUGIN_USB_CONNECTED;
1231 break;
1234 return 0;
1237 int show_inventory(void) {
1238 rb->lcd_clear_display();
1239 rb->lcd_puts(1, 0, "Inventory");
1240 char men[20], tanks[20], planes[20], inds[20], farms[20], nukes[20],
1241 cash[20], food[20], bank[20];
1242 rb->snprintf(men, sizeof(men), "Men: %d", humanres.men);
1243 rb->snprintf(tanks, sizeof(tanks), "Tanks: %d", humanres.tanks);
1244 rb->snprintf(planes, sizeof(planes), "Planes: %d", humanres.planes);
1245 rb->snprintf(inds, sizeof(inds), "Factories: %d", humanres.inds);
1246 rb->snprintf(farms, sizeof(farms), "Farms: %d", humanres.farms);
1247 rb->snprintf(nukes, sizeof(nukes), "Nukes: %d", humanres.nukes);
1248 rb->snprintf(cash, sizeof(cash), "Cash: %d", humanres.cash);
1249 rb->snprintf(food, sizeof(food), "Food: %d", humanres.food);
1250 rb->snprintf(bank, sizeof(bank), "Bank: %d", humanres.bank);
1251 rb->lcd_puts(2, 1, men);
1252 rb->lcd_puts(2, 2, tanks);
1253 rb->lcd_puts(2, 3, planes);
1254 rb->lcd_puts(2, 4, inds);
1255 rb->lcd_puts(2, 5, farms);
1256 rb->lcd_puts(2, 6, nukes);
1257 rb->lcd_puts(2, 7, cash);
1258 rb->lcd_puts(2, 8, food);
1259 rb->lcd_puts(2, 9, bank);
1260 rb->lcd_update();
1261 if(rb->default_event_handler(rb->button_get(true)) == SYS_USB_CONNECTED) {
1262 return PLUGIN_USB_CONNECTED;
1263 } else {
1264 return 0;
1268 int production_menu(void) {
1269 int selection, tempbank, tempmenu;
1271 MENUITEM_STRINGLIST(prod_menu, "Production", NULL, "Buy resources",
1272 "Show inventory", "Check map", "Invest money",
1273 "Withdraw money", "Finish turn", "Game menu");
1275 while(1) {
1276 selection=rb->do_menu(&prod_menu,&selection);
1277 switch(selection) {
1278 case 0:
1279 tempmenu = buy_resources_menu();
1280 switch(tempmenu) {
1281 case PLUGIN_USB_CONNECTED:
1282 return PLUGIN_USB_CONNECTED;
1283 break;
1284 case SUPERDOM_QUIT:
1285 return SUPERDOM_QUIT;
1286 break;
1288 break;
1289 case 1:
1290 tempmenu = show_inventory();
1291 switch(tempmenu) {
1292 case 0:
1293 break;
1294 case PLUGIN_USB_CONNECTED:
1295 return PLUGIN_USB_CONNECTED;
1296 break;
1298 break;
1299 case 2:
1300 tempmenu = select_square();
1301 switch(tempmenu) {
1302 case PLUGIN_USB_CONNECTED:
1303 return PLUGIN_USB_CONNECTED;
1304 break;
1305 case SUPERDOM_QUIT:
1306 return SUPERDOM_QUIT;
1307 break;
1308 case 0:
1309 break;
1311 break;
1312 case 3:
1313 tempbank = humanres.cash;
1314 if(get_number("How much do you want to invest?", &tempbank)
1315 == PLUGIN_USB_CONNECTED)
1316 return PLUGIN_USB_CONNECTED;
1317 if(tempbank>humanres.cash) {
1318 rb->splash(HZ, "You don't have that much cash to invest");
1319 } else {
1320 humanres.cash -= tempbank;
1321 humanres.bank += tempbank;
1323 break;
1324 case 4:
1325 tempbank = 0;
1326 if(get_number("How much do you want to withdraw?", &tempbank)
1327 == PLUGIN_USB_CONNECTED)
1328 return PLUGIN_USB_CONNECTED;
1329 if(tempbank>humanres.bank) {
1330 rb->splash(HZ, "You don't have that much cash to withdraw");
1331 } else {
1332 humanres.cash += tempbank;
1333 humanres.bank -= tempbank;
1335 break;
1336 case 5:
1337 return 0;
1338 break;
1339 case 6:
1340 tempmenu = ingame_menu();
1341 switch(tempmenu) {
1342 case PLUGIN_USB_CONNECTED:
1343 return PLUGIN_USB_CONNECTED;
1344 break;
1345 case SUPERDOM_QUIT:
1346 return SUPERDOM_QUIT;
1347 break;
1349 break;
1350 case MENU_ATTACHED_USB:
1351 return PLUGIN_USB_CONNECTED;
1352 break;
1355 return 0;
1358 void init_resources(void) {
1359 humanres.cash = superdom_settings.startcash;
1360 humanres.food = superdom_settings.startfood;
1361 humanres.tanks = 0;
1362 humanres.planes = 0;
1363 humanres.nukes = 0;
1364 humanres.inds = 0;
1365 humanres.farms = 0;
1366 humanres.men = 0;
1367 humanres.bank = 0;
1368 humanres.moves = 0;
1369 compres.cash = superdom_settings.startcash;
1370 compres.food = superdom_settings.startfood;
1371 compres.tanks = 0;
1372 compres.planes = 0;
1373 compres.nukes = 0;
1374 compres.inds = 0;
1375 compres.farms = 0;
1376 compres.men = 0;
1377 compres.bank = 0;
1378 compres.moves = 0;
1381 int select_square(void) {
1382 draw_board();
1383 draw_cursor();
1384 update_score();
1385 #if LCD_WIDTH >= 220
1386 rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
1387 rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
1388 rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
1389 rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
1390 #endif
1391 rb->lcd_update();
1392 int button = 0;
1393 while(1) {
1394 button = rb->button_get(true);
1395 switch(button) {
1396 case SUPERDOM_CANCEL:
1397 return 0;
1398 break;
1399 case SUPERDOM_OK:
1400 return 2;
1401 break;
1402 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1403 case SUPERDOM_LEFT:
1404 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1405 draw_cursor(); /* Deselect the current tile */
1406 if(cursor.x>1) {
1407 cursor.x--;
1408 } else {
1409 #ifdef IPOD_STYLE
1410 if(cursor.y>1)
1411 cursor.y--;
1412 else
1413 cursor.y = 10;
1414 #endif
1415 cursor.x = 10;
1417 update_score();
1418 draw_cursor();
1419 break;
1420 case SUPERDOM_RIGHT:
1421 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1422 draw_cursor(); /* Deselect the current tile */
1423 if(cursor.x<10) {
1424 cursor.x++;
1425 } else {
1426 #ifdef IPOD_STYLE
1427 if(cursor.y<10)
1428 cursor.y++;
1429 else
1430 cursor.y = 1;
1431 #endif
1432 cursor.x = 1;
1434 update_score();
1435 draw_cursor();
1436 break;
1437 #endif
1438 #ifndef IPOD_STYLE
1439 case SUPERDOM_UP:
1440 case (SUPERDOM_UP|BUTTON_REPEAT):
1441 draw_cursor(); /* Deselect the current tile */
1442 if(cursor.y>1) {
1443 cursor.y--;
1444 } else {
1445 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1446 if(cursor.x > 1)
1447 cursor.x--;
1448 else
1449 cursor.x = 10;
1450 #endif
1451 cursor.y = 10;
1453 update_score();
1454 draw_cursor();
1455 break;
1456 case SUPERDOM_DOWN:
1457 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1458 draw_cursor(); /* Deselect the current tile */
1459 if(cursor.y<10) {
1460 cursor.y++;
1461 } else {
1462 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1463 if(cursor.x < 10)
1464 cursor.x++;
1465 else
1466 cursor.x = 1;
1467 #endif
1468 cursor.y = 1;
1470 update_score();
1471 draw_cursor();
1472 break;
1473 #endif
1474 default:
1475 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1477 return PLUGIN_USB_CONNECTED;
1483 int killmen(bool human) {
1484 int menkilled,i,j;
1485 int percent;
1486 if(human) {
1487 percent = (humanres.food*1000)/humanres.men;
1488 humanres.food = 0;
1489 } else {
1490 percent = (compres.food*1000)/compres.men;
1491 compres.food = 0;
1493 menkilled = 0;
1494 for(i=1;i<12;i++) {
1495 for(j=1;j<12;j++) {
1496 if(board[i][j].colour == human) {
1497 menkilled += ((board[i][j].men * percent)/1000);
1498 board[i][j].men = (board[i][j].men * percent)/1000;
1503 if(human)
1504 humanres.men -= menkilled;
1505 else
1506 compres.men -= menkilled;
1507 return menkilled;
1510 int war_menu(void) {
1511 int selection, tempmenu;
1513 MENUITEM_STRINGLIST(wartime_menu, "War!", NULL,
1514 "Select territory to attack", "Finish turn", "Game menu");
1516 humanres.moves = superdom_settings.movesperturn;
1517 while(humanres.moves) {
1518 selection=rb->do_menu(&wartime_menu,&selection);
1519 switch(selection) {
1520 case 0:
1521 if(select_square() == PLUGIN_USB_CONNECTED)
1522 return PLUGIN_USB_CONNECTED;
1523 if(board[cursor.x][cursor.y].colour == COLOUR_DARK) {
1524 if(calc_strength(COLOUR_LIGHT, cursor.x,
1525 cursor.y) > calc_strength(COLOUR_DARK,
1526 cursor.x, cursor.y)) {
1527 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1528 board[cursor.x][cursor.y].tank = 0;
1529 board[cursor.x][cursor.y].men = 0;
1530 board[cursor.x][cursor.y].plane = 0;
1531 board[cursor.x][cursor.y].nuke = 0;
1532 draw_board();
1533 rb->sleep(HZ*2);
1534 humanres.moves--;
1535 } else if(calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)==
1536 calc_strength(COLOUR_DARK, cursor.x, cursor.y)) {
1537 if(rb->rand()%2) {
1538 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1539 board[cursor.x][cursor.y].tank = 0;
1540 board[cursor.x][cursor.y].men = 0;
1541 board[cursor.x][cursor.y].plane = 0;
1542 board[cursor.x][cursor.y].nuke = 0;
1543 draw_board();
1544 rb->sleep(HZ*2);
1545 humanres.moves--;
1546 } else {
1547 rb->splash(HZ, "Your troops were unable to"
1548 " overcome the enemy troops");
1549 humanres.moves--;
1551 } else {
1552 rb->splash(HZ, "Your troops were unable to overcome"
1553 " the enemy troops");
1554 humanres.moves--;
1556 } else {
1557 rb->splash(HZ, "You can't attack your own territory");
1559 break;
1560 case 1:
1561 return 0;
1562 break;
1563 case 2:
1564 tempmenu = ingame_menu();
1565 switch(tempmenu) {
1566 case PLUGIN_USB_CONNECTED:
1567 return PLUGIN_USB_CONNECTED;
1568 break;
1569 case SUPERDOM_QUIT:
1570 return SUPERDOM_QUIT;
1571 break;
1573 break;
1576 return 0;
1579 struct threat {
1580 int x;
1581 int y;
1582 int str_diff;
1585 bool place_adjacent(bool tank, int x, int y) {
1586 if(tank) {
1587 if(!board[x-1][y].tank && (board[x][y].colour==board[x-1][y].colour)) {
1588 compres.cash -= 300;
1589 board[x-1][y].tank = true;
1590 compres.tanks++;
1591 return 0;
1593 if(!board[x+1][y].tank && (board[x][y].colour==board[x+1][y].colour)) {
1594 compres.cash -= 300;
1595 board[x+1][y].tank = true;
1596 compres.tanks++;
1597 return 0;
1599 if(!board[x][y-1].tank && (board[x][y].colour==board[x][y-1].colour)) {
1600 compres.cash -= 300;
1601 board[x][y-1].tank = true;
1602 compres.tanks++;
1603 return 0;
1605 if(!board[x][y+1].tank && (board[x][y].colour==board[x][y+1].colour)) {
1606 compres.cash -= 300;
1607 board[x][y+1].tank = true;
1608 compres.tanks++;
1609 return 0;
1611 } else {
1612 if(!board[x-1][y].plane && (board[x][y].colour==board[x-1][y].colour)) {
1613 compres.cash -= 600;
1614 board[x-1][y].plane = true;
1615 compres.planes++;
1616 return 0;
1618 if(!board[x+1][y].plane && (board[x][y].colour==board[x+1][y].colour)) {
1619 compres.cash -= 600;
1620 board[x+1][y].plane = true;
1621 compres.planes++;
1622 return 0;
1624 if(!board[x][y-1].plane && (board[x][y].colour==board[x][y-1].colour)) {
1625 compres.cash -= 600;
1626 board[x][y-1].plane = true;
1627 compres.planes++;
1628 return 0;
1630 if(!board[x][y+1].plane && (board[x][y].colour==board[x][y+1].colour)) {
1631 compres.cash -= 600;
1632 board[x][y+1].plane = true;
1633 compres.planes++;
1634 return 0;
1637 return 1;
1640 bool has_adjacent(int x, int y) {
1641 if((board[x][y].colour == COLOUR_LIGHT) &&
1642 ((board[x-1][y].colour == COLOUR_DARK) ||
1643 (board[x+1][y].colour == COLOUR_DARK) ||
1644 (board[x][y+1].colour == COLOUR_DARK) ||
1645 (board[x][y-1].colour == COLOUR_DARK)))
1646 return 1;
1647 else
1648 return 0;
1651 void find_adjacent(int x, int y, int* adj_x, int* adj_y, bool* full) {
1652 /* Finds adjacent squares, returning squares without tanks on them
1653 * in preference to those with them */
1654 if(((board[x-1][y].tank && (board[x-1][y].colour == COLOUR_DARK)) ||
1655 board[x-1][y].colour != COLOUR_DARK) &&
1656 ((board[x+1][y].tank && (board[x+1][y].colour == COLOUR_DARK)) ||
1657 board[x+1][y].colour != COLOUR_DARK) &&
1658 ((board[x][y-1].tank && (board[x][y-1].colour == COLOUR_DARK)) ||
1659 board[x][y-1].colour != COLOUR_DARK) &&
1660 ((board[x][y+1].tank && (board[x][y+1].colour == COLOUR_DARK)) ||
1661 board[x][y+1].colour != COLOUR_DARK)) {
1662 *full = true;
1663 } else {
1664 *full = false;
1667 if(board[x-1][y].colour == COLOUR_DARK) {
1668 *adj_x = x-1;
1669 *adj_y = y;
1670 if(board[x-1][y].tank) {
1671 if(*full)
1672 return;
1673 } else {
1674 return;
1677 if(board[x+1][y].colour == COLOUR_DARK) {
1678 *adj_x = x+1;
1679 *adj_y = y;
1680 if(board[x+1][y].tank) {
1681 if(*full)
1682 return;
1683 } else {
1684 return;
1687 if(board[x][y-1].colour == COLOUR_DARK) {
1688 *adj_x = x;
1689 *adj_y = y-1;
1690 if(board[x][y-1].tank) {
1691 if(*full)
1692 return;
1693 } else {
1694 return;
1697 if(board[x][y+1].colour == COLOUR_DARK) {
1698 *adj_x = x;
1699 *adj_y = y+1;
1700 if(board[x][y+1].tank) {
1701 if(*full)
1702 return;
1703 } else {
1704 return;
1709 void computer_allocate(void) {
1710 /* Firstly, decide whether to go offensive or defensive.
1711 * This is primarily decided by the human player posing a threat to either
1712 * the computer's farms or factories */
1713 int i, j, k;
1714 bool offensive = true;
1715 struct threat threats[4];
1716 int numthreats = 0;
1717 int total_str_diff = 0;
1718 int men_needed;
1719 struct threat targets[2];
1720 int numtargets;
1721 struct cursor adj;
1722 bool full = false;
1723 for(i=1;i<12;i++) {
1724 for(j=1;j<12;j++) {
1725 if((board[i][j].colour == COLOUR_DARK) &&
1726 (calc_strength(COLOUR_DARK,i,j) <
1727 calc_strength(COLOUR_LIGHT,i,j))) {
1728 if(board[i][j].ind || board[i][j].farm) {
1729 if(numthreats < 3) {
1730 offensive = false;
1731 threats[numthreats].x = i;
1732 threats[numthreats].y = j;
1733 threats[numthreats].str_diff =
1734 calc_strength(COLOUR_LIGHT,i,j) -
1735 calc_strength(COLOUR_DARK,i,j);
1736 numthreats++;
1742 if(offensive) {
1743 /* The AI is going to go straight for the throat here and attack
1744 * the player's farms and factories. The amount of cash
1745 * the AI has to spend will determine how many targets there are */
1746 if(compres.cash > 1200) {
1747 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1748 numtargets = 2;
1749 } else {
1750 numtargets = 1;
1752 /* Work out which target(s) to attack. They must have adjacent squares
1753 * owned by the computer. If none are found just place troops in
1754 * random places around the map until we run out of money */
1755 k = 0;
1756 while(k<numtargets) {
1757 for(i=1;i<12;i++) {
1758 for(j=1;j<12;j++) {
1759 if((board[i][j].colour == COLOUR_LIGHT) &&
1760 (board[i][j].ind || board[i][j].farm) &&
1761 has_adjacent(i,j)) {
1762 targets[k].x = i;
1763 targets[k].y = j;
1764 targets[k].str_diff = abs(calc_strength(COLOUR_LIGHT,
1765 i, j) - calc_strength(COLOUR_DARK,
1766 i, j));
1767 k++;
1772 if(k == 0) {
1773 /* No targets found! Randomly pick squares and if they're owned
1774 * by the computer then stick a tank on it. */
1775 rb->srand(*rb->current_tick);
1776 while(compres.cash >= 300) {
1777 i = rb->rand()%11 + 1;
1778 j = rb->rand()%11 + 1;
1779 if(board[i][j].colour == COLOUR_DARK) {
1780 if(compres.cash >= 300) {
1781 if(!board[i][j].tank) {
1782 board[i][j].tank = true;
1783 compres.tanks++;
1784 compres.cash -= 300;
1785 draw_board();
1786 rb->sleep(HZ);
1791 compres.bank += compres.cash;
1792 compres.cash = 0;
1793 } else {
1794 for(i=0;i<k;i++) {
1795 men_needed = targets[i].str_diff + 20;
1796 find_adjacent(targets[i].x,targets[i].y, &adj.x, &adj.y, &full);
1797 while(((calc_strength(COLOUR_LIGHT, targets[i].x, targets[i].y)
1798 + 20) > calc_strength(COLOUR_DARK, targets[i].x,
1799 targets[i].y)) && compres.cash > 0) {
1800 /* While we still need them keep placing men */
1801 if(compres.cash >= 300 && !full) {
1802 if(board[adj.x][adj.y].tank) {
1803 find_adjacent(targets[i].x, targets[i].y,
1804 &adj.x, &adj.y, &full);
1805 } else {
1806 board[adj.x][adj.y].tank = true;
1807 compres.tanks++;
1808 compres.cash -= 300;
1809 draw_board();
1810 rb->sleep(HZ);
1812 } else {
1813 men_needed = (calc_strength(COLOUR_LIGHT, targets[i].x,
1814 targets[i].y) + 20 -
1815 calc_strength(COLOUR_DARK, targets[i].x,
1816 targets[i].y))*1000/133;
1817 if(compres.cash >= men_needed) {
1818 board[adj.x][adj.y].men += men_needed;
1819 compres.men += men_needed;
1820 compres.cash -= men_needed;
1821 compres.bank += compres.cash;
1822 compres.cash = 0;
1823 } else {
1824 board[adj.x][adj.y].men += compres.cash;
1825 compres.men += compres.cash;
1826 compres.cash = 0;
1828 draw_board();
1829 rb->sleep(HZ);
1833 compres.bank += compres.cash;
1834 compres.cash = 0;
1836 } else {
1837 /* Work out what to place on each square to defend it.
1838 * Tanks are preferential because they do not require food,
1839 * but if the budget is tight then we fall back onto troops.
1840 * Conversely if cash is not an issue and there are already tanks in
1841 * place planes will be deployed. We would like a margin of at least
1842 * 20 points to be safe. */
1844 for(i=0;i<numthreats;i++) {
1845 total_str_diff += threats[i].str_diff;
1847 if((total_str_diff+20)*10 > compres.cash) {
1848 /* Not enough cash to accomodate all threats using tanks alone -
1849 * use men as a backup */
1850 for(i=0;i<numthreats;i++) {
1851 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1852 if(compres.cash >= men_needed) {
1853 board[threats[i].x][threats[i].y].men += men_needed;
1854 compres.cash -= men_needed;
1855 compres.men += men_needed;
1856 draw_board();
1857 rb->sleep(HZ);
1858 } else {
1859 board[threats[i].x][threats[i].y].men += compres.cash;
1860 compres.men += compres.cash;
1861 compres.cash = 0;
1862 draw_board();
1863 rb->sleep(HZ);
1866 } else if((total_str_diff+20)*15 < compres.cash) {
1867 /* Enough money to pay their way by planes */
1868 for(i=0;i<numthreats;i++) {
1869 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1870 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1871 20)) {
1872 if(board[threats[i].x][threats[i].y].plane) {
1873 if(place_adjacent(0, threats[i].x, threats[i].y)) {
1874 /* No room for any more planes, revert to men */
1875 men_needed = (calc_strength(COLOUR_LIGHT,
1876 threats[i].x, threats[i].y) + 20 -
1877 calc_strength(COLOUR_DARK,
1878 threats[i].x, threats[i].y)*1000/133);
1879 if(compres.cash >= men_needed) {
1880 compres.cash -= men_needed;
1881 compres.men += men_needed;
1882 board[threats[i].x][threats[i].y].men +=
1883 men_needed;
1884 draw_board();
1885 rb->sleep(HZ);
1888 } else {
1889 if(compres.cash >= 600) {
1890 board[threats[i].x][threats[i].y].plane = true;
1891 compres.cash -= 600;
1892 compres.planes++;
1893 draw_board();
1894 rb->sleep(HZ);
1899 } else {
1900 /* Tanks it is */
1901 for(i=0;i<numthreats;i++) {
1902 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1903 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1904 20) && compres.cash > 0) {
1905 if(board[threats[i].x][threats[i].y].tank) {
1906 if(place_adjacent(1, threats[i].x, threats[i].y)) {
1907 /* No room for any more tanks, revert to men */
1908 men_needed = (calc_strength(COLOUR_LIGHT,
1909 threats[i].x, threats[i].y) + 20 -
1910 calc_strength(COLOUR_DARK,
1911 threats[i].x, threats[i].y)*1000/133);
1912 if(compres.cash >= men_needed) {
1913 compres.cash -= men_needed;
1914 compres.men += men_needed;
1915 board[threats[i].x][threats[i].y].men +=
1916 men_needed;
1917 draw_board();
1918 rb->sleep(HZ);
1921 } else {
1922 if(compres.cash >= 300) {
1923 board[threats[i].x][threats[i].y].tank = true;
1924 compres.tanks++;
1925 compres.cash -= 300;
1926 draw_board();
1927 rb->sleep(HZ);
1933 compres.bank += compres.cash;
1934 compres.cash = 0;
1938 int find_adj_target(int x, int y, struct cursor* adj) {
1939 /* Find a square next to a computer's farm or factory owned by the player
1940 * that is vulnerable. Return 1 on success, 0 otherwise */
1941 if(board[x+1][y].colour == COLOUR_LIGHT &&
1942 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1943 adj->x = x+1;
1944 adj->y = y;
1945 return 1;
1947 if(board[x-1][y].colour == COLOUR_LIGHT &&
1948 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1949 adj->x = x-1;
1950 adj->y = y;
1951 return 1;
1953 if(board[x][y+1].colour == COLOUR_LIGHT &&
1954 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1955 adj->x = x;
1956 adj->y = y+1;
1957 return 1;
1959 if(board[x][y-1].colour == COLOUR_LIGHT &&
1960 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1961 adj->x = x;
1962 adj->y = y-1;
1963 return 1;
1965 return 0;
1968 void computer_war(void) {
1969 /* Work out where to attack - prioritise the defence of buildings */
1970 int i, j;
1971 struct cursor adj;
1973 while(compres.moves) {
1974 for(i=1;i<12;i++) {
1975 for(j=1;j<12;j++) {
1976 if((board[i][j].colour == COLOUR_DARK) &&
1977 (board[i][j].farm || board[i][j].ind)) {
1978 if(find_adj_target(i, j, &adj) && compres.moves) {
1979 if(calc_strength(COLOUR_LIGHT, adj.x, adj.y) ==
1980 calc_strength(COLOUR_DARK, adj.x, adj.y)) {
1981 rb->srand(*rb->current_tick);
1982 if(rb->rand()%2) {
1983 board[adj.x][adj.y].colour = COLOUR_DARK;
1984 board[adj.x][adj.y].tank = false;
1985 board[adj.x][adj.y].plane = false;
1986 board[adj.x][adj.y].nuke = false;
1987 humanres.men -= board[adj.x][adj.y].men;
1988 board[adj.x][adj.y].men = 0;
1989 draw_board();
1990 rb->sleep(HZ);
1991 compres.moves--;
1992 } else {
1993 rb->splash(HZ*2, "The computer attempted"
1994 " to attack, but the"
1995 " invasion was pushed"
1996 " back");
1997 compres.moves--;
1999 } else {
2000 if(compres.moves) {
2001 board[adj.x][adj.y].colour = COLOUR_DARK;
2002 board[adj.x][adj.y].tank = false;
2003 board[adj.x][adj.y].plane = false;
2004 board[adj.x][adj.y].nuke = false;
2005 humanres.men -= board[adj.x][adj.y].men;
2006 board[adj.x][adj.y].men = 0;
2007 draw_board();
2008 rb->sleep(HZ);
2009 compres.moves--;
2016 if(compres.moves) {
2017 /* Defence stage done, move on to OFFENCE */
2018 for(i=1;i<12;i++) {
2019 for(j=1;j<12;j++) {
2020 if(board[i][j].colour == COLOUR_LIGHT && compres.moves &&
2021 (board[i][j].ind || board[i][j].farm) &&
2022 (calc_strength(COLOUR_DARK, i, j) >=
2023 calc_strength(COLOUR_LIGHT, i, j))) {
2024 if(calc_strength(COLOUR_DARK, i, j) ==
2025 calc_strength(COLOUR_LIGHT, i, j)) {
2026 if(rb->rand()%2) {
2027 board[i][j].colour = COLOUR_DARK;
2028 board[i][j].tank = false;
2029 board[i][j].plane = false;
2030 board[i][j].nuke = false;
2031 board[i][j].men = 0;
2032 draw_board();
2033 rb->sleep(HZ);
2034 compres.moves--;
2035 } else {
2036 rb->splash(HZ*2, "The computer attempted to "
2037 "attack, but the invasion was"
2038 " pushed back");
2039 compres.moves--;
2041 } else {
2042 board[i][j].colour = COLOUR_DARK;
2043 board[i][j].tank = false;
2044 board[i][j].plane = false;
2045 board[i][j].nuke = false;
2046 board[i][j].men = 0;
2047 draw_board();
2048 rb->sleep(HZ);
2049 compres.moves--;
2054 while(compres.moves > 0) {
2055 /* Spend leftover moves wherever attacking randomly */
2056 rb->srand(*rb->current_tick);
2057 i = (rb->rand()%10)+1;
2058 j = (rb->rand()%10)+1;
2059 if(board[i][j].colour == COLOUR_LIGHT &&
2060 (calc_strength(COLOUR_DARK, i, j) >=
2061 calc_strength(COLOUR_LIGHT, i, j))) {
2062 if(calc_strength(COLOUR_DARK, i, j) ==
2063 calc_strength(COLOUR_LIGHT, i, j)) {
2064 if(rb->rand()%2) {
2065 board[i][j].colour = COLOUR_DARK;
2066 board[i][j].tank = false;
2067 board[i][j].plane = false;
2068 board[i][j].nuke = false;
2069 board[i][j].men = 0;
2070 draw_board();
2071 rb->sleep(HZ);
2072 compres.moves--;
2073 } else {
2074 rb->splash(HZ*2, "The computer attempted to"
2075 " attack, but the invasion was"
2076 " pushed back");
2077 compres.moves--;
2079 } else {
2080 board[i][j].colour = COLOUR_DARK;
2081 board[i][j].tank = false;
2082 board[i][j].plane = false;
2083 board[i][j].nuke = false;
2084 board[i][j].men = 0;
2085 draw_board();
2086 rb->sleep(HZ);
2087 compres.moves--;
2095 int load_game(char* file) {
2096 int fd;
2098 fd = rb->open(file, O_RDONLY);
2099 if(fd == 0) {
2100 DEBUGF("Couldn't open savegame\n");
2101 return -1;
2103 rb->read(fd, buf, 5);
2104 if(rb->strcmp(buf, "SSGv2")) {
2105 rb->splash(HZ, "Invalid/incompatible savegame\n");
2106 return -1;
2108 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
2109 rb->read(fd, &humanres.food, sizeof(humanres.food));
2110 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
2111 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
2112 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
2113 rb->read(fd, &humanres.men, sizeof(humanres.men));
2114 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
2115 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
2116 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
2117 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
2118 rb->read(fd, &compres.cash, sizeof(humanres.cash));
2119 rb->read(fd, &compres.food, sizeof(humanres.food));
2120 rb->read(fd, &compres.bank, sizeof(humanres.bank));
2121 rb->read(fd, &compres.planes, sizeof(humanres.planes));
2122 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
2123 rb->read(fd, &compres.men, sizeof(humanres.men));
2124 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
2125 rb->read(fd, &compres.inds, sizeof(humanres.inds));
2126 rb->read(fd, &compres.farms, sizeof(humanres.farms));
2127 rb->read(fd, &compres.moves, sizeof(humanres.moves));
2128 rb->read(fd, board, sizeof(board));
2129 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
2130 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
2131 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2132 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2133 rb->read(fd, &superdom_settings.startcash, sizeof(int));
2134 rb->read(fd, &superdom_settings.startfood, sizeof(int));
2135 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
2136 return 0;
2139 void default_settings(void) {
2140 superdom_settings.compstartfarms = 1;
2141 superdom_settings.compstartinds = 1;
2142 superdom_settings.humanstartfarms = 2;
2143 superdom_settings.humanstartinds = 2;
2144 superdom_settings.startcash = 0;
2145 superdom_settings.startfood = 0;
2146 superdom_settings.movesperturn = 2;
2149 int average_strength(bool colour) {
2150 /* This function calculates the average strength of the given player,
2151 * used to determine when the computer wins or loses. */
2152 int i,j;
2153 int totalpower = 0;
2154 for(i=0;i<12;i++) {
2155 for(j=0;j<12;j++) {
2156 if(board[i][j].colour != -1) {
2157 totalpower += calc_strength(colour, i, j);
2161 return totalpower/100;
2164 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2166 int tempmenu;
2167 bool statusbar_setting;
2169 rb = api;
2171 #if LCD_DEPTH > 1
2172 rb->lcd_set_backdrop(NULL);
2173 rb->lcd_set_foreground(LCD_BLACK);
2174 rb->lcd_set_background(LCD_WHITE);
2175 #endif
2177 statusbar_setting = rb->global_settings->statusbar;
2178 rb->global_settings->statusbar = false;
2179 cursor.x = 1;
2180 cursor.y = 1;
2181 default_settings();
2182 if(parameter) {
2183 if(load_game(parameter) != 0) {
2184 DEBUGF("Loading failed, generating new game\n");
2185 init_resources();
2186 init_board();
2187 } else {
2188 goto startyear;
2190 } else {
2191 init_resources();
2192 init_board();
2195 bool play = false;
2196 while(!play) {
2197 switch(menu()) {
2198 case 0:
2199 play = true;
2200 break;
2201 case 2:
2202 rb->global_settings->statusbar = statusbar_setting;
2203 return PLUGIN_OK;
2204 break;
2207 gen_resources();
2208 startyear:
2209 if((average_strength(COLOUR_LIGHT) - average_strength(COLOUR_DARK)) > 15) {
2210 rb->splash(HZ*4, "The computer has surrendered. You win.");
2211 rb->global_settings->statusbar = statusbar_setting;
2212 return PLUGIN_OK;
2214 if((average_strength(COLOUR_DARK) - average_strength(COLOUR_LIGHT)) > 15) {
2215 rb->splash(HZ*4, "Your army have suffered terrible morale from the bleak prospects of winning. You lose");
2216 rb->global_settings->statusbar = statusbar_setting;
2217 return PLUGIN_OK;
2219 tempmenu = production_menu();
2220 switch(tempmenu) {
2221 case PLUGIN_USB_CONNECTED:
2222 rb->global_settings->statusbar = statusbar_setting;
2223 return PLUGIN_USB_CONNECTED;
2224 break;
2225 case SUPERDOM_QUIT:
2226 rb->global_settings->statusbar = statusbar_setting;
2227 return PLUGIN_OK;
2228 break;
2230 computer_allocate();
2231 humanres.moves += superdom_settings.movesperturn;
2232 tempmenu = movement_menu();
2233 switch(tempmenu) {
2234 case PLUGIN_USB_CONNECTED:
2235 rb->global_settings->statusbar = statusbar_setting;
2236 return PLUGIN_USB_CONNECTED;
2237 break;
2238 case SUPERDOM_QUIT:
2239 rb->global_settings->statusbar = statusbar_setting;
2240 return PLUGIN_OK;
2241 break;
2243 if(humanres.men) {
2244 if(humanres.food > humanres.men) {
2245 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2246 humanres.men);
2247 humanres.food -= humanres.men;
2248 } else {
2249 rb->snprintf(buf, sizeof(buf), "There was not enough food to feed"
2250 " all your men, %d men have died of starvation",
2251 killmen(COLOUR_LIGHT));
2253 rb->splash(HZ*2, buf);
2255 if(compres.men) {
2256 if(compres.food < compres.men) {
2257 rb->snprintf(buf, sizeof(buf), "The computer does not have enough"
2258 " food to feed its men. %d have ided of starvation",
2259 killmen(COLOUR_DARK));
2260 rb->splash(HZ, buf);
2263 tempmenu = war_menu();
2264 switch(tempmenu) {
2265 case PLUGIN_USB_CONNECTED:
2266 rb->global_settings->statusbar = statusbar_setting;
2267 return PLUGIN_USB_CONNECTED;
2268 break;
2269 case SUPERDOM_QUIT:
2270 rb->global_settings->statusbar = statusbar_setting;
2271 return PLUGIN_OK;
2272 break;
2274 compres.moves += superdom_settings.movesperturn;
2275 computer_war();
2276 gen_resources();
2277 goto startyear;
2278 rb->global_settings->statusbar = statusbar_setting;
2279 return PLUGIN_OK;