Fix some quotation marks. Thanks to Alexander Levin for pointing it out.
[Rockbox.git] / apps / plugins / superdom.c
blobc047ed454a7f1ab00d1df915039045b70b262b47
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 #elif CONFIG_KEYPAD == COWOND2_PAD
131 #define SUPERDOM_OK BUTTON_SELECT
132 #define SUPERDOM_UP BUTTON_UP
133 #define SUPERDOM_LEFT BUTTON_LEFT
134 #define SUPERDOM_RIGHT BUTTON_RIGHT
135 #define SUPERDOM_DOWN BUTTON_DOWN
136 #define SUPERDOM_CANCEL BUTTON_MENU
138 #endif
140 #define SUPERDOM_QUIT 23
142 void gen_interest(void);
143 int production_menu(void);
144 void init_resources(void);
145 int select_square(void);
146 void update_score(void);
147 void gen_resources(void);
148 void draw_cursor(void);
149 int calc_strength(bool colour, int x, int y);
150 void draw_board(void);
152 struct tile{
153 signed int colour; /* -1 = Unset */
154 bool tank;
155 bool plane;
156 bool nuke;
157 bool ind;
158 bool farm;
159 int men;
162 struct resources {
163 int cash;
164 int food;
165 int farms;
166 int inds;
167 int men;
168 int tanks;
169 int planes;
170 int nukes;
171 int bank;
172 int moves;
175 struct settings {
176 int compstartfarms;
177 int compstartinds;
178 int humanstartfarms;
179 int humanstartinds;
180 int startcash;
181 int startfood;
182 int movesperturn;
183 } superdom_settings;
185 struct resources humanres;
186 struct resources compres;
188 struct cursor{
189 int x;
190 int y;
191 } cursor;
193 struct tile board[12][12];
195 void init_board(void) {
196 rb->srand(*rb->current_tick);
197 int i,j;
198 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
199 for(j=0;j<12;j++) {
200 if((i<1)||(j<1)||(i>10)||(j>10))
201 board[i][j].colour = -1; /* Unset */
202 else
203 board[i][j].colour = rb->rand()%2;
204 board[i][j].tank = false;
205 board[i][j].plane = false;
206 board[i][j].nuke = false;
207 board[i][j].ind = false;
208 board[i][j].farm = false;
209 board[i][j].men = 0;
213 while(compres.farms < superdom_settings.compstartfarms) {
214 i = rb->rand()%10 + 1;
215 j = rb->rand()%10 + 1;
216 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
217 board[i][j].farm = true;
218 compres.farms++;
219 break;
222 while(compres.inds < superdom_settings.compstartinds) {
223 i = rb->rand()%10 + 1;
224 j = rb->rand()%10 + 1;
225 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
226 board[i][j].ind = true;
227 compres.inds++;
228 break;
231 while(humanres.farms<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].farm == false)) {
235 board[i][j].farm = true;
236 humanres.farms++;
239 while(humanres.inds<superdom_settings.humanstartfarms) {
240 i = rb->rand()%10 + 1;
241 j = rb->rand()%10 + 1;
242 if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) {
243 board[i][j].ind = true;
244 humanres.inds++;
249 void draw_board(void) {
250 rb->lcd_clear_display();
251 int i,j;
252 for(i=1;i<11;i++) {
253 for(j=1;j<11;j++) {
254 if(board[i][j].colour == COLOUR_DARK) {
255 rb->lcd_set_foreground(LCD_DARKGRAY);
256 } else {
257 rb->lcd_set_foreground(LCD_LIGHTGRAY);
259 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
260 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
261 BOX_HEIGHT);
262 #if LCD_DEPTH != 16
263 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
264 #endif
265 if(board[i][j].ind) {
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, 0, STRIDE,
272 #if LCD_WIDTH > LCD_HEIGHT
273 MARGIN+(BOX_WIDTH*(i-1))+1,
274 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
275 #else
276 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
277 MARGIN+(BOX_HEIGHT*(j-1))+1,
278 #endif
279 ICON_WIDTH, ICON_HEIGHT);
281 if(board[i][j].farm) {
282 #if (LCD_DEPTH == 16)
283 rb->lcd_bitmap_transparent_part(superdom_boarditems,
284 #else
285 rb->lcd_mono_bitmap_part(superdom_boarditems,
286 #endif
287 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
288 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
289 MARGIN+(BOX_HEIGHT*(j-1))+1,
290 ICON_WIDTH, ICON_HEIGHT);
292 if(board[i][j].tank) {
293 #if (LCD_DEPTH == 16)
294 rb->lcd_bitmap_transparent_part(superdom_boarditems,
295 #else
296 rb->lcd_mono_bitmap_part(superdom_boarditems,
297 #endif
298 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
299 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
300 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
301 ICON_WIDTH, ICON_HEIGHT);
303 if(board[i][j].men) {
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*3,
310 #if LCD_WIDTH > LCD_HEIGHT
311 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
312 MARGIN+(BOX_HEIGHT*(j-1))+1,
313 #else
314 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
315 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
316 #endif
317 ICON_WIDTH, ICON_HEIGHT);
319 if(board[i][j].plane) {
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*4,
326 #if LCD_WIDTH > LCD_HEIGHT
327 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
328 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
329 #else
330 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
331 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
332 #endif
333 ICON_WIDTH, ICON_HEIGHT);
335 if(board[i][j].nuke) {
336 #if (LCD_DEPTH == 16)
337 rb->lcd_bitmap_transparent_part(superdom_boarditems,
338 #else
339 rb->lcd_mono_bitmap_part(superdom_boarditems,
340 #endif
341 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
342 #if LCD_WIDTH > LCD_HEIGHT
343 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
344 MARGIN+(BOX_HEIGHT*(j-1))+1,
345 #else
346 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
347 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
348 #endif
349 ICON_WIDTH, ICON_HEIGHT);
351 #if LCD_DEPTH != 16
352 rb->lcd_set_drawmode(DRMODE_SOLID);
353 #endif
356 rb->lcd_set_foreground(LCD_BLACK);
357 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
358 rb->lcd_drawline(MARGIN, MARGIN+(BOX_HEIGHT*i), MARGIN+(BOX_WIDTH*10),
359 MARGIN+(BOX_HEIGHT*i));
361 for(i=0;i<=10;i++) { /* Draw Vertical lines */
362 rb->lcd_drawline(MARGIN+(BOX_WIDTH*i),MARGIN, MARGIN+(BOX_WIDTH*i),
363 MARGIN+(BOX_HEIGHT*10));
365 rb->lcd_update();
368 int calc_strength(bool colour, int x, int y) {
369 int a, b, score=0;
370 for (a = -1; a < 2; a++){
371 for (b = -1; b < 2; b++){
372 if (b == 0){
373 if(board[x + a][y].colour == colour)
374 score+=10;
375 if(((board[x + a][y].colour == colour) && board[x + a][y].tank) || ((board[x + a][y].colour == colour) && board[x + a][y].farm))
376 score+=30;
377 if(((board[x + a][y].colour == colour) && board[x + a][y].plane) || ((board[x + a][y].colour == colour) && board[x + a][y].ind))
378 score+=40;
379 if((board[x + a][y].colour == colour) && board[x + a][y].nuke)
380 score+=20;
381 if((board[x + a][y].colour == colour) && board[x + a][y].men)
382 score+=(board[x + a][y].men*133/1000);
383 } else if (a == 0){
384 if(board[x][y + b].colour == colour)
385 score+=10;
386 if(((board[x][y + b].colour == colour) && board[x][y + b].tank) || ((board[x][y + b].colour == colour) && board[x][y + b].farm))
387 score+=30;
388 if(((board[x][y + b].colour == colour) && board[x][y + b].plane) || ((board[x][y + b].colour == colour) && board[x][y + b].ind))
389 score+=40;
390 if((board[x][y + b].colour == colour) && board[x][y + b].nuke)
391 score+=20;
392 if((board[x][y + b].colour == colour) && board[x][y + b].men)
393 score+=(board[x][y + b].men*133/1000);
397 return score;
400 void gen_interest(void) {
401 /* Interest should be around 10% */
402 rb->srand(*rb->current_tick);
403 int interest = 7+rb->rand()%6;
404 humanres.bank = humanres.bank+(interest*humanres.bank/100);
407 void draw_cursor(void) {
408 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
409 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
410 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
411 rb->lcd_set_drawmode(DRMODE_SOLID);
412 rb->lcd_update();
415 void gen_resources(void) {
416 gen_interest();
417 int inccash = 0;
418 int incfood = 0;
419 int i;
420 rb->srand(*rb->current_tick);
421 /* Generate Human's resources */
422 for(i=0;i<humanres.inds;i++) {
423 inccash += (300+rb->rand()%200);
425 for(i=0;i<humanres.farms;i++) {
426 incfood += (200+rb->rand()%200);
428 if(inccash/humanres.inds > 450) {
429 if(incfood/humanres.farms > 350) {
430 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
431 " is up this year!");
432 } else {
433 rb->splash(HZ*2, "Factories working at maximum efficiency,"
434 " cash production up this year!");
436 } else if((inccash/humanres.inds>350)&&(inccash/humanres.inds<=450)) {
437 if(incfood/humanres.farms > 350) {
438 rb->splash(HZ*2, "Record crop harvest this year!");
439 } else if((incfood/humanres.farms > 250) &&
440 (incfood/humanres.farms <= 350)) {
441 rb->splash(HZ*2, "Production continues as normal");
442 } else {
443 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
444 " output this year");
446 } else {
447 if(incfood/humanres.farms > 350) {
448 rb->splash(HZ*2, "Record crop harvest this year!");
449 } else if((incfood/humanres.farms > 250) &&
450 (incfood/humanres.farms <= 350)) {
451 rb->splash(HZ*2, "Factory unions introduced. Industrial"
452 " production is down this year.");
453 } else {
454 rb->splash(HZ*2, "Internet created. All production is down"
455 " due to time wasted.");
458 humanres.cash += inccash;
459 humanres.food += incfood;
461 /* Generate Computer's resources */
462 inccash = 0;
463 incfood = 0;
464 for(i=0;i<compres.inds;i++) {
465 inccash += (300+rb->rand()%200);
467 for(i=0;i<compres.farms;i++) {
468 incfood += (200+rb->rand()%200);
470 compres.cash += inccash;
471 compres.food += incfood;
474 void update_score(void) {
475 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
476 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
477 rb->lcd_set_drawmode(DRMODE_SOLID);
478 rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
479 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)/10,
480 calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)%10);
481 rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
482 rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
483 calc_strength(COLOUR_DARK, cursor.x, cursor.y)/10,
484 calc_strength(COLOUR_DARK, cursor.x, cursor.y)%10);
485 rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
488 int settings_menu_function(void) {
489 int selection = 0;
491 MENUITEM_STRINGLIST(settings_menu,"Super Domination Settings",NULL,
492 "Computer starting farms","Computer starting factories",
493 "Human starting farms","Human starting factories",
494 "Starting cash","Starting food","Moves per turn");
495 settings_menu:
496 selection=rb->do_menu(&settings_menu,&selection, NULL, false);
497 switch(selection) {
498 case 0:
499 rb->set_int("Computer starting farms", "", UNIT_INT,
500 &superdom_settings.compstartfarms, NULL,
501 1, 0, 5, NULL);
502 goto settings_menu;
503 break;
504 case 1:
505 rb->set_int("Computer starting factories", "", UNIT_INT,
506 &superdom_settings.compstartinds, NULL,
507 1, 0, 5, NULL);
508 goto settings_menu;
509 break;
510 case 2:
511 rb->set_int("Human starting farms", "", UNIT_INT,
512 &superdom_settings.humanstartfarms, NULL,
513 1, 0, 5, NULL);
514 goto settings_menu;
515 break;
516 case 3:
517 superdom_settings.humanstartinds =
518 rb->set_int("Human starting factories", "", UNIT_INT,
519 &superdom_settings.humanstartinds, NULL,
520 1, 0, 5, NULL);
521 goto settings_menu;
522 break;
523 case 4:
524 rb->set_int("Starting cash", "", UNIT_INT,
525 &superdom_settings.startcash, NULL,
526 250, 0, 5000, NULL);
527 goto settings_menu;
528 break;
529 case 5:
530 rb->set_int("Starting food", "", UNIT_INT,
531 &superdom_settings.startfood, NULL,
532 250, 0, 5000, NULL);
533 goto settings_menu;
534 break;
535 case 6:
536 rb->set_int("Moves per turn", "", UNIT_INT,
537 &superdom_settings.movesperturn, NULL,
538 1, 1, 5, NULL);
539 goto settings_menu;
540 break;
541 case MENU_ATTACHED_USB:
542 return PLUGIN_USB_CONNECTED;
543 break;
545 return 0;
548 int do_help(void) {
549 int selection = 0;
551 MENUITEM_STRINGLIST(help_menu,"Help",NULL,"Super domination is a turn",
552 "based strategy game, where the aim is to overpower the",
553 "computer player by taking their territory.",
554 "Each year you are allocated an amount of cash and food,",
555 "depending on how many farms and factories you control."
556 "Use this cash and food to buy and feed your army.",
557 "Each tile has a strength, calculated by the ownership",
558 "of adjacent tiles, and the type and number of troops",
559 "on them.");
560 rb->do_menu(&help_menu,&selection, NULL, false);
561 switch(selection) {
562 case MENU_ATTACHED_USB:
563 return PLUGIN_USB_CONNECTED;
564 break;
566 return 0;
569 int menu(void) {
570 int selection = 0;
572 MENUITEM_STRINGLIST(main_menu,"Super Domination Menu",NULL,
573 "Play Super Domination","Settings","Help","Quit");
575 while(1) {
576 selection=rb->do_menu(&main_menu,&selection, NULL, false);
577 switch(selection) {
578 case 0:
579 return 0; /* start playing */
580 break;
581 case 1:
582 if(settings_menu_function()==PLUGIN_USB_CONNECTED)
583 return PLUGIN_USB_CONNECTED;
584 break;
585 case 2:
586 if(do_help()==PLUGIN_USB_CONNECTED)
587 return PLUGIN_USB_CONNECTED;
588 break;
589 default:
590 return 2; /* quit program */
591 break;
595 return 3;
598 int save_game(void) {
599 int fd;
600 char savepath[MAX_PATH];
602 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
603 if(rb->kbd_input(savepath, MAX_PATH)) {
604 DEBUGF("Keyboard input failed\n");
605 return -1;
608 fd = rb->open(savepath, O_WRONLY|O_CREAT);
609 DEBUGF("savepath: %s\n", savepath);
610 if(fd < 0) {
611 DEBUGF("Couldn't create/open file\n");
612 return -1;
615 rb->write(fd, "SSGv2", 5);
616 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
617 rb->write(fd, &humanres.food, sizeof(humanres.food));
618 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
619 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
620 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
621 rb->write(fd, &humanres.men, sizeof(humanres.men));
622 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
623 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
624 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
625 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
626 rb->write(fd, &compres.cash, sizeof(compres.cash));
627 rb->write(fd, &compres.food, sizeof(compres.food));
628 rb->write(fd, &compres.bank, sizeof(compres.bank));
629 rb->write(fd, &compres.planes, sizeof(compres.planes));
630 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
631 rb->write(fd, &compres.men, sizeof(compres.men));
632 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
633 rb->write(fd, &compres.inds, sizeof(compres.inds));
634 rb->write(fd, &compres.farms, sizeof(compres.farms));
635 rb->write(fd, &compres.moves, sizeof(compres.moves));
636 rb->write(fd, board, sizeof(board));
637 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
638 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
639 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
640 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
641 rb->write(fd, &superdom_settings.startcash, sizeof(int));
642 rb->write(fd, &superdom_settings.startfood, sizeof(int));
643 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
644 rb->close(fd);
645 return 0;
648 int ingame_menu(void) {
649 int selection = 0;
651 MENUITEM_STRINGLIST(ingame_menu,"Super Domination Menu",NULL,
652 "Return to game","Save Game", "Quit");
654 selection=rb->do_menu(&ingame_menu,&selection, NULL, false);
655 switch(selection) {
656 case 0:
657 return 0;
658 break;
659 case 1:
660 if(!save_game())
661 rb->splash(HZ, "Game saved");
662 else
663 rb->splash(HZ, "Error in save");
664 break;
665 case 2:
666 return SUPERDOM_QUIT;
667 break;
668 case MENU_ATTACHED_USB:
669 return PLUGIN_USB_CONNECTED;
670 break;
672 return 0;
675 int get_number(char* param, int* value) {
676 //int numbers[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
677 int numbers[3][3];
678 numbers[0][0] = 1;
679 numbers[0][1] = 2;
680 numbers[0][2] = 3;
681 numbers[1][0] = 4;
682 numbers[1][1] = 5;
683 numbers[1][2] = 6;
684 numbers[2][0] = 7;
685 numbers[2][1] = 8;
686 numbers[2][2] = 9;
687 rb->lcd_clear_display();
688 /* Draw a 3x4 grid */
689 int i,j,x=0,y=0;
690 for(i=0;i<=3;i++) { /* Vertical lines */
691 rb->lcd_drawline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
692 NUM_MARGIN_X+(NUM_BOX_WIDTH*i),
693 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
695 for(i=0;i<=4;i++) { /* Horizontal lines */
696 rb->lcd_drawline(NUM_MARGIN_X, NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT),
697 NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
698 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
700 int temp = 1;
701 for(i=0;i<3;i++) {
702 for(j=0;j<3;j++) {
703 rb->snprintf(buf, sizeof(buf), "%d", temp);
704 rb->lcd_putsxy(NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+10,
705 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+8, buf);
706 temp++;
709 rb->lcd_putsxy(NUM_MARGIN_X+5, NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "CLR");
710 rb->lcd_putsxy(NUM_MARGIN_X+NUM_BOX_WIDTH+10,
711 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "0");
712 rb->lcd_putsxy(NUM_MARGIN_X+2*NUM_BOX_WIDTH+8,
713 NUM_MARGIN_Y+(3*NUM_BOX_HEIGHT)+8, "OK");
714 rb->snprintf(buf,sizeof(buf), "%d", *value);
715 rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
716 int height, width;
717 rb->lcd_getstringsize(param, &width, &height);
718 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
719 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
720 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
721 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y), NUM_BOX_WIDTH+1,
722 NUM_BOX_HEIGHT+1);
723 rb->lcd_set_drawmode(DRMODE_SOLID);
724 int button = 0;
725 rb->lcd_update();
726 while(1) {
727 button = rb->button_get(true);
728 switch(button) {
729 case SUPERDOM_OK:
730 *value *= 10;
731 if(y!=3) {
732 *value += numbers[y][x];
733 } else if(y==3 && x==0) {
734 *value /= 100;
735 } else if(y==3 && x==2) {
736 *value /= 10;
737 return 0;
739 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
740 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
741 LCD_WIDTH, 30);
742 rb->lcd_set_drawmode(DRMODE_SOLID);
743 rb->snprintf(buf,sizeof(buf), "%d", *value);
744 rb->lcd_putsxy(NUM_MARGIN_X+10,
745 NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
746 break;
747 case SUPERDOM_CANCEL:
748 return 0;
749 break;
750 #if CONFIG_KEYPAD != IRIVER_H10_PAD
751 case SUPERDOM_LEFT:
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 if(x==0) {
758 #ifdef IPOD_STYLE
759 if(y>0)
760 y--;
761 else
762 y=3;
763 #endif
764 x=2;
765 } else {
766 x--;
768 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
769 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
770 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
771 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
772 rb->lcd_set_drawmode(DRMODE_SOLID);
773 break;
774 case SUPERDOM_RIGHT:
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 if(x==2) {
781 #ifdef IPOD_STYLE
782 if(y==3)
783 y=0;
784 else
785 y++;
786 #endif
787 x=0;
788 } else {
789 x++;
791 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
792 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
793 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
794 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
795 rb->lcd_set_drawmode(DRMODE_SOLID);
796 break;
797 #endif
798 #ifndef IPOD_STYLE
799 case SUPERDOM_UP:
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 if(y==0) {
806 #if CONFIG_KEYPAD == IRIVER_H10_PAD
807 if(x > 0)
808 x--;
809 else
810 x=2;
811 #endif
812 y=3;
813 } else {
814 y--;
816 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
817 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
818 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
819 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
820 rb->lcd_set_drawmode(DRMODE_SOLID);
821 break;
822 case SUPERDOM_DOWN:
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 if(y==3) {
829 #if CONFIG_KEYPAD == IRIVER_H10_PAD
830 if(x < 2)
831 x++;
832 else
833 x=0;
834 #endif
835 y=0;
836 } else {
837 y++;
839 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
840 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
841 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
842 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
843 rb->lcd_set_drawmode(DRMODE_SOLID);
844 break;
845 #endif
846 default:
847 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
849 return PLUGIN_USB_CONNECTED;
851 break;
853 rb->lcd_update();
855 return 0;
858 int buy_resources_menu(void) {
859 int selection,tempmenu,nummen;
861 MENUITEM_STRINGLIST(res_menu, "Buy Resources", NULL, "Buy men ($1)",
862 "Buy tank ($300)", "Buy plane ($600)", "Buy Farm ($1150)",
863 "Buy Factory ($1300)", "Buy Nuke ($2000)",
864 "Finish buying", "Game menu");
866 resources_menu:
867 selection=rb->do_menu(&res_menu,&selection, NULL, false);
868 switch(selection) {
869 case 0:
870 nummen = 0;
871 if(get_number("How many men would you like?", &nummen)
872 == PLUGIN_USB_CONNECTED)
873 return PLUGIN_USB_CONNECTED;
874 if(humanres.cash>=nummen) {
875 rb->splash(HZ, "Where do you want to place them?");
876 tempmenu = select_square();
877 switch(tempmenu) {
878 case 0:
879 rb->splash(HZ, "Cancelled");
880 break;
881 case 2:
882 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
883 humanres.men += nummen;
884 board[cursor.x][cursor.y].men += nummen;
885 humanres.cash -= nummen;
886 } else {
887 rb->splash(HZ,"Can't place men on enemy territory");
889 break;
890 case PLUGIN_USB_CONNECTED:
891 return PLUGIN_USB_CONNECTED;
892 break;
894 } else {
895 rb->splash(HZ, "Not enough money!");
897 goto resources_menu;
898 break;
899 case 1:
900 if(humanres.cash>=300) {
901 rb->splash(HZ, "Where do you want to place the tank?");
902 tempmenu = select_square();
903 switch(tempmenu) {
904 case 0:
905 rb->splash(HZ, "Cancelled");
906 goto resources_menu;
907 break;
908 case PLUGIN_USB_CONNECTED:
909 return PLUGIN_USB_CONNECTED;
910 break;
912 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
913 if(board[cursor.x][cursor.y].tank) {
914 rb->splash(HZ, "There is already a tank there");
915 } else {
916 board[cursor.x][cursor.y].tank = true;
917 humanres.cash -= 300;
918 humanres.tanks++;
920 } else {
921 rb->splash(HZ, "Can't place men on enemy territory");
923 } else {
924 rb->splash(HZ, "Not enough money!");
926 goto resources_menu;
927 break;
928 case 2:
929 if(humanres.cash>=600) {
930 rb->splash(HZ, "Where do you want to place the plane?");
931 tempmenu = select_square();
932 switch(tempmenu) {
933 case 0:
934 rb->splash(HZ, "Cancelled");
935 goto resources_menu;
936 break;
937 case PLUGIN_USB_CONNECTED:
938 return PLUGIN_USB_CONNECTED;
939 break;
941 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
942 if(board[cursor.x][cursor.y].plane) {
943 rb->splash(HZ, "There is already a plane there");
944 } else {
945 board[cursor.x][cursor.y].plane = true;
946 humanres.cash -= 600;
947 humanres.planes++;
949 } else {
950 rb->splash(HZ, "Can't place men on enemy territory");
952 } else {
953 rb->splash(HZ, "Not enough money!");
955 goto resources_menu;
956 break;
957 case 3:
958 if(humanres.cash>=1150) {
959 rb->splash(HZ, "Where do you want to place the farm?");
960 tempmenu = select_square();
961 switch(tempmenu) {
962 case 0:
963 rb->splash(HZ, "Cancelled");
964 goto resources_menu;
965 break;
966 case PLUGIN_USB_CONNECTED:
967 return PLUGIN_USB_CONNECTED;
968 break;
970 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
971 if(board[cursor.x][cursor.y].farm) {
972 rb->splash(HZ, "There is already a farm there");
973 } else {
974 board[cursor.x][cursor.y].farm = true;
975 humanres.cash -= 1150;
976 humanres.farms++;
978 } else {
979 rb->splash(HZ, "Can't build on enemy territory");
981 } else {
982 rb->splash(HZ, "Not enough money!");
984 goto resources_menu;
985 break;
986 case 4:
987 if(humanres.cash>=1300) {
988 rb->splash(HZ, "Where do you want to place the industrial"
989 " plant?");
990 tempmenu = select_square();
991 switch(tempmenu) {
992 case 0:
993 rb->splash(HZ, "Cancelled");
994 goto resources_menu;
995 break;
996 case PLUGIN_USB_CONNECTED:
997 return PLUGIN_USB_CONNECTED;
998 break;
1000 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1001 if(board[cursor.x][cursor.y].ind) {
1002 rb->splash(HZ, "There is already an industrial"
1003 " plant there");
1004 } else {
1005 board[cursor.x][cursor.y].ind = true;
1006 humanres.cash -= 1300;
1007 humanres.inds++;
1009 } else {
1010 rb->splash(HZ, "Can't build on enemy territory");
1012 } else {
1013 rb->splash(HZ, "Not enough money!");
1015 goto resources_menu;
1016 break;
1017 case 5:
1018 if(humanres.cash>=2000) {
1019 rb->splash(HZ, "Where do you want to place the nuke?");
1020 tempmenu = select_square();
1021 switch(tempmenu) {
1022 case 0:
1023 rb->splash(HZ, "Cancelled");
1024 goto resources_menu;
1025 break;
1026 case PLUGIN_USB_CONNECTED:
1027 return PLUGIN_USB_CONNECTED;
1028 break;
1030 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1031 if(board[cursor.x][cursor.y].nuke) {
1032 rb->splash(HZ, "There is already a nuke there");
1033 } else {
1034 board[cursor.x][cursor.y].nuke = true;
1035 humanres.cash -= 2000;
1036 humanres.nukes++;
1038 } else {
1039 rb->splash(HZ, "Can't place a nuke on enemy territory");
1041 } else {
1042 rb->splash(HZ, "Not enough money!");
1044 goto resources_menu;
1045 break;
1046 case 6:
1047 return 0;
1048 break;
1049 case MENU_ATTACHED_USB:
1050 return PLUGIN_USB_CONNECTED;
1051 break;
1053 return 0;
1056 int move_unit(void) {
1057 int selection, nummen;
1058 struct cursor from;
1060 MENUITEM_STRINGLIST(move_unit_menu, "Move unit", NULL, "Move men",
1061 "Move tank", "Move plane");
1062 selection=rb->do_menu(&move_unit_menu,&selection, NULL, false);
1063 switch(selection) {
1064 case 0:
1065 rb->splash(HZ, "Select where to move troops from");
1066 if(select_square() == PLUGIN_USB_CONNECTED)
1067 return PLUGIN_USB_CONNECTED;
1068 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1069 if(board[cursor.x][cursor.y].men) {
1070 from.x = cursor.x;
1071 from.y = cursor.y;
1072 nummen = board[from.x][from.y].men;
1073 if(get_number("How many men do you want to move?",
1074 &nummen) == PLUGIN_USB_CONNECTED)
1075 return PLUGIN_USB_CONNECTED;
1076 if(nummen > board[from.x][from.y].men) {
1077 rb->splash(HZ, "You don't have that many troops.");
1078 } else {
1079 rb->splash(HZ,"Select where to move the troops to");
1080 if(select_square() == PLUGIN_USB_CONNECTED)
1081 return PLUGIN_USB_CONNECTED;
1082 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT) &&
1083 (abs(cursor.x - from.x) <= 1) &&
1084 abs(cursor.y - from.y) <= 1) {
1085 board[from.x][from.y].men -= nummen;
1086 board[cursor.x][cursor.y].men += nummen;
1087 humanres.moves--;
1088 return 0;
1091 } else {
1092 rb->splash(HZ, "You don't have any troops there");
1094 } else {
1095 rb->splash(HZ, "Can't move enemy troops");
1097 break;
1098 case 1:
1099 rb->splash(HZ, "Select where you want to move the tank from");
1100 if(select_square() == PLUGIN_USB_CONNECTED)
1101 return PLUGIN_USB_CONNECTED;
1102 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1103 if(board[cursor.x][cursor.y].tank) {
1104 from.x = cursor.x;
1105 from.y = cursor.y;
1106 rb->splash(HZ, "Select where you want"
1107 " to move the tank to");
1108 if(select_square() == PLUGIN_USB_CONNECTED)
1109 return PLUGIN_USB_CONNECTED;
1110 if((board[cursor.x][cursor.y].colour == COLOUR_LIGHT)&&
1111 (abs(cursor.x-from.x) <= 1) &&
1112 (abs(cursor.y-from.y) <= 1)) {
1113 if(board[cursor.x][cursor.y].tank) {
1114 rb->splash(HZ, "There is already a tank there");
1115 } else {
1116 board[from.x][from.y].tank = false;
1117 board[cursor.x][cursor.y].tank = true;
1118 humanres.moves--;
1119 return 0;
1121 } else {
1122 rb->splash(HZ, "Invalid move");
1124 } else {
1125 rb->splash(HZ, "You don't have a tank there");
1127 } else {
1128 rb->splash(HZ, "That isn't your territory");
1130 break;
1131 case 2:
1132 rb->splash(HZ, "Select where you want"
1133 " to move the plane from");
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 from.x = cursor.x;
1139 from.y = cursor.y;
1140 rb->splash(HZ, "Select where you want"
1141 " to move the plane to");
1142 if(select_square() == PLUGIN_USB_CONNECTED)
1143 return PLUGIN_USB_CONNECTED;
1144 if(board[cursor.x][cursor.y].colour == COLOUR_LIGHT) {
1145 if(board[cursor.x][cursor.y].plane) {
1146 rb->splash(HZ,"There is already a plane there");
1147 } else {
1148 board[from.x][from.y].plane = false;
1149 board[cursor.x][cursor.y].plane = true;
1150 humanres.moves--;
1151 return 0;
1153 } else {
1154 rb->splash(HZ, "Invalid move");
1156 } else {
1157 rb->splash(HZ, "You don't have a plane there");
1159 } else {
1160 rb->splash(HZ, "That isn't your territory");
1162 break;
1164 return 0;
1167 int movement_menu(void) {
1168 int selection, tempmenu;
1169 bool menu_quit = false;
1171 MENUITEM_STRINGLIST(move_menu, "Movement", NULL, "Move unit",
1172 "Buy additional moves ($100)", "Launch nuclear missile",
1173 "Check map", "Finish moving", "Game menu");
1175 while(!menu_quit) {
1176 selection=rb->do_menu(&move_menu,&selection, NULL, false);
1177 switch(selection) {
1178 case 0:
1179 if(humanres.moves) {
1180 if(move_unit()==PLUGIN_USB_CONNECTED)
1181 return PLUGIN_USB_CONNECTED;
1182 } else {
1183 rb->splash(HZ, "You have no more moves left."
1184 " You can buy more for $100 each.");
1186 break;
1187 case 1:
1188 if(humanres.cash > 100) {
1189 humanres.moves++;
1190 humanres.cash -= 100;
1191 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1192 humanres.moves);
1193 rb->splash(HZ, buf);
1195 break;
1196 case 2:
1197 if(humanres.nukes==0) {
1198 rb->splash(HZ, "You do not have any nukes to launch");
1199 } else {
1200 rb->splash(HZ, "Select place to launch nuke from");
1201 if(select_square() == PLUGIN_USB_CONNECTED) {
1202 return PLUGIN_USB_CONNECTED;
1204 if(board[cursor.x][cursor.y].nuke) {
1205 rb->splash(HZ, "Select place to target with nuke");
1206 if(select_square() == PLUGIN_USB_CONNECTED) {
1207 return PLUGIN_USB_CONNECTED;
1209 board[cursor.x][cursor.y].men = 0;
1210 board[cursor.x][cursor.y].tank = 0;
1211 board[cursor.x][cursor.y].plane = 0;
1212 board[cursor.x][cursor.y].ind = 0;
1213 board[cursor.x][cursor.y].nuke = 0;
1214 board[cursor.x][cursor.y].farm = 0;
1215 /* TODO: Fallout carried by wind */
1218 break;
1219 case 3:
1220 if(select_square() == PLUGIN_USB_CONNECTED)
1221 return PLUGIN_USB_CONNECTED;
1222 break;
1223 case 4:
1224 return 0;
1225 break;
1226 case 5:
1227 tempmenu = ingame_menu();
1228 switch(tempmenu) {
1229 case PLUGIN_USB_CONNECTED:
1230 return PLUGIN_USB_CONNECTED;
1231 break;
1232 case SUPERDOM_QUIT:
1233 return SUPERDOM_QUIT;
1234 break;
1236 break;
1237 case MENU_ATTACHED_USB:
1238 return PLUGIN_USB_CONNECTED;
1239 break;
1242 return 0;
1245 int show_inventory(void) {
1246 rb->lcd_clear_display();
1247 rb->lcd_puts(1, 0, "Inventory");
1248 char men[20], tanks[20], planes[20], inds[20], farms[20], nukes[20],
1249 cash[20], food[20], bank[20];
1250 rb->snprintf(men, sizeof(men), "Men: %d", humanres.men);
1251 rb->snprintf(tanks, sizeof(tanks), "Tanks: %d", humanres.tanks);
1252 rb->snprintf(planes, sizeof(planes), "Planes: %d", humanres.planes);
1253 rb->snprintf(inds, sizeof(inds), "Factories: %d", humanres.inds);
1254 rb->snprintf(farms, sizeof(farms), "Farms: %d", humanres.farms);
1255 rb->snprintf(nukes, sizeof(nukes), "Nukes: %d", humanres.nukes);
1256 rb->snprintf(cash, sizeof(cash), "Cash: %d", humanres.cash);
1257 rb->snprintf(food, sizeof(food), "Food: %d", humanres.food);
1258 rb->snprintf(bank, sizeof(bank), "Bank: %d", humanres.bank);
1259 rb->lcd_puts(2, 1, men);
1260 rb->lcd_puts(2, 2, tanks);
1261 rb->lcd_puts(2, 3, planes);
1262 rb->lcd_puts(2, 4, inds);
1263 rb->lcd_puts(2, 5, farms);
1264 rb->lcd_puts(2, 6, nukes);
1265 rb->lcd_puts(2, 7, cash);
1266 rb->lcd_puts(2, 8, food);
1267 rb->lcd_puts(2, 9, bank);
1268 rb->lcd_update();
1269 if(rb->default_event_handler(rb->button_get(true)) == SYS_USB_CONNECTED) {
1270 return PLUGIN_USB_CONNECTED;
1271 } else {
1272 return 0;
1276 int production_menu(void) {
1277 int selection, tempbank, tempmenu;
1279 MENUITEM_STRINGLIST(prod_menu, "Production", NULL, "Buy resources",
1280 "Show inventory", "Check map", "Invest money",
1281 "Withdraw money", "Finish turn", "Game menu");
1283 while(1) {
1284 selection=rb->do_menu(&prod_menu,&selection, NULL, false);
1285 switch(selection) {
1286 case 0:
1287 tempmenu = buy_resources_menu();
1288 switch(tempmenu) {
1289 case PLUGIN_USB_CONNECTED:
1290 return PLUGIN_USB_CONNECTED;
1291 break;
1292 case SUPERDOM_QUIT:
1293 return SUPERDOM_QUIT;
1294 break;
1296 break;
1297 case 1:
1298 tempmenu = show_inventory();
1299 switch(tempmenu) {
1300 case 0:
1301 break;
1302 case PLUGIN_USB_CONNECTED:
1303 return PLUGIN_USB_CONNECTED;
1304 break;
1306 break;
1307 case 2:
1308 tempmenu = select_square();
1309 switch(tempmenu) {
1310 case PLUGIN_USB_CONNECTED:
1311 return PLUGIN_USB_CONNECTED;
1312 break;
1313 case SUPERDOM_QUIT:
1314 return SUPERDOM_QUIT;
1315 break;
1316 case 0:
1317 break;
1319 break;
1320 case 3:
1321 tempbank = humanres.cash;
1322 if(get_number("How much do you want to invest?", &tempbank)
1323 == PLUGIN_USB_CONNECTED)
1324 return PLUGIN_USB_CONNECTED;
1325 if(tempbank>humanres.cash) {
1326 rb->splash(HZ, "You don't have that much cash to invest");
1327 } else {
1328 humanres.cash -= tempbank;
1329 humanres.bank += tempbank;
1331 break;
1332 case 4:
1333 tempbank = 0;
1334 if(get_number("How much do you want to withdraw?", &tempbank)
1335 == PLUGIN_USB_CONNECTED)
1336 return PLUGIN_USB_CONNECTED;
1337 if(tempbank>humanres.bank) {
1338 rb->splash(HZ, "You don't have that much cash to withdraw");
1339 } else {
1340 humanres.cash += tempbank;
1341 humanres.bank -= tempbank;
1343 break;
1344 case 5:
1345 return 0;
1346 break;
1347 case 6:
1348 tempmenu = ingame_menu();
1349 switch(tempmenu) {
1350 case PLUGIN_USB_CONNECTED:
1351 return PLUGIN_USB_CONNECTED;
1352 break;
1353 case SUPERDOM_QUIT:
1354 return SUPERDOM_QUIT;
1355 break;
1357 break;
1358 case MENU_ATTACHED_USB:
1359 return PLUGIN_USB_CONNECTED;
1360 break;
1363 return 0;
1366 void init_resources(void) {
1367 humanres.cash = superdom_settings.startcash;
1368 humanres.food = superdom_settings.startfood;
1369 humanres.tanks = 0;
1370 humanres.planes = 0;
1371 humanres.nukes = 0;
1372 humanres.inds = 0;
1373 humanres.farms = 0;
1374 humanres.men = 0;
1375 humanres.bank = 0;
1376 humanres.moves = 0;
1377 compres.cash = superdom_settings.startcash;
1378 compres.food = superdom_settings.startfood;
1379 compres.tanks = 0;
1380 compres.planes = 0;
1381 compres.nukes = 0;
1382 compres.inds = 0;
1383 compres.farms = 0;
1384 compres.men = 0;
1385 compres.bank = 0;
1386 compres.moves = 0;
1389 int select_square(void) {
1390 draw_board();
1391 draw_cursor();
1392 update_score();
1393 #if LCD_WIDTH >= 220
1394 rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
1395 rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
1396 rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
1397 rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
1398 #endif
1399 rb->lcd_update();
1400 int button = 0;
1401 while(1) {
1402 button = rb->button_get(true);
1403 switch(button) {
1404 case SUPERDOM_CANCEL:
1405 return 0;
1406 break;
1407 case SUPERDOM_OK:
1408 return 2;
1409 break;
1410 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1411 case SUPERDOM_LEFT:
1412 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1413 draw_cursor(); /* Deselect the current tile */
1414 if(cursor.x>1) {
1415 cursor.x--;
1416 } else {
1417 #ifdef IPOD_STYLE
1418 if(cursor.y>1)
1419 cursor.y--;
1420 else
1421 cursor.y = 10;
1422 #endif
1423 cursor.x = 10;
1425 update_score();
1426 draw_cursor();
1427 break;
1428 case SUPERDOM_RIGHT:
1429 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1430 draw_cursor(); /* Deselect the current tile */
1431 if(cursor.x<10) {
1432 cursor.x++;
1433 } else {
1434 #ifdef IPOD_STYLE
1435 if(cursor.y<10)
1436 cursor.y++;
1437 else
1438 cursor.y = 1;
1439 #endif
1440 cursor.x = 1;
1442 update_score();
1443 draw_cursor();
1444 break;
1445 #endif
1446 #ifndef IPOD_STYLE
1447 case SUPERDOM_UP:
1448 case (SUPERDOM_UP|BUTTON_REPEAT):
1449 draw_cursor(); /* Deselect the current tile */
1450 if(cursor.y>1) {
1451 cursor.y--;
1452 } else {
1453 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1454 if(cursor.x > 1)
1455 cursor.x--;
1456 else
1457 cursor.x = 10;
1458 #endif
1459 cursor.y = 10;
1461 update_score();
1462 draw_cursor();
1463 break;
1464 case SUPERDOM_DOWN:
1465 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1466 draw_cursor(); /* Deselect the current tile */
1467 if(cursor.y<10) {
1468 cursor.y++;
1469 } else {
1470 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1471 if(cursor.x < 10)
1472 cursor.x++;
1473 else
1474 cursor.x = 1;
1475 #endif
1476 cursor.y = 1;
1478 update_score();
1479 draw_cursor();
1480 break;
1481 #endif
1482 default:
1483 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1485 return PLUGIN_USB_CONNECTED;
1491 int killmen(bool human) {
1492 int menkilled,i,j;
1493 int percent;
1494 if(human) {
1495 percent = (humanres.food*1000)/humanres.men;
1496 humanres.food = 0;
1497 } else {
1498 percent = (compres.food*1000)/compres.men;
1499 compres.food = 0;
1501 menkilled = 0;
1502 for(i=1;i<12;i++) {
1503 for(j=1;j<12;j++) {
1504 if(board[i][j].colour == human) {
1505 menkilled += ((board[i][j].men * percent)/1000);
1506 board[i][j].men = (board[i][j].men * percent)/1000;
1511 if(human)
1512 humanres.men -= menkilled;
1513 else
1514 compres.men -= menkilled;
1515 return menkilled;
1518 int war_menu(void) {
1519 int selection, tempmenu;
1521 MENUITEM_STRINGLIST(wartime_menu, "War!", NULL,
1522 "Select territory to attack", "Finish turn", "Game menu");
1524 humanres.moves = superdom_settings.movesperturn;
1525 while(humanres.moves) {
1526 selection=rb->do_menu(&wartime_menu,&selection, NULL, false);
1527 switch(selection) {
1528 case 0:
1529 if(select_square() == PLUGIN_USB_CONNECTED)
1530 return PLUGIN_USB_CONNECTED;
1531 if(board[cursor.x][cursor.y].colour == COLOUR_DARK) {
1532 if(calc_strength(COLOUR_LIGHT, cursor.x,
1533 cursor.y) > calc_strength(COLOUR_DARK,
1534 cursor.x, cursor.y)) {
1535 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1536 board[cursor.x][cursor.y].tank = 0;
1537 board[cursor.x][cursor.y].men = 0;
1538 board[cursor.x][cursor.y].plane = 0;
1539 board[cursor.x][cursor.y].nuke = 0;
1540 draw_board();
1541 rb->sleep(HZ*2);
1542 humanres.moves--;
1543 } else if(calc_strength(COLOUR_LIGHT, cursor.x, cursor.y)==
1544 calc_strength(COLOUR_DARK, cursor.x, cursor.y)) {
1545 if(rb->rand()%2) {
1546 board[cursor.x][cursor.y].colour = COLOUR_LIGHT;
1547 board[cursor.x][cursor.y].tank = 0;
1548 board[cursor.x][cursor.y].men = 0;
1549 board[cursor.x][cursor.y].plane = 0;
1550 board[cursor.x][cursor.y].nuke = 0;
1551 draw_board();
1552 rb->sleep(HZ*2);
1553 humanres.moves--;
1554 } else {
1555 rb->splash(HZ, "Your troops were unable to"
1556 " overcome the enemy troops");
1557 humanres.moves--;
1559 } else {
1560 rb->splash(HZ, "Your troops were unable to overcome"
1561 " the enemy troops");
1562 humanres.moves--;
1564 } else {
1565 rb->splash(HZ, "You can't attack your own territory");
1567 break;
1568 case 1:
1569 return 0;
1570 break;
1571 case 2:
1572 tempmenu = ingame_menu();
1573 switch(tempmenu) {
1574 case PLUGIN_USB_CONNECTED:
1575 return PLUGIN_USB_CONNECTED;
1576 break;
1577 case SUPERDOM_QUIT:
1578 return SUPERDOM_QUIT;
1579 break;
1581 break;
1584 return 0;
1587 struct threat {
1588 int x;
1589 int y;
1590 int str_diff;
1593 bool place_adjacent(bool tank, int x, int y) {
1594 if(tank) {
1595 if(!board[x-1][y].tank && (board[x][y].colour==board[x-1][y].colour)) {
1596 compres.cash -= 300;
1597 board[x-1][y].tank = true;
1598 compres.tanks++;
1599 return 0;
1601 if(!board[x+1][y].tank && (board[x][y].colour==board[x+1][y].colour)) {
1602 compres.cash -= 300;
1603 board[x+1][y].tank = true;
1604 compres.tanks++;
1605 return 0;
1607 if(!board[x][y-1].tank && (board[x][y].colour==board[x][y-1].colour)) {
1608 compres.cash -= 300;
1609 board[x][y-1].tank = true;
1610 compres.tanks++;
1611 return 0;
1613 if(!board[x][y+1].tank && (board[x][y].colour==board[x][y+1].colour)) {
1614 compres.cash -= 300;
1615 board[x][y+1].tank = true;
1616 compres.tanks++;
1617 return 0;
1619 } else {
1620 if(!board[x-1][y].plane && (board[x][y].colour==board[x-1][y].colour)) {
1621 compres.cash -= 600;
1622 board[x-1][y].plane = true;
1623 compres.planes++;
1624 return 0;
1626 if(!board[x+1][y].plane && (board[x][y].colour==board[x+1][y].colour)) {
1627 compres.cash -= 600;
1628 board[x+1][y].plane = true;
1629 compres.planes++;
1630 return 0;
1632 if(!board[x][y-1].plane && (board[x][y].colour==board[x][y-1].colour)) {
1633 compres.cash -= 600;
1634 board[x][y-1].plane = true;
1635 compres.planes++;
1636 return 0;
1638 if(!board[x][y+1].plane && (board[x][y].colour==board[x][y+1].colour)) {
1639 compres.cash -= 600;
1640 board[x][y+1].plane = true;
1641 compres.planes++;
1642 return 0;
1645 return 1;
1648 bool has_adjacent(int x, int y) {
1649 if((board[x][y].colour == COLOUR_LIGHT) &&
1650 ((board[x-1][y].colour == COLOUR_DARK) ||
1651 (board[x+1][y].colour == COLOUR_DARK) ||
1652 (board[x][y+1].colour == COLOUR_DARK) ||
1653 (board[x][y-1].colour == COLOUR_DARK)))
1654 return 1;
1655 else
1656 return 0;
1659 void find_adjacent(int x, int y, int* adj_x, int* adj_y, bool* full) {
1660 /* Finds adjacent squares, returning squares without tanks on them
1661 * in preference to those with them */
1662 if(((board[x-1][y].tank && (board[x-1][y].colour == COLOUR_DARK)) ||
1663 board[x-1][y].colour != COLOUR_DARK) &&
1664 ((board[x+1][y].tank && (board[x+1][y].colour == COLOUR_DARK)) ||
1665 board[x+1][y].colour != COLOUR_DARK) &&
1666 ((board[x][y-1].tank && (board[x][y-1].colour == COLOUR_DARK)) ||
1667 board[x][y-1].colour != COLOUR_DARK) &&
1668 ((board[x][y+1].tank && (board[x][y+1].colour == COLOUR_DARK)) ||
1669 board[x][y+1].colour != COLOUR_DARK)) {
1670 *full = true;
1671 } else {
1672 *full = false;
1675 if(board[x-1][y].colour == COLOUR_DARK) {
1676 *adj_x = x-1;
1677 *adj_y = y;
1678 if(board[x-1][y].tank) {
1679 if(*full)
1680 return;
1681 } else {
1682 return;
1685 if(board[x+1][y].colour == COLOUR_DARK) {
1686 *adj_x = x+1;
1687 *adj_y = y;
1688 if(board[x+1][y].tank) {
1689 if(*full)
1690 return;
1691 } else {
1692 return;
1695 if(board[x][y-1].colour == COLOUR_DARK) {
1696 *adj_x = x;
1697 *adj_y = y-1;
1698 if(board[x][y-1].tank) {
1699 if(*full)
1700 return;
1701 } else {
1702 return;
1705 if(board[x][y+1].colour == COLOUR_DARK) {
1706 *adj_x = x;
1707 *adj_y = y+1;
1708 if(board[x][y+1].tank) {
1709 if(*full)
1710 return;
1711 } else {
1712 return;
1717 void computer_allocate(void) {
1718 /* Firstly, decide whether to go offensive or defensive.
1719 * This is primarily decided by the human player posing a threat to either
1720 * the computer's farms or factories */
1721 int i, j, k;
1722 bool offensive = true;
1723 struct threat threats[4];
1724 int numthreats = 0;
1725 int total_str_diff = 0;
1726 int men_needed;
1727 struct threat targets[2];
1728 int numtargets;
1729 struct cursor adj;
1730 bool full = false;
1731 for(i=1;i<12;i++) {
1732 for(j=1;j<12;j++) {
1733 if((board[i][j].colour == COLOUR_DARK) &&
1734 (calc_strength(COLOUR_DARK,i,j) <
1735 calc_strength(COLOUR_LIGHT,i,j))) {
1736 if(board[i][j].ind || board[i][j].farm) {
1737 if(numthreats < 3) {
1738 offensive = false;
1739 threats[numthreats].x = i;
1740 threats[numthreats].y = j;
1741 threats[numthreats].str_diff =
1742 calc_strength(COLOUR_LIGHT,i,j) -
1743 calc_strength(COLOUR_DARK,i,j);
1744 numthreats++;
1750 if(offensive) {
1751 /* The AI is going to go straight for the throat here and attack
1752 * the player's farms and factories. The amount of cash
1753 * the AI has to spend will determine how many targets there are */
1754 if(compres.cash > 1200) {
1755 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1756 numtargets = 2;
1757 } else {
1758 numtargets = 1;
1760 /* Work out which target(s) to attack. They must have adjacent squares
1761 * owned by the computer. If none are found just place troops in
1762 * random places around the map until we run out of money */
1763 k = 0;
1764 while(k<numtargets) {
1765 for(i=1;i<12;i++) {
1766 for(j=1;j<12;j++) {
1767 if((board[i][j].colour == COLOUR_LIGHT) &&
1768 (board[i][j].ind || board[i][j].farm) &&
1769 has_adjacent(i,j)) {
1770 targets[k].x = i;
1771 targets[k].y = j;
1772 targets[k].str_diff = abs(calc_strength(COLOUR_LIGHT,
1773 i, j) - calc_strength(COLOUR_DARK,
1774 i, j));
1775 k++;
1780 if(k == 0) {
1781 /* No targets found! Randomly pick squares and if they're owned
1782 * by the computer then stick a tank on it. */
1783 rb->srand(*rb->current_tick);
1784 while(compres.cash >= 300) {
1785 i = rb->rand()%11 + 1;
1786 j = rb->rand()%11 + 1;
1787 if(board[i][j].colour == COLOUR_DARK) {
1788 if(compres.cash >= 300) {
1789 if(!board[i][j].tank) {
1790 board[i][j].tank = true;
1791 compres.tanks++;
1792 compres.cash -= 300;
1793 draw_board();
1794 rb->sleep(HZ);
1799 compres.bank += compres.cash;
1800 compres.cash = 0;
1801 } else {
1802 for(i=0;i<k;i++) {
1803 men_needed = targets[i].str_diff + 20;
1804 find_adjacent(targets[i].x,targets[i].y, &adj.x, &adj.y, &full);
1805 while(((calc_strength(COLOUR_LIGHT, targets[i].x, targets[i].y)
1806 + 20) > calc_strength(COLOUR_DARK, targets[i].x,
1807 targets[i].y)) && compres.cash > 0) {
1808 /* While we still need them keep placing men */
1809 if(compres.cash >= 300 && !full) {
1810 if(board[adj.x][adj.y].tank) {
1811 find_adjacent(targets[i].x, targets[i].y,
1812 &adj.x, &adj.y, &full);
1813 } else {
1814 board[adj.x][adj.y].tank = true;
1815 compres.tanks++;
1816 compres.cash -= 300;
1817 draw_board();
1818 rb->sleep(HZ);
1820 } else {
1821 men_needed = (calc_strength(COLOUR_LIGHT, targets[i].x,
1822 targets[i].y) + 20 -
1823 calc_strength(COLOUR_DARK, targets[i].x,
1824 targets[i].y))*1000/133;
1825 if(compres.cash >= men_needed) {
1826 board[adj.x][adj.y].men += men_needed;
1827 compres.men += men_needed;
1828 compres.cash -= men_needed;
1829 compres.bank += compres.cash;
1830 compres.cash = 0;
1831 } else {
1832 board[adj.x][adj.y].men += compres.cash;
1833 compres.men += compres.cash;
1834 compres.cash = 0;
1836 draw_board();
1837 rb->sleep(HZ);
1841 compres.bank += compres.cash;
1842 compres.cash = 0;
1844 } else {
1845 /* Work out what to place on each square to defend it.
1846 * Tanks are preferential because they do not require food,
1847 * but if the budget is tight then we fall back onto troops.
1848 * Conversely if cash is not an issue and there are already tanks in
1849 * place planes will be deployed. We would like a margin of at least
1850 * 20 points to be safe. */
1852 for(i=0;i<numthreats;i++) {
1853 total_str_diff += threats[i].str_diff;
1855 if((total_str_diff+20)*10 > compres.cash) {
1856 /* Not enough cash to accomodate all threats using tanks alone -
1857 * use men as a backup */
1858 for(i=0;i<numthreats;i++) {
1859 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1860 if(compres.cash >= men_needed) {
1861 board[threats[i].x][threats[i].y].men += men_needed;
1862 compres.cash -= men_needed;
1863 compres.men += men_needed;
1864 draw_board();
1865 rb->sleep(HZ);
1866 } else {
1867 board[threats[i].x][threats[i].y].men += compres.cash;
1868 compres.men += compres.cash;
1869 compres.cash = 0;
1870 draw_board();
1871 rb->sleep(HZ);
1874 } else if((total_str_diff+20)*15 < compres.cash) {
1875 /* Enough money to pay their way by planes */
1876 for(i=0;i<numthreats;i++) {
1877 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1878 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1879 20)) {
1880 if(board[threats[i].x][threats[i].y].plane) {
1881 if(place_adjacent(0, threats[i].x, threats[i].y)) {
1882 /* No room for any more planes, revert to men */
1883 men_needed = (calc_strength(COLOUR_LIGHT,
1884 threats[i].x, threats[i].y) + 20 -
1885 calc_strength(COLOUR_DARK,
1886 threats[i].x, threats[i].y)*1000/133);
1887 if(compres.cash >= men_needed) {
1888 compres.cash -= men_needed;
1889 compres.men += men_needed;
1890 board[threats[i].x][threats[i].y].men +=
1891 men_needed;
1892 draw_board();
1893 rb->sleep(HZ);
1896 } else {
1897 if(compres.cash >= 600) {
1898 board[threats[i].x][threats[i].y].plane = true;
1899 compres.cash -= 600;
1900 compres.planes++;
1901 draw_board();
1902 rb->sleep(HZ);
1907 } else {
1908 /* Tanks it is */
1909 for(i=0;i<numthreats;i++) {
1910 while(calc_strength(COLOUR_DARK,threats[i].x, threats[i].y) <
1911 (calc_strength(COLOUR_LIGHT,threats[i].x, threats[i].y) +
1912 20) && compres.cash > 0) {
1913 if(board[threats[i].x][threats[i].y].tank) {
1914 if(place_adjacent(1, threats[i].x, threats[i].y)) {
1915 /* No room for any more tanks, revert to men */
1916 men_needed = (calc_strength(COLOUR_LIGHT,
1917 threats[i].x, threats[i].y) + 20 -
1918 calc_strength(COLOUR_DARK,
1919 threats[i].x, threats[i].y)*1000/133);
1920 if(compres.cash >= men_needed) {
1921 compres.cash -= men_needed;
1922 compres.men += men_needed;
1923 board[threats[i].x][threats[i].y].men +=
1924 men_needed;
1925 draw_board();
1926 rb->sleep(HZ);
1929 } else {
1930 if(compres.cash >= 300) {
1931 board[threats[i].x][threats[i].y].tank = true;
1932 compres.tanks++;
1933 compres.cash -= 300;
1934 draw_board();
1935 rb->sleep(HZ);
1941 compres.bank += compres.cash;
1942 compres.cash = 0;
1946 int find_adj_target(int x, int y, struct cursor* adj) {
1947 /* Find a square next to a computer's farm or factory owned by the player
1948 * that is vulnerable. Return 1 on success, 0 otherwise */
1949 if(board[x+1][y].colour == COLOUR_LIGHT &&
1950 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1951 adj->x = x+1;
1952 adj->y = y;
1953 return 1;
1955 if(board[x-1][y].colour == COLOUR_LIGHT &&
1956 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1957 adj->x = x-1;
1958 adj->y = y;
1959 return 1;
1961 if(board[x][y+1].colour == COLOUR_LIGHT &&
1962 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1963 adj->x = x;
1964 adj->y = y+1;
1965 return 1;
1967 if(board[x][y-1].colour == COLOUR_LIGHT &&
1968 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1969 adj->x = x;
1970 adj->y = y-1;
1971 return 1;
1973 return 0;
1976 void computer_war(void) {
1977 /* Work out where to attack - prioritise the defence of buildings */
1978 int i, j;
1979 struct cursor adj;
1981 while(compres.moves) {
1982 for(i=1;i<12;i++) {
1983 for(j=1;j<12;j++) {
1984 if((board[i][j].colour == COLOUR_DARK) &&
1985 (board[i][j].farm || board[i][j].ind)) {
1986 if(find_adj_target(i, j, &adj) && compres.moves) {
1987 if(calc_strength(COLOUR_LIGHT, adj.x, adj.y) ==
1988 calc_strength(COLOUR_DARK, adj.x, adj.y)) {
1989 rb->srand(*rb->current_tick);
1990 if(rb->rand()%2) {
1991 board[adj.x][adj.y].colour = COLOUR_DARK;
1992 board[adj.x][adj.y].tank = false;
1993 board[adj.x][adj.y].plane = false;
1994 board[adj.x][adj.y].nuke = false;
1995 humanres.men -= board[adj.x][adj.y].men;
1996 board[adj.x][adj.y].men = 0;
1997 draw_board();
1998 rb->sleep(HZ);
1999 compres.moves--;
2000 } else {
2001 rb->splash(HZ*2, "The computer attempted"
2002 " to attack, but the"
2003 " invasion was pushed"
2004 " back");
2005 compres.moves--;
2007 } else {
2008 if(compres.moves) {
2009 board[adj.x][adj.y].colour = COLOUR_DARK;
2010 board[adj.x][adj.y].tank = false;
2011 board[adj.x][adj.y].plane = false;
2012 board[adj.x][adj.y].nuke = false;
2013 humanres.men -= board[adj.x][adj.y].men;
2014 board[adj.x][adj.y].men = 0;
2015 draw_board();
2016 rb->sleep(HZ);
2017 compres.moves--;
2024 if(compres.moves) {
2025 /* Defence stage done, move on to OFFENCE */
2026 for(i=1;i<12;i++) {
2027 for(j=1;j<12;j++) {
2028 if(board[i][j].colour == COLOUR_LIGHT && compres.moves &&
2029 (board[i][j].ind || board[i][j].farm) &&
2030 (calc_strength(COLOUR_DARK, i, j) >=
2031 calc_strength(COLOUR_LIGHT, i, j))) {
2032 if(calc_strength(COLOUR_DARK, i, j) ==
2033 calc_strength(COLOUR_LIGHT, i, j)) {
2034 if(rb->rand()%2) {
2035 board[i][j].colour = COLOUR_DARK;
2036 board[i][j].tank = false;
2037 board[i][j].plane = false;
2038 board[i][j].nuke = false;
2039 board[i][j].men = 0;
2040 draw_board();
2041 rb->sleep(HZ);
2042 compres.moves--;
2043 } else {
2044 rb->splash(HZ*2, "The computer attempted to "
2045 "attack, but the invasion was"
2046 " pushed back");
2047 compres.moves--;
2049 } else {
2050 board[i][j].colour = COLOUR_DARK;
2051 board[i][j].tank = false;
2052 board[i][j].plane = false;
2053 board[i][j].nuke = false;
2054 board[i][j].men = 0;
2055 draw_board();
2056 rb->sleep(HZ);
2057 compres.moves--;
2062 while(compres.moves > 0) {
2063 /* Spend leftover moves wherever attacking randomly */
2064 rb->srand(*rb->current_tick);
2065 i = (rb->rand()%10)+1;
2066 j = (rb->rand()%10)+1;
2067 if(board[i][j].colour == COLOUR_LIGHT &&
2068 (calc_strength(COLOUR_DARK, i, j) >=
2069 calc_strength(COLOUR_LIGHT, i, j))) {
2070 if(calc_strength(COLOUR_DARK, i, j) ==
2071 calc_strength(COLOUR_LIGHT, i, j)) {
2072 if(rb->rand()%2) {
2073 board[i][j].colour = COLOUR_DARK;
2074 board[i][j].tank = false;
2075 board[i][j].plane = false;
2076 board[i][j].nuke = false;
2077 board[i][j].men = 0;
2078 draw_board();
2079 rb->sleep(HZ);
2080 compres.moves--;
2081 } else {
2082 rb->splash(HZ*2, "The computer attempted to"
2083 " attack, but the invasion was"
2084 " pushed back");
2085 compres.moves--;
2087 } else {
2088 board[i][j].colour = COLOUR_DARK;
2089 board[i][j].tank = false;
2090 board[i][j].plane = false;
2091 board[i][j].nuke = false;
2092 board[i][j].men = 0;
2093 draw_board();
2094 rb->sleep(HZ);
2095 compres.moves--;
2103 int load_game(char* file) {
2104 int fd;
2106 fd = rb->open(file, O_RDONLY);
2107 if(fd == 0) {
2108 DEBUGF("Couldn't open savegame\n");
2109 return -1;
2111 rb->read(fd, buf, 5);
2112 if(rb->strcmp(buf, "SSGv2")) {
2113 rb->splash(HZ, "Invalid/incompatible savegame\n");
2114 return -1;
2116 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
2117 rb->read(fd, &humanres.food, sizeof(humanres.food));
2118 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
2119 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
2120 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
2121 rb->read(fd, &humanres.men, sizeof(humanres.men));
2122 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
2123 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
2124 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
2125 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
2126 rb->read(fd, &compres.cash, sizeof(humanres.cash));
2127 rb->read(fd, &compres.food, sizeof(humanres.food));
2128 rb->read(fd, &compres.bank, sizeof(humanres.bank));
2129 rb->read(fd, &compres.planes, sizeof(humanres.planes));
2130 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
2131 rb->read(fd, &compres.men, sizeof(humanres.men));
2132 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
2133 rb->read(fd, &compres.inds, sizeof(humanres.inds));
2134 rb->read(fd, &compres.farms, sizeof(humanres.farms));
2135 rb->read(fd, &compres.moves, sizeof(humanres.moves));
2136 rb->read(fd, board, sizeof(board));
2137 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
2138 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
2139 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2140 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2141 rb->read(fd, &superdom_settings.startcash, sizeof(int));
2142 rb->read(fd, &superdom_settings.startfood, sizeof(int));
2143 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
2144 return 0;
2147 void default_settings(void) {
2148 superdom_settings.compstartfarms = 1;
2149 superdom_settings.compstartinds = 1;
2150 superdom_settings.humanstartfarms = 2;
2151 superdom_settings.humanstartinds = 2;
2152 superdom_settings.startcash = 0;
2153 superdom_settings.startfood = 0;
2154 superdom_settings.movesperturn = 2;
2157 int average_strength(bool colour) {
2158 /* This function calculates the average strength of the given player,
2159 * used to determine when the computer wins or loses. */
2160 int i,j;
2161 int totalpower = 0;
2162 for(i=0;i<12;i++) {
2163 for(j=0;j<12;j++) {
2164 if(board[i][j].colour != -1) {
2165 totalpower += calc_strength(colour, i, j);
2169 return totalpower/100;
2172 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2174 int tempmenu;
2175 bool statusbar_setting;
2177 rb = api;
2179 #if LCD_DEPTH > 1
2180 rb->lcd_set_backdrop(NULL);
2181 rb->lcd_set_foreground(LCD_BLACK);
2182 rb->lcd_set_background(LCD_WHITE);
2183 #endif
2185 statusbar_setting = rb->global_settings->statusbar;
2186 rb->global_settings->statusbar = false;
2187 cursor.x = 1;
2188 cursor.y = 1;
2189 default_settings();
2190 if(parameter) {
2191 if(load_game(parameter) != 0) {
2192 DEBUGF("Loading failed, generating new game\n");
2193 init_resources();
2194 init_board();
2195 } else {
2196 goto startyear;
2198 } else {
2199 init_resources();
2200 init_board();
2203 bool play = false;
2204 while(!play) {
2205 switch(menu()) {
2206 case 0:
2207 play = true;
2208 break;
2209 case 2:
2210 rb->global_settings->statusbar = statusbar_setting;
2211 return PLUGIN_OK;
2212 break;
2215 gen_resources();
2216 startyear:
2217 if((average_strength(COLOUR_LIGHT) - average_strength(COLOUR_DARK)) > 15) {
2218 rb->splash(HZ*4, "The computer has surrendered. You win.");
2219 rb->global_settings->statusbar = statusbar_setting;
2220 return PLUGIN_OK;
2222 if((average_strength(COLOUR_DARK) - average_strength(COLOUR_LIGHT)) > 15) {
2223 rb->splash(HZ*4, "Your army have suffered terrible morale from the bleak prospects of winning. You lose");
2224 rb->global_settings->statusbar = statusbar_setting;
2225 return PLUGIN_OK;
2227 tempmenu = production_menu();
2228 switch(tempmenu) {
2229 case PLUGIN_USB_CONNECTED:
2230 rb->global_settings->statusbar = statusbar_setting;
2231 return PLUGIN_USB_CONNECTED;
2232 break;
2233 case SUPERDOM_QUIT:
2234 rb->global_settings->statusbar = statusbar_setting;
2235 return PLUGIN_OK;
2236 break;
2238 computer_allocate();
2239 humanres.moves += superdom_settings.movesperturn;
2240 tempmenu = movement_menu();
2241 switch(tempmenu) {
2242 case PLUGIN_USB_CONNECTED:
2243 rb->global_settings->statusbar = statusbar_setting;
2244 return PLUGIN_USB_CONNECTED;
2245 break;
2246 case SUPERDOM_QUIT:
2247 rb->global_settings->statusbar = statusbar_setting;
2248 return PLUGIN_OK;
2249 break;
2251 if(humanres.men) {
2252 if(humanres.food > humanres.men) {
2253 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2254 humanres.men);
2255 humanres.food -= humanres.men;
2256 } else {
2257 rb->snprintf(buf, sizeof(buf), "There was not enough food to feed"
2258 " all your men, %d men have died of starvation",
2259 killmen(COLOUR_LIGHT));
2261 rb->splash(HZ*2, buf);
2263 if(compres.men) {
2264 if(compres.food < compres.men) {
2265 rb->snprintf(buf, sizeof(buf), "The computer does not have enough"
2266 " food to feed its men. %d have ided of starvation",
2267 killmen(COLOUR_DARK));
2268 rb->splash(HZ, buf);
2271 tempmenu = war_menu();
2272 switch(tempmenu) {
2273 case PLUGIN_USB_CONNECTED:
2274 rb->global_settings->statusbar = statusbar_setting;
2275 return PLUGIN_USB_CONNECTED;
2276 break;
2277 case SUPERDOM_QUIT:
2278 rb->global_settings->statusbar = statusbar_setting;
2279 return PLUGIN_OK;
2280 break;
2282 compres.moves += superdom_settings.movesperturn;
2283 computer_war();
2284 gen_resources();
2285 goto startyear;
2286 rb->global_settings->statusbar = statusbar_setting;
2287 return PLUGIN_OK;