Call the oddly labelled button on the gigabeat remote "Menu" in the
[kugel-rb.git] / apps / plugins / superdom.c
blobdc078170e9dfb6cf65f7c9833f26dcd4d68cde63
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 STRIDE BMPWIDTH_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 == COWOND2_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 == ONDAVX747_PAD) || (CONFIG_KEYPAD == MROBE500_PAD)
143 #define SUPERDOM_CANCEL BUTTON_POWER
145 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
146 #define SUPERDOM_OK BUTTON_PLAY
147 #define SUPERDOM_UP BUTTON_UP
148 #define SUPERDOM_DOWN BUTTON_DOWN
149 #define SUPERDOM_LEFT BUTTON_LEFT
150 #define SUPERDOM_RIGHT BUTTON_RIGHT
151 #define SUPERDOM_CANCEL BUTTON_REW
153 #endif
155 #ifdef HAVE_TOUCHSCREEN
156 #ifndef SUPERDOM_OK
157 #define SUPERDOM_OK BUTTON_CENTER
158 #endif
159 #ifndef SUPERDOM_UP
160 #define SUPERDOM_UP BUTTON_TOPMIDDLE
161 #endif
162 #ifndef SUPERDOM_LEFT
163 #define SUPERDOM_LEFT BUTTON_MIDLEFT
164 #endif
165 #ifndef SUPERDOM_RIGHT
166 #define SUPERDOM_RIGHT BUTTON_MIDRIGHT
167 #endif
168 #ifndef SUPERDOM_DOWN
169 #define SUPERDOM_DOWN BUTTON_BOTTOMMIDDLE
170 #endif
171 #ifndef SUPERDOM_CANCEL
172 #define SUPERDOM_CANCEL BUTTON_TOPLEFT
173 #endif
174 #endif
176 enum {
177 RET_VAL_OK,
178 RET_VAL_USB,
179 RET_VAL_QUIT_ERR, /* quit or error */
182 void gen_interest(void);
183 void init_resources(void);
184 int select_square(void);
185 void update_score(void);
186 void gen_resources(void);
187 void draw_cursor(void);
188 void draw_board(void);
190 struct tile{
191 signed int colour; /* -1 = Unset */
192 bool tank;
193 bool plane;
194 bool nuke;
195 bool ind;
196 bool farm;
197 int men;
200 struct resources {
201 int cash;
202 int food;
203 int farms;
204 int inds;
205 int men;
206 int tanks;
207 int planes;
208 int nukes;
209 int bank;
210 int moves;
213 struct settings {
214 int compstartfarms;
215 int compstartinds;
216 int humanstartfarms;
217 int humanstartinds;
218 int startcash;
219 int startfood;
220 int movesperturn;
221 } superdom_settings;
223 struct resources humanres;
224 struct resources compres;
225 enum { GS_PROD, GS_MOVE, GS_WAR } gamestate;
227 struct cursor{
228 int x;
229 int y;
230 } cursor;
232 struct tile board[12][12];
234 void init_board(void) {
235 int i,j;
236 rb->srand(*rb->current_tick);
237 for(i=0;i<12;i++) { /* Hopefully about 50% each colour */
238 for(j=0;j<12;j++) {
239 if((i<1)||(j<1)||(i>10)||(j>10))
240 board[i][j].colour = -1; /* Unset */
241 else
242 board[i][j].colour = rb->rand()%2;
243 board[i][j].tank = false;
244 board[i][j].plane = false;
245 board[i][j].nuke = false;
246 board[i][j].ind = false;
247 board[i][j].farm = false;
248 board[i][j].men = 0;
252 while(compres.farms < superdom_settings.compstartfarms) {
253 i = rb->rand()%10 + 1;
254 j = rb->rand()%10 + 1;
255 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) {
256 board[i][j].farm = true;
257 compres.farms++;
260 while(compres.inds < superdom_settings.compstartinds) {
261 i = rb->rand()%10 + 1;
262 j = rb->rand()%10 + 1;
263 if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) {
264 board[i][j].ind = true;
265 compres.inds++;
268 while(humanres.farms<superdom_settings.humanstartfarms) {
269 i = rb->rand()%10 + 1;
270 j = rb->rand()%10 + 1;
271 if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) {
272 board[i][j].farm = true;
273 humanres.farms++;
276 while(humanres.inds<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].ind == false)) {
280 board[i][j].ind = true;
281 humanres.inds++;
286 void draw_board(void) {
287 int i,j;
288 rb->lcd_clear_display();
289 for(i=1;i<11;i++) {
290 for(j=1;j<11;j++) {
291 if(board[i][j].colour == COLOUR_DARK) {
292 rb->lcd_set_foreground(LCD_DARKGRAY);
293 } else {
294 rb->lcd_set_foreground(LCD_LIGHTGRAY);
296 rb->lcd_fillrect(MARGIN+(BOX_WIDTH*(i-1)),
297 MARGIN+(BOX_HEIGHT*(j-1)), BOX_WIDTH,
298 BOX_HEIGHT);
299 #if LCD_DEPTH != 16
300 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
301 #endif
302 if(board[i][j].ind) {
303 MY_BITMAP_PART(superdom_boarditems,
304 board[i][j].colour?ICON_WIDTH:0, 0, STRIDE,
305 #if LCD_WIDTH > LCD_HEIGHT
306 MARGIN+(BOX_WIDTH*(i-1))+1,
307 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
308 #else
309 MARGIN+(BOX_WIDTH*(i-1))+1+ICON_WIDTH,
310 MARGIN+(BOX_HEIGHT*(j-1))+1,
311 #endif
312 ICON_WIDTH, ICON_HEIGHT);
314 if(board[i][j].farm) {
315 MY_BITMAP_PART(superdom_boarditems,
316 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT,
317 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
318 MARGIN+(BOX_HEIGHT*(j-1))+1,
319 ICON_WIDTH, ICON_HEIGHT);
321 if(board[i][j].tank) {
322 MY_BITMAP_PART(superdom_boarditems,
323 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*2,
324 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
325 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
326 ICON_WIDTH, ICON_HEIGHT);
328 if(board[i][j].men) {
329 MY_BITMAP_PART(superdom_boarditems,
330 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*3,
331 #if LCD_WIDTH > LCD_HEIGHT
332 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
333 MARGIN+(BOX_HEIGHT*(j-1))+1,
334 #else
335 STRIDE, MARGIN+(BOX_WIDTH*(i-1))+1,
336 MARGIN+(BOX_HEIGHT*(j-1))+1+ICON_HEIGHT,
337 #endif
338 ICON_WIDTH, ICON_HEIGHT);
340 if(board[i][j].plane) {
341 MY_BITMAP_PART(superdom_boarditems,
342 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*4,
343 #if LCD_WIDTH > LCD_HEIGHT
344 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
345 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT+1,
346 #else
347 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH+1,
348 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
349 #endif
350 ICON_WIDTH, ICON_HEIGHT);
352 if(board[i][j].nuke) {
353 MY_BITMAP_PART(superdom_boarditems,
354 board[i][j].colour?ICON_WIDTH:0, ICON_HEIGHT*5,
355 #if LCD_WIDTH > LCD_HEIGHT
356 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+ICON_WIDTH*2+1,
357 MARGIN+(BOX_HEIGHT*(j-1))+1,
358 #else
359 STRIDE,MARGIN+(BOX_WIDTH*(i-1))+1,
360 MARGIN+(BOX_HEIGHT*(j-1))+ICON_HEIGHT*2+1,
361 #endif
362 ICON_WIDTH, ICON_HEIGHT);
364 #if LCD_DEPTH != 16
365 rb->lcd_set_drawmode(DRMODE_SOLID);
366 #endif
369 rb->lcd_set_foreground(LCD_BLACK);
370 for(i=0;i<=10;i++) { /* Draw Horizontal lines */
371 rb->lcd_hline(MARGIN, MARGIN+(BOX_WIDTH*10), MARGIN+(BOX_HEIGHT*i));
373 for(i=0;i<=10;i++) { /* Draw Vertical lines */
374 rb->lcd_vline(MARGIN+(BOX_WIDTH*i), MARGIN, MARGIN+(BOX_HEIGHT*10));
376 rb->lcd_update();
379 int calc_strength(int colour, int x, int y) {
380 int a, b, score=0;
381 for (a = -1; a < 2; a++) {
382 for (b = -1; b < 2; b++) {
383 if ((b == 0 || a == 0) &&
384 (board[x + a][y + b].colour == colour)) {
385 score += 10;
386 if(board[x + a][y + b].tank || board[x + a][y + b].farm)
387 score += 30;
388 if(board[x + a][y + b].plane || board[x + a][y + b].ind)
389 score += 40;
390 if(board[x + a][y + b].nuke)
391 score += 20;
392 if(board[x + a][y + b].men)
393 score += (board[x + a][y + b].men*133/1000);
397 return score;
400 void gen_interest(void) {
401 /* Interest should be around 10% */
402 rb->srand(*rb->current_tick);
403 int interest = 7+rb->rand()%6;
404 humanres.bank = humanres.bank+(interest*humanres.bank/100);
405 compres.bank = compres.bank+(interest*compres.bank/100);
408 void draw_cursor(void) {
409 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
410 rb->lcd_fillrect(MARGIN+((cursor.x-1)*BOX_WIDTH),
411 MARGIN+((cursor.y-1)*BOX_HEIGHT), BOX_WIDTH+1, BOX_HEIGHT+1);
412 rb->lcd_set_drawmode(DRMODE_SOLID);
413 rb->lcd_update();
416 void gen_resources(void) {
417 int inccash = 0;
418 int incfood = 0;
419 int ratecash = 0;
420 int ratefood = 0;
421 int i;
422 gen_interest();
423 rb->srand(*rb->current_tick);
424 /* Generate Human's resources */
425 for(i=0;i<humanres.inds;i++) {
426 inccash += (300+rb->rand()%200);
428 for(i=0;i<humanres.farms;i++) {
429 incfood += (200+rb->rand()%200);
431 if(humanres.inds)
432 ratecash = inccash/humanres.inds;
433 if(humanres.farms)
434 ratefood = incfood/humanres.farms;
435 if(ratecash > 450) {
436 if(ratefood > 350) {
437 rb->splash(HZ*2, "Patriotism sweeps the land, all production"
438 " is up this year!");
439 } else {
440 rb->splash(HZ*2, "Factories working at maximum efficiency,"
441 " cash production up this year!");
443 } else if(ratecash > 350) {
444 if(ratefood > 350) {
445 rb->splash(HZ*2, "Record crop harvest this year!");
446 } else if(ratefood > 250) {
447 rb->splash(HZ*2, "Production continues as normal");
448 } else {
449 rb->splash(HZ*2, "Spoilage of crops leads to reduced farm"
450 " output this year");
452 } else {
453 if(ratefood > 350) {
454 rb->splash(HZ*2, "Record crop harvest this year!");
455 } else if(ratefood > 250) {
456 rb->splash(HZ*2, "Factory unions introduced. Industrial"
457 " production is down this year.");
458 } else {
459 rb->splash(HZ*2, "Internet created. All production is down"
460 " due to time wasted.");
463 humanres.cash += inccash;
464 humanres.food += incfood;
466 /* Generate Computer's resources */
467 inccash = 0;
468 incfood = 0;
469 for(i=0;i<compres.inds;i++) {
470 inccash += (300+rb->rand()%200);
472 for(i=0;i<compres.farms;i++) {
473 incfood += (200+rb->rand()%200);
475 compres.cash += inccash;
476 compres.food += incfood;
479 void update_score(void) {
480 int strength;
481 rb->lcd_setfont(FONT_SYSFIXED);
482 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
483 rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
484 rb->lcd_set_drawmode(DRMODE_SOLID);
485 strength = calc_strength(COLOUR_LIGHT, cursor.x, cursor.y);
486 rb->snprintf(buf, sizeof(buf), "Your power: %d.%d",
487 strength/10, strength%10);
488 rb->lcd_putsxy(5,LCD_HEIGHT-20, buf);
489 strength = calc_strength(COLOUR_DARK, cursor.x, cursor.y);
490 rb->snprintf(buf, sizeof(buf), "Comp power: %d.%d",
491 strength/10, strength%10);
492 rb->lcd_putsxy(5,LCD_HEIGHT-10, buf);
493 rb->lcd_setfont(FONT_UI);
496 int settings_menu(void) {
497 int selection = 0;
499 MENUITEM_STRINGLIST(menu, "Super Domination Settings", NULL,
500 "Computer starting farms", "Computer starting factories",
501 "Human starting farms", "Human starting factories",
502 "Starting cash", "Starting food", "Moves per turn");
504 while(1) {
505 switch(rb->do_menu(&menu, &selection, NULL, false)) {
506 case 0:
507 rb->set_int("Computer starting farms", "", UNIT_INT,
508 &superdom_settings.compstartfarms, NULL,
509 1, 0, 5, NULL);
510 break;
511 case 1:
512 rb->set_int("Computer starting factories", "", UNIT_INT,
513 &superdom_settings.compstartinds, NULL,
514 1, 0, 5, NULL);
515 break;
516 case 2:
517 rb->set_int("Human starting farms", "", UNIT_INT,
518 &superdom_settings.humanstartfarms, NULL,
519 1, 0, 5, NULL);
520 break;
521 case 3:
522 rb->set_int("Human starting factories", "", UNIT_INT,
523 &superdom_settings.humanstartinds, NULL,
524 1, 0, 5, NULL);
525 break;
526 case 4:
527 rb->set_int("Starting cash", "", UNIT_INT,
528 &superdom_settings.startcash, NULL,
529 250, 0, 5000, NULL);
530 break;
531 case 5:
532 rb->set_int("Starting food", "", UNIT_INT,
533 &superdom_settings.startfood, NULL,
534 250, 0, 5000, NULL);
535 break;
536 case 6:
537 rb->set_int("Moves per turn", "", UNIT_INT,
538 &superdom_settings.movesperturn, NULL,
539 1, 1, 5, NULL);
540 break;
541 case MENU_ATTACHED_USB:
542 return RET_VAL_USB;
543 break;
544 case GO_TO_PREVIOUS:
545 return RET_VAL_OK;
546 break;
549 return RET_VAL_OK;
552 static int superdom_help(void) {
553 int button;
554 #define WORDS (sizeof help_text / sizeof (char*))
555 static char* help_text[] = {
556 "Super", "domination", "is", "a", "turn", "based", "strategy", "game,",
557 "where", "the", "aim", "is", "to", "overpower", "the", "computer",
558 "player", "by", "taking", "their", "territory.", "",
559 "Each", "year", "you", "are", "allocated", "an", "amount", "of", "cash",
560 "and", "food,", "depending", "on", "how", "many", "farms", "and",
561 "factories", "you", "control.", "",
562 "Use", "this", "cash", "and", "food", "to", "buy", "and", "feed", "your",
563 "army.", "Each", "tile", "has", "a", "strength,", "calculated", "by",
564 "the", "ownership", "of", "adjacent", "tiles,", "and", "the", "type",
565 "and", "number", "of", "troops", "on", "them.",
568 if (display_text(WORDS, help_text, NULL, NULL))
569 return RET_VAL_USB;
570 do {
571 button = rb->button_get(true);
572 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
573 return RET_VAL_USB;
574 } while( ( button == BUTTON_NONE )
575 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
577 return RET_VAL_OK;
580 int start_menu(void) {
581 int selection = 0;
583 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
584 "Play Super Domination", "Settings",
585 "Help", "Playback Control", "Quit");
587 while(1) {
588 switch(rb->do_menu(&menu, &selection, NULL, false)) {
589 case 0:
590 return RET_VAL_OK; /* start playing */
591 break;
592 case 1:
593 if(settings_menu()==RET_VAL_USB)
594 return RET_VAL_USB;
595 break;
596 case 2:
597 if(superdom_help()==RET_VAL_USB)
598 return RET_VAL_USB;
599 break;
600 case 3:
601 if(playback_control(NULL))
602 return RET_VAL_USB;
603 break;
604 default:
605 return RET_VAL_QUIT_ERR;
606 break;
609 return RET_VAL_QUIT_ERR;
612 int save_game(void) {
613 int fd;
614 char savepath[MAX_PATH];
616 rb->snprintf(savepath, sizeof(savepath), "/Savegame.ssg");
617 if(rb->kbd_input(savepath, MAX_PATH)) {
618 DEBUGF("Keyboard input failed\n");
619 return -1;
622 fd = rb->open(savepath, O_WRONLY|O_CREAT);
623 DEBUGF("savepath: %s\n", savepath);
624 if(fd < 0) {
625 DEBUGF("Couldn't create/open file\n");
626 return -1;
629 rb->write(fd, "SSGv3", 5);
630 rb->write(fd, &gamestate, sizeof(gamestate));
631 rb->write(fd, &humanres.cash, sizeof(humanres.cash));
632 rb->write(fd, &humanres.food, sizeof(humanres.food));
633 rb->write(fd, &humanres.bank, sizeof(humanres.bank));
634 rb->write(fd, &humanres.planes, sizeof(humanres.planes));
635 rb->write(fd, &humanres.tanks, sizeof(humanres.tanks));
636 rb->write(fd, &humanres.men, sizeof(humanres.men));
637 rb->write(fd, &humanres.nukes, sizeof(humanres.nukes));
638 rb->write(fd, &humanres.inds, sizeof(humanres.inds));
639 rb->write(fd, &humanres.farms, sizeof(humanres.farms));
640 rb->write(fd, &humanres.moves, sizeof(humanres.moves));
641 rb->write(fd, &compres.cash, sizeof(compres.cash));
642 rb->write(fd, &compres.food, sizeof(compres.food));
643 rb->write(fd, &compres.bank, sizeof(compres.bank));
644 rb->write(fd, &compres.planes, sizeof(compres.planes));
645 rb->write(fd, &compres.tanks, sizeof(compres.tanks));
646 rb->write(fd, &compres.men, sizeof(compres.men));
647 rb->write(fd, &compres.nukes, sizeof(compres.nukes));
648 rb->write(fd, &compres.inds, sizeof(compres.inds));
649 rb->write(fd, &compres.farms, sizeof(compres.farms));
650 rb->write(fd, &compres.moves, sizeof(compres.moves));
651 rb->write(fd, board, sizeof(board));
652 rb->write(fd, &superdom_settings.compstartfarms, sizeof(int));
653 rb->write(fd, &superdom_settings.compstartinds, sizeof(int));
654 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
655 rb->write(fd, &superdom_settings.humanstartfarms, sizeof(int));
656 rb->write(fd, &superdom_settings.startcash, sizeof(int));
657 rb->write(fd, &superdom_settings.startfood, sizeof(int));
658 rb->write(fd, &superdom_settings.movesperturn, sizeof(int));
659 rb->close(fd);
660 return 0;
663 int ingame_menu(void) {
664 MENUITEM_STRINGLIST(menu, "Super Domination Menu", NULL,
665 "Return to game", "Save Game",
666 "Playback Control", "Quit");
668 switch(rb->do_menu(&menu, NULL, NULL, false)) {
669 case 0:
670 return RET_VAL_OK;
671 break;
672 case 1:
673 if(!save_game())
674 rb->splash(HZ, "Game saved");
675 else
676 rb->splash(HZ, "Error in save");
677 break;
678 case 2:
679 if(playback_control(NULL))
680 return RET_VAL_USB;
681 break;
682 case 3:
683 return RET_VAL_QUIT_ERR;
684 break;
685 case MENU_ATTACHED_USB:
686 return RET_VAL_USB;
687 break;
688 case GO_TO_PREVIOUS:
689 return RET_VAL_OK;
690 break;
692 return RET_VAL_OK;
695 int get_number(char* param, int* value) {
696 static const char *button_labels[4][3] = {
697 { "1", "2", "3" },
698 { "4", "5", "6" },
699 { "7", "8", "9" },
700 { "CLR", "0", "OK" }
702 int i,j,x=0,y=0;
703 int height, width;
704 int button = 0;
705 rb->lcd_clear_display();
706 rb->lcd_getstringsize("CLR", &width, &height);
707 if(width > NUM_BOX_WIDTH || height > NUM_BOX_HEIGHT)
708 rb->lcd_setfont(FONT_SYSFIXED);
709 /* Draw a 3x4 grid */
710 for(i=0;i<=3;i++) { /* Vertical lines */
711 rb->lcd_vline(NUM_MARGIN_X+(NUM_BOX_WIDTH*i), NUM_MARGIN_Y,
712 NUM_MARGIN_Y+(4*NUM_BOX_HEIGHT));
714 for(i=0;i<=4;i++) { /* Horizontal lines */
715 rb->lcd_hline(NUM_MARGIN_X, NUM_MARGIN_X+(3*NUM_BOX_WIDTH),
716 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*i));
718 for(i=0;i<4;i++) {
719 for(j=0;j<3;j++) {
720 rb->lcd_getstringsize(button_labels[i][j], &width, &height);
721 rb->lcd_putsxy(
722 NUM_MARGIN_X+(j*NUM_BOX_WIDTH)+NUM_BOX_WIDTH/2-width/2,
723 NUM_MARGIN_Y+(i*NUM_BOX_HEIGHT)+NUM_BOX_HEIGHT/2-height/2,
724 button_labels[i][j]);
727 rb->snprintf(buf,sizeof(buf), "%d", *value);
728 rb->lcd_putsxy(NUM_MARGIN_X+10, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
729 rb->lcd_getstringsize(param, &width, &height);
730 if(width < LCD_WIDTH)
731 rb->lcd_putsxy((LCD_WIDTH-width)/2, (NUM_MARGIN_Y-height)/2, param);
732 else
733 rb->lcd_puts_scroll(0, (NUM_MARGIN_Y/height-1)/2, param);
734 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
735 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
736 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
737 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
738 rb->lcd_set_drawmode(DRMODE_SOLID);
739 rb->lcd_update();
740 while(1) {
741 button = rb->button_get(true);
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 switch(button) {
748 case SUPERDOM_OK:
749 if(y!=3) {
750 *value *= 10;
751 *value += button_labels[y][x][0] - '0';
752 } else if(x==0) {
753 *value /= 10;
754 } else if(x==1) {
755 *value *= 10;
756 } else if(x==2) {
757 rb->lcd_setfont(FONT_UI);
758 return RET_VAL_OK;
760 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
761 rb->lcd_fillrect(0, NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10,
762 LCD_WIDTH, 30);
763 rb->lcd_set_drawmode(DRMODE_SOLID);
764 rb->snprintf(buf,sizeof(buf), "%d", *value);
765 rb->lcd_putsxy(NUM_MARGIN_X+10,
766 NUM_MARGIN_Y+4*NUM_BOX_HEIGHT+10, buf);
767 break;
768 case SUPERDOM_CANCEL:
769 *value = 0;
770 rb->lcd_setfont(FONT_UI);
771 rb->splash(HZ, "Cancelled");
772 return RET_VAL_QUIT_ERR;
773 break;
774 #if CONFIG_KEYPAD != IRIVER_H10_PAD
775 case SUPERDOM_LEFT:
776 if(x==0) {
777 #ifdef IPOD_STYLE
778 if(y>0)
779 y--;
780 else
781 y=3;
782 #endif
783 x=2;
784 } else {
785 x--;
787 break;
788 case SUPERDOM_RIGHT:
789 if(x==2) {
790 #ifdef IPOD_STYLE
791 if(y==3)
792 y=0;
793 else
794 y++;
795 #endif
796 x=0;
797 } else {
798 x++;
800 break;
801 #endif
802 #ifndef IPOD_STYLE
803 case SUPERDOM_UP:
804 if(y==0) {
805 #if CONFIG_KEYPAD == IRIVER_H10_PAD
806 if(x > 0)
807 x--;
808 else
809 x=2;
810 #endif
811 y=3;
812 } else {
813 y--;
815 break;
816 case SUPERDOM_DOWN:
817 if(y==3) {
818 #if CONFIG_KEYPAD == IRIVER_H10_PAD
819 if(x < 2)
820 x++;
821 else
822 x=0;
823 #endif
824 y=0;
825 } else {
826 y++;
828 break;
829 #endif
830 default:
831 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
833 rb->lcd_setfont(FONT_UI);
834 return RET_VAL_USB;
836 break;
838 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
839 rb->lcd_fillrect(NUM_MARGIN_X+(NUM_BOX_WIDTH*x),
840 NUM_MARGIN_Y+(NUM_BOX_HEIGHT*y),
841 NUM_BOX_WIDTH+1, NUM_BOX_HEIGHT+1);
842 rb->lcd_set_drawmode(DRMODE_SOLID);
843 rb->lcd_update();
845 rb->lcd_setfont(FONT_UI);
846 return RET_VAL_OK;
849 bool tile_has_item(int type, int x, int y) {
850 switch(type) {
851 case 0:
852 return (board[x][y].men > 0);
853 break;
854 case 1:
855 return board[x][y].tank;
856 break;
857 case 2:
858 return board[x][y].plane;
859 break;
860 case 3:
861 return board[x][y].farm;
862 break;
863 case 4:
864 return board[x][y].ind;
865 break;
866 case 5:
867 return board[x][y].nuke;
868 break;
870 return false;
873 int buy_resources(int colour, int type, int x, int y, int nummen) {
874 const char *itemnames[][6] = {
876 "them",
877 "the tank",
878 "the plane",
879 "the farm",
880 "the industrial plant",
881 "the nuke",
882 }, {
883 "place men",
884 "place a tank",
885 "place a plane",
886 "build a farm",
887 "build an industrial plant",
888 "place a nuke",
889 }, {
890 NULL,
891 "a tank",
892 "a plane",
893 "a farm",
894 "an industrial plant",
895 "a nuke",
899 bool human = (colour == COLOUR_LIGHT);
900 int price = 0;
901 int temp;
902 struct resources *res;
904 if(human) {
905 res = &humanres;
906 } else {
907 res = &compres;
909 switch(type) {
910 case 0: /* men */
911 price = 1*nummen;
912 break;
913 case 1: /* tank */
914 price = 300;
915 break;
916 case 2: /* plane */
917 price = 600;
918 break;
919 case 3: /* Farm */
920 price = 1150;
921 break;
922 case 4: /* Factory */
923 price = 1300;
924 break;
925 case 5: /* nuke */
926 price = 2000;
927 break;
929 if(res->cash < price) {
930 if(human)
931 rb->splash(HZ, "Not enough money!");
932 return RET_VAL_QUIT_ERR;
934 if(human) {
935 rb->splashf(HZ, "Where do you want to place %s?", itemnames[0][type]);
936 if((temp = select_square()) != RET_VAL_OK)
937 return temp;
938 x = cursor.x;
939 y = cursor.y;
941 if(board[x][y].colour != colour) {
942 if(human)
943 rb->splashf(HZ, "Can't %s on enemy territory", itemnames[1][type]);
944 return RET_VAL_QUIT_ERR;
946 if(type != 0 && tile_has_item(type, x, y)) {
947 if(human)
948 rb->splashf(HZ, "There is already %s there", itemnames[2][type]);
949 return RET_VAL_QUIT_ERR;
951 switch(type) {
952 case 0:
953 board[x][y].men += nummen;
954 res->men += nummen;
955 break;
956 case 1:
957 board[x][y].tank = true;
958 res->tanks++;
959 break;
960 case 2:
961 board[x][y].plane = true;
962 res->planes++;
963 break;
964 case 3:
965 board[x][y].farm = true;
966 res->farms++;
967 break;
968 case 4:
969 board[x][y].ind = true;
970 res->inds++;
971 break;
972 case 5:
973 board[x][y].nuke = true;
974 res->nukes++;
975 break;
977 res->cash -= price;
979 draw_board();
980 rb->sleep(HZ);
982 return RET_VAL_OK;
985 int buy_resources_menu(void) {
986 int selection = 0,nummen;
988 MENUITEM_STRINGLIST(menu, "Buy Resources", NULL,
989 "Buy men ($1)", "Buy tank ($300)", "Buy plane ($600)",
990 "Buy Farm ($1150)", "Buy Factory ($1300)",
991 "Buy Nuke ($2000)",
992 "Finish buying");
994 while(1) {
995 switch(rb->do_menu(&menu, &selection, NULL, false)) {
996 case 0:
997 nummen = 0;
998 if(get_number("How many men would you like?", &nummen)
999 == RET_VAL_USB)
1000 return RET_VAL_USB;
1001 if(!nummen)
1002 break;
1003 /* fall through */
1004 case 1:
1005 case 2:
1006 case 3:
1007 case 4:
1008 case 5:
1009 if(buy_resources(COLOUR_LIGHT, selection, 0, 0, nummen)
1010 == RET_VAL_USB)
1011 return RET_VAL_USB;
1012 break;
1013 case 6:
1014 return RET_VAL_OK;
1015 break;
1016 case MENU_ATTACHED_USB:
1017 return RET_VAL_USB;
1018 break;
1019 case GO_TO_PREVIOUS:
1020 return RET_VAL_OK;
1021 break;
1024 return RET_VAL_OK;
1027 int move_unit(int colour, int type, int fromx, int fromy,
1028 int tox, int toy, int nummen) {
1029 const char *itemnames[][3] = {
1031 "troops",
1032 "the tank",
1033 "the plane",
1034 }, {
1035 "any troops",
1036 "a tank",
1037 "a plane",
1038 }, {
1039 "the troops",
1040 "the tank",
1041 "the plane",
1044 bool human = (colour == COLOUR_LIGHT);
1045 int temp;
1047 if(human) {
1048 rb->splashf(HZ, "Select where you want to move %s from",
1049 itemnames[0][type]);
1050 if((temp = select_square()) != RET_VAL_OK)
1051 return temp;
1052 fromx = cursor.x;
1053 fromy = cursor.y;
1055 if(board[fromx][fromy].colour != colour) {
1056 if(human)
1057 rb->splash(HZ, "That isn't your territory");
1058 return RET_VAL_QUIT_ERR;
1060 if(!tile_has_item(type, fromx, fromy)) {
1061 if(human)
1062 rb->splashf(HZ, "You don't have %s there", itemnames[1][type]);
1063 return RET_VAL_QUIT_ERR;
1065 if(type == 0) {
1066 if(human) {
1067 nummen = board[fromx][fromy].men;
1068 if((temp = get_number("How many men do you want to move?", &nummen))
1069 != RET_VAL_OK)
1070 return temp;
1072 if(nummen > board[fromx][fromy].men) {
1073 if(human)
1074 rb->splash(HZ, "You don't have that many troops.");
1075 return RET_VAL_QUIT_ERR;
1078 if(human) {
1079 rb->splashf(HZ, "Select where you want to move %s to",
1080 itemnames[2][type]);
1081 if((temp = select_square()) != RET_VAL_OK)
1082 return temp;
1083 tox = cursor.x;
1084 toy = cursor.y;
1086 if((tox == fromx && toy == fromy) ||
1087 board[tox][toy].colour != colour ||
1088 (type != 2 && (abs(tox - fromx) > 1 || abs(toy - fromy) > 1))) {
1089 if(human)
1090 rb->splash(HZ, "Invalid move");
1091 return RET_VAL_QUIT_ERR;
1093 if(type != 0 && tile_has_item(type, tox, toy)) {
1094 if(human)
1095 rb->splashf(HZ, "There is already %s there", itemnames[1][type]);
1096 return RET_VAL_QUIT_ERR;
1098 switch(type) {
1099 case 0:
1100 board[fromx][fromy].men -= nummen;
1101 board[tox][toy].men += nummen;
1102 break;
1103 case 1:
1104 board[fromx][fromy].tank = false;
1105 board[tox][toy].tank = true;
1106 break;
1107 case 2:
1108 board[fromx][fromy].plane = false;
1109 board[tox][toy].plane = true;
1110 break;
1112 return RET_VAL_OK;
1115 int move_unit_menu(void) {
1116 int selection = 0;
1118 MENUITEM_STRINGLIST(menu, "Move unit", NULL,
1119 "Move men", "Move tank", "Move plane");
1120 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1121 case 0:
1122 case 1:
1123 case 2:
1124 switch(move_unit(COLOUR_LIGHT, selection, 0, 0, 0, 0, 0)) {
1125 case RET_VAL_OK:
1126 humanres.moves--;
1127 break;
1128 case RET_VAL_USB:
1129 return RET_VAL_USB;
1130 break;
1132 break;
1133 case MENU_ATTACHED_USB:
1134 return RET_VAL_USB;
1136 return RET_VAL_OK;
1139 int launch_nuke(int colour, int nukex, int nukey, int targetx, int targety) {
1140 bool human = (colour == COLOUR_LIGHT);
1141 int temp;
1142 struct resources *res;
1144 if(board[nukex][nukey].colour != colour) {
1145 if(human)
1146 rb->splash(HZ, "That isn't your territory");
1147 return RET_VAL_QUIT_ERR;
1149 if(! board[nukex][nukey].nuke) {
1150 if(human)
1151 rb->splashf(HZ, "You don't have %s there", "a nuke");
1152 return RET_VAL_QUIT_ERR;
1154 if(human) {
1155 rb->splash(HZ, "Select place to target with nuke");
1156 if((temp = select_square()) != RET_VAL_OK)
1157 return temp;
1158 targetx = cursor.x;
1159 targety = cursor.y;
1161 if(human) {
1162 humanres.nukes--;
1163 } else {
1164 compres.nukes--;
1166 board[nukex][nukey].nuke = false;
1168 if(board[targetx][targety].colour == COLOUR_LIGHT) {
1169 res = &humanres;
1170 } else {
1171 res = &compres;
1173 res->men -= board[targetx][targety].men;
1174 res->tanks -= board[targetx][targety].tank;
1175 res->planes -= board[targetx][targety].plane;
1176 res->nukes -= board[targetx][targety].nuke;
1177 res->farms -= board[targetx][targety].farm;
1178 res->inds -= board[targetx][targety].ind;
1179 board[targetx][targety].men = 0;
1180 board[targetx][targety].tank = false;
1181 board[targetx][targety].plane = false;
1182 board[targetx][targety].ind = false;
1183 board[targetx][targety].nuke = false;
1184 board[targetx][targety].farm = false;
1185 /* TODO: Fallout carried by wind */
1187 return RET_VAL_OK;
1190 int movement_menu(void) {
1191 int selection = 0, temp;
1193 MENUITEM_STRINGLIST(menu, "Movement", NULL,
1194 "Move unit", "Buy additional moves ($100)",
1195 "Launch nuclear missile", "Check map",
1196 "Finish moving", "Game menu");
1198 while(1) {
1199 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1200 case 0:
1201 if(humanres.moves) {
1202 if(move_unit_menu()==RET_VAL_USB)
1203 return RET_VAL_USB;
1204 } else {
1205 rb->splash(HZ, "You have no more moves left."
1206 " You can buy more for $100 each.");
1208 break;
1209 case 1:
1210 if(humanres.cash > 100) {
1211 humanres.moves++;
1212 humanres.cash -= 100;
1213 rb->snprintf(buf, sizeof(buf), "You now have %d moves",
1214 humanres.moves);
1215 rb->splash(HZ, buf);
1217 break;
1218 case 2:
1219 if(humanres.nukes==0) {
1220 rb->splash(HZ, "You do not have any nukes to launch");
1221 } else {
1222 rb->splash(HZ, "Select place to launch nuke from");
1223 switch(select_square()) {
1224 case RET_VAL_OK:
1225 if(launch_nuke(COLOUR_LIGHT, cursor.x, cursor.y,
1226 0, 0) == RET_VAL_USB)
1227 return RET_VAL_USB;
1228 break;
1229 case RET_VAL_USB:
1230 return RET_VAL_USB;
1231 break;
1234 break;
1235 case 3:
1236 if(select_square() == RET_VAL_USB)
1237 return RET_VAL_USB;
1238 break;
1239 case 4:
1240 return RET_VAL_OK;
1241 break;
1242 case 5:
1243 if((temp = ingame_menu()) != RET_VAL_OK)
1244 return temp;
1245 break;
1246 case MENU_ATTACHED_USB:
1247 return RET_VAL_USB;
1248 break;
1251 return RET_VAL_OK;
1254 static const char* inventory_data(int selected_item, void * data,
1255 char * buffer, size_t buffer_len) {
1256 (void)data;
1257 switch(selected_item) {
1258 case 0:
1259 rb->snprintf(buffer,buffer_len,"Men: %d", humanres.men);
1260 break;
1261 case 1:
1262 rb->snprintf(buffer,buffer_len,"Tanks: %d", humanres.tanks);
1263 break;
1264 case 2:
1265 rb->snprintf(buffer,buffer_len,"Planes: %d", humanres.planes);
1266 break;
1267 case 3:
1268 rb->snprintf(buffer,buffer_len,"Factories: %d", humanres.inds);
1269 break;
1270 case 4:
1271 rb->snprintf(buffer,buffer_len,"Farms: %d", humanres.farms);
1272 break;
1273 case 5:
1274 rb->snprintf(buffer,buffer_len,"Nukes: %d", humanres.nukes);
1275 break;
1276 case 6:
1277 rb->snprintf(buffer,buffer_len,"Cash: %d", humanres.cash);
1278 break;
1279 case 7:
1280 rb->snprintf(buffer,buffer_len,"Food: %d", humanres.food);
1281 break;
1282 case 8:
1283 rb->snprintf(buffer,buffer_len,"Bank: %d", humanres.bank);
1284 break;
1285 default:
1286 return NULL;
1288 return buffer;
1291 int show_inventory(void) {
1292 struct simplelist_info info;
1293 rb->simplelist_info_init(&info, "Inventory", 9, NULL);
1294 info.hide_selection = true;
1295 info.get_name = inventory_data;
1296 if(rb->simplelist_show_list(&info)) {
1297 return RET_VAL_USB;
1298 } else {
1299 return RET_VAL_OK;
1303 int production_menu(void) {
1304 int selection = 0, temp;
1306 MENUITEM_STRINGLIST(menu, "Production", NULL,
1307 "Buy resources", "Show inventory", "Check map",
1308 "Invest money", "Withdraw money",
1309 "Finish turn", "Game menu");
1311 while(1) {
1312 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1313 case 0:
1314 if(buy_resources_menu() == RET_VAL_USB)
1315 return RET_VAL_USB;
1316 break;
1317 case 1:
1318 if(show_inventory() == RET_VAL_USB)
1319 return RET_VAL_USB;
1320 break;
1321 case 2:
1322 if(select_square() == RET_VAL_USB)
1323 return RET_VAL_USB;
1324 break;
1325 case 3:
1326 temp = humanres.cash;
1327 if(get_number("How much do you want to invest?", &temp)
1328 == RET_VAL_USB)
1329 return RET_VAL_USB;
1330 if(temp > humanres.cash) {
1331 rb->splash(HZ, "You don't have that much cash to invest");
1332 } else {
1333 humanres.cash -= temp;
1334 humanres.bank += temp;
1336 break;
1337 case 4:
1338 temp = humanres.bank;
1339 if(get_number("How much do you want to withdraw?", &temp)
1340 == RET_VAL_USB)
1341 return RET_VAL_USB;
1342 if(temp > humanres.bank) {
1343 rb->splash(HZ, "You don't have that much cash to withdraw");
1344 } else {
1345 humanres.cash += temp;
1346 humanres.bank -= temp;
1348 break;
1349 case 5:
1350 return RET_VAL_OK;
1351 break;
1352 case 6:
1353 if((temp = ingame_menu()) != RET_VAL_OK)
1354 return temp;
1355 break;
1356 case MENU_ATTACHED_USB:
1357 return RET_VAL_USB;
1358 break;
1361 return RET_VAL_OK;
1364 void init_resources(void) {
1365 humanres.cash = superdom_settings.startcash;
1366 humanres.food = superdom_settings.startfood;
1367 humanres.tanks = 0;
1368 humanres.planes = 0;
1369 humanres.nukes = 0;
1370 humanres.inds = 0;
1371 humanres.farms = 0;
1372 humanres.men = 0;
1373 humanres.bank = 0;
1374 humanres.moves = 0;
1375 compres.cash = superdom_settings.startcash;
1376 compres.food = superdom_settings.startfood;
1377 compres.tanks = 0;
1378 compres.planes = 0;
1379 compres.nukes = 0;
1380 compres.inds = 0;
1381 compres.farms = 0;
1382 compres.men = 0;
1383 compres.bank = 0;
1384 compres.moves = 0;
1387 int select_square(void) {
1388 int button = 0;
1389 draw_board();
1390 draw_cursor();
1391 update_score();
1392 #if LCD_WIDTH >= 220
1393 rb->lcd_setfont(FONT_SYSFIXED);
1394 rb->snprintf(buf, sizeof(buf), "Cash: %d", humanres.cash);
1395 rb->lcd_putsxy(125, LCD_HEIGHT-20, buf);
1396 rb->snprintf(buf, sizeof(buf), "Food: %d", humanres.food);
1397 rb->lcd_putsxy(125, LCD_HEIGHT-10, buf);
1398 rb->lcd_setfont(FONT_UI);
1399 #endif
1400 rb->lcd_update();
1401 while(1) {
1402 button = rb->button_get(true);
1403 switch(button) {
1404 case SUPERDOM_CANCEL:
1405 rb->splash(HZ, "Cancelled");
1406 return RET_VAL_QUIT_ERR;
1407 break;
1408 case SUPERDOM_OK:
1409 return RET_VAL_OK;
1410 break;
1411 #if CONFIG_KEYPAD != IRIVER_H10_PAD
1412 case SUPERDOM_LEFT:
1413 case (SUPERDOM_LEFT|BUTTON_REPEAT):
1414 draw_cursor(); /* Deselect the current tile */
1415 if(cursor.x>1) {
1416 cursor.x--;
1417 } else {
1418 #ifdef IPOD_STYLE
1419 if(cursor.y>1)
1420 cursor.y--;
1421 else
1422 cursor.y = 10;
1423 #endif
1424 cursor.x = 10;
1426 update_score();
1427 draw_cursor();
1428 break;
1429 case SUPERDOM_RIGHT:
1430 case (SUPERDOM_RIGHT|BUTTON_REPEAT):
1431 draw_cursor(); /* Deselect the current tile */
1432 if(cursor.x<10) {
1433 cursor.x++;
1434 } else {
1435 #ifdef IPOD_STYLE
1436 if(cursor.y<10)
1437 cursor.y++;
1438 else
1439 cursor.y = 1;
1440 #endif
1441 cursor.x = 1;
1443 update_score();
1444 draw_cursor();
1445 break;
1446 #endif
1447 #ifndef IPOD_STYLE
1448 case SUPERDOM_UP:
1449 case (SUPERDOM_UP|BUTTON_REPEAT):
1450 draw_cursor(); /* Deselect the current tile */
1451 if(cursor.y>1) {
1452 cursor.y--;
1453 } else {
1454 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1455 if(cursor.x > 1)
1456 cursor.x--;
1457 else
1458 cursor.x = 10;
1459 #endif
1460 cursor.y = 10;
1462 update_score();
1463 draw_cursor();
1464 break;
1465 case SUPERDOM_DOWN:
1466 case (SUPERDOM_DOWN|BUTTON_REPEAT):
1467 draw_cursor(); /* Deselect the current tile */
1468 if(cursor.y<10) {
1469 cursor.y++;
1470 } else {
1471 #if CONFIG_KEYPAD == IRIVER_H10_PAD
1472 if(cursor.x < 10)
1473 cursor.x++;
1474 else
1475 cursor.x = 1;
1476 #endif
1477 cursor.y = 1;
1479 update_score();
1480 draw_cursor();
1481 break;
1482 #endif
1483 default:
1484 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
1486 return RET_VAL_USB;
1492 int killmen(int colour) {
1493 bool human = (colour == COLOUR_LIGHT);
1494 int menkilled,i,j;
1495 int percent;
1496 if(human) {
1497 percent = (humanres.food*1000)/humanres.men;
1498 humanres.food = 0;
1499 } else {
1500 percent = (compres.food*1000)/compres.men;
1501 compres.food = 0;
1503 menkilled = 0;
1504 for(i=1;i<11;i++) {
1505 for(j=1;j<11;j++) {
1506 if(board[i][j].colour == colour) {
1507 int nummen = ((board[i][j].men * percent)/1000);
1508 menkilled += board[i][j].men - nummen;
1509 board[i][j].men = nummen;
1514 if(human)
1515 humanres.men -= menkilled;
1516 else
1517 compres.men -= menkilled;
1518 return menkilled;
1521 /* return -1 if error, 1 if attack is succeeded, 0 otherwise */
1522 int attack_territory(int colour, int x, int y) {
1523 bool human = (colour == COLOUR_LIGHT);
1524 int str_diff;
1526 if(board[x][y].colour == colour) {
1527 if(human)
1528 rb->splash(HZ, "You can't attack your own territory");
1529 return -1;
1531 str_diff = calc_strength(COLOUR_DARK, x, y) -
1532 calc_strength(COLOUR_LIGHT, x, y);
1533 if(human) {
1534 str_diff = -str_diff;
1536 rb->srand(*rb->current_tick);
1537 if(str_diff > 0 || (str_diff == 0 && rb->rand()%2)) {
1538 struct resources *offres, *defres;
1539 if(human) {
1540 offres = &humanres;
1541 defres = &compres;
1542 } else {
1543 offres = &compres;
1544 defres = &humanres;
1546 defres->men -= board[x][y].men;
1547 defres->tanks -= board[x][y].tank;
1548 defres->planes -= board[x][y].plane;
1549 defres->nukes -= board[x][y].nuke;
1550 defres->farms -= board[x][y].farm;
1551 defres->inds -= board[x][y].ind;
1552 offres->farms += board[x][y].farm;
1553 offres->inds += board[x][y].ind;
1554 board[x][y].colour = colour;
1555 board[x][y].men = 0;
1556 board[x][y].tank = false;
1557 board[x][y].plane = false;
1558 board[x][y].nuke = false;
1559 draw_board();
1560 if(human)
1561 rb->sleep(HZ*2);
1562 else
1563 rb->sleep(HZ);
1564 return 1;
1565 } else {
1566 if(human)
1567 rb->splash(HZ, "Your troops were unable to overcome"
1568 " the enemy troops");
1569 else
1570 rb->splash(HZ*2, "The computer attempted to "
1571 "attack, but the invasion was"
1572 " pushed back");
1573 return 0;
1575 return 0;
1578 int war_menu(void) {
1579 int selection = 0, temp;
1581 MENUITEM_STRINGLIST(menu, "War!", NULL,
1582 "Select territory to attack",
1583 "Finish turn", "Game menu");
1585 while(humanres.moves) {
1586 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1587 case 0:
1588 switch(select_square()) {
1589 case RET_VAL_OK:
1590 if(attack_territory(COLOUR_LIGHT, cursor.x, cursor.y)
1591 >= 0)
1592 humanres.moves--;
1593 break;
1594 case RET_VAL_USB:
1595 return RET_VAL_USB;
1596 break;
1598 break;
1599 case 1:
1600 return RET_VAL_OK;
1601 break;
1602 case 2:
1603 if((temp = ingame_menu()) != RET_VAL_OK)
1604 return temp;
1605 break;
1608 return RET_VAL_OK;
1611 struct threat {
1612 int x;
1613 int y;
1614 int str_diff;
1617 bool place_adjacent(bool tank, int x, int y) {
1618 int type = (tank? 1: 2);
1619 if(!buy_resources(COLOUR_DARK, type, x, y, 0)) {
1620 return true;
1622 if(!buy_resources(COLOUR_DARK, type, x-1, y, 0)) {
1623 return true;
1625 if(!buy_resources(COLOUR_DARK, type, x+1, y, 0)) {
1626 return true;
1628 if(!buy_resources(COLOUR_DARK, type, x, y-1, 0)) {
1629 return true;
1631 if(!buy_resources(COLOUR_DARK, type, x, y+1, 0)) {
1632 return true;
1634 return false;
1637 bool has_adjacent(int x, int y) {
1638 if((board[x][y].colour == COLOUR_LIGHT) &&
1639 ((board[x-1][y].colour == COLOUR_DARK) ||
1640 (board[x+1][y].colour == COLOUR_DARK) ||
1641 (board[x][y+1].colour == COLOUR_DARK) ||
1642 (board[x][y-1].colour == COLOUR_DARK)))
1643 return 1;
1644 else
1645 return 0;
1648 void find_adjacent(int x, int y, int* adj_x, int* adj_y) {
1649 /* Finds adjacent squares, returning squares without tanks on them
1650 * in preference to those with them */
1651 if(board[x-1][y].colour == COLOUR_DARK) {
1652 *adj_x = x-1;
1653 *adj_y = y;
1654 return;
1656 if(board[x+1][y].colour == COLOUR_DARK) {
1657 *adj_x = x+1;
1658 *adj_y = y;
1659 return;
1661 if(board[x][y-1].colour == COLOUR_DARK) {
1662 *adj_x = x;
1663 *adj_y = y-1;
1664 return;
1666 if(board[x][y+1].colour == COLOUR_DARK) {
1667 *adj_x = x;
1668 *adj_y = y+1;
1669 return;
1673 void computer_allocate(void) {
1674 /* Firstly, decide whether to go offensive or defensive.
1675 * This is primarily decided by the human player posing a threat to either
1676 * the computer's farms or factories */
1677 int i, j, k;
1678 bool offensive = true;
1679 struct threat threats[4];
1680 int numthreats = 0;
1681 int total_str_diff = 0;
1682 int numterritory = 0;
1683 int str_diff;
1684 int men_needed;
1685 struct threat targets[2];
1686 int numtargets;
1687 struct cursor adj;
1689 compres.cash += compres.bank;
1690 compres.bank = 0;
1691 for(i=1;i<11;i++) {
1692 for(j=1;j<11;j++) {
1693 if(board[i][j].colour == COLOUR_DARK) {
1694 numterritory++;
1695 str_diff = calc_strength(COLOUR_LIGHT,i,j) -
1696 calc_strength(COLOUR_DARK,i,j);
1697 if(str_diff > 0 && (board[i][j].ind || board[i][j].farm)) {
1698 if(numthreats < 3) {
1699 offensive = false;
1700 threats[numthreats].x = i;
1701 threats[numthreats].y = j;
1702 threats[numthreats].str_diff = str_diff;
1703 numthreats++;
1707 rb->yield();
1710 if(offensive) {
1711 /* The AI is going to go straight for the throat here and attack
1712 * the player's farms and factories. The amount of cash
1713 * the AI has to spend will determine how many targets there are */
1714 if(compres.cash > 1200) {
1715 /* 1200 is a figure I pulled out of nowhere. Adjust as needed */
1716 numtargets = 2;
1717 } else {
1718 numtargets = 1;
1720 /* Work out which target(s) to attack. They must have adjacent squares
1721 * owned by the computer. If none are found just place troops in
1722 * random places around the map until we run out of money */
1723 k = 0;
1724 for(i=1;i<11;i++) {
1725 for(j=1;j<11;j++) {
1726 if(has_adjacent(i,j) &&
1727 (board[i][j].ind || board[i][j].farm)) {
1728 if(k<numtargets) {
1729 targets[k].x = i;
1730 targets[k].y = j;
1731 targets[k].str_diff =
1732 calc_strength(COLOUR_LIGHT, i, j) -
1733 calc_strength(COLOUR_DARK, i, j);
1734 k++;
1737 rb->yield();
1740 if(k == 0) {
1741 /* No targets found! Randomly pick squares and if they're owned
1742 * by the computer then stick a tank on it. */
1743 rb->srand(*rb->current_tick);
1744 while(compres.cash >= 300 && compres.tanks < numterritory) {
1745 i = rb->rand()%10 + 1;
1746 j = rb->rand()%10 + 1;
1747 if(board[i][j].colour == COLOUR_DARK) {
1748 buy_resources(COLOUR_DARK, 1, i, j, 0);
1750 rb->yield();
1752 } else {
1753 for(i=0;i<k;i++) {
1754 str_diff = targets[i].str_diff;
1755 while(str_diff + 20 > 0 && compres.cash > 0) {
1756 /* While we still need them keep placing men */
1757 if(!place_adjacent(true, targets[i].x, targets[i].y)) {
1758 find_adjacent(targets[i].x, targets[i].y,
1759 &adj.x, &adj.y);
1760 men_needed = (str_diff + 20)*1000/133;
1761 if(compres.cash < men_needed) {
1762 men_needed = compres.cash;
1764 buy_resources(COLOUR_DARK, 0, adj.x, adj.y,
1765 men_needed);
1766 break;
1768 str_diff = calc_strength(COLOUR_LIGHT,
1769 targets[i].x, targets[i].y) -
1770 calc_strength(COLOUR_DARK,
1771 targets[i].x, targets[i].y);
1775 } else {
1776 /* Work out what to place on each square to defend it.
1777 * Tanks are preferential because they do not require food,
1778 * but if the budget is tight then we fall back onto troops.
1779 * Conversely if cash is not an issue and there are already tanks in
1780 * place planes will be deployed. We would like a margin of at least
1781 * 20 points to be safe. */
1783 for(i=0;i<numthreats;i++) {
1784 total_str_diff += threats[i].str_diff;
1786 if((total_str_diff+20)*10 > compres.cash) {
1787 /* Not enough cash to accomodate all threats using tanks alone -
1788 * use men as a backup */
1789 for(i=0;i<numthreats;i++) {
1790 men_needed = ((threats[i].str_diff + 20)*1000)/133;
1791 if(compres.cash < men_needed) {
1792 men_needed = compres.cash;
1794 buy_resources(COLOUR_DARK, 0, threats[i].x, threats[i].y,
1795 men_needed);
1797 } else {
1798 /* Tanks it is */
1799 /* Enough money to pay their way by planes? */
1800 bool tank = ((total_str_diff+20)*15 >= compres.cash);
1801 for(i=0;i<numthreats;i++) {
1802 str_diff = threats[i].str_diff;
1803 while(str_diff + 20 > 0) {
1804 if(!place_adjacent(tank, threats[i].x, threats[i].y)) {
1805 /* No room for any more planes or tanks, revert to
1806 * men */
1807 find_adjacent(threats[i].x, threats[i].y,
1808 &adj.x, &adj.y);
1809 men_needed = (str_diff + 20)*1000/133;
1810 if(compres.cash < men_needed) {
1811 men_needed = compres.cash;
1813 buy_resources(COLOUR_DARK, 0, threats[i].x,
1814 threats[i].y, men_needed);
1815 break;
1817 str_diff = calc_strength(COLOUR_LIGHT,
1818 threats[i].x, threats[i].y) -
1819 calc_strength(COLOUR_DARK,
1820 threats[i].x, threats[i].y);
1825 compres.bank += compres.cash;
1826 compres.cash = 0;
1829 int find_adj_target(int x, int y, struct cursor* adj) {
1830 /* Find a square next to a computer's farm or factory owned by the player
1831 * that is vulnerable. Return 1 on success, 0 otherwise */
1832 if(board[x+1][y].colour == COLOUR_LIGHT &&
1833 calc_strength(COLOUR_LIGHT,x+1,y)<=calc_strength(COLOUR_DARK,x+1,y)) {
1834 adj->x = x+1;
1835 adj->y = y;
1836 return 1;
1838 if(board[x-1][y].colour == COLOUR_LIGHT &&
1839 calc_strength(COLOUR_LIGHT,x-1,y)<=calc_strength(COLOUR_DARK,x-1,y)) {
1840 adj->x = x-1;
1841 adj->y = y;
1842 return 1;
1844 if(board[x][y+1].colour == COLOUR_LIGHT &&
1845 calc_strength(COLOUR_LIGHT,x,y+1)<=calc_strength(COLOUR_DARK,x,y+1)) {
1846 adj->x = x;
1847 adj->y = y+1;
1848 return 1;
1850 if(board[x][y-1].colour == COLOUR_LIGHT &&
1851 calc_strength(COLOUR_LIGHT,x,y-1)<=calc_strength(COLOUR_DARK,x,y-1)) {
1852 adj->x = x;
1853 adj->y = y-1;
1854 return 1;
1856 return 0;
1859 void computer_war(void) {
1860 /* Work out where to attack - prioritise the defence of buildings */
1861 int i, j;
1862 bool found_target = true;
1863 struct cursor adj;
1865 while(found_target) {
1866 found_target = false;
1867 for(i=1;i<11;i++) {
1868 for(j=1;j<11;j++) {
1869 if((board[i][j].colour == COLOUR_DARK) &&
1870 (board[i][j].farm || board[i][j].ind) &&
1871 find_adj_target(i, j, &adj)) {
1872 found_target = true;
1873 if(attack_territory(COLOUR_DARK, adj.x, adj.y) >= 0) {
1874 compres.moves--;
1875 if(!compres.moves)
1876 return;
1879 rb->yield();
1883 /* Defence stage done, move on to OFFENCE */
1884 found_target = true;
1885 while(found_target) {
1886 found_target = false;
1887 for(i=1;i<11;i++) {
1888 for(j=1;j<11;j++) {
1889 if(board[i][j].colour == COLOUR_LIGHT &&
1890 (board[i][j].ind || board[i][j].farm) &&
1891 (calc_strength(COLOUR_DARK, i, j) >=
1892 calc_strength(COLOUR_LIGHT, i, j))) {
1893 found_target = true;
1894 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1895 compres.moves--;
1896 if(!compres.moves)
1897 return;
1900 rb->yield();
1904 /* Spend leftover moves wherever attacking randomly */
1905 found_target = true;
1906 while(found_target) {
1907 found_target = false;
1908 for(i=1;i<11;i++) {
1909 for(j=1;j<11;j++) {
1910 if(board[i][j].colour == COLOUR_LIGHT &&
1911 (calc_strength(COLOUR_DARK, i, j) >=
1912 calc_strength(COLOUR_LIGHT, i, j))) {
1913 found_target = true;
1914 if(attack_territory(COLOUR_DARK, i, j) >= 0) {
1915 compres.moves--;
1916 if(!compres.moves)
1917 return;
1920 rb->yield();
1926 static int load_game(const char* file) {
1927 int fd;
1929 fd = rb->open(file, O_RDONLY);
1930 if(fd == 0) {
1931 DEBUGF("Couldn't open savegame\n");
1932 return -1;
1934 rb->read(fd, buf, 5);
1935 if(rb->strcmp(buf, "SSGv3")) {
1936 rb->splash(HZ, "Invalid/incompatible savegame");
1937 return -1;
1939 rb->read(fd, &gamestate, sizeof(gamestate));
1940 rb->read(fd, &humanres.cash, sizeof(humanres.cash));
1941 rb->read(fd, &humanres.food, sizeof(humanres.food));
1942 rb->read(fd, &humanres.bank, sizeof(humanres.bank));
1943 rb->read(fd, &humanres.planes, sizeof(humanres.planes));
1944 rb->read(fd, &humanres.tanks, sizeof(humanres.tanks));
1945 rb->read(fd, &humanres.men, sizeof(humanres.men));
1946 rb->read(fd, &humanres.nukes, sizeof(humanres.nukes));
1947 rb->read(fd, &humanres.inds, sizeof(humanres.inds));
1948 rb->read(fd, &humanres.farms, sizeof(humanres.farms));
1949 rb->read(fd, &humanres.moves, sizeof(humanres.moves));
1950 rb->read(fd, &compres.cash, sizeof(humanres.cash));
1951 rb->read(fd, &compres.food, sizeof(humanres.food));
1952 rb->read(fd, &compres.bank, sizeof(humanres.bank));
1953 rb->read(fd, &compres.planes, sizeof(humanres.planes));
1954 rb->read(fd, &compres.tanks, sizeof(humanres.tanks));
1955 rb->read(fd, &compres.men, sizeof(humanres.men));
1956 rb->read(fd, &compres.nukes, sizeof(humanres.nukes));
1957 rb->read(fd, &compres.inds, sizeof(humanres.inds));
1958 rb->read(fd, &compres.farms, sizeof(humanres.farms));
1959 rb->read(fd, &compres.moves, sizeof(humanres.moves));
1960 rb->read(fd, board, sizeof(board));
1961 rb->read(fd, &superdom_settings.compstartfarms, sizeof(int));
1962 rb->read(fd, &superdom_settings.compstartinds, sizeof(int));
1963 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
1964 rb->read(fd, &superdom_settings.humanstartfarms, sizeof(int));
1965 rb->read(fd, &superdom_settings.startcash, sizeof(int));
1966 rb->read(fd, &superdom_settings.startfood, sizeof(int));
1967 rb->read(fd, &superdom_settings.movesperturn, sizeof(int));
1968 rb->close(fd);
1969 return 0;
1972 void default_settings(void) {
1973 superdom_settings.compstartfarms = 1;
1974 superdom_settings.compstartinds = 1;
1975 superdom_settings.humanstartfarms = 2;
1976 superdom_settings.humanstartinds = 2;
1977 superdom_settings.startcash = 0;
1978 superdom_settings.startfood = 0;
1979 superdom_settings.movesperturn = 2;
1982 int average_strength(int colour) {
1983 /* This function calculates the average strength of the given player,
1984 * used to determine when the computer wins or loses. */
1985 int i,j;
1986 int totalpower = 0;
1987 for(i=1;i<11;i++) {
1988 for(j=1;j<11;j++) {
1989 if(board[i][j].colour != -1) {
1990 totalpower += calc_strength(colour, i, j);
1994 return totalpower/100;
1997 enum plugin_status plugin_start(const void* parameter)
1999 #if LCD_DEPTH > 1
2000 rb->lcd_set_backdrop(NULL);
2001 rb->lcd_set_foreground(LCD_BLACK);
2002 rb->lcd_set_background(LCD_WHITE);
2003 #endif
2005 cursor.x = 1;
2006 cursor.y = 1;
2007 default_settings();
2008 if(parameter) {
2009 if(load_game(parameter) != 0) {
2010 DEBUGF("Loading failed, generating new game\n");
2011 } else {
2012 switch(gamestate) {
2013 case GS_PROD:
2014 goto startprod;
2015 break;
2016 case GS_MOVE:
2017 goto startmove;
2018 break;
2019 case GS_WAR:
2020 goto startwar;
2021 break;
2022 default:
2023 goto startyear;
2024 break;
2029 switch(start_menu()) {
2030 case RET_VAL_OK: /* start playing */
2031 break;
2032 case RET_VAL_QUIT_ERR: /* quit */
2033 return PLUGIN_OK;
2034 break;
2035 case RET_VAL_USB:
2036 return PLUGIN_USB_CONNECTED;
2037 break;
2040 init_resources();
2041 init_board();
2042 gen_resources();
2043 startyear:
2044 while(1) {
2045 int avg_str_diff = (average_strength(COLOUR_LIGHT) -
2046 average_strength(COLOUR_DARK));
2047 if(avg_str_diff > 15) {
2048 rb->splash(HZ*4, "The computer has surrendered. You win.");
2049 return PLUGIN_OK;
2051 if(-avg_str_diff > 15) {
2052 rb->splash(HZ*4, "Your army have suffered terrible morale from"
2053 " the bleak prospects of winning. You lose.");
2054 return PLUGIN_OK;
2057 /* production */
2058 startprod:
2059 gamestate = GS_PROD;
2060 switch(production_menu()) {
2061 case RET_VAL_USB:
2062 return PLUGIN_USB_CONNECTED;
2063 break;
2064 case RET_VAL_QUIT_ERR:
2065 return PLUGIN_OK;
2066 break;
2068 computer_allocate();
2070 /* movement */
2071 humanres.moves = superdom_settings.movesperturn;
2072 startmove:
2073 gamestate = GS_MOVE;
2074 switch(movement_menu()) {
2075 case RET_VAL_USB:
2076 return PLUGIN_USB_CONNECTED;
2077 break;
2078 case RET_VAL_QUIT_ERR:
2079 return PLUGIN_OK;
2080 break;
2082 /* feed men */
2083 if(humanres.men) {
2084 if(humanres.food > humanres.men) {
2085 rb->snprintf(buf, sizeof(buf), "Your men ate %d units of food",
2086 humanres.men);
2087 humanres.food -= humanres.men;
2088 } else {
2089 rb->snprintf(buf, sizeof(buf), "There was not enough food"
2090 " to feed all your men, %d men have died of starvation",
2091 killmen(COLOUR_LIGHT));
2093 rb->splash(HZ*2, buf);
2095 if(compres.men) {
2096 if(compres.food > compres.men) {
2097 compres.food -= compres.men;
2098 } else {
2099 rb->snprintf(buf, sizeof(buf), "The computer does not have"
2100 " enough food to feed its men. %d have died of starvation",
2101 killmen(COLOUR_DARK));
2102 rb->splash(HZ, buf);
2105 /* war */
2106 humanres.moves = superdom_settings.movesperturn;
2107 startwar:
2108 gamestate = GS_WAR;
2109 switch(war_menu()) {
2110 case RET_VAL_USB:
2111 return PLUGIN_USB_CONNECTED;
2112 break;
2113 case RET_VAL_QUIT_ERR:
2114 return PLUGIN_OK;
2115 break;
2117 compres.moves = superdom_settings.movesperturn;
2118 computer_war();
2119 gen_resources();
2121 return PLUGIN_OK;