Cleanups and some refactoring of the SuperMelee code.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3502 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
# ifdef NETPLAY_CHECKSUM
|
||||
# include "netplay/checksum.h"
|
||||
# endif
|
||||
# include "netplay/notifyall.h"
|
||||
#endif
|
||||
#include "supermelee/pickmele.h"
|
||||
#include "resinst.h"
|
||||
@@ -187,7 +188,7 @@ ProcessInput (void)
|
||||
if (!(PlayerControl[cur_player] & NETWORK_CONTROL))
|
||||
{
|
||||
BattleInputBuffer *bib = getBattleInputBuffer(cur_player);
|
||||
sendBattleInputConnections (InputState);
|
||||
Netplay_NotifyAll_battleInput (InputState);
|
||||
flushPacketQueues ();
|
||||
|
||||
BattleInputBuffer_push (bib, InputState);
|
||||
@@ -279,7 +280,7 @@ DoBattle (BATTLE_STATE *bs)
|
||||
crc_processState (&state);
|
||||
checksum = (Checksum) crc_finish (&state);
|
||||
|
||||
sendChecksumConnections ((uint32) battleFrameCount,
|
||||
Netplay_NotifyAll_checksum ((uint32) battleFrameCount,
|
||||
(uint32) checksum);
|
||||
flushPacketQueues ();
|
||||
addLocalChecksum (battleFrameCount, checksum);
|
||||
|
||||
@@ -66,8 +66,10 @@ ConfirmSaveLoad (STAMP *MsgStamp)
|
||||
t.CharCount = (COUNT)~0;
|
||||
if (MsgStamp)
|
||||
t.pStr = GAME_STRING (SAVEGAME_STRING_BASE + 0);
|
||||
// "Saving . . ."
|
||||
else
|
||||
t.pStr = GAME_STRING (SAVEGAME_STRING_BASE + 1);
|
||||
// "Loading . . ."
|
||||
TextRect (&t, &r, NULL);
|
||||
r.corner.x -= 4;
|
||||
r.corner.y -= 4;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
uqm_SUBDIRS="proto"
|
||||
uqm_CFILES="checkbuf.c checksum.c crc.c netconnection.c netinput.c netmelee.c netmisc.c netoptions.c netrcv.c netsend.c netstate.c notify.c packet.c packethandlers.c packetsenders.c packetq.c"
|
||||
uqm_CFILES="checkbuf.c checksum.c crc.c netconnection.c netinput.c netmelee.c netmisc.c netoptions.c netrcv.c netsend.c netstate.c notify.c notifyall.c packet.c packethandlers.c packetsenders.c packetq.c"
|
||||
|
||||
|
||||
@@ -61,6 +61,33 @@ removeNetConnection(int playerNr) {
|
||||
numNetConnections--;
|
||||
}
|
||||
|
||||
size_t
|
||||
getNumNetConnections(void) {
|
||||
return numNetConnections;
|
||||
}
|
||||
|
||||
// If the callback function returns 'false', the function will immediately
|
||||
// return with 'false'. Otherwise it will return 'true' after calling
|
||||
// the callback function for each connected player.
|
||||
bool
|
||||
forEachConnectedPlayer(ForEachConnectionCallback callback, void *arg) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
if (!(*callback)(conn, arg))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
closeAllConnections(void) {
|
||||
COUNT player;
|
||||
@@ -87,12 +114,6 @@ closeDisconnectedConnections(void) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
getNumNetConnections(void) {
|
||||
return numNetConnections;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -120,8 +141,7 @@ NetMelee_getBattleState(NetConnection *conn) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline
|
||||
void
|
||||
static inline void
|
||||
netInputAux(uint32 timeoutMs) {
|
||||
NetManager_process(&timeoutMs);
|
||||
// This may cause more packets to be queued, hence the
|
||||
@@ -249,42 +269,6 @@ allConnected(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
sendBattleInputConnections(BATTLE_INPUT_STATE input) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
Netplay_battleInput(conn, input);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
void
|
||||
sendChecksumConnections(uint32 frameNr, uint32 checksum) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
Netplay_sendChecksum(conn, frameNr, checksum);
|
||||
}
|
||||
}
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
|
||||
void
|
||||
initBattleStateDataConnections(void) {
|
||||
COUNT player;
|
||||
@@ -415,28 +399,6 @@ closePlayerNetworkConnection(COUNT player) {
|
||||
NetConnection_close(netConnections[player]);
|
||||
}
|
||||
|
||||
// If the callback function returns 'false', the function will immediately
|
||||
// return with 'false'. Otherwise it will return 'true' after calling
|
||||
// the callback function for each connected player.
|
||||
bool
|
||||
forAllConnectedPlayers(ForAllCallback callback, void *arg) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
if (!(*callback)(conn, arg))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
setupInputDelay(size_t localInputDelay) {
|
||||
COUNT player;
|
||||
@@ -466,51 +428,39 @@ setupInputDelay(size_t localInputDelay) {
|
||||
}
|
||||
|
||||
static bool
|
||||
sendInputDelayConnection(NetConnection *conn, const size_t *delay) {
|
||||
Netplay_sendInputDelay(conn, *delay);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
sendInputDelayConnections(size_t delay) {
|
||||
return forAllConnectedPlayers(
|
||||
(ForAllCallback) sendInputDelayConnection, &delay);
|
||||
}
|
||||
|
||||
static bool
|
||||
setStateConnection(NetConnection *conn, const NetState *state) {
|
||||
setStateConnection(NetConnection *conn, void *arg) {
|
||||
const NetState *state = (NetState *) arg;
|
||||
NetConnection_setState(conn, *state);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
setStateConnections(NetState state) {
|
||||
return forAllConnectedPlayers(
|
||||
(bool(*)(NetConnection *, void *)) setStateConnection, &state);
|
||||
return forEachConnectedPlayer(setStateConnection, &state);
|
||||
}
|
||||
|
||||
static bool
|
||||
sendAbortConnection(NetConnection *conn, const NetplayAbortReason *reason) {
|
||||
sendAbortConnection(NetConnection *conn, void *arg) {
|
||||
const NetplayAbortReason *reason = (NetplayAbortReason *) arg;
|
||||
sendAbort(conn, *reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
sendAbortConnections(NetplayAbortReason reason) {
|
||||
return forAllConnectedPlayers(
|
||||
(bool(*)(NetConnection *, void *)) sendAbortConnection, &reason);
|
||||
return forEachConnectedPlayer(sendAbortConnection, &reason);
|
||||
}
|
||||
|
||||
static bool
|
||||
resetConnection(NetConnection *conn, const NetplayResetReason *reason) {
|
||||
resetConnection(NetConnection *conn, void *arg) {
|
||||
const NetplayResetReason *reason = (NetplayResetReason *) arg;
|
||||
Netplay_localReset(conn, *reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
resetConnections(NetplayResetReason reason) {
|
||||
return forAllConnectedPlayers(
|
||||
(bool(*)(NetConnection *, void *)) resetConnection, &reason);
|
||||
return forEachConnectedPlayer(resetConnection, &reason);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -522,9 +472,10 @@ typedef struct {
|
||||
} LocalReadyConnectionArg;
|
||||
|
||||
static bool
|
||||
localReadyConnection(NetConnection *conn, LocalReadyConnectionArg *arg) {
|
||||
Netplay_localReady(conn, arg->readyCallback, arg->readyCallbackArg,
|
||||
arg->notifyRemote);
|
||||
localReadyConnection(NetConnection *conn, void *arg) {
|
||||
LocalReadyConnectionArg *readyArg = (LocalReadyConnectionArg *) arg;
|
||||
Netplay_localReady(conn, readyArg->readyCallback,
|
||||
readyArg->readyCallbackArg, readyArg->notifyRemote);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -536,8 +487,7 @@ localReadyConnections(NetConnection_ReadyCallback readyCallback,
|
||||
arg.readyCallbackArg = readyArg;
|
||||
arg.notifyRemote = notifyRemote;
|
||||
|
||||
return forAllConnectedPlayers(
|
||||
(bool(*)(NetConnection *, void *)) localReadyConnection, &arg);
|
||||
return forEachConnectedPlayer(localReadyConnection, &arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -636,7 +586,7 @@ typedef struct WaitReadyState WaitReadyState;
|
||||
struct WaitReadyState {
|
||||
// Common fields of INPUT_STATE_DESC, from which this structure
|
||||
// "inherits".
|
||||
BOOLEAN(*InputFunc)(void *pInputState);
|
||||
BOOLEAN (*InputFunc)(void *pInputState);
|
||||
|
||||
NetConnection *conn;
|
||||
NetConnection_ReadyCallback readyCallback;
|
||||
@@ -760,7 +710,7 @@ out:
|
||||
return NetConnection_isConnected(conn);
|
||||
}
|
||||
|
||||
// Wait until we have received a reset packet to all connections. If we
|
||||
// Wait until we have received a reset packet from all connections. If we
|
||||
// ourselves have not sent a reset packet, one is sent, with reason
|
||||
// 'manualReset'.
|
||||
// XXX: Right now all connections are handled one by one. Handling them all
|
||||
|
||||
@@ -40,6 +40,8 @@ void removeNetConnection(int playerNr);
|
||||
void closeAllConnections(void);
|
||||
void closeDisconnectedConnections(void);
|
||||
size_t getNumNetConnections(void);
|
||||
typedef bool(*ForEachConnectionCallback)(NetConnection *conn, void *arg);
|
||||
bool forEachConnectedPlayer(ForEachConnectionCallback callback, void *arg);
|
||||
|
||||
struct melee_state *NetMelee_getMeleeState(NetConnection *conn);
|
||||
struct battlestate_struct *NetMelee_getBattleState(NetConnection *conn);
|
||||
@@ -54,8 +56,6 @@ void connectionsLocalReady(NetConnection_ReadyCallback callback, void *arg);
|
||||
|
||||
bool allConnected(void);
|
||||
|
||||
void sendBattleInputConnections(BATTLE_INPUT_STATE input);
|
||||
void sendChecksumConnections(uint32 frameNr, uint32 checksum);
|
||||
void initBattleStateDataConnections(void);
|
||||
void setBattleStateConnections(struct battlestate_struct *bs);
|
||||
|
||||
@@ -65,11 +65,7 @@ BATTLE_INPUT_STATE networkBattleInput(NetworkInputContext *context,
|
||||
NetConnection *openPlayerNetworkConnection(COUNT player, void *extra);
|
||||
void closePlayerNetworkConnection(COUNT player);
|
||||
|
||||
typedef bool(*ForAllCallback)(NetConnection *conn, void *arg);
|
||||
bool forAllConnectedPlayers(ForAllCallback callback, void *arg);
|
||||
|
||||
bool setupInputDelay(size_t localInputDelay);
|
||||
bool sendInputDelayConnections(size_t delay);
|
||||
bool setStateConnections(NetState state);
|
||||
bool sendAbortConnections(NetplayAbortReason reason);
|
||||
bool resetConnections(NetplayResetReason reason);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "netmisc.h"
|
||||
|
||||
#include "netmelee.h"
|
||||
#include "notifyall.h"
|
||||
#include "packetsenders.h"
|
||||
#include "proto/ready.h"
|
||||
|
||||
@@ -118,8 +119,8 @@ NetMelee_enterState_inSetup(NetConnection *conn, void *arg) {
|
||||
|
||||
connectedFeedback(conn);
|
||||
|
||||
entireFleetChanged(meleeState, player);
|
||||
teamStringChanged(meleeState, player);
|
||||
Netplay_NotifyAll_setFleet(meleeState, player);
|
||||
Netplay_NotifyAll_setTeamName(meleeState, player);
|
||||
|
||||
flushPacketQueues();
|
||||
|
||||
@@ -151,13 +152,10 @@ NetMelee_reenterState_inSetup(NetConnection *conn) {
|
||||
|
||||
for (side = 0; side < NUM_SIDES; side++)
|
||||
{
|
||||
entireFleetChanged(meleeState, side);
|
||||
teamStringChanged(meleeState, side);
|
||||
Netplay_NotifyAll_setFleet(meleeState, side);
|
||||
Netplay_NotifyAll_setTeamName(meleeState, side);
|
||||
}
|
||||
flushPacketQueues();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@ netSide(NetConnection *conn, int side) {
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_selectShip(NetConnection *conn, uint16 index) {
|
||||
Netplay_Notify_shipSelected(NetConnection *conn, FleetShipIndex index) {
|
||||
assert(NetConnection_getState(conn) == NetState_selectShip);
|
||||
|
||||
sendSelectShip(conn, index);
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_battleInput(NetConnection *conn, BATTLE_INPUT_STATE input) {
|
||||
Netplay_Notify_battleInput(NetConnection *conn, BATTLE_INPUT_STATE input) {
|
||||
assert(NetConnection_getState(conn) == NetState_inBattle ||
|
||||
NetConnection_getState(conn) == NetState_endingBattle ||
|
||||
NetConnection_getState(conn) == NetState_endingBattle2);
|
||||
@@ -53,18 +53,18 @@ Netplay_battleInput(NetConnection *conn, BATTLE_INPUT_STATE input) {
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_teamStringChanged(NetConnection *conn, int player,
|
||||
Netplay_Notify_setTeamName(NetConnection *conn, int player,
|
||||
const char *name, size_t len) {
|
||||
assert(NetConnection_getState(conn) == NetState_inSetup);
|
||||
assert(!conn->stateFlags.handshake.localOk);
|
||||
|
||||
sendTeamString(conn, netSide(conn, player), name, len);
|
||||
sendTeamName(conn, netSide(conn, player), name, len);
|
||||
}
|
||||
|
||||
// On initialisation, or load.
|
||||
void
|
||||
Netplay_entireFleetChanged(NetConnection *conn, int player,
|
||||
const BYTE *fleet, size_t fleetSize) {
|
||||
Netplay_Notify_setFleet(NetConnection *conn, int player,
|
||||
const MeleeShip *fleet, size_t fleetSize) {
|
||||
assert(NetConnection_getState(conn) == NetState_inSetup);
|
||||
assert(!conn->stateFlags.handshake.localOk);
|
||||
|
||||
@@ -72,8 +72,8 @@ Netplay_entireFleetChanged(NetConnection *conn, int player,
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_fleetShipChanged(NetConnection *conn, int player,
|
||||
size_t index, BYTE ship) {
|
||||
Netplay_Notify_setShip(NetConnection *conn, int player,
|
||||
FleetShipIndex index, MeleeShip ship) {
|
||||
assert(NetConnection_getState(conn) == NetState_inSetup);
|
||||
assert(!conn->stateFlags.handshake.localOk);
|
||||
|
||||
@@ -81,7 +81,7 @@ Netplay_fleetShipChanged(NetConnection *conn, int player,
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_seedRandom(NetConnection *conn, uint32 seed) {
|
||||
Netplay_Notify_seedRandom(NetConnection *conn, uint32 seed) {
|
||||
assert(NetConnection_getState(conn) == NetState_preBattle);
|
||||
|
||||
sendSeedRandom(conn, seed);
|
||||
@@ -89,14 +89,15 @@ Netplay_seedRandom(NetConnection *conn, uint32 seed) {
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_sendInputDelay(NetConnection *conn, uint32 delay) {
|
||||
Netplay_Notify_inputDelay(NetConnection *conn, uint32 delay) {
|
||||
assert(NetConnection_getState(conn) == NetState_preBattle);
|
||||
|
||||
sendInputDelay(conn, delay);
|
||||
}
|
||||
|
||||
void
|
||||
Netplay_sendFrameCount(NetConnection *conn, BattleFrameCounter frameCount) {
|
||||
Netplay_Notify_frameCount(NetConnection *conn,
|
||||
BattleFrameCounter frameCount) {
|
||||
assert(NetConnection_getState(conn) == NetState_endingBattle);
|
||||
|
||||
sendFrameCount(conn, frameCount);
|
||||
@@ -104,7 +105,7 @@ Netplay_sendFrameCount(NetConnection *conn, BattleFrameCounter frameCount) {
|
||||
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
void
|
||||
Netplay_sendChecksum(NetConnection *conn, BattleFrameCounter frameNr,
|
||||
Netplay_Notify_checksum(NetConnection *conn, BattleFrameCounter frameNr,
|
||||
Checksum checksum) {
|
||||
assert(NetState_battleActive(NetConnection_getState(conn)));
|
||||
|
||||
|
||||
@@ -27,21 +27,26 @@
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
# include "checksum.h"
|
||||
#endif
|
||||
#include "../supermelee/meleeship.h"
|
||||
// for MeleeShip
|
||||
#include "../supermelee/meleesetup.h"
|
||||
// for FleetShipIndex
|
||||
|
||||
void Netplay_selectShip(NetConnection *conn, uint16 index);
|
||||
void Netplay_battleInput(NetConnection *conn, BATTLE_INPUT_STATE input);
|
||||
void Netplay_teamStringChanged(NetConnection *conn, int player,
|
||||
void Netplay_Notify_shipSelected(NetConnection *conn, FleetShipIndex index);
|
||||
void Netplay_Notify_battleInput(NetConnection *conn,
|
||||
BATTLE_INPUT_STATE input);
|
||||
void Netplay_Notify_setTeamName(NetConnection *conn, int player,
|
||||
const char *name, size_t len);
|
||||
void Netplay_entireFleetChanged(NetConnection *conn, int player,
|
||||
const BYTE *fleet, size_t fleetSize);
|
||||
void Netplay_fleetShipChanged(NetConnection *conn, int player,
|
||||
size_t index, BYTE ship);
|
||||
void Netplay_seedRandom(NetConnection *conn, uint32 seed);
|
||||
void Netplay_sendInputDelay(NetConnection *conn, uint32 delay);
|
||||
void Netplay_sendFrameCount(NetConnection *conn,
|
||||
void Netplay_Notify_setFleet(NetConnection *conn, int player,
|
||||
const MeleeShip *fleet, size_t fleetSize);
|
||||
void Netplay_Notify_setShip(NetConnection *conn, int player,
|
||||
FleetShipIndex index, MeleeShip ship);
|
||||
void Netplay_Notify_seedRandom(NetConnection *conn, uint32 seed);
|
||||
void Netplay_Notify_inputDelay(NetConnection *conn, uint32 delay);
|
||||
void Netplay_Notify_frameCount(NetConnection *conn,
|
||||
BattleFrameCounter frameCount);
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
void Netplay_sendChecksum(NetConnection *conn,
|
||||
void Netplay_Notify_checksum(NetConnection *conn,
|
||||
BattleFrameCounter frameCount, Checksum checksum);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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 "notifyall.h"
|
||||
|
||||
#include "netmelee.h"
|
||||
#include "notify.h"
|
||||
|
||||
// Notify the network connections of a team name change.
|
||||
void
|
||||
Netplay_NotifyAll_setTeamName (MELEE_STATE *pMS, size_t playerNr)
|
||||
{
|
||||
const char *name;
|
||||
size_t len;
|
||||
size_t playerI;
|
||||
|
||||
name = MeleeSetup_getTeamName (pMS->meleeSetup, playerNr);
|
||||
len = strlen (name);
|
||||
for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
|
||||
{
|
||||
NetConnection *conn = netConnections[playerI];
|
||||
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected (conn))
|
||||
continue;
|
||||
|
||||
if (NetConnection_getState (conn) != NetState_inSetup)
|
||||
continue;
|
||||
|
||||
Netplay_Notify_setTeamName (conn, playerNr, name, len);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the network connections of the configuration of a fleet.
|
||||
void
|
||||
Netplay_NotifyAll_setFleet (MELEE_STATE *pMS, size_t playerNr)
|
||||
{
|
||||
MeleeSetup *setup = pMS->meleeSetup;
|
||||
const MeleeShip *ships = MeleeSetup_getFleet (setup, playerNr);
|
||||
size_t playerI;
|
||||
|
||||
for (playerI = 0; playerI < NUM_PLAYERS; playerI++) {
|
||||
NetConnection *conn = netConnections[playerI];
|
||||
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected (conn))
|
||||
continue;
|
||||
|
||||
if (NetConnection_getState (conn) != NetState_inSetup)
|
||||
continue;
|
||||
|
||||
Netplay_Notify_setFleet (conn, playerNr, ships, MELEE_FLEET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the network of a change in the configuration of a fleet.
|
||||
void
|
||||
Netplay_NotifyAll_setShip (MELEE_STATE *pMS, size_t playerNr, size_t index)
|
||||
{
|
||||
MeleeSetup *setup = pMS->meleeSetup;
|
||||
MeleeShip ship = MeleeSetup_getShip (setup, playerNr, index);
|
||||
|
||||
size_t playerI;
|
||||
for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
|
||||
{
|
||||
NetConnection *conn = netConnections[playerI];
|
||||
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected (conn))
|
||||
continue;
|
||||
|
||||
if (NetConnection_getState (conn) != NetState_inSetup)
|
||||
continue;
|
||||
|
||||
Netplay_Notify_setShip (conn, playerNr, index, ship);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
Netplay_NotifyAll_inputDelayCallback(NetConnection *conn, void *arg) {
|
||||
const size_t *delay = (size_t *) arg;
|
||||
Netplay_Notify_inputDelay(conn, *delay);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Netplay_NotifyAll_inputDelay(size_t delay) {
|
||||
return forEachConnectedPlayer(Netplay_NotifyAll_inputDelayCallback,
|
||||
&delay);
|
||||
}
|
||||
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
void
|
||||
Netplay_NotifyAll_checksum(BattleFrameCounter frameNr, Checksum checksum) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
Netplay_Notify_checksum(conn, frameNr, checksum);
|
||||
}
|
||||
}
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
|
||||
void
|
||||
Netplay_NotifyAll_battleInput(BATTLE_INPUT_STATE input) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
if (!NetConnection_isConnected(conn))
|
||||
continue;
|
||||
|
||||
Netplay_Notify_battleInput(conn, input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 NOTIFYALL_H
|
||||
#define NOTIFYALL_H
|
||||
|
||||
#include "../battle.h"
|
||||
#include "../battlecontrols.h"
|
||||
#include "../supermelee/melee.h"
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
# include "checksum.h"
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
|
||||
void Netplay_NotifyAll_setTeamName (MELEE_STATE *pMS, size_t playerNr);
|
||||
void Netplay_NotifyAll_setFleet (MELEE_STATE *pMS, size_t playerNr);
|
||||
void Netplay_NotifyAll_setShip (MELEE_STATE *pMS, size_t playerNr,
|
||||
size_t index);
|
||||
|
||||
bool Netplay_NotifyAll_inputDelay(size_t delay);
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
void Netplay_NotifyAll_checksum(BattleFrameCounter frameNr,
|
||||
Checksum checksum);
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
void Netplay_NotifyAll_battleInput(BATTLE_INPUT_STATE input);
|
||||
|
||||
|
||||
#endif /* NOTIFYALL_H */
|
||||
|
||||
@@ -174,7 +174,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
uint8 index; /* Position in the fleet */
|
||||
uint8 ship; /* Ship type index */
|
||||
uint8 ship; /* Ship type index; actually MeleeShip */
|
||||
} FleetEntry;
|
||||
// Structure describing an update to a player's fleet.
|
||||
// TODO: use strings as ship identifiers, instead of numbers,
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
// for GLOBAL
|
||||
#include "../supermelee/melee.h"
|
||||
// for various update functions.
|
||||
#include "../supermelee/meleeship.h"
|
||||
// for MeleeShip
|
||||
#include "../supermelee/pickmele.h"
|
||||
// for various update functions.
|
||||
#include "libs/mathlib.h"
|
||||
@@ -263,16 +265,26 @@ PacketHandler_Fleet(NetConnection *conn, const Packet_Fleet *packet) {
|
||||
}
|
||||
|
||||
for (i = 0; i < numShips; i++) {
|
||||
int ship = packet->ships[i].ship;
|
||||
int index = packet->ships[i].index;
|
||||
MeleeShip ship = (MeleeShip) packet->ships[i].ship;
|
||||
FleetShipIndex index = (FleetShipIndex) packet->ships[i].index;
|
||||
|
||||
bool updateResult = updateFleetShip(
|
||||
battleStateData->meleeState, player, index, ship);
|
||||
if (!updateResult)
|
||||
{
|
||||
if (!MeleeShip_valid(ship)) {
|
||||
log_add (log_Warning, "Invalid ship type number %d (max = %d).\n",
|
||||
ship, NUM_MELEE_SHIPS - 1);
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (index >= MELEE_FLEET_SIZE)
|
||||
{
|
||||
log_add (log_Warning, "Invalid ship position number %d "
|
||||
"(max = %d).\n", index, MELEE_FLEET_SIZE - 1);
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Melee_RemoteChange_ship (battleStateData->meleeState, conn,
|
||||
player, index, ship);
|
||||
}
|
||||
|
||||
// Padding data may follow; it is ignored.
|
||||
@@ -312,8 +324,17 @@ PacketHandler_TeamName(NetConnection *conn, const Packet_TeamName *packet) {
|
||||
- sizeof (Packet_TeamName) - 1;
|
||||
// The -1 is for not counting the terminating '\0'.
|
||||
|
||||
updateTeamName(battleStateData->meleeState, side,
|
||||
(const char *) packet->name, nameLen);
|
||||
{
|
||||
char buf[MAX_TEAM_CHARS + 1];
|
||||
|
||||
if (nameLen > MAX_TEAM_CHARS)
|
||||
nameLen = MAX_TEAM_CHARS;
|
||||
memcpy (buf, (const char *) packet->name, nameLen);
|
||||
buf[nameLen] = '\0';
|
||||
|
||||
Melee_RemoteChange_teamName(battleStateData->meleeState, conn,
|
||||
side, buf);
|
||||
}
|
||||
|
||||
// Padding data may follow; it is ignored.
|
||||
return 0;
|
||||
|
||||
@@ -107,7 +107,7 @@ sendHandshakeCancelAck(NetConnection *conn) {
|
||||
}
|
||||
|
||||
void
|
||||
sendTeamString(NetConnection *conn, NetplaySide side, const char *name,
|
||||
sendTeamName(NetConnection *conn, NetplaySide side, const char *name,
|
||||
size_t len) {
|
||||
Packet_TeamName *packet;
|
||||
|
||||
@@ -116,30 +116,30 @@ sendTeamString(NetConnection *conn, NetplaySide side, const char *name,
|
||||
}
|
||||
|
||||
void
|
||||
sendFleet(NetConnection *conn, NetplaySide side, const BYTE *ships,
|
||||
size_t numShips) {
|
||||
sendFleet(NetConnection *conn, NetplaySide side, const MeleeShip *ships,
|
||||
size_t shipCount) {
|
||||
size_t i;
|
||||
Packet_Fleet *packet;
|
||||
|
||||
packet = Packet_Fleet_create(side, numShips);
|
||||
packet = Packet_Fleet_create(side, shipCount);
|
||||
|
||||
for (i = 0; i < numShips; i++) {
|
||||
for (i = 0; i < shipCount; i++) {
|
||||
packet->ships[i].index = (uint8) i;
|
||||
packet->ships[i].ship = ships[i];
|
||||
packet->ships[i].ship = (uint8) ships[i];
|
||||
}
|
||||
|
||||
queuePacket(conn, (Packet *) packet, false);
|
||||
}
|
||||
|
||||
void
|
||||
sendFleetShip(NetConnection *conn, NetplaySide side, size_t shipIndex,
|
||||
BYTE ship) {
|
||||
sendFleetShip(NetConnection *conn, NetplaySide side,
|
||||
FleetShipIndex shipIndex, MeleeShip ship) {
|
||||
Packet_Fleet *packet;
|
||||
|
||||
packet = Packet_Fleet_create(side, 1);
|
||||
|
||||
packet->ships[0].index = shipIndex;
|
||||
packet->ships[0].ship = ship;
|
||||
packet->ships[0].index = (uint8) shipIndex;
|
||||
packet->ships[0].ship = (uint8) ship;
|
||||
|
||||
queuePacket(conn, (Packet *) packet, false);
|
||||
}
|
||||
@@ -161,10 +161,10 @@ sendInputDelay(NetConnection *conn, uint32 delay) {
|
||||
}
|
||||
|
||||
void
|
||||
sendSelectShip(NetConnection *conn, COUNT ship) {
|
||||
sendSelectShip(NetConnection *conn, FleetShipIndex index) {
|
||||
Packet_SelectShip *packet;
|
||||
|
||||
packet = Packet_SelectShip_create(ship);
|
||||
packet = Packet_SelectShip_create((uint16) index);
|
||||
queuePacket(conn, (Packet *) packet, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
|
||||
#include "../controls.h"
|
||||
// for BATTLE_INPUT_STATE
|
||||
#include "../supermelee/meleeship.h"
|
||||
// for MeleeShip
|
||||
#include "../supermelee/meleesetup.h"
|
||||
// for FleetShipIndex
|
||||
|
||||
void sendInit(NetConnection *conn);
|
||||
void sendPing(NetConnection *conn, uint32 id);
|
||||
@@ -37,18 +41,19 @@ void sendHandshake0(NetConnection *conn);
|
||||
void sendHandshake1(NetConnection *conn);
|
||||
void sendHandshakeCancel(NetConnection *conn);
|
||||
void sendHandshakeCancelAck(NetConnection *conn);
|
||||
void sendTeamString(NetConnection *conn, NetplaySide side,
|
||||
void sendTeamName(NetConnection *conn, NetplaySide side,
|
||||
const char *name, size_t len);
|
||||
void sendFleet(NetConnection *conn, NetplaySide side, const BYTE *ships,
|
||||
size_t numShips);
|
||||
void sendFleet(NetConnection *conn, NetplaySide side,
|
||||
const MeleeShip *ships, size_t numShips);
|
||||
void sendFleetShip(NetConnection *conn, NetplaySide player,
|
||||
size_t shipIndex, BYTE ship);
|
||||
FleetShipIndex shipIndex, MeleeShip ship);
|
||||
void sendSeedRandom(NetConnection *conn, uint32 seed);
|
||||
void sendInputDelay(NetConnection *conn, uint32 delay);
|
||||
void sendSelectShip(NetConnection *conn, COUNT ship);
|
||||
void sendSelectShip(NetConnection *conn, FleetShipIndex index);
|
||||
void sendBattleInput(NetConnection *conn, BATTLE_INPUT_STATE input);
|
||||
void sendFrameCount(NetConnection *conn, uint32 frameCount);
|
||||
void sendChecksum(NetConnection *conn, uint32 frameNr, uint32 checksum);
|
||||
void sendFrameCount(NetConnection *conn, BattleFrameCounter frameCount);
|
||||
void sendChecksum(NetConnection *conn, BattleFrameCounter frameNr,
|
||||
Checksum checksum);
|
||||
void sendAbort(NetConnection *conn, NetplayAbortReason reason);
|
||||
void sendReset(NetConnection *conn, NetplayResetReason reason);
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uqm_CFILES="loadmele.c melee.c pickmele.c"
|
||||
uqm_CFILES="buildpick.c loadmele.c melee.c meleesetup.c pickmele.c"
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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 "buildpick.h"
|
||||
|
||||
#include "../controls.h"
|
||||
#include "../colors.h"
|
||||
#include "../fmv.h"
|
||||
#include "../master.h"
|
||||
#include "../setup.h"
|
||||
#include "../sounds.h"
|
||||
#include "libs/gfxlib.h"
|
||||
|
||||
static FRAME BuildPickFrame;
|
||||
|
||||
void
|
||||
BuildBuildPickFrame (void)
|
||||
{
|
||||
STAMP s;
|
||||
RECT r;
|
||||
COUNT i;
|
||||
CONTEXT OldContext = SetContext (OffScreenContext);
|
||||
|
||||
// create team building ship selection box
|
||||
s.origin.x = 0;
|
||||
s.origin.y = 0;
|
||||
s.frame = SetAbsFrameIndex (MeleeFrame, 27);
|
||||
// 5x5 grid of ships to pick from
|
||||
GetFrameRect (s.frame, &r);
|
||||
|
||||
BuildPickFrame = CaptureDrawable (CreateDrawable (
|
||||
WANT_PIXMAP, r.extent.width, r.extent.height, 1));
|
||||
SetContextFGFrame (BuildPickFrame);
|
||||
SetFrameHot (s.frame, MAKE_HOT_SPOT (0, 0));
|
||||
DrawStamp (&s);
|
||||
|
||||
for (i = 0; i < NUM_PICK_COLS * NUM_PICK_ROWS; ++i)
|
||||
DrawPickIcon (i, true);
|
||||
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
void
|
||||
DestroyBuildPickFrame (void)
|
||||
{
|
||||
DestroyDrawable (ReleaseDrawable (BuildPickFrame));
|
||||
BuildPickFrame = 0;
|
||||
}
|
||||
|
||||
// Draw a ship icon in the ship selection popup.
|
||||
void
|
||||
DrawPickIcon (MeleeShip ship, bool DrawErase)
|
||||
{
|
||||
STAMP s;
|
||||
RECT r;
|
||||
|
||||
GetFrameRect (BuildPickFrame, &r);
|
||||
|
||||
s.origin.x = r.corner.x + 20 + (ship % NUM_PICK_COLS) * 18;
|
||||
s.origin.y = r.corner.y + 5 + (ship / NUM_PICK_COLS) * 18;
|
||||
s.frame = GetShipIconsFromIndex (ship);
|
||||
if (DrawErase)
|
||||
{ // draw icon
|
||||
DrawStamp (&s);
|
||||
}
|
||||
else
|
||||
{ // erase icon
|
||||
Color OldColor;
|
||||
|
||||
OldColor = SetContextForeGroundColor (BLACK_COLOR);
|
||||
DrawFilledStamp (&s);
|
||||
SetContextForeGroundColor (OldColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Pre: the called holds the GraphicsLock
|
||||
void
|
||||
DrawPickFrame (MELEE_STATE *pMS)
|
||||
{
|
||||
RECT r, r0, r1, ship_r;
|
||||
STAMP s;
|
||||
|
||||
GetShipBox (&r0, 0, 0, 0),
|
||||
GetShipBox (&r1, 1, NUM_MELEE_ROWS - 1, NUM_MELEE_COLUMNS - 1),
|
||||
BoxUnion (&r0, &r1, &ship_r);
|
||||
|
||||
s.frame = SetAbsFrameIndex (BuildPickFrame, 0);
|
||||
GetFrameRect (s.frame, &r);
|
||||
r.corner.x = -(ship_r.corner.x
|
||||
+ ((ship_r.extent.width - r.extent.width) >> 1));
|
||||
if (pMS->side)
|
||||
r.corner.y = -ship_r.corner.y;
|
||||
else
|
||||
r.corner.y = -(ship_r.corner.y
|
||||
+ (ship_r.extent.height - r.extent.height));
|
||||
SetFrameHot (s.frame, MAKE_HOT_SPOT (r.corner.x, r.corner.y));
|
||||
s.origin.x = 0;
|
||||
s.origin.y = 0;
|
||||
DrawStamp (&s);
|
||||
DrawMeleeShipStrings (pMS, pMS->currentShip);
|
||||
}
|
||||
|
||||
void
|
||||
GetBuildPickFrameRect (RECT *r)
|
||||
{
|
||||
GetFrameRect (BuildPickFrame, r);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
DoPickShip (MELEE_STATE *pMS)
|
||||
{
|
||||
DWORD TimeIn = GetTimeCounter ();
|
||||
|
||||
/* Cancel any presses of the Pause key. */
|
||||
GamePaused = FALSE;
|
||||
|
||||
if (GLOBAL (CurrentActivity) & CHECK_ABORT)
|
||||
{
|
||||
pMS->buildPickConfirmed = false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_SELECT] ||
|
||||
PulsedInputState.menu[KEY_MENU_CANCEL])
|
||||
{
|
||||
// Confirm selection or cancel.
|
||||
pMS->buildPickConfirmed = !PulsedInputState.menu[KEY_MENU_CANCEL];
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_SPECIAL]
|
||||
&& (pMS->currentShip != MELEE_NONE))
|
||||
{
|
||||
// Show ship spin video.
|
||||
DoShipSpin (pMS->currentShip, (MUSIC_REF) 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
MeleeShip newSelectedShip;
|
||||
|
||||
newSelectedShip = pMS->currentShip;
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_LEFT])
|
||||
{
|
||||
if (newSelectedShip % NUM_PICK_COLS == 0)
|
||||
newSelectedShip += NUM_PICK_COLS;
|
||||
--newSelectedShip;
|
||||
}
|
||||
else if (PulsedInputState.menu[KEY_MENU_RIGHT])
|
||||
{
|
||||
++newSelectedShip;
|
||||
if (newSelectedShip % NUM_PICK_COLS == 0)
|
||||
newSelectedShip -= NUM_PICK_COLS;
|
||||
}
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_UP])
|
||||
{
|
||||
if (newSelectedShip >= NUM_PICK_COLS)
|
||||
newSelectedShip -= NUM_PICK_COLS;
|
||||
else
|
||||
newSelectedShip += NUM_PICK_COLS * (NUM_PICK_ROWS - 1);
|
||||
}
|
||||
else if (PulsedInputState.menu[KEY_MENU_DOWN])
|
||||
{
|
||||
if (newSelectedShip < NUM_PICK_COLS * (NUM_PICK_ROWS - 1))
|
||||
newSelectedShip += NUM_PICK_COLS;
|
||||
else
|
||||
newSelectedShip -= NUM_PICK_COLS * (NUM_PICK_ROWS - 1);
|
||||
}
|
||||
|
||||
if (newSelectedShip != pMS->currentShip)
|
||||
{
|
||||
// A new ship has been selected.
|
||||
LockMutex (GraphicsLock);
|
||||
DrawPickIcon (pMS->currentShip, true);
|
||||
pMS->currentShip = newSelectedShip;
|
||||
DrawMeleeShipStrings (pMS, newSelectedShip);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
}
|
||||
|
||||
Melee_flashSelection (pMS);
|
||||
|
||||
SleepThreadUntil (TimeIn + ONE_SECOND / 30);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Returns true if a ship has been selected, or false if the operation has
|
||||
// been cancelled or if the general abort key was pressed (in which case
|
||||
// 'GLOBAL (CurrentActivity) & CHECK_ABORT' is true as usual.
|
||||
// If a ship was selected, pMS->currentShip is set to the selected ship.
|
||||
bool
|
||||
BuildPickShip (MELEE_STATE *pMS)
|
||||
{
|
||||
FlushInput ();
|
||||
|
||||
if (pMS->currentShip == MELEE_NONE)
|
||||
pMS->currentShip = 0;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
DrawPickFrame (pMS);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
pMS->InputFunc = DoPickShip;
|
||||
DoInput (pMS, FALSE);
|
||||
|
||||
return pMS->buildPickConfirmed;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef BUILDPICK_H
|
||||
#define BUILDPICK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "melee.h"
|
||||
|
||||
void BuildBuildPickFrame (void);
|
||||
void DestroyBuildPickFrame (void);
|
||||
bool BuildPickShip (MELEE_STATE *pMS);
|
||||
void GetBuildPickFrameRect (RECT *r);
|
||||
|
||||
void DrawPickFrame (MELEE_STATE *pMS);
|
||||
void DrawPickIcon (MeleeShip ship, bool DrawErase);
|
||||
|
||||
|
||||
#endif /* BUILDPICK_H */
|
||||
|
||||
+250
-283
@@ -18,6 +18,7 @@
|
||||
|
||||
// This file handles loading of teams, but the UI and the actual loading.
|
||||
|
||||
#define MELEESETUP_INTERNAL
|
||||
#include "melee.h"
|
||||
|
||||
#include "../controls.h"
|
||||
@@ -25,10 +26,11 @@
|
||||
#include "../gamestr.h"
|
||||
#include "../globdata.h"
|
||||
#include "../master.h"
|
||||
#include "meleesetup.h"
|
||||
#include "../save.h"
|
||||
#include "../setup.h"
|
||||
#include "../sounds.h"
|
||||
#include "../../options.h"
|
||||
#include "options.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
|
||||
@@ -48,53 +50,23 @@ static void DrawFileStrings (MELEE_STATE *pMS);
|
||||
static bool FillFileView (MELEE_STATE *pMS);
|
||||
|
||||
|
||||
bool
|
||||
ReadTeamImage (TEAM_IMAGE *pTI, uio_Stream *load_fp)
|
||||
{
|
||||
int status;
|
||||
FleetShipIndex i;
|
||||
|
||||
status = ReadResFile (pTI, sizeof (*pTI), 1, load_fp);
|
||||
if (status != 1)
|
||||
return false;
|
||||
|
||||
// Sanity check on the entries.
|
||||
for (i = 0; i < MELEE_FLEET_SIZE; i++)
|
||||
{
|
||||
BYTE StarShip = pTI->ShipList[i];
|
||||
|
||||
if (StarShip == MELEE_NONE)
|
||||
continue;
|
||||
|
||||
if (StarShip >= NUM_MELEE_SHIPS)
|
||||
{
|
||||
log_add (log_Warning, "Invalid ship type in loaded team (index "
|
||||
"%d, ship type is %d, max valid is %d).",
|
||||
i, StarShip, NUM_MELEE_SHIPS - 1);
|
||||
pTI->ShipList[i] = MELEE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
LoadTeamImage (DIRENTRY DirEntry, TEAM_IMAGE *pTI)
|
||||
LoadTeamImage (DIRENTRY DirEntry, MeleeTeam *team)
|
||||
{
|
||||
const BYTE *fileName;
|
||||
uio_Stream *load_fp;
|
||||
const char *fileName;
|
||||
uio_Stream *stream;
|
||||
bool status;
|
||||
|
||||
fileName = GetDirEntryAddress (DirEntry);
|
||||
load_fp = res_OpenResFile (meleeDir, (const char *) fileName, "rb");
|
||||
if (load_fp == 0)
|
||||
|
||||
stream = uio_fopen (meleeDir, fileName, "rb");
|
||||
if (stream == NULL)
|
||||
return false;
|
||||
|
||||
if (LengthResFile (load_fp) != sizeof (*pTI))
|
||||
status = false;
|
||||
else
|
||||
status = ReadTeamImage (pTI, load_fp);
|
||||
res_CloseResFile (load_fp);
|
||||
if (MeleeTeam_deserialize (team, stream) == -1)
|
||||
return false;
|
||||
|
||||
uio_fclose (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -123,13 +95,13 @@ UnindexFleets (MELEE_STATE *pMS, COUNT index, COUNT count)
|
||||
}
|
||||
|
||||
static bool
|
||||
GetFleetByIndex (MELEE_STATE *pMS, COUNT index, TEAM_IMAGE *result)
|
||||
GetFleetByIndex (MELEE_STATE *pMS, COUNT index, MeleeTeam *result)
|
||||
{
|
||||
COUNT firstIndex;
|
||||
|
||||
if (index < pMS->load.preBuiltCount)
|
||||
{
|
||||
*result = pMS->load.preBuiltList[index];
|
||||
MeleeTeam_copy (result, pMS->load.preBuiltList[index]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -144,7 +116,7 @@ GetFleetByIndex (MELEE_STATE *pMS, COUNT index, TEAM_IMAGE *result)
|
||||
break; // Success
|
||||
|
||||
{
|
||||
const BYTE *fileName;
|
||||
const char *fileName;
|
||||
fileName = GetDirEntryAddress (entry);
|
||||
log_add (log_Warning, "Warning: File '%s' is not a valid "
|
||||
"SuperMelee team.", fileName);
|
||||
@@ -167,7 +139,7 @@ GetFleetIndexByFileName (MELEE_STATE *pMS, const char *fileName)
|
||||
{
|
||||
DIRENTRY entry = SetAbsDirEntryTableIndex (pMS->load.dirEntries,
|
||||
pMS->load.entryIndices[index]);
|
||||
const BYTE *entryName = GetDirEntryAddress (entry);
|
||||
const char *entryName = GetDirEntryAddress (entry);
|
||||
|
||||
if (strcasecmp ((const char *) entryName, fileName) == 0)
|
||||
return pMS->load.preBuiltCount + index;
|
||||
@@ -181,8 +153,8 @@ GetFleetIndexByFileName (MELEE_STATE *pMS, const char *fileName)
|
||||
// fleet name and value; if not, only the fleet name and value are drawn.
|
||||
// If highlite is set the text is drawn in the color used for highlighting.
|
||||
static void
|
||||
DrawFileString (TEAM_IMAGE *pTI, POINT *origin, BOOLEAN drawShips,
|
||||
BOOLEAN highlite)
|
||||
DrawFileString (const MeleeTeam *team, const POINT *origin,
|
||||
BOOLEAN drawShips, BOOLEAN highlite)
|
||||
{
|
||||
SetContextForeGroundColor (highlite ?
|
||||
LOAD_TEAM_NAME_TEXT_COLOR_HILITE : LOAD_TEAM_NAME_TEXT_COLOR);
|
||||
@@ -193,7 +165,7 @@ DrawFileString (TEAM_IMAGE *pTI, POINT *origin, BOOLEAN drawShips,
|
||||
|
||||
Text.baseline = *origin;
|
||||
Text.align = ALIGN_LEFT;
|
||||
Text.pStr = pTI->TeamName;
|
||||
Text.pStr = MeleeTeam_getTeamName(team);
|
||||
Text.CharCount = (COUNT)~0;
|
||||
font_DrawText (&Text);
|
||||
}
|
||||
@@ -203,7 +175,7 @@ DrawFileString (TEAM_IMAGE *pTI, POINT *origin, BOOLEAN drawShips,
|
||||
TEXT Text;
|
||||
UNICODE buf[60];
|
||||
|
||||
sprintf (buf, "%u", GetTeamValue (pTI));
|
||||
sprintf (buf, "%u", MeleeTeam_getValue (team));
|
||||
Text.baseline = *origin;
|
||||
Text.baseline.x += NUM_MELEE_COLUMNS *
|
||||
(LOAD_MELEE_BOX_WIDTH + LOAD_MELEE_BOX_SPACE) - 1;
|
||||
@@ -217,15 +189,15 @@ DrawFileString (TEAM_IMAGE *pTI, POINT *origin, BOOLEAN drawShips,
|
||||
if (drawShips)
|
||||
{
|
||||
STAMP s;
|
||||
FleetShipIndex index;
|
||||
FleetShipIndex slotI;
|
||||
|
||||
s.origin.x = origin->x + 1;
|
||||
s.origin.y = origin->y + 4;
|
||||
for (index = 0; index < MELEE_FLEET_SIZE; index++)
|
||||
for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++)
|
||||
{
|
||||
BYTE StarShip;
|
||||
|
||||
StarShip = pTI->ShipList[index];
|
||||
StarShip = team->ships[slotI];
|
||||
if (StarShip != MELEE_NONE)
|
||||
{
|
||||
s.frame = GetShipIconsFromIndex (StarShip);
|
||||
@@ -247,7 +219,7 @@ FillFileView (MELEE_STATE *pMS)
|
||||
for (viewI = 0; viewI < LOAD_TEAM_VIEW_SIZE; viewI++)
|
||||
{
|
||||
bool success = GetFleetByIndex (pMS, pMS->load.top + viewI,
|
||||
&pMS->load.view[viewI]);
|
||||
pMS->load.view[viewI]);
|
||||
if (!success)
|
||||
break;
|
||||
}
|
||||
@@ -278,7 +250,7 @@ SelectFileString (MELEE_STATE *pMS, bool hilite)
|
||||
|
||||
origin.x = FILE_STRING_ORIGIN_X;
|
||||
origin.y = FILE_STRING_ORIGIN_Y + viewI * ENTRY_HEIGHT;
|
||||
DrawFileString (&pMS->load.view[viewI], &origin, FALSE, hilite);
|
||||
DrawFileString (pMS->load.view[viewI], &origin, FALSE, hilite);
|
||||
|
||||
UnbatchGraphics ();
|
||||
SetContext (OldContext);
|
||||
@@ -303,7 +275,7 @@ DrawFileStrings (MELEE_STATE *pMS)
|
||||
{
|
||||
COUNT i;
|
||||
for (i = pMS->load.top; i < pMS->load.bot; i++) {
|
||||
DrawFileString (&pMS->load.view[i - pMS->load.top], &origin,
|
||||
DrawFileString (pMS->load.view[i - pMS->load.top], &origin,
|
||||
TRUE, FALSE);
|
||||
origin.y += ENTRY_HEIGHT;
|
||||
}
|
||||
@@ -379,12 +351,8 @@ DoLoadTeam (MELEE_STATE *pMS)
|
||||
if (PulsedInputState.menu[KEY_MENU_SELECT])
|
||||
{
|
||||
// Copy the selected fleet to the player.
|
||||
pMS->SideState[pMS->side].TeamImage =
|
||||
pMS->load.view[pMS->load.cur - pMS->load.top];
|
||||
pMS->SideState[pMS->side].star_bucks =
|
||||
GetTeamValue (&pMS->SideState[pMS->side].TeamImage);
|
||||
entireFleetChanged (pMS, pMS->side);
|
||||
teamStringChanged (pMS, pMS->side);
|
||||
Melee_Change_team (pMS, pMS->side,
|
||||
pMS->load.view[pMS->load.cur - pMS->load.top]);
|
||||
}
|
||||
|
||||
pMS->InputFunc = DoMelee;
|
||||
@@ -470,12 +438,6 @@ DoLoadTeam (MELEE_STATE *pMS)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
WriteTeamImage (TEAM_IMAGE *pTI, uio_Stream *save_fp)
|
||||
{
|
||||
return WriteResFile (pTI, sizeof (*pTI), 1, save_fp);
|
||||
}
|
||||
|
||||
void
|
||||
SelectTeamByFileName (MELEE_STATE *pMS, const char *fileName)
|
||||
{
|
||||
@@ -509,73 +471,67 @@ DoSaveTeam (MELEE_STATE *pMS)
|
||||
{
|
||||
STAMP MsgStamp;
|
||||
char file[NAME_MAX];
|
||||
uio_Stream *save_fp;
|
||||
uio_Stream *stream;
|
||||
CONTEXT OldContext;
|
||||
bool saveOk = false;
|
||||
|
||||
sprintf (file, "%s.mle", pMS->SideState[pMS->side].TeamImage.TeamName);
|
||||
snprintf (file, sizeof file, "%s.mle",
|
||||
MeleeSetup_getTeamName (pMS->meleeSetup, pMS->side));
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
OldContext = SetContext (ScreenContext);
|
||||
ConfirmSaveLoad (&MsgStamp);
|
||||
save_fp = res_OpenResFile (meleeDir, file, "wb");
|
||||
if (save_fp)
|
||||
{
|
||||
BOOLEAN err;
|
||||
// Show the "Saving . . ." message.
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
err = (BOOLEAN)(WriteTeamImage (
|
||||
&pMS->SideState[pMS->side].TeamImage, save_fp) == 0);
|
||||
if (res_CloseResFile (save_fp) == 0)
|
||||
err = TRUE;
|
||||
if (err)
|
||||
save_fp = 0;
|
||||
stream = uio_fopen (meleeDir, file, "wb");
|
||||
if (stream != NULL)
|
||||
{
|
||||
saveOk = (MeleeTeam_serialize (&pMS->meleeSetup->teams[pMS->side],
|
||||
stream) == 0);
|
||||
uio_fclose (stream);
|
||||
|
||||
if (!saveOk)
|
||||
uio_unlink (meleeDir, file);
|
||||
}
|
||||
|
||||
pMS->load.top = 0;
|
||||
pMS->load.cur = 0;
|
||||
|
||||
if (save_fp == 0)
|
||||
{
|
||||
DrawStamp (&MsgStamp);
|
||||
DestroyDrawable (ReleaseDrawable (MsgStamp.frame));
|
||||
SetContext (OldContext);
|
||||
UnlockMutex (GraphicsLock);
|
||||
// Undo the screen damage done by the "Saving . . ." message.
|
||||
LockMutex (GraphicsLock);
|
||||
DrawStamp (&MsgStamp);
|
||||
DestroyDrawable (ReleaseDrawable (MsgStamp.frame));
|
||||
SetContext (OldContext);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
DeleteResFile (meleeDir, file);
|
||||
if (!saveOk)
|
||||
SaveProblem ();
|
||||
}
|
||||
|
||||
// Update the team list; a previously existing team may have been
|
||||
// deleted when save failed.
|
||||
LoadTeamList (pMS);
|
||||
SelectTeamByFileName (pMS, file);
|
||||
|
||||
if (save_fp != 0)
|
||||
{
|
||||
DrawStamp (&MsgStamp);
|
||||
DestroyDrawable (ReleaseDrawable (MsgStamp.frame));
|
||||
SetContext (OldContext);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
return (save_fp != 0);
|
||||
return (stream != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
InitPreBuilt (MELEE_STATE *pMS)
|
||||
{
|
||||
TEAM_IMAGE *list;
|
||||
MeleeTeam **list;
|
||||
|
||||
#define PREBUILT_COUNT 15
|
||||
pMS->load.preBuiltList =
|
||||
HMalloc (PREBUILT_COUNT * sizeof pMS->load.preBuiltList[0]);
|
||||
HMalloc (PREBUILT_COUNT * sizeof (MeleeTeam *));
|
||||
pMS->load.preBuiltCount = PREBUILT_COUNT;
|
||||
#undef PREBUILT_COUNT
|
||||
|
||||
{
|
||||
FleetShipIndex shipI = 0;
|
||||
int fleetI;
|
||||
size_t fleetI;
|
||||
|
||||
for (fleetI = 0; fleetI < pMS->load.preBuiltCount; fleetI++)
|
||||
for (shipI = 0; shipI < MELEE_FLEET_SIZE; shipI++)
|
||||
pMS->load.preBuiltList[fleetI].ShipList[shipI] = MELEE_NONE;
|
||||
pMS->load.preBuiltList[fleetI] = MeleeTeam_new ();
|
||||
}
|
||||
|
||||
list = pMS->load.preBuiltList;
|
||||
@@ -583,260 +539,245 @@ InitPreBuilt (MELEE_STATE *pMS)
|
||||
{
|
||||
/* "Balanced Team 1" */
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
GAME_STRING (MELEE_STRING_BASE + 4));
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
list->ShipList[i++] = MELEE_SYREEN;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
MeleeTeam_setName (*list, GAME_STRING (MELEE_STRING_BASE + 4));
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SYREEN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
/* "Balanced Team 2" */
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
GAME_STRING (MELEE_STRING_BASE + 5));
|
||||
list->ShipList[i++] = MELEE_ARILOU;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_YEHAT;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_THRADDASH;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
MeleeTeam_setName (*list, GAME_STRING (MELEE_STRING_BASE + 5));
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ARILOU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_YEHAT);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_THRADDASH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
/* "200 points" */
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
GAME_STRING (MELEE_STRING_BASE + 6));
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
list->ShipList[i++] = MELEE_ILWRATH;
|
||||
list->ShipList[i++] = MELEE_VUX;
|
||||
MeleeTeam_setName (*list, GAME_STRING (MELEE_STRING_BASE + 6));
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ILWRATH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_VUX);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
/* "Behemoth Zenith" */
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
GAME_STRING (MELEE_STRING_BASE + 7));
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
MeleeTeam_setName (*list, GAME_STRING (MELEE_STRING_BASE + 7));
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
/* "The Peeled Eyes" */
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
GAME_STRING (MELEE_STRING_BASE + 8));
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_SYREEN;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
MeleeTeam_setName (*list, GAME_STRING (MELEE_STRING_BASE + 8));
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SYREEN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Ford's Fighters");
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
list->ShipList[i++] = MELEE_UMGAH;
|
||||
MeleeTeam_setName (*list, "Ford's Fighters");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UMGAH);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Leyland's Lashers");
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
MeleeTeam_setName (*list, "Leyland's Lashers");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"The Gregorizers 200");
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
MeleeTeam_setName (*list, "The Gregorizers 200");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"300 point Armada!");
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_YEHAT;
|
||||
MeleeTeam_setName (*list, "300 point Armada!");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_YEHAT);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Little Dudes with Attitudes");
|
||||
list->ShipList[i++] = MELEE_UMGAH;
|
||||
list->ShipList[i++] = MELEE_THRADDASH;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_VUX;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
MeleeTeam_setName (*list, "Little Dudes with Attitudes");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UMGAH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_THRADDASH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_VUX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"New Alliance Ships");
|
||||
list->ShipList[i++] = MELEE_ARILOU;
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_SYREEN;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_YEHAT;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_THRADDASH;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
MeleeTeam_setName (*list, "New Alliance Ships");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ARILOU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SYREEN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_YEHAT);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_THRADDASH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Old Alliance Ships");
|
||||
list->ShipList[i++] = MELEE_ARILOU;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_MMRNMHRM;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
list->ShipList[i++] = MELEE_SYREEN;
|
||||
list->ShipList[i++] = MELEE_YEHAT;
|
||||
MeleeTeam_setName (*list, "Old Alliance Ships");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ARILOU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MMRNMHRM);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SYREEN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_YEHAT);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Old Hierarchy Ships");
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_ILWRATH;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
list->ShipList[i++] = MELEE_UMGAH;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_VUX;
|
||||
MeleeTeam_setName (*list, "Old Hierarchy Ships");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ILWRATH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UMGAH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_VUX);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Star Control 1");
|
||||
list->ShipList[i++] = MELEE_ANDROSYNTH;
|
||||
list->ShipList[i++] = MELEE_ARILOU;
|
||||
list->ShipList[i++] = MELEE_CHENJESU;
|
||||
list->ShipList[i++] = MELEE_EARTHLING;
|
||||
list->ShipList[i++] = MELEE_ILWRATH;
|
||||
list->ShipList[i++] = MELEE_MMRNMHRM;
|
||||
list->ShipList[i++] = MELEE_MYCON;
|
||||
list->ShipList[i++] = MELEE_SHOFIXTI;
|
||||
list->ShipList[i++] = MELEE_SPATHI;
|
||||
list->ShipList[i++] = MELEE_SYREEN;
|
||||
list->ShipList[i++] = MELEE_UMGAH;
|
||||
list->ShipList[i++] = MELEE_URQUAN;
|
||||
list->ShipList[i++] = MELEE_VUX;
|
||||
list->ShipList[i++] = MELEE_YEHAT;
|
||||
MeleeTeam_setName (*list, "Star Control 1");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ANDROSYNTH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ARILOU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHENJESU);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_EARTHLING);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ILWRATH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MMRNMHRM);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MYCON);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SHOFIXTI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SPATHI);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SYREEN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UMGAH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_URQUAN);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_VUX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_YEHAT);
|
||||
list++;
|
||||
}
|
||||
|
||||
{
|
||||
FleetShipIndex i = 0;
|
||||
utf8StringCopy (list->TeamName, sizeof (list->TeamName),
|
||||
"Star Control 2");
|
||||
list->ShipList[i++] = MELEE_CHMMR;
|
||||
list->ShipList[i++] = MELEE_DRUUGE;
|
||||
list->ShipList[i++] = MELEE_KOHR_AH;
|
||||
list->ShipList[i++] = MELEE_MELNORME;
|
||||
list->ShipList[i++] = MELEE_ORZ;
|
||||
list->ShipList[i++] = MELEE_PKUNK;
|
||||
list->ShipList[i++] = MELEE_SLYLANDRO;
|
||||
list->ShipList[i++] = MELEE_SUPOX;
|
||||
list->ShipList[i++] = MELEE_THRADDASH;
|
||||
list->ShipList[i++] = MELEE_UTWIG;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
list->ShipList[i++] = MELEE_ZOQFOTPIK;
|
||||
MeleeTeam_setName (*list, "Star Control 2");
|
||||
MeleeTeam_setShip (*list, i++, MELEE_CHMMR);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_DRUUGE);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_KOHR_AH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_MELNORME);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ORZ);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_PKUNK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SLYLANDRO);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_SUPOX);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_THRADDASH);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_UTWIG);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
MeleeTeam_setShip (*list, i++, MELEE_ZOQFOTPIK);
|
||||
list++;
|
||||
}
|
||||
|
||||
@@ -844,21 +785,47 @@ InitPreBuilt (MELEE_STATE *pMS)
|
||||
}
|
||||
|
||||
static void
|
||||
UninitPreBuilt (MELEE_STATE *pMS) {
|
||||
UninitPreBuilt (MELEE_STATE *pMS)
|
||||
{
|
||||
size_t fleetI;
|
||||
for (fleetI = 0; fleetI < pMS->load.preBuiltCount; fleetI++)
|
||||
MeleeTeam_delete (pMS->load.preBuiltList[fleetI]);
|
||||
HFree (pMS->load.preBuiltList);
|
||||
pMS->load.preBuiltCount = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
InitLoadView (MELEE_STATE *pMS)
|
||||
{
|
||||
size_t viewI;
|
||||
MeleeTeam **view = pMS->load.view;
|
||||
|
||||
for (viewI = 0; viewI < LOAD_TEAM_VIEW_SIZE; viewI++)
|
||||
view[viewI] = MeleeTeam_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
UninitLoadView (MELEE_STATE *pMS)
|
||||
{
|
||||
size_t viewI;
|
||||
MeleeTeam **view = pMS->load.view;
|
||||
|
||||
for (viewI = 0; viewI < LOAD_TEAM_VIEW_SIZE; viewI++)
|
||||
MeleeTeam_delete(view[viewI]);
|
||||
}
|
||||
|
||||
void
|
||||
InitMeleeLoadState (MELEE_STATE *pMS)
|
||||
{
|
||||
pMS->load.entryIndices = NULL;
|
||||
InitPreBuilt (pMS);
|
||||
InitLoadView (pMS);
|
||||
}
|
||||
|
||||
void
|
||||
UninitMeleeLoadState (MELEE_STATE *pMS)
|
||||
{
|
||||
UninitLoadView (pMS);
|
||||
UninitPreBuilt (pMS);
|
||||
if (pMS->load.entryIndices != NULL)
|
||||
HFree (pMS->load.entryIndices);
|
||||
|
||||
@@ -24,17 +24,18 @@
|
||||
struct melee_load_state;
|
||||
|
||||
#include "melee.h"
|
||||
#include "meleesetup.h"
|
||||
|
||||
struct melee_load_state
|
||||
{
|
||||
TEAM_IMAGE *preBuiltList;
|
||||
MeleeTeam **preBuiltList;
|
||||
COUNT preBuiltCount;
|
||||
|
||||
DIRENTRY dirEntries;
|
||||
COUNT *entryIndices;
|
||||
COUNT numIndices;
|
||||
|
||||
TEAM_IMAGE view[LOAD_TEAM_VIEW_SIZE];
|
||||
MeleeTeam *view[LOAD_TEAM_VIEW_SIZE];
|
||||
COUNT top;
|
||||
// Index of the first entry for the view.
|
||||
COUNT bot;
|
||||
@@ -51,8 +52,8 @@ void UninitMeleeLoadState (MELEE_STATE *pMS);
|
||||
|
||||
BOOLEAN DoLoadTeam (MELEE_STATE *pMS);
|
||||
BOOLEAN DoSaveTeam (MELEE_STATE *pMS);
|
||||
bool ReadTeamImage (TEAM_IMAGE *pTI, uio_Stream *load_fp);
|
||||
int WriteTeamImage (TEAM_IMAGE *pTI, uio_Stream *save_fp);
|
||||
bool ReadTeamImage (MeleeTeam *pTI, uio_Stream *load_fp);
|
||||
int WriteTeamImage (const MeleeTeam *pTI, uio_Stream *save_fp);
|
||||
void LoadTeamList (MELEE_STATE *pMS);
|
||||
|
||||
#endif /* _LOADMELE_H */
|
||||
|
||||
+486
-714
File diff suppressed because it is too large
Load Diff
@@ -30,39 +30,6 @@
|
||||
|
||||
typedef struct melee_state MELEE_STATE;
|
||||
|
||||
enum
|
||||
{
|
||||
MELEE_ANDROSYNTH,
|
||||
MELEE_ARILOU,
|
||||
MELEE_CHENJESU,
|
||||
MELEE_CHMMR,
|
||||
MELEE_DRUUGE,
|
||||
MELEE_EARTHLING,
|
||||
MELEE_ILWRATH,
|
||||
MELEE_KOHR_AH,
|
||||
MELEE_MELNORME,
|
||||
MELEE_MMRNMHRM,
|
||||
MELEE_MYCON,
|
||||
MELEE_ORZ,
|
||||
MELEE_PKUNK,
|
||||
MELEE_SHOFIXTI,
|
||||
MELEE_SLYLANDRO,
|
||||
MELEE_SPATHI,
|
||||
MELEE_SUPOX,
|
||||
MELEE_SYREEN,
|
||||
MELEE_THRADDASH,
|
||||
MELEE_UMGAH,
|
||||
MELEE_URQUAN,
|
||||
MELEE_UTWIG,
|
||||
MELEE_VUX,
|
||||
MELEE_YEHAT,
|
||||
MELEE_ZOQFOTPIK,
|
||||
|
||||
NUM_MELEE_SHIPS,
|
||||
|
||||
MELEE_NONE = (BYTE) ~0
|
||||
};
|
||||
|
||||
#define NUM_MELEE_ROWS 2
|
||||
#define NUM_MELEE_COLUMNS 7
|
||||
//#define NUM_MELEE_COLUMNS 6
|
||||
@@ -82,23 +49,10 @@ extern FRAME PickMeleeFrame;
|
||||
#define NUM_PICK_ROWS 5
|
||||
|
||||
typedef BYTE MELEE_OPTIONS;
|
||||
typedef COUNT FleetShipIndex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE ShipList[MELEE_FLEET_SIZE];
|
||||
UNICODE TeamName[MAX_TEAM_CHARS + 1 + 24];
|
||||
/* The +1 is for the terminating \0; the +24 is in case some
|
||||
* default name in starcon.txt is unknowingly mangled. */
|
||||
} TEAM_IMAGE;
|
||||
|
||||
#include "loadmele.h"
|
||||
|
||||
struct melee_side_state
|
||||
{
|
||||
TEAM_IMAGE TeamImage;
|
||||
COUNT star_bucks;
|
||||
};
|
||||
#include "meleesetup.h"
|
||||
#include "meleeship.h"
|
||||
|
||||
struct melee_state
|
||||
{
|
||||
@@ -106,10 +60,24 @@ struct melee_state
|
||||
|
||||
BOOLEAN Initialized;
|
||||
MELEE_OPTIONS MeleeOption;
|
||||
COUNT side, row, col;
|
||||
struct melee_side_state SideState[NUM_SIDES];
|
||||
COUNT side;
|
||||
COUNT row;
|
||||
COUNT col;
|
||||
MeleeSetup *meleeSetup;
|
||||
struct melee_load_state load;
|
||||
MeleeShip currentShip;
|
||||
// The ship currently displayed. Not really needed.
|
||||
// Also the current ship position when selecting a ship.
|
||||
COUNT CurIndex;
|
||||
#define MELEE_STATE_INDEX_DONE ((COUNT) -1)
|
||||
// Current position in the team string when editing it.
|
||||
// Set to MELEE_STATE_INDEX_DONE when done.
|
||||
BOOLEAN buildPickConfirmed;
|
||||
// Used by DoPickShip () to communicate to the calling
|
||||
// function BuildPickShip() whether a ship has been selected
|
||||
// to add to the fleet, or whether the operation has been
|
||||
// cancelled. If a ship was selected, it is set in
|
||||
// currentShip.
|
||||
RandomContext *randomContext;
|
||||
/* RNG state for all local random decisions, i.e. those
|
||||
* decisions that are not shared among network parties. */
|
||||
@@ -123,17 +91,14 @@ extern void Melee (void);
|
||||
// Some prototypes for use by loadmele.c:
|
||||
BOOLEAN DoMelee (MELEE_STATE *pMS);
|
||||
void DrawMeleeIcon (COUNT which_icon);
|
||||
COUNT GetTeamValue (TEAM_IMAGE *pTI);
|
||||
void RepairMeleeFrame (RECT *pRect);
|
||||
void GetShipBox (RECT *pRect, COUNT side, COUNT row, COUNT col);
|
||||
void RepairMeleeFrame (const RECT *pRect);
|
||||
void DrawMeleeShipStrings (MELEE_STATE *pMS, MeleeShip NewStarShip);
|
||||
extern FRAME MeleeFrame;
|
||||
void Melee_flashSelection (MELEE_STATE *pMS);
|
||||
|
||||
void teamStringChanged (MELEE_STATE *pMS, int player);
|
||||
void entireFleetChanged (MELEE_STATE *pMS, int player);
|
||||
void fleetShipChanged (MELEE_STATE *pMS, int player, size_t index);
|
||||
COUNT GetShipValue (MeleeShip StarShip);
|
||||
|
||||
void updateTeamName (MELEE_STATE *pMS, COUNT side, const char *name,
|
||||
size_t len);
|
||||
bool updateFleetShip (MELEE_STATE *pMS, COUNT side, COUNT index, BYTE ship);
|
||||
void updateRandomSeed (MELEE_STATE *pMS, COUNT side, DWORD seed);
|
||||
void confirmationCancelled(MELEE_STATE *pMS, COUNT side);
|
||||
void connectedFeedback (NetConnection *conn);
|
||||
@@ -143,5 +108,18 @@ void resetFeedback (NetConnection *conn, NetplayResetReason reason,
|
||||
void errorFeedback (NetConnection *conn);
|
||||
void closeFeedback (NetConnection *conn);
|
||||
|
||||
bool Melee_Change_ship (MELEE_STATE *pMS, COUNT side, FleetShipIndex index,
|
||||
MeleeShip ship);
|
||||
bool Melee_Change_teamName (MELEE_STATE *pMS, COUNT side, const char *name);
|
||||
bool Melee_Change_fleet (MELEE_STATE *pMS, size_t teamNr,
|
||||
const MeleeShip *fleet);
|
||||
bool Melee_Change_team (MELEE_STATE *pMS, size_t teamNr,
|
||||
const MeleeTeam *team);
|
||||
|
||||
void Melee_RemoteChange_ship (MELEE_STATE *pMS, NetConnection *conn,
|
||||
COUNT side, FleetShipIndex index, MeleeShip ship);
|
||||
void Melee_RemoteChange_teamName (MELEE_STATE *pMS, NetConnection *conn,
|
||||
COUNT side, const char *name);
|
||||
|
||||
#endif /* _MELEE_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define MELEESETUP_INTERNAL
|
||||
#include "port.h"
|
||||
#include "meleesetup.h"
|
||||
|
||||
#include "../master.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Temporary
|
||||
const size_t MeleeTeam_size = sizeof (MeleeTeam);
|
||||
|
||||
void
|
||||
MeleeTeam_init (MeleeTeam *team)
|
||||
{
|
||||
FleetShipIndex slotI;
|
||||
|
||||
for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++)
|
||||
team->ships[slotI] = MELEE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
MeleeTeam_uninit (MeleeTeam *team)
|
||||
{
|
||||
(void) team;
|
||||
}
|
||||
|
||||
MeleeTeam *
|
||||
MeleeTeam_new (void)
|
||||
{
|
||||
MeleeTeam *result = HMalloc (sizeof (MeleeTeam));
|
||||
MeleeTeam_init (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
MeleeTeam_delete (MeleeTeam *team)
|
||||
{
|
||||
MeleeTeam_uninit (team);
|
||||
HFree (team);
|
||||
}
|
||||
|
||||
int
|
||||
MeleeTeam_serialize (const MeleeTeam *team, uio_Stream *stream)
|
||||
{
|
||||
FleetShipIndex slotI;
|
||||
|
||||
for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++) {
|
||||
if (uio_putc ((int) team->ships[slotI], stream) == EOF)
|
||||
return -1;
|
||||
}
|
||||
if (uio_fwrite ((char *) team->name, sizeof team->name, 1, stream) != 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
MeleeTeam_deserialize (MeleeTeam *team, uio_Stream *stream)
|
||||
{
|
||||
FleetShipIndex slotI;
|
||||
|
||||
// Sanity check on the ships.
|
||||
for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++)
|
||||
{
|
||||
int ship = uio_getc (stream);
|
||||
if (ship == EOF)
|
||||
goto err;
|
||||
team->ships[slotI] = (MeleeShip) ship;
|
||||
|
||||
if (team->ships[slotI] == MELEE_NONE)
|
||||
continue;
|
||||
|
||||
if (team->ships[slotI] >= NUM_MELEE_SHIPS)
|
||||
{
|
||||
log_add (log_Warning, "Invalid ship type in loaded team (index "
|
||||
"%d, ship type is %d, max valid is %d).",
|
||||
slotI, team->ships[slotI], NUM_MELEE_SHIPS - 1);
|
||||
team->ships[slotI] = MELEE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (uio_fread (team->name, sizeof team->name, 1, stream) != 1)
|
||||
goto err;
|
||||
|
||||
team->name[MAX_TEAM_CHARS] = '\0';
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
MeleeTeam_delete(team);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// XXX: move this to elsewhere?
|
||||
COUNT
|
||||
MeleeTeam_getValue (const MeleeTeam *team)
|
||||
{
|
||||
COUNT total = 0;
|
||||
FleetShipIndex slotI;
|
||||
|
||||
for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++)
|
||||
{
|
||||
MeleeShip ship = team->ships[slotI];
|
||||
COUNT shipValue = GetShipValue (ship);
|
||||
if (shipValue == (COUNT)~0)
|
||||
{
|
||||
// Invalid ship.
|
||||
continue;
|
||||
}
|
||||
total += shipValue;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
MeleeShip
|
||||
MeleeTeam_getShip (const MeleeTeam *team, FleetShipIndex slotNr)
|
||||
{
|
||||
return team->ships[slotNr];
|
||||
}
|
||||
|
||||
void
|
||||
MeleeTeam_setShip (MeleeTeam *team, FleetShipIndex slotNr, MeleeShip ship)
|
||||
{
|
||||
team->ships[slotNr] = ship;
|
||||
}
|
||||
|
||||
const MeleeShip *
|
||||
MeleeTeam_getFleet (const MeleeTeam *team)
|
||||
{
|
||||
return team->ships;
|
||||
}
|
||||
|
||||
const char *
|
||||
MeleeTeam_getTeamName (const MeleeTeam *team)
|
||||
{
|
||||
return team->name;
|
||||
}
|
||||
|
||||
// Returns true iff the state has actually changed.
|
||||
void
|
||||
MeleeTeam_setName (MeleeTeam *team, const UNICODE *name)
|
||||
{
|
||||
strncpy (team->name, name, sizeof team->name - 1);
|
||||
team->name[sizeof team->name - 1] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
MeleeTeam_copy (MeleeTeam *copy, const MeleeTeam *original)
|
||||
{
|
||||
*copy = *original;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MeleeSetup *
|
||||
MeleeSetup_new (void)
|
||||
{
|
||||
size_t teamI;
|
||||
MeleeSetup *result = HMalloc (sizeof (MeleeSetup));
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
for (teamI = 0; teamI < NUM_SIDES; teamI++)
|
||||
{
|
||||
MeleeTeam_init (&result->teams[teamI]);
|
||||
result->fleetValue[teamI] = 0;
|
||||
#ifdef NETPLAY
|
||||
MeleeTeam_init (&result->confirmedTeams[teamI]);
|
||||
#endif /* NETPLAY */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
MeleeSetup_delete (MeleeSetup *setup)
|
||||
{
|
||||
HFree (setup);
|
||||
}
|
||||
|
||||
// Returns true iff the state has actually changed.
|
||||
bool
|
||||
MeleeSetup_setShip (MeleeSetup *setup, size_t teamNr, FleetShipIndex slotNr,
|
||||
MeleeShip ship)
|
||||
{
|
||||
MeleeTeam *team = &setup->teams[teamNr];
|
||||
MeleeShip oldShip = MeleeTeam_getShip (team, slotNr);
|
||||
|
||||
if (ship == oldShip)
|
||||
return false;
|
||||
|
||||
if (oldShip != MELEE_NONE)
|
||||
setup->fleetValue[teamNr] -= GetShipCostFromIndex (oldShip);
|
||||
|
||||
MeleeTeam_setShip (team, slotNr, ship);
|
||||
|
||||
if (ship != MELEE_NONE)
|
||||
setup->fleetValue[teamNr] += GetShipCostFromIndex (ship);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MeleeShip
|
||||
MeleeSetup_getShip (const MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr)
|
||||
{
|
||||
return MeleeTeam_getShip (&setup->teams[teamNr], slotNr);
|
||||
}
|
||||
|
||||
const MeleeShip *
|
||||
MeleeSetup_getFleet (const MeleeSetup *setup, size_t teamNr)
|
||||
{
|
||||
return MeleeTeam_getFleet (&setup->teams[teamNr]);
|
||||
}
|
||||
|
||||
// Returns true iff the state has actually changed.
|
||||
bool
|
||||
MeleeSetup_setTeamName (MeleeSetup *setup, size_t teamNr,
|
||||
const UNICODE *name)
|
||||
{
|
||||
MeleeTeam *team = &setup->teams[teamNr];
|
||||
const UNICODE *oldName = MeleeTeam_getTeamName (team);
|
||||
|
||||
if (strcmp (oldName, name) == 0)
|
||||
return false;
|
||||
|
||||
MeleeTeam_setName (team, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *
|
||||
MeleeSetup_getTeamName (const MeleeSetup *setup, size_t teamNr)
|
||||
{
|
||||
return MeleeTeam_getTeamName (&setup->teams[teamNr]);
|
||||
}
|
||||
|
||||
COUNT
|
||||
MeleeSetup_getFleetValue (const MeleeSetup *setup, size_t teamNr)
|
||||
{
|
||||
return setup->fleetValue[teamNr];
|
||||
}
|
||||
|
||||
int
|
||||
MeleeSetup_deserializeTeam (MeleeSetup *setup, size_t teamNr,
|
||||
uio_Stream *stream)
|
||||
{
|
||||
MeleeTeam *team = &setup->teams[teamNr];
|
||||
return MeleeTeam_deserialize (team, stream);
|
||||
}
|
||||
|
||||
int
|
||||
MeleeSetup_serializeTeam (const MeleeSetup *setup, size_t teamNr,
|
||||
uio_Stream *stream)
|
||||
{
|
||||
const MeleeTeam *team = &setup->teams[teamNr];
|
||||
return MeleeTeam_serialize (team, stream);
|
||||
}
|
||||
|
||||
#ifdef NETPLAY
|
||||
MeleeShip
|
||||
MeleeSetup_getConfirmedShip (const MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr)
|
||||
{
|
||||
return MeleeTeam_getShip (&setup->confirmedTeams[teamNr], slotNr);
|
||||
}
|
||||
|
||||
const char *
|
||||
MeleeSetup_getConfirmedTeamName (const MeleeSetup *setup, size_t teamNr)
|
||||
{
|
||||
return MeleeTeam_getTeamName (&setup->confirmedTeams[teamNr]);
|
||||
}
|
||||
|
||||
// Returns true iff the state has actually changed.
|
||||
bool
|
||||
MeleeSetup_setConfirmedShip (MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr, MeleeShip ship)
|
||||
{
|
||||
MeleeTeam *team = &setup->confirmedTeams[teamNr];
|
||||
MeleeShip oldShip = MeleeTeam_getShip (team, slotNr);
|
||||
|
||||
if (ship == oldShip)
|
||||
return false;
|
||||
|
||||
MeleeTeam_setShip (team, slotNr, ship);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true iff the state has actually changed.
|
||||
bool
|
||||
MeleeSetup_setConfirmedTeamName (MeleeSetup *setup, size_t teamNr,
|
||||
const UNICODE *name)
|
||||
{
|
||||
MeleeTeam *team = &setup->confirmedTeams[teamNr];
|
||||
const UNICODE *oldName = MeleeTeam_getTeamName (team);
|
||||
|
||||
if (strcmp (oldName, name) == 0)
|
||||
return false;
|
||||
|
||||
MeleeTeam_setName (team, name);
|
||||
return true;
|
||||
}
|
||||
#endif /* NETPLAY */
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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 MELEESETUP_H
|
||||
#define MELEESETUP_H
|
||||
|
||||
typedef struct MeleeTeam MeleeTeam;
|
||||
typedef struct MeleeSetup MeleeSetup;
|
||||
|
||||
#ifdef MELEESETUP_INTERNAL
|
||||
# define MELEETEAM_INTERNAL
|
||||
#endif /* MELEESETUP_INTERNAL */
|
||||
|
||||
#include "libs/compiler.h"
|
||||
|
||||
typedef COUNT FleetShipIndex;
|
||||
|
||||
#include "libs/uio.h"
|
||||
#include "melee.h"
|
||||
#include "meleeship.h"
|
||||
|
||||
#ifdef MELEETEAM_INTERNAL
|
||||
struct MeleeTeam
|
||||
{
|
||||
MeleeShip ships[MELEE_FLEET_SIZE];
|
||||
UNICODE name[MAX_TEAM_CHARS + 1 + 24];
|
||||
/* The +1 is for the terminating \0; the +24 is in case some
|
||||
* default name in starcon.txt is unknowingly mangled. */
|
||||
};
|
||||
#endif /* MELEETEAM_INTERNAL */
|
||||
|
||||
#ifdef MELEESETUP_INTERNAL
|
||||
// When Netplay is enabled, we keep two copies of the teams: the team as we
|
||||
// consider it to be locally, and last confirmed team.
|
||||
// There are no separate change and confirmation messages; a confirmation
|
||||
// message is a message reporting a change to the value which was specified
|
||||
// by the remote side.
|
||||
// When a local change is made, the current team is updated, and a message
|
||||
// is sent to the other side.
|
||||
// When we receive a message of a remote update:
|
||||
// - if the current value is the same as the received value, we change
|
||||
// the confirmed value to the current/received value
|
||||
// - if the current value is different from the received value, and
|
||||
// the current value is the same as the confirmed value, we change both
|
||||
// the current value and the confirmed value to the received value,
|
||||
// and sent a message to the remote side of our modification.
|
||||
// - if the current value is different from the received value, and
|
||||
// the current value is not the same as the confirmed value, our
|
||||
// action depends on who "owns" the value:
|
||||
// - if the change is to the remote fleet, we change the current and
|
||||
// confirmed value to the received value, and send a message to the
|
||||
// remote side of our modification (as above)
|
||||
// - if the change is to the local fleet, we take no action.
|
||||
// (In this situation, a local change has been made, and a message of
|
||||
// this has already been sent to the other side, and a confirmation
|
||||
// from the other side will arrive eventually.)
|
||||
// XXX: put this in docs/netplay/protocols.
|
||||
// XXX: this not only works for teams, but also for other properties.
|
||||
struct MeleeSetup
|
||||
{
|
||||
MeleeTeam teams[NUM_SIDES];
|
||||
COUNT fleetValue[NUM_SIDES];
|
||||
#ifdef NETPLAY
|
||||
MeleeTeam confirmedTeams[NUM_SIDES];
|
||||
// The least team which both sides agreed upon.
|
||||
// XXX: this may actually be deallocated when the battle starts.
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* MELEESETUP_INTERNAL */
|
||||
|
||||
extern const size_t MeleeTeam_size;
|
||||
|
||||
void MeleeTeam_init (MeleeTeam *team);
|
||||
void MeleeTeam_uninit (MeleeTeam *team);
|
||||
MeleeTeam *MeleeTeam_new (void);
|
||||
void MeleeTeam_delete (MeleeTeam *team);
|
||||
int MeleeTeam_serialize (const MeleeTeam *team, uio_Stream *stream);
|
||||
int MeleeTeam_deserialize (MeleeTeam *team, uio_Stream *stream);
|
||||
COUNT MeleeTeam_getValue (const MeleeTeam *team);
|
||||
MeleeShip MeleeTeam_getShip (const MeleeTeam *team, FleetShipIndex slotNr);
|
||||
void MeleeTeam_setShip (MeleeTeam *team, FleetShipIndex slotNr,
|
||||
MeleeShip ship);
|
||||
const MeleeShip *MeleeTeam_getFleet (const MeleeTeam *team);
|
||||
const char *MeleeTeam_getTeamName (const MeleeTeam *team);
|
||||
void MeleeTeam_setName (MeleeTeam *team, const UNICODE *name);
|
||||
void MeleeTeam_copy (MeleeTeam *copy, const MeleeTeam *original);
|
||||
|
||||
#ifdef NETPLAY
|
||||
MeleeShip MeleeSetup_getConfirmedShip (const MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr);
|
||||
const char *MeleeSetup_getConfirmedTeamName (const MeleeSetup *setup,
|
||||
size_t teamNr);
|
||||
bool MeleeSetup_setConfirmedShip (MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr, MeleeShip ship);
|
||||
bool MeleeSetup_setConfirmedTeamName (MeleeSetup *setup, size_t teamNr,
|
||||
const UNICODE *name);
|
||||
#endif /* NETPLAY */
|
||||
|
||||
MeleeSetup *MeleeSetup_new (void);
|
||||
void MeleeSetup_delete (MeleeSetup *setup);
|
||||
|
||||
bool MeleeSetup_setShip (MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr, MeleeShip ship);
|
||||
MeleeShip MeleeSetup_getShip (const MeleeSetup *setup, size_t teamNr,
|
||||
FleetShipIndex slotNr);
|
||||
bool MeleeSetup_setFleet (MeleeSetup *setup, size_t teamNr,
|
||||
const MeleeShip *fleet);
|
||||
const MeleeShip *MeleeSetup_getFleet (const MeleeSetup *setup, size_t teamNr);
|
||||
bool MeleeSetup_setTeamName (MeleeSetup *setup, size_t teamNr,
|
||||
const UNICODE *name);
|
||||
const char *MeleeSetup_getTeamName (const MeleeSetup *setup,
|
||||
size_t teamNr);
|
||||
COUNT MeleeSetup_getFleetValue (const MeleeSetup *setup, size_t teamNr);
|
||||
int MeleeSetup_deserializeTeam (MeleeSetup *setup, size_t teamNr,
|
||||
uio_Stream *stream);
|
||||
int MeleeSetup_serializeTeam (const MeleeSetup *setup, size_t teamNr,
|
||||
uio_Stream *stream);
|
||||
|
||||
|
||||
void MeleeState_setShip (MELEE_STATE *pMS, size_t teamNr,
|
||||
FleetShipIndex slotNr, MeleeShip ship);
|
||||
void MeleeState_setFleet (MELEE_STATE *pMS, size_t teamNr,
|
||||
const MeleeShip *fleet);
|
||||
void MeleeState_setTeamName (MELEE_STATE *pMS, size_t teamNr,
|
||||
const UNICODE *name);
|
||||
void MeleeState_setTeam (MELEE_STATE *pMS, size_t teamNr,
|
||||
const MeleeTeam *team);
|
||||
|
||||
#endif /* MELEESETUP_H */
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef MELEESHIP_H
|
||||
#define MELEESHIP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum MeleeShip {
|
||||
MELEE_ANDROSYNTH,
|
||||
MELEE_ARILOU,
|
||||
MELEE_CHENJESU,
|
||||
MELEE_CHMMR,
|
||||
MELEE_DRUUGE,
|
||||
MELEE_EARTHLING,
|
||||
MELEE_ILWRATH,
|
||||
MELEE_KOHR_AH,
|
||||
MELEE_MELNORME,
|
||||
MELEE_MMRNMHRM,
|
||||
MELEE_MYCON,
|
||||
MELEE_ORZ,
|
||||
MELEE_PKUNK,
|
||||
MELEE_SHOFIXTI,
|
||||
MELEE_SLYLANDRO,
|
||||
MELEE_SPATHI,
|
||||
MELEE_SUPOX,
|
||||
MELEE_SYREEN,
|
||||
MELEE_THRADDASH,
|
||||
MELEE_UMGAH,
|
||||
MELEE_URQUAN,
|
||||
MELEE_UTWIG,
|
||||
MELEE_VUX,
|
||||
MELEE_YEHAT,
|
||||
MELEE_ZOQFOTPIK,
|
||||
|
||||
MELEE_NONE = (BYTE) ~0
|
||||
} MeleeShip;
|
||||
#define NUM_MELEE_SHIPS (MELEE_ZOQFOTPIK + 1)
|
||||
|
||||
static inline bool
|
||||
MeleeShip_valid (MeleeShip ship)
|
||||
{
|
||||
return (ship < NUM_MELEE_SHIPS) || (ship == MELEE_NONE);
|
||||
}
|
||||
|
||||
#endif /* MELEESHIP_H */
|
||||
|
||||
@@ -20,10 +20,14 @@
|
||||
#include "pickmele.h"
|
||||
|
||||
#include "../battlecontrols.h"
|
||||
#include "../battle.h"
|
||||
#include "../build.h"
|
||||
#include "../controls.h"
|
||||
#include "../flash.h"
|
||||
#include "../igfxres.h"
|
||||
#include "../intel.h"
|
||||
#include "../battle.h"
|
||||
#include "../master.h"
|
||||
#include "../nameref.h"
|
||||
#include "melee.h"
|
||||
#ifdef NETPLAY
|
||||
# include "../netplay/netmelee.h"
|
||||
@@ -37,15 +41,49 @@
|
||||
#include "libs/mathlib.h"
|
||||
|
||||
|
||||
#define NUM_MELEE_COLS_ORIG NUM_MELEE_COLUMNS
|
||||
#define NUM_PICKMELEE_ROWS 2
|
||||
#define NUM_PICKMELEE_COLUMNS 7
|
||||
|
||||
#define PICK_X_OFFS 57
|
||||
#define PICK_Y_OFFS 24
|
||||
#define PICK_SIDE_OFFS 100
|
||||
|
||||
#define NAME_AREA_HEIGHT 7
|
||||
#define MELEE_WIDTH 149
|
||||
#define MELEE_HEIGHT (48 + NAME_AREA_HEIGHT)
|
||||
|
||||
#define PICKSHIP_TEAM_NAME_TEXT_COLOR \
|
||||
BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)
|
||||
#define PICKSHIP_TEAM_START_VALUE_COLOR \
|
||||
BUILD_COLOR (MAKE_RGB15 (0x04, 0x05, 0x1F), 0x4B)
|
||||
|
||||
|
||||
#ifdef NETPLAY
|
||||
static void reportShipSelected (GETMELEE_STATE *gms, COUNT index);
|
||||
#endif
|
||||
|
||||
|
||||
FRAME PickMeleeFrame;
|
||||
|
||||
|
||||
static FleetShipIndex
|
||||
PickMelee_GetShipIndex (BYTE row, BYTE col)
|
||||
{
|
||||
return row * NUM_PICKMELEE_COLUMNS + col;
|
||||
}
|
||||
|
||||
static BYTE
|
||||
PickMelee_GetShipRow (FleetShipIndex index)
|
||||
{
|
||||
return index / NUM_PICKMELEE_COLUMNS;
|
||||
}
|
||||
|
||||
static BYTE
|
||||
PickMelee_GetShipColumn (int index)
|
||||
{
|
||||
return index % NUM_PICKMELEE_COLUMNS;
|
||||
}
|
||||
|
||||
// Returns the <index>th ship in the queue, or 0 if it is not available.
|
||||
static HSTARSHIP
|
||||
MeleeShipByQueueIndex (const QUEUE *queue, COUNT index)
|
||||
@@ -161,13 +199,13 @@ SelectShip_processInput (GETMELEE_STATE *gms, COUNT playerI,
|
||||
{
|
||||
if (inputState & BATTLE_WEAPON)
|
||||
{
|
||||
if (gms->player[playerI].col == NUM_MELEE_COLS_ORIG &&
|
||||
if (gms->player[playerI].col == NUM_PICKMELEE_COLUMNS &&
|
||||
gms->player[playerI].row == 0)
|
||||
{
|
||||
// Random ship
|
||||
(void) setShipSelected (gms, playerI, (COUNT) ~0, TRUE);
|
||||
}
|
||||
else if (gms->player[playerI].col == NUM_MELEE_COLS_ORIG &&
|
||||
else if (gms->player[playerI].col == NUM_PICKMELEE_COLUMNS &&
|
||||
gms->player[playerI].row == 1)
|
||||
{
|
||||
// Selected exit
|
||||
@@ -177,10 +215,9 @@ SelectShip_processInput (GETMELEE_STATE *gms, COUNT playerI,
|
||||
else
|
||||
{
|
||||
// Selection is on a ship slot.
|
||||
COUNT shipI =
|
||||
(gms->player[playerI].row * NUM_MELEE_COLS_ORIG)
|
||||
+ gms->player[playerI].col;
|
||||
(void) setShipSelected (gms, playerI, shipI, TRUE);
|
||||
COUNT slotNr = PickMelee_GetShipIndex (gms->player[playerI].row,
|
||||
gms->player[playerI].col);
|
||||
(void) setShipSelected (gms, playerI, slotNr, TRUE);
|
||||
// If the choice is not valid, setShipSelected()
|
||||
// will not set .done.
|
||||
}
|
||||
@@ -195,21 +232,21 @@ SelectShip_processInput (GETMELEE_STATE *gms, COUNT playerI,
|
||||
if (inputState & BATTLE_LEFT)
|
||||
{
|
||||
if (new_col-- == 0)
|
||||
new_col = NUM_MELEE_COLS_ORIG;
|
||||
new_col = NUM_PICKMELEE_COLUMNS;
|
||||
}
|
||||
else if (inputState & BATTLE_RIGHT)
|
||||
{
|
||||
if (new_col++ == NUM_MELEE_COLS_ORIG)
|
||||
if (new_col++ == NUM_PICKMELEE_COLUMNS)
|
||||
new_col = 0;
|
||||
}
|
||||
if (inputState & BATTLE_THRUST)
|
||||
{
|
||||
if (new_row-- == 0)
|
||||
new_row = NUM_MELEE_ROWS - 1;
|
||||
new_row = NUM_PICKMELEE_ROWS - 1;
|
||||
}
|
||||
else if (inputState & BATTLE_DOWN)
|
||||
{
|
||||
if (++new_row == NUM_MELEE_ROWS)
|
||||
if (++new_row == NUM_PICKMELEE_ROWS)
|
||||
new_row = 0;
|
||||
}
|
||||
|
||||
@@ -384,17 +421,19 @@ GetRaceQueueValue (const QUEUE *queue) {
|
||||
// 'shipI' is the index in the ship list.
|
||||
// Pre: caller holds the graphics lock.
|
||||
static void
|
||||
CrossOutShip (FRAME frame, COUNT shipI)
|
||||
CrossOutShip (FRAME frame, COUNT shipNr)
|
||||
{
|
||||
CONTEXT OldContext;
|
||||
STAMP s;
|
||||
BYTE row = PickMelee_GetShipRow (shipNr);
|
||||
BYTE col = PickMelee_GetShipColumn (shipNr);
|
||||
|
||||
OldContext = SetContext (OffScreenContext);
|
||||
|
||||
SetContextFGFrame (frame);
|
||||
|
||||
s.origin.x = 3 + ((ICON_WIDTH + 2) * (shipI % NUM_MELEE_COLS_ORIG));
|
||||
s.origin.y = 9 + ((ICON_HEIGHT + 2) * (shipI / NUM_MELEE_COLS_ORIG));
|
||||
s.origin.x = 3 + ((ICON_WIDTH + 2) * col);
|
||||
s.origin.y = 9 + ((ICON_HEIGHT + 2) * row);
|
||||
s.frame = SetAbsFrameIndex (StatusFrame, 3);
|
||||
// Cross for through the ship image.
|
||||
DrawStamp (&s);
|
||||
@@ -442,6 +481,158 @@ UpdatePickMeleeFleetValue (FRAME frame, COUNT which_player)
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
// Create a frame for each player to display their current fleet in,
|
||||
// to be used when selecting the next ship to fight with.
|
||||
void
|
||||
BuildPickMeleeFrame (void)
|
||||
{
|
||||
STAMP s;
|
||||
CONTEXT OldContext = SetContext (OffScreenContext);
|
||||
|
||||
if (PickMeleeFrame)
|
||||
DestroyDrawable (ReleaseDrawable (PickMeleeFrame));
|
||||
|
||||
PickMeleeFrame = CaptureDrawable (CreateDrawable (
|
||||
WANT_PIXMAP, MELEE_WIDTH, MELEE_HEIGHT, 2));
|
||||
s.origin.x = 0;
|
||||
s.origin.y = 0;
|
||||
|
||||
s.frame = CaptureDrawable (LoadGraphic (MELEE_PICK_MASK_PMAP_ANIM));
|
||||
SetContextFGFrame (PickMeleeFrame);
|
||||
DrawStamp (&s);
|
||||
|
||||
s.frame = IncFrameIndex (s.frame);
|
||||
SetContextFGFrame (IncFrameIndex (PickMeleeFrame));
|
||||
DrawStamp (&s);
|
||||
|
||||
DestroyDrawable (ReleaseDrawable (s.frame));
|
||||
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
// Put the ship icons in the PickMeleeFrame, and create a queue
|
||||
// for each player.
|
||||
// XXX TODO: split off creating the queue into a separate function.
|
||||
void
|
||||
FillPickMeleeFrame (MeleeSetup *setup)
|
||||
{
|
||||
COUNT sideI;
|
||||
CONTEXT OldContext;
|
||||
|
||||
OldContext = SetContext (OffScreenContext);
|
||||
|
||||
for (sideI = 0; sideI < NUM_SIDES; ++sideI)
|
||||
{
|
||||
COUNT side;
|
||||
RECT r;
|
||||
TEXT t;
|
||||
STAMP s;
|
||||
UNICODE buf[30];
|
||||
FleetShipIndex index;
|
||||
|
||||
side = !sideI;
|
||||
|
||||
s.frame = SetAbsFrameIndex (PickMeleeFrame, side);
|
||||
SetContextFGFrame (s.frame);
|
||||
|
||||
GetFrameRect (s.frame, &r);
|
||||
t.baseline.x = r.extent.width >> 1;
|
||||
t.baseline.y = r.extent.height - NAME_AREA_HEIGHT + 4;
|
||||
|
||||
r.corner.x += 2;
|
||||
r.corner.y += 2;
|
||||
r.extent.width -= (2 * 2) + (ICON_WIDTH + 2) + 1;
|
||||
r.extent.height -= (2 * 2) + NAME_AREA_HEIGHT;
|
||||
SetContextForeGroundColor (PICK_BG_COLOR);
|
||||
DrawFilledRectangle (&r);
|
||||
|
||||
r.corner.x += 2;
|
||||
r.extent.width += (ICON_WIDTH + 2) - (2 * 2);
|
||||
r.corner.y += r.extent.height;
|
||||
r.extent.height = NAME_AREA_HEIGHT;
|
||||
DrawFilledRectangle (&r);
|
||||
|
||||
// Team name at the bottom of the frame:
|
||||
t.align = ALIGN_CENTER;
|
||||
t.pStr = MeleeSetup_getTeamName (setup, sideI);
|
||||
t.CharCount = (COUNT) ~0;
|
||||
SetContextFont (TinyFont);
|
||||
SetContextForeGroundColor (PICKSHIP_TEAM_NAME_TEXT_COLOR);
|
||||
font_DrawText (&t);
|
||||
|
||||
// Total team value of the starting team:
|
||||
sprintf (buf, "%u", MeleeSetup_getFleetValue (setup, sideI));
|
||||
t.baseline.x = 4;
|
||||
t.baseline.y = 7;
|
||||
t.align = ALIGN_LEFT;
|
||||
t.pStr = buf;
|
||||
t.CharCount = (COUNT)~0;
|
||||
SetContextForeGroundColor (PICKSHIP_TEAM_START_VALUE_COLOR);
|
||||
font_DrawText (&t);
|
||||
|
||||
assert (CountLinks (&race_q[side]) == 0);
|
||||
|
||||
for (index = 0; index < MELEE_FLEET_SIZE; index++)
|
||||
{
|
||||
MeleeShip StarShip;
|
||||
|
||||
StarShip = MeleeSetup_getShip (setup, sideI, index);
|
||||
if (StarShip == MELEE_NONE)
|
||||
continue;
|
||||
|
||||
{
|
||||
BYTE row, col;
|
||||
BYTE ship_cost;
|
||||
HMASTERSHIP hMasterShip;
|
||||
HSTARSHIP hBuiltShip;
|
||||
MASTER_SHIP_INFO *MasterPtr;
|
||||
STARSHIP *BuiltShipPtr;
|
||||
BYTE captains_name_index;
|
||||
|
||||
hMasterShip = GetStarShipFromIndex (&master_q, StarShip);
|
||||
MasterPtr = LockMasterShip (&master_q, hMasterShip);
|
||||
|
||||
captains_name_index = NameCaptain (&race_q[side],
|
||||
MasterPtr->SpeciesID);
|
||||
hBuiltShip = Build (&race_q[side], MasterPtr->SpeciesID);
|
||||
|
||||
// Draw the icon.
|
||||
row = PickMelee_GetShipRow (index);
|
||||
col = PickMelee_GetShipColumn (index);
|
||||
s.origin.x = 4 + ((ICON_WIDTH + 2) * col);
|
||||
s.origin.y = 10 + ((ICON_HEIGHT + 2) * row);
|
||||
s.frame = MasterPtr->ShipInfo.icons;
|
||||
DrawStamp (&s);
|
||||
|
||||
ship_cost = MasterPtr->ShipInfo.ship_cost;
|
||||
UnlockMasterShip (&master_q, hMasterShip);
|
||||
|
||||
BuiltShipPtr = LockStarShip (&race_q[side], hBuiltShip);
|
||||
BuiltShipPtr->index = index;
|
||||
BuiltShipPtr->ship_cost = ship_cost;
|
||||
BuiltShipPtr->playerNr = side;
|
||||
BuiltShipPtr->captains_name_index = captains_name_index;
|
||||
// The next ones are not used in Melee
|
||||
BuiltShipPtr->crew_level = 0;
|
||||
BuiltShipPtr->max_crew = 0;
|
||||
BuiltShipPtr->race_strings = 0;
|
||||
BuiltShipPtr->icons = 0;
|
||||
BuiltShipPtr->RaceDescPtr = 0;
|
||||
UnlockStarShip (&race_q[side], hBuiltShip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
void
|
||||
DestroyPickMeleeFrame (void)
|
||||
{
|
||||
DestroyDrawable (ReleaseDrawable (PickMeleeFrame));
|
||||
PickMeleeFrame = 0;
|
||||
}
|
||||
|
||||
// Pre: caller holds the graphics lock.
|
||||
static void
|
||||
DrawPickMeleeFrame (COUNT which_player)
|
||||
@@ -574,7 +765,7 @@ GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships)
|
||||
|
||||
gmstate.player[playerI].timeIn = now;
|
||||
gmstate.player[playerI].row = 0;
|
||||
gmstate.player[playerI].col = NUM_MELEE_COLS_ORIG;
|
||||
gmstate.player[playerI].col = NUM_PICKMELEE_COLUMNS;
|
||||
#ifdef NETPLAY
|
||||
gmstate.player[playerI].remoteSelected = FALSE;
|
||||
#endif
|
||||
@@ -764,7 +955,7 @@ reportShipSelected (GETMELEE_STATE *gms, COUNT index)
|
||||
if (!NetConnection_isConnected (conn))
|
||||
continue;
|
||||
|
||||
Netplay_selectShip (conn, index);
|
||||
Netplay_Notify_shipSelected (conn, index);
|
||||
}
|
||||
(void) gms;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,13 @@ typedef struct getmelee_struct GETMELEE_STATE;
|
||||
|
||||
#include "../races.h"
|
||||
#include "../battlecontrols.h"
|
||||
#include "meleesetup.h"
|
||||
#include "libs/compiler.h"
|
||||
|
||||
BOOLEAN MeleeShipDeath (STARSHIP *ship, COUNT which_player);
|
||||
void BuildPickMeleeFrame (void);
|
||||
void DestroyPickMeleeFrame (void);
|
||||
void FillPickMeleeFrame (MeleeSetup *setup);
|
||||
void MeleeGameOver (void);
|
||||
BOOLEAN GetInitialMeleeStarShips (HSTARSHIP *result);
|
||||
BOOLEAN GetNextMeleeStarShip (COUNT which_player, HSTARSHIP *result);
|
||||
|
||||
@@ -90,7 +90,7 @@ readyToEndCallback (NetConnection *conn, void *arg)
|
||||
NetConnection_setState (conn, NetState_endingBattle);
|
||||
if (battleFrameCount + 1 > battleStateData->endFrameCount)
|
||||
battleStateData->endFrameCount = battleFrameCount + 1;
|
||||
Netplay_sendFrameCount (conn, battleFrameCount + 1);
|
||||
Netplay_Notify_frameCount (conn, battleFrameCount + 1);
|
||||
// The +1 is to ensure that after the remote side receives the
|
||||
// frame count it will still receive one more frame data packet,
|
||||
// so it will know in advance when the last frame data packet
|
||||
|
||||
Reference in New Issue
Block a user