source: branches/reyalp-flt/core/gui_reversi.c @ 1514

Revision 1514, 14.4 KB checked in by philmoz, 17 months ago (diff)

Update for module system for review in reyalp-flt branch

  • renamed camera_info to camera_sensor
  • added camera_screen structure for bitmap details
  • cleanup up unnecessary vid_get_bitmap_??? functions (moved to camera.h / platform_camera.h)
  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "keyboard.h"
3#include "platform.h"
4#include "core.h"
5#include "lang.h"
6#include "gui.h"
7#include "gui_draw.h"
8#include "gui_lang.h"
9#include "gui_batt.h"
10#include "gui_mbox.h"
11#include "gui_reversi.h"
12
13#include "module_load.h"
14
15void gui_module_menu_kbd_process();
16void gui_reversi_kbd_process();
17void gui_reversi_draw(int enforce_redraw);
18
19gui_handler GUI_MODE_REVERSI =
20    /*GUI_MODE_REVERSI*/    { GUI_MODE_MODULE,   gui_reversi_draw,     gui_reversi_kbd_process,    gui_module_menu_kbd_process, GUI_MODE_FLAG_NODRAWRESTORE, GUI_MODE_MAGICNUM };
21
22
23//-------------------------------------------------------------------
24#define FIELD_EMPTY             0
25#define FIELD_PLAYER1           1
26#define FIELD_PLAYER2           2
27#define COMPUTER_ONLY           3
28
29
30#define FIELD_COLOR_WHITE       COLOR_YELLOW
31#define FIELD_COLOR_BLACK       COLOR_GREY
32#define MARKER_COLOR_WHITE      COLOR_WHITE
33#define MARKER_COLOR_BLACK      COLOR_BLACK
34#define SELECTED_COLOR          COLOR_RED
35
36
37//-------------------------------------------------------------------
38typedef unsigned char uchar;
39
40//-------------------------------------------------------------------
41static uchar Field[8][8];
42static uchar CurrPlayer, Computer, InGame=0, NumPl1, NumPl2;
43
44static unsigned short field_size, field_x, field_y, cell_size;
45
46static uchar xPos=3, yPos=3;
47static volatile uchar need_redraw = 0, need_redraw_all = 0;
48
49static char buf[128];
50
51//-------------------------------------------------------------------
52static void redraw();
53static void redrawstatus();
54
55//-------------------------------------------------------------------
56static uchar NotPlayer(uchar Pl) {
57    if (Pl==FIELD_PLAYER1)
58        return FIELD_PLAYER2;
59    else
60        return FIELD_PLAYER1;
61}
62
63//-------------------------------------------------------------------
64static void InitField() {
65    uchar x, y;
66 
67    for (x=0; x<8; ++x)
68        for (y=0; y<8; ++y)
69            Field[x][y]=FIELD_EMPTY;
70   
71    Field[3][3] = Field[4][4] = FIELD_PLAYER1;
72    Field[3][4] = Field[4][3] = FIELD_PLAYER2;
73}
74
75//-------------------------------------------------------------------
76static uchar GetNum(uchar Player) {
77    uchar x, y, N=0;
78   
79    for (x=0; x<8; ++x)
80        for (y=0; y<8; ++y)
81            if (Field[x][y]==Player) ++N;
82       
83    return N;
84}
85
86//-------------------------------------------------------------------
87static uchar Place(uchar x, uchar y, uchar Player, uchar Placed) {
88/*0..64 - Ok
89 0xFF - not empty*/
90    int I, J, x1, y1;
91    uchar Eated, E;
92 
93    if (Field[x][y]!=FIELD_EMPTY) {
94        return 0xFF;
95    } else {
96        Eated=0;
97        for (I=-1;I<=1;I++) {
98            for (J=-1;J<=1;J++) {
99                E=0;
100                x1=x+I;
101                y1=y+J;
102                while (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (Field[x1][y1]!=Player)) {
103                    E++;
104                    x1=x1+I;
105                    y1=y1+J;
106                }
107                if ((Placed) && ((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (E>0)) {
108                    Field[x][y]=Player;
109                    x1=x+I;
110                    y1=y+J;
111                    while (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY) && (Field[x1][y1]!=Player)) {
112                        Field[x1][y1]=Player;
113                        x1=x1+I;
114                        y1=y1+J;
115                    }
116                }
117                if (((x1>=0) && (x1<8) && (y1>=0) && (y1<8)) && (Field[x1][y1]!=FIELD_EMPTY))
118                    Eated+=E;
119            }
120        }
121        return Eated;
122    }
123}
124
125//-------------------------------------------------------------------
126static uchar ComputerPlace(uchar Player) {
127    static const uchar PlaceTable[8][8] ={{1,8,2,2,2,2,8,1},
128                                          {8,8,6,5,5,6,8,8},
129                                          {2,6,4,3,3,4,6,2},
130                                          {2,5,3,1,1,3,5,2},
131                                          {2,5,3,1,1,3,5,2},
132                                          {2,6,4,3,3,4,6,2},
133                                          {8,8,6,5,5,6,8,8},
134                                          {1,8,2,2,2,2,8,1}};
135    uchar PlX[61];
136    uchar PlY[61];
137    uchar NPl=0, I, J, MaxE=0, E, MinPr=9;
138   
139    for (I=0; I<8; I++) {
140        for (J=0; J<8; J++) {
141            E=Place(I, J, Player, 0);
142            if ((MinPr>PlaceTable[I][J]) && (E<0xFF) && (E>0)) {
143                MinPr=PlaceTable[I][J];
144                NPl=0;
145                MaxE=0;
146            }
147            if ((E<0xFF) && (MinPr==PlaceTable[I][J])) {
148                if (E>MaxE) {
149                    MaxE=E;
150                    NPl=1;
151                    PlX[1]=I;
152                    PlY[1]=J;
153                } else {
154                    if (E==MaxE) {
155                        NPl++;
156                        PlX[NPl]=I;
157                        PlY[NPl]=J;
158                    }
159                }
160            }
161        }
162    }
163//    E=1;
164    srand(get_tick_count());
165    E=(rand()%NPl)+1;
166    Place(PlX[E],PlY[E],Player,1);
167    return ((PlX[E] << 4) | PlY[E]);
168}
169
170//-------------------------------------------------------------------
171static uchar CanPlace(uchar Player) {
172    uchar I, J, E=0, E1;
173 
174    for (I=0;I<8;I++) {
175        for (J=0;J<8;J++) {
176            E1=Place(I,J,Player,0);
177            if (E1<0xFF) E+=E1;
178        }
179    }
180    return (E>0);
181}
182
183//-------------------------------------------------------------------
184static void Result() {
185    if (NumPl1>NumPl2)
186        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_WON, MBOX_TEXT_CENTER, NULL);
187    else if (NumPl1<NumPl2)
188        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_LOST, MBOX_TEXT_CENTER, NULL);
189    else
190        gui_mbox_init(LANG_REVERSI_MSG_RESULTS_TITLE, LANG_REVERSI_MSG_RESULTS_DRAW, MBOX_TEXT_CENTER, NULL);
191    redraw();
192    redrawstatus();
193    need_redraw_all = 1;
194}
195
196//-------------------------------------------------------------------
197static void DrawCell(uchar x, uchar y) {
198    draw_filled_rect(field_x+cell_size*x, field_y+cell_size*y,
199                     field_x+cell_size*(x+1), field_y+cell_size*(y+1),
200                     (x==xPos && y==yPos)?MAKE_COLOR(SELECTED_COLOR, COLOR_RED):((x+y)&1)?MAKE_COLOR(FIELD_COLOR_WHITE, COLOR_WHITE):MAKE_COLOR(FIELD_COLOR_BLACK, COLOR_WHITE));
201}
202
203//-------------------------------------------------------------------
204static void DrawMainWindow() {
205    uchar x, y;
206
207    draw_filled_rect(0, 0, camera_screen.width-1, camera_screen.height-1, MAKE_COLOR(SCREEN_COLOR, SCREEN_COLOR));
208    for (y=0; y<8; ++y) {
209        for (x=0; x<8; ++x) {
210            DrawCell(x, y);
211        }
212    }
213    for (x=0; x<8; ++x) {
214        draw_char(field_x+cell_size*x+((cell_size-FONT_WIDTH)>>1)+1,  field_y-FONT_HEIGHT-1, '1'+x,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
215        draw_char(field_x+cell_size*x+((cell_size-FONT_WIDTH)>>1)+1,  field_y+field_size+3,  '1'+x,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
216    }
217    for (y=0; y<8; ++y) {
218        draw_char(field_x-FONT_WIDTH-4,  field_y+cell_size*y+((cell_size-FONT_HEIGHT)>>1)+1, 'A'+y,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
219        draw_char(field_x+field_size+3,  field_y+cell_size*y+((cell_size-FONT_HEIGHT)>>1)+1, 'A'+y,  MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
220    }
221}
222
223//-------------------------------------------------------------------
224static void InitMainWindow() {
225    NumPl1=GetNum(FIELD_PLAYER1);
226    NumPl2=GetNum(FIELD_PLAYER2);
227    CurrPlayer=FIELD_PLAYER1;
228    Computer=FIELD_PLAYER2;
229    InGame=0;
230
231    field_size = (camera_screen.height-2*FONT_HEIGHT-4)&0xFFF8;
232    field_x = camera_screen.ts_button_border+FONT_WIDTH+8;
233    field_y = (camera_screen.height-field_size)>>1;
234    cell_size = field_size >> 3;
235
236//    DrawMainWindow();
237}
238
239//-------------------------------------------------------------------
240static void NewGame() {
241    InitField();
242    CurrPlayer=FIELD_PLAYER1;
243    Computer=FIELD_PLAYER2;
244    NumPl1=2;
245    NumPl2=2;
246    xPos = yPos = 3;
247    InGame=1;
248    need_redraw = 1;
249}
250
251//-------------------------------------------------------------------
252static void Clk(uchar x, uchar y) {
253    uchar Placed;
254 
255    if ((CurrPlayer==Computer) || (! InGame) || (Computer==COMPUTER_ONLY))
256        ;
257    else {
258        Placed=Place(x,y ,CurrPlayer,0);
259        if (Placed==0) {
260            gui_mbox_init(LANG_REVERSI_MSG_WRONG_TITLE, LANG_REVERSI_MSG_WRONG_TEXT_1, MBOX_TEXT_CENTER, NULL);
261            need_redraw_all = 1;
262        } else if (Placed==0xFF) {
263            gui_mbox_init(LANG_REVERSI_MSG_WRONG_TITLE, LANG_REVERSI_MSG_WRONG_TEXT_2, MBOX_TEXT_CENTER, NULL);
264            need_redraw_all = 1;
265        } else {
266            Placed=Place(x, y, CurrPlayer,1);
267            CurrPlayer=NotPlayer(CurrPlayer);
268            NumPl1=GetNum(FIELD_PLAYER1);
269            NumPl2=GetNum(FIELD_PLAYER2);
270            need_redraw = 1;
271            if (!CanPlace(FIELD_PLAYER1) && !CanPlace(FIELD_PLAYER2)) {
272                InGame=0;
273                Result();
274            }
275            if (InGame && !CanPlace(CurrPlayer)) {
276                CurrPlayer=NotPlayer(CurrPlayer);
277                need_redraw = 1;
278            }
279        }
280    }
281}
282
283//-------------------------------------------------------------------
284static void Timer() {
285    uchar PPP;
286 
287    if ((InGame) & (CurrPlayer==Computer || Computer==COMPUTER_ONLY)) {
288        if (CanPlace(CurrPlayer)) {
289            PPP=ComputerPlace(CurrPlayer);
290            //xPos = PPP >> 4; yPos = PPP & 0x0F;
291            NumPl1=GetNum(FIELD_PLAYER1);
292            NumPl2=GetNum(FIELD_PLAYER2);
293            need_redraw=1;
294        }
295        CurrPlayer=NotPlayer(CurrPlayer);
296        if (!CanPlace(FIELD_PLAYER1) && !CanPlace(FIELD_PLAYER2)) {
297            InGame=0;
298            Result();
299        }
300        if (InGame && !CanPlace(CurrPlayer)) {
301            CurrPlayer=NotPlayer(CurrPlayer);
302            need_redraw=1;
303        }
304    }
305}
306
307//-------------------------------------------------------------------
308static void redraw() {
309    uchar x, y;
310 
311    for (x=0; x<8; ++x) {
312        for (y=0; y<8; ++y) {
313            DrawCell(x, y);
314            switch (Field[x][y]) {
315                case FIELD_EMPTY:
316                    break;
317                case FIELD_PLAYER1:
318                    draw_filled_ellipse(field_x+cell_size*x+(cell_size>>1), field_y+cell_size*y+(cell_size>>1),
319                                        (cell_size>>1)-4, (cell_size>>1)-4, MAKE_COLOR(MARKER_COLOR_WHITE, MARKER_COLOR_WHITE));
320                    break;
321                case FIELD_PLAYER2:
322                    draw_filled_ellipse(field_x+cell_size*x+(cell_size>>1), field_y+cell_size*y+(cell_size>>1),
323                                        (cell_size>>1)-4, (cell_size>>1)-4, MAKE_COLOR(MARKER_COLOR_BLACK, MARKER_COLOR_BLACK));
324                    break;
325            }
326        }
327    }
328
329    draw_rect(field_x+cell_size*xPos, field_y+cell_size*yPos, field_x+cell_size*(xPos+1), field_y+cell_size*(yPos+1), COLOR_RED);
330}
331
332//-------------------------------------------------------------------
333static void redrawstatus() {
334    int x=camera_screen.ts_button_border+field_size+FONT_WIDTH*2+23, y = 25;
335    if (InGame) {
336        if (CurrPlayer==FIELD_PLAYER1) {
337            draw_string(x+1, y, lang_str(LANG_REVERSI_MOVE_WHITE), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
338        } else {
339            draw_string(x+1, y, lang_str(LANG_REVERSI_MOVE_BLACK), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
340        }
341    } else {
342        draw_string(x, y, lang_str(LANG_REVERSI_GAME_OVER), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
343    }
344    draw_string(x, y+FONT_HEIGHT+8, lang_str(LANG_REVERSI_WHITE_BLACK), MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
345    sprintf(buf, " %d ", NumPl1);
346    draw_string(x+FONT_WIDTH*(7-strlen(buf))/2, y+FONT_HEIGHT*2+8, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
347    sprintf(buf, " %d ", NumPl2);
348    draw_string(x+FONT_WIDTH*7+FONT_WIDTH*(7-strlen(buf))/2, y+FONT_HEIGHT*2+8, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
349    draw_rect(x-4, y-4, x+FONT_WIDTH*14+4, y+FONT_HEIGHT*3+8+4, COLOR_WHITE);
350    draw_rect(x-2, y-2, x+FONT_WIDTH*14+2, y+FONT_HEIGHT*3+8+2, COLOR_WHITE);
351    draw_line(x-2, y+FONT_HEIGHT+4, x+FONT_WIDTH*14+2, y+FONT_HEIGHT+4, COLOR_WHITE);
352    draw_line(x+FONT_WIDTH*7, y+FONT_HEIGHT+4, x+FONT_WIDTH*7, y+FONT_HEIGHT*3+8+2, COLOR_WHITE);
353}
354
355//-------------------------------------------------------------------
356int basic_module_init() {
357    gui_set_mode(&GUI_MODE_REVERSI);
358    InitMainWindow();
359    NewGame();
360    need_redraw_all = 1;
361        return 1;
362}
363
364//-------------------------------------------------------------------
365void gui_reversi_kbd_process() {
366    switch (kbd_get_autoclicked_key()) {
367        case KEY_UP:
368            yPos =(yPos-1)&7;
369            need_redraw = 1;
370            break;
371        case KEY_DOWN:
372            yPos =(yPos+1)&7;
373            need_redraw = 1;
374            break;
375        case KEY_LEFT:
376            xPos =(xPos-1)&7;
377            need_redraw = 1;
378            break;
379        case KEY_RIGHT:
380            xPos =(xPos+1)&7;
381            need_redraw = 1;
382            break;
383        case KEY_SET:
384            if (InGame)
385                Clk(xPos, yPos);
386            else
387                NewGame();
388            need_redraw = 1;
389            break;
390        case KEY_ERASE:
391        case KEY_DISPLAY:
392            if (InGame)
393                Computer=COMPUTER_ONLY;
394            else
395                NewGame();
396            need_redraw = 1;
397            break;
398    }
399}
400
401//-------------------------------------------------------------------
402void gui_reversi_draw(int enforce_redraw) {
403    if (need_redraw_all) {
404        need_redraw_all = 0;
405        DrawMainWindow();
406        need_redraw = 1;
407    }
408    if (need_redraw) {
409        need_redraw = 0;
410        redraw();
411        redrawstatus();
412    }
413
414    sprintf(buf, "Batt:%3d%%", get_batt_perc());
415    draw_txt_string((camera_screen.width-camera_screen.ts_button_border)/FONT_WIDTH-2-9, camera_screen.height/FONT_HEIGHT-1, buf, MAKE_COLOR(SCREEN_COLOR, COLOR_WHITE));
416
417    Timer();
418}
419
420
421extern int module_idx;
422void gui_module_menu_kbd_process() {
423        gui_default_kbd_process_menu_btn();
424        module_async_unload(module_idx);
425}
426
427
428/******************** Module Information structure ******************/
429
430struct ModuleInfo _module_info = {      MODULEINFO_V1_MAGICNUM,
431                                                                        sizeof(struct ModuleInfo),
432
433                                                                        ANY_CHDK_BRANCH, 0,                     // Requirements of CHDK version
434                                                                        ANY_PLATFORM_ALLOWED,           // Specify platform dependency
435                                                                        0,                                                      // flag
436                                                                        -LANG_MENU_GAMES_REVERSI,       // Module name
437                                                                        1, 0,                                           // Module version
438                                                                        (int32_t)"Game"
439                                                                 };
Note: See TracBrowser for help on using the repository browser.