Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

dll/debug.c

Go to the documentation of this file.
00001 /* {{{
00002  * CalcRogue, a roguelike game for PCs, calculators and PDAs
00003  * Copyright (C) 2003 Jim Babcock
00004  * 
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * }}} */
00019 // debug.c
00022 
00023 #include "crogue.h"
00024 #include "dll.h"
00025 
00026 #define NUM_DEBUGOPTS 12
00027 
00028 #ifdef ALLOWDEBUG
00029 #ifdef DEBUG_HEAVILY
00030 static void do_diagnostic(void);
00031 #endif
00032 
00033 //{{{
00034 const char* debugmenuopts[NUM_DEBUGOPTS] = {
00035     gettext("Gain level"),
00036     gettext("Gain attributes"),
00037     gettext("Heal"),
00038     gettext("Invulnerability"),
00039     gettext("Drain satiation"),
00040     gettext("Show free mem"),
00041     gettext("Reveal map"),
00042     gettext("Run diagnostic"),
00043     gettext("Show facing"),
00044     gettext("Throw exception"),
00045     gettext("Give item"),
00046     gettext("Spell times")
00047 };
00048 //}}}
00049 //{{{
00050 void debugmenu_pick(int N, char *buf)
00051 {
00052     strcpy(buf, debugmenuopts[N]);
00053 }
00054 //}}}
00055 //{{{
00056 void debugmenu_item(int N, char *buf)
00057 {
00058     item itm = {N+1, 0, 1, 0, 0, 0, 0};
00059     strcpy(buf, itemname(&itm));
00060 }
00061 //}}}
00062 
00063 //{{{
00064 //
00065 // Debug menu: opens a list of debug (cheat) commands and handles the
00066 // selection
00067 //
00068 void debug(void)
00069 {
00070     int ii, jj;
00071     int choice;
00072     item itm = {0, 0, 1, 0, 0, 0, 0};
00073     
00074     if(!w->debug_mode)
00075     {
00076         if(!prompt(gettext("Warning: If you use debug features, you will not receive a score. Continue?")))
00077             return;
00078     }
00079     choice = UI_Menu_Pick(debug_rect, NUM_DEBUGOPTS, &debugmenu_pick, 0);
00080     
00081     if(choice>=0)
00082         w->debug_mode = 1;
00083     
00084     // Indeces correspond to debugmenuopts strings
00085     switch( choice )
00086     {
00087         case 0: // Gain level
00088             w->plr.level ++;
00089             w->plr.xp = 0;
00090             update_player();
00091             break;
00092         case 1: // Gain attributes
00093             for(ii=0; ii<5; ii++)
00094                 w->plr.intrinsic[ii] += 10;
00095             
00096             update_player();
00097             break;
00098         case 2: // Heal
00099             w->plr.hps = w->plr.hps_max;
00100             break;
00101         case 3: // Pseudo-invulnerability
00102             w->plr.hps_max_mod = 2000;
00103             update_player();
00104             w->plr.hps = w->plr.hps_max;
00105             break;
00106         case 4: // Remove satiation
00107             w->plr.satiation -= 200;
00108             break;
00109         case 5: // Show free memory
00110 #ifdef IS_CALCULATOR
00111             message(gettext("Free memory: %li"), HeapAvail());
00112 #else
00113             message(gettext("Free memory: Lots."));
00114 #endif
00115             break;
00116         case 6:
00117             for(jj=0; jj<MAPSIZE_Y; jj++)
00118             for(ii=0; ii<MAPSIZE_X; ii++) {
00119                 w->t[jj][ii].flags |= TFLAG_EXPLORED;
00120                 draw_tile(ii, jj);
00121             }
00122             break;
00123         
00124         case 7:
00125 #ifdef DEBUG_HEAVILY
00126             do_diagnostic();
00127 #endif
00128             break;
00129         case 8:
00130             message(gettext("Facing: %i, forced: %i"), w->plr.facing, w->plr.facing_forced);
00131             break;
00132         
00133         case 9:
00134 #ifdef IS_CALCULATOR
00135             if(prompt(gettext("This will end your game. Are you sure?")))
00136                 ER_throw(ER_MEMORY);
00137 #else
00138             message(gettext("Exceptions are only used on TI calculators."));
00139 #endif
00140             break;
00141         case 10:
00142             // Identify all types
00143             for(ii=0; ii<w->desc.itementries; ii++) {
00144                 identify_type(ii);
00145             }
00146             itm.type = UI_Menu_Pick(debug_item_rect, w->desc.itementries - 1, debugmenu_item, 0) + 1;
00147             itm.stacksize = ITEMDESC(itm).stacksize;
00148             give_item(&itm, 1);
00149             break;
00150         case 11:
00151             message(gettext("Current time is %li."), (long)w->time);
00152             for(ii=0; ii<w->desc.numspells; ii++)
00153                 message("%li,", (long)w->plr.spellknowledge[ii]);
00154     }
00155     
00156     full_redraw();
00157 }
00158 //}}}
00159 
00160 #ifdef DEBUG_HEAVILY
00161 static draw_string_info output_state = {0, 0};
00162 
00163 //{{{
00164 void diagnostic_print(const char *text)
00165 {
00166     draw_string(text, &output_state, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
00167 }
00168 //}}}
00169 //{{{
00170 void do_diagnostic(void)
00171 {
00172     int xi, yi, ii, pos, total_items=0;
00173     int pass, failed=0;
00174     int monstcount = 0;
00175     output_state.curX = output_state.curRow = 0;
00176     
00177     clrscr();
00178     
00179 #ifndef REALCOMPUTER
00180     diagnostic_print(gettext("Checking memory... "));
00181     if(HeapAvail() < 4096) {
00182         diagnostic_print(retprintf(gettext("Only %li bytes of RAM left! "), HeapAvail()));
00183         failed++;
00184     }
00185 #endif
00186     
00187     diagnostic_print(gettext("\nChecking world/monster consistency... "));
00188     for(yi=0; yi<MAPSIZE_Y; yi++)
00189     for(xi=0; xi<MAPSIZE_X; xi++)
00190     {
00191         if(w->t[yi][xi].flags & TFLAG_OCCUPIED)
00192         {
00193             pass = 0;
00194             for(ii=0; ii<MONSTERS_MAX; ii++)
00195             {
00196                 if(isNull(w->m[ii].type))
00197                     continue;
00198                 if(w->m[ii].x == xi && w->m[ii].y == yi)
00199                 {
00200                     monstcount++;
00201                     pass++;
00202                 }
00203             }
00204             if(w->plr.x==xi && w->plr.y==yi)
00205                 pass++;
00206             if(pass==0)
00207             {
00208                 diagnostic_print(retprintf(gettext("Found mis-marked monster at (%i, %i)! "), xi, yi));
00209                 failed++;
00210             }
00211             else if(pass>1)
00212             {
00213                 diagnostic_print(retprintf(gettext("Found overlapping %i monsters at (%i, %i): "), pass, xi, yi));
00214                 failed++;
00215                 for(ii=0; ii<MONSTERS_MAX; ii++)
00216                 {
00217                     if(isNull(w->m[ii].type))
00218                         continue;
00219                     if(w->m[ii].x == xi && w->m[ii].y == yi)
00220                         diagnostic_print(retprintf("%i, ", ii));
00221                 }
00222             }
00223         }
00224     }
00225     
00226     for(ii=0; ii<MONSTERS_MAX; ii++)
00227     {
00228         if(isNull(w->m[ii].type))
00229             continue;
00230         if(w->m[ii].x<0 || w->m[ii].y<0 || w->m[ii].x>=MAPSIZE_X || w->m[ii].y>=MAPSIZE_Y)
00231         {
00232             diagnostic_print(retprintf(gettext("Found out of bounds monster at (%i, %i)! ", w->m[ii].x, w->m[ii].y));
00233             failed++;
00234             continue;
00235         }
00236         if(!(w->t[w->m[ii].y][w->m[ii].x].flags & TFLAG_OCCUPIED))
00237         {
00238             diagnostic_print(retprintf(gettext("Found monster on unmarked tile at (%i, %i)! "), w->m[ii].x, w->m[ii].y));
00239             failed++;
00240             continue;
00241         }
00242     }
00243     
00244     diagnostic_print(gettext("\nChecking item chains... "));
00245     for(yi=0; yi<MAPSIZE_Y; yi++)
00246     for(xi=0; xi<MAPSIZE_X; xi++)
00247     {
00248         if(w->t[yi][xi].flags & TFLAG_ITEM)
00249         {
00250             pos = top_item(xi, yi);
00251             
00252             if(w->items.items[pos].type > w->desc.itementries)
00253             {
00254                 diagnostic_print(retprintf(gettext("Invalid item at (%i, %i) has type %i! "), xi, yi, w->items.items[pos].type) );
00255                 failed++;
00256             }
00257             
00258             while(pos != 0) {
00259                 pos = w->items.items[pos].next;
00260                 total_items++;
00261             }
00262         }
00263     }
00264     
00265     if(total_items != w->items.num)
00266     {
00267         diagnostic_print(retprintf(gettext("Total number of items found does not match: expected %i, found %i. "), w->items.num, total_items));
00268         failed++;
00269     }
00270     diagnostic_print(retprintf(gettext("\n%i items stored, %i allocated. "), w->items.num, w->items.alloced));
00271     diagnostic_print(retprintf(gettext("\n%i monsters."), monstcount));
00272     
00273     diagnostic_print(retprintf(gettext("\n\nSummary: %i tests failed"),failed));
00274     read_char();
00275 }
00276 //}}}
00277 #endif
00278 
00279 #else
00280 
00281 // Stub for debug() (since it's part of the exported interface, it can't be
00282 // left out entirely)
00283 void debug() {}
00284 
00285 #endif
00286 

Generated on Thu May 20 13:12:09 2004 for CalcRogue by doxygen 1.3.6