CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
gui_sokoban.c-Dateireferenz
#include "camera_info.h"
#include "keyboard.h"
#include "modes.h"
#include "lang.h"
#include "conf.h"
#include "gui.h"
#include "gui_draw.h"
#include "gui_lang.h"
#include "gui_batt.h"
#include "gui_mbox.h"
#include "module_def.h"
#include "simple_module.h"
+ Include-Abhängigkeitsdiagramm für gui_sokoban.c:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  SokobanConf
 

Makrodefinitionen

#define FIELD_WIDTH   15
 
#define FIELD_HEIGHT   15
 
#define WALL_COLOR_1   COLOR_GREY
 
#define WALL_COLOR_2   COLOR_BLACK
 
#define BOX_COLOR_1   COLOR_RED
 
#define BOX_COLOR_2   COLOR_BLACK
 
#define BOX_COLOR_3   COLOR_YELLOW
 
#define PLACE_COLOR_1   COLOR_BLUE
 
#define PLACE_COLOR_2   COLOR_BLACK
 
#define PLAYER_COLOR_1   COLOR_GREEN
 
#define PLAYER_COLOR_2   COLOR_BLACK
 
#define MARKER_WALL   '#'
 
#define MARKER_BOX   '$'
 
#define MARKER_PLACE   '.'
 
#define MARKER_BOX_PLACE   '*'
 
#define MARKER_PLAYER   '@'
 
#define MARKER_PLAYER_PLACE   '+'
 
#define MARKER_EMPTY   '_'
 
#define MARKER_LINE_END   '\n'
 
#define MARKER_LEVEL_END   '!'
 
#define LEVEL_CHARS   "#$.*@+_"
 
#define UNDO_SIZE   1000
 
#define MAX_LEVELS   200
 

Funktionen

void gui_module_menu_kbd_process ()
 
int gui_sokoban_kbd_process ()
 
void gui_sokoban_draw ()
 
static void sokoban_undo_add (int dx, int dy, int box)
 
static void sokoban_undo ()
 
static void sokoban_redo ()
 
static void sokoban_undo_reset ()
 
static void sokoban_set_level (int lvl)
 
static int sokoban_finished ()
 
static void sokoban_next_level ()
 
static int sokoban_move (int dx, int dy)
 
static void sokoban_draw_box (int x, int y, twoColors cl)
 
int gui_sokoban_init ()
 
int _run ()
 
int _module_loader (__attribute__((unused)) unsigned int *chdk_export_list)
 
int _module_unloader ()
 
int _module_can_unload ()
 
int _module_exit_alt ()
 

Variablen

SokobanConf sconf
 
static ConfInfo conf_info []
 
gui_handler GUI_MODE_SOKOBAN
 
static const char * level_file_name ="A/CHDK/GAMES/SOKOBAN.LEV"
 
static unsigned short level_start_list [MAX_LEVELS]
 
static unsigned char level_length_list [MAX_LEVELS]
 
static int num_levels
 
static int need_redraw
 
static int need_redraw_all
 
static int moves
 
static char field [FIELD_HEIGHT][FIELD_WIDTH]
 
static int cell_size
 
static int xPl
 
static int yPl
 
static int undo [UNDO_SIZE/10]
 
static int undo_begin
 
static int undo_end
 
static int undo_curr
 
static int running = 0
 
libsimple_sym _librun
 
ModuleInfo _module_info
 

Makro-Dokumentation

#define BOX_COLOR_1   COLOR_RED

Definiert in Zeile 42 der Datei gui_sokoban.c.

#define BOX_COLOR_2   COLOR_BLACK

Definiert in Zeile 43 der Datei gui_sokoban.c.

#define BOX_COLOR_3   COLOR_YELLOW

Definiert in Zeile 44 der Datei gui_sokoban.c.

#define FIELD_HEIGHT   15

Definiert in Zeile 38 der Datei gui_sokoban.c.

#define FIELD_WIDTH   15

Definiert in Zeile 37 der Datei gui_sokoban.c.

#define LEVEL_CHARS   "#$.*@+_"

Definiert in Zeile 60 der Datei gui_sokoban.c.

#define MARKER_BOX   '$'

Definiert in Zeile 51 der Datei gui_sokoban.c.

#define MARKER_BOX_PLACE   '*'

Definiert in Zeile 53 der Datei gui_sokoban.c.

#define MARKER_EMPTY   '_'

Definiert in Zeile 56 der Datei gui_sokoban.c.

#define MARKER_LEVEL_END   '!'

Definiert in Zeile 58 der Datei gui_sokoban.c.

#define MARKER_LINE_END   '\n'

Definiert in Zeile 57 der Datei gui_sokoban.c.

#define MARKER_PLACE   '.'

Definiert in Zeile 52 der Datei gui_sokoban.c.

#define MARKER_PLAYER   '@'

Definiert in Zeile 54 der Datei gui_sokoban.c.

#define MARKER_PLAYER_PLACE   '+'

Definiert in Zeile 55 der Datei gui_sokoban.c.

#define MARKER_WALL   '#'

Definiert in Zeile 50 der Datei gui_sokoban.c.

#define MAX_LEVELS   200

Definiert in Zeile 66 der Datei gui_sokoban.c.

#define PLACE_COLOR_1   COLOR_BLUE

Definiert in Zeile 45 der Datei gui_sokoban.c.

#define PLACE_COLOR_2   COLOR_BLACK

Definiert in Zeile 46 der Datei gui_sokoban.c.

#define PLAYER_COLOR_1   COLOR_GREEN

Definiert in Zeile 47 der Datei gui_sokoban.c.

#define PLAYER_COLOR_2   COLOR_BLACK

Definiert in Zeile 48 der Datei gui_sokoban.c.

#define UNDO_SIZE   1000

Definiert in Zeile 62 der Datei gui_sokoban.c.

#define WALL_COLOR_1   COLOR_GREY

Definiert in Zeile 40 der Datei gui_sokoban.c.

#define WALL_COLOR_2   COLOR_BLACK

Definiert in Zeile 41 der Datei gui_sokoban.c.

Dokumentation der Funktionen

int _module_can_unload ( )

Definiert in Zeile 511 der Datei gui_sokoban.c.

512 {
513  return running == 0;
514 }
int _module_exit_alt ( )

Definiert in Zeile 516 der Datei gui_sokoban.c.

517 {
518  running = 0;
519  return 0;
520 }
int _module_loader ( __attribute__((unused)) unsigned int *  chdk_export_list)

Definiert in Zeile 494 der Datei gui_sokoban.c.

495 {
496  sconf.sokoban_level = 0;
497  config_restore(&conf_info[0], "A/CHDK/MODULES/CFG/sokoban.cfg", 0);
498  return 0;
499 }
int _module_unloader ( )

Definiert in Zeile 505 der Datei gui_sokoban.c.

506 {
507  config_save(&conf_info[0], "A/CHDK/MODULES/CFG/sokoban.cfg", 99000);
508  return 0;
509 }
int _run ( )

Definiert in Zeile 475 der Datei gui_sokoban.c.

476 {
478  {
480  }
481  else
482  {
483  running = 1;
485  }
486 
487  return 0;
488 }
void gui_module_menu_kbd_process ( )

Definiert in Zeile 463 der Datei gui_sokoban.c.

464 {
465  running = 0;
467 }
void gui_sokoban_draw ( )

Definiert in Zeile 400 der Datei gui_sokoban.c.

400  {
401  int y, x;
402  static char str[16];
403 
404  if (need_redraw_all) {
406  need_redraw_all = 0;
407  need_redraw = 1;
408  }
409 
410  if (need_redraw) {
411  need_redraw = 0;
412  for (y=0; y<FIELD_HEIGHT; ++y) {
413  for (x=0; x<FIELD_WIDTH; ++x) {
414  switch (field[y][x]) {
415  case MARKER_WALL:
416  draw_rectangle(camera_screen.disp_left+x*cell_size, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1, y*cell_size+cell_size-1, MAKE_COLOR(WALL_COLOR_1, WALL_COLOR_2), RECT_BORDER1|DRAW_FILLED);
417  break;
418  case MARKER_BOX:
420  break;
421  case MARKER_PLACE:
422  draw_rectangle(camera_screen.disp_left+x*cell_size, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1, y*cell_size+cell_size-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
423  draw_rectangle(camera_screen.disp_left+x*cell_size+4, y*cell_size+4, camera_screen.disp_left+x*cell_size+cell_size-1-4, y*cell_size+cell_size-1-4, MAKE_COLOR(PLACE_COLOR_1, PLACE_COLOR_2), RECT_BORDER1|DRAW_FILLED);
424  break;
425  case MARKER_BOX_PLACE:
427  break;
428  case MARKER_PLAYER:
429  case MARKER_PLAYER_PLACE:
430  draw_rectangle(camera_screen.disp_left+x*cell_size, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1, y*cell_size+cell_size-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
431  draw_ellipse(camera_screen.disp_left+x*cell_size+(cell_size>>1)-1, y*cell_size+(cell_size>>1)-1, (cell_size>>1)-3, (cell_size>>1)-3, PLAYER_COLOR_1, DRAW_FILLED);
432  break;
433  case MARKER_EMPTY:
434  default:
435  draw_rectangle(camera_screen.disp_left+x*cell_size, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1, y*cell_size+cell_size-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
436  break;
437  }
438  }
439  }
440 
441  draw_line(camera_screen.disp_left+cell_size*FIELD_WIDTH, 0, camera_screen.disp_left+cell_size*FIELD_WIDTH, camera_screen.height-1, COLOR_WHITE);
442  draw_line(camera_screen.disp_left+cell_size*FIELD_WIDTH+1, 0, camera_screen.disp_left+cell_size*FIELD_WIDTH+1, camera_screen.height-1, COLOR_BLACK);
443 
445  draw_string(camera_screen.disp_left+cell_size*FIELD_WIDTH+2, 8, str, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE));
446  sprintf(str, "%s: %-6d", lang_str(LANG_SOKOBAN_TEXT_MOVES), moves);
448 
449  if (sokoban_finished()) {
452  }
453  }
454 
455  sprintf(str, "Batt:%3d%%", get_batt_perc());
458 }
int gui_sokoban_init ( )

Definiert in Zeile 282 der Datei gui_sokoban.c.

282  {
283  /* first time through, load the file and make an index
284  if would could tell when the user left sokoban,
285  we could avoid this and malloc all the data structures
286  unfortunately, gui_mode gets set all over the place */
287  if(!num_levels) {
288  char *buf,*p;
289  FILE *fd;
290  struct stat st;
291 
292  if (stat((char *)level_file_name,&st) != 0 || st.st_size==0)
293  return 0;
294 
295  fd=fopen(level_file_name,"rb");
296  if(!fd)
297  return 0;
298 
299  buf=malloc(st.st_size+1);
300  if(!buf) {
301  fclose(fd);
302  return 0;
303  }
304 
305  fread(buf,1,st.st_size,fd);
306  buf[st.st_size]=0;
307  fclose(fd);
308  p = buf;
309  do {
310  // skip to the first level char
311  p = strpbrk(p,LEVEL_CHARS);
312  // found a level char, store the start
313  if (p) {
314  unsigned pos = p - buf;
315  if ( pos > 65535 ) {
316  break;
317  }
318  level_start_list[num_levels] = (unsigned short)pos;
320  // found the end char, store the end
321  if(p) {
322  unsigned len = p - (buf + level_start_list[num_levels]);
323  // bail on invalid level
324  if ( len > 255 ) {
325  break;
326  }
327  level_length_list[num_levels] = (unsigned char)len;
328  ++num_levels;
329  }
330  }
331  } while(p && num_levels < MAX_LEVELS);
332  free(buf);
333  }
334  if(!num_levels) {
335  return 0;
336  }
337  else if(sconf.sokoban_level >= num_levels) {
338  sconf.sokoban_level = 0;
339  }
341  // worst case scenario (640x480)
343  }
344  else {
346  }
348  // if the file is no longer readable, set_level will set this
349  if(!num_levels) {
350  return 0;
351  }
352  need_redraw_all = 1;
353 
355  return 1;
356 }
int gui_sokoban_kbd_process ( )

Definiert in Zeile 359 der Datei gui_sokoban.c.

359  {
360  switch (kbd_get_autoclicked_key()) {
361  case KEY_UP:
362  moves+=sokoban_move(0, -1);
363  need_redraw = 1;
364  break;
365  case KEY_DOWN:
366  moves+=sokoban_move(0, +1);
367  need_redraw = 1;
368  break;
369  case KEY_LEFT:
370  moves+=sokoban_move(-1, 0);
371  need_redraw = 1;
372  break;
373  case KEY_RIGHT:
374  moves+=sokoban_move(+1, 0);
375  need_redraw = 1;
376  break;
377  case KEY_SET:
378  if (moves == 0) {
380  }
381  break;
382  case KEY_ZOOM_OUT:
383  sokoban_undo();
384  need_redraw = 1;
385  break;
386  case KEY_ZOOM_IN:
387  sokoban_redo();
388  need_redraw = 1;
389  break;
390  case KEY_ERASE:
391  case KEY_DISPLAY:
393  need_redraw_all = 1;
394  break;
395  }
396  return 0;
397 }
static void sokoban_draw_box ( int  x,
int  y,
twoColors  cl 
)
static

Definiert in Zeile 273 der Datei gui_sokoban.c.

273  {
274  draw_rectangle(camera_screen.disp_left+x*cell_size, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1, y*cell_size+cell_size-1, cl, RECT_BORDER1|DRAW_FILLED);
275  draw_line(camera_screen.disp_left+x*cell_size+2, y*cell_size, camera_screen.disp_left+x*cell_size+2, y*cell_size+cell_size-1, FG_COLOR(cl));
276  draw_line(camera_screen.disp_left+x*cell_size+cell_size-1-2, y*cell_size, camera_screen.disp_left+x*cell_size+cell_size-1-2, y*cell_size+cell_size-1, FG_COLOR(cl));
277  draw_line(camera_screen.disp_left+x*cell_size+2, y*cell_size+2, camera_screen.disp_left+x*cell_size+cell_size-1-2, y*cell_size+2, FG_COLOR(cl));
278  draw_line(camera_screen.disp_left+x*cell_size+2, y*cell_size+cell_size-1-2, camera_screen.disp_left+x*cell_size+cell_size-1-2, y*cell_size+cell_size-1-2, FG_COLOR(cl));
279 }
static int sokoban_finished ( )
static

Definiert in Zeile 227 der Datei gui_sokoban.c.

227  {
228  int x, y;
229 
230  for (y=0; y<FIELD_HEIGHT; ++y)
231  for (x=0; x<FIELD_WIDTH; ++x)
232  if (field[y][x]==MARKER_BOX)
233  return 0;
234  return 1;
235 }
static int sokoban_move ( int  dx,
int  dy 
)
static

Definiert in Zeile 245 der Datei gui_sokoban.c.

245  {
246  switch (field[yPl+dy][xPl+dx]) {
247  case MARKER_WALL:
248  return 0;
249  break;
250  case MARKER_BOX:
251  case MARKER_BOX_PLACE:
252  if (field[yPl+dy*2][xPl+dx*2]==MARKER_WALL || field[yPl+dy*2][xPl+dx*2]==MARKER_BOX || field[yPl+dy*2][xPl+dx*2]==MARKER_BOX_PLACE)
253  return 0;
254  break;
255  case MARKER_PLACE:
256  case MARKER_EMPTY:
257  break;
258  }
260  xPl+=dx; yPl+=dy;
264  sokoban_undo_add(dx, dy, 1);
265  } else {
266  sokoban_undo_add(dx, dy, 0);
267  }
269  return 1;
270 }
static void sokoban_next_level ( )
static

Definiert in Zeile 238 der Datei gui_sokoban.c.

238  {
241  need_redraw_all = 1;
242 }
static void sokoban_redo ( )
static

Definiert in Zeile 129 der Datei gui_sokoban.c.

129  {
130  int dx=0, dy=0, value;
131 
132  if (undo_curr!=undo_end) {
133  value = (undo[undo_curr/10]>>((undo_curr%10)*3))&7;
134  if (value&1) dy=1; else dx=1;
135  if (value&2) {dy=-dy; dx=-dx;}
136 
138  xPl+=dx; yPl+=dy;
139  if (value&4) {
142  }
144  ++moves;
145 
146  ++undo_curr;
147  if (undo_curr==UNDO_SIZE) undo_curr=0;
148  }
149 }
static void sokoban_set_level ( int  lvl)
static

Definiert in Zeile 157 der Datei gui_sokoban.c.

157  {
158  int x=0, y, w=0, h=0;
159  const char *p;
160  char *buf;
161  FILE *fd;
162  int start,len;
163 
164  len=level_length_list[lvl];
165  start=level_start_list[lvl];
166  fd=fopen(level_file_name,"rb");
167  if(!fd) {
168  num_levels=0;
169  return;
170  }
171 
172  buf=malloc(len+1);
173  if(!buf) {
174  fclose(fd);
175  return;
176  }
177 
178  if(fseek(fd,start,SEEK_SET) != 0) {
179  fclose(fd);
180  free(buf);
181  return;
182  }
183  fread(buf,1,len,fd);
184  buf[len]=0;
185  fclose(fd);
186 
187  p=buf;
188 
189  // determine dimensions
190  while (*p) {
191  if (*p==MARKER_LINE_END) {
192  ++h;
193  if (x>w) w=x;
194  x=0;
195  } else {
196  ++x;
197  }
198  ++p;
199  }
200  if (x>w) w=x;
201  h-=1; //the last line didn't previously have an end marker
202 
203  // clear field
204  for (y=0; y<FIELD_HEIGHT; ++y)
205  for (x=0; x<FIELD_WIDTH; ++x)
206  field[y][x]=MARKER_EMPTY;
207 
208  // place maze at the center
209  p=buf;
210  for (y=(FIELD_HEIGHT-h)/2; y<FIELD_HEIGHT; ++y, ++p) {
211  for (x=(FIELD_WIDTH-w)/2; x<FIELD_WIDTH && *p && *p!=MARKER_LINE_END; ++x, ++p) {
212  field[y][x]=*p;
213  if (field[y][x] == MARKER_PLAYER || field[y][x] == MARKER_PLAYER_PLACE) {
214  xPl = x; yPl = y;
215  }
216  }
217  if (!*p || (*p == MARKER_LINE_END && !*(p+1))) break;
218  }
219 
220  free(buf);
221  sconf.sokoban_level = lvl;
222  moves = 0;
224 }
static void sokoban_undo ( )
static

Definiert in Zeile 106 der Datei gui_sokoban.c.

106  {
107  int dx=0, dy=0, value;
108 
109  if (undo_curr!=undo_begin) {
110  if (undo_curr==0) undo_curr=UNDO_SIZE;
111  --undo_curr;
112 
113  value = (undo[undo_curr/10]>>((undo_curr%10)*3))&7;
114  if (value&1) dy=1; else dx=1;
115  if (value&2) {dy=-dy; dx=-dx;}
116 
118  if (value&4) {
121  }
122  xPl-=dx; yPl-=dy;
124  --moves;
125  }
126 }
static void sokoban_undo_add ( int  dx,
int  dy,
int  box 
)
static

Definiert in Zeile 83 der Datei gui_sokoban.c.

83  {
84  int offs, bits, value;
85 
86  value = ((box)?1:0)<<2;
87  if (dx) {
88  value |= ((dx<0)?1:0)<<1;
89  } else {
90  value |= (((dy<0)?1:0)<<1)|1;
91  }
92 
93  offs = undo_curr/10;
94  bits = (undo_curr%10)*3;
95  undo[offs] &= ~(7<<bits);
96  undo[offs] |= (value&7)<<bits;
97 
98  if (++undo_curr==UNDO_SIZE) undo_curr=0;
99  if (undo_curr==undo_begin) {
100  if (++undo_begin==UNDO_SIZE) undo_begin=0;
101  }
103 }
static void sokoban_undo_reset ( )
static

Definiert in Zeile 152 der Datei gui_sokoban.c.

152  {
154 }

Variablen-Dokumentation

libsimple_sym _librun
Initialisierung:

Definiert in Zeile 524 der Datei gui_sokoban.c.

int cell_size
static

Definiert in Zeile 76 der Datei gui_sokoban.c.

ConfInfo conf_info[]
static
Initialisierung:

Definiert in Zeile 24 der Datei gui_sokoban.c.

char field[FIELD_HEIGHT][FIELD_WIDTH]
static

Definiert in Zeile 74 der Datei gui_sokoban.c.

const char* level_file_name ="A/CHDK/GAMES/SOKOBAN.LEV"
static

Definiert in Zeile 65 der Datei gui_sokoban.c.

unsigned char level_length_list[MAX_LEVELS]
static

Definiert in Zeile 68 der Datei gui_sokoban.c.

unsigned short level_start_list[MAX_LEVELS]
static

Definiert in Zeile 67 der Datei gui_sokoban.c.

int moves
static

Definiert in Zeile 73 der Datei gui_sokoban.c.

int need_redraw
static

Definiert in Zeile 71 der Datei gui_sokoban.c.

int need_redraw_all
static

Definiert in Zeile 72 der Datei gui_sokoban.c.

int num_levels
static

Definiert in Zeile 69 der Datei gui_sokoban.c.

int running = 0
static

Definiert in Zeile 461 der Datei gui_sokoban.c.

SokobanConf sconf

Definiert in Zeile 22 der Datei gui_sokoban.c.

int undo[UNDO_SIZE/10]
static

Definiert in Zeile 79 der Datei gui_sokoban.c.

int undo_begin
static

Definiert in Zeile 80 der Datei gui_sokoban.c.

int undo_curr
static

Definiert in Zeile 80 der Datei gui_sokoban.c.

int undo_end
static

Definiert in Zeile 80 der Datei gui_sokoban.c.

int xPl
static

Definiert in Zeile 77 der Datei gui_sokoban.c.

int yPl
static

Definiert in Zeile 77 der Datei gui_sokoban.c.