Initial commit of the Samsung YP-R0 port.
[maemo-rb.git] / apps / plugins / superdom.c
blob135a6ae44540e2965149a49018b0d950e42787c6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Will Robertson
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "lib/playback_control.h"
23 #include "lib/display_text.h"
24 #include "pluginbitmaps/superdom_boarditems.h"
27 extern const fb_data superdom_boarditems[];
28 char buf[255];
30 #define COLOUR_DARK 0
31 #define COLOUR_LIGHT 1
33 #define MARGIN 5
35 #if (LCD_DEPTH == 16)
36 #define MY_BITMAP_PART rb->lcd_bitmap_transparent_part
37 #else
38 #define MY_BITMAP_PART rb->lcd_mono_bitmap_part
39 #endif
41 #if LCD_WIDTH > LCD_HEIGHT
42 #define BOX_WIDTH ((LCD_WIDTH-(MARGIN*2))/10)
43 #define BOX_HEIGHT ((BOX_WIDTH*2)/3)
45 #else
46 #define BOX_HEIGHT ((LCD_HEIGHT-(MARGIN*2)-15)/10)
47 #define BOX_WIDTH ((BOX_HEIGHT*2)/3)
49 #endif
51 /* NUM_BOX HEIGHT and WIDTH are used for the number pad in the game. The height
52 * calculation includes spacing for the text placed above and below the number
53 * pad (it divides by 6 instead of just 4). The width calculation gives extra
54 * spacing on the sides of the pad too (divides by 5 instead of 3).
56 #define NUM_BOX_HEIGHT (LCD_HEIGHT/6)
57 #define NUM_BOX_WIDTH (LCD_WIDTH/5)
59 #define NUM_MARGIN_X (LCD_WIDTH-3*NUM_BOX_WIDTH)/2
60 #define NUM_MARGIN_Y (LCD_HEIGHT-4*NUM_BOX_HEIGHT)/2
62 /* These parameters define the piece image dimensions, Stride is the total width
63 * of the bitmap.
65 #define ICON_STRIDE STRIDE(SCREEN_MAIN, BMPWIDTH_superdom_boarditems, BMPHEIGHT_superdom_boarditems)
66 #define ICON_HEIGHT (BMPHEIGHT_superdom_boarditems/6)
67 #define ICON_WIDTH (BMPWIDTH_superdom_boarditems/2)
69 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
70 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
71 #define SUPERDOM_OK BUTTON_SELECT
72 #define SUPERDOM_CANCEL BUTTON_MENU
73 #define SUPERDOM_LEFT BUTTON_LEFT
74 #define SUPERDOM_RIGHT BUTTON_RIGHT
75 #define IPOD_STYLE
77 #elif CONFIG_KEYPAD == IRIVER_H300_PAD || CONFIG_KEYPAD == IRIVER_H100_PAD
78 #define SUPERDOM_OK BUTTON_SELECT
79 #define SUPERDOM_LEFT BUTTON_LEFT
80 #define SUPERDOM_RIGHT BUTTON_RIGHT
81 #define SUPERDOM_UP BUTTON_UP
82 #define SUPERDOM_DOWN BUTTON_DOWN
83 #define SUPERDOM_CANCEL BUTTON_OFF
85 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
86 #define SUPERDOM_OK BUTTON_SELECT
87 #define SUPERDOM_LEFT BUTTON_LEFT
88 #define SUPERDOM_RIGHT BUTTON_RIGHT
89 #define SUPERDOM_UP BUTTON_UP
90 #define SUPERDOM_DOWN BUTTON_DOWN
91 #define SUPERDOM_CANCEL BUTTON_REC
93 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
94 #define SUPERDOM_OK BUTTON_RIGHT
95 #define SUPERDOM_UP BUTTON_SCROLL_UP
96 #define SUPERDOM_DOWN BUTTON_SCROLL_DOWN
97 #define SUPERDOM_CANCEL BUTTON_LEFT
99 #elif CONFIG_KEYPAD == GIGABEAT_PAD
100 #define SUPERDOM_OK BUTTON_SELECT
101 #define SUPERDOM_UP BUTTON_UP
102 #define SUPERDOM_DOWN BUTTON_DOWN
103 #define SUPERDOM_LEFT BUTTON_LEFT
104 #define SUPERDOM_RIGHT BUTTON_RIGHT
105 #define SUPERDOM_CANCEL BUTTON_POWER
107 #elif CONFIG_KEYPAD == SANSA_E200_PAD
108 #define SUPERDOM_OK BUTTON_SELECT
109 #define SUPERDOM_UP BUTTON_SCROLL_BACK
110 #define SUPERDOM_DOWN BUTTON_SCROLL_FWD
111 #define SUPERDOM_LEFT BUTTON_LEFT
112 #define SUPERDOM_RIGHT BUTTON_RIGHT
113 #define SUPERDOM_CANCEL BUTTON_POWER
115 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
116 #define SUPERDOM_OK BUTTON_SELECT
117 #define SUPERDOM_UP BUTTON_SCROLL_BACK
118 #define SUPERDOM_DOWN BUTTON_SCROLL_FWD
119 #define SUPERDOM_LEFT BUTTON_LEFT
120 #define SUPERDOM_RIGHT BUTTON_RIGHT
121 #define SUPERDOM_CANCEL (BUTTON_HOME|BUTTON_REPEAT)
123 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD || \
124 CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
125 #define SUPERDOM_OK BUTTON_SELECT
126 #define SUPERDOM_UP BUTTON_UP
127 #define SUPERDOM_DOWN BUTTON_DOWN
128 #define SUPERDOM_LEFT BUTTON_LEFT
129 #define SUPERDOM_RIGHT BUTTON_RIGHT
130 #define SUPERDOM_CANCEL BUTTON_BACK
132 #elif CONFIG_KEYPAD == COWON_D2_PAD
133 #define SUPERDOM_CANCEL BUTTON_POWER
135 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
136 #define SUPERDOM_OK BUTTON_SELECT
137 #define SUPERDOM_UP BUTTON_UP
138 #define SUPERDOM_DOWN BUTTON_DOWN
139 #define SUPERDOM_LEFT BUTTON_LEFT
140 #define SUPERDOM_RIGHT BUTTON_RIGHT
141 #define SUPERDOM_CANCEL BUTTON_BACK
143 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
144 #define SUPERDOM_OK BUTTON_PLAY
145 #define SUPERDOM_UP BUTTON_UP
146 #define SUPERDOM_DOWN BUTTON_DOWN
147 #define SUPERDOM_LEFT BUTTON_PREV
148 #define SUPERDOM_RIGHT BUTTON_NEXT
149 #define SUPERDOM_CANCEL BUTTON_LEFT
151 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
152 #define SUPERDOM_OK BUTTON_PLAY
153 #define SUPERDOM_UP BUTTON_UP
154 #define SUPERDOM_DOWN BUTTON_DOWN
155 #define SUPERDOM_LEFT BUTTON_PREV
156 #define SUPERDOM_RIGHT BUTTON_NEXT
157 #define SUPERDOM_CANCEL BUTTON_LEFT
159 #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || (CONFIG_KEYPAD == MROBE500_PAD)
160 #define SUPERDOM_CANCEL BUTTON_POWER
162 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
163 #define SUPERDOM_OK BUTTON_PLAY
164 #define SUPERDOM_UP BUTTON_UP
165 #define SUPERDOM_DOWN BUTTON_DOWN
166 #define SUPERDOM_LEFT BUTTON_LEFT
167 #define SUPERDOM_RIGHT BUTTON_RIGHT
168 #define SUPERDOM_CANCEL BUTTON_REW
170 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
171 #define SUPERDOM_OK BUTTON_OK
172 #define SUPERDOM_UP BUTTON_UP
173 #define SUPERDOM_DOWN BUTTON_DOWN
174 #define SUPERDOM_LEFT BUTTON_PREV
175 #define SUPERDOM_RIGHT BUTTON_NEXT
176 #define SUPERDOM_CANCEL BUTTON_CANCEL
178 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
179 #define SUPERDOM_OK BUTTON_ENTER
180 #define SUPERDOM_UP BUTTON_UP
181 #define SUPERDOM_DOWN BUTTON_DOWN
182 #define SUPERDOM_LEFT BUTTON_REW
183 #define SUPERDOM_RIGHT BUTTON_FF
184 #define SUPERDOM_CANCEL BUTTON_MENU
186 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
187 #define SUPERDOM_OK BUTTON_SELECT
188 #define SUPERDOM_UP BUTTON_UP
189 #define SUPERDOM_DOWN BUTTON_DOWN
190 #define SUPERDOM_LEFT BUTTON_LEFT
191 #define SUPERDOM_RIGHT BUTTON_RIGHT
192 #define SUPERDOM_CANCEL BUTTON_BACK
194 #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
195 #define SUPERDOM_OK BUTTON_SELECT
196 #define SUPERDOM_UP BUTTON_UP
197 #define SUPERDOM_DOWN BUTTON_DOWN
198 #define SUPERDOM_LEFT BUTTON_LEFT
199 #define SUPERDOM_RIGHT BUTTON_RIGHT
200 #define SUPERDOM_CANCEL BUTTON_POWER
202 #endif
204 #ifdef HAVE_TOUCHSCREEN
205 #ifndef SUPERDOM_OK
206 #define SUPERDOM_OK BUTTON_CENTER
207 #endif
208 #ifndef SUPERDOM_UP
209 #define SUPERDOM_UP BUTTON_TOPMIDDLE
210 #endif
211 #ifndef SUPERDOM_LEFT
212 #define SUPERDOM_LEFT BUTTON_MIDLEFT
213 #endif
214 #ifndef SUPERDOM_RIGHT
215 #define SUPERDOM_RIGHT BUTTON_MIDRIGHT
216 #endif
217 #ifndef SUPERDOM_DOWN
218 #define SUPERDOM_DOWN BUTTON_BOTTOMMIDDLE
219 #endif
220 #ifndef SUPERDOM_CANCEL
221 #define SUPERDOM_CANCEL BUTTON_TOPLEFT
222 #endif
223 #endif
225 enum {
226 RET_VAL_OK,
227 RET_VAL_USB,
228 RET_VAL_QUIT_ERR, /* quit or error */
231 void gen_interest(void);
232 void init_resources(void);
233 int select_square(void);
234 void update_score(void);
235 void gen_resources(void);
236 void draw_cursor(void);
237 void draw_board(void);
239 struct tile{
240 signed int colour; /* -1 = Unset */
241 bool tank;
242 bool plane;
243 bool nuke;
244 bool ind;
245 bool farm;
246 int men;
249 struct resources {
250 int cash;
251 int food;
252 int farms;
253 int inds;
254 int men;
255 int tanks;
256 int planes;
257 int nukes;
258 int bank;
259 int moves;
262 struct settings {
263 int compstartfarms;
264 int compstartinds;
265 int humanstartfarms;
266 int humanstartinds;
267 int startcash;
268 int startfood;
269 int movesperturn;
270 } superdom_settings;
272 struct resources humanres;
273 struct resources compres;
274 enum { GS_PROD, GS_MOVE, GS_WAR };
275 int gamestate;
277 struct cursor{
278 int x;
279 int y;
280 } cursor;
282 struct tile board[12][12];
284 void init_board(void) {
285 int i,j;
286 rb->srand(*rb->current_tick);
287 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
288 for(j=0;j<12;j++) {
289 if((i<1)||(j<1)||(i>10)||(j>10))
290 board[i][j].colour = -1; /* Unset */
291 else
292 board[i][j].colour = rb->rand()%2;
293 board[i][j].tank = false;
294 board[i][j].plane = false;
295 board[i][j].nuke = false;
296 board[i][j].ind = false;
297 board[i][j].farm = false;
298 board[i][j].men = 0;
302 while(compres.farms < superdom_settings.compstartfarms) {
303 i = rb->rand()%10 + 1;
304 j = rb->rand()%10 + 1;
305 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
306 board[i][j].farm = true;
307 compres.farms++;
310 while(compres.inds < superdom_settings.compstartinds) {
311 i = rb->rand()%10 + 1;
312 j = rb->rand()%10 + 1;
313 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
314 board[i][j].ind = true;
315 compres.inds++;
318 while(humanres.farms < superdom_settings.humanstartfarms) {
319 i = rb->rand()%10 + 1;
320 j = rb->rand()%10 + 1;
321 if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
322 board[i][j].farm = true;
323 humanres.farms++;
326 while(humanres.inds < superdom_settings.humanstartinds) {
327 i = rb->rand()%10 + 1;
328 j = rb->rand()%10 + 1;
329 if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) {
330 board[i][j].ind = true;
331 humanres.inds++;
336 void draw_board(void) {
337 int i,j;
338 rb->lcd_clear_display();
339 for(i=1;i<11;i++) {
340 for(j=1;j<11;j++) {
341 if(board[i][j].colour == COLOUR_DARK) {
342 rb->lcd_set_foreground(LCD_DARKGRAY);
343 } else {
344 rb->lcd_set_foreground(LCD_LIGHTGRAY);
346 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
347 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
348 BOX_HEIGHT);
349 #if LCD_DEPTH != 16
350 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
351 #endif
352 if(board[i][j].ind) {
353 MY_BITMAP_PART(superdom_boarditems,
354 board[i][j].colour?ICON_WIDTH:0, 0, ICON_STRIDE,
355 #if LCD_WIDTH > LCD_HEIGHT
356 MARGIN+(BOX_WIDTH*(i-1))+1,
357 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
358 #else
359 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
360 MARGIN+(BOX_HEIGHT*(j-1))+1,
361 #endif
362 ICON_WIDTH, ICON_HEIGHT);
364 if(board[i][j].farm) {
365 MY_BITMAP_PART(superdom_boarditems,
366 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
367 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
368 MARGIN+(BOX_HEIGHT*(j-1))+1,
369 ICON_WIDTH, ICON_HEIGHT);
371 if(board[i][j].tank) {
372 MY_BITMAP_PART(superdom_boarditems,
373 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
374 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
375 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
376 ICON_WIDTH, ICON_HEIGHT);
378 if(board[i][j].men) {
379 MY_BITMAP_PART(superdom_boarditems,
380 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
381 #if LCD_WIDTH > LCD_HEIGHT
382 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
383 MARGIN+(BOX_HEIGHT*(j-1))+1,
384 #else
385 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
386 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
387 #endif
388 ICON_WIDTH, ICON_HEIGHT);
390 if(board[i][j].plane) {
391 MY_BITMAP_PART(superdom_boarditems,
392 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
393 #if LCD_WIDTH > LCD_HEIGHT
394 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
395 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
396 #else
397 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
398 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
399 #endif
400 ICON_WIDTH, ICON_HEIGHT);
402 if(board[i][j].nuke) {
403 MY_BITMAP_PART(superdom_boarditems,
404 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
405 #if LCD_WIDTH > LCD_HEIGHT
406 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
407 MARGIN+(BOX_HEIGHT*(j-1))+1,
408 #else
409 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
410 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
411 #endif
412 ICON_WIDTH, ICON_HEIGHT);
414 #if LCD_DEPTH != 16
415 rb->lcd_set_drawmode(DRMODE_SOLID);
416 #endif
419 rb->lcd_set_foreground(LCD_BLACK);
420 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
421 rb->lcd_hline(MARGIN, MARGIN+(BOX_WIDTH*10), MARGIN+(BOX_HEIGHT*i));
423 for(i=0;i<=10;i++) { /* Draw Vertical lines */
424 rb->lcd_vline(MARGIN+(BOX_WIDTH*i), MARGIN, MARGIN+(BOX_HEIGHT*10));
426 rb->lcd_update();
429 int calc_strength(int colour, int x, int y) {
430 int a, b, score=0;
431 for (a = -1; a < 2; a++) {
432 for (b = -1; b < 2; b++) {
433 if ((b == 0 || a == 0) &&
434 (board[x + a][y + b].colour == colour)) {
435 score += 10;
436 if(board[x + a][y + b].tank || board[x + a][y + b].farm)
437 score += 30;
438 if(board[x + a][y + b].plane || board[x + a][y + b].ind)
439 score += 40;
440 if(board[x + a][y + b].nuke)
441 score += 20;
442 if(board[x + a][y + b].men)
443 score += (board[x + a][y + b].men*133/1000);
447 return score;
450 void gen_interest(void) {
451 /* Interest should be around 10% */
452 rb->srand(*rb->current_tick);
453 int interest = 7+rb->rand()%6;
454 humanres.bank = humanres.bank+(interest*humanres.bank/100);
455 compres.bank = compres.bank+(interest*compres.bank/100);
458 void draw_cursor(void) {
459 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
460 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
461 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
462 rb->lcd_set_drawmode(DRMODE_SOLID);
463 rb->lcd_update();
466 void gen_resources(void) {
467 int inccash = 0;
468 int incfood = 0;
469 int ratecash = 0;
470 int ratefood = 0;
471 int i;
472 gen_interest();
473 rb->srand(*rb->current_tick);
474 /* Generate Human's resources */
475 for(i=0;i<humanres.inds;i++) {
476 inccash += (300+rb->rand()%200);
478 for(i=0;i<humanres.farms;i++) {
479 incfood += (200+rb->rand()%200);
481 if(humanres.inds)
482 ratecash = inccash/humanres.inds;
483 if(humanres.farms)
484 ratefood = incfood/humanres.farms;
485 if(ratecash > 450) {
486 if(ratefood > 350) {
487 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
488 " is up this year!");
489 } else {
490 rb->splash(HZ*2, "Factories working at maximum efficiency,"
491 " cash production up this year!");
493 } else if(ratecash > 350) {
494 if(ratefood > 350) {
495 rb->splash(HZ*2, "Record crop harvest this year!");
496 } else if(ratefood > 250) {
497 rb->splash(HZ*2, "Production continues as normal");
498 } else {
499 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
500 " output this year");
502 } else {
503 if(ratefood > 350) {
504 rb->splash(HZ*2, "Record crop harvest this year!");
505 } else if(ratefood > 250) {
506 rb->splash(HZ*2, "Factory unions introduced. Industrial"
507 " production is down this year.");
508 } else {
509 rb->splash(HZ*2, "Internet created. All production is down"
510 " due to time wasted.");
513 humanres.cash += inccash;
514 humanres.food += incfood;
516 /* Generate Computer's resources */
517 inccash = 0;
518 incfood = 0;
519 for(i=0;i<compres.inds;i++) {
520 inccash += (300+rb->rand()%200);
522 for(i=0;i<compres.farms;i++) {
523 incfood += (200+rb->rand()%200);
525 compres.cash += inccash;
526 compres.food += incfood;
529 void update_score(void) {
530 int strength;
531 rb->lcd_setfont(FONT_SYSFIXED);
532 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
533 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
534 rb->lcd_set_drawmode(DRMODE_SOLID);
535 strength = calc_strength(COLOUR_LIGHT, cursor.x, cursor.y);
536 rb->lcd_putsxyf(5,LCD_HEIGHT-20,"Your power: %d.%d",strength/10,strength%10);
537 strength = calc_strength(COLOUR_DARK, cursor.x, cursor.y);
538 rb->lcd_putsxyf(5,LCD_HEIGHT-10,"Comp power: %d.%d",strength/10,strength%10);
539 rb->lcd_setfont(FONT_UI);
542 int settings_menu(void) {
543 int selection = 0;
545 MENUITEM_STRINGLIST(menu, "Super Domination Settings", NULL,
546 "Computer starting farms", "Computer starting factories",
547 "Human starting farms", "Human starting factories",
548 "Starting cash", "Starting food", "Moves per turn");
550 while(1) {
551 switch(rb->do_menu(&menu, &selection, NULL, false)) {
552 case 0:
553 rb->set_int("Computer starting farms", "", UNIT_INT,
554 &superdom_settings.compstartfarms, NULL,
555 1, 0, 5, NULL);
556 break;
557 case 1:
558 rb->set_int("Computer starting factories", "", UNIT_INT,
559 &superdom_settings.compstartinds, NULL,
560 1, 0, 5, NULL);
561 break;
562 case 2:
563 rb->set_int("Human starting farms", "", UNIT_INT,
564 &superdom_settings.humanstartfarms, NULL,
565 1, 0, 5, NULL);
566 break;
567 case 3:
568 rb->set_int("Human starting factories", "", UNIT_INT,
569 &superdom_settings.humanstartinds, NULL,
570 1, 0, 5, NULL);
571 break;
572 case 4:
573 rb->set_int("Starting cash", "", UNIT_INT,
574 &superdom_settings.startcash, NULL,
575 250, 0, 5000, NULL);
576 break;
577 case 5:
578 rb->set_int("Starting food", "", UNIT_INT,
579 &superdom_settings.startfood, NULL,
580 250, 0, 5000, NULL);
581 break;
582 case 6:
583 rb->set_int("Moves per turn", "", UNIT_INT,
584 &superdom_settings.movesperturn, NULL,
585 1, 1, 5, NULL);
586 break;
587 case MENU_ATTACHED_USB:
588 return RET_VAL_USB;
589 break;
590 case GO_TO_PREVIOUS:
591 return RET_VAL_OK;
592 break;
595 return RET_VAL_OK;
598 static int superdom_help(void) {
599 static char* help_text[] = {
600 "Super", "domination", "is", "a", "turn", "based", "strategy", "game,",
601 "where", "the", "aim", "is", "to", "overpower", "the", "computer",
602 "player", "by", "taking", "their", "territory.", "",
603 "Each", "year", "you", "are", "allocated", "an", "amount", "of", "cash",
604 "and", "food,", "depending", "on", "how", "many", "farms", "and",
605 "factories", "you", "control.", "",
606 "Use", "this", "cash", "and", "food", "to", "buy", "and", "feed", "your",
607 "army.", "Each", "tile", "has", "a", "strength,", "calculated", "by",
608 "the", "ownership", "of", "adjacent", "tiles,", "and", "the", "type",
609 "and", "number", "of", "troops", "on", "them.",
612 if (display_text(ARRAYLEN(help_text), help_text, NULL, NULL, true))
613 return RET_VAL_USB;
614 return RET_VAL_OK;
617 int start_menu(void) {
618 int selection = 0;
620 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
621 "Play Super Domination", "Settings",
622 "Help", "Playback Control", "Quit");
624 while(1) {
625 switch(rb->do_menu(&menu, &selection, NULL, false)) {
626 case 0:
627 return RET_VAL_OK; /* start playing */
628 break;
629 case 1:
630 if(settings_menu()==RET_VAL_USB)
631 return RET_VAL_USB;
632 break;
633 case 2:
634 if(superdom_help()==RET_VAL_USB)
635 return RET_VAL_USB;
636 break;
637 case 3:
638 if(playback_control(NULL))
639 return RET_VAL_USB;
640 break;
641 case 4:
642 return RET_VAL_QUIT_ERR;
643 break;
646 return RET_VAL_QUIT_ERR;
649 int save_game(void) {
650 int fd;
651 char savepath[MAX_PATH];
653 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
654 if(rb->kbd_input(savepath, MAX_PATH)) {
655 DEBUGF("Keyboard input failed\n");
656 return -1;
659 fd = rb->open(savepath, O_WRONLY|O_CREAT, 0666);
660 DEBUGF("savepath: %s\n", savepath);
661 if(fd < 0) {
662 DEBUGF("Couldn't create/open file\n");
663 return -1;
666 rb->write(fd, "SSGv3", 5);
667 rb->write(fd, &gamestate, sizeof(gamestate));
668 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
669 rb->write(fd, &humanres.food, sizeof(humanres.food));
670 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
671 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
672 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
673 rb->write(fd, &humanres.men, sizeof(humanres.men));
674 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
675 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
676 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
677 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
678 rb->write(fd, &compres.cash, sizeof(compres.cash));
679 rb->write(fd, &compres.food, sizeof(compres.food));
680 rb->write(fd, &compres.bank, sizeof(compres.bank));
681 rb->write(fd, &compres.planes, sizeof(compres.planes));
682 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
683 rb->write(fd, &compres.men, sizeof(compres.men));
684 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
685 rb->write(fd, &compres.inds, sizeof(compres.inds));
686 rb->write(fd, &compres.farms, sizeof(compres.farms));
687 rb->write(fd, &compres.moves, sizeof(compres.moves));
688 rb->write(fd, board, sizeof(board));
689 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
690 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
691 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
692 rb->write(fd, &superdom_settings.humanstartinds, sizeof(int));
693 rb->write(fd, &superdom_settings.startcash, sizeof(int));
694 rb->write(fd, &superdom_settings.startfood, sizeof(int));
695 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
696 rb->close(fd);
697 return 0;
700 int ingame_menu(void) {
701 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
702 "Return to game", "Save Game",
703 "Playback Control", "Quit");
705 switch(rb->do_menu(&menu, NULL, NULL, false)) {
706 case 0:
707 return RET_VAL_OK;
708 break;
709 case 1:
710 if(!save_game())
711 rb->splash(HZ, "Game saved");
712 else
713 rb->splash(HZ, "Error in save");
714 break;
715 case 2:
716 if(playback_control(NULL))
717 return RET_VAL_USB;
718 break;
719 case 3:
720 return RET_VAL_QUIT_ERR;
721 break;
722 case MENU_ATTACHED_USB:
723 return RET_VAL_USB;
724 break;
725 case GO_TO_PREVIOUS:
726 return RET_VAL_OK;
727 break;
729 return RET_VAL_OK;
732 int get_number(char* param, int* value, int max) {
733 static const char *button_labels[4][3] = {
734 { "1", "2", "3" },
735 { "4", "5", "6" },
736 { "7", "8", "9" },
737 { "CLR", "0", "OK" }
739 int i,j,x=0,y=0;
740 int height, width;
741 int button = 0, ret = RET_VAL_OK;
742 bool done = false;
743 rb->lcd_clear_display();
744 rb->lcd_getstringsize("CLR", &width, &height);
745 if(width > NUM_BOX_WIDTH || height > NUM_BOX_HEIGHT)
746 rb->lcd_setfont(FONT_SYSFIXED);
747 /* Draw a 3x4 grid */
748 for(i=0;i<=3;i++) { /* Vertical lines */
749 rb->lcd_vline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
750 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
752 for(i=0;i<=4;i++) { /* Horizontal lines */
753 rb->lcd_hline(NUM_MARGIN_X, NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
754 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
756 for(i=0;i<4;i++) {
757 for(j=0;j<3;j++) {
758 rb->lcd_getstringsize(button_labels[i][j], &width, &height);
759 rb->lcd_putsxy(
760 NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+NUM_BOX_WIDTH/2-width/2,
761 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+NUM_BOX_HEIGHT/2-height/2,
762 button_labels[i][j]);
765 rb->lcd_putsxyf(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,"%d",*value);
766 rb->lcd_getstringsize(param, &width, &height);
767 if(width < LCD_WIDTH)
768 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
769 else
770 rb->lcd_puts_scroll(0, (NUM_MARGIN_Y/height-1)/2, param);
771 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
772 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
773 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
774 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
775 rb->lcd_set_drawmode(DRMODE_SOLID);
776 rb->lcd_update();
777 while(!done) {
778 button = rb->button_get(true);
779 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
780 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
781 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
782 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
783 rb->lcd_set_drawmode(DRMODE_SOLID);
784 switch(button) {
785 case SUPERDOM_OK:
786 if(y!=3) {
787 *value *= 10;
788 *value += button_labels[y][x][0] - '0';
789 } else if(x==0) {
790 *value /= 10;
791 } else if(x==1) {
792 *value *= 10;
793 } else if(x==2) {
794 done = true;
795 break;
797 if ((unsigned) *value > (unsigned) max)
798 *value = max;
799 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
800 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
801 LCD_WIDTH, 30);
802 rb->lcd_set_drawmode(DRMODE_SOLID);
803 rb->lcd_putsxyf(NUM_MARGIN_X+10,NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
804 "%d", *value);
805 break;
806 case SUPERDOM_CANCEL:
807 *value = 0;
808 done = true;
809 ret = RET_VAL_QUIT_ERR;
810 break;
811 #if CONFIG_KEYPAD != IRIVER_H10_PAD
812 case SUPERDOM_LEFT:
813 if(x==0) {
814 #ifdef IPOD_STYLE
815 if(y>0)
816 y--;
817 else
818 y=3;
819 #endif
820 x=2;
821 } else {
822 x--;
824 break;
825 case SUPERDOM_RIGHT:
826 if(x==2) {
827 #ifdef IPOD_STYLE
828 if(y==3)
829 y=0;
830 else
831 y++;
832 #endif
833 x=0;
834 } else {
835 x++;
837 break;
838 #endif
839 #ifndef IPOD_STYLE
840 case SUPERDOM_UP:
841 if(y==0) {
842 #if CONFIG_KEYPAD == IRIVER_H10_PAD
843 if(x > 0)
844 x--;
845 else
846 x=2;
847 #endif
848 y=3;
849 } else {
850 y--;
852 break;
853 case SUPERDOM_DOWN:
854 if(y==3) {
855 #if CONFIG_KEYPAD == IRIVER_H10_PAD
856 if(x < 2)
857 x++;
858 else
859 x=0;
860 #endif
861 y=0;
862 } else {
863 y++;
865 break;
866 #endif
867 default:
868 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
870 done = true;
871 ret = RET_VAL_USB;
873 break;
875 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
876 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
877 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
878 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
879 rb->lcd_set_drawmode(DRMODE_SOLID);
880 rb->lcd_update();
882 rb->lcd_setfont(FONT_UI);
883 rb->lcd_stop_scroll();
884 if (ret == RET_VAL_QUIT_ERR)
885 rb->splash(HZ, "Cancelled");
886 return ret;
889 bool tile_has_item(int type, int x, int y) {
890 switch(type) {
891 case 0:
892 return (board[x][y].men > 0);
893 break;
894 case 1:
895 return board[x][y].tank;
896 break;
897 case 2:
898 return board[x][y].plane;
899 break;
900 case 3:
901 return board[x][y].farm;
902 break;
903 case 4:
904 return board[x][y].ind;
905 break;
906 case 5:
907 return board[x][y].nuke;
908 break;
910 return false;
913 int buy_resources(int colour, int type, int x, int y, int nummen) {
914 const char *itemnames[][6] = {
916 "them",
917 "the tank",
918 "the plane",
919 "the farm",
920 "the industrial plant",
921 "the nuke",
922 }, {
923 "place men",
924 "place a tank",
925 "place a plane",
926 "build a farm",
927 "build an industrial plant",
928 "place a nuke",
929 }, {
930 NULL,
931 "a tank",
932 "a plane",
933 "a farm",
934 "an industrial plant",
935 "a nuke",
939 bool human = (colour == COLOUR_LIGHT);
940 int price = 0;
941 int temp;
942 struct resources *res;
944 if(human) {
945 res = &humanres;
946 } else {
947 res = &compres;
949 switch(type) {
950 case 0: /* men */
951 price = 1*nummen;
952 break;
953 case 1: /* tank */
954 price = 300;
955 break;
956 case 2: /* plane */
957 price = 600;
958 break;
959 case 3: /* Farm */
960 price = 1150;
961 break;
962 case 4: /* Factory */
963 price = 1300;
964 break;
965 case 5: /* nuke */
966 price = 2000;
967 break;
969 if(res->cash < price) {
970 if(human)
971 rb->splash(HZ, "Not enough money!");
972 return RET_VAL_QUIT_ERR;
974 if(human) {
975 rb->splashf(HZ, "Where do you want to place %s?", itemnames[0][type]);
976 if((temp = select_square()) != RET_VAL_OK)
977 return temp;
978 x = cursor.x;
979 y = cursor.y;
981 if(board[x][y].colour != colour) {
982 if(human)
983 rb->splashf(HZ, "Can't %s on enemy territory", itemnames[1][type]);
984 return RET_VAL_QUIT_ERR;
986 if(type != 0 && tile_has_item(type, x, y)) {
987 if(human)
988 rb->splashf(HZ, "There is already %s there", itemnames[2][type]);
989 return RET_VAL_QUIT_ERR;
991 switch(type) {
992 case 0:
993 board[x][y].men += nummen;
994 res->men += nummen;
995 break;
996 case 1:
997 board[x][y].tank = true;
998 res->tanks++;
999 break;
1000 case 2:
1001 board[x][y].plane = true;
1002 res->planes++;
1003 break;
1004 case 3:
1005 board[x][y].farm = true;
1006 res->farms++;
1007 break;
1008 case 4:
1009 board[x][y].ind = true;
1010 res->inds++;
1011 break;
1012 case 5:
1013 board[x][y].nuke = true;
1014 res->nukes++;
1015 break;
1017 res->cash -= price;
1019 draw_board();
1020 rb->sleep(HZ);
1022 return RET_VAL_OK;
1025 int buy_resources_menu(void) {
1026 int selection = 0,nummen;
1028 MENUITEM_STRINGLIST(menu, "Buy Resources", NULL,
1029 "Buy men ($1)", "Buy tank ($300)", "Buy plane ($600)",
1030 "Buy Farm ($1150)", "Buy Factory ($1300)",
1031 "Buy Nuke ($2000)",
1032 "Finish buying");
1034 while(1) {
1035 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1036 case 0:
1037 nummen = 0;
1038 if(get_number("How many men would you like?", &nummen,
1039 humanres.cash) == RET_VAL_USB)
1040 return RET_VAL_USB;
1041 if(!nummen)
1042 break;
1043 /* fall through */
1044 case 1:
1045 case 2:
1046 case 3:
1047 case 4:
1048 case 5:
1049 if(buy_resources(COLOUR_LIGHT, selection, 0, 0, nummen)
1050 == RET_VAL_USB)
1051 return RET_VAL_USB;
1052 break;
1053 case 6:
1054 return RET_VAL_OK;
1055 break;
1056 case MENU_ATTACHED_USB:
1057 return RET_VAL_USB;
1058 break;
1059 case GO_TO_PREVIOUS:
1060 return RET_VAL_OK;
1061 break;
1064 return RET_VAL_OK;
1067 int move_unit(int colour, int type, int fromx, int fromy,
1068 int tox, int toy, int nummen) {
1069 const char *itemnames[][3] = {
1071 "troops",
1072 "the tank",
1073 "the plane",
1074 }, {
1075 "any troops",
1076 "a tank",
1077 "a plane",
1078 }, {
1079 "the troops",
1080 "the tank",
1081 "the plane",
1084 bool human = (colour == COLOUR_LIGHT);
1085 int temp;
1087 if(human) {
1088 rb->splashf(HZ, "Select where you want to move %s from",
1089 itemnames[0][type]);
1090 if((temp = select_square()) != RET_VAL_OK)
1091 return temp;
1092 fromx = cursor.x;
1093 fromy = cursor.y;
1095 if(board[fromx][fromy].colour != colour) {
1096 if(human)
1097 rb->splash(HZ, "That isn't your territory");
1098 return RET_VAL_QUIT_ERR;
1100 if(!tile_has_item(type, fromx, fromy)) {
1101 if(human)
1102 rb->splashf(HZ, "You don't have %s there", itemnames[1][type]);
1103 return RET_VAL_QUIT_ERR;
1105 if(type == 0) {
1106 if(human) {
1107 nummen = board[fromx][fromy].men;
1108 if((temp = get_number("How many men do you want to move?", &nummen,
1109 nummen)) != RET_VAL_OK)
1110 return temp;
1112 if(nummen > board[fromx][fromy].men) {
1113 if(human)
1114 rb->splash(HZ, "You don't have that many troops.");
1115 return RET_VAL_QUIT_ERR;
1118 if(human) {
1119 rb->splashf(HZ, "Select where you want to move %s to",
1120 itemnames[2][type]);
1121 if((temp = select_square()) != RET_VAL_OK)
1122 return temp;
1123 tox = cursor.x;
1124 toy = cursor.y;
1126 if((tox == fromx && toy == fromy) ||
1127 board[tox][toy].colour != colour ||
1128 (type != 2 && (abs(tox - fromx) > 1 || abs(toy - fromy) > 1))) {
1129 if(human)
1130 rb->splash(HZ, "Invalid move");
1131 return RET_VAL_QUIT_ERR;
1133 if(type != 0 && tile_has_item(type, tox, toy)) {
1134 if(human)
1135 rb->splashf(HZ, "There is already %s there", itemnames[1][type]);
1136 return RET_VAL_QUIT_ERR;
1138 switch(type) {
1139 case 0:
1140 board[fromx][fromy].men -= nummen;
1141 board[tox][toy].men += nummen;
1142 break;
1143 case 1:
1144 board[fromx][fromy].tank = false;
1145 board[tox][toy].tank = true;
1146 break;
1147 case 2:
1148 board[fromx][fromy].plane = false;
1149 board[tox][toy].plane = true;
1150 break;
1152 return RET_VAL_OK;
1155 int move_unit_menu(void) {
1156 int selection = 0;
1158 MENUITEM_STRINGLIST(menu, "Move unit", NULL,
1159 "Move men", "Move tank", "Move plane");
1160 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1161 case 0:
1162 case 1:
1163 case 2:
1164 switch(move_unit(COLOUR_LIGHT, selection, 0, 0, 0, 0, 0)) {
1165 case RET_VAL_OK:
1166 humanres.moves--;
1167 break;
1168 case RET_VAL_USB:
1169 return RET_VAL_USB;
1170 break;
1172 break;
1173 case MENU_ATTACHED_USB:
1174 return RET_VAL_USB;
1176 return RET_VAL_OK;
1179 int launch_nuke(int colour, int nukex, int nukey, int targetx, int targety) {
1180 bool human = (colour == COLOUR_LIGHT);
1181 int temp;
1182 struct resources *res;
1184 if(board[nukex][nukey].colour != colour) {
1185 if(human)
1186 rb->splash(HZ, "That isn't your territory");
1187 return RET_VAL_QUIT_ERR;
1189 if(! board[nukex][nukey].nuke) {
1190 if(human)
1191 rb->splashf(HZ, "You don't have %s there", "a nuke");
1192 return RET_VAL_QUIT_ERR;
1194 if(human) {
1195 rb->splash(HZ, "Select place to target with nuke");
1196 if((temp = select_square()) != RET_VAL_OK)
1197 return temp;
1198 targetx = cursor.x;
1199 targety = cursor.y;
1201 if(human) {
1202 humanres.nukes--;
1203 } else {
1204 compres.nukes--;
1206 board[nukex][nukey].nuke = false;
1208 if(board[targetx][targety].colour == COLOUR_LIGHT) {
1209 res = &humanres;
1210 } else {
1211 res = &compres;
1213 res->men -= board[targetx][targety].men;
1214 res->tanks -= board[targetx][targety].tank;
1215 res->planes -= board[targetx][targety].plane;
1216 res->nukes -= board[targetx][targety].nuke;
1217 res->farms -= board[targetx][targety].farm;
1218 res->inds -= board[targetx][targety].ind;
1219 board[targetx][targety].men = 0;
1220 board[targetx][targety].tank = false;
1221 board[targetx][targety].plane = false;
1222 board[targetx][targety].ind = false;
1223 board[targetx][targety].nuke = false;
1224 board[targetx][targety].farm = false;
1225 /* TODO: Fallout carried by wind */
1227 return RET_VAL_OK;
1230 int movement_menu(void) {
1231 int selection = 0, temp;
1233 MENUITEM_STRINGLIST(menu, "Movement", NULL,
1234 "Move unit", "Buy additional moves ($100)",
1235 "Launch nuclear missile", "Check map",
1236 "Finish moving", "Game menu");
1238 while(1) {
1239 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1240 case 0:
1241 if(humanres.moves) {
1242 if(move_unit_menu()==RET_VAL_USB)
1243 return RET_VAL_USB;
1244 } else {
1245 rb->splash(HZ, "You have no more moves left."
1246 " You can buy more for $100 each.");
1248 break;
1249 case 1:
1250 if(humanres.cash > 100) {
1251 humanres.moves++;
1252 humanres.cash -= 100;
1253 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1254 humanres.moves);
1255 rb->splash(HZ, buf);
1257 break;
1258 case 2:
1259 if(humanres.nukes==0) {
1260 rb->splash(HZ, "You do not have any nukes to launch");
1261 } else {
1262 rb->splash(HZ, "Select place to launch nuke from");
1263 switch(select_square()) {
1264 case RET_VAL_OK:
1265 if(launch_nuke(COLOUR_LIGHT, cursor.x, cursor.y,
1266 0, 0) == RET_VAL_USB)
1267 return RET_VAL_USB;
1268 break;
1269 case RET_VAL_USB:
1270 return RET_VAL_USB;
1271 break;
1274 break;
1275 case 3:
1276 if(select_square() == RET_VAL_USB)
1277 return RET_VAL_USB;
1278 break;
1279 case 4:
1280 return RET_VAL_OK;
1281 break;
1282 case 5:
1283 if((temp = ingame_menu()) != RET_VAL_OK)
1284 return temp;
1285 break;
1286 case MENU_ATTACHED_USB:
1287 return RET_VAL_USB;
1288 break;
1291 return RET_VAL_OK;
1294 static const char* inventory_data(int selected_item, void * data,
1295 char * buffer, size_t buffer_len) {
1296 (void)data;
1297 switch(selected_item) {
1298 case 0:
1299 rb->snprintf(buffer,buffer_len,"Men: %d", humanres.men);
1300 break;
1301 case 1:
1302 rb->snprintf(buffer,buffer_len,"Tanks: %d", humanres.tanks);
1303 break;
1304 case 2:
1305 rb->snprintf(buffer,buffer_len,"Planes: %d", humanres.planes);
1306 break;
1307 case 3:
1308 rb->snprintf(buffer,buffer_len,"Factories: %d", humanres.inds);
1309 break;
1310 case 4:
1311 rb->snprintf(buffer,buffer_len,"Farms: %d", humanres.farms);
1312 break;
1313 case 5:
1314 rb->snprintf(buffer,buffer_len,"Nukes: %d", humanres.nukes);
1315 break;
1316 case 6:
1317 rb->snprintf(buffer,buffer_len,"Cash: %d", humanres.cash);
1318 break;
1319 case 7:
1320 rb->snprintf(buffer,buffer_len,"Food: %d", humanres.food);
1321 break;
1322 case 8:
1323 rb->snprintf(buffer,buffer_len,"Bank: %d", humanres.bank);
1324 break;
1325 default:
1326 return NULL;
1328 return buffer;
1331 int show_inventory(void) {
1332 struct simplelist_info info;
1333 rb->simplelist_info_init(&info, "Inventory", 9, NULL);
1334 info.hide_selection = true;
1335 info.get_name = inventory_data;
1336 if(rb->simplelist_show_list(&info)) {
1337 return RET_VAL_USB;
1338 } else {
1339 return RET_VAL_OK;
1343 int production_menu(void) {
1344 int selection = 0, temp;
1346 MENUITEM_STRINGLIST(menu, "Production", NULL,
1347 "Buy resources", "Show inventory", "Check map",
1348 "Invest money", "Withdraw money",
1349 "Finish turn", "Game menu");
1351 while(1) {
1352 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1353 case 0:
1354 if(buy_resources_menu() == RET_VAL_USB)
1355 return RET_VAL_USB;
1356 break;
1357 case 1:
1358 if(show_inventory() == RET_VAL_USB)
1359 return RET_VAL_USB;
1360 break;
1361 case 2:
1362 if(select_square() == RET_VAL_USB)
1363 return RET_VAL_USB;
1364 break;
1365 case 3:
1366 temp = humanres.cash;
1367 if(get_number("How much do you want to invest?", &temp,
1368 humanres.cash) == RET_VAL_USB)
1369 return RET_VAL_USB;
1370 if(temp > humanres.cash) {
1371 rb->splash(HZ, "You don't have that much cash to invest");
1372 } else {
1373 humanres.cash -= temp;
1374 humanres.bank += temp;
1376 break;
1377 case 4:
1378 temp = humanres.bank;
1379 if(get_number("How much do you want to withdraw?", &temp,
1380 humanres.bank) == RET_VAL_USB)
1381 return RET_VAL_USB;
1382 if(temp > humanres.bank) {
1383 rb->splash(HZ, "You don't have that much cash to withdraw");
1384 } else {
1385 humanres.cash += temp;
1386 humanres.bank -= temp;
1388 break;
1389 case 5:
1390 return RET_VAL_OK;
1391 break;
1392 case 6:
1393 if((temp = ingame_menu()) != RET_VAL_OK)
1394 return temp;
1395 break;
1396 case MENU_ATTACHED_USB:
1397 return RET_VAL_USB;
1398 break;
1401 return RET_VAL_OK;
1404 void init_resources(void) {
1405 humanres.cash = superdom_settings.startcash;
1406 humanres.food = superdom_settings.startfood;
1407 humanres.tanks = 0;
1408 humanres.planes = 0;
1409 humanres.nukes = 0;
1410 humanres.inds = 0;
1411 humanres.farms = 0;
1412 humanres.men = 0;
1413 humanres.bank = 0;
1414 humanres.moves = 0;
1415 compres.cash = superdom_settings.startcash;
1416 compres.food = superdom_settings.startfood;
1417 compres.tanks = 0;
1418 compres.planes = 0;
1419 compres.nukes = 0;
1420 compres.inds = 0;
1421 compres.farms = 0;
1422 compres.men = 0;
1423 compres.bank = 0;
1424 compres.moves = 0;
1427 int select_square(void) {
1428 int button = 0;
1429 draw_board();
1430 draw_cursor();
1431 update_score();
1432 #if LCD_WIDTH >= 220
1433 rb->lcd_setfont(FONT_SYSFIXED);
1434 rb->lcd_putsxyf(125, LCD_HEIGHT-20,"Cash: %d", humanres.cash);
1435 rb->lcd_putsxyf(125, LCD_HEIGHT-10,"Food: %d", humanres.food);
1436 rb->lcd_setfont(FONT_UI);
1437 #endif
1438 rb->lcd_update();
1439 while(1) {
1440 button = rb->button_get(true);
1441 switch(button) {
1442 case SUPERDOM_CANCEL:
1443 rb->splash(HZ, "Cancelled");
1444 return RET_VAL_QUIT_ERR;
1445 break;
1446 case SUPERDOM_OK:
1447 return RET_VAL_OK;
1448 break;
1449 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1450 case SUPERDOM_LEFT:
1451 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1452 draw_cursor(); /* Deselect the current tile */
1453 if(cursor.x>1) {
1454 cursor.x--;
1455 } else {
1456 #ifdef IPOD_STYLE
1457 if(cursor.y>1)
1458 cursor.y--;
1459 else
1460 cursor.y = 10;
1461 #endif
1462 cursor.x = 10;
1464 update_score();
1465 draw_cursor();
1466 break;
1467 case SUPERDOM_RIGHT:
1468 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1469 draw_cursor(); /* Deselect the current tile */
1470 if(cursor.x<10) {
1471 cursor.x++;
1472 } else {
1473 #ifdef IPOD_STYLE
1474 if(cursor.y<10)
1475 cursor.y++;
1476 else
1477 cursor.y = 1;
1478 #endif
1479 cursor.x = 1;
1481 update_score();
1482 draw_cursor();
1483 break;
1484 #endif
1485 #ifndef IPOD_STYLE
1486 case SUPERDOM_UP:
1487 case (SUPERDOM_UP|BUTTON_REPEAT):
1488 draw_cursor(); /* Deselect the current tile */
1489 if(cursor.y>1) {
1490 cursor.y--;
1491 } else {
1492 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1493 if(cursor.x > 1)
1494 cursor.x--;
1495 else
1496 cursor.x = 10;
1497 #endif
1498 cursor.y = 10;
1500 update_score();
1501 draw_cursor();
1502 break;
1503 case SUPERDOM_DOWN:
1504 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1505 draw_cursor(); /* Deselect the current tile */
1506 if(cursor.y<10) {
1507 cursor.y++;
1508 } else {
1509 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1510 if(cursor.x < 10)
1511 cursor.x++;
1512 else
1513 cursor.x = 1;
1514 #endif
1515 cursor.y = 1;
1517 update_score();
1518 draw_cursor();
1519 break;
1520 #endif
1521 default:
1522 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1524 return RET_VAL_USB;
1530 int killmen(int colour) {
1531 bool human = (colour == COLOUR_LIGHT);
1532 int menkilled,i,j;
1533 int percent;
1534 if(human) {
1535 percent = (humanres.food*1000)/humanres.men;
1536 humanres.food = 0;
1537 } else {
1538 percent = (compres.food*1000)/compres.men;
1539 compres.food = 0;
1541 menkilled = 0;
1542 for(i=1;i<11;i++) {
1543 for(j=1;j<11;j++) {
1544 if(board[i][j].colour == colour) {
1545 int nummen = ((board[i][j].men * percent)/1000);
1546 menkilled += board[i][j].men - nummen;
1547 board[i][j].men = nummen;
1552 if(human)
1553 humanres.men -= menkilled;
1554 else
1555 compres.men -= menkilled;
1556 return menkilled;
1559 /* return -1 if error, 1 if attack is succeeded, 0 otherwise */
1560 int attack_territory(int colour, int x, int y) {
1561 bool human = (colour == COLOUR_LIGHT);
1562 int str_diff;
1564 if(board[x][y].colour == colour) {
1565 if(human)
1566 rb->splash(HZ, "You can't attack your own territory");
1567 return -1;
1569 str_diff = calc_strength(COLOUR_DARK, x, y) -
1570 calc_strength(COLOUR_LIGHT, x, y);
1571 if(human) {
1572 str_diff = -str_diff;
1574 rb->srand(*rb->current_tick);
1575 if(str_diff > 0 || (str_diff == 0 && rb->rand()%2)) {
1576 struct resources *offres, *defres;
1577 if(human) {
1578 offres = &humanres;
1579 defres = &compres;
1580 } else {
1581 offres = &compres;
1582 defres = &humanres;
1584 defres->men -= board[x][y].men;
1585 defres->tanks -= board[x][y].tank;
1586 defres->planes -= board[x][y].plane;
1587 defres->nukes -= board[x][y].nuke;
1588 defres->farms -= board[x][y].farm;
1589 defres->inds -= board[x][y].ind;
1590 offres->farms += board[x][y].farm;
1591 offres->inds += board[x][y].ind;
1592 board[x][y].colour = colour;
1593 board[x][y].men = 0;
1594 board[x][y].tank = false;
1595 board[x][y].plane = false;
1596 board[x][y].nuke = false;
1597 draw_board();
1598 if(human)
1599 rb->sleep(HZ*2);
1600 else
1601 rb->sleep(HZ);
1602 return 1;
1603 } else {
1604 if(human)
1605 rb->splash(HZ, "Your troops were unable to overcome"
1606 " the enemy troops");
1607 else
1608 rb->splash(HZ*2, "The computer attempted to "
1609 "attack, but the invasion was"
1610 " pushed back");
1611 return 0;
1613 return 0;
1616 int war_menu(void) {
1617 int selection = 0, temp;
1619 MENUITEM_STRINGLIST(menu, "War!", NULL,
1620 "Select territory to attack",
1621 "Finish turn", "Game menu");
1623 while(humanres.moves) {
1624 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1625 case 0:
1626 switch(select_square()) {
1627 case RET_VAL_OK:
1628 if(attack_territory(COLOUR_LIGHT, cursor.x, cursor.y)
1629 >= 0)
1630 humanres.moves--;
1631 break;
1632 case RET_VAL_USB:
1633 return RET_VAL_USB;
1634 break;
1636 break;
1637 case 1:
1638 return RET_VAL_OK;
1639 break;
1640 case 2:
1641 if((temp = ingame_menu()) != RET_VAL_OK)
1642 return temp;
1643 break;
1646 return RET_VAL_OK;
1649 struct threat {
1650 int x;
1651 int y;
1652 int str_diff;
1655 bool place_adjacent(bool tank, int x, int y) {
1656 int type = (tank? 1: 2);
1657 if(!buy_resources(COLOUR_DARK, type, x, y, 0)) {
1658 return true;
1660 if(!buy_resources(COLOUR_DARK, type, x-1, y, 0)) {
1661 return true;
1663 if(!buy_resources(COLOUR_DARK, type, x+1, y, 0)) {
1664 return true;
1666 if(!buy_resources(COLOUR_DARK, type, x, y-1, 0)) {
1667 return true;
1669 if(!buy_resources(COLOUR_DARK, type, x, y+1, 0)) {
1670 return true;
1672 return false;
1675 bool has_adjacent(int x, int y) {
1676 if((board[x][y].colour == COLOUR_LIGHT) &&
1677 ((board[x-1][y].colour == COLOUR_DARK) ||
1678 (board[x+1][y].colour == COLOUR_DARK) ||
1679 (board[x][y+1].colour == COLOUR_DARK) ||
1680 (board[x][y-1].colour == COLOUR_DARK)))
1681 return 1;
1682 else
1683 return 0;
1686 void find_adjacent(int x, int y, int* adj_x, int* adj_y) {
1687 /* Finds adjacent squares, returning squares without tanks on them
1688 * in preference to those with them */
1689 if(board[x-1][y].colour == COLOUR_DARK) {
1690 *adj_x = x-1;
1691 *adj_y = y;
1692 return;
1694 if(board[x+1][y].colour == COLOUR_DARK) {
1695 *adj_x = x+1;
1696 *adj_y = y;
1697 return;
1699 if(board[x][y-1].colour == COLOUR_DARK) {
1700 *adj_x = x;
1701 *adj_y = y-1;
1702 return;
1704 if(board[x][y+1].colour == COLOUR_DARK) {
1705 *adj_x = x;
1706 *adj_y = y+1;
1707 return;
1711 void computer_allocate(void) {
1712 /* Firstly, decide whether to go offensive or defensive.
1713 * This is primarily decided by the human player posing a threat to either
1714 * the computer's farms or factories */
1715 int i, j, k;
1716 bool offensive = true;
1717 struct threat threats[4];
1718 int numthreats = 0;
1719 int total_str_diff = 0;
1720 int numterritory = 0;
1721 int str_diff;
1722 int men_needed;
1723 struct threat targets[2];
1724 int numtargets;
1725 struct cursor adj;
1727 compres.cash += compres.bank;
1728 compres.bank = 0;
1729 for(i=1;i<11;i++) {
1730 for(j=1;j<11;j++) {
1731 if(board[i][j].colour == COLOUR_DARK) {
1732 numterritory++;
1733 str_diff = calc_strength(COLOUR_LIGHT,i,j) -
1734 calc_strength(COLOUR_DARK,i,j);
1735 if(str_diff > 0 && (board[i][j].ind || board[i][j].farm)) {
1736 if(numthreats < 3) {
1737 offensive = false;
1738 threats[numthreats].x = i;
1739 threats[numthreats].y = j;
1740 threats[numthreats].str_diff = str_diff;
1741 numthreats++;
1745 rb->yield();
1748 if(offensive) {
1749 /* The AI is going to go straight for the throat here and attack
1750 * the player's farms and factories. The amount of cash
1751 * the AI has to spend will determine how many targets there are */
1752 if(compres.cash > 1200) {
1753 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1754 numtargets = 2;
1755 } else {
1756 numtargets = 1;
1758 /* Work out which target(s) to attack. They must have adjacent squares
1759 * owned by the computer. If none are found just place troops in
1760 * random places around the map until we run out of money */
1761 k = 0;
1762 for(i=1;i<11;i++) {
1763 for(j=1;j<11;j++) {
1764 if(has_adjacent(i,j) &&
1765 (board[i][j].ind || board[i][j].farm)) {
1766 if(k<numtargets) {
1767 targets[k].x = i;
1768 targets[k].y = j;
1769 targets[k].str_diff =
1770 calc_strength(COLOUR_LIGHT, i, j) -
1771 calc_strength(COLOUR_DARK, i, j);
1772 k++;
1775 rb->yield();
1778 if(k == 0) {
1779 /* No targets found! Randomly pick squares and if they're owned
1780 * by the computer then stick a tank on it. */
1781 rb->srand(*rb->current_tick);
1782 while(compres.cash >= 300 && compres.tanks < numterritory) {
1783 i = rb->rand()%10 + 1;
1784 j = rb->rand()%10 + 1;
1785 if(board[i][j].colour == COLOUR_DARK) {
1786 buy_resources(COLOUR_DARK, 1, i, j, 0);
1788 rb->yield();
1790 } else {
1791 for(i=0;i<k;i++) {
1792 str_diff = targets[i].str_diff;
1793 while(str_diff + 20 > 0 && compres.cash > 0) {
1794 /* While we still need them keep placing men */
1795 if(!place_adjacent(true, targets[i].x, targets[i].y)) {
1796 find_adjacent(targets[i].x, targets[i].y,
1797 &adj.x, &adj.y);
1798 men_needed = (str_diff + 20)*1000/133;
1799 if(compres.cash < men_needed) {
1800 men_needed = compres.cash;
1802 buy_resources(COLOUR_DARK, 0, adj.x, adj.y,
1803 men_needed);
1804 break;
1806 str_diff = calc_strength(COLOUR_LIGHT,
1807 targets[i].x, targets[i].y) -
1808 calc_strength(COLOUR_DARK,
1809 targets[i].x, targets[i].y);
1813 } else {
1814 /* Work out what to place on each square to defend it.
1815 * Tanks are preferential because they do not require food,
1816 * but if the budget is tight then we fall back onto troops.
1817 * Conversely if cash is not an issue and there are already tanks in
1818 * place planes will be deployed. We would like a margin of at least
1819 * 20 points to be safe. */
1821 for(i=0;i<numthreats;i++) {
1822 total_str_diff += threats[i].str_diff;
1824 if((total_str_diff+20)*10 > compres.cash) {
1825 /* Not enough cash to accomodate all threats using tanks alone -
1826 * use men as a backup */
1827 for(i=0;i<numthreats;i++) {
1828 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1829 if(compres.cash < men_needed) {
1830 men_needed = compres.cash;
1832 buy_resources(COLOUR_DARK, 0, threats[i].x, threats[i].y,
1833 men_needed);
1835 } else {
1836 /* Tanks it is */
1837 /* Enough money to pay their way by planes? */
1838 bool tank = ((total_str_diff+20)*15 >= compres.cash);
1839 for(i=0;i<numthreats;i++) {
1840 str_diff = threats[i].str_diff;
1841 while(str_diff + 20 > 0) {
1842 if(!place_adjacent(tank, threats[i].x, threats[i].y)) {
1843 /* No room for any more planes or tanks, revert to
1844 * men */
1845 find_adjacent(threats[i].x, threats[i].y,
1846 &adj.x, &adj.y);
1847 men_needed = (str_diff + 20)*1000/133;
1848 if(compres.cash < men_needed) {
1849 men_needed = compres.cash;
1851 buy_resources(COLOUR_DARK, 0, threats[i].x,
1852 threats[i].y, men_needed);
1853 break;
1855 str_diff = calc_strength(COLOUR_LIGHT,
1856 threats[i].x, threats[i].y) -
1857 calc_strength(COLOUR_DARK,
1858 threats[i].x, threats[i].y);
1863 compres.bank += compres.cash;
1864 compres.cash = 0;
1867 int find_adj_target(int x, int y, struct cursor* adj) {
1868 /* Find a square next to a computer's farm or factory owned by the player
1869 * that is vulnerable. Return 1 on success, 0 otherwise */
1870 if(board[x+1][y].colour == COLOUR_LIGHT &&
1871 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1872 adj->x = x+1;
1873 adj->y = y;
1874 return 1;
1876 if(board[x-1][y].colour == COLOUR_LIGHT &&
1877 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1878 adj->x = x-1;
1879 adj->y = y;
1880 return 1;
1882 if(board[x][y+1].colour == COLOUR_LIGHT &&
1883 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1884 adj->x = x;
1885 adj->y = y+1;
1886 return 1;
1888 if(board[x][y-1].colour == COLOUR_LIGHT &&
1889 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1890 adj->x = x;
1891 adj->y = y-1;
1892 return 1;
1894 return 0;
1897 void computer_war(void) {
1898 /* Work out where to attack - prioritise the defence of buildings */
1899 int i, j;
1900 bool found_target = true;
1901 struct cursor adj;
1903 while(found_target) {
1904 found_target = false;
1905 for(i=1;i<11;i++) {
1906 for(j=1;j<11;j++) {
1907 if((board[i][j].colour == COLOUR_DARK) &&
1908 (board[i][j].farm || board[i][j].ind) &&
1909 find_adj_target(i, j, &adj)) {
1910 found_target = true;
1911 if(attack_territory(COLOUR_DARK, adj.x, adj.y) >= 0) {
1912 compres.moves--;
1913 if(!compres.moves)
1914 return;
1917 rb->yield();
1921 /* Defence stage done, move on to OFFENCE */
1922 found_target = true;
1923 while(found_target) {
1924 found_target = false;
1925 for(i=1;i<11;i++) {
1926 for(j=1;j<11;j++) {
1927 if(board[i][j].colour == COLOUR_LIGHT &&
1928 (board[i][j].ind || board[i][j].farm) &&
1929 (calc_strength(COLOUR_DARK, i, j) >=
1930 calc_strength(COLOUR_LIGHT, i, j))) {
1931 found_target = true;
1932 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1933 compres.moves--;
1934 if(!compres.moves)
1935 return;
1938 rb->yield();
1942 /* Spend leftover moves wherever attacking randomly */
1943 found_target = true;
1944 while(found_target) {
1945 found_target = false;
1946 for(i=1;i<11;i++) {
1947 for(j=1;j<11;j++) {
1948 if(board[i][j].colour == COLOUR_LIGHT &&
1949 (calc_strength(COLOUR_DARK, i, j) >=
1950 calc_strength(COLOUR_LIGHT, i, j))) {
1951 found_target = true;
1952 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1953 compres.moves--;
1954 if(!compres.moves)
1955 return;
1958 rb->yield();
1964 static int load_game(const char* file) {
1965 int fd;
1967 fd = rb->open(file, O_RDONLY);
1968 if(fd < 0) {
1969 DEBUGF("Couldn't open savegame\n");
1970 return -1;
1972 rb->read(fd, buf, 5);
1973 if(rb->strcmp(buf, "SSGv3")) {
1974 rb->splash(HZ, "Invalid/incompatible savegame");
1975 return -1;
1977 rb->read(fd, &gamestate, sizeof(gamestate));
1978 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
1979 rb->read(fd, &humanres.food, sizeof(humanres.food));
1980 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
1981 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
1982 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
1983 rb->read(fd, &humanres.men, sizeof(humanres.men));
1984 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
1985 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
1986 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
1987 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
1988 rb->read(fd, &compres.cash, sizeof(humanres.cash));
1989 rb->read(fd, &compres.food, sizeof(humanres.food));
1990 rb->read(fd, &compres.bank, sizeof(humanres.bank));
1991 rb->read(fd, &compres.planes, sizeof(humanres.planes));
1992 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
1993 rb->read(fd, &compres.men, sizeof(humanres.men));
1994 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
1995 rb->read(fd, &compres.inds, sizeof(humanres.inds));
1996 rb->read(fd, &compres.farms, sizeof(humanres.farms));
1997 rb->read(fd, &compres.moves, sizeof(humanres.moves));
1998 rb->read(fd, board, sizeof(board));
1999 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
2000 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
2001 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
2002 rb->read(fd, &superdom_settings.humanstartinds, sizeof(int));
2003 rb->read(fd, &superdom_settings.startcash, sizeof(int));
2004 rb->read(fd, &superdom_settings.startfood, sizeof(int));
2005 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
2006 rb->close(fd);
2007 return 0;
2010 void default_settings(void) {
2011 superdom_settings.compstartfarms = 1;
2012 superdom_settings.compstartinds = 1;
2013 superdom_settings.humanstartfarms = 2;
2014 superdom_settings.humanstartinds = 2;
2015 superdom_settings.startcash = 0;
2016 superdom_settings.startfood = 0;
2017 superdom_settings.movesperturn = 2;
2020 int average_strength(int colour) {
2021 /* This function calculates the average strength of the given player,
2022 * used to determine when the computer wins or loses. */
2023 int i,j;
2024 int totalpower = 0;
2025 for(i=1;i<11;i++) {
2026 for(j=1;j<11;j++) {
2027 if(board[i][j].colour != -1) {
2028 totalpower += calc_strength(colour, i, j);
2032 return totalpower/100;
2035 enum plugin_status plugin_start(const void* parameter)
2037 #if LCD_DEPTH > 1
2038 rb->lcd_set_backdrop(NULL);
2039 rb->lcd_set_foreground(LCD_BLACK);
2040 rb->lcd_set_background(LCD_WHITE);
2041 #endif
2043 cursor.x = 1;
2044 cursor.y = 1;
2045 default_settings();
2046 if(parameter) {
2047 if(load_game(parameter) != 0) {
2048 DEBUGF("Loading failed, generating new game\n");
2049 } else {
2050 switch(gamestate) {
2051 case GS_PROD:
2052 goto startprod;
2053 break;
2054 case GS_MOVE:
2055 goto startmove;
2056 break;
2057 case GS_WAR:
2058 goto startwar;
2059 break;
2060 default:
2061 goto startyear;
2062 break;
2067 switch(start_menu()) {
2068 case RET_VAL_OK: /* start playing */
2069 break;
2070 case RET_VAL_QUIT_ERR: /* quit */
2071 return PLUGIN_OK;
2072 break;
2073 case RET_VAL_USB:
2074 return PLUGIN_USB_CONNECTED;
2075 break;
2078 init_resources();
2079 init_board();
2080 gen_resources();
2081 startyear:
2082 while(1) {
2083 int avg_str_diff = (average_strength(COLOUR_LIGHT) -
2084 average_strength(COLOUR_DARK));
2085 if(avg_str_diff > 15) {
2086 rb->splash(HZ*4, "The computer has surrendered. You win.");
2087 return PLUGIN_OK;
2089 if(-avg_str_diff > 15) {
2090 rb->splash(HZ*4, "Your army have suffered terrible morale from"
2091 " the bleak prospects of winning. You lose.");
2092 return PLUGIN_OK;
2095 /* production */
2096 startprod:
2097 gamestate = GS_PROD;
2098 switch(production_menu()) {
2099 case RET_VAL_USB:
2100 return PLUGIN_USB_CONNECTED;
2101 break;
2102 case RET_VAL_QUIT_ERR:
2103 return PLUGIN_OK;
2104 break;
2106 computer_allocate();
2108 /* movement */
2109 humanres.moves = superdom_settings.movesperturn;
2110 startmove:
2111 gamestate = GS_MOVE;
2112 switch(movement_menu()) {
2113 case RET_VAL_USB:
2114 return PLUGIN_USB_CONNECTED;
2115 break;
2116 case RET_VAL_QUIT_ERR:
2117 return PLUGIN_OK;
2118 break;
2120 /* feed men */
2121 if(humanres.men) {
2122 if(humanres.food > humanres.men) {
2123 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2124 humanres.men);
2125 humanres.food -= humanres.men;
2126 } else {
2127 rb->snprintf(buf, sizeof(buf), "There was not enough food"
2128 " to feed all your men, %d men have died of starvation",
2129 killmen(COLOUR_LIGHT));
2131 rb->splash(HZ*2, buf);
2133 if(compres.men) {
2134 if(compres.food > compres.men) {
2135 compres.food -= compres.men;
2136 } else {
2137 rb->snprintf(buf, sizeof(buf), "The computer does not have"
2138 " enough food to feed its men. %d have died of starvation",
2139 killmen(COLOUR_DARK));
2140 rb->splash(HZ, buf);
2143 /* war */
2144 humanres.moves = superdom_settings.movesperturn;
2145 startwar:
2146 gamestate = GS_WAR;
2147 switch(war_menu()) {
2148 case RET_VAL_USB:
2149 return PLUGIN_USB_CONNECTED;
2150 break;
2151 case RET_VAL_QUIT_ERR:
2152 return PLUGIN_OK;
2153 break;
2155 compres.moves = superdom_settings.movesperturn;
2156 computer_war();
2157 gen_resources();
2159 return PLUGIN_OK;