Fix red, moved around a bit to much.
[kugel-rb.git] / apps / plugins / superdom.c
blob4113ed7de24943b9977c78c9ac45a19560d562cf
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"
25 PLUGIN_HEADER
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 #define SUPERDOM_OK BUTTON_SELECT
125 #define SUPERDOM_UP BUTTON_UP
126 #define SUPERDOM_DOWN BUTTON_DOWN
127 #define SUPERDOM_LEFT BUTTON_LEFT
128 #define SUPERDOM_RIGHT BUTTON_RIGHT
129 #define SUPERDOM_CANCEL BUTTON_BACK
131 #elif CONFIG_KEYPAD == COWON_D2_PAD
132 #define SUPERDOM_CANCEL BUTTON_POWER
134 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
135 #define SUPERDOM_OK BUTTON_SELECT
136 #define SUPERDOM_UP BUTTON_UP
137 #define SUPERDOM_DOWN BUTTON_DOWN
138 #define SUPERDOM_LEFT BUTTON_LEFT
139 #define SUPERDOM_RIGHT BUTTON_RIGHT
140 #define SUPERDOM_CANCEL BUTTON_BACK
142 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
143 #define SUPERDOM_OK BUTTON_PLAY
144 #define SUPERDOM_UP BUTTON_UP
145 #define SUPERDOM_DOWN BUTTON_DOWN
146 #define SUPERDOM_LEFT BUTTON_PREV
147 #define SUPERDOM_RIGHT BUTTON_NEXT
148 #define SUPERDOM_CANCEL BUTTON_LEFT
150 #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || (CONFIG_KEYPAD == MROBE500_PAD)
151 #define SUPERDOM_CANCEL BUTTON_POWER
153 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
154 #define SUPERDOM_OK BUTTON_PLAY
155 #define SUPERDOM_UP BUTTON_UP
156 #define SUPERDOM_DOWN BUTTON_DOWN
157 #define SUPERDOM_LEFT BUTTON_LEFT
158 #define SUPERDOM_RIGHT BUTTON_RIGHT
159 #define SUPERDOM_CANCEL BUTTON_REW
161 #endif
163 #ifdef HAVE_TOUCHSCREEN
164 #ifndef SUPERDOM_OK
165 #define SUPERDOM_OK BUTTON_CENTER
166 #endif
167 #ifndef SUPERDOM_UP
168 #define SUPERDOM_UP BUTTON_TOPMIDDLE
169 #endif
170 #ifndef SUPERDOM_LEFT
171 #define SUPERDOM_LEFT BUTTON_MIDLEFT
172 #endif
173 #ifndef SUPERDOM_RIGHT
174 #define SUPERDOM_RIGHT BUTTON_MIDRIGHT
175 #endif
176 #ifndef SUPERDOM_DOWN
177 #define SUPERDOM_DOWN BUTTON_BOTTOMMIDDLE
178 #endif
179 #ifndef SUPERDOM_CANCEL
180 #define SUPERDOM_CANCEL BUTTON_TOPLEFT
181 #endif
182 #endif
184 enum {
185 RET_VAL_OK,
186 RET_VAL_USB,
187 RET_VAL_QUIT_ERR, /* quit or error */
190 void gen_interest(void);
191 void init_resources(void);
192 int select_square(void);
193 void update_score(void);
194 void gen_resources(void);
195 void draw_cursor(void);
196 void draw_board(void);
198 struct tile{
199 signed int colour; /* -1 = Unset */
200 bool tank;
201 bool plane;
202 bool nuke;
203 bool ind;
204 bool farm;
205 int men;
208 struct resources {
209 int cash;
210 int food;
211 int farms;
212 int inds;
213 int men;
214 int tanks;
215 int planes;
216 int nukes;
217 int bank;
218 int moves;
221 struct settings {
222 int compstartfarms;
223 int compstartinds;
224 int humanstartfarms;
225 int humanstartinds;
226 int startcash;
227 int startfood;
228 int movesperturn;
229 } superdom_settings;
231 struct resources humanres;
232 struct resources compres;
233 enum { GS_PROD, GS_MOVE, GS_WAR } gamestate;
235 struct cursor{
236 int x;
237 int y;
238 } cursor;
240 struct tile board[12][12];
242 void init_board(void) {
243 int i,j;
244 rb->srand(*rb->current_tick);
245 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
246 for(j=0;j<12;j++) {
247 if((i<1)||(j<1)||(i>10)||(j>10))
248 board[i][j].colour = -1; /* Unset */
249 else
250 board[i][j].colour = rb->rand()%2;
251 board[i][j].tank = false;
252 board[i][j].plane = false;
253 board[i][j].nuke = false;
254 board[i][j].ind = false;
255 board[i][j].farm = false;
256 board[i][j].men = 0;
260 while(compres.farms < superdom_settings.compstartfarms) {
261 i = rb->rand()%10 + 1;
262 j = rb->rand()%10 + 1;
263 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
264 board[i][j].farm = true;
265 compres.farms++;
268 while(compres.inds < superdom_settings.compstartinds) {
269 i = rb->rand()%10 + 1;
270 j = rb->rand()%10 + 1;
271 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
272 board[i][j].ind = true;
273 compres.inds++;
276 while(humanres.farms<superdom_settings.humanstartfarms) {
277 i = rb->rand()%10 + 1;
278 j = rb->rand()%10 + 1;
279 if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
280 board[i][j].farm = true;
281 humanres.farms++;
284 while(humanres.inds<superdom_settings.humanstartfarms) {
285 i = rb->rand()%10 + 1;
286 j = rb->rand()%10 + 1;
287 if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) {
288 board[i][j].ind = true;
289 humanres.inds++;
294 void draw_board(void) {
295 int i,j;
296 rb->lcd_clear_display();
297 for(i=1;i<11;i++) {
298 for(j=1;j<11;j++) {
299 if(board[i][j].colour == COLOUR_DARK) {
300 rb->lcd_set_foreground(LCD_DARKGRAY);
301 } else {
302 rb->lcd_set_foreground(LCD_LIGHTGRAY);
304 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
305 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
306 BOX_HEIGHT);
307 #if LCD_DEPTH != 16
308 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
309 #endif
310 if(board[i][j].ind) {
311 MY_BITMAP_PART(superdom_boarditems,
312 board[i][j].colour?ICON_WIDTH:0, 0, ICON_STRIDE,
313 #if LCD_WIDTH > LCD_HEIGHT
314 MARGIN+(BOX_WIDTH*(i-1))+1,
315 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
316 #else
317 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
318 MARGIN+(BOX_HEIGHT*(j-1))+1,
319 #endif
320 ICON_WIDTH, ICON_HEIGHT);
322 if(board[i][j].farm) {
323 MY_BITMAP_PART(superdom_boarditems,
324 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
325 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
326 MARGIN+(BOX_HEIGHT*(j-1))+1,
327 ICON_WIDTH, ICON_HEIGHT);
329 if(board[i][j].tank) {
330 MY_BITMAP_PART(superdom_boarditems,
331 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
332 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
333 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
334 ICON_WIDTH, ICON_HEIGHT);
336 if(board[i][j].men) {
337 MY_BITMAP_PART(superdom_boarditems,
338 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
339 #if LCD_WIDTH > LCD_HEIGHT
340 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
341 MARGIN+(BOX_HEIGHT*(j-1))+1,
342 #else
343 ICON_STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
344 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
345 #endif
346 ICON_WIDTH, ICON_HEIGHT);
348 if(board[i][j].plane) {
349 MY_BITMAP_PART(superdom_boarditems,
350 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
351 #if LCD_WIDTH > LCD_HEIGHT
352 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
353 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
354 #else
355 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
356 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
357 #endif
358 ICON_WIDTH, ICON_HEIGHT);
360 if(board[i][j].nuke) {
361 MY_BITMAP_PART(superdom_boarditems,
362 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
363 #if LCD_WIDTH > LCD_HEIGHT
364 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
365 MARGIN+(BOX_HEIGHT*(j-1))+1,
366 #else
367 ICON_STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
368 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
369 #endif
370 ICON_WIDTH, ICON_HEIGHT);
372 #if LCD_DEPTH != 16
373 rb->lcd_set_drawmode(DRMODE_SOLID);
374 #endif
377 rb->lcd_set_foreground(LCD_BLACK);
378 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
379 rb->lcd_hline(MARGIN, MARGIN+(BOX_WIDTH*10), MARGIN+(BOX_HEIGHT*i));
381 for(i=0;i<=10;i++) { /* Draw Vertical lines */
382 rb->lcd_vline(MARGIN+(BOX_WIDTH*i), MARGIN, MARGIN+(BOX_HEIGHT*10));
384 rb->lcd_update();
387 int calc_strength(int colour, int x, int y) {
388 int a, b, score=0;
389 for (a = -1; a < 2; a++) {
390 for (b = -1; b < 2; b++) {
391 if ((b == 0 || a == 0) &&
392 (board[x + a][y + b].colour == colour)) {
393 score += 10;
394 if(board[x + a][y + b].tank || board[x + a][y + b].farm)
395 score += 30;
396 if(board[x + a][y + b].plane || board[x + a][y + b].ind)
397 score += 40;
398 if(board[x + a][y + b].nuke)
399 score += 20;
400 if(board[x + a][y + b].men)
401 score += (board[x + a][y + b].men*133/1000);
405 return score;
408 void gen_interest(void) {
409 /* Interest should be around 10% */
410 rb->srand(*rb->current_tick);
411 int interest = 7+rb->rand()%6;
412 humanres.bank = humanres.bank+(interest*humanres.bank/100);
413 compres.bank = compres.bank+(interest*compres.bank/100);
416 void draw_cursor(void) {
417 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
418 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
419 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
420 rb->lcd_set_drawmode(DRMODE_SOLID);
421 rb->lcd_update();
424 void gen_resources(void) {
425 int inccash = 0;
426 int incfood = 0;
427 int ratecash = 0;
428 int ratefood = 0;
429 int i;
430 gen_interest();
431 rb->srand(*rb->current_tick);
432 /* Generate Human's resources */
433 for(i=0;i<humanres.inds;i++) {
434 inccash += (300+rb->rand()%200);
436 for(i=0;i<humanres.farms;i++) {
437 incfood += (200+rb->rand()%200);
439 if(humanres.inds)
440 ratecash = inccash/humanres.inds;
441 if(humanres.farms)
442 ratefood = incfood/humanres.farms;
443 if(ratecash > 450) {
444 if(ratefood > 350) {
445 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
446 " is up this year!");
447 } else {
448 rb->splash(HZ*2, "Factories working at maximum efficiency,"
449 " cash production up this year!");
451 } else if(ratecash > 350) {
452 if(ratefood > 350) {
453 rb->splash(HZ*2, "Record crop harvest this year!");
454 } else if(ratefood > 250) {
455 rb->splash(HZ*2, "Production continues as normal");
456 } else {
457 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
458 " output this year");
460 } else {
461 if(ratefood > 350) {
462 rb->splash(HZ*2, "Record crop harvest this year!");
463 } else if(ratefood > 250) {
464 rb->splash(HZ*2, "Factory unions introduced. Industrial"
465 " production is down this year.");
466 } else {
467 rb->splash(HZ*2, "Internet created. All production is down"
468 " due to time wasted.");
471 humanres.cash += inccash;
472 humanres.food += incfood;
474 /* Generate Computer's resources */
475 inccash = 0;
476 incfood = 0;
477 for(i=0;i<compres.inds;i++) {
478 inccash += (300+rb->rand()%200);
480 for(i=0;i<compres.farms;i++) {
481 incfood += (200+rb->rand()%200);
483 compres.cash += inccash;
484 compres.food += incfood;
487 void update_score(void) {
488 int strength;
489 rb->lcd_setfont(FONT_SYSFIXED);
490 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
491 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
492 rb->lcd_set_drawmode(DRMODE_SOLID);
493 strength = calc_strength(COLOUR_LIGHT, cursor.x, cursor.y);
494 rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
495 strength/10, strength%10);
496 rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
497 strength = calc_strength(COLOUR_DARK, cursor.x, cursor.y);
498 rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
499 strength/10, strength%10);
500 rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
501 rb->lcd_setfont(FONT_UI);
504 int settings_menu(void) {
505 int selection = 0;
507 MENUITEM_STRINGLIST(menu, "Super Domination Settings", NULL,
508 "Computer starting farms", "Computer starting factories",
509 "Human starting farms", "Human starting factories",
510 "Starting cash", "Starting food", "Moves per turn");
512 while(1) {
513 switch(rb->do_menu(&menu, &selection, NULL, false)) {
514 case 0:
515 rb->set_int("Computer starting farms", "", UNIT_INT,
516 &superdom_settings.compstartfarms, NULL,
517 1, 0, 5, NULL);
518 break;
519 case 1:
520 rb->set_int("Computer starting factories", "", UNIT_INT,
521 &superdom_settings.compstartinds, NULL,
522 1, 0, 5, NULL);
523 break;
524 case 2:
525 rb->set_int("Human starting farms", "", UNIT_INT,
526 &superdom_settings.humanstartfarms, NULL,
527 1, 0, 5, NULL);
528 break;
529 case 3:
530 rb->set_int("Human starting factories", "", UNIT_INT,
531 &superdom_settings.humanstartinds, NULL,
532 1, 0, 5, NULL);
533 break;
534 case 4:
535 rb->set_int("Starting cash", "", UNIT_INT,
536 &superdom_settings.startcash, NULL,
537 250, 0, 5000, NULL);
538 break;
539 case 5:
540 rb->set_int("Starting food", "", UNIT_INT,
541 &superdom_settings.startfood, NULL,
542 250, 0, 5000, NULL);
543 break;
544 case 6:
545 rb->set_int("Moves per turn", "", UNIT_INT,
546 &superdom_settings.movesperturn, NULL,
547 1, 1, 5, NULL);
548 break;
549 case MENU_ATTACHED_USB:
550 return RET_VAL_USB;
551 break;
552 case GO_TO_PREVIOUS:
553 return RET_VAL_OK;
554 break;
557 return RET_VAL_OK;
560 static int superdom_help(void) {
561 int button;
562 #define WORDS (sizeof help_text / sizeof (char*))
563 static char* help_text[] = {
564 "Super", "domination", "is", "a", "turn", "based", "strategy", "game,",
565 "where", "the", "aim", "is", "to", "overpower", "the", "computer",
566 "player", "by", "taking", "their", "territory.", "",
567 "Each", "year", "you", "are", "allocated", "an", "amount", "of", "cash",
568 "and", "food,", "depending", "on", "how", "many", "farms", "and",
569 "factories", "you", "control.", "",
570 "Use", "this", "cash", "and", "food", "to", "buy", "and", "feed", "your",
571 "army.", "Each", "tile", "has", "a", "strength,", "calculated", "by",
572 "the", "ownership", "of", "adjacent", "tiles,", "and", "the", "type",
573 "and", "number", "of", "troops", "on", "them.",
576 if (display_text(WORDS, help_text, NULL, NULL))
577 return RET_VAL_USB;
578 do {
579 button = rb->button_get(true);
580 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
581 return RET_VAL_USB;
582 } while( ( button == BUTTON_NONE )
583 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
585 return RET_VAL_OK;
588 int start_menu(void) {
589 int selection = 0;
591 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
592 "Play Super Domination", "Settings",
593 "Help", "Playback Control", "Quit");
595 while(1) {
596 switch(rb->do_menu(&menu, &selection, NULL, false)) {
597 case 0:
598 return RET_VAL_OK; /* start playing */
599 break;
600 case 1:
601 if(settings_menu()==RET_VAL_USB)
602 return RET_VAL_USB;
603 break;
604 case 2:
605 if(superdom_help()==RET_VAL_USB)
606 return RET_VAL_USB;
607 break;
608 case 3:
609 if(playback_control(NULL))
610 return RET_VAL_USB;
611 break;
612 default:
613 return RET_VAL_QUIT_ERR;
614 break;
617 return RET_VAL_QUIT_ERR;
620 int save_game(void) {
621 int fd;
622 char savepath[MAX_PATH];
624 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
625 if(rb->kbd_input(savepath, MAX_PATH)) {
626 DEBUGF("Keyboard input failed\n");
627 return -1;
630 fd = rb->open(savepath, O_WRONLY|O_CREAT);
631 DEBUGF("savepath: %s\n", savepath);
632 if(fd < 0) {
633 DEBUGF("Couldn't create/open file\n");
634 return -1;
637 rb->write(fd, "SSGv3", 5);
638 rb->write(fd, &gamestate, sizeof(gamestate));
639 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
640 rb->write(fd, &humanres.food, sizeof(humanres.food));
641 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
642 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
643 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
644 rb->write(fd, &humanres.men, sizeof(humanres.men));
645 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
646 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
647 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
648 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
649 rb->write(fd, &compres.cash, sizeof(compres.cash));
650 rb->write(fd, &compres.food, sizeof(compres.food));
651 rb->write(fd, &compres.bank, sizeof(compres.bank));
652 rb->write(fd, &compres.planes, sizeof(compres.planes));
653 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
654 rb->write(fd, &compres.men, sizeof(compres.men));
655 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
656 rb->write(fd, &compres.inds, sizeof(compres.inds));
657 rb->write(fd, &compres.farms, sizeof(compres.farms));
658 rb->write(fd, &compres.moves, sizeof(compres.moves));
659 rb->write(fd, board, sizeof(board));
660 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
661 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
662 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
663 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
664 rb->write(fd, &superdom_settings.startcash, sizeof(int));
665 rb->write(fd, &superdom_settings.startfood, sizeof(int));
666 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
667 rb->close(fd);
668 return 0;
671 int ingame_menu(void) {
672 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
673 "Return to game", "Save Game",
674 "Playback Control", "Quit");
676 switch(rb->do_menu(&menu, NULL, NULL, false)) {
677 case 0:
678 return RET_VAL_OK;
679 break;
680 case 1:
681 if(!save_game())
682 rb->splash(HZ, "Game saved");
683 else
684 rb->splash(HZ, "Error in save");
685 break;
686 case 2:
687 if(playback_control(NULL))
688 return RET_VAL_USB;
689 break;
690 case 3:
691 return RET_VAL_QUIT_ERR;
692 break;
693 case MENU_ATTACHED_USB:
694 return RET_VAL_USB;
695 break;
696 case GO_TO_PREVIOUS:
697 return RET_VAL_OK;
698 break;
700 return RET_VAL_OK;
703 int get_number(char* param, int* value) {
704 static const char *button_labels[4][3] = {
705 { "1", "2", "3" },
706 { "4", "5", "6" },
707 { "7", "8", "9" },
708 { "CLR", "0", "OK" }
710 int i,j,x=0,y=0;
711 int height, width;
712 int button = 0;
713 rb->lcd_clear_display();
714 rb->lcd_getstringsize("CLR", &width, &height);
715 if(width > NUM_BOX_WIDTH || height > NUM_BOX_HEIGHT)
716 rb->lcd_setfont(FONT_SYSFIXED);
717 /* Draw a 3x4 grid */
718 for(i=0;i<=3;i++) { /* Vertical lines */
719 rb->lcd_vline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
720 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
722 for(i=0;i<=4;i++) { /* Horizontal lines */
723 rb->lcd_hline(NUM_MARGIN_X, NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
724 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
726 for(i=0;i<4;i++) {
727 for(j=0;j<3;j++) {
728 rb->lcd_getstringsize(button_labels[i][j], &width, &height);
729 rb->lcd_putsxy(
730 NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+NUM_BOX_WIDTH/2-width/2,
731 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+NUM_BOX_HEIGHT/2-height/2,
732 button_labels[i][j]);
735 rb->snprintf(buf,sizeof(buf), "%d", *value);
736 rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
737 rb->lcd_getstringsize(param, &width, &height);
738 if(width < LCD_WIDTH)
739 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
740 else
741 rb->lcd_puts_scroll(0, (NUM_MARGIN_Y/height-1)/2, param);
742 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
743 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
744 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
745 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
746 rb->lcd_set_drawmode(DRMODE_SOLID);
747 rb->lcd_update();
748 while(1) {
749 button = rb->button_get(true);
750 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
751 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
752 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
753 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
754 rb->lcd_set_drawmode(DRMODE_SOLID);
755 switch(button) {
756 case SUPERDOM_OK:
757 if(y!=3) {
758 *value *= 10;
759 *value += button_labels[y][x][0] - '0';
760 } else if(x==0) {
761 *value /= 10;
762 } else if(x==1) {
763 *value *= 10;
764 } else if(x==2) {
765 rb->lcd_setfont(FONT_UI);
766 return RET_VAL_OK;
768 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
769 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
770 LCD_WIDTH, 30);
771 rb->lcd_set_drawmode(DRMODE_SOLID);
772 rb->snprintf(buf,sizeof(buf), "%d", *value);
773 rb->lcd_putsxy(NUM_MARGIN_X+10,
774 NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
775 break;
776 case SUPERDOM_CANCEL:
777 *value = 0;
778 rb->lcd_setfont(FONT_UI);
779 rb->splash(HZ, "Cancelled");
780 return RET_VAL_QUIT_ERR;
781 break;
782 #if CONFIG_KEYPAD != IRIVER_H10_PAD
783 case SUPERDOM_LEFT:
784 if(x==0) {
785 #ifdef IPOD_STYLE
786 if(y>0)
787 y--;
788 else
789 y=3;
790 #endif
791 x=2;
792 } else {
793 x--;
795 break;
796 case SUPERDOM_RIGHT:
797 if(x==2) {
798 #ifdef IPOD_STYLE
799 if(y==3)
800 y=0;
801 else
802 y++;
803 #endif
804 x=0;
805 } else {
806 x++;
808 break;
809 #endif
810 #ifndef IPOD_STYLE
811 case SUPERDOM_UP:
812 if(y==0) {
813 #if CONFIG_KEYPAD == IRIVER_H10_PAD
814 if(x > 0)
815 x--;
816 else
817 x=2;
818 #endif
819 y=3;
820 } else {
821 y--;
823 break;
824 case SUPERDOM_DOWN:
825 if(y==3) {
826 #if CONFIG_KEYPAD == IRIVER_H10_PAD
827 if(x < 2)
828 x++;
829 else
830 x=0;
831 #endif
832 y=0;
833 } else {
834 y++;
836 break;
837 #endif
838 default:
839 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
841 rb->lcd_setfont(FONT_UI);
842 return RET_VAL_USB;
844 break;
846 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
847 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
848 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
849 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
850 rb->lcd_set_drawmode(DRMODE_SOLID);
851 rb->lcd_update();
853 rb->lcd_setfont(FONT_UI);
854 return RET_VAL_OK;
857 bool tile_has_item(int type, int x, int y) {
858 switch(type) {
859 case 0:
860 return (board[x][y].men > 0);
861 break;
862 case 1:
863 return board[x][y].tank;
864 break;
865 case 2:
866 return board[x][y].plane;
867 break;
868 case 3:
869 return board[x][y].farm;
870 break;
871 case 4:
872 return board[x][y].ind;
873 break;
874 case 5:
875 return board[x][y].nuke;
876 break;
878 return false;
881 int buy_resources(int colour, int type, int x, int y, int nummen) {
882 const char *itemnames[][6] = {
884 "them",
885 "the tank",
886 "the plane",
887 "the farm",
888 "the industrial plant",
889 "the nuke",
890 }, {
891 "place men",
892 "place a tank",
893 "place a plane",
894 "build a farm",
895 "build an industrial plant",
896 "place a nuke",
897 }, {
898 NULL,
899 "a tank",
900 "a plane",
901 "a farm",
902 "an industrial plant",
903 "a nuke",
907 bool human = (colour == COLOUR_LIGHT);
908 int price = 0;
909 int temp;
910 struct resources *res;
912 if(human) {
913 res = &humanres;
914 } else {
915 res = &compres;
917 switch(type) {
918 case 0: /* men */
919 price = 1*nummen;
920 break;
921 case 1: /* tank */
922 price = 300;
923 break;
924 case 2: /* plane */
925 price = 600;
926 break;
927 case 3: /* Farm */
928 price = 1150;
929 break;
930 case 4: /* Factory */
931 price = 1300;
932 break;
933 case 5: /* nuke */
934 price = 2000;
935 break;
937 if(res->cash < price) {
938 if(human)
939 rb->splash(HZ, "Not enough money!");
940 return RET_VAL_QUIT_ERR;
942 if(human) {
943 rb->splashf(HZ, "Where do you want to place %s?", itemnames[0][type]);
944 if((temp = select_square()) != RET_VAL_OK)
945 return temp;
946 x = cursor.x;
947 y = cursor.y;
949 if(board[x][y].colour != colour) {
950 if(human)
951 rb->splashf(HZ, "Can't %s on enemy territory", itemnames[1][type]);
952 return RET_VAL_QUIT_ERR;
954 if(type != 0 && tile_has_item(type, x, y)) {
955 if(human)
956 rb->splashf(HZ, "There is already %s there", itemnames[2][type]);
957 return RET_VAL_QUIT_ERR;
959 switch(type) {
960 case 0:
961 board[x][y].men += nummen;
962 res->men += nummen;
963 break;
964 case 1:
965 board[x][y].tank = true;
966 res->tanks++;
967 break;
968 case 2:
969 board[x][y].plane = true;
970 res->planes++;
971 break;
972 case 3:
973 board[x][y].farm = true;
974 res->farms++;
975 break;
976 case 4:
977 board[x][y].ind = true;
978 res->inds++;
979 break;
980 case 5:
981 board[x][y].nuke = true;
982 res->nukes++;
983 break;
985 res->cash -= price;
987 draw_board();
988 rb->sleep(HZ);
990 return RET_VAL_OK;
993 int buy_resources_menu(void) {
994 int selection = 0,nummen;
996 MENUITEM_STRINGLIST(menu, "Buy Resources", NULL,
997 "Buy men ($1)", "Buy tank ($300)", "Buy plane ($600)",
998 "Buy Farm ($1150)", "Buy Factory ($1300)",
999 "Buy Nuke ($2000)",
1000 "Finish buying");
1002 while(1) {
1003 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1004 case 0:
1005 nummen = 0;
1006 if(get_number("How many men would you like?", &nummen)
1007 == RET_VAL_USB)
1008 return RET_VAL_USB;
1009 if(!nummen)
1010 break;
1011 /* fall through */
1012 case 1:
1013 case 2:
1014 case 3:
1015 case 4:
1016 case 5:
1017 if(buy_resources(COLOUR_LIGHT, selection, 0, 0, nummen)
1018 == RET_VAL_USB)
1019 return RET_VAL_USB;
1020 break;
1021 case 6:
1022 return RET_VAL_OK;
1023 break;
1024 case MENU_ATTACHED_USB:
1025 return RET_VAL_USB;
1026 break;
1027 case GO_TO_PREVIOUS:
1028 return RET_VAL_OK;
1029 break;
1032 return RET_VAL_OK;
1035 int move_unit(int colour, int type, int fromx, int fromy,
1036 int tox, int toy, int nummen) {
1037 const char *itemnames[][3] = {
1039 "troops",
1040 "the tank",
1041 "the plane",
1042 }, {
1043 "any troops",
1044 "a tank",
1045 "a plane",
1046 }, {
1047 "the troops",
1048 "the tank",
1049 "the plane",
1052 bool human = (colour == COLOUR_LIGHT);
1053 int temp;
1055 if(human) {
1056 rb->splashf(HZ, "Select where you want to move %s from",
1057 itemnames[0][type]);
1058 if((temp = select_square()) != RET_VAL_OK)
1059 return temp;
1060 fromx = cursor.x;
1061 fromy = cursor.y;
1063 if(board[fromx][fromy].colour != colour) {
1064 if(human)
1065 rb->splash(HZ, "That isn't your territory");
1066 return RET_VAL_QUIT_ERR;
1068 if(!tile_has_item(type, fromx, fromy)) {
1069 if(human)
1070 rb->splashf(HZ, "You don't have %s there", itemnames[1][type]);
1071 return RET_VAL_QUIT_ERR;
1073 if(type == 0) {
1074 if(human) {
1075 nummen = board[fromx][fromy].men;
1076 if((temp = get_number("How many men do you want to move?", &nummen))
1077 != RET_VAL_OK)
1078 return temp;
1080 if(nummen > board[fromx][fromy].men) {
1081 if(human)
1082 rb->splash(HZ, "You don't have that many troops.");
1083 return RET_VAL_QUIT_ERR;
1086 if(human) {
1087 rb->splashf(HZ, "Select where you want to move %s to",
1088 itemnames[2][type]);
1089 if((temp = select_square()) != RET_VAL_OK)
1090 return temp;
1091 tox = cursor.x;
1092 toy = cursor.y;
1094 if((tox == fromx && toy == fromy) ||
1095 board[tox][toy].colour != colour ||
1096 (type != 2 && (abs(tox - fromx) > 1 || abs(toy - fromy) > 1))) {
1097 if(human)
1098 rb->splash(HZ, "Invalid move");
1099 return RET_VAL_QUIT_ERR;
1101 if(type != 0 && tile_has_item(type, tox, toy)) {
1102 if(human)
1103 rb->splashf(HZ, "There is already %s there", itemnames[1][type]);
1104 return RET_VAL_QUIT_ERR;
1106 switch(type) {
1107 case 0:
1108 board[fromx][fromy].men -= nummen;
1109 board[tox][toy].men += nummen;
1110 break;
1111 case 1:
1112 board[fromx][fromy].tank = false;
1113 board[tox][toy].tank = true;
1114 break;
1115 case 2:
1116 board[fromx][fromy].plane = false;
1117 board[tox][toy].plane = true;
1118 break;
1120 return RET_VAL_OK;
1123 int move_unit_menu(void) {
1124 int selection = 0;
1126 MENUITEM_STRINGLIST(menu, "Move unit", NULL,
1127 "Move men", "Move tank", "Move plane");
1128 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1129 case 0:
1130 case 1:
1131 case 2:
1132 switch(move_unit(COLOUR_LIGHT, selection, 0, 0, 0, 0, 0)) {
1133 case RET_VAL_OK:
1134 humanres.moves--;
1135 break;
1136 case RET_VAL_USB:
1137 return RET_VAL_USB;
1138 break;
1140 break;
1141 case MENU_ATTACHED_USB:
1142 return RET_VAL_USB;
1144 return RET_VAL_OK;
1147 int launch_nuke(int colour, int nukex, int nukey, int targetx, int targety) {
1148 bool human = (colour == COLOUR_LIGHT);
1149 int temp;
1150 struct resources *res;
1152 if(board[nukex][nukey].colour != colour) {
1153 if(human)
1154 rb->splash(HZ, "That isn't your territory");
1155 return RET_VAL_QUIT_ERR;
1157 if(! board[nukex][nukey].nuke) {
1158 if(human)
1159 rb->splashf(HZ, "You don't have %s there", "a nuke");
1160 return RET_VAL_QUIT_ERR;
1162 if(human) {
1163 rb->splash(HZ, "Select place to target with nuke");
1164 if((temp = select_square()) != RET_VAL_OK)
1165 return temp;
1166 targetx = cursor.x;
1167 targety = cursor.y;
1169 if(human) {
1170 humanres.nukes--;
1171 } else {
1172 compres.nukes--;
1174 board[nukex][nukey].nuke = false;
1176 if(board[targetx][targety].colour == COLOUR_LIGHT) {
1177 res = &humanres;
1178 } else {
1179 res = &compres;
1181 res->men -= board[targetx][targety].men;
1182 res->tanks -= board[targetx][targety].tank;
1183 res->planes -= board[targetx][targety].plane;
1184 res->nukes -= board[targetx][targety].nuke;
1185 res->farms -= board[targetx][targety].farm;
1186 res->inds -= board[targetx][targety].ind;
1187 board[targetx][targety].men = 0;
1188 board[targetx][targety].tank = false;
1189 board[targetx][targety].plane = false;
1190 board[targetx][targety].ind = false;
1191 board[targetx][targety].nuke = false;
1192 board[targetx][targety].farm = false;
1193 /* TODO: Fallout carried by wind */
1195 return RET_VAL_OK;
1198 int movement_menu(void) {
1199 int selection = 0, temp;
1201 MENUITEM_STRINGLIST(menu, "Movement", NULL,
1202 "Move unit", "Buy additional moves ($100)",
1203 "Launch nuclear missile", "Check map",
1204 "Finish moving", "Game menu");
1206 while(1) {
1207 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1208 case 0:
1209 if(humanres.moves) {
1210 if(move_unit_menu()==RET_VAL_USB)
1211 return RET_VAL_USB;
1212 } else {
1213 rb->splash(HZ, "You have no more moves left."
1214 " You can buy more for $100 each.");
1216 break;
1217 case 1:
1218 if(humanres.cash > 100) {
1219 humanres.moves++;
1220 humanres.cash -= 100;
1221 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1222 humanres.moves);
1223 rb->splash(HZ, buf);
1225 break;
1226 case 2:
1227 if(humanres.nukes==0) {
1228 rb->splash(HZ, "You do not have any nukes to launch");
1229 } else {
1230 rb->splash(HZ, "Select place to launch nuke from");
1231 switch(select_square()) {
1232 case RET_VAL_OK:
1233 if(launch_nuke(COLOUR_LIGHT, cursor.x, cursor.y,
1234 0, 0) == RET_VAL_USB)
1235 return RET_VAL_USB;
1236 break;
1237 case RET_VAL_USB:
1238 return RET_VAL_USB;
1239 break;
1242 break;
1243 case 3:
1244 if(select_square() == RET_VAL_USB)
1245 return RET_VAL_USB;
1246 break;
1247 case 4:
1248 return RET_VAL_OK;
1249 break;
1250 case 5:
1251 if((temp = ingame_menu()) != RET_VAL_OK)
1252 return temp;
1253 break;
1254 case MENU_ATTACHED_USB:
1255 return RET_VAL_USB;
1256 break;
1259 return RET_VAL_OK;
1262 static const char* inventory_data(int selected_item, void * data,
1263 char * buffer, size_t buffer_len) {
1264 (void)data;
1265 switch(selected_item) {
1266 case 0:
1267 rb->snprintf(buffer,buffer_len,"Men: %d", humanres.men);
1268 break;
1269 case 1:
1270 rb->snprintf(buffer,buffer_len,"Tanks: %d", humanres.tanks);
1271 break;
1272 case 2:
1273 rb->snprintf(buffer,buffer_len,"Planes: %d", humanres.planes);
1274 break;
1275 case 3:
1276 rb->snprintf(buffer,buffer_len,"Factories: %d", humanres.inds);
1277 break;
1278 case 4:
1279 rb->snprintf(buffer,buffer_len,"Farms: %d", humanres.farms);
1280 break;
1281 case 5:
1282 rb->snprintf(buffer,buffer_len,"Nukes: %d", humanres.nukes);
1283 break;
1284 case 6:
1285 rb->snprintf(buffer,buffer_len,"Cash: %d", humanres.cash);
1286 break;
1287 case 7:
1288 rb->snprintf(buffer,buffer_len,"Food: %d", humanres.food);
1289 break;
1290 case 8:
1291 rb->snprintf(buffer,buffer_len,"Bank: %d", humanres.bank);
1292 break;
1293 default:
1294 return NULL;
1296 return buffer;
1299 int show_inventory(void) {
1300 struct simplelist_info info;
1301 rb->simplelist_info_init(&info, "Inventory", 9, NULL);
1302 info.hide_selection = true;
1303 info.get_name = inventory_data;
1304 if(rb->simplelist_show_list(&info)) {
1305 return RET_VAL_USB;
1306 } else {
1307 return RET_VAL_OK;
1311 int production_menu(void) {
1312 int selection = 0, temp;
1314 MENUITEM_STRINGLIST(menu, "Production", NULL,
1315 "Buy resources", "Show inventory", "Check map",
1316 "Invest money", "Withdraw money",
1317 "Finish turn", "Game menu");
1319 while(1) {
1320 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1321 case 0:
1322 if(buy_resources_menu() == RET_VAL_USB)
1323 return RET_VAL_USB;
1324 break;
1325 case 1:
1326 if(show_inventory() == RET_VAL_USB)
1327 return RET_VAL_USB;
1328 break;
1329 case 2:
1330 if(select_square() == RET_VAL_USB)
1331 return RET_VAL_USB;
1332 break;
1333 case 3:
1334 temp = humanres.cash;
1335 if(get_number("How much do you want to invest?", &temp)
1336 == RET_VAL_USB)
1337 return RET_VAL_USB;
1338 if(temp > humanres.cash) {
1339 rb->splash(HZ, "You don't have that much cash to invest");
1340 } else {
1341 humanres.cash -= temp;
1342 humanres.bank += temp;
1344 break;
1345 case 4:
1346 temp = humanres.bank;
1347 if(get_number("How much do you want to withdraw?", &temp)
1348 == RET_VAL_USB)
1349 return RET_VAL_USB;
1350 if(temp > humanres.bank) {
1351 rb->splash(HZ, "You don't have that much cash to withdraw");
1352 } else {
1353 humanres.cash += temp;
1354 humanres.bank -= temp;
1356 break;
1357 case 5:
1358 return RET_VAL_OK;
1359 break;
1360 case 6:
1361 if((temp = ingame_menu()) != RET_VAL_OK)
1362 return temp;
1363 break;
1364 case MENU_ATTACHED_USB:
1365 return RET_VAL_USB;
1366 break;
1369 return RET_VAL_OK;
1372 void init_resources(void) {
1373 humanres.cash = superdom_settings.startcash;
1374 humanres.food = superdom_settings.startfood;
1375 humanres.tanks = 0;
1376 humanres.planes = 0;
1377 humanres.nukes = 0;
1378 humanres.inds = 0;
1379 humanres.farms = 0;
1380 humanres.men = 0;
1381 humanres.bank = 0;
1382 humanres.moves = 0;
1383 compres.cash = superdom_settings.startcash;
1384 compres.food = superdom_settings.startfood;
1385 compres.tanks = 0;
1386 compres.planes = 0;
1387 compres.nukes = 0;
1388 compres.inds = 0;
1389 compres.farms = 0;
1390 compres.men = 0;
1391 compres.bank = 0;
1392 compres.moves = 0;
1395 int select_square(void) {
1396 int button = 0;
1397 draw_board();
1398 draw_cursor();
1399 update_score();
1400 #if LCD_WIDTH >= 220
1401 rb->lcd_setfont(FONT_SYSFIXED);
1402 rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
1403 rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
1404 rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
1405 rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
1406 rb->lcd_setfont(FONT_UI);
1407 #endif
1408 rb->lcd_update();
1409 while(1) {
1410 button = rb->button_get(true);
1411 switch(button) {
1412 case SUPERDOM_CANCEL:
1413 rb->splash(HZ, "Cancelled");
1414 return RET_VAL_QUIT_ERR;
1415 break;
1416 case SUPERDOM_OK:
1417 return RET_VAL_OK;
1418 break;
1419 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1420 case SUPERDOM_LEFT:
1421 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1422 draw_cursor(); /* Deselect the current tile */
1423 if(cursor.x>1) {
1424 cursor.x--;
1425 } else {
1426 #ifdef IPOD_STYLE
1427 if(cursor.y>1)
1428 cursor.y--;
1429 else
1430 cursor.y = 10;
1431 #endif
1432 cursor.x = 10;
1434 update_score();
1435 draw_cursor();
1436 break;
1437 case SUPERDOM_RIGHT:
1438 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1439 draw_cursor(); /* Deselect the current tile */
1440 if(cursor.x<10) {
1441 cursor.x++;
1442 } else {
1443 #ifdef IPOD_STYLE
1444 if(cursor.y<10)
1445 cursor.y++;
1446 else
1447 cursor.y = 1;
1448 #endif
1449 cursor.x = 1;
1451 update_score();
1452 draw_cursor();
1453 break;
1454 #endif
1455 #ifndef IPOD_STYLE
1456 case SUPERDOM_UP:
1457 case (SUPERDOM_UP|BUTTON_REPEAT):
1458 draw_cursor(); /* Deselect the current tile */
1459 if(cursor.y>1) {
1460 cursor.y--;
1461 } else {
1462 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1463 if(cursor.x > 1)
1464 cursor.x--;
1465 else
1466 cursor.x = 10;
1467 #endif
1468 cursor.y = 10;
1470 update_score();
1471 draw_cursor();
1472 break;
1473 case SUPERDOM_DOWN:
1474 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1475 draw_cursor(); /* Deselect the current tile */
1476 if(cursor.y<10) {
1477 cursor.y++;
1478 } else {
1479 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1480 if(cursor.x < 10)
1481 cursor.x++;
1482 else
1483 cursor.x = 1;
1484 #endif
1485 cursor.y = 1;
1487 update_score();
1488 draw_cursor();
1489 break;
1490 #endif
1491 default:
1492 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1494 return RET_VAL_USB;
1500 int killmen(int colour) {
1501 bool human = (colour == COLOUR_LIGHT);
1502 int menkilled,i,j;
1503 int percent;
1504 if(human) {
1505 percent = (humanres.food*1000)/humanres.men;
1506 humanres.food = 0;
1507 } else {
1508 percent = (compres.food*1000)/compres.men;
1509 compres.food = 0;
1511 menkilled = 0;
1512 for(i=1;i<11;i++) {
1513 for(j=1;j<11;j++) {
1514 if(board[i][j].colour == colour) {
1515 int nummen = ((board[i][j].men * percent)/1000);
1516 menkilled += board[i][j].men - nummen;
1517 board[i][j].men = nummen;
1522 if(human)
1523 humanres.men -= menkilled;
1524 else
1525 compres.men -= menkilled;
1526 return menkilled;
1529 /* return -1 if error, 1 if attack is succeeded, 0 otherwise */
1530 int attack_territory(int colour, int x, int y) {
1531 bool human = (colour == COLOUR_LIGHT);
1532 int str_diff;
1534 if(board[x][y].colour == colour) {
1535 if(human)
1536 rb->splash(HZ, "You can't attack your own territory");
1537 return -1;
1539 str_diff = calc_strength(COLOUR_DARK, x, y) -
1540 calc_strength(COLOUR_LIGHT, x, y);
1541 if(human) {
1542 str_diff = -str_diff;
1544 rb->srand(*rb->current_tick);
1545 if(str_diff > 0 || (str_diff == 0 && rb->rand()%2)) {
1546 struct resources *offres, *defres;
1547 if(human) {
1548 offres = &humanres;
1549 defres = &compres;
1550 } else {
1551 offres = &compres;
1552 defres = &humanres;
1554 defres->men -= board[x][y].men;
1555 defres->tanks -= board[x][y].tank;
1556 defres->planes -= board[x][y].plane;
1557 defres->nukes -= board[x][y].nuke;
1558 defres->farms -= board[x][y].farm;
1559 defres->inds -= board[x][y].ind;
1560 offres->farms += board[x][y].farm;
1561 offres->inds += board[x][y].ind;
1562 board[x][y].colour = colour;
1563 board[x][y].men = 0;
1564 board[x][y].tank = false;
1565 board[x][y].plane = false;
1566 board[x][y].nuke = false;
1567 draw_board();
1568 if(human)
1569 rb->sleep(HZ*2);
1570 else
1571 rb->sleep(HZ);
1572 return 1;
1573 } else {
1574 if(human)
1575 rb->splash(HZ, "Your troops were unable to overcome"
1576 " the enemy troops");
1577 else
1578 rb->splash(HZ*2, "The computer attempted to "
1579 "attack, but the invasion was"
1580 " pushed back");
1581 return 0;
1583 return 0;
1586 int war_menu(void) {
1587 int selection = 0, temp;
1589 MENUITEM_STRINGLIST(menu, "War!", NULL,
1590 "Select territory to attack",
1591 "Finish turn", "Game menu");
1593 while(humanres.moves) {
1594 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1595 case 0:
1596 switch(select_square()) {
1597 case RET_VAL_OK:
1598 if(attack_territory(COLOUR_LIGHT, cursor.x, cursor.y)
1599 >= 0)
1600 humanres.moves--;
1601 break;
1602 case RET_VAL_USB:
1603 return RET_VAL_USB;
1604 break;
1606 break;
1607 case 1:
1608 return RET_VAL_OK;
1609 break;
1610 case 2:
1611 if((temp = ingame_menu()) != RET_VAL_OK)
1612 return temp;
1613 break;
1616 return RET_VAL_OK;
1619 struct threat {
1620 int x;
1621 int y;
1622 int str_diff;
1625 bool place_adjacent(bool tank, int x, int y) {
1626 int type = (tank? 1: 2);
1627 if(!buy_resources(COLOUR_DARK, type, x, y, 0)) {
1628 return true;
1630 if(!buy_resources(COLOUR_DARK, type, x-1, y, 0)) {
1631 return true;
1633 if(!buy_resources(COLOUR_DARK, type, x+1, y, 0)) {
1634 return true;
1636 if(!buy_resources(COLOUR_DARK, type, x, y-1, 0)) {
1637 return true;
1639 if(!buy_resources(COLOUR_DARK, type, x, y+1, 0)) {
1640 return true;
1642 return false;
1645 bool has_adjacent(int x, int y) {
1646 if((board[x][y].colour == COLOUR_LIGHT) &&
1647 ((board[x-1][y].colour == COLOUR_DARK) ||
1648 (board[x+1][y].colour == COLOUR_DARK) ||
1649 (board[x][y+1].colour == COLOUR_DARK) ||
1650 (board[x][y-1].colour == COLOUR_DARK)))
1651 return 1;
1652 else
1653 return 0;
1656 void find_adjacent(int x, int y, int* adj_x, int* adj_y) {
1657 /* Finds adjacent squares, returning squares without tanks on them
1658 * in preference to those with them */
1659 if(board[x-1][y].colour == COLOUR_DARK) {
1660 *adj_x = x-1;
1661 *adj_y = y;
1662 return;
1664 if(board[x+1][y].colour == COLOUR_DARK) {
1665 *adj_x = x+1;
1666 *adj_y = y;
1667 return;
1669 if(board[x][y-1].colour == COLOUR_DARK) {
1670 *adj_x = x;
1671 *adj_y = y-1;
1672 return;
1674 if(board[x][y+1].colour == COLOUR_DARK) {
1675 *adj_x = x;
1676 *adj_y = y+1;
1677 return;
1681 void computer_allocate(void) {
1682 /* Firstly, decide whether to go offensive or defensive.
1683 * This is primarily decided by the human player posing a threat to either
1684 * the computer's farms or factories */
1685 int i, j, k;
1686 bool offensive = true;
1687 struct threat threats[4];
1688 int numthreats = 0;
1689 int total_str_diff = 0;
1690 int numterritory = 0;
1691 int str_diff;
1692 int men_needed;
1693 struct threat targets[2];
1694 int numtargets;
1695 struct cursor adj;
1697 compres.cash += compres.bank;
1698 compres.bank = 0;
1699 for(i=1;i<11;i++) {
1700 for(j=1;j<11;j++) {
1701 if(board[i][j].colour == COLOUR_DARK) {
1702 numterritory++;
1703 str_diff = calc_strength(COLOUR_LIGHT,i,j) -
1704 calc_strength(COLOUR_DARK,i,j);
1705 if(str_diff > 0 && (board[i][j].ind || board[i][j].farm)) {
1706 if(numthreats < 3) {
1707 offensive = false;
1708 threats[numthreats].x = i;
1709 threats[numthreats].y = j;
1710 threats[numthreats].str_diff = str_diff;
1711 numthreats++;
1715 rb->yield();
1718 if(offensive) {
1719 /* The AI is going to go straight for the throat here and attack
1720 * the player's farms and factories. The amount of cash
1721 * the AI has to spend will determine how many targets there are */
1722 if(compres.cash > 1200) {
1723 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1724 numtargets = 2;
1725 } else {
1726 numtargets = 1;
1728 /* Work out which target(s) to attack. They must have adjacent squares
1729 * owned by the computer. If none are found just place troops in
1730 * random places around the map until we run out of money */
1731 k = 0;
1732 for(i=1;i<11;i++) {
1733 for(j=1;j<11;j++) {
1734 if(has_adjacent(i,j) &&
1735 (board[i][j].ind || board[i][j].farm)) {
1736 if(k<numtargets) {
1737 targets[k].x = i;
1738 targets[k].y = j;
1739 targets[k].str_diff =
1740 calc_strength(COLOUR_LIGHT, i, j) -
1741 calc_strength(COLOUR_DARK, i, j);
1742 k++;
1745 rb->yield();
1748 if(k == 0) {
1749 /* No targets found! Randomly pick squares and if they're owned
1750 * by the computer then stick a tank on it. */
1751 rb->srand(*rb->current_tick);
1752 while(compres.cash >= 300 && compres.tanks < numterritory) {
1753 i = rb->rand()%10 + 1;
1754 j = rb->rand()%10 + 1;
1755 if(board[i][j].colour == COLOUR_DARK) {
1756 buy_resources(COLOUR_DARK, 1, i, j, 0);
1758 rb->yield();
1760 } else {
1761 for(i=0;i<k;i++) {
1762 str_diff = targets[i].str_diff;
1763 while(str_diff + 20 > 0 && compres.cash > 0) {
1764 /* While we still need them keep placing men */
1765 if(!place_adjacent(true, targets[i].x, targets[i].y)) {
1766 find_adjacent(targets[i].x, targets[i].y,
1767 &adj.x, &adj.y);
1768 men_needed = (str_diff + 20)*1000/133;
1769 if(compres.cash < men_needed) {
1770 men_needed = compres.cash;
1772 buy_resources(COLOUR_DARK, 0, adj.x, adj.y,
1773 men_needed);
1774 break;
1776 str_diff = calc_strength(COLOUR_LIGHT,
1777 targets[i].x, targets[i].y) -
1778 calc_strength(COLOUR_DARK,
1779 targets[i].x, targets[i].y);
1783 } else {
1784 /* Work out what to place on each square to defend it.
1785 * Tanks are preferential because they do not require food,
1786 * but if the budget is tight then we fall back onto troops.
1787 * Conversely if cash is not an issue and there are already tanks in
1788 * place planes will be deployed. We would like a margin of at least
1789 * 20 points to be safe. */
1791 for(i=0;i<numthreats;i++) {
1792 total_str_diff += threats[i].str_diff;
1794 if((total_str_diff+20)*10 > compres.cash) {
1795 /* Not enough cash to accomodate all threats using tanks alone -
1796 * use men as a backup */
1797 for(i=0;i<numthreats;i++) {
1798 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1799 if(compres.cash < men_needed) {
1800 men_needed = compres.cash;
1802 buy_resources(COLOUR_DARK, 0, threats[i].x, threats[i].y,
1803 men_needed);
1805 } else {
1806 /* Tanks it is */
1807 /* Enough money to pay their way by planes? */
1808 bool tank = ((total_str_diff+20)*15 >= compres.cash);
1809 for(i=0;i<numthreats;i++) {
1810 str_diff = threats[i].str_diff;
1811 while(str_diff + 20 > 0) {
1812 if(!place_adjacent(tank, threats[i].x, threats[i].y)) {
1813 /* No room for any more planes or tanks, revert to
1814 * men */
1815 find_adjacent(threats[i].x, threats[i].y,
1816 &adj.x, &adj.y);
1817 men_needed = (str_diff + 20)*1000/133;
1818 if(compres.cash < men_needed) {
1819 men_needed = compres.cash;
1821 buy_resources(COLOUR_DARK, 0, threats[i].x,
1822 threats[i].y, men_needed);
1823 break;
1825 str_diff = calc_strength(COLOUR_LIGHT,
1826 threats[i].x, threats[i].y) -
1827 calc_strength(COLOUR_DARK,
1828 threats[i].x, threats[i].y);
1833 compres.bank += compres.cash;
1834 compres.cash = 0;
1837 int find_adj_target(int x, int y, struct cursor* adj) {
1838 /* Find a square next to a computer's farm or factory owned by the player
1839 * that is vulnerable. Return 1 on success, 0 otherwise */
1840 if(board[x+1][y].colour == COLOUR_LIGHT &&
1841 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1842 adj->x = x+1;
1843 adj->y = y;
1844 return 1;
1846 if(board[x-1][y].colour == COLOUR_LIGHT &&
1847 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1848 adj->x = x-1;
1849 adj->y = y;
1850 return 1;
1852 if(board[x][y+1].colour == COLOUR_LIGHT &&
1853 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1854 adj->x = x;
1855 adj->y = y+1;
1856 return 1;
1858 if(board[x][y-1].colour == COLOUR_LIGHT &&
1859 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1860 adj->x = x;
1861 adj->y = y-1;
1862 return 1;
1864 return 0;
1867 void computer_war(void) {
1868 /* Work out where to attack - prioritise the defence of buildings */
1869 int i, j;
1870 bool found_target = true;
1871 struct cursor adj;
1873 while(found_target) {
1874 found_target = false;
1875 for(i=1;i<11;i++) {
1876 for(j=1;j<11;j++) {
1877 if((board[i][j].colour == COLOUR_DARK) &&
1878 (board[i][j].farm || board[i][j].ind) &&
1879 find_adj_target(i, j, &adj)) {
1880 found_target = true;
1881 if(attack_territory(COLOUR_DARK, adj.x, adj.y) >= 0) {
1882 compres.moves--;
1883 if(!compres.moves)
1884 return;
1887 rb->yield();
1891 /* Defence stage done, move on to OFFENCE */
1892 found_target = true;
1893 while(found_target) {
1894 found_target = false;
1895 for(i=1;i<11;i++) {
1896 for(j=1;j<11;j++) {
1897 if(board[i][j].colour == COLOUR_LIGHT &&
1898 (board[i][j].ind || board[i][j].farm) &&
1899 (calc_strength(COLOUR_DARK, i, j) >=
1900 calc_strength(COLOUR_LIGHT, i, j))) {
1901 found_target = true;
1902 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1903 compres.moves--;
1904 if(!compres.moves)
1905 return;
1908 rb->yield();
1912 /* Spend leftover moves wherever attacking randomly */
1913 found_target = true;
1914 while(found_target) {
1915 found_target = false;
1916 for(i=1;i<11;i++) {
1917 for(j=1;j<11;j++) {
1918 if(board[i][j].colour == COLOUR_LIGHT &&
1919 (calc_strength(COLOUR_DARK, i, j) >=
1920 calc_strength(COLOUR_LIGHT, i, j))) {
1921 found_target = true;
1922 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1923 compres.moves--;
1924 if(!compres.moves)
1925 return;
1928 rb->yield();
1934 static int load_game(const char* file) {
1935 int fd;
1937 fd = rb->open(file, O_RDONLY);
1938 if(fd < 0) {
1939 DEBUGF("Couldn't open savegame\n");
1940 return -1;
1942 rb->read(fd, buf, 5);
1943 if(rb->strcmp(buf, "SSGv3")) {
1944 rb->splash(HZ, "Invalid/incompatible savegame");
1945 return -1;
1947 rb->read(fd, &gamestate, sizeof(gamestate));
1948 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
1949 rb->read(fd, &humanres.food, sizeof(humanres.food));
1950 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
1951 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
1952 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
1953 rb->read(fd, &humanres.men, sizeof(humanres.men));
1954 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
1955 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
1956 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
1957 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
1958 rb->read(fd, &compres.cash, sizeof(humanres.cash));
1959 rb->read(fd, &compres.food, sizeof(humanres.food));
1960 rb->read(fd, &compres.bank, sizeof(humanres.bank));
1961 rb->read(fd, &compres.planes, sizeof(humanres.planes));
1962 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
1963 rb->read(fd, &compres.men, sizeof(humanres.men));
1964 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
1965 rb->read(fd, &compres.inds, sizeof(humanres.inds));
1966 rb->read(fd, &compres.farms, sizeof(humanres.farms));
1967 rb->read(fd, &compres.moves, sizeof(humanres.moves));
1968 rb->read(fd, board, sizeof(board));
1969 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
1970 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
1971 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
1972 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
1973 rb->read(fd, &superdom_settings.startcash, sizeof(int));
1974 rb->read(fd, &superdom_settings.startfood, sizeof(int));
1975 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
1976 rb->close(fd);
1977 return 0;
1980 void default_settings(void) {
1981 superdom_settings.compstartfarms = 1;
1982 superdom_settings.compstartinds = 1;
1983 superdom_settings.humanstartfarms = 2;
1984 superdom_settings.humanstartinds = 2;
1985 superdom_settings.startcash = 0;
1986 superdom_settings.startfood = 0;
1987 superdom_settings.movesperturn = 2;
1990 int average_strength(int colour) {
1991 /* This function calculates the average strength of the given player,
1992 * used to determine when the computer wins or loses. */
1993 int i,j;
1994 int totalpower = 0;
1995 for(i=1;i<11;i++) {
1996 for(j=1;j<11;j++) {
1997 if(board[i][j].colour != -1) {
1998 totalpower += calc_strength(colour, i, j);
2002 return totalpower/100;
2005 enum plugin_status plugin_start(const void* parameter)
2007 #if LCD_DEPTH > 1
2008 rb->lcd_set_backdrop(NULL);
2009 rb->lcd_set_foreground(LCD_BLACK);
2010 rb->lcd_set_background(LCD_WHITE);
2011 #endif
2013 cursor.x = 1;
2014 cursor.y = 1;
2015 default_settings();
2016 if(parameter) {
2017 if(load_game(parameter) != 0) {
2018 DEBUGF("Loading failed, generating new game\n");
2019 } else {
2020 switch(gamestate) {
2021 case GS_PROD:
2022 goto startprod;
2023 break;
2024 case GS_MOVE:
2025 goto startmove;
2026 break;
2027 case GS_WAR:
2028 goto startwar;
2029 break;
2030 default:
2031 goto startyear;
2032 break;
2037 switch(start_menu()) {
2038 case RET_VAL_OK: /* start playing */
2039 break;
2040 case RET_VAL_QUIT_ERR: /* quit */
2041 return PLUGIN_OK;
2042 break;
2043 case RET_VAL_USB:
2044 return PLUGIN_USB_CONNECTED;
2045 break;
2048 init_resources();
2049 init_board();
2050 gen_resources();
2051 startyear:
2052 while(1) {
2053 int avg_str_diff = (average_strength(COLOUR_LIGHT) -
2054 average_strength(COLOUR_DARK));
2055 if(avg_str_diff > 15) {
2056 rb->splash(HZ*4, "The computer has surrendered. You win.");
2057 return PLUGIN_OK;
2059 if(-avg_str_diff > 15) {
2060 rb->splash(HZ*4, "Your army have suffered terrible morale from"
2061 " the bleak prospects of winning. You lose.");
2062 return PLUGIN_OK;
2065 /* production */
2066 startprod:
2067 gamestate = GS_PROD;
2068 switch(production_menu()) {
2069 case RET_VAL_USB:
2070 return PLUGIN_USB_CONNECTED;
2071 break;
2072 case RET_VAL_QUIT_ERR:
2073 return PLUGIN_OK;
2074 break;
2076 computer_allocate();
2078 /* movement */
2079 humanres.moves = superdom_settings.movesperturn;
2080 startmove:
2081 gamestate = GS_MOVE;
2082 switch(movement_menu()) {
2083 case RET_VAL_USB:
2084 return PLUGIN_USB_CONNECTED;
2085 break;
2086 case RET_VAL_QUIT_ERR:
2087 return PLUGIN_OK;
2088 break;
2090 /* feed men */
2091 if(humanres.men) {
2092 if(humanres.food > humanres.men) {
2093 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2094 humanres.men);
2095 humanres.food -= humanres.men;
2096 } else {
2097 rb->snprintf(buf, sizeof(buf), "There was not enough food"
2098 " to feed all your men, %d men have died of starvation",
2099 killmen(COLOUR_LIGHT));
2101 rb->splash(HZ*2, buf);
2103 if(compres.men) {
2104 if(compres.food > compres.men) {
2105 compres.food -= compres.men;
2106 } else {
2107 rb->snprintf(buf, sizeof(buf), "The computer does not have"
2108 " enough food to feed its men. %d have died of starvation",
2109 killmen(COLOUR_DARK));
2110 rb->splash(HZ, buf);
2113 /* war */
2114 humanres.moves = superdom_settings.movesperturn;
2115 startwar:
2116 gamestate = GS_WAR;
2117 switch(war_menu()) {
2118 case RET_VAL_USB:
2119 return PLUGIN_USB_CONNECTED;
2120 break;
2121 case RET_VAL_QUIT_ERR:
2122 return PLUGIN_OK;
2123 break;
2125 compres.moves = superdom_settings.movesperturn;
2126 computer_war();
2127 gen_resources();
2129 return PLUGIN_OK;