diff --git a/sc2/ChangeLog b/sc2/ChangeLog index bf58be148..1cc4933cf 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.4: +- Added lots of debugging functions, SvdB - Cleaned up use of the DEBUG define, SvdB - Talking Pet .txt file corrected to match the .ogg files, and talkpet.ts corrections, from Nic diff --git a/sc2/build.vars.in b/sc2/build.vars.in index 9052a6239..bb2bb1c63 100644 --- a/sc2/build.vars.in +++ b/sc2/build.vars.in @@ -20,7 +20,6 @@ MKDEPEND='gcc -MM' MAKE='@MAKE@' uqm_CFLAGS='@CFLAGS@' uqm_LDFLAGS='@LDFLAGS@' -DEBUG='@DEBUG@' uqm_INSTALL_BINDIR='@INSTALL_BINDIR@' uqm_INSTALL_LIBDIR='@INSTALL_LIBDIR@' uqm_INSTALL_SHAREDIR='@INSTALL_SHAREDIR@' @@ -33,5 +32,6 @@ uqm_USE_ZIP_IO='@USE_ZIP_IO@' WINDRES='@WINDRES@' REZ='@REZ@' SETFILE='@SETFILE@' -export uqm_SOUNDMODULE uqm_HAVE_OPENGL uqm_USE_ZIP_IO WINDRES +DEBUG='@DEBUG@' +export uqm_SOUNDMODULE uqm_HAVE_OPENGL uqm_USE_ZIP_IO WINDRES DEBUG diff --git a/sc2/doc/devel/debug b/sc2/doc/devel/debug new file mode 100644 index 000000000..445287f1c --- /dev/null +++ b/sc2/doc/devel/debug @@ -0,0 +1,47 @@ +The file src/sc2code/debug.c and src/sc2code/debug.h contain various +debugging functions, which are included in the binary when the game +is built in debug mode. +These functions can be called from anywhere in the code, though some +require the game to be in a specific state. +The function debugKeyPressed() in debug.c is called when the debug key +is pressed. This function is a suitable place to put various debugging +calls. +The debug key can be specified in keys.cfg by adding a line with a text +similar to "Debug: key F11". +An interactive way to access various debugging code, similar to +the uio debug mode (see below) is in the works. + +The most interesting debugging functionality available at the moment is +listed below: +- the function equipShip() + When this function is called, the SIS is equiped with various useful + modules (a possible Precursor Bomb is left in place), all + fuel tanks and crew pods are filled to the maximum, you are given + the maximum number of landers, and all possible lander shields are + installed. +- the boolean variable instantMove + When this variable is set to TRUE, you can select a location on the + star map, and your HyperSpace/Quasispace coordinates will immediately + be set to them. Your realspace coordinates are not changed, so if you + are exploring a solar system, you'll only notice it when you leave to + HyperSpace. +- the function forwardToNextEvent() + Fast forwards the clock until the next event. If TRUE is given as an + argument, the HYPERSPACE_ENCOUNTER_EVENTs, which normally happen every + day, are skipped. +- the function dumpEvents() + Outputs information on all scheduled events to a FILE. +- the function dumpStars() + Outputs information on all stars to a FILE. + With the 'flags' variable, the amount of detail can be specified. + At this time this function will only work when called from the top of + ExploreSolarSys(). +- uio_debugInteractive() + This function is not defined in sc2code/debug.h, but in libs/uio.h. + This function can interactively (tty-based) display information on + the state of the uio file system, and modifications can be made. + + +The first version of this document was created by Serge van den Boom, +on 2004-05-15. + diff --git a/sc2/doc/devel/files b/sc2/doc/devel/files index 8ea09edd7..ea4df38e0 100644 --- a/sc2/doc/devel/files +++ b/sc2/doc/devel/files @@ -9,8 +9,12 @@ commglue.c Helper functions for communication with aliens. confirm.c Asks for confirmation on exit. credits.c Shows the credits after a victory. cyborg.c Handles combat AI. +debug.c Debugging functions. demo.c Code for demo mode and game journal. -displist.c +displist.c Generic doubly linked list, which can keep its own pool + of preallocated link structures. + This generic list is used in various places throughout + the game source, but without preallocaded link structures. dummy.c encount.c Handles what to do when a player encounters an alien. fmv.c Handles video sequences. @@ -69,12 +73,11 @@ status.c Maintain and draw some information like the captain picture, crew, energy. (also shipstat.c) tactrans.c Code for some additional combat events (explosions, dying, new ship, ion trail, escape). -trans.c +trans.c Integer variant of atan2(). utils.c Various auxiliary utils, code for pausing. velocity.c Velocity computation routines. weapon.c Routines for weapons fire in combat. -test.c Sound testing program. (to be deleted?) build.h clock.h diff --git a/sc2/src/msvc++/UrQuanMasters.dsp b/sc2/src/msvc++/UrQuanMasters.dsp index b46750794..3faa7be34 100644 --- a/sc2/src/msvc++/UrQuanMasters.dsp +++ b/sc2/src/msvc++/UrQuanMasters.dsp @@ -3265,6 +3265,16 @@ SOURCE=..\sc2code\credits.h SOURCE=..\sc2code\cyborg.c # End Source File +!IF "$(CFG)" == "UrQuanMasters - Win32 Debug" +# Begin Source File + +SOURCE=..\sc2code\debug.c +# End Source File +# End Source File +!ENDIF +# Begin Source File + +SOURCE=..\sc2code\debug.h # Begin Source File SOURCE=..\sc2code\demo.c diff --git a/sc2/src/sc2code/Makeinfo b/sc2/src/sc2code/Makeinfo index 4a3d6d7d5..f0d355193 100644 --- a/sc2/src/sc2code/Makeinfo +++ b/sc2/src/sc2code/Makeinfo @@ -10,3 +10,7 @@ uqm_CFILES="battle.c border.c build.c cleanup.c clock.c collide.c comm.c starcon.c starmap.c state.c status.c tactrans.c trans.c util.c velocity.c weapon.c" +if [ -n "$DEBUG" ]; then + uqm_CFILES="$uqm_CFILES debug.c" +fi + diff --git a/sc2/src/sc2code/clock.h b/sc2/src/sc2code/clock.h index 0c3b4bf3f..e69ec07cb 100644 --- a/sc2/src/sc2code/clock.h +++ b/sc2/src/sc2code/clock.h @@ -85,16 +85,19 @@ typedef enum #define EVENTPTR PEVENT #define AllocEvent() AllocLink (&GLOBAL (GameClock.event_q)) -#define PutEvent(h) PutQueue (&GLOBAL (GameClock.event_q), h) -#define InsertEvent(h,i) InsertQueue (&GLOBAL (GameClock.event_q), h, i) +#define PutEvent(h) PutQueue (&GLOBAL (GameClock.event_q), (h)) +#define InsertEvent(h,i) InsertQueue (&GLOBAL (GameClock.event_q), (h), (i)) #define GetHeadEvent() GetHeadLink (&GLOBAL (GameClock.event_q)) #define GetTailEvent() GetTailLink (&GLOBAL (GameClock.event_q)) -#define LockEvent(h,eptr) *(eptr) = (EVENTPTR)LockLink (&GLOBAL (GameClock.event_q), h) -#define UnlockEvent(h) UnlockLink (&GLOBAL (GameClock.event_q), h) -#define RemoveEvent(h) RemoveQueue (&GLOBAL (GameClock.event_q), h) -#define FreeEvent(h) FreeLink (&GLOBAL (GameClock.event_q), h) +#define LockEvent(h,eptr) *(eptr) = (EVENTPTR)LockLink ( \ + &GLOBAL (GameClock.event_q), (h)) +#define UnlockEvent(h) UnlockLink (&GLOBAL (GameClock.event_q), (h)) +#define RemoveEvent(h) RemoveQueue (&GLOBAL (GameClock.event_q), (h)) +#define FreeEvent(h) FreeLink (&GLOBAL (GameClock.event_q), (h)) #define GetPredEvent(l) _GetPredLink (l) #define GetSuccEvent(l) _GetSuccLink (l) +#define ForAllEvents(callback, arg) ForAllLinks(&GLOBAL (GameClock.event_q), \ + (void (*)(LINKPTR, void *)) (callback), (arg)) /* rates are in seconds per game day */ #define HYPERSPACE_CLOCK_RATE 5 diff --git a/sc2/src/sc2code/debug.c b/sc2/src/sc2code/debug.c new file mode 100644 index 000000000..b4fe4b968 --- /dev/null +++ b/sc2/src/sc2code/debug.c @@ -0,0 +1,551 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include "starcon.h" +#include "debug.h" + +static void dumpEventCallback (EVENTPTR eventPtr, void *arg); +static void dumpStarCallback(STAR_DESC *star, void *arg); +static void dumpPlanetCallback (PLANET_DESC *planet, void *arg); + +BOOLEAN instantMove = FALSE; + +void +debugKeyPressed (void) +{ + // State modifying: + equipShip (); + instantMove = !instantMove; +// forwardToNextEvent (TRUE); + + // Informational: +// dumpEvents (stderr); +// dumpStars (stdout, DUMP_PLANETS); + // Currently dumpStars() does not work when called from here. + // It needs to be called from the top of ExploreSolarSys(). + + // Interactive: +// uio_debugInteractive(stdin, stdout, stderr); +} + +// Fast forwards to the next event. +// If skipHEE is set, HYPERSPACE_ENCOUNTER_EVENTs are skipped. +void +forwardToNextEvent (BOOLEAN skipHEE) +{ + HEVENT hEvent; + EVENTPTR EventPtr; + COUNT year, month, day; + // time of next event + BOOLEAN done; + + if (!GameClockRunning ()) + return; + + SuspendGameClock (); + + done = !skipHEE; + do { + hEvent = GetHeadEvent (); + if (hEvent == 0) + return; + LockEvent (hEvent, &EventPtr); + if (EventPtr->func_index != HYPERSPACE_ENCOUNTER_EVENT) + done = TRUE; + year = EventPtr->year_index; + month = EventPtr->month_index; + day = EventPtr->day_index; + UnlockEvent (hEvent); + + for (;;) { + if (GLOBAL (GameClock.year_index) > year || + (GLOBAL (GameClock.year_index) == year && + (GLOBAL (GameClock.month_index) > month || + (GLOBAL (GameClock.month_index) == month && + GLOBAL (GameClock.day_index) >= day)))) + break; + + while (ClockTick () > 0) + ; + + ResumeGameClock (); + SleepThread (ONE_SECOND / 60); + SuspendGameClock (); + } + } while (!done); + + ResumeGameClock (); +} + +const char * +eventName (BYTE func_index) +{ + switch (func_index) { + case ARILOU_ENTRANCE_EVENT: + return "ARILOU_ENTRANCE_EVENT"; + case ARILOU_EXIT_EVENT: + return "ARILOU_EXIT_EVENT"; + case HYPERSPACE_ENCOUNTER_EVENT: + return "HYPERSPACE_ENCOUNTER_EVENT"; + case KOHR_AH_VICTORIOUS_EVENT: + return "KOHR_AH_VICTORIOUS_EVENT"; + case ADVANCE_PKUNK_MISSION: + return "ADVANCE_PKUNK_MISSION"; + case ADVANCE_THRADD_MISSION: + return "ADVANCE_THRADD_MISSION"; + case ZOQFOT_DISTRESS_EVENT: + return "ZOQFOT_DISTRESS"; + case ZOQFOT_DEATH_EVENT: + return "ZOQFOT_DEATH_EVENT"; + case SHOFIXTI_RETURN_EVENT: + return "SHOFIXTI_RETURN_EVENT"; + case ADVANCE_UTWIG_SUPOX_MISSION: + return "ADVANCE_UTWIG_SUPOX_MISSION"; + case KOHR_AH_GENOCIDE_EVENT: + return "KOHR_AH_GENOCIDE_EVENT"; + case SPATHI_SHIELD_EVENT: + return "SPATHI_SHIELD_EVENT"; + case ADVANCE_ILWRATH_MISSION: + return "ADVANCE_ILWRATH_MISSION"; + case ADVANCE_MYCON_MISSION: + return "ADVANCE_MYCON_MISSION"; + case ARILOU_UMGAH_CHECK: + return "ARILOU_UMGAH_CHECK"; + case YEHAT_REBEL_EVENT: + return "YEHAT_REBEL_EVENT"; + case SLYLANDRO_RAMP_UP: + return "SLYLANDRO_RAMP_UP"; + case SLYLANDRO_RAMP_DOWN: + return "SLYLANDRO_RAMP_DOWN"; + default: + // Should not happen + return "???"; + } +} + +static void +dumpEventCallback (EVENTPTR eventPtr, void *arg) +{ + FILE *out = (FILE *) arg; + dumpEvent (out, eventPtr); +} + +void +dumpEvent (FILE *out, EVENTPTR eventPtr) +{ + fprintf (out, "%04u/%02u/%02u: %s\n", + eventPtr->year_index, + eventPtr->month_index, + eventPtr->day_index, + eventName (eventPtr->func_index)); +} + +void +dumpEvents (FILE *out) +{ + BOOLEAN restartClock = FALSE; + + if (GameClockRunning ()) { + SuspendGameClock (); + restartClock = TRUE; + } + ForAllEvents (dumpEventCallback, out); + if (restartClock) + ResumeGameClock (); +} + + +// NB: Ship maximum speed and turning rate aren't updated in +// HyperSpace/QuasiSpace or in melee. +void +equipShip (void) +{ + int i; + + // Don't do anything unless in the full game. + if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) + return; + + // Thrusters: + for (i = 0; i < NUM_DRIVE_SLOTS; i++) + GLOBAL_SIS (DriveSlots[i]) = FUSION_THRUSTER; + + // Turning jets: + for (i = 0; i < NUM_JET_SLOTS; i++) + GLOBAL_SIS (JetSlots[i]) = TURNING_JETS; + + // Shields: + SET_GAME_STATE (LANDER_SHIELDS, + (1 << EARTHQUAKE_DISASTER) | + (1 << BIOLOGICAL_DISASTER) | + (1 << LIGHTNING_DISASTER) | + (1 << LAVASPOT_DISASTER)); + + // Modules: + if (GET_GAME_STATE (CHMMR_BOMB_STATE) < 2) + { + // The Precursor bomb has not been installed. + // This is the original TFB testing layout. + i = 0; + GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; + GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = STORAGE_BAY; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + GLOBAL_SIS (ModuleSlots[i++]) = DYNAMO_UNIT; + GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; + GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; + GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; + + // Landers: + GLOBAL_SIS (NumLanders) = MAX_LANDERS; + } + else + { + // The Precursor bomb has been installed. + i = NUM_BOMB_MODULES; + GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; + GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; + GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; + } + + assert (i <= NUM_MODULE_SLOTS); + + // Fill the fuel and crew compartments to the maximum. + GLOBAL_SIS (FuelOnBoard) = 0; + GLOBAL_SIS (CrewEnlisted) = 0; + for (i = 0; i < NUM_MODULE_SLOTS; i++) + { + switch (GLOBAL_SIS (ModuleSlots[i])) { + case CREW_POD: + GLOBAL_SIS (CrewEnlisted) += CREW_POD_CAPACITY; + break; + case FUEL_TANK: + GLOBAL_SIS (FuelOnBoard) += FUEL_TANK_CAPACITY; + break; + case HIGHEFF_FUELSYS: + GLOBAL_SIS (FuelOnBoard) += HEFUEL_TANK_CAPACITY; + break; + } + } + + // Update the maximum speed and turning rate when in interplanetary. + if (pSolarSysState != NULL) + { + // Thrusters: + pSolarSysState->max_ship_speed = 5 * IP_SHIP_THRUST_INCREMENT; + for (i = 0; i < NUM_DRIVE_SLOTS; i++) + if (GLOBAL_SIS (DriveSlots[i] == FUSION_THRUSTER)) + pSolarSysState->max_ship_speed += IP_SHIP_THRUST_INCREMENT; + + // Turning jets: + pSolarSysState->turn_wait = IP_SHIP_TURN_WAIT; + for (i = 0; i < NUM_JET_SLOTS; i++) + if (GLOBAL_SIS (JetSlots[i]) == TURNING_JETS) + pSolarSysState->turn_wait -= IP_SHIP_TURN_DECREMENT; + } + + // Make sure everything is redrawn: + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE || + LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY) + { + LockMutex (GraphicsLock); + DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); + UnlockMutex (GraphicsLock); + } +} + +void +forAllStars(void (*callback) (STAR_DESC *, void *), void *arg) { + int i; + extern STAR_DESC starmap_array[]; + + for (i = 0; i < NUM_SOLAR_SYSTEMS; i++) + callback (&starmap_array[i], arg); +} + +typedef struct { + FILE *out; + UWORD flags; +} DumpStarsArg; + +void +dumpStars(FILE *out, UWORD flags) { + DumpStarsArg dumpStarsArg; + dumpStarsArg.out = out; + dumpStarsArg.flags = flags; + + forAllStars (dumpStarCallback, (void *) &dumpStarsArg); +} + +static void +dumpStarCallback(STAR_DESC *star, void *arg) { + DumpStarsArg *dumpStarsArg = (DumpStarsArg *) arg; + + dumpStar(dumpStarsArg->out, star, dumpStarsArg->flags); +} + +void +dumpStar(FILE *out, const STAR_DESC *star, UWORD flags) { + UNICODE name[40]; + UNICODE buf[40]; + + GetClusterName ((STAR_DESCPTR) star, name); + snprintf (buf, sizeof buf, "%s %s", + starColorString (STAR_COLOR(star->Type)), + starTypeString (STAR_TYPE(star->Type))); + fprintf (out, "%-22s (%3d.%1d, %3d.%1d) %-19s %s\n", + name, + star->star_pt.x / 10, star->star_pt.x % 10, + star->star_pt.y / 10, star->star_pt.y % 10, + buf, + starPresenceString (star->Index)); + if (flags & DUMP_PLANETS) + dumpPlanets (out, star, flags); +} + +const char * +starColorString (BYTE col) { + switch (col) { + case BLUE_BODY: + return "blue"; + case GREEN_BODY: + return "green"; + case ORANGE_BODY: + return "orange"; + case RED_BODY: + return "red"; + case WHITE_BODY: + return "white"; + case YELLOW_BODY: + return "yellow"; + default: + // Should not happen + return "???"; + } +} + +const char * +starTypeString (BYTE type) { + switch (type) { + case DWARF_STAR: + return "dwarf"; + case GIANT_STAR: + return "giant"; + case SUPER_GIANT_STAR: + return "super giant"; + default: + // Should not happen + return "???"; + } +} + +const char * +starPresenceString (BYTE index) { + switch (index) { + case 0: + // nothing + return ""; + case SOL_DEFINED: + return "Sol"; + case SHOFIXTI_DEFINED: + return "Shofixti male"; + case MAIDENS_DEFINED: + return "Shofixti maidens"; + case START_COLONY_DEFINED: + return "Starting colony"; + case SPATHI_DEFINED: + return "Spathi home"; + case ZOQFOT_DEFINED: + return "Zoq-Fot-Pik home"; + case MELNORME0_DEFINED: + return "Melnorme trader #0"; + case MELNORME1_DEFINED: + return "Melnorme trader #1"; + case MELNORME2_DEFINED: + return "Melnorme trader #2"; + case MELNORME3_DEFINED: + return "Melnorme trader #3"; + case MELNORME4_DEFINED: + return "Melnorme trader #4"; + case MELNORME5_DEFINED: + return "Melnorme trader #5"; + case MELNORME6_DEFINED: + return "Melnorme trader #6"; + case MELNORME7_DEFINED: + return "Melnorme trader #7"; + case MELNORME8_DEFINED: + return "Melnorme trader #8"; + case TALKING_PET_DEFINED: + return "Talking Pet"; + case CHMMR_DEFINED: + return "Chmmr home"; + case SYREEN_DEFINED: + return "Syreen home"; + case BURVIXESE_DEFINED: + return "Burvixese ruins"; + case SLYLANDRO_DEFINED: + return "Slylandro home"; + case DRUUGE_DEFINED: + return "Druuge home"; + case BOMB_DEFINED: + return "Precursor bomb"; + case AQUA_HELIX_DEFINED: + return "Aqua Helix"; + case SUN_DEVICE_DEFINED: + return "Sun Device"; + case TAALO_PROTECTOR_DEFINED: + return "Taalo Shield"; + case SHIP_VAULT_DEFINED: + return "Syreen ship vault"; + case URQUAN_WRECK_DEFINED: + return "Ur-Quan ship wreck"; + case VUX_BEAST_DEFINED: + return "Zex' beauty"; + case SAMATRA_DEFINED: + return "Sa-Matra"; + case ZOQ_SCOUT_DEFINED: + return "Zoq-Fot-Pik scout"; + case MYCON_DEFINED: + return "Mycon home"; + case EGG_CASE0_DEFINED: + return "Mycon egg shell #0"; + case EGG_CASE1_DEFINED: + return "Mycon egg shell #1"; + case EGG_CASE2_DEFINED: + return "Mycon egg shell #2"; + case PKUNK_DEFINED: + return "Pkunk home"; + case UTWIG_DEFINED: + return "Utwig home"; + case SUPOX_DEFINED: + return "Supox home"; + case YEHAT_DEFINED: + return "Yehat home"; + case VUX_DEFINED: + return "Vux home"; + case ORZ_DEFINED: + return "Orz home"; + case THRADD_DEFINED: + return "Thraddash home"; + case RAINBOW_DEFINED: + return "Rainbow world"; + case ILWRATH_DEFINED: + return "Ilwrath home"; + case ANDROSYNTH_DEFINED: + return "Androsynth ruins"; + case MYCON_TRAP_DEFINED: + return "Mycon trap"; + default: + // Should not happen + return "???"; + } +} + +// Currently, this function only works when called from the top of +// ExploreSolarSys(). The state afterwards is undefined. +void +forAllPlanets(STAR_DESC *star, + void (*callback) (PLANET_DESC *, void *), void *arg) +{ + // These two functions were originally static to solarsys.c + extern void InitSolarSys(void); + extern void UninitSolarSys(void); + + SOLARSYS_STATE solarSysState; + STAR_DESC *oldStarDescPtr; + COUNT i; + + oldStarDescPtr = CurStarDescPtr; + CurStarDescPtr = star; + + GLOBAL_SIS (log_x) = UNIVERSE_TO_LOGX (CurStarDescPtr->star_pt.x); + GLOBAL_SIS (log_y) = UNIVERSE_TO_LOGY (CurStarDescPtr->star_pt.y); + + memset (&solarSysState, 0, sizeof solarSysState); + solarSysState.GenFunc = GenerateIP (CurStarDescPtr->Index); + + pSolarSysState = &solarSysState; + + GLOBAL (CurrentActivity) = MAKE_WORD (IN_INTERPLANETARY, 0); + SuspendGameClock (); + InitSolarSys (); + + for (i = 0; i < pSolarSysState->SunDesc[0].NumPlanets; i++) + callback (&pSolarSysState->PlanetDesc[i], arg); + + GLOBAL (autopilot.x) = ~0; + GLOBAL (autopilot.y) = ~0; + GLOBAL (ShipStamp.frame) = 0; + GLOBAL (CurrentActivity) |= START_INTERPLANETARY; + UninitSolarSys (); + pSolarSysState = 0; + + CurStarDescPtr = oldStarDescPtr; +} + +typedef struct { + FILE *out; + UWORD flags; +} DumpPlanetsArg; + +void +dumpPlanets (FILE *out, const STAR_DESC *star, UWORD flags) { + DumpPlanetsArg dumpPlanetsArg; + dumpPlanetsArg.out = out; + dumpPlanetsArg.flags = flags; + + forAllPlanets ((STAR_DESC *) star, dumpPlanetCallback, + (void *) &dumpPlanetsArg); +} + +static void +dumpPlanetCallback (PLANET_DESC *planet, void *arg) +{ + DumpPlanetsArg *dumpPlanetsArg = (DumpPlanetsArg *) arg; + dumpPlanet (dumpPlanetsArg->out, planet, dumpPlanetsArg->flags); +} + +void +dumpPlanet(FILE *out, const PLANET_DESC *planet, UWORD flags) +{ + PLANET_DESC *oldPlanetDesc; + + oldPlanetDesc= pSolarSysState->pBaseDesc; + + // For now, only the name is printed. Other data may be added later. + pSolarSysState->pBaseDesc = (PLANET_DESC *) planet; + (*pSolarSysState->GenFunc) (GENERATE_NAME); + fprintf (out, "- %s\n", GLOBAL_SIS (PlanetName)); + + pSolarSysState->pBaseDesc = oldPlanetDesc; + + (void) flags; +} + + diff --git a/sc2/src/sc2code/debug.h b/sc2/src/sc2code/debug.h new file mode 100644 index 000000000..b64f07312 --- /dev/null +++ b/sc2/src/sc2code/debug.h @@ -0,0 +1,67 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if !defined(_DEBUG_H) && defined(DEBUG) +#define _DEBUG_H + +// Called when the debug key (symbol 'Debug' in the keys.cfg) is pressed. +extern void debugKeyPressed (void); + +// Forward time to the next event. If skipHEE is set, the event named +// HYPERSPACE_ENCOUNTER_EVENT, which normally occurs every game day, +// is skipped. +extern void forwardToNextEvent (BOOLEAN skipHEE); +// Generate a list of all events in the event queue. +extern void dumpEvents (FILE *out); +// Describe one event. +extern void dumpEvent (FILE *out, EVENTPTR eventPtr); +// Get the name of one event. +extern const char *eventName (BYTE func_index); + +// Give the flagship a decent equipment for debugging. +extern void equipShip (void); + +// Call a function for all stars. +extern void forAllStars (void (*callBack) (STAR_DESC *, void *), + void *arg); +// Flags for dumpStar(), dumpStars(), dumpPlanets(), and dumpPlanet(). +#define DUMP_PLANETS (1 << 0) +// Describe one star system. +extern void dumpStar(FILE *out, const STAR_DESC *star, UWORD flags); +// Generate a list of all stars. +extern void dumpStars(FILE *out, UWORD flags); +// Get a star color as a string. +extern const char *starColorString (BYTE col); +// Get a star type as a string. +extern const char *starTypeString (BYTE type); +// Get a string describing special presence in the star system. +extern const char *starPresenceString (BYTE index); +// Call a function for all planets in a star system. +extern void forAllPlanets(STAR_DESC *star, + void (*callback) (PLANET_DESC *, void *), void *arg); +// Get a list describing all planets in a star. +extern void dumpPlanets (FILE *out, const STAR_DESC *star, UWORD flags); +// Describe one planet. +extern void dumpPlanet(FILE *out, const PLANET_DESC *planet, UWORD flags); + +// Move instantly across hyperspace/quasispace. +extern BOOLEAN instantMove; + +// To add some day: +// - a function to fast forward the game clock to a specifiable time. + +#endif /* _DEBUG_H */ + diff --git a/sc2/src/sc2code/displist.c b/sc2/src/sc2code/displist.c index b0b75e9d5..feed474f2 100644 --- a/sc2/src/sc2code/displist.c +++ b/sc2/src/sc2code/displist.c @@ -18,6 +18,13 @@ #include "displist.h" +/* + * This file contains code for generic doubly linked lists. + * If QUEUE_TABLE is defined, each lists has its own preallocated + * pool of link structures. The size is specific on InitQueue(), + * and poses a hard limit on the number of elements in the list. + */ + BOOLEAN InitQueue (PQUEUE pq, COUNT num_elements, OBJ_SIZE size) { @@ -241,3 +248,19 @@ CountLinks (PQUEUE pq) return (LinkCount); } +void +ForAllLinks (PQUEUE pq, void (*callback)(LINKPTR, void *), void *arg) +{ + HLINK hLink, hNextLink; + + for (hLink = GetHeadLink (pq); hLink; hLink = hNextLink) + { + LINKPTR LinkPtr; + LinkPtr = LockLink (pq, hLink); + hNextLink = _GetSuccLink (LinkPtr); + (*callback) (LinkPtr, arg); + UnlockLink (pq, hLink); + } +} + + diff --git a/sc2/src/sc2code/displist.h b/sc2/src/sc2code/displist.h index 7d8623450..6f3dbf199 100644 --- a/sc2/src/sc2code/displist.h +++ b/sc2/src/sc2code/displist.h @@ -97,6 +97,7 @@ extern void PutQueue (PQUEUE pq, HLINK hLink); extern void InsertQueue (PQUEUE pq, HLINK hLink, HLINK hRefLink); extern void RemoveQueue (PQUEUE pq, HLINK hLink); extern COUNT CountLinks (PQUEUE pq); +void ForAllLinks(PQUEUE pq, void (*callback)(LINKPTR, void *), void *arg); #ifdef QUEUE_TABLE extern HLINK AllocLink (PQUEUE pq); extern void FreeLink (PQUEUE pq, HLINK hLink); diff --git a/sc2/src/sc2code/globdata.c b/sc2/src/sc2code/globdata.c index c68f710e6..672bd26f5 100644 --- a/sc2/src/sc2code/globdata.c +++ b/sc2/src/sc2code/globdata.c @@ -214,34 +214,8 @@ InitSIS (void) GLOBAL_SIS (ModuleSlots[2]) = CREW_POD; GLOBAL_SIS (CrewEnlisted) = CREW_POD_CAPACITY; GLOBAL_SIS (ModuleSlots[8]) = STORAGE_BAY; -#ifndef TESTING GLOBAL_SIS (ModuleSlots[1]) = FUEL_TANK; GLOBAL_SIS (FuelOnBoard) = 10 * FUEL_TANK_SCALE; -#else /* TESTING */ -for (i = 0; i < NUM_DRIVE_SLOTS; ++i) - GLOBAL_SIS (DriveSlots[i]) = FUSION_THRUSTER; -for (i = 0; i < NUM_JET_SLOTS; ++i) - GLOBAL_SIS (JetSlots[i]) = TURNING_JETS; -for (i = 0; i < 2; ++i) -{ -GLOBAL_SIS (ModuleSlots[i]) = HIGHEFF_FUELSYS; -GLOBAL_SIS (FuelOnBoard) += HEFUEL_TANK_CAPACITY; -} -for (; i < 7; ++i) -{ -GLOBAL_SIS (ModuleSlots[i]) = CREW_POD; -GLOBAL_SIS (CrewEnlisted) += CREW_POD_CAPACITY; -} -GLOBAL_SIS (ModuleSlots[i++]) = STORAGE_BAY; -GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; -GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; -GLOBAL_SIS (ModuleSlots[i++]) = DYNAMO_UNIT; -GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; -GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; -GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; -GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; -GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; -#endif /* TESTING */ InitQueue (&GLOBAL (built_ship_q), MAX_BUILT_SHIPS, sizeof (SHIP_FRAGMENT)); diff --git a/sc2/src/sc2code/globdata.h b/sc2/src/sc2code/globdata.h index b9522db14..433ab6584 100644 --- a/sc2/src/sc2code/globdata.h +++ b/sc2/src/sc2code/globdata.h @@ -832,7 +832,7 @@ END_GAME_STATE enum { - SUPER_MELEE = 0, + SUPER_MELEE = 0, /* Is also used while in the main menu */ IN_LAST_BATTLE, IN_ENCOUNTER, IN_HYPERSPACE /* in Hyperspace or Quasispace */, diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index aec8dd98e..72ae48d0d 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -31,6 +31,7 @@ #include "bbox.h" #include "port.h" #include "libs/uio.h" +#include "debug.h" SDL_Surface *SDL_Video; SDL_Surface *SDL_Screen; @@ -151,11 +152,13 @@ TFB_ProcessEvents () } if (ImmediateInputState.key[KEY_ABORT] || abortFlag) exit (0); +#ifdef DEBUG if (ImmediateInputState.key[KEY_DEBUG]) { FlushInput (); - uio_debugInteractive(stdin, stdout, stderr); + debugKeyPressed (); } +#endif /* DEBUG */ } void diff --git a/sc2/src/sc2code/libs/uio/debug.c b/sc2/src/sc2code/libs/uio/debug.c index d65a71316..852ef27b3 100644 --- a/sc2/src/sc2code/libs/uio/debug.c +++ b/sc2/src/sc2code/libs/uio/debug.c @@ -305,7 +305,7 @@ makeArgs(char *lineBuf, int *argc, char ***argv) { numArg = 0; ptr = lineBuf; - while(1) { + while(true) { while (isspace((int) *ptr)) ptr++; if (*ptr == '\0') @@ -318,7 +318,7 @@ makeArgs(char *lineBuf, int *argc, char ***argv) { args = uio_malloc((numArg + 1) * sizeof (char *)); numArg = 0; ptr = lineBuf; - while(1) { + while(true) { while (isspace((int) *ptr)) ptr++; if (*ptr == '\0') diff --git a/sc2/src/sc2code/planets/pstarmap.c b/sc2/src/sc2code/planets/pstarmap.c index 30e0ebe62..1be9a076f 100644 --- a/sc2/src/sc2code/planets/pstarmap.c +++ b/sc2/src/sc2code/planets/pstarmap.c @@ -21,6 +21,7 @@ #include "options.h" #include "controls.h" #include "libs/inplib.h" +#include "debug.h" //Added by Chris @@ -641,7 +642,20 @@ DoMoveCursor (PMENU_STATE pMS) else if (PulsedInputState.key[KEY_MENU_SELECT]) { GLOBAL (autopilot) = pMS->first_item; - +#ifdef DEBUG + if (instantMove) { + GLOBAL_SIS (log_x) = UNIVERSE_TO_LOGX(pMS->first_item.x); + GLOBAL_SIS (log_y) = UNIVERSE_TO_LOGY(pMS->first_item.y); + PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 3), 0, + NotPositional (), NULL, GAME_SOUND_PRIORITY); + if (pMS->flash_task) + { + ConcludeTask (pMS->flash_task); + pMS->flash_task = 0; + } + return (FALSE); + } +#endif DrawStarMap (0, NULL_PTR); } else diff --git a/sc2/src/sc2code/planets/solarsys.c b/sc2/src/sc2code/planets/solarsys.c index df9f713cb..0190b4a18 100644 --- a/sc2/src/sc2code/planets/solarsys.c +++ b/sc2/src/sc2code/planets/solarsys.c @@ -19,6 +19,7 @@ #include "starcon.h" #include "libs/graphics/gfx_common.h" #include "controls.h" +#include "debug.h" //#define DEBUG_SOLARSYS @@ -1369,7 +1370,7 @@ StartGroups: } } -static void +void InitSolarSys (void) { BOOLEAN InnerSystem; @@ -1475,7 +1476,7 @@ InitSolarSys (void) } } -static void +void UninitSolarSys (void) { FreeSolarSys (); @@ -1893,6 +1894,24 @@ void ExploreSolarSys (void) { SOLARSYS_STATE SolarSysState; + +#if 0 + { + FILE *out; + + // Write the star and planet info to a file in the current + // directory (which currently is the content/ directory). + out = fopen("PlanetInfo", "w"); + if (out == NULL) + exit(1); + dumpStars(out, DUMP_PLANETS); + fclose(out); + fprintf(stdout, "*** Star dump complete. You can terminate the program " + "now if it does not do so automatically.\n"); + exit(0); + // There may be other threads left. + } +#endif if (CurStarDescPtr == 0) {