Introduce Rockbox Utility to the manual as automated installation option. Only rather...
[Rockbox.git] / apps / plugins / superdom.c
blobf963d7f828f78ff2c5d2100501bfb3adc28520fe
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_UP
117 #define SUPERDOM_DOWN BUTTON_SCROLL_DOWN
118 #define SUPERDOM_LEFT BUTTON_LEFT
119 #define SUPERDOM_RIGHT BUTTON_RIGHT
120 #define SUPERDOM_CANCEL BUTTON_POWER
122 #endif
124 #define SUPERDOM_QUIT 23
126 void gen_interest(void);
127 int production_menu(void);
128 void init_resources(void);
129 int select_square(void);
130 void update_score(void);
131 void gen_resources(void);
132 void draw_cursor(void);
133 int calc_strength(bool colour, int x, int y);
134 void draw_board(void);
136 struct tile{
137 signed int colour; /* -1 = Unset */
138 bool tank;
139 bool plane;
140 bool nuke;
141 bool ind;
142 bool farm;
143 int men;
146 struct resources {
147 int cash;
148 int food;
149 int farms;
150 int inds;
151 int men;
152 int tanks;
153 int planes;
154 int nukes;
155 int bank;
156 int moves;
159 struct settings {
160 int compstartfarms;
161 int compstartinds;
162 int humanstartfarms;
163 int humanstartinds;
164 int startcash;
165 int startfood;
166 int movesperturn;
167 } superdom_settings;
169 struct resources humanres;
170 struct resources compres;
172 struct cursor{
173 int x;
174 int y;
175 } cursor;
177 struct tile board[12][12];
179 void init_board(void) {
180 rb->srand(*rb->current_tick);
181 int i,j;
182 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
183 for(j=0;j<12;j++) {
184 if((i<1)||(j<1)||(i>10)||(j>10))
185 board[i][j].colour = -1; /* Unset */
186 else
187 board[i][j].colour = rb->rand()%2;
188 board[i][j].tank = false;
189 board[i][j].plane = false;
190 board[i][j].nuke = false;
191 board[i][j].ind = false;
192 board[i][j].farm = false;
193 board[i][j].men = 0;
197 while(compres.farms < superdom_settings.compstartfarms) {
198 i = rb->rand()%10 + 1;
199 j = rb->rand()%10 + 1;
200 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
201 board[i][j].farm = true;
202 compres.farms++;
203 break;
206 while(compres.inds < superdom_settings.compstartinds) {
207 i = rb->rand()%10 + 1;
208 j = rb->rand()%10 + 1;
209 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
210 board[i][j].ind = true;
211 compres.inds++;
212 break;
215 while(humanres.farms<superdom_settings.humanstartfarms) {
216 i = rb->rand()%10 + 1;
217 j = rb->rand()%10 + 1;
218 if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
219 board[i][j].farm = true;
220 humanres.farms++;
223 while(humanres.inds<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].ind == false)) {
227 board[i][j].ind = true;
228 humanres.inds++;
233 void draw_board(void) {
234 rb->lcd_clear_display();
235 int i,j;
236 for(i=1;i<11;i++) {
237 for(j=1;j<11;j++) {
238 if(board[i][j].colour == COLOUR_DARK) {
239 rb->lcd_set_foreground(LCD_DARKGRAY);
240 } else {
241 rb->lcd_set_foreground(LCD_LIGHTGRAY);
243 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
244 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
245 BOX_HEIGHT);
246 #if LCD_DEPTH != 16
247 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
248 #endif
249 if(board[i][j].ind) {
250 #if (LCD_DEPTH == 16)
251 rb->lcd_bitmap_transparent_part(superdom_boarditems,
252 #else
253 rb->lcd_mono_bitmap_part(superdom_boarditems,
254 #endif
255 board[i][j].colour?ICON_WIDTH:0, 0, STRIDE,
256 #if LCD_WIDTH > LCD_HEIGHT
257 MARGIN+(BOX_WIDTH*(i-1))+1,
258 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
259 #else
260 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
261 MARGIN+(BOX_HEIGHT*(j-1))+1,
262 #endif
263 ICON_WIDTH, ICON_HEIGHT);
265 if(board[i][j].farm) {
266 #if (LCD_DEPTH == 16)
267 rb->lcd_bitmap_transparent_part(superdom_boarditems,
268 #else
269 rb->lcd_mono_bitmap_part(superdom_boarditems,
270 #endif
271 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
272 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
273 MARGIN+(BOX_HEIGHT*(j-1))+1,
274 ICON_WIDTH, ICON_HEIGHT);
276 if(board[i][j].tank) {
277 #if (LCD_DEPTH == 16)
278 rb->lcd_bitmap_transparent_part(superdom_boarditems,
279 #else
280 rb->lcd_mono_bitmap_part(superdom_boarditems,
281 #endif
282 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
283 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
284 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
285 ICON_WIDTH, ICON_HEIGHT);
287 if(board[i][j].men) {
288 #if (LCD_DEPTH == 16)
289 rb->lcd_bitmap_transparent_part(superdom_boarditems,
290 #else
291 rb->lcd_mono_bitmap_part(superdom_boarditems,
292 #endif
293 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
294 #if LCD_WIDTH > LCD_HEIGHT
295 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
296 MARGIN+(BOX_HEIGHT*(j-1))+1,
297 #else
298 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
299 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
300 #endif
301 ICON_WIDTH, ICON_HEIGHT);
303 if(board[i][j].plane) {
304 #if (LCD_DEPTH == 16)
305 rb->lcd_bitmap_transparent_part(superdom_boarditems,
306 #else
307 rb->lcd_mono_bitmap_part(superdom_boarditems,
308 #endif
309 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
310 #if LCD_WIDTH > LCD_HEIGHT
311 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
312 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
313 #else
314 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
315 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
316 #endif
317 ICON_WIDTH, ICON_HEIGHT);
319 if(board[i][j].nuke) {
320 #if (LCD_DEPTH == 16)
321 rb->lcd_bitmap_transparent_part(superdom_boarditems,
322 #else
323 rb->lcd_mono_bitmap_part(superdom_boarditems,
324 #endif
325 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
326 #if LCD_WIDTH > LCD_HEIGHT
327 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
328 MARGIN+(BOX_HEIGHT*(j-1))+1,
329 #else
330 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
331 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
332 #endif
333 ICON_WIDTH, ICON_HEIGHT);
335 #if LCD_DEPTH != 16
336 rb->lcd_set_drawmode(DRMODE_SOLID);
337 #endif
340 rb->lcd_set_foreground(LCD_BLACK);
341 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
342 rb->lcd_drawline(MARGIN, MARGIN+(BOX_HEIGHT*i), MARGIN+(BOX_WIDTH*10),
343 MARGIN+(BOX_HEIGHT*i));
345 for(i=0;i<=10;i++) { /* Draw Vertical lines */
346 rb->lcd_drawline(MARGIN+(BOX_WIDTH*i),MARGIN, MARGIN+(BOX_WIDTH*i),
347 MARGIN+(BOX_HEIGHT*10));
349 rb->lcd_update();
352 int calc_strength(bool colour, int x, int y) {
353 int a, b, score=0;
354 for (a = -1; a < 2; a++){
355 for (b = -1; b < 2; b++){
356 if (b == 0){
357 if(board[x + a][y].colour == colour)
358 score+=10;
359 if(((board[x + a][y].colour == colour) && board[x + a][y].tank) || ((board[x + a][y].colour == colour) && board[x + a][y].farm))
360 score+=30;
361 if(((board[x + a][y].colour == colour) && board[x + a][y].plane) || ((board[x + a][y].colour == colour) && board[x + a][y].ind))
362 score+=40;
363 if((board[x + a][y].colour == colour) && board[x + a][y].nuke)
364 score+=20;
365 if((board[x + a][y].colour == colour) && board[x + a][y].men)
366 score+=(board[x + a][y].men*133/1000);
367 } else if (a == 0){
368 if(board[x][y + b].colour == colour)
369 score+=10;
370 if(((board[x][y + b].colour == colour) && board[x][y + b].tank) || ((board[x][y + b].colour == colour) && board[x][y + b].farm))
371 score+=30;
372 if(((board[x][y + b].colour == colour) && board[x][y + b].plane) || ((board[x][y + b].colour == colour) && board[x][y + b].ind))
373 score+=40;
374 if((board[x][y + b].colour == colour) && board[x][y + b].nuke)
375 score+=20;
376 if((board[x][y + b].colour == colour) && board[x][y + b].men)
377 score+=(board[x][y + b].men*133/1000);
381 return score;
384 void gen_interest(void) {
385 /* Interest should be around 10% */
386 rb->srand(*rb->current_tick);
387 int interest = 7+rb->rand()%6;
388 humanres.bank = humanres.bank+(interest*humanres.bank/100);
391 void draw_cursor(void) {
392 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
393 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
394 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
395 rb->lcd_set_drawmode(DRMODE_SOLID);
396 rb->lcd_update();
399 void gen_resources(void) {
400 gen_interest();
401 int inccash = 0;
402 int incfood = 0;
403 int i;
404 rb->srand(*rb->current_tick);
405 /* Generate Human's resources */
406 for(i=0;i<humanres.inds;i++) {
407 inccash += (300+rb->rand()%200);
409 for(i=0;i<humanres.farms;i++) {
410 incfood += (200+rb->rand()%200);
412 if(inccash/humanres.inds > 450) {
413 if(incfood/humanres.farms > 350) {
414 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
415 " is up this year!");
416 } else {
417 rb->splash(HZ*2, "Factories working at maximum efficiency,"
418 " cash production up this year!");
420 } else if((inccash/humanres.inds>350)&&(inccash/humanres.inds<=450)) {
421 if(incfood/humanres.farms > 350) {
422 rb->splash(HZ*2, "Record crop harvest this year!");
423 } else if((incfood/humanres.farms > 250) &&
424 (incfood/humanres.farms <= 350)) {
425 rb->splash(HZ*2, "Production continues as normal");
426 } else {
427 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
428 " output this year");
430 } else {
431 if(incfood/humanres.farms > 350) {
432 rb->splash(HZ*2, "Record crop harvest this year!");
433 } else if((incfood/humanres.farms > 250) &&
434 (incfood/humanres.farms <= 350)) {
435 rb->splash(HZ*2, "Factory unions introduced. Industrial"
436 " production is down this year.");
437 } else {
438 rb->splash(HZ*2, "Internet created. All production is down"
439 " due to time wasted.");
442 humanres.cash += inccash;
443 humanres.food += incfood;
445 /* Generate Computer's resources */
446 inccash = 0;
447 incfood = 0;
448 for(i=0;i<compres.inds;i++) {
449 inccash += (300+rb->rand()%200);
451 for(i=0;i<compres.farms;i++) {
452 incfood += (200+rb->rand()%200);
454 compres.cash += inccash;
455 compres.food += incfood;
458 void update_score(void) {
459 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
460 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
461 rb->lcd_set_drawmode(DRMODE_SOLID);
462 rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
463 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)/10,
464 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)%10);
465 rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
466 rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
467 calc_strength(COLOUR_DARK, cursor.x, cursor.y)/10,
468 calc_strength(COLOUR_DARK, cursor.x, cursor.y)%10);
469 rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
472 int settings_menu_function(void) {
473 int selection = 0;
475 MENUITEM_STRINGLIST(settings_menu,"Super Domination Settings",NULL,
476 "Computer starting farms","Computer starting factories",
477 "Human starting farms","Human starting factories",
478 "Starting cash","Starting food","Moves per turn");
479 settings_menu:
480 selection=rb->do_menu(&settings_menu,&selection);
481 switch(selection) {
482 case 0:
483 rb->set_int("Computer starting farms", "", UNIT_INT,
484 &superdom_settings.compstartfarms, NULL,
485 1, 0, 5, NULL);
486 goto settings_menu;
487 break;
488 case 1:
489 rb->set_int("Computer starting factories", "", UNIT_INT,
490 &superdom_settings.compstartinds, NULL,
491 1, 0, 5, NULL);
492 goto settings_menu;
493 break;
494 case 2:
495 rb->set_int("Human starting farms", "", UNIT_INT,
496 &superdom_settings.humanstartfarms, NULL,
497 1, 0, 5, NULL);
498 goto settings_menu;
499 break;
500 case 3:
501 superdom_settings.humanstartinds =
502 rb->set_int("Human starting factories", "", UNIT_INT,
503 &superdom_settings.humanstartinds, NULL,
504 1, 0, 5, NULL);
505 goto settings_menu;
506 break;
507 case 4:
508 rb->set_int("Starting cash", "", UNIT_INT,
509 &superdom_settings.startcash, NULL,
510 250, 0, 5000, NULL);
511 goto settings_menu;
512 break;
513 case 5:
514 rb->set_int("Starting food", "", UNIT_INT,
515 &superdom_settings.startfood, NULL,
516 250, 0, 5000, NULL);
517 goto settings_menu;
518 break;
519 case 6:
520 rb->set_int("Moves per turn", "", UNIT_INT,
521 &superdom_settings.movesperturn, NULL,
522 1, 1, 5, NULL);
523 goto settings_menu;
524 break;
525 case MENU_ATTACHED_USB:
526 return PLUGIN_USB_CONNECTED;
527 break;
529 return 0;
532 int do_help(void) {
533 int selection = 0;
535 MENUITEM_STRINGLIST(help_menu,"Help",NULL,"Super domination is a turn",
536 "based strategy game, where the aim is to overpower the",
537 "computer player by taking their territory.",
538 "Each year you are allocated an amount of cash and food,",
539 "depending on how many farms and factories you control."
540 "Use this cash and food to buy and feed your army.",
541 "Each tile has a strength, calculated by the ownership",
542 "of adjacent tiles, and the type and number of troops",
543 "on them.");
544 rb->do_menu(&help_menu,&selection);
545 switch(selection) {
546 case MENU_ATTACHED_USB:
547 return PLUGIN_USB_CONNECTED;
548 break;
550 return 0;
553 int menu(void) {
554 int selection = 0;
556 MENUITEM_STRINGLIST(main_menu,"Super Domination Menu",NULL,
557 "Play Super Domination","Settings","Help","Quit");
559 while(1) {
560 selection=rb->do_menu(&main_menu,&selection);
561 switch(selection) {
562 case 0:
563 return 0; /* start playing */
564 break;
565 case 1:
566 if(settings_menu_function()==PLUGIN_USB_CONNECTED)
567 return PLUGIN_USB_CONNECTED;
568 break;
569 case 2:
570 if(do_help()==PLUGIN_USB_CONNECTED)
571 return PLUGIN_USB_CONNECTED;
572 break;
573 default:
574 return 2; /* quit program */
575 break;
579 return 3;
582 int save_game(void) {
583 int fd;
584 char savepath[MAX_PATH];
586 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
587 if(rb->kbd_input(savepath, MAX_PATH)) {
588 DEBUGF("Keyboard input failed\n");
589 return -1;
592 fd = rb->open(savepath, O_WRONLY|O_CREAT);
593 DEBUGF("savepath: %s\n", savepath);
594 if(fd < 0) {
595 DEBUGF("Couldn't create/open file\n");
596 return -1;
599 rb->write(fd, "SSGv2", 5);
600 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
601 rb->write(fd, &humanres.food, sizeof(humanres.food));
602 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
603 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
604 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
605 rb->write(fd, &humanres.men, sizeof(humanres.men));
606 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
607 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
608 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
609 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
610 rb->write(fd, &compres.cash, sizeof(compres.cash));
611 rb->write(fd, &compres.food, sizeof(compres.food));
612 rb->write(fd, &compres.bank, sizeof(compres.bank));
613 rb->write(fd, &compres.planes, sizeof(compres.planes));
614 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
615 rb->write(fd, &compres.men, sizeof(compres.men));
616 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
617 rb->write(fd, &compres.inds, sizeof(compres.inds));
618 rb->write(fd, &compres.farms, sizeof(compres.farms));
619 rb->write(fd, &compres.moves, sizeof(compres.moves));
620 rb->write(fd, board, sizeof(board));
621 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
622 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
623 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
624 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
625 rb->write(fd, &superdom_settings.startcash, sizeof(int));
626 rb->write(fd, &superdom_settings.startfood, sizeof(int));
627 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
628 rb->close(fd);
629 return 0;
632 int ingame_menu(void) {
633 int selection = 0;
635 MENUITEM_STRINGLIST(ingame_menu,"Super Domination Menu",NULL,
636 "Return to game","Save Game", "Quit");
638 selection=rb->do_menu(&ingame_menu,&selection);
639 switch(selection) {
640 case 0:
641 return 0;
642 break;
643 case 1:
644 if(!save_game())
645 rb->splash(HZ, "Game saved");
646 else
647 rb->splash(HZ, "Error in save");
648 break;
649 case 2:
650 return SUPERDOM_QUIT;
651 break;
652 case MENU_ATTACHED_USB:
653 return PLUGIN_USB_CONNECTED;
654 break;
656 return 0;
659 int get_number(char* param, int* value) {
660 //int numbers[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
661 int numbers[3][3];
662 numbers[0][0] = 1;
663 numbers[0][1] = 2;
664 numbers[0][2] = 3;
665 numbers[1][0] = 4;
666 numbers[1][1] = 5;
667 numbers[1][2] = 6;
668 numbers[2][0] = 7;
669 numbers[2][1] = 8;
670 numbers[2][2] = 9;
671 rb->lcd_clear_display();
672 /* Draw a 3x4 grid */
673 int i,j,x=0,y=0;
674 for(i=0;i<=3;i++) { /* Vertical lines */
675 rb->lcd_drawline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
676 NUM_MARGIN_X+(NUM_BOX_WIDTH*i),
677 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
679 for(i=0;i<=4;i++) { /* Horizontal lines */
680 rb->lcd_drawline(NUM_MARGIN_X, NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT),
681 NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
682 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
684 int temp = 1;
685 for(i=0;i<3;i++) {
686 for(j=0;j<3;j++) {
687 rb->snprintf(buf, sizeof(buf), "%d", temp);
688 rb->lcd_putsxy(NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+10,
689 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+8, buf);
690 temp++;
693 rb->lcd_putsxy(NUM_MARGIN_X+5, NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "CLR");
694 rb->lcd_putsxy(NUM_MARGIN_X+NUM_BOX_WIDTH+10,
695 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "0");
696 rb->lcd_putsxy(NUM_MARGIN_X+2*NUM_BOX_WIDTH+8,
697 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "OK");
698 rb->snprintf(buf,sizeof(buf), "%d", *value);
699 rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
700 int height, width;
701 rb->lcd_getstringsize(param, &width, &height);
702 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
703 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
704 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
705 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y), NUM_BOX_WIDTH+1,
706 NUM_BOX_HEIGHT+1);
707 rb->lcd_set_drawmode(DRMODE_SOLID);
708 int button = 0;
709 rb->lcd_update();
710 while(1) {
711 button = rb->button_get(true);
712 switch(button) {
713 case SUPERDOM_OK:
714 *value *= 10;
715 if(y!=3) {
716 *value += numbers[y][x];
717 } else if(y==3 && x==0) {
718 *value /= 100;
719 } else if(y==3 && x==2) {
720 *value /= 10;
721 return 0;
723 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
724 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
725 LCD_WIDTH, 30);
726 rb->lcd_set_drawmode(DRMODE_SOLID);
727 rb->snprintf(buf,sizeof(buf), "%d", *value);
728 rb->lcd_putsxy(NUM_MARGIN_X+10,
729 NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
730 break;
731 case SUPERDOM_CANCEL:
732 return 0;
733 break;
734 #if CONFIG_KEYPAD != IRIVER_H10_PAD
735 case SUPERDOM_LEFT:
736 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
737 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
738 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
739 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
740 rb->lcd_set_drawmode(DRMODE_SOLID);
741 if(x==0) {
742 #ifdef IPOD_STYLE
743 if(y>0)
744 y--;
745 else
746 y=3;
747 #endif
748 x=2;
749 } else {
750 x--;
752 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
753 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
754 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
755 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
756 rb->lcd_set_drawmode(DRMODE_SOLID);
757 break;
758 case SUPERDOM_RIGHT:
759 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
760 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
761 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
762 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
763 rb->lcd_set_drawmode(DRMODE_SOLID);
764 if(x==2) {
765 #ifdef IPOD_STYLE
766 if(y==3)
767 y=0;
768 else
769 y++;
770 #endif
771 x=0;
772 } else {
773 x++;
775 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
776 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
777 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
778 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
779 rb->lcd_set_drawmode(DRMODE_SOLID);
780 break;
781 #endif
782 #ifndef IPOD_STYLE
783 case SUPERDOM_UP:
784 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
785 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
786 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
787 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
788 rb->lcd_set_drawmode(DRMODE_SOLID);
789 if(y==0) {
790 #if CONFIG_KEYPAD == IRIVER_H10_PAD
791 if(x > 0)
792 x--;
793 else
794 x=2;
795 #endif
796 y=3;
797 } else {
798 y--;
800 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
801 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
802 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
803 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
804 rb->lcd_set_drawmode(DRMODE_SOLID);
805 break;
806 case SUPERDOM_DOWN:
807 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
808 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
809 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
810 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
811 rb->lcd_set_drawmode(DRMODE_SOLID);
812 if(y==3) {
813 #if CONFIG_KEYPAD == IRIVER_H10_PAD
814 if(x < 2)
815 x++;
816 else
817 x=0;
818 #endif
819 y=0;
820 } else {
821 y++;
823 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
824 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
825 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
826 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
827 rb->lcd_set_drawmode(DRMODE_SOLID);
828 break;
829 #endif
830 default:
831 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
833 return PLUGIN_USB_CONNECTED;
835 break;
837 rb->lcd_update();
839 return 0;
842 int buy_resources_menu(void) {
843 int selection,tempmenu,nummen;
845 MENUITEM_STRINGLIST(res_menu, "Buy Resources", NULL, "Buy men ($1)",
846 "Buy tank ($300)", "Buy plane ($600)", "Buy Farm ($1150)",
847 "Buy Factory ($1300)", "Buy Nuke ($2000)",
848 "Finish buying", "Game menu");
850 resources_menu:
851 selection=rb->do_menu(&res_menu,&selection);
852 switch(selection) {
853 case 0:
854 nummen = 0;
855 if(get_number("How many men would you like?", &nummen)
856 == PLUGIN_USB_CONNECTED)
857 return PLUGIN_USB_CONNECTED;
858 if(humanres.cash>=nummen) {
859 rb->splash(HZ, "Where do you want to place them?");
860 tempmenu = select_square();
861 switch(tempmenu) {
862 case 0:
863 rb->splash(HZ, "Cancelled");
864 break;
865 case 2:
866 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
867 humanres.men += nummen;
868 board[cursor.x][cursor.y].men += nummen;
869 humanres.cash -= nummen;
870 } else {
871 rb->splash(HZ,"Can't place men on enemy territory");
873 break;
874 case PLUGIN_USB_CONNECTED:
875 return PLUGIN_USB_CONNECTED;
876 break;
878 } else {
879 rb->splash(HZ, "Not enough money!");
881 goto resources_menu;
882 break;
883 case 1:
884 if(humanres.cash>=300) {
885 rb->splash(HZ, "Where do you want to place the tank?");
886 tempmenu = select_square();
887 switch(tempmenu) {
888 case 0:
889 rb->splash(HZ, "Cancelled");
890 goto resources_menu;
891 break;
892 case PLUGIN_USB_CONNECTED:
893 return PLUGIN_USB_CONNECTED;
894 break;
896 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
897 if(board[cursor.x][cursor.y].tank) {
898 rb->splash(HZ, "There is already a tank there");
899 } else {
900 board[cursor.x][cursor.y].tank = true;
901 humanres.cash -= 300;
902 humanres.tanks++;
904 } else {
905 rb->splash(HZ, "Can't place men on enemy territory");
907 } else {
908 rb->splash(HZ, "Not enough money!");
910 goto resources_menu;
911 break;
912 case 2:
913 if(humanres.cash>=600) {
914 rb->splash(HZ, "Where do you want to place the plane?");
915 tempmenu = select_square();
916 switch(tempmenu) {
917 case 0:
918 rb->splash(HZ, "Cancelled");
919 goto resources_menu;
920 break;
921 case PLUGIN_USB_CONNECTED:
922 return PLUGIN_USB_CONNECTED;
923 break;
925 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
926 if(board[cursor.x][cursor.y].plane) {
927 rb->splash(HZ, "There is already a plane there");
928 } else {
929 board[cursor.x][cursor.y].plane = true;
930 humanres.cash -= 600;
931 humanres.planes++;
933 } else {
934 rb->splash(HZ, "Can't place men on enemy territory");
936 } else {
937 rb->splash(HZ, "Not enough money!");
939 goto resources_menu;
940 break;
941 case 3:
942 if(humanres.cash>=1150) {
943 rb->splash(HZ, "Where do you want to place the farm?");
944 tempmenu = select_square();
945 switch(tempmenu) {
946 case 0:
947 rb->splash(HZ, "Cancelled");
948 goto resources_menu;
949 break;
950 case PLUGIN_USB_CONNECTED:
951 return PLUGIN_USB_CONNECTED;
952 break;
954 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
955 if(board[cursor.x][cursor.y].farm) {
956 rb->splash(HZ, "There is already a farm there");
957 } else {
958 board[cursor.x][cursor.y].farm = true;
959 humanres.cash -= 1150;
960 humanres.farms++;
962 } else {
963 rb->splash(HZ, "Can't build on enemy territory");
965 } else {
966 rb->splash(HZ, "Not enough money!");
968 goto resources_menu;
969 break;
970 case 4:
971 if(humanres.cash>=1300) {
972 rb->splash(HZ, "Where do you want to place the industrial"
973 " plant?");
974 tempmenu = select_square();
975 switch(tempmenu) {
976 case 0:
977 rb->splash(HZ, "Cancelled");
978 goto resources_menu;
979 break;
980 case PLUGIN_USB_CONNECTED:
981 return PLUGIN_USB_CONNECTED;
982 break;
984 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
985 if(board[cursor.x][cursor.y].ind) {
986 rb->splash(HZ, "There is already an industrial"
987 " plant there");
988 } else {
989 board[cursor.x][cursor.y].ind = true;
990 humanres.cash -= 1300;
991 humanres.inds++;
993 } else {
994 rb->splash(HZ, "Can't build on enemy territory");
996 } else {
997 rb->splash(HZ, "Not enough money!");
999 goto resources_menu;
1000 break;
1001 case 5:
1002 if(humanres.cash>=2000) {
1003 rb->splash(HZ, "Where do you want to place the nuke?");
1004 tempmenu = select_square();
1005 switch(tempmenu) {
1006 case 0:
1007 rb->splash(HZ, "Cancelled");
1008 goto resources_menu;
1009 break;
1010 case PLUGIN_USB_CONNECTED:
1011 return PLUGIN_USB_CONNECTED;
1012 break;
1014 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1015 if(board[cursor.x][cursor.y].nuke) {
1016 rb->splash(HZ, "There is already a nuke there");
1017 } else {
1018 board[cursor.x][cursor.y].nuke = true;
1019 humanres.cash -= 2000;
1020 humanres.nukes++;
1022 } else {
1023 rb->splash(HZ, "Can't place a nuke on enemy territory");
1025 } else {
1026 rb->splash(HZ, "Not enough money!");
1028 goto resources_menu;
1029 break;
1030 case 6:
1031 return 0;
1032 break;
1033 case MENU_ATTACHED_USB:
1034 return PLUGIN_USB_CONNECTED;
1035 break;
1037 return 0;
1040 int move_unit(void) {
1041 int selection, nummen;
1042 struct cursor from;
1044 MENUITEM_STRINGLIST(move_unit_menu, "Move unit", NULL, "Move men",
1045 "Move tank", "Move plane");
1046 selection=rb->do_menu(&move_unit_menu,&selection);
1047 switch(selection) {
1048 case 0:
1049 rb->splash(HZ, "Select where to move troops from");
1050 if(select_square() == PLUGIN_USB_CONNECTED)
1051 return PLUGIN_USB_CONNECTED;
1052 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1053 if(board[cursor.x][cursor.y].men) {
1054 from.x = cursor.x;
1055 from.y = cursor.y;
1056 nummen = board[from.x][from.y].men;
1057 if(get_number("How many men do you want to move?",
1058 &nummen) == PLUGIN_USB_CONNECTED)
1059 return PLUGIN_USB_CONNECTED;
1060 if(nummen > board[from.x][from.y].men) {
1061 rb->splash(HZ, "You don't have that many troops.");
1062 } else {
1063 rb->splash(HZ,"Select where to move the troops to");
1064 if(select_square() == PLUGIN_USB_CONNECTED)
1065 return PLUGIN_USB_CONNECTED;
1066 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT) &&
1067 (abs(cursor.x - from.x) <= 1) &&
1068 abs(cursor.y - from.y) <= 1) {
1069 board[from.x][from.y].men -= nummen;
1070 board[cursor.x][cursor.y].men += nummen;
1071 humanres.moves--;
1072 return 0;
1075 } else {
1076 rb->splash(HZ, "You don't have any troops there");
1078 } else {
1079 rb->splash(HZ, "Can't move enemy troops");
1081 break;
1082 case 1:
1083 rb->splash(HZ, "Select where you want to move the tank from");
1084 if(select_square() == PLUGIN_USB_CONNECTED)
1085 return PLUGIN_USB_CONNECTED;
1086 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1087 if(board[cursor.x][cursor.y].tank) {
1088 from.x = cursor.x;
1089 from.y = cursor.y;
1090 rb->splash(HZ, "Select where you want"
1091 " to move the tank to");
1092 if(select_square() == PLUGIN_USB_CONNECTED)
1093 return PLUGIN_USB_CONNECTED;
1094 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT)&&
1095 (abs(cursor.x-from.x) <= 1) &&
1096 (abs(cursor.y-from.y) <= 1)) {
1097 if(board[cursor.x][cursor.y].tank) {
1098 rb->splash(HZ, "There is already a tank there");
1099 } else {
1100 board[from.x][from.y].tank = false;
1101 board[cursor.x][cursor.y].tank = true;
1102 humanres.moves--;
1103 return 0;
1105 } else {
1106 rb->splash(HZ, "Invalid move");
1108 } else {
1109 rb->splash(HZ, "You don't have a tank there");
1111 } else {
1112 rb->splash(HZ, "That isn't your territory");
1114 break;
1115 case 2:
1116 rb->splash(HZ, "Select where you want"
1117 " to move the plane from");
1118 if(select_square() == PLUGIN_USB_CONNECTED)
1119 return PLUGIN_USB_CONNECTED;
1120 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1121 if(board[cursor.x][cursor.y].plane) {
1122 from.x = cursor.x;
1123 from.y = cursor.y;
1124 rb->splash(HZ, "Select where you want"
1125 " to move the plane to");
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 rb->splash(HZ,"There is already a plane there");
1131 } else {
1132 board[from.x][from.y].plane = false;
1133 board[cursor.x][cursor.y].plane = true;
1134 humanres.moves--;
1135 return 0;
1137 } else {
1138 rb->splash(HZ, "Invalid move");
1140 } else {
1141 rb->splash(HZ, "You don't have a plane there");
1143 } else {
1144 rb->splash(HZ, "That isn't your territory");
1146 break;
1148 return 0;
1151 int movement_menu(void) {
1152 int selection, tempmenu;
1153 bool menu_quit = false;
1155 MENUITEM_STRINGLIST(move_menu, "Movement", NULL, "Move unit",
1156 "Buy additional moves ($100)", "Launch nuclear missile",
1157 "Check map", "Finish moving", "Game menu");
1159 while(!menu_quit) {
1160 selection=rb->do_menu(&move_menu,&selection);
1161 switch(selection) {
1162 case 0:
1163 if(humanres.moves) {
1164 if(move_unit()==PLUGIN_USB_CONNECTED)
1165 return PLUGIN_USB_CONNECTED;
1166 } else {
1167 rb->splash(HZ, "You have no more moves left."
1168 " You can buy more for $100 each.");
1170 break;
1171 case 1:
1172 if(humanres.cash > 100) {
1173 humanres.moves++;
1174 humanres.cash -= 100;
1175 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1176 humanres.moves);
1177 rb->splash(HZ, buf);
1179 break;
1180 case 2:
1181 if(humanres.nukes==0) {
1182 rb->splash(HZ, "You do not have any nukes to launch");
1183 } else {
1184 rb->splash(HZ, "Select place to launch nuke from");
1185 if(select_square() == PLUGIN_USB_CONNECTED) {
1186 return PLUGIN_USB_CONNECTED;
1188 if(board[cursor.x][cursor.y].nuke) {
1189 rb->splash(HZ, "Select place to target with nuke");
1190 if(select_square() == PLUGIN_USB_CONNECTED) {
1191 return PLUGIN_USB_CONNECTED;
1193 board[cursor.x][cursor.y].men = 0;
1194 board[cursor.x][cursor.y].tank = 0;
1195 board[cursor.x][cursor.y].plane = 0;
1196 board[cursor.x][cursor.y].ind = 0;
1197 board[cursor.x][cursor.y].nuke = 0;
1198 board[cursor.x][cursor.y].farm = 0;
1199 /* TODO: Fallout carried by wind */
1202 break;
1203 case 3:
1204 if(select_square() == PLUGIN_USB_CONNECTED)
1205 return PLUGIN_USB_CONNECTED;
1206 break;
1207 case 4:
1208 return 0;
1209 break;
1210 case 5:
1211 tempmenu = ingame_menu();
1212 switch(tempmenu) {
1213 case PLUGIN_USB_CONNECTED:
1214 return PLUGIN_USB_CONNECTED;
1215 break;
1216 case SUPERDOM_QUIT:
1217 return SUPERDOM_QUIT;
1218 break;
1220 break;
1221 case MENU_ATTACHED_USB:
1222 return PLUGIN_USB_CONNECTED;
1223 break;
1226 return 0;
1229 int show_inventory(void) {
1230 rb->lcd_clear_display();
1231 rb->lcd_puts(1, 0, "Inventory");
1232 char men[20], tanks[20], planes[20], inds[20], farms[20], nukes[20],
1233 cash[20], food[20], bank[20];
1234 rb->snprintf(men, sizeof(men), "Men: %d", humanres.men);
1235 rb->snprintf(tanks, sizeof(tanks), "Tanks: %d", humanres.tanks);
1236 rb->snprintf(planes, sizeof(planes), "Planes: %d", humanres.planes);
1237 rb->snprintf(inds, sizeof(inds), "Factories: %d", humanres.inds);
1238 rb->snprintf(farms, sizeof(farms), "Farms: %d", humanres.farms);
1239 rb->snprintf(nukes, sizeof(nukes), "Nukes: %d", humanres.nukes);
1240 rb->snprintf(cash, sizeof(cash), "Cash: %d", humanres.cash);
1241 rb->snprintf(food, sizeof(food), "Food: %d", humanres.food);
1242 rb->snprintf(bank, sizeof(bank), "Bank: %d", humanres.bank);
1243 rb->lcd_puts(2, 1, men);
1244 rb->lcd_puts(2, 2, tanks);
1245 rb->lcd_puts(2, 3, planes);
1246 rb->lcd_puts(2, 4, inds);
1247 rb->lcd_puts(2, 5, farms);
1248 rb->lcd_puts(2, 6, nukes);
1249 rb->lcd_puts(2, 7, cash);
1250 rb->lcd_puts(2, 8, food);
1251 rb->lcd_puts(2, 9, bank);
1252 rb->lcd_update();
1253 if(rb->default_event_handler(rb->button_get(true)) == SYS_USB_CONNECTED) {
1254 return PLUGIN_USB_CONNECTED;
1255 } else {
1256 return 0;
1260 int production_menu(void) {
1261 int selection, tempbank, tempmenu;
1263 MENUITEM_STRINGLIST(prod_menu, "Production", NULL, "Buy resources",
1264 "Show inventory", "Check map", "Invest money",
1265 "Withdraw money", "Finish turn", "Game menu");
1267 while(1) {
1268 selection=rb->do_menu(&prod_menu,&selection);
1269 switch(selection) {
1270 case 0:
1271 tempmenu = buy_resources_menu();
1272 switch(tempmenu) {
1273 case PLUGIN_USB_CONNECTED:
1274 return PLUGIN_USB_CONNECTED;
1275 break;
1276 case SUPERDOM_QUIT:
1277 return SUPERDOM_QUIT;
1278 break;
1280 break;
1281 case 1:
1282 tempmenu = show_inventory();
1283 switch(tempmenu) {
1284 case 0:
1285 break;
1286 case PLUGIN_USB_CONNECTED:
1287 return PLUGIN_USB_CONNECTED;
1288 break;
1290 break;
1291 case 2:
1292 tempmenu = select_square();
1293 switch(tempmenu) {
1294 case PLUGIN_USB_CONNECTED:
1295 return PLUGIN_USB_CONNECTED;
1296 break;
1297 case SUPERDOM_QUIT:
1298 return SUPERDOM_QUIT;
1299 break;
1300 case 0:
1301 break;
1303 break;
1304 case 3:
1305 tempbank = humanres.cash;
1306 if(get_number("How much do you want to invest?", &tempbank)
1307 == PLUGIN_USB_CONNECTED)
1308 return PLUGIN_USB_CONNECTED;
1309 if(tempbank>humanres.cash) {
1310 rb->splash(HZ, "You don't have that much cash to invest");
1311 } else {
1312 humanres.cash -= tempbank;
1313 humanres.bank += tempbank;
1315 break;
1316 case 4:
1317 tempbank = 0;
1318 if(get_number("How much do you want to withdraw?", &tempbank)
1319 == PLUGIN_USB_CONNECTED)
1320 return PLUGIN_USB_CONNECTED;
1321 if(tempbank>humanres.bank) {
1322 rb->splash(HZ, "You don't have that much cash to withdraw");
1323 } else {
1324 humanres.cash += tempbank;
1325 humanres.bank -= tempbank;
1327 break;
1328 case 5:
1329 return 0;
1330 break;
1331 case 6:
1332 tempmenu = ingame_menu();
1333 switch(tempmenu) {
1334 case PLUGIN_USB_CONNECTED:
1335 return PLUGIN_USB_CONNECTED;
1336 break;
1337 case SUPERDOM_QUIT:
1338 return SUPERDOM_QUIT;
1339 break;
1341 break;
1342 case MENU_ATTACHED_USB:
1343 return PLUGIN_USB_CONNECTED;
1344 break;
1347 return 0;
1350 void init_resources(void) {
1351 humanres.cash = superdom_settings.startcash;
1352 humanres.food = superdom_settings.startfood;
1353 humanres.tanks = 0;
1354 humanres.planes = 0;
1355 humanres.nukes = 0;
1356 humanres.inds = 0;
1357 humanres.farms = 0;
1358 humanres.men = 0;
1359 humanres.bank = 0;
1360 humanres.moves = 0;
1361 compres.cash = superdom_settings.startcash;
1362 compres.food = superdom_settings.startfood;
1363 compres.tanks = 0;
1364 compres.planes = 0;
1365 compres.nukes = 0;
1366 compres.inds = 0;
1367 compres.farms = 0;
1368 compres.men = 0;
1369 compres.bank = 0;
1370 compres.moves = 0;
1373 int select_square(void) {
1374 draw_board();
1375 draw_cursor();
1376 update_score();
1377 #if LCD_WIDTH >= 220
1378 rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
1379 rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
1380 rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
1381 rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
1382 #endif
1383 rb->lcd_update();
1384 int button = 0;
1385 while(1) {
1386 button = rb->button_get(true);
1387 switch(button) {
1388 case SUPERDOM_CANCEL:
1389 return 0;
1390 break;
1391 case SUPERDOM_OK:
1392 return 2;
1393 break;
1394 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1395 case SUPERDOM_LEFT:
1396 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1397 draw_cursor(); /* Deselect the current tile */
1398 if(cursor.x>1) {
1399 cursor.x--;
1400 } else {
1401 #ifdef IPOD_STYLE
1402 if(cursor.y>1)
1403 cursor.y--;
1404 else
1405 cursor.y = 10;
1406 #endif
1407 cursor.x = 10;
1409 update_score();
1410 draw_cursor();
1411 break;
1412 case SUPERDOM_RIGHT:
1413 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1414 draw_cursor(); /* Deselect the current tile */
1415 if(cursor.x<10) {
1416 cursor.x++;
1417 } else {
1418 #ifdef IPOD_STYLE
1419 if(cursor.y<10)
1420 cursor.y++;
1421 else
1422 cursor.y = 1;
1423 #endif
1424 cursor.x = 1;
1426 update_score();
1427 draw_cursor();
1428 break;
1429 #endif
1430 #ifndef IPOD_STYLE
1431 case SUPERDOM_UP:
1432 case (SUPERDOM_UP|BUTTON_REPEAT):
1433 draw_cursor(); /* Deselect the current tile */
1434 if(cursor.y>1) {
1435 cursor.y--;
1436 } else {
1437 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1438 if(cursor.x > 1)
1439 cursor.x--;
1440 else
1441 cursor.x = 10;
1442 #endif
1443 cursor.y = 10;
1445 update_score();
1446 draw_cursor();
1447 break;
1448 case SUPERDOM_DOWN:
1449 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1450 draw_cursor(); /* Deselect the current tile */
1451 if(cursor.y<10) {
1452 cursor.y++;
1453 } else {
1454 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1455 if(cursor.x < 10)
1456 cursor.x++;
1457 else
1458 cursor.x = 1;
1459 #endif
1460 cursor.y = 1;
1462 update_score();
1463 draw_cursor();
1464 break;
1465 #endif
1466 default:
1467 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1469 return PLUGIN_USB_CONNECTED;
1475 int killmen(bool human) {
1476 int menkilled,i,j;
1477 int percent;
1478 if(human) {
1479 percent = (humanres.food*1000)/humanres.men;
1480 humanres.food = 0;
1481 } else {
1482 percent = (compres.food*1000)/compres.men;
1483 compres.food = 0;
1485 menkilled = 0;
1486 for(i=1;i<12;i++) {
1487 for(j=1;j<12;j++) {
1488 if(board[i][j].colour == human) {
1489 menkilled += ((board[i][j].men * percent)/1000);
1490 board[i][j].men = (board[i][j].men * percent)/1000;
1495 if(human)
1496 humanres.men -= menkilled;
1497 else
1498 compres.men -= menkilled;
1499 return menkilled;
1502 int war_menu(void) {
1503 int selection, tempmenu;
1505 MENUITEM_STRINGLIST(wartime_menu, "War!", NULL,
1506 "Select territory to attack", "Finish turn", "Game menu");
1508 humanres.moves = superdom_settings.movesperturn;
1509 while(humanres.moves) {
1510 selection=rb->do_menu(&wartime_menu,&selection);
1511 switch(selection) {
1512 case 0:
1513 if(select_square() == PLUGIN_USB_CONNECTED)
1514 return PLUGIN_USB_CONNECTED;
1515 if(board[cursor.x][cursor.y].colour == COLOUR_DARK) {
1516 if(calc_strength(COLOUR_LIGHT, cursor.x,
1517 cursor.y) > calc_strength(COLOUR_DARK,
1518 cursor.x, cursor.y)) {
1519 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1520 board[cursor.x][cursor.y].tank = 0;
1521 board[cursor.x][cursor.y].men = 0;
1522 board[cursor.x][cursor.y].plane = 0;
1523 board[cursor.x][cursor.y].nuke = 0;
1524 draw_board();
1525 rb->sleep(HZ*2);
1526 humanres.moves--;
1527 } else if(calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)==
1528 calc_strength(COLOUR_DARK, cursor.x, cursor.y)) {
1529 if(rb->rand()%2) {
1530 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1531 board[cursor.x][cursor.y].tank = 0;
1532 board[cursor.x][cursor.y].men = 0;
1533 board[cursor.x][cursor.y].plane = 0;
1534 board[cursor.x][cursor.y].nuke = 0;
1535 draw_board();
1536 rb->sleep(HZ*2);
1537 humanres.moves--;
1538 } else {
1539 rb->splash(HZ, "Your troops were unable to"
1540 " overcome the enemy troops");
1541 humanres.moves--;
1543 } else {
1544 rb->splash(HZ, "Your troops were unable to overcome"
1545 " the enemy troops");
1546 humanres.moves--;
1548 } else {
1549 rb->splash(HZ, "You can't attack your own territory");
1551 break;
1552 case 1:
1553 return 0;
1554 break;
1555 case 2:
1556 tempmenu = ingame_menu();
1557 switch(tempmenu) {
1558 case PLUGIN_USB_CONNECTED:
1559 return PLUGIN_USB_CONNECTED;
1560 break;
1561 case SUPERDOM_QUIT:
1562 return SUPERDOM_QUIT;
1563 break;
1565 break;
1568 return 0;
1571 struct threat {
1572 int x;
1573 int y;
1574 int str_diff;
1577 bool place_adjacent(bool tank, int x, int y) {
1578 if(tank) {
1579 if(!board[x-1][y].tank && (board[x][y].colour==board[x-1][y].colour)) {
1580 compres.cash -= 300;
1581 board[x-1][y].tank = true;
1582 compres.tanks++;
1583 return 0;
1585 if(!board[x+1][y].tank && (board[x][y].colour==board[x+1][y].colour)) {
1586 compres.cash -= 300;
1587 board[x+1][y].tank = true;
1588 compres.tanks++;
1589 return 0;
1591 if(!board[x][y-1].tank && (board[x][y].colour==board[x][y-1].colour)) {
1592 compres.cash -= 300;
1593 board[x][y-1].tank = true;
1594 compres.tanks++;
1595 return 0;
1597 if(!board[x][y+1].tank && (board[x][y].colour==board[x][y+1].colour)) {
1598 compres.cash -= 300;
1599 board[x][y+1].tank = true;
1600 compres.tanks++;
1601 return 0;
1603 } else {
1604 if(!board[x-1][y].plane && (board[x][y].colour==board[x-1][y].colour)) {
1605 compres.cash -= 600;
1606 board[x-1][y].plane = true;
1607 compres.planes++;
1608 return 0;
1610 if(!board[x+1][y].plane && (board[x][y].colour==board[x+1][y].colour)) {
1611 compres.cash -= 600;
1612 board[x+1][y].plane = true;
1613 compres.planes++;
1614 return 0;
1616 if(!board[x][y-1].plane && (board[x][y].colour==board[x][y-1].colour)) {
1617 compres.cash -= 600;
1618 board[x][y-1].plane = true;
1619 compres.planes++;
1620 return 0;
1622 if(!board[x][y+1].plane && (board[x][y].colour==board[x][y+1].colour)) {
1623 compres.cash -= 600;
1624 board[x][y+1].plane = true;
1625 compres.planes++;
1626 return 0;
1629 return 1;
1632 bool has_adjacent(int x, int y) {
1633 if((board[x][y].colour == COLOUR_LIGHT) &&
1634 ((board[x-1][y].colour == COLOUR_DARK) ||
1635 (board[x+1][y].colour == COLOUR_DARK) ||
1636 (board[x][y+1].colour == COLOUR_DARK) ||
1637 (board[x][y-1].colour == COLOUR_DARK)))
1638 return 1;
1639 else
1640 return 0;
1643 void find_adjacent(int x, int y, int* adj_x, int* adj_y, bool* full) {
1644 /* Finds adjacent squares, returning squares without tanks on them
1645 * in preference to those with them */
1646 if(((board[x-1][y].tank && (board[x-1][y].colour == COLOUR_DARK)) ||
1647 board[x-1][y].colour != COLOUR_DARK) &&
1648 ((board[x+1][y].tank && (board[x+1][y].colour == COLOUR_DARK)) ||
1649 board[x+1][y].colour != COLOUR_DARK) &&
1650 ((board[x][y-1].tank && (board[x][y-1].colour == COLOUR_DARK)) ||
1651 board[x][y-1].colour != COLOUR_DARK) &&
1652 ((board[x][y+1].tank && (board[x][y+1].colour == COLOUR_DARK)) ||
1653 board[x][y+1].colour != COLOUR_DARK)) {
1654 *full = true;
1655 } else {
1656 *full = false;
1659 if(board[x-1][y].colour == COLOUR_DARK) {
1660 *adj_x = x-1;
1661 *adj_y = y;
1662 if(board[x-1][y].tank) {
1663 if(*full)
1664 return;
1665 } else {
1666 return;
1669 if(board[x+1][y].colour == COLOUR_DARK) {
1670 *adj_x = x+1;
1671 *adj_y = y;
1672 if(board[x+1][y].tank) {
1673 if(*full)
1674 return;
1675 } else {
1676 return;
1679 if(board[x][y-1].colour == COLOUR_DARK) {
1680 *adj_x = x;
1681 *adj_y = y-1;
1682 if(board[x][y-1].tank) {
1683 if(*full)
1684 return;
1685 } else {
1686 return;
1689 if(board[x][y+1].colour == COLOUR_DARK) {
1690 *adj_x = x;
1691 *adj_y = y+1;
1692 if(board[x][y+1].tank) {
1693 if(*full)
1694 return;
1695 } else {
1696 return;
1701 void computer_allocate(void) {
1702 /* Firstly, decide whether to go offensive or defensive.
1703 * This is primarily decided by the human player posing a threat to either
1704 * the computer's farms or factories */
1705 int i, j, k;
1706 bool offensive = true;
1707 struct threat threats[4];
1708 int numthreats = 0;
1709 int total_str_diff = 0;
1710 int men_needed;
1711 struct threat targets[2];
1712 int numtargets;
1713 struct cursor adj;
1714 bool full = false;
1715 for(i=1;i<12;i++) {
1716 for(j=1;j<12;j++) {
1717 if((board[i][j].colour == COLOUR_DARK) &&
1718 (calc_strength(COLOUR_DARK,i,j) <
1719 calc_strength(COLOUR_LIGHT,i,j))) {
1720 if(board[i][j].ind || board[i][j].farm) {
1721 if(numthreats < 3) {
1722 offensive = false;
1723 threats[numthreats].x = i;
1724 threats[numthreats].y = j;
1725 threats[numthreats].str_diff =
1726 calc_strength(COLOUR_LIGHT,i,j) -
1727 calc_strength(COLOUR_DARK,i,j);
1728 numthreats++;
1734 if(offensive) {
1735 /* The AI is going to go straight for the throat here and attack
1736 * the player's farms and factories. The amount of cash
1737 * the AI has to spend will determine how many targets there are */
1738 if(compres.cash > 1200) {
1739 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1740 numtargets = 2;
1741 } else {
1742 numtargets = 1;
1744 /* Work out which target(s) to attack. They must have adjacent squares
1745 * owned by the computer. If none are found just place troops in
1746 * random places around the map until we run out of money */
1747 k = 0;
1748 while(k<numtargets) {
1749 for(i=1;i<12;i++) {
1750 for(j=1;j<12;j++) {
1751 if((board[i][j].colour == COLOUR_LIGHT) &&
1752 (board[i][j].ind || board[i][j].farm) &&
1753 has_adjacent(i,j)) {
1754 targets[k].x = i;
1755 targets[k].y = j;
1756 targets[k].str_diff = abs(calc_strength(COLOUR_LIGHT,
1757 i, j) - calc_strength(COLOUR_DARK,
1758 i, j));
1759 k++;
1764 if(k == 0) {
1765 /* No targets found! Randomly pick squares and if they're owned
1766 * by the computer then stick a tank on it. */
1767 rb->srand(*rb->current_tick);
1768 while(compres.cash >= 300) {
1769 i = rb->rand()%11 + 1;
1770 j = rb->rand()%11 + 1;
1771 if(board[i][j].colour == COLOUR_DARK) {
1772 if(compres.cash >= 300) {
1773 if(!board[i][j].tank) {
1774 board[i][j].tank = true;
1775 compres.tanks++;
1776 compres.cash -= 300;
1777 draw_board();
1778 rb->sleep(HZ);
1783 compres.bank += compres.cash;
1784 compres.cash = 0;
1785 } else {
1786 for(i=0;i<k;i++) {
1787 men_needed = targets[i].str_diff + 20;
1788 find_adjacent(targets[i].x,targets[i].y, &adj.x, &adj.y, &full);
1789 while(((calc_strength(COLOUR_LIGHT, targets[i].x, targets[i].y)
1790 + 20) > calc_strength(COLOUR_DARK, targets[i].x,
1791 targets[i].y)) && compres.cash > 0) {
1792 /* While we still need them keep placing men */
1793 if(compres.cash >= 300 && !full) {
1794 if(board[adj.x][adj.y].tank) {
1795 find_adjacent(targets[i].x, targets[i].y,
1796 &adj.x, &adj.y, &full);
1797 } else {
1798 board[adj.x][adj.y].tank = true;
1799 compres.tanks++;
1800 compres.cash -= 300;
1801 draw_board();
1802 rb->sleep(HZ);
1804 } else {
1805 men_needed = (calc_strength(COLOUR_LIGHT, targets[i].x,
1806 targets[i].y) + 20 -
1807 calc_strength(COLOUR_DARK, targets[i].x,
1808 targets[i].y))*1000/133;
1809 if(compres.cash >= men_needed) {
1810 board[adj.x][adj.y].men += men_needed;
1811 compres.men += men_needed;
1812 compres.cash -= men_needed;
1813 compres.bank += compres.cash;
1814 compres.cash = 0;
1815 } else {
1816 board[adj.x][adj.y].men += compres.cash;
1817 compres.men += compres.cash;
1818 compres.cash = 0;
1820 draw_board();
1821 rb->sleep(HZ);
1825 compres.bank += compres.cash;
1826 compres.cash = 0;
1828 } else {
1829 /* Work out what to place on each square to defend it.
1830 * Tanks are preferential because they do not require food,
1831 * but if the budget is tight then we fall back onto troops.
1832 * Conversely if cash is not an issue and there are already tanks in
1833 * place planes will be deployed. We would like a margin of at least
1834 * 20 points to be safe. */
1836 for(i=0;i<numthreats;i++) {
1837 total_str_diff += threats[i].str_diff;
1839 if((total_str_diff+20)*10 > compres.cash) {
1840 /* Not enough cash to accomodate all threats using tanks alone -
1841 * use men as a backup */
1842 for(i=0;i<numthreats;i++) {
1843 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1844 if(compres.cash >= men_needed) {
1845 board[threats[i].x][threats[i].y].men += men_needed;
1846 compres.cash -= men_needed;
1847 compres.men += men_needed;
1848 draw_board();
1849 rb->sleep(HZ);
1850 } else {
1851 board[threats[i].x][threats[i].y].men += compres.cash;
1852 compres.men += compres.cash;
1853 compres.cash = 0;
1854 draw_board();
1855 rb->sleep(HZ);
1858 } else if((total_str_diff+20)*15 < compres.cash) {
1859 /* Enough money to pay their way by planes */
1860 for(i=0;i<numthreats;i++) {
1861 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1862 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1863 20)) {
1864 if(board[threats[i].x][threats[i].y].plane) {
1865 if(place_adjacent(0, threats[i].x, threats[i].y)) {
1866 /* No room for any more planes, revert to men */
1867 men_needed = (calc_strength(COLOUR_LIGHT,
1868 threats[i].x, threats[i].y) + 20 -
1869 calc_strength(COLOUR_DARK,
1870 threats[i].x, threats[i].y)*1000/133);
1871 if(compres.cash >= men_needed) {
1872 compres.cash -= men_needed;
1873 compres.men += men_needed;
1874 board[threats[i].x][threats[i].y].men +=
1875 men_needed;
1876 draw_board();
1877 rb->sleep(HZ);
1880 } else {
1881 if(compres.cash >= 600) {
1882 board[threats[i].x][threats[i].y].plane = true;
1883 compres.cash -= 600;
1884 compres.planes++;
1885 draw_board();
1886 rb->sleep(HZ);
1891 } else {
1892 /* Tanks it is */
1893 for(i=0;i<numthreats;i++) {
1894 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1895 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1896 20) && compres.cash > 0) {
1897 if(board[threats[i].x][threats[i].y].tank) {
1898 if(place_adjacent(1, threats[i].x, threats[i].y)) {
1899 /* No room for any more tanks, revert to men */
1900 men_needed = (calc_strength(COLOUR_LIGHT,
1901 threats[i].x, threats[i].y) + 20 -
1902 calc_strength(COLOUR_DARK,
1903 threats[i].x, threats[i].y)*1000/133);
1904 if(compres.cash >= men_needed) {
1905 compres.cash -= men_needed;
1906 compres.men += men_needed;
1907 board[threats[i].x][threats[i].y].men +=
1908 men_needed;
1909 draw_board();
1910 rb->sleep(HZ);
1913 } else {
1914 if(compres.cash >= 300) {
1915 board[threats[i].x][threats[i].y].tank = true;
1916 compres.tanks++;
1917 compres.cash -= 300;
1918 draw_board();
1919 rb->sleep(HZ);
1925 compres.bank += compres.cash;
1926 compres.cash = 0;
1930 int find_adj_target(int x, int y, struct cursor* adj) {
1931 /* Find a square next to a computer's farm or factory owned by the player
1932 * that is vulnerable. Return 1 on success, 0 otherwise */
1933 if(board[x+1][y].colour == COLOUR_LIGHT &&
1934 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1935 adj->x = x+1;
1936 adj->y = y;
1937 return 1;
1939 if(board[x-1][y].colour == COLOUR_LIGHT &&
1940 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1941 adj->x = x-1;
1942 adj->y = y;
1943 return 1;
1945 if(board[x][y+1].colour == COLOUR_LIGHT &&
1946 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1947 adj->x = x;
1948 adj->y = y+1;
1949 return 1;
1951 if(board[x][y-1].colour == COLOUR_LIGHT &&
1952 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1953 adj->x = x;
1954 adj->y = y-1;
1955 return 1;
1957 return 0;
1960 void computer_war(void) {
1961 /* Work out where to attack - prioritise the defence of buildings */
1962 int i, j;
1963 struct cursor adj;
1965 while(compres.moves) {
1966 for(i=1;i<12;i++) {
1967 for(j=1;j<12;j++) {
1968 if((board[i][j].colour == COLOUR_DARK) &&
1969 (board[i][j].farm || board[i][j].ind)) {
1970 if(find_adj_target(i, j, &adj) && compres.moves) {
1971 if(calc_strength(COLOUR_LIGHT, adj.x, adj.y) ==
1972 calc_strength(COLOUR_DARK, adj.x, adj.y)) {
1973 rb->srand(*rb->current_tick);
1974 if(rb->rand()%2) {
1975 board[adj.x][adj.y].colour = COLOUR_DARK;
1976 board[adj.x][adj.y].tank = false;
1977 board[adj.x][adj.y].plane = false;
1978 board[adj.x][adj.y].nuke = false;
1979 humanres.men -= board[adj.x][adj.y].men;
1980 board[adj.x][adj.y].men = 0;
1981 draw_board();
1982 rb->sleep(HZ);
1983 compres.moves--;
1984 } else {
1985 rb->splash(HZ*2, "The computer attempted"
1986 " to attack, but the"
1987 " invasion was pushed"
1988 " back");
1989 compres.moves--;
1991 } else {
1992 if(compres.moves) {
1993 board[adj.x][adj.y].colour = COLOUR_DARK;
1994 board[adj.x][adj.y].tank = false;
1995 board[adj.x][adj.y].plane = false;
1996 board[adj.x][adj.y].nuke = false;
1997 humanres.men -= board[adj.x][adj.y].men;
1998 board[adj.x][adj.y].men = 0;
1999 draw_board();
2000 rb->sleep(HZ);
2001 compres.moves--;
2008 if(compres.moves) {
2009 /* Defence stage done, move on to OFFENCE */
2010 for(i=1;i<12;i++) {
2011 for(j=1;j<12;j++) {
2012 if(board[i][j].colour == COLOUR_LIGHT && compres.moves &&
2013 (board[i][j].ind || board[i][j].farm) &&
2014 (calc_strength(COLOUR_DARK, i, j) >=
2015 calc_strength(COLOUR_LIGHT, i, j))) {
2016 if(calc_strength(COLOUR_DARK, i, j) ==
2017 calc_strength(COLOUR_LIGHT, i, j)) {
2018 if(rb->rand()%2) {
2019 board[i][j].colour = COLOUR_DARK;
2020 board[i][j].tank = false;
2021 board[i][j].plane = false;
2022 board[i][j].nuke = false;
2023 board[i][j].men = 0;
2024 draw_board();
2025 rb->sleep(HZ);
2026 compres.moves--;
2027 } else {
2028 rb->splash(HZ*2, "The computer attempted to "
2029 "attack, but the invasion was"
2030 " pushed back");
2031 compres.moves--;
2033 } else {
2034 board[i][j].colour = COLOUR_DARK;
2035 board[i][j].tank = false;
2036 board[i][j].plane = false;
2037 board[i][j].nuke = false;
2038 board[i][j].men = 0;
2039 draw_board();
2040 rb->sleep(HZ);
2041 compres.moves--;
2046 while(compres.moves > 0) {
2047 /* Spend leftover moves wherever attacking randomly */
2048 rb->srand(*rb->current_tick);
2049 i = (rb->rand()%10)+1;
2050 j = (rb->rand()%10)+1;
2051 if(board[i][j].colour == COLOUR_LIGHT &&
2052 (calc_strength(COLOUR_DARK, i, j) >=
2053 calc_strength(COLOUR_LIGHT, i, j))) {
2054 if(calc_strength(COLOUR_DARK, i, j) ==
2055 calc_strength(COLOUR_LIGHT, i, j)) {
2056 if(rb->rand()%2) {
2057 board[i][j].colour = COLOUR_DARK;
2058 board[i][j].tank = false;
2059 board[i][j].plane = false;
2060 board[i][j].nuke = false;
2061 board[i][j].men = 0;
2062 draw_board();
2063 rb->sleep(HZ);
2064 compres.moves--;
2065 } else {
2066 rb->splash(HZ*2, "The computer attempted to"
2067 " attack, but the invasion was"
2068 " pushed back");
2069 compres.moves--;
2071 } else {
2072 board[i][j].colour = COLOUR_DARK;
2073 board[i][j].tank = false;
2074 board[i][j].plane = false;
2075 board[i][j].nuke = false;
2076 board[i][j].men = 0;
2077 draw_board();
2078 rb->sleep(HZ);
2079 compres.moves--;
2087 int load_game(char* file) {
2088 int fd;
2090 fd = rb->open(file, O_RDONLY);
2091 if(fd == 0) {
2092 DEBUGF("Couldn't open savegame\n");
2093 return -1;
2095 rb->read(fd, buf, 5);
2096 if(rb->strcmp(buf, "SSGv2")) {
2097 rb->splash(HZ, "Invalid/incompatible savegame\n");
2098 return -1;
2100 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
2101 rb->read(fd, &humanres.food, sizeof(humanres.food));
2102 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
2103 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
2104 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
2105 rb->read(fd, &humanres.men, sizeof(humanres.men));
2106 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
2107 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
2108 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
2109 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
2110 rb->read(fd, &compres.cash, sizeof(humanres.cash));
2111 rb->read(fd, &compres.food, sizeof(humanres.food));
2112 rb->read(fd, &compres.bank, sizeof(humanres.bank));
2113 rb->read(fd, &compres.planes, sizeof(humanres.planes));
2114 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
2115 rb->read(fd, &compres.men, sizeof(humanres.men));
2116 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
2117 rb->read(fd, &compres.inds, sizeof(humanres.inds));
2118 rb->read(fd, &compres.farms, sizeof(humanres.farms));
2119 rb->read(fd, &compres.moves, sizeof(humanres.moves));
2120 rb->read(fd, board, sizeof(board));
2121 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
2122 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
2123 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2124 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2125 rb->read(fd, &superdom_settings.startcash, sizeof(int));
2126 rb->read(fd, &superdom_settings.startfood, sizeof(int));
2127 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
2128 return 0;
2131 void default_settings(void) {
2132 superdom_settings.compstartfarms = 1;
2133 superdom_settings.compstartinds = 1;
2134 superdom_settings.humanstartfarms = 2;
2135 superdom_settings.humanstartinds = 2;
2136 superdom_settings.startcash = 0;
2137 superdom_settings.startfood = 0;
2138 superdom_settings.movesperturn = 2;
2141 int average_strength(bool colour) {
2142 /* This function calculates the average strength of the given player,
2143 * used to determine when the computer wins or loses. */
2144 int i,j;
2145 int totalpower = 0;
2146 for(i=0;i<12;i++) {
2147 for(j=0;j<12;j++) {
2148 if(board[i][j].colour != -1) {
2149 totalpower += calc_strength(colour, i, j);
2153 return totalpower/100;
2156 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2158 int tempmenu;
2159 bool statusbar_setting;
2161 rb = api;
2163 #if LCD_DEPTH > 1
2164 rb->lcd_set_backdrop(NULL);
2165 rb->lcd_set_foreground(LCD_BLACK);
2166 rb->lcd_set_background(LCD_WHITE);
2167 #endif
2169 statusbar_setting = rb->global_settings->statusbar;
2170 rb->global_settings->statusbar = false;
2171 cursor.x = 1;
2172 cursor.y = 1;
2173 default_settings();
2174 if(parameter) {
2175 if(load_game(parameter) != 0) {
2176 DEBUGF("Loading failed, generating new game\n");
2177 init_resources();
2178 init_board();
2179 } else {
2180 goto startyear;
2182 } else {
2183 init_resources();
2184 init_board();
2187 bool play = false;
2188 while(!play) {
2189 switch(menu()) {
2190 case 0:
2191 play = true;
2192 break;
2193 case 2:
2194 rb->global_settings->statusbar = statusbar_setting;
2195 return PLUGIN_OK;
2196 break;
2199 gen_resources();
2200 startyear:
2201 if((average_strength(COLOUR_LIGHT) - average_strength(COLOUR_DARK)) > 15) {
2202 rb->splash(HZ*4, "The computer has surrendered. You win.");
2203 rb->global_settings->statusbar = statusbar_setting;
2204 return PLUGIN_OK;
2206 if((average_strength(COLOUR_DARK) - average_strength(COLOUR_LIGHT)) > 15) {
2207 rb->splash(HZ*4, "Your army have suffered terrible morale from the bleak prospects of winning. You lose");
2208 rb->global_settings->statusbar = statusbar_setting;
2209 return PLUGIN_OK;
2211 tempmenu = production_menu();
2212 switch(tempmenu) {
2213 case PLUGIN_USB_CONNECTED:
2214 rb->global_settings->statusbar = statusbar_setting;
2215 return PLUGIN_USB_CONNECTED;
2216 break;
2217 case SUPERDOM_QUIT:
2218 rb->global_settings->statusbar = statusbar_setting;
2219 return PLUGIN_OK;
2220 break;
2222 computer_allocate();
2223 humanres.moves += superdom_settings.movesperturn;
2224 tempmenu = movement_menu();
2225 switch(tempmenu) {
2226 case PLUGIN_USB_CONNECTED:
2227 rb->global_settings->statusbar = statusbar_setting;
2228 return PLUGIN_USB_CONNECTED;
2229 break;
2230 case SUPERDOM_QUIT:
2231 rb->global_settings->statusbar = statusbar_setting;
2232 return PLUGIN_OK;
2233 break;
2235 if(humanres.men) {
2236 if(humanres.food > humanres.men) {
2237 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2238 humanres.men);
2239 humanres.food -= humanres.men;
2240 } else {
2241 rb->snprintf(buf, sizeof(buf), "There was not enough food to feed"
2242 " all your men, %d men have died of starvation",
2243 killmen(COLOUR_LIGHT));
2245 rb->splash(HZ*2, buf);
2247 if(compres.men) {
2248 if(compres.food < compres.men) {
2249 rb->snprintf(buf, sizeof(buf), "The computer does not have enough"
2250 " food to feed its men. %d have ided of starvation",
2251 killmen(COLOUR_DARK));
2252 rb->splash(HZ, buf);
2255 tempmenu = war_menu();
2256 switch(tempmenu) {
2257 case PLUGIN_USB_CONNECTED:
2258 rb->global_settings->statusbar = statusbar_setting;
2259 return PLUGIN_USB_CONNECTED;
2260 break;
2261 case SUPERDOM_QUIT:
2262 rb->global_settings->statusbar = statusbar_setting;
2263 return PLUGIN_OK;
2264 break;
2266 compres.moves += superdom_settings.movesperturn;
2267 computer_war();
2268 gen_resources();
2269 goto startyear;
2270 rb->global_settings->statusbar = statusbar_setting;
2271 return PLUGIN_OK;