diff --git a/sc2/ChangeLog b/sc2/ChangeLog index b39acd4f3..fa6b9d287 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.7: +- Introduce the concept of an "InputContext" - SvdB - Don't use alloca() in uio. - SvdB - Replace PlayerOne/PlayerTwo by PlayerControls[0]/PlayerControls[1] - SvdB - Moved comm resources into starcon.ls2 - Michael diff --git a/sc2/src/msvc++/UrQuanMasters.dsp b/sc2/src/msvc++/UrQuanMasters.dsp index 3693e2a7c..43d4c8cfd 100644 --- a/sc2/src/msvc++/UrQuanMasters.dsp +++ b/sc2/src/msvc++/UrQuanMasters.dsp @@ -3848,6 +3848,14 @@ SOURCE=..\sc2code\battle.h # End Source File # Begin Source File +SOURCE=..\sc2code\battlecontrols.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\battlecontrols.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\border.c # End Source File # Begin Source File @@ -4304,6 +4312,10 @@ SOURCE=..\sc2code\tactrans.c # End Source File # Begin Source File +SOURCE=..\sc2code\tactrans.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\trans.c # End Source File # Begin Source File diff --git a/sc2/src/sc2code/Makeinfo b/sc2/src/sc2code/Makeinfo index a9f24c6d5..2f439da96 100644 --- a/sc2/src/sc2code/Makeinfo +++ b/sc2/src/sc2code/Makeinfo @@ -1,15 +1,14 @@ uqm_SUBDIRS="comm libs planets ships" -uqm_CFILES="battle.c border.c build.c cleanup.c clock.c cnctdlg.c collide.c - comm.c commanim.c commglue.c confirm.c credits.c cyborg.c - demo.c displist.c dummy.c encount.c flash.c fmv.c galaxy.c gameev.c - gameinp.c gameopt.c gendef.c getchar.c globdata.c gravity.c - gravwell.c grpinfo.c hyper.c init.c intel.c intro.c ipdisp.c - load.c loadmele.c loadship.c master.c melee.c menu.c misc.c - oscill.c outfit.c pickmele.c pickship.c plandata.c process.c - restart.c save.c settings.c setup.c setupmenu.c ship.c - shipstat.c shipyard.c sis.c sounds.c starbase.c starcon.c - starmap.c state.c status.c tactrans.c trans.c uqmdebug.c - util.c velocity.c weapon.c" +uqm_CFILES="battle.c battlecontrols.c border.c build.c cleanup.c clock.c + cnctdlg.c collide.c comm.c commanim.c commglue.c confirm.c credits.c + cyborg.c demo.c displist.c dummy.c encount.c flash.c fmv.c galaxy.c + gameev.c gameinp.c gameopt.c gendef.c getchar.c globdata.c gravity.c + gravwell.c grpinfo.c hyper.c init.c intel.c intro.c ipdisp.c load.c + loadmele.c loadship.c master.c melee.c menu.c misc.c oscill.c + outfit.c pickmele.c pickship.c plandata.c process.c restart.c save.c + settings.c setup.c setupmenu.c ship.c shipstat.c shipyard.c sis.c + sounds.c starbase.c starcon.c starmap.c state.c status.c tactrans.c + trans.c uqmdebug.c util.c velocity.c weapon.c" if [ -n "$uqm_NETPLAY" ]; then uqm_SUBDIRS="$uqm_SUBDIRS netplay" fi diff --git a/sc2/src/sc2code/battle.c b/sc2/src/sc2code/battle.c index 8f0ca71c6..de75b6dba 100644 --- a/sc2/src/sc2code/battle.c +++ b/sc2/src/sc2code/battle.c @@ -18,8 +18,8 @@ #include "battle.h" +#include "battlecontrols.h" #include "controls.h" -#include "options.h" #include "init.h" #include "intel.h" #ifdef NETPLAY @@ -132,6 +132,13 @@ setupBattleInputOrder(void) #endif } +BATTLE_INPUT_STATE +frameInputHuman (HumanInputContext *context, STARSHIP *StarShipPtr) +{ + (void) StarShipPtr; + return CurrentInputToBattleInput (context->playerNr); +} + static void ProcessInput (void) { @@ -163,8 +170,9 @@ ProcessInput (void) { CyborgDescPtr = StarShipPtr; - InputState = (*(PlayerInput[cur_player]))(cur_player, - StarShipPtr); + InputState = PlayerInput[cur_player]->handlers->frameInput ( + PlayerInput[cur_player], StarShipPtr); + #if CREATE_JOURNAL JournalInput (InputState); #endif /* CREATE_JOURNAL */ diff --git a/sc2/src/sc2code/battle.h b/sc2/src/sc2code/battle.h index 0f7194f07..7cf0ef7fc 100644 --- a/sc2/src/sc2code/battle.h +++ b/sc2/src/sc2code/battle.h @@ -16,8 +16,15 @@ #ifndef _BATTLE_H #define _BATTLE_H +#include "options.h" #include "libs/compiler.h" + +#if defined (NETPLAY) +typedef DWORD BattleFrameCounter; +#endif + #include "displist.h" + // for QUEUE #include "init.h" // For NUM_SIDES @@ -35,16 +42,17 @@ extern QUEUE disp_q; extern BYTE battle_counter[NUM_SIDES]; extern BOOLEAN instantVictory; -#ifdef NETPLAY -typedef DWORD BattleFrameCounter; +#if defined (NETPLAY) extern BattleFrameCounter battleFrameCount; +#endif +#ifdef NETPLAY extern COUNT currentDeadSide; COUNT GetPlayerOrder (COUNT i); #else # define GetPlayerOrder(i) (i) #endif -extern BOOLEAN Battle (void); +BOOLEAN Battle (void); #endif /* _BATTLE_H */ diff --git a/sc2/src/sc2code/battlecontrols.c b/sc2/src/sc2code/battlecontrols.c new file mode 100644 index 000000000..d63d2bb46 --- /dev/null +++ b/sc2/src/sc2code/battlecontrols.c @@ -0,0 +1,98 @@ +/* + * 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 "battlecontrols.h" + +#include "intel.h" + // For computer_intelligence() +#include "tactrans.h" + // For battleEndReady* +#include "libs/misc.h" + // For HFree() +#ifdef NETPLAY +# include "netplay/netmelee.h" +#endif /* NETPLAY */ + +InputContext *PlayerInput[NUM_PLAYERS]; + +BattleInputHandlers ComputerInputHandlers = { + /* .frameInput = */ (BattleFrameInputFunction) computer_intelligence, + /* .selectShip = */ (SelectShipFunction) selectShipComputer, + /* .battleEndReady = */ (BattleEndReadyFunction) battleEndReadyComputer, + /* .deleteContext = */ InputContext_delete, +}; + +BattleInputHandlers HumanInputHandlers = { + /* .frameInput = */ (BattleFrameInputFunction) frameInputHuman, + /* .selectShip = */ (SelectShipFunction) selectShipHuman, + /* .battleEndReady = */ (BattleEndReadyFunction) battleEndReadyHuman, + /* .deleteContext = */ InputContext_delete, +}; + +#ifdef NETPLAY +BattleInputHandlers NetworkInputHandlers = { + /* .frameInput = */ (BattleFrameInputFunction) networkBattleInput, + /* .selectShip = */ (SelectShipFunction) selectShipNetwork, + /* .battleEndReady = */ (BattleEndReadyFunction) battleEndReadyNetwork, + /* .deleteContext = */ InputContext_delete, +}; +#endif + + +void +InputContext_init (InputContext *context, BattleInputHandlers *handlers, + COUNT playerNr) +{ + context->handlers = handlers; + context->playerNr = playerNr; +} + +void +InputContext_delete (InputContext *context) +{ + HFree (context); +} + +ComputerInputContext * +ComputerInputContext_new (COUNT playerNr) +{ + ComputerInputContext *result = HMalloc (sizeof (ComputerInputContext)); + InputContext_init ((InputContext *) result, + &ComputerInputHandlers, playerNr); + return result; +} + +HumanInputContext * +HumanInputContext_new (COUNT playerNr) +{ + HumanInputContext *result = HMalloc (sizeof (HumanInputContext)); + InputContext_init ((InputContext *) result, + &HumanInputHandlers, playerNr); + return result; +} + +#ifdef NETPLAY +NetworkInputContext * +NetworkInputContext_new (COUNT playerNr) +{ + NetworkInputContext *result = HMalloc (sizeof (NetworkInputContext)); + InputContext_init ((InputContext *) result, + &NetworkInputHandlers, playerNr); + return result; +} +#endif + + diff --git a/sc2/src/sc2code/battlecontrols.h b/sc2/src/sc2code/battlecontrols.h new file mode 100644 index 000000000..dd8cf3275 --- /dev/null +++ b/sc2/src/sc2code/battlecontrols.h @@ -0,0 +1,93 @@ +/* + * 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. + */ + +#ifndef _BATTLECONTROLS_H +#define _BATTLECONTROLS_H + +typedef struct BattleInputHandlers BattleInputHandlers; +typedef struct InputContext InputContext; +typedef struct ComputerInputContext ComputerInputContext; +typedef struct HumanInputContext HumanInputContext; +#ifdef NETPLAY +typedef struct NetworkInputContext NetworkInputContext; +#endif /* NETPLAY */ + +#include "controls.h" +#include "pickmele.h" +#include "races.h" +#include "libs/compiler.h" + +typedef BATTLE_INPUT_STATE (*BattleFrameInputFunction) ( + InputContext *context, STARSHIP *StarShipPtr); +typedef BOOLEAN (*SelectShipFunction) (InputContext *context, + GETMELEE_STATE *gms); +typedef bool (*BattleEndReadyFunction) (InputContext *context); +typedef void (*DeleteInputContextFunction) (InputContext *context); + + +struct BattleInputHandlers { + BattleFrameInputFunction frameInput; + SelectShipFunction selectShip; + BattleEndReadyFunction battleEndReady; + DeleteInputContextFunction deleteContext; +}; + +#define INPUT_CONTEXT_COMMON \ + BattleInputHandlers *handlers; \ + COUNT playerNr; + +// Base "class" for all ...InputContext structures +struct InputContext { + INPUT_CONTEXT_COMMON +}; + +struct ComputerInputContext { + INPUT_CONTEXT_COMMON + // TODO: Put RNG Context used for the AI here. +}; + +struct HumanInputContext { + INPUT_CONTEXT_COMMON +}; + +#ifdef NETPLAY +struct NetworkInputContext { + INPUT_CONTEXT_COMMON + // TODO: put NetworkConnection for this player here. +}; +#endif /* NETPLAY */ + +ComputerInputContext *ComputerInputContext_new (COUNT playerNr); +HumanInputContext *HumanInputContext_new (COUNT playerNr); +#ifdef NETPLAY +NetworkInputContext *NetworkInputContext_new (COUNT playerNr); +#endif /* NETPLAY */ + +extern InputContext *PlayerInput[]; + + +BATTLE_INPUT_STATE frameInputHuman (HumanInputContext *context, + STARSHIP *StarShipPtr); +void InputContext_init(InputContext *context, BattleInputHandlers *handlers, + COUNT playerNr); +void InputContext_delete (InputContext *context); + // Do not call directly, only from the FreeInputContextFunction. + // Call InputContext->handlers->freeContext() to release an + // InputContext. + +#endif /* _BATTLECONTROLS_H */ + + diff --git a/sc2/src/sc2code/controls.h b/sc2/src/sc2code/controls.h index 0b088357f..c4ad4774f 100644 --- a/sc2/src/sc2code/controls.h +++ b/sc2/src/sc2code/controls.h @@ -19,9 +19,6 @@ #ifndef _CONTROLS_H_ #define _CONTROLS_H_ -#include "races.h" - // For STARSHIP - #include "libs/compiler.h" #include "libs/strlib.h" @@ -89,10 +86,8 @@ typedef UBYTE BATTLE_INPUT_STATE; #define BATTLE_ESCAPE ((BATTLE_INPUT_STATE)(1 << 5)) #define BATTLE_DOWN ((BATTLE_INPUT_STATE)(1 << 6)) -typedef BATTLE_INPUT_STATE (*battle_summary_func) (COUNT player, - STARSHIP *StarShipPtr); -extern battle_summary_func ComputerInput, HumanInput[], NetworkInput; -extern battle_summary_func PlayerInput[]; +BATTLE_INPUT_STATE CurrentInputToBattleInput (COUNT player); +BATTLE_INPUT_STATE PulsedInputToBattleInput (COUNT player); extern CONTROLLER_INPUT_STATE CurrentInputState; extern CONTROLLER_INPUT_STATE PulsedInputState; @@ -114,8 +109,6 @@ BOOLEAN ConfirmExit (void); void DoPopupWindow(const char *msg); void DoInput (void *pInputState, BOOLEAN resetInput); -BATTLE_INPUT_STATE combat_summary (COUNT player, STARSHIP *StarShipPtr); - extern volatile BOOLEAN GamePaused; extern volatile BOOLEAN ExitRequested; diff --git a/sc2/src/sc2code/cyborg.c b/sc2/src/sc2code/cyborg.c index 637993849..f5b001bc5 100644 --- a/sc2/src/sc2code/cyborg.c +++ b/sc2/src/sc2code/cyborg.c @@ -1010,7 +1010,7 @@ Avoid (ELEMENT *ShipPtr, EVALUATE_DESC *EvalDescPtr) } BATTLE_INPUT_STATE -tactical_intelligence (COUNT player, STARSHIP *StarShipPtr) +tactical_intelligence (ComputerInputContext *context, STARSHIP *StarShipPtr) { ELEMENT *ShipPtr; ELEMENT Ship; @@ -1038,7 +1038,7 @@ tactical_intelligence (COUNT player, STARSHIP *StarShipPtr) ShipMoved = TRUE; /* Disable ship's special completely for the Standard AI */ - if (PlayerControl[player] & STANDARD_RATING) + if (PlayerControl[context->playerNr] & STANDARD_RATING) ++StarShipPtr->special_counter; #ifdef DEBUG_CYBORG @@ -1146,9 +1146,9 @@ if (!(ShipPtr->state_flags & FINITE_LIFE) InitCyborg (EnemyStarShipPtr); ed.which_turn = WORLD_TO_TURN ( - square_root ((long)dx * dx + (long)dy * dy) - ); - if (ed.which_turn > ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn) + square_root ((long)dx * dx + (long)dy * dy)); + if (ed.which_turn > + ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn) { UnlockElement (hElement); continue; @@ -1261,7 +1261,7 @@ if (!(ShipPtr->state_flags & FINITE_LIFE) ed.which_turn = 0; } } - else if (!(PlayerControl[player] & AWESOME_RATING)) + else if (!(PlayerControl[context->playerNr] & AWESOME_RATING)) ed.which_turn = 0; else { diff --git a/sc2/src/sc2code/encount.c b/sc2/src/sc2code/encount.c index f11d2ce9f..af86eb939 100644 --- a/sc2/src/sc2code/encount.c +++ b/sc2/src/sc2code/encount.c @@ -19,6 +19,7 @@ #include "encount.h" #include "battle.h" +#include "battlecontrols.h" #include "build.h" #include "colors.h" #include "controls.h" @@ -724,6 +725,7 @@ EncounterBattle (void) RESOURCE_INDEX hLastIndex; ACTIVITY OldActivity; extern UWORD nth_frame; + InputContext *savedPlayerInput; LockMutex (GraphicsLock); @@ -756,7 +758,9 @@ EncounterBattle (void) cur_speed = (BYTE)~0; /* maximum speed - no rendering */ nth_frame = MAKE_WORD (1, cur_speed); PlayerControl[0] = CYBORG_CONTROL | AWESOME_RATING; - PlayerInput[0] = ComputerInput; + savedPlayerInput = PlayerInput[0]; + PlayerInput[0] = NULL; + SetPlayerInput (0); } GameSounds = CaptureSound (LoadSound (GAME_SOUNDS)); @@ -775,7 +779,8 @@ EncounterBattle (void) { nth_frame = MAKE_WORD (0, 0); PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; - PlayerInput[0] = HumanInput[0]; + ClearPlayerInput (0); + PlayerInput[0] = savedPlayerInput; } SetResourceIndex (hResIndex); diff --git a/sc2/src/sc2code/gameinp.c b/sc2/src/sc2code/gameinp.c index e694c06fd..45af9c8d6 100644 --- a/sc2/src/sc2code/gameinp.c +++ b/sc2/src/sc2code/gameinp.c @@ -17,18 +17,22 @@ */ #include "controls.h" +#include "battlecontrols.h" #include "init.h" +#include "intel.h" + // For computer_intelligence +#ifdef NETPLAY +# include "netplay/netmelee.h" +#endif #include "planets/planets.h" #include "settings.h" #include "sounds.h" +#include "tactrans.h" #include "libs/inplib.h" #include "libs/timelib.h" #include "libs/threadlib.h" -battle_summary_func ComputerInput, HumanInput[NUM_PLAYERS], NetworkInput; -battle_summary_func PlayerInput[NUM_PLAYERS]; - #define ACCELERATION_INCREMENT (ONE_SECOND / 12) #define MENU_REPEAT_DELAY (ONE_SECOND >> 1) @@ -417,13 +421,19 @@ ControlInputToBattleInput (const int *keyState) } BATTLE_INPUT_STATE -combat_summary (COUNT player, STARSHIP *StarShipPtr) +CurrentInputToBattleInput (COUNT player) { - (void) StarShipPtr; return ControlInputToBattleInput( CurrentInputState.key[PlayerControls[player]]); } +BATTLE_INPUT_STATE +PulsedInputToBattleInput (COUNT player) +{ + return ControlInputToBattleInput( + PulsedInputState.key[PlayerControls[player]]); +} + BOOLEAN AnyButtonPress (BOOLEAN CheckSpecial) { diff --git a/sc2/src/sc2code/intel.c b/sc2/src/sc2code/intel.c index 48e3aba02..627ae79a4 100644 --- a/sc2/src/sc2code/intel.c +++ b/sc2/src/sc2code/intel.c @@ -18,6 +18,7 @@ #include "intel.h" +#include "battlecontrols.h" #include "controls.h" #include "globdata.h" #include "setup.h" @@ -29,7 +30,7 @@ SIZE cur_player; BATTLE_INPUT_STATE -computer_intelligence (COUNT player, STARSHIP *StarShipPtr) +computer_intelligence (ComputerInputContext *context, STARSHIP *StarShipPtr) { BATTLE_INPUT_STATE InputState; @@ -38,19 +39,20 @@ computer_intelligence (COUNT player, STARSHIP *StarShipPtr) if (StarShipPtr) { - if (PlayerControl[player] & CYBORG_CONTROL) + // Selecting the next action for in battle. + if (PlayerControl[context->playerNr] & CYBORG_CONTROL) { - InputState = tactical_intelligence (player, StarShipPtr); + InputState = tactical_intelligence (context, StarShipPtr); - // allow a player to warp-escape in cyborg mode - if (player == 0) - InputState |= (*(HumanInput[player])) (player, StarShipPtr) - & BATTLE_ESCAPE; + // Allow a player to warp-escape in cyborg mode + if (context->playerNr == 0) + InputState |= CurrentInputToBattleInput ( + context->playerNr) & BATTLE_ESCAPE; } else - InputState = (*(HumanInput[player])) (player, StarShipPtr); + InputState = CurrentInputToBattleInput (context->playerNr); } - else if (!(PlayerControl[player] & PSYTRON_CONTROL)) + else if (!(PlayerControl[context->playerNr] & PSYTRON_CONTROL)) InputState = 0; else { diff --git a/sc2/src/sc2code/intel.h b/sc2/src/sc2code/intel.h index 9a4b3a31a..531312539 100644 --- a/sc2/src/sc2code/intel.h +++ b/sc2/src/sc2code/intel.h @@ -19,6 +19,7 @@ #ifndef _INTEL_H #define _INTEL_H +#include "battlecontrols.h" #include "controls.h" #include "element.h" #include "races.h" @@ -46,10 +47,10 @@ enum extern STARSHIP *CyborgDescPtr; extern SIZE cur_player; -extern BATTLE_INPUT_STATE computer_intelligence (COUNT player, - STARSHIP *StarShipPtr); -extern BATTLE_INPUT_STATE tactical_intelligence (COUNT player, - STARSHIP *StarShipPtr); +extern BATTLE_INPUT_STATE computer_intelligence ( + ComputerInputContext *context, STARSHIP *StarShipPtr); +extern BATTLE_INPUT_STATE tactical_intelligence ( + ComputerInputContext *context, STARSHIP *StarShipPtr); extern void ship_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter); extern BOOLEAN ship_weapons (ELEMENT *ShipPtr, ELEMENT *OtherPtr, @@ -67,6 +68,7 @@ extern BOOLEAN ThrustShip (ELEMENT *ShipPtr, COUNT angle); #define PSYTRON_CONTROL (BYTE)(1 << 2) #define NETWORK_CONTROL (BYTE)(1 << 3) #define COMPUTER_CONTROL (CYBORG_CONTROL | PSYTRON_CONTROL) +#define CONTROL_MASK (HUMAN_CONTROL | COMPUTER_CONTROL | NETWORK_CONTROL) #define STANDARD_RATING (BYTE)(1 << 4) #define GOOD_RATING (BYTE)(1 << 5) diff --git a/sc2/src/sc2code/melee.c b/sc2/src/sc2code/melee.c index 7dbb0de0b..8729ad9ab 100644 --- a/sc2/src/sc2code/melee.c +++ b/sc2/src/sc2code/melee.c @@ -1714,10 +1714,12 @@ StartMelee (MELEE_STATE *pMS) WaitForSoundEnd (TFBSOUND_WAIT_ALL); + SetPlayerInputAll (); load_gravity_well ((BYTE)((COUNT)TFB_Random () % NUMBER_OF_PLANET_TYPES)); Battle (); free_gravity_well (); + ClearPlayerInputAll (); if (GLOBAL (CurrentActivity) & CHECK_ABORT) return; @@ -1926,7 +1928,6 @@ DoConnectingDialog (MELEE_STATE *pMS) { /* Connection complete! */ PlayerControl[which_side] = NETWORK_CONTROL | STANDARD_RATING; - SetPlayerInput (); DrawControls (which_side, TRUE); RedrawMeleeFrame (); @@ -1975,11 +1976,6 @@ check_for_disconnections (MELEE_STATE *pMS) } } - if (changed) - { - SetPlayerInput (); - } - (void) pMS; } @@ -2326,7 +2322,6 @@ Melee (void) PlayerControl[1] = COMPUTER_CONTROL | STANDARD_RATING; MenuState.SideState[1].TeamImage = MenuState.load.preBuiltList[1]; } - SetPlayerInput (); teamStringChanged (&MenuState, 0); teamStringChanged (&MenuState, 1); entireFleetChanged (&MenuState, 0); diff --git a/sc2/src/sc2code/netplay/netmelee.c b/sc2/src/sc2code/netplay/netmelee.c index b1c778a6a..07db76f84 100644 --- a/sc2/src/sc2code/netplay/netmelee.c +++ b/sc2/src/sc2code/netplay/netmelee.c @@ -30,6 +30,8 @@ #include "netplay/proto/ready.h" #include "netplay/proto/reset.h" +#include "battlecontrols.h" + // for NetworkInputContext #include "controls.h" // for BATTLE_INPUT_STATE #include "init.h" @@ -318,8 +320,8 @@ setBattleStateConnections(struct battlestate_struct *bs) { } BATTLE_INPUT_STATE -networkBattleInput(COUNT player, STARSHIP *StarShipPtr) { - BattleInputBuffer *bib = getBattleInputBuffer(player); +networkBattleInput(NetworkInputContext *context, STARSHIP *StarShipPtr) { + BattleInputBuffer *bib = getBattleInputBuffer(context->playerNr); BATTLE_INPUT_STATE result; for (;;) { @@ -345,7 +347,7 @@ networkBattleInput(COUNT player, STARSHIP *StarShipPtr) { break; { - NetConnection *conn = netConnections[player]; + NetConnection *conn = netConnections[context->playerNr]; // First try whether there is incoming data, without blocking. // If there isn't any, only then give a warning, and then @@ -364,7 +366,7 @@ networkBattleInput(COUNT player, STARSHIP *StarShipPtr) { #if 0 log_add(log_Warning, "NETPLAY: [%d] stalling for " "network input. Increase the input delay if this " - "happens a lot.\n", player); + "happens a lot.\n", context->playerNr); #endif #define MAX_BLOCK_TIME 500 netInputBlocking(MAX_BLOCK_TIME); diff --git a/sc2/src/sc2code/netplay/netmelee.h b/sc2/src/sc2code/netplay/netmelee.h index fa2580aad..36f5dc401 100644 --- a/sc2/src/sc2code/netplay/netmelee.h +++ b/sc2/src/sc2code/netplay/netmelee.h @@ -24,8 +24,12 @@ #include "netconnection.h" #include "packetsenders.h" +#include "../battlecontrols.h" + // for NetworkInputContext #include "../controls.h" // for BATTLE_INPUT_STATE +#include "../races.h" + // for STARSHIP extern struct NetConnection *netConnections[]; @@ -55,7 +59,8 @@ void sendChecksumConnections(uint32 frameNr, uint32 checksum); void initBattleStateDataConnections(void); void setBattleStateConnections(struct battlestate_struct *bs); -BATTLE_INPUT_STATE networkBattleInput(COUNT player, STARSHIP *StarShipPtr); +BATTLE_INPUT_STATE networkBattleInput(NetworkInputContext *context, + STARSHIP *StarShipPtr); NetConnection *openPlayerNetworkConnection(COUNT player, void *extra); void closePlayerNetworkConnection(COUNT player); diff --git a/sc2/src/sc2code/pickmele.c b/sc2/src/sc2code/pickmele.c index 0f97c97e0..f26cbecf2 100644 --- a/sc2/src/sc2code/pickmele.c +++ b/sc2/src/sc2code/pickmele.c @@ -16,9 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define PICKMELE_INTERNAL #include "pickmele.h" -#include "build.h" +#include "battlecontrols.h" #include "controls.h" #include "flash.h" #include "intel.h" @@ -29,10 +30,8 @@ # include "netplay/notify.h" #endif #include "races.h" -#include "settings.h" #include "setup.h" #include "sounds.h" -#include "libs/inplib.h" #include "libs/log.h" #include "libs/mathlib.h" @@ -42,33 +41,6 @@ #define PICK_Y_OFFS 24 #define PICK_SIDE_OFFS 100 -struct getmelee_struct { - BOOLEAN (*InputFunc) (struct getmelee_struct *pInputState); - COUNT MenuRepeatDelay; - BOOLEAN Initialized; - - struct { - TimeCount timeIn; - HSTARSHIP hBattleShip; - // Chosen ship. - COUNT row; - COUNT col; - COUNT ships_left; - // Number of ships still available. - COUNT randomIndex; - // Pre-generated random number. - BOOLEAN selecting; - // Is this player selecting a ship? - BOOLEAN done; - // Has a selection been made for this player? - FlashContext *flashContext; - // Context for controlling the flash rectangle. -#ifdef NETPLAY - BOOLEAN remoteSelected; -#endif - } player[NUM_PLAYERS]; -}; - #ifdef NETPLAY static void reportShipSelected (GETMELEE_STATE *gms, COUNT index); #endif @@ -146,95 +118,72 @@ PickMelee_ChangedSelection (GETMELEE_STATE *gms, COUNT playerI) Flash_setRect (gms->player[playerI].flashContext, &r); } -// Auxiliary function to DoGetMelee for a single player -// Returns FALSE if the player selected abort. -static BOOLEAN -DoGetMeleePlayer (GETMELEE_STATE *gms, COUNT which_player) +// Only returns false when there is no ship for the choice. +bool +setShipSelected(GETMELEE_STATE *gms, COUNT playerI, COUNT choice, + bool reportNetwork) { - BOOLEAN left, right, up, down, select; + HSTARSHIP ship; - if (PlayerInput[which_player] == ComputerInput) - { -#define COMPUTER_SELECTION_DELAY (ONE_SECOND >> 1) - TimeCount now = GetTimeCounter (); - if (now < gms->player[which_player].timeIn + - COMPUTER_SELECTION_DELAY) - return TRUE; + assert (!gms->player[playerI].done); - left = right = up = down = FALSE; - select = TRUE; - } -#ifdef NETPLAY - else if (PlayerInput[which_player] == NetworkInput) + if (choice == (COUNT) ~0) { - flushPacketQueues (); - // Sets gms->player[which_player].remoteSelected if input - // is received. - if (gms->player[which_player].remoteSelected) - gms->player[which_player].done = TRUE; - return TRUE; + // Random ship selection. + ship = MeleeShipByUsedIndex (&race_q[playerI], + gms->player[playerI].randomIndex); } -#endif else { - CONTROL_TEMPLATE template; - - if (which_player == 0) - template = PlayerControls[0]; - else - template = PlayerControls[1]; - - left = PulsedInputState.key[template][KEY_LEFT]; - right = PulsedInputState.key[template][KEY_RIGHT]; - up = PulsedInputState.key[template][KEY_UP]; - down = PulsedInputState.key[template][KEY_DOWN]; - select = PulsedInputState.key[template][KEY_WEAPON]; + // Explicit ship selection. + ship = MeleeShipByQueueIndex (&race_q[playerI], choice); } - if (select) - { - if (gms->player[which_player].col == NUM_MELEE_COLS_ORIG) - { - // Selection is on a non-ship slot. (Random or exit). - if (gms->player[which_player].row == 0) - { - // Random ship - gms->player[which_player].hBattleShip = - MeleeShipByUsedIndex (&race_q[which_player], - gms->player[which_player].randomIndex); - PlayMenuSound (MENU_SOUND_SUCCESS); + if (ship == 0) + return false; + + gms->player[playerI].choice = choice; + gms->player[playerI].hBattleShip = ship; + PlayMenuSound (MENU_SOUND_SUCCESS); #ifdef NETPLAY - reportShipSelected (gms, (COUNT)~0); + if (reportNetwork) + reportShipSelected (gms, choice); +#else + (void) reportNetwork; #endif - gms->player[which_player].done = TRUE; - } - else - { - // Selected exit - if (ConfirmExit ()) - return FALSE; - } + gms->player[playerI].done = true; + return true; +} + +// Returns FALSE if aborted. +static BOOLEAN +SelectShip_processInput (GETMELEE_STATE *gms, COUNT playerI, + BATTLE_INPUT_STATE inputState) +{ + if (inputState & BATTLE_WEAPON) + { + if (gms->player[playerI].col == NUM_MELEE_COLS_ORIG && + gms->player[playerI].row == 0) + { + // Random ship + (void) setShipSelected (gms, playerI, (COUNT) ~0, TRUE); + } + else if (gms->player[playerI].col == NUM_MELEE_COLS_ORIG && + gms->player[playerI].row == 1) + { + // Selected exit + if (ConfirmExit ()) + return FALSE; } else { // Selection is on a ship slot. - COUNT ship_index; - HSTARSHIP ship; - - ship_index = (gms->player[which_player].row * NUM_MELEE_COLS_ORIG) - + gms->player[which_player].col; - ship = MeleeShipByQueueIndex (&race_q[which_player], ship_index); - if (ship != 0) - { - // Selection contains a ship. - gms->player[which_player].hBattleShip = ship; - gms->player[which_player].done = true; - PlayMenuSound (MENU_SOUND_SUCCESS); -#ifdef NETPLAY - reportShipSelected (gms, ship_index); -#endif - return TRUE; - } + COUNT shipI = + (gms->player[playerI].row * NUM_MELEE_COLS_ORIG) + + gms->player[playerI].col; + (void) setShipSelected (gms, playerI, shipI, TRUE); + // If the choice is not valid, setShipSelected() + // will not set .done. } } else @@ -242,43 +191,79 @@ DoGetMeleePlayer (GETMELEE_STATE *gms, COUNT which_player) // Process motion commands. COUNT new_row, new_col; - new_row = gms->player[which_player].row; - new_col = gms->player[which_player].col; - if (left) + new_row = gms->player[playerI].row; + new_col = gms->player[playerI].col; + if (inputState & BATTLE_LEFT) { if (new_col-- == 0) new_col = NUM_MELEE_COLS_ORIG; } - else if (right) + else if (inputState & BATTLE_RIGHT) { if (new_col++ == NUM_MELEE_COLS_ORIG) new_col = 0; } - if (up) + if (inputState & BATTLE_THRUST) { if (new_row-- == 0) new_row = NUM_MELEE_ROWS - 1; } - else if (down) + else if (inputState & BATTLE_DOWN) { if (++new_row == NUM_MELEE_ROWS) new_row = 0; } - if (new_row != gms->player[which_player].row || - new_col != gms->player[which_player].col) + if (new_row != gms->player[playerI].row || + new_col != gms->player[playerI].col) { - gms->player[which_player].row = new_row; - gms->player[which_player].col = new_col; + gms->player[playerI].row = new_row; + gms->player[playerI].col = new_col; PlayMenuSound (MENU_SOUND_MOVE); - PickMelee_ChangedSelection (gms, which_player); + PickMelee_ChangedSelection (gms, playerI); } } return TRUE; } +BOOLEAN +selectShipHuman (HumanInputContext *context, GETMELEE_STATE *gms) +{ + BATTLE_INPUT_STATE inputState = + PulsedInputToBattleInput (context->playerNr); + + return SelectShip_processInput (gms, context->playerNr, inputState); +} + +BOOLEAN +selectShipComputer (ComputerInputContext *context, GETMELEE_STATE *gms) +{ +#define COMPUTER_SELECTION_DELAY (ONE_SECOND >> 1) + TimeCount now = GetTimeCounter (); + if (now < gms->player[context->playerNr].timeIn + + COMPUTER_SELECTION_DELAY) + return TRUE; + + return SelectShip_processInput (gms, context->playerNr, BATTLE_WEAPON); + // Simulate selection of the random choice button. +} + +#ifdef NETPLAY +BOOLEAN +selectShipNetwork (NetworkInputContext *context, GETMELEE_STATE *gms) +{ + flushPacketQueues (); + // Sets gms->player[context->playerNr].remoteSelected if input + // is received. + if (gms->player[context->playerNr].remoteSelected) + gms->player[context->playerNr].done = TRUE; + + return TRUE; +} +#endif + // Select a new ship from the fleet for battle. // Returns 'TRUE' if no choice has been made yet; this function is to be // called again later. @@ -328,7 +313,8 @@ DoGetMelee (GETMELEE_STATE *gms) continue; if (!gms->player[playerI].done) { - if (!DoGetMeleePlayer (gms, playerI)) + if (!PlayerInput[playerI]->handlers->selectShip ( + PlayerInput[playerI], gms)) goto aborted; if (gms->player[playerI].done) @@ -351,7 +337,13 @@ aborted: flushPacketQueues (); #endif for (playerI = 0; playerI < NUM_PLAYERS; playerI++) + { + if (!gms->player[playerI].selecting) + continue; + + gms->player[playerI].choice = 0; gms->player[playerI].hBattleShip = 0; + } GLOBAL (CurrentActivity) &= ~CHECK_ABORT; return FALSE; } @@ -591,7 +583,7 @@ GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships) Flash_setFrameTime (gmstate.player[playerI].flashContext, ONE_SECOND / 16); #ifdef NETPLAY - if (PlayerInput[playerI] == NetworkInput) + if (PlayerControl[playerI] & NETWORK_CONTROL) Flash_setSpeed (gmstate.player[playerI].flashContext, ONE_SECOND / 2, 0, ONE_SECOND / 2, 0); else @@ -653,6 +645,8 @@ GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships) if (!negotiateReadyConnections (true, NetState_interBattle)) ok = false; } + else + setStateConnections (NetState_interBattle); #endif if (!ok) @@ -745,19 +739,7 @@ updateMeleeSelection (GETMELEE_STATE *gms, COUNT playerI, COUNT ship) return false; } - if (ship == (COUNT) ~0) - { - // Random selection. - gms->player[playerI].hBattleShip = - MeleeShipByUsedIndex (&race_q[playerI], - gms->player[playerI].randomIndex); - gms->player[playerI].remoteSelected = TRUE; - return true; - } - - gms->player[playerI].hBattleShip = - MeleeShipByQueueIndex (&race_q[playerI], ship); - if (gms->player[playerI].hBattleShip == 0) + if (!setShipSelected (gms, playerI, ship, false)) { log_add (log_Warning, "Invalid ship selection received from remote " "party.\n"); diff --git a/sc2/src/sc2code/pickmele.h b/sc2/src/sc2code/pickmele.h index 728aefaf1..996ac3a55 100644 --- a/sc2/src/sc2code/pickmele.h +++ b/sc2/src/sc2code/pickmele.h @@ -17,7 +17,10 @@ #ifndef _PICKMELE_H #define _PICKMELE_H +typedef struct getmelee_struct GETMELEE_STATE; + #include "races.h" +#include "battlecontrols.h" #include "libs/compiler.h" BOOLEAN MeleeShipDeath (STARSHIP *ship, COUNT which_player); @@ -25,9 +28,54 @@ void MeleeGameOver (void); BOOLEAN GetInitialMeleeStarShips (HSTARSHIP *result); BOOLEAN GetNextMeleeStarShip (COUNT which_player, HSTARSHIP *result); -typedef struct getmelee_struct GETMELEE_STATE; - bool updateMeleeSelection (GETMELEE_STATE *gms, COUNT player, COUNT ship); +BOOLEAN selectShipHuman (HumanInputContext *context, GETMELEE_STATE *gms); +BOOLEAN selectShipComputer (ComputerInputContext *context, + GETMELEE_STATE *gms); +#ifdef NETPLAY +BOOLEAN selectShipNetwork (NetworkInputContext *context, GETMELEE_STATE *gms); +#endif /* NETPLAY */ + +#ifdef PICKMELE_INTERNAL + +#include "flash.h" +#include "libs/timelib.h" + +struct getmelee_struct { + BOOLEAN (*InputFunc) (struct getmelee_struct *pInputState); + COUNT MenuRepeatDelay; + BOOLEAN Initialized; + + struct { + TimeCount timeIn; + HSTARSHIP hBattleShip; + // Chosen ship. + COUNT choice; + // Index of chosen ship, or (COUNT) ~0 for random choice. + + COUNT row; + COUNT col; + COUNT ships_left; + // Number of ships still available. + COUNT randomIndex; + // Pre-generated random number. + BOOLEAN selecting; + // Is this player selecting a ship? + BOOLEAN done; + // Has a selection been made for this player? + FlashContext *flashContext; + // Context for controlling the flash rectangle. +#ifdef NETPLAY + BOOLEAN remoteSelected; +#endif + } player[NUM_PLAYERS]; +}; + +bool setShipSelected(GETMELEE_STATE *gms, COUNT playerI, COUNT choice, + bool reportNetwork); + +#endif /* PICKMELE_INTERNAL */ + #endif /* _PICKMELE_H */ diff --git a/sc2/src/sc2code/races.h b/sc2/src/sc2code/races.h index 2513fb30a..a0337b6e5 100644 --- a/sc2/src/sc2code/races.h +++ b/sc2/src/sc2code/races.h @@ -21,6 +21,11 @@ #include "libs/compiler.h" #include "units.h" +#include "displist.h" + +typedef struct STARSHIP STARSHIP; +typedef HLINK HSTARSHIP; + #include "element.h" #include "libs/sndlib.h" #include "libs/reslib.h" @@ -184,9 +189,7 @@ typedef struct } SHIP_BASE; -typedef HLINK HSTARSHIP; - -typedef struct +struct STARSHIP { SHIP_BASE_COMMON; @@ -221,7 +224,7 @@ typedef struct HELEMENT hShip; COUNT ShipFacing; -} STARSHIP; +}; static inline STARSHIP * LockStarShip (const QUEUE *pq, HSTARSHIP h) diff --git a/sc2/src/sc2code/restart.c b/sc2/src/sc2code/restart.c index cca03e9f1..c1b6a8659 100644 --- a/sc2/src/sc2code/restart.c +++ b/sc2/src/sc2code/restart.c @@ -420,7 +420,6 @@ StartGame (void) PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; PlayerControl[1] = COMPUTER_CONTROL | AWESOME_RATING; - SetPlayerInput (); return (TRUE); } diff --git a/sc2/src/sc2code/setup.c b/sc2/src/sc2code/setup.c index 5827af7b3..e4fbc0014 100644 --- a/sc2/src/sc2code/setup.c +++ b/sc2/src/sc2code/setup.c @@ -73,12 +73,6 @@ uio_DirHandle *rootDir; static void InitPlayerInput (void) { - HumanInput[0] = combat_summary; - HumanInput[1] = combat_summary; - ComputerInput = computer_intelligence; -#ifdef NETPLAY - NetworkInput = networkBattleInput; -#endif } void @@ -229,34 +223,56 @@ InitGameKernel (void) } void -SetPlayerInput (void) +SetPlayerInput (COUNT playerI) { - COUNT which_player; + assert (PlayerInput[playerI] == NULL); - for (which_player = 0; which_player < NUM_PLAYERS; ++which_player) - { - if (PlayerControl[which_player] & COMPUTER_CONTROL) - PlayerInput[which_player] = ComputerInput; - else if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) - { - // Full game. - if (which_player == 0) - PlayerInput[which_player] = HumanInput[0]; - else - { - PlayerInput[which_player] = ComputerInput; - PlayerControl[which_player] = COMPUTER_CONTROL | AWESOME_RATING; - } - } + switch (PlayerControl[playerI] & CONTROL_MASK) { + case HUMAN_CONTROL: + PlayerInput[playerI] = + (InputContext *) HumanInputContext_new (playerI); + break; + case COMPUTER_CONTROL: + PlayerInput[playerI] = + (InputContext *) ComputerInputContext_new (playerI); + break; #ifdef NETPLAY - else if (PlayerControl[which_player] & NETWORK_CONTROL) - PlayerInput[which_player] = NetworkInput; + case NETWORK_CONTROL: + PlayerInput[playerI] = + (InputContext *) NetworkInputContext_new (playerI); + break; #endif - else - PlayerInput[which_player] = HumanInput[which_player]; + default: + fprintf (stderr, "Invalid control method in SetPlayerInput().\n"); + explode (); /* Does not return */ } } +void +SetPlayerInputAll (void) +{ + COUNT playerI; + for (playerI = 0; playerI < NUM_PLAYERS; playerI++) + SetPlayerInput (playerI); +} + +void +ClearPlayerInput (COUNT playerI) +{ + assert (PlayerInput[playerI] != NULL); + + PlayerInput[playerI]->handlers->deleteContext (PlayerInput[playerI]); + PlayerInput[playerI] = NULL; +} + +void +ClearPlayerInputAll (void) +{ + COUNT playerI; + for (playerI = 0; playerI < NUM_PLAYERS; playerI++) + ClearPlayerInput (playerI); +} + int initIO (void) { diff --git a/sc2/src/sc2code/setup.h b/sc2/src/sc2code/setup.h index d273889e2..727f66748 100644 --- a/sc2/src/sc2code/setup.h +++ b/sc2/src/sc2code/setup.h @@ -57,14 +57,17 @@ extern ACTIVITY LastActivity; extern BYTE PlayerControl[]; extern SIZE cur_player; -extern BOOLEAN InitContexts (void); -extern void UninitPlayerInput (void); -extern BOOLEAN InitGameKernel (void); +BOOLEAN InitContexts (void); +void UninitPlayerInput (void); +BOOLEAN InitGameKernel (void); -extern int initIO (void); -extern void uninitIO (void); +int initIO (void); +void uninitIO (void); -extern void SetPlayerInput (void); +void SetPlayerInput (COUNT playerI); +void SetPlayerInputAll (void); +void ClearPlayerInput (COUNT playerI); +void ClearPlayerInputAll (void); #endif /* _SETUP_H */ diff --git a/sc2/src/sc2code/starcon.c b/sc2/src/sc2code/starcon.c index fb65671cc..028317960 100644 --- a/sc2/src/sc2code/starcon.c +++ b/sc2/src/sc2code/starcon.c @@ -150,6 +150,7 @@ while (--ac > 0) // OpenJournal (); while (StartGame ()) { + SetPlayerInputAll (); InitSIS (); InitGameClock (); @@ -248,6 +249,7 @@ while (--ac > 0) StopSound (); UninitGameClock (); UninitSIS (); + ClearPlayerInputAll (); } // CloseJournal (); diff --git a/sc2/src/sc2code/tactrans.c b/sc2/src/sc2code/tactrans.c index 8538e6165..5e8617ef9 100644 --- a/sc2/src/sc2code/tactrans.c +++ b/sc2/src/sc2code/tactrans.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "battlecontrols.h" #include "build.h" #include "collide.h" #include "globdata.h" @@ -119,7 +120,7 @@ readyToEndCallback (NetConnection *conn, void *arg) * 5. The battle ends. */ static bool -readyForBattleEndPlayer (NetConnection *conn, void *arg) +readyForBattleEndPlayer (NetConnection *conn) { BattleStateData *battleStateData; battleStateData = (BattleStateData *) NetConnection_getStateData(conn); @@ -176,11 +177,30 @@ readyForBattleEndPlayer (NetConnection *conn, void *arg) // We are ready and wait for the other party to become ready too. negotiateReady (conn, true, NetState_interBattle); - (void) arg; return true; } #endif +bool +battleEndReadyHuman (HumanInputContext *context) +{ + (void) context; + return true; +} + +bool +battleEndReadyComputer (ComputerInputContext *context) +{ + (void) context; + return true; +} + +bool +battleEndReadyNetwork (NetworkInputContext *context) +{ + return readyForBattleEndPlayer (netConnections[context->playerNr]); +} + // Returns true iff this side is ready to end the battle. static inline bool readyForBattleEnd (COUNT side) @@ -196,6 +216,8 @@ readyForBattleEnd (COUNT side) return !PLRPlaying ((MUSIC_REF)~0); #endif /* !DEMO_MODE */ #else /* defined (NETPLAY) */ + int playerI; + if (PLRPlaying ((MUSIC_REF)~0)) return false; @@ -213,8 +235,10 @@ readyForBattleEnd (COUNT side) return false; } - if (!forAllConnectedPlayers (readyForBattleEndPlayer, NULL)) - return false; + for (playerI = 0; playerI < NUM_PLAYERS; playerI++) + if (!PlayerInput[playerI]->handlers->battleEndReady ( + PlayerInput[playerI])) + return false; currentDeadSide = (COUNT)~0; // Another side may be handled. diff --git a/sc2/src/sc2code/tactrans.h b/sc2/src/sc2code/tactrans.h new file mode 100644 index 000000000..4ec8b2492 --- /dev/null +++ b/sc2/src/sc2code/tactrans.h @@ -0,0 +1,28 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +#ifndef _TACTRANS_H +#define _TACTRANS_H + +bool battleEndReadyHuman (COUNT side); +bool battleEndReadyComputer (COUNT side); +bool battleEndReadyNetwork (COUNT side); + +#endif /* _TACTRANS_H */ + + diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index b5e80f9b4..8f78f45cf 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -31,6 +31,8 @@ #include "libs/input/input_common.h" #include "libs/tasklib.h" #include "controls.h" +#include "element.h" + // For BATTLE_FRAME_RATE #include "file.h" #include "port.h" #include "libs/memlib.h"