Use popup windows for disconnect messages.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2575 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -90,11 +90,14 @@ Bugs:
|
||||
to keep sync on games with a different resolution.
|
||||
- Both sides need identical battle frame rates. This value is not
|
||||
negotiated.
|
||||
- When melee selection is aborted, the remote player will be stuck.
|
||||
- If there are packets in the packet queue when a connection is closed,
|
||||
the callback that clears the queue isn't called in time.
|
||||
- When the player returns from the SuperMelee menu to the main menu,
|
||||
all open connections should be closed.
|
||||
- If one player closes the connection while the other player is selecting
|
||||
a ship to put in his fleet, or loading a fleet, the "Network Control"
|
||||
button won't be updated.
|
||||
- Per state data (in NetConnection.stateData) is unnecessarilly complicated.
|
||||
Putting all fields directly in NetConnection simplifies things a lot.
|
||||
It's not as generic, but this code won't be used elsewhere anyhow.
|
||||
|
||||
|
||||
Final actions:
|
||||
|
||||
@@ -240,13 +240,6 @@ FreeBattleSong (void)
|
||||
BattleRef = 0;
|
||||
}
|
||||
|
||||
typedef struct battlestate_struct {
|
||||
BOOLEAN (*InputFunc) (struct battlestate_struct *pInputState);
|
||||
COUNT MenuRepeatDelay;
|
||||
BOOLEAN first_time;
|
||||
DWORD NextTime;
|
||||
} BATTLE_STATE;
|
||||
|
||||
static BOOLEAN
|
||||
DoBattle (BATTLE_STATE *bs)
|
||||
{
|
||||
@@ -459,6 +452,7 @@ Battle (void)
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
battleFrameCount = 0;
|
||||
currentDeadSide = (COUNT)~0;
|
||||
setBattleStateConnections (&bs);
|
||||
#endif /* NETPLAY */
|
||||
|
||||
if (!selectAllShips (num_ships)) {
|
||||
@@ -492,12 +486,14 @@ AbortBattle:
|
||||
{
|
||||
// Do not return to the main menu when a game is aborted,
|
||||
// (just to the supermelee menu).
|
||||
#ifdef NETPLAY
|
||||
UnlockMutex (GraphicsLock);
|
||||
waitResetConnections(NetState_inSetup);
|
||||
// A connection may already be in inSetup (set from
|
||||
// GetMeleeStarship). This is not a problem, although
|
||||
// it will generate a warning in debug mode.
|
||||
LockMutex (GraphicsLock);
|
||||
#endif
|
||||
|
||||
GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
|
||||
}
|
||||
@@ -507,6 +503,7 @@ AbortBattle:
|
||||
#ifdef NETPLAY_CHECKSUM
|
||||
uninitChecksumBuffers ();
|
||||
#endif /* NETPLAY_CHECKSUM */
|
||||
setBattleStateConnections (NULL);
|
||||
#endif /* NETPLAY */
|
||||
|
||||
StopMusic ();
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
#include "libs/compiler.h"
|
||||
#include "displist.h"
|
||||
|
||||
typedef struct battlestate_struct {
|
||||
BOOLEAN (*InputFunc) (struct battlestate_struct *pInputState);
|
||||
COUNT MenuRepeatDelay;
|
||||
BOOLEAN first_time;
|
||||
DWORD NextTime;
|
||||
} BATTLE_STATE;
|
||||
|
||||
extern QUEUE disp_q;
|
||||
extern SIZE battle_counter;
|
||||
extern BOOLEAN instantVictory;
|
||||
|
||||
+40
-37
@@ -3203,19 +3203,33 @@ confirmationCancelled(PMELEE_STATE pMS, COUNT side)
|
||||
pMS->InputFunc = DoMelee;
|
||||
}
|
||||
|
||||
static void
|
||||
connectionFeedback (NetConnection *conn, const char *str) {
|
||||
struct battlestate_struct *bs = NetMelee_getBattleState (conn);
|
||||
|
||||
if (bs == NULL)
|
||||
{
|
||||
// bs == NULL means the game has started.
|
||||
LockMutex (GraphicsLock);
|
||||
DrawMeleeStatusMessage (str);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoPopupWindow (str);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
connectedFeedback (PMELEE_STATE pMS, COUNT side) {
|
||||
LockMutex (GraphicsLock);
|
||||
if (side == 0)
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 8));
|
||||
connectedFeedback (NetConnection *conn) {
|
||||
if (NetConnection_getPlayerNr(conn) == 0)
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 8));
|
||||
// "Bottom player is connected."
|
||||
else
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 9));
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 9));
|
||||
// "Top player is connected."
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
PlayMenuSound (MENU_SOUND_INVOKED);
|
||||
(void) pMS;
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -3240,19 +3254,13 @@ abortReasonString (NetplayResetReason reason)
|
||||
}
|
||||
|
||||
void
|
||||
abortFeedback (COUNT side, NetplayAbortReason reason)
|
||||
abortFeedback (NetConnection *conn, NetplayAbortReason reason)
|
||||
{
|
||||
const char *msg;
|
||||
|
||||
msg = abortReasonString (reason);
|
||||
if (msg != NULL)
|
||||
{
|
||||
LockMutex (GraphicsLock);
|
||||
DrawMeleeStatusMessage (msg);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
(void) side;
|
||||
connectionFeedback (conn, msg);
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -3276,11 +3284,18 @@ resetReasonString (NetplayResetReason reason)
|
||||
}
|
||||
|
||||
void
|
||||
resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote)
|
||||
resetFeedback (NetConnection *conn, NetplayResetReason reason,
|
||||
bool byRemote)
|
||||
{
|
||||
const char *msg;
|
||||
|
||||
GLOBAL (CurrentActivity) |= CHECK_ABORT;
|
||||
flushPacketQueues ();
|
||||
// If the local side queued a reset packet as a result of a
|
||||
// remote reset, that packet will not have been sent yet.
|
||||
// We flush the queue now, so that the remote side won't be
|
||||
// waiting for the reset packet while this side is waiting
|
||||
// for an acknowledgement of the feedback message.
|
||||
|
||||
if (reason == ResetReason_manualReset && !byRemote) {
|
||||
// No message needed, the player initiated the reset.
|
||||
@@ -3289,41 +3304,29 @@ resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote)
|
||||
|
||||
msg = resetReasonString (reason);
|
||||
if (msg != NULL)
|
||||
{
|
||||
LockMutex (GraphicsLock);
|
||||
DrawMeleeStatusMessage (msg);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
(void) side;
|
||||
connectionFeedback (conn, msg);
|
||||
}
|
||||
|
||||
void
|
||||
errorFeedback (PMELEE_STATE pMS, COUNT side)
|
||||
errorFeedback (NetConnection *conn)
|
||||
{
|
||||
LockMutex (GraphicsLock);
|
||||
if (side == 0)
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 10));
|
||||
if (NetConnection_getPlayerNr(conn) == 0)
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 10));
|
||||
// "Bottom player: connection failed."
|
||||
else
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 11));
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 11));
|
||||
// "Top player: connection failed."
|
||||
UnlockMutex (GraphicsLock);
|
||||
(void) pMS;
|
||||
}
|
||||
|
||||
void
|
||||
closeFeedback (PMELEE_STATE pMS, COUNT side)
|
||||
closeFeedback (NetConnection *conn)
|
||||
{
|
||||
LockMutex (GraphicsLock);
|
||||
if (side == 0)
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 12));
|
||||
if (NetConnection_getPlayerNr(conn) == 0)
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 12));
|
||||
// "Bottom player: connection closed."
|
||||
else
|
||||
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 13));
|
||||
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 13));
|
||||
// "Top player: connection closed."
|
||||
UnlockMutex (GraphicsLock);
|
||||
(void) pMS;
|
||||
}
|
||||
|
||||
#endif /* NETPLAY */
|
||||
|
||||
@@ -124,11 +124,12 @@ void updateTeamName (PMELEE_STATE pMS, COUNT side, const char *name,
|
||||
bool updateFleetShip (PMELEE_STATE pMS, COUNT side, COUNT index, BYTE ship);
|
||||
void updateRandomSeed (PMELEE_STATE pMS, COUNT side, DWORD seed);
|
||||
void confirmationCancelled(PMELEE_STATE pMS, COUNT side);
|
||||
void connectedFeedback (PMELEE_STATE pMS, COUNT side);
|
||||
void abortFeedback (COUNT side, NetplayAbortReason reason);
|
||||
void resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote);
|
||||
void errorFeedback (PMELEE_STATE pMS, COUNT side);
|
||||
void closeFeedback (PMELEE_STATE pMS, COUNT side);
|
||||
void connectedFeedback (NetConnection *conn);
|
||||
void abortFeedback (NetConnection *conn, NetplayAbortReason reason);
|
||||
void resetFeedback (NetConnection *conn, NetplayResetReason reason,
|
||||
bool byRemote);
|
||||
void errorFeedback (NetConnection *conn);
|
||||
void closeFeedback (NetConnection *conn);
|
||||
|
||||
#endif /* _MELEE_H */
|
||||
|
||||
|
||||
@@ -83,6 +83,31 @@ getNumNetConnections(void) {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct melee_state *
|
||||
NetMelee_getMeleeState(NetConnection *conn) {
|
||||
if (NetConnection_getState(conn) > NetState_connecting) {
|
||||
BattleStateData *battleStateData =
|
||||
(BattleStateData *) NetConnection_getStateData(conn);
|
||||
return battleStateData->meleeState;
|
||||
} else {
|
||||
return (struct melee_state *) NetConnection_getExtra(conn);
|
||||
}
|
||||
}
|
||||
|
||||
struct battlestate_struct *
|
||||
NetMelee_getBattleState(NetConnection *conn) {
|
||||
if (NetConnection_getState(conn) > NetState_connecting) {
|
||||
BattleStateData *battleStateData =
|
||||
(BattleStateData *) NetConnection_getStateData(conn);
|
||||
return battleStateData->battleState;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Check the network connections for input.
|
||||
void
|
||||
netInput(void) {
|
||||
@@ -260,6 +285,23 @@ initBattleStateDataConnections(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setBattleStateConnections(struct battlestate_struct *bs) {
|
||||
COUNT player;
|
||||
|
||||
for (player = 0; player < NUM_PLAYERS; player++)
|
||||
{
|
||||
BattleStateData *battleStateData;
|
||||
NetConnection *conn = netConnections[player];
|
||||
if (conn == NULL)
|
||||
continue;
|
||||
|
||||
battleStateData =
|
||||
(BattleStateData *) NetConnection_getStateData(conn);
|
||||
battleStateData->battleState = bs;
|
||||
}
|
||||
}
|
||||
|
||||
BATTLE_INPUT_STATE
|
||||
networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr) {
|
||||
BattleInputBuffer *bib = getBattleInputBuffer(player);
|
||||
|
||||
@@ -37,6 +37,9 @@ void closeAllConnections(void);
|
||||
void closeAllConnections(void);
|
||||
size_t getNumNetConnections(void);
|
||||
|
||||
struct melee_state *NetMelee_getMeleeState(NetConnection *conn);
|
||||
struct battlestate_struct *NetMelee_getBattleState(NetConnection *conn);
|
||||
|
||||
void netInput(void);
|
||||
void netInputBlocking(uint32 timeoutMs);
|
||||
void flushPacketQueues(void);
|
||||
@@ -50,6 +53,7 @@ bool allConnected(void);
|
||||
void sendBattleInputConnections(BATTLE_INPUT_STATE input);
|
||||
void sendChecksumConnections(uint32 frameNr, uint32 checksum);
|
||||
void initBattleStateDataConnections(void);
|
||||
void setBattleStateConnections(struct battlestate_struct *bs);
|
||||
|
||||
BATTLE_INPUT_STATE networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ static BattleStateData *BattleStateData_alloc(void);
|
||||
static void BattleStateData_free(BattleStateData *battleStateData);
|
||||
static inline BattleStateData *BattleStateData_new(
|
||||
struct melee_state *meleeState,
|
||||
struct battlestate_struct *battleState,
|
||||
struct getmelee_struct *getMeleeState);
|
||||
static void BattleStateData_delete(BattleStateData *battleStateData);
|
||||
|
||||
@@ -49,11 +50,13 @@ BattleStateData_free(BattleStateData *battleStateData) {
|
||||
|
||||
static inline BattleStateData *
|
||||
BattleStateData_new(struct melee_state *meleeState,
|
||||
struct battlestate_struct *battleState,
|
||||
struct getmelee_struct *getMeleeState) {
|
||||
BattleStateData *battleStateData = BattleStateData_alloc();
|
||||
battleStateData->releaseFunction =
|
||||
(NetConnectionStateData_ReleaseFunction) BattleStateData_delete;
|
||||
battleStateData->meleeState = meleeState;
|
||||
battleStateData->battleState = battleState;
|
||||
battleStateData->getMeleeState = getMeleeState;
|
||||
return battleStateData;
|
||||
}
|
||||
@@ -72,14 +75,6 @@ static void NetMelee_enterState_inSetup(NetConnection *conn, void *arg);
|
||||
// Called when a connection has been established.
|
||||
void
|
||||
NetMelee_connectCallback(NetConnection *conn) {
|
||||
BattleStateData *battleStateData;
|
||||
struct melee_state *meleeState;
|
||||
|
||||
meleeState = (struct melee_state *) NetConnection_getExtra(conn);
|
||||
battleStateData = BattleStateData_new(meleeState, NULL);
|
||||
NetConnection_setStateData(conn, (void *) battleStateData);
|
||||
NetConnection_setExtra(conn, NULL);
|
||||
|
||||
sendInit(conn);
|
||||
Netplay_localReady (conn, NetMelee_enterState_inSetup, NULL, false);
|
||||
}
|
||||
@@ -87,28 +82,14 @@ NetMelee_connectCallback(NetConnection *conn) {
|
||||
// Called when a connection is closed.
|
||||
void
|
||||
NetMelee_closeCallback(NetConnection *conn) {
|
||||
struct melee_state *meleeState;
|
||||
|
||||
if (NetConnection_getState(conn) > NetState_connecting) {
|
||||
BattleStateData *battleStateData =
|
||||
(BattleStateData *) NetConnection_getStateData(conn);
|
||||
meleeState = battleStateData->meleeState;
|
||||
} else {
|
||||
meleeState = (struct melee_state *) NetConnection_getExtra(conn);
|
||||
}
|
||||
|
||||
closeFeedback(meleeState, NetConnection_getPlayerNr(conn));
|
||||
closeFeedback(conn);
|
||||
}
|
||||
|
||||
// Called when a network error occurs during connect.
|
||||
void
|
||||
NetMelee_errorCallback(NetConnection *conn,
|
||||
const NetConnectionError *error) {
|
||||
void *meleeState;
|
||||
|
||||
meleeState = NetConnection_getExtra(conn);
|
||||
errorFeedback(meleeState, NetConnection_getPlayerNr(conn));
|
||||
|
||||
errorFeedback(conn);
|
||||
(void) error;
|
||||
}
|
||||
|
||||
@@ -122,12 +103,14 @@ NetMelee_enterState_inSetup(NetConnection *conn, void *arg) {
|
||||
|
||||
NetConnection_setState(conn, NetState_inSetup);
|
||||
|
||||
battleStateData = (BattleStateData *) NetConnection_getStateData(conn);
|
||||
meleeState = battleStateData->meleeState;
|
||||
meleeState = (struct melee_state *) NetConnection_getExtra(conn);
|
||||
battleStateData = BattleStateData_new(meleeState, NULL, NULL);
|
||||
NetConnection_setStateData(conn, (void *) battleStateData);
|
||||
NetConnection_setExtra(conn, NULL);
|
||||
|
||||
player = NetConnection_getPlayerNr(conn);
|
||||
|
||||
connectedFeedback(meleeState, player);
|
||||
connectedFeedback(conn);
|
||||
|
||||
entireFleetChanged(meleeState, player);
|
||||
teamStringChanged(meleeState, player);
|
||||
|
||||
@@ -32,6 +32,7 @@ struct BattleStateData {
|
||||
NETCONNECTION_STATE_DATA_COMMON
|
||||
|
||||
struct melee_state *meleeState;
|
||||
struct battlestate_struct *battleState;
|
||||
struct getmelee_struct *getMeleeState;
|
||||
BattleFrameCounter endFrameCount;
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef void (*NetConnectionStateData_ReleaseFunction)(
|
||||
NetConnectionStateData *stateData);
|
||||
|
||||
#define NETCONNECTION_STATE_DATA_COMMON \
|
||||
NetConnectionStateData_ReleaseFunction releaseFunction;
|
||||
NetConnectionStateData_ReleaseFunction releaseFunction;
|
||||
|
||||
struct
|
||||
NetConnectionStateData {
|
||||
|
||||
@@ -94,7 +94,7 @@ PacketHandler_Init(NetConnection *conn, const Packet_Init *packet) {
|
||||
if (packet->protoVersion.major != NETPLAY_PROTOCOL_VERSION_MAJOR ||
|
||||
packet->protoVersion.minor != NETPLAY_PROTOCOL_VERSION_MINOR) {
|
||||
sendAbort (conn, AbortReason_versionMismatch);
|
||||
abortFeedback(conn->player, AbortReason_versionMismatch);
|
||||
abortFeedback(conn, AbortReason_versionMismatch);
|
||||
log_add(log_Error, "Protocol version %d.%d not supported.\n",
|
||||
packet->protoVersion.major, packet->protoVersion.minor);
|
||||
errno = ENOSYS;
|
||||
@@ -106,7 +106,7 @@ PacketHandler_Init(NetConnection *conn, const Packet_Init *packet) {
|
||||
NETPLAY_MIN_UQM_VERSION_MINOR, NETPLAY_MIN_UQM_VERSION_PATCH)
|
||||
< 0) {
|
||||
sendAbort (conn, AbortReason_versionMismatch);
|
||||
abortFeedback(conn->player, AbortReason_versionMismatch);
|
||||
abortFeedback(conn, AbortReason_versionMismatch);
|
||||
log_add(log_Error, "Remote side is running a version of UQM that "
|
||||
"is too old (%d.%d.%d; %d.%d.%d is required).\n",
|
||||
packet->uqmVersion.major, packet->uqmVersion.minor,
|
||||
@@ -662,7 +662,7 @@ PacketHandler_Checksum(NetConnection *conn, const Packet_Checksum *packet) {
|
||||
|
||||
int
|
||||
PacketHandler_Abort(NetConnection *conn, const Packet_Abort *packet) {
|
||||
abortFeedback(conn->player, packet->reason);
|
||||
abortFeedback(conn, packet->reason);
|
||||
|
||||
return -1;
|
||||
// Close connection.
|
||||
|
||||
@@ -83,7 +83,7 @@ Netplay_connectionReset(NetConnection *conn, NetplayResetReason reason,
|
||||
case NetState_endingBattle:
|
||||
case NetState_endingBattle2:
|
||||
case NetState_endMelee:
|
||||
resetFeedback(conn->player, reason, byRemote);
|
||||
resetFeedback(conn, reason, byRemote);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -147,9 +147,9 @@ Netplay_remoteReset(NetConnection *conn, NetplayResetReason reason) {
|
||||
|
||||
conn->stateFlags.reset.remoteReset = true;
|
||||
if (!conn->stateFlags.reset.localReset) {
|
||||
Netplay_connectionReset(conn, reason, true);
|
||||
sendReset(conn, reason);
|
||||
conn->stateFlags.reset.localReset = true;
|
||||
Netplay_connectionReset(conn, reason, true);
|
||||
}
|
||||
|
||||
Netplay_resetConditionTriggered(conn);
|
||||
|
||||
Reference in New Issue
Block a user