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:
meep-eep
2006-12-07 03:06:46 +00:00
parent 187d2084a7
commit 48af246772
12 changed files with 127 additions and 86 deletions
+6 -3
View File
@@ -90,11 +90,14 @@ Bugs:
to keep sync on games with a different resolution. to keep sync on games with a different resolution.
- Both sides need identical battle frame rates. This value is not - Both sides need identical battle frame rates. This value is not
negotiated. 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, - If there are packets in the packet queue when a connection is closed,
the callback that clears the queue isn't called in time. the callback that clears the queue isn't called in time.
- When the player returns from the SuperMelee menu to the main menu, - If one player closes the connection while the other player is selecting
all open connections should be closed. 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: Final actions:
+4 -7
View File
@@ -240,13 +240,6 @@ FreeBattleSong (void)
BattleRef = 0; BattleRef = 0;
} }
typedef struct battlestate_struct {
BOOLEAN (*InputFunc) (struct battlestate_struct *pInputState);
COUNT MenuRepeatDelay;
BOOLEAN first_time;
DWORD NextTime;
} BATTLE_STATE;
static BOOLEAN static BOOLEAN
DoBattle (BATTLE_STATE *bs) DoBattle (BATTLE_STATE *bs)
{ {
@@ -459,6 +452,7 @@ Battle (void)
#endif /* NETPLAY_CHECKSUM */ #endif /* NETPLAY_CHECKSUM */
battleFrameCount = 0; battleFrameCount = 0;
currentDeadSide = (COUNT)~0; currentDeadSide = (COUNT)~0;
setBattleStateConnections (&bs);
#endif /* NETPLAY */ #endif /* NETPLAY */
if (!selectAllShips (num_ships)) { if (!selectAllShips (num_ships)) {
@@ -492,12 +486,14 @@ AbortBattle:
{ {
// Do not return to the main menu when a game is aborted, // Do not return to the main menu when a game is aborted,
// (just to the supermelee menu). // (just to the supermelee menu).
#ifdef NETPLAY
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
waitResetConnections(NetState_inSetup); waitResetConnections(NetState_inSetup);
// A connection may already be in inSetup (set from // A connection may already be in inSetup (set from
// GetMeleeStarship). This is not a problem, although // GetMeleeStarship). This is not a problem, although
// it will generate a warning in debug mode. // it will generate a warning in debug mode.
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
#endif
GLOBAL (CurrentActivity) &= ~CHECK_ABORT; GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
} }
@@ -507,6 +503,7 @@ AbortBattle:
#ifdef NETPLAY_CHECKSUM #ifdef NETPLAY_CHECKSUM
uninitChecksumBuffers (); uninitChecksumBuffers ();
#endif /* NETPLAY_CHECKSUM */ #endif /* NETPLAY_CHECKSUM */
setBattleStateConnections (NULL);
#endif /* NETPLAY */ #endif /* NETPLAY */
StopMusic (); StopMusic ();
+7
View File
@@ -19,6 +19,13 @@
#include "libs/compiler.h" #include "libs/compiler.h"
#include "displist.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 QUEUE disp_q;
extern SIZE battle_counter; extern SIZE battle_counter;
extern BOOLEAN instantVictory; extern BOOLEAN instantVictory;
+40 -37
View File
@@ -3203,19 +3203,33 @@ confirmationCancelled(PMELEE_STATE pMS, COUNT side)
pMS->InputFunc = DoMelee; pMS->InputFunc = DoMelee;
} }
void static void
connectedFeedback (PMELEE_STATE pMS, COUNT side) { 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); LockMutex (GraphicsLock);
if (side == 0) DrawMeleeStatusMessage (str);
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 8)); UnlockMutex (GraphicsLock);
}
else
{
DoPopupWindow (str);
}
}
void
connectedFeedback (NetConnection *conn) {
if (NetConnection_getPlayerNr(conn) == 0)
connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 8));
// "Bottom player is connected." // "Bottom player is connected."
else else
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 9)); connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 9));
// "Top player is connected." // "Top player is connected."
UnlockMutex (GraphicsLock);
PlayMenuSound (MENU_SOUND_INVOKED); PlayMenuSound (MENU_SOUND_INVOKED);
(void) pMS;
} }
const char * const char *
@@ -3240,19 +3254,13 @@ abortReasonString (NetplayResetReason reason)
} }
void void
abortFeedback (COUNT side, NetplayAbortReason reason) abortFeedback (NetConnection *conn, NetplayAbortReason reason)
{ {
const char *msg; const char *msg;
msg = abortReasonString (reason); msg = abortReasonString (reason);
if (msg != NULL) if (msg != NULL)
{ connectionFeedback (conn, msg);
LockMutex (GraphicsLock);
DrawMeleeStatusMessage (msg);
UnlockMutex (GraphicsLock);
}
(void) side;
} }
const char * const char *
@@ -3276,11 +3284,18 @@ resetReasonString (NetplayResetReason reason)
} }
void void
resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote) resetFeedback (NetConnection *conn, NetplayResetReason reason,
bool byRemote)
{ {
const char *msg; const char *msg;
GLOBAL (CurrentActivity) |= CHECK_ABORT; 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) { if (reason == ResetReason_manualReset && !byRemote) {
// No message needed, the player initiated the reset. // No message needed, the player initiated the reset.
@@ -3289,41 +3304,29 @@ resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote)
msg = resetReasonString (reason); msg = resetReasonString (reason);
if (msg != NULL) if (msg != NULL)
{ connectionFeedback (conn, msg);
LockMutex (GraphicsLock);
DrawMeleeStatusMessage (msg);
UnlockMutex (GraphicsLock);
}
(void) side;
} }
void void
errorFeedback (PMELEE_STATE pMS, COUNT side) errorFeedback (NetConnection *conn)
{ {
LockMutex (GraphicsLock); if (NetConnection_getPlayerNr(conn) == 0)
if (side == 0) connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 10));
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 10));
// "Bottom player: connection failed." // "Bottom player: connection failed."
else else
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 11)); connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 11));
// "Top player: connection failed." // "Top player: connection failed."
UnlockMutex (GraphicsLock);
(void) pMS;
} }
void void
closeFeedback (PMELEE_STATE pMS, COUNT side) closeFeedback (NetConnection *conn)
{ {
LockMutex (GraphicsLock); if (NetConnection_getPlayerNr(conn) == 0)
if (side == 0) connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 12));
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 12));
// "Bottom player: connection closed." // "Bottom player: connection closed."
else else
DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 13)); connectionFeedback (conn, GAME_STRING (NETMELEE_STRING_BASE + 13));
// "Top player: connection closed." // "Top player: connection closed."
UnlockMutex (GraphicsLock);
(void) pMS;
} }
#endif /* NETPLAY */ #endif /* NETPLAY */
+6 -5
View File
@@ -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); bool updateFleetShip (PMELEE_STATE pMS, COUNT side, COUNT index, BYTE ship);
void updateRandomSeed (PMELEE_STATE pMS, COUNT side, DWORD seed); void updateRandomSeed (PMELEE_STATE pMS, COUNT side, DWORD seed);
void confirmationCancelled(PMELEE_STATE pMS, COUNT side); void confirmationCancelled(PMELEE_STATE pMS, COUNT side);
void connectedFeedback (PMELEE_STATE pMS, COUNT side); void connectedFeedback (NetConnection *conn);
void abortFeedback (COUNT side, NetplayAbortReason reason); void abortFeedback (NetConnection *conn, NetplayAbortReason reason);
void resetFeedback (COUNT side, NetplayResetReason reason, bool byRemote); void resetFeedback (NetConnection *conn, NetplayResetReason reason,
void errorFeedback (PMELEE_STATE pMS, COUNT side); bool byRemote);
void closeFeedback (PMELEE_STATE pMS, COUNT side); void errorFeedback (NetConnection *conn);
void closeFeedback (NetConnection *conn);
#endif /* _MELEE_H */ #endif /* _MELEE_H */
+42
View File
@@ -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. // Check the network connections for input.
void void
netInput(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 BATTLE_INPUT_STATE
networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr) { networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr) {
BattleInputBuffer *bib = getBattleInputBuffer(player); BattleInputBuffer *bib = getBattleInputBuffer(player);
+4
View File
@@ -37,6 +37,9 @@ void closeAllConnections(void);
void closeAllConnections(void); void closeAllConnections(void);
size_t getNumNetConnections(void); size_t getNumNetConnections(void);
struct melee_state *NetMelee_getMeleeState(NetConnection *conn);
struct battlestate_struct *NetMelee_getBattleState(NetConnection *conn);
void netInput(void); void netInput(void);
void netInputBlocking(uint32 timeoutMs); void netInputBlocking(uint32 timeoutMs);
void flushPacketQueues(void); void flushPacketQueues(void);
@@ -50,6 +53,7 @@ bool allConnected(void);
void sendBattleInputConnections(BATTLE_INPUT_STATE input); void sendBattleInputConnections(BATTLE_INPUT_STATE input);
void sendChecksumConnections(uint32 frameNr, uint32 checksum); void sendChecksumConnections(uint32 frameNr, uint32 checksum);
void initBattleStateDataConnections(void); void initBattleStateDataConnections(void);
void setBattleStateConnections(struct battlestate_struct *bs);
BATTLE_INPUT_STATE networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr); BATTLE_INPUT_STATE networkBattleInput(COUNT player, STARSHIPPTR StarShipPtr);
+10 -27
View File
@@ -33,6 +33,7 @@ static BattleStateData *BattleStateData_alloc(void);
static void BattleStateData_free(BattleStateData *battleStateData); static void BattleStateData_free(BattleStateData *battleStateData);
static inline BattleStateData *BattleStateData_new( static inline BattleStateData *BattleStateData_new(
struct melee_state *meleeState, struct melee_state *meleeState,
struct battlestate_struct *battleState,
struct getmelee_struct *getMeleeState); struct getmelee_struct *getMeleeState);
static void BattleStateData_delete(BattleStateData *battleStateData); static void BattleStateData_delete(BattleStateData *battleStateData);
@@ -49,11 +50,13 @@ BattleStateData_free(BattleStateData *battleStateData) {
static inline BattleStateData * static inline BattleStateData *
BattleStateData_new(struct melee_state *meleeState, BattleStateData_new(struct melee_state *meleeState,
struct battlestate_struct *battleState,
struct getmelee_struct *getMeleeState) { struct getmelee_struct *getMeleeState) {
BattleStateData *battleStateData = BattleStateData_alloc(); BattleStateData *battleStateData = BattleStateData_alloc();
battleStateData->releaseFunction = battleStateData->releaseFunction =
(NetConnectionStateData_ReleaseFunction) BattleStateData_delete; (NetConnectionStateData_ReleaseFunction) BattleStateData_delete;
battleStateData->meleeState = meleeState; battleStateData->meleeState = meleeState;
battleStateData->battleState = battleState;
battleStateData->getMeleeState = getMeleeState; battleStateData->getMeleeState = getMeleeState;
return battleStateData; return battleStateData;
} }
@@ -72,14 +75,6 @@ static void NetMelee_enterState_inSetup(NetConnection *conn, void *arg);
// Called when a connection has been established. // Called when a connection has been established.
void void
NetMelee_connectCallback(NetConnection *conn) { 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); sendInit(conn);
Netplay_localReady (conn, NetMelee_enterState_inSetup, NULL, false); Netplay_localReady (conn, NetMelee_enterState_inSetup, NULL, false);
} }
@@ -87,28 +82,14 @@ NetMelee_connectCallback(NetConnection *conn) {
// Called when a connection is closed. // Called when a connection is closed.
void void
NetMelee_closeCallback(NetConnection *conn) { NetMelee_closeCallback(NetConnection *conn) {
struct melee_state *meleeState; closeFeedback(conn);
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));
} }
// Called when a network error occurs during connect. // Called when a network error occurs during connect.
void void
NetMelee_errorCallback(NetConnection *conn, NetMelee_errorCallback(NetConnection *conn,
const NetConnectionError *error) { const NetConnectionError *error) {
void *meleeState; errorFeedback(conn);
meleeState = NetConnection_getExtra(conn);
errorFeedback(meleeState, NetConnection_getPlayerNr(conn));
(void) error; (void) error;
} }
@@ -122,12 +103,14 @@ NetMelee_enterState_inSetup(NetConnection *conn, void *arg) {
NetConnection_setState(conn, NetState_inSetup); NetConnection_setState(conn, NetState_inSetup);
battleStateData = (BattleStateData *) NetConnection_getStateData(conn); meleeState = (struct melee_state *) NetConnection_getExtra(conn);
meleeState = battleStateData->meleeState; battleStateData = BattleStateData_new(meleeState, NULL, NULL);
NetConnection_setStateData(conn, (void *) battleStateData);
NetConnection_setExtra(conn, NULL);
player = NetConnection_getPlayerNr(conn); player = NetConnection_getPlayerNr(conn);
connectedFeedback(meleeState, player); connectedFeedback(conn);
entireFleetChanged(meleeState, player); entireFleetChanged(meleeState, player);
teamStringChanged(meleeState, player); teamStringChanged(meleeState, player);
+1
View File
@@ -32,6 +32,7 @@ struct BattleStateData {
NETCONNECTION_STATE_DATA_COMMON NETCONNECTION_STATE_DATA_COMMON
struct melee_state *meleeState; struct melee_state *meleeState;
struct battlestate_struct *battleState;
struct getmelee_struct *getMeleeState; struct getmelee_struct *getMeleeState;
BattleFrameCounter endFrameCount; BattleFrameCounter endFrameCount;
}; };
+3 -3
View File
@@ -94,7 +94,7 @@ PacketHandler_Init(NetConnection *conn, const Packet_Init *packet) {
if (packet->protoVersion.major != NETPLAY_PROTOCOL_VERSION_MAJOR || if (packet->protoVersion.major != NETPLAY_PROTOCOL_VERSION_MAJOR ||
packet->protoVersion.minor != NETPLAY_PROTOCOL_VERSION_MINOR) { packet->protoVersion.minor != NETPLAY_PROTOCOL_VERSION_MINOR) {
sendAbort (conn, AbortReason_versionMismatch); sendAbort (conn, AbortReason_versionMismatch);
abortFeedback(conn->player, AbortReason_versionMismatch); abortFeedback(conn, AbortReason_versionMismatch);
log_add(log_Error, "Protocol version %d.%d not supported.\n", log_add(log_Error, "Protocol version %d.%d not supported.\n",
packet->protoVersion.major, packet->protoVersion.minor); packet->protoVersion.major, packet->protoVersion.minor);
errno = ENOSYS; errno = ENOSYS;
@@ -106,7 +106,7 @@ PacketHandler_Init(NetConnection *conn, const Packet_Init *packet) {
NETPLAY_MIN_UQM_VERSION_MINOR, NETPLAY_MIN_UQM_VERSION_PATCH) NETPLAY_MIN_UQM_VERSION_MINOR, NETPLAY_MIN_UQM_VERSION_PATCH)
< 0) { < 0) {
sendAbort (conn, AbortReason_versionMismatch); 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 " 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", "is too old (%d.%d.%d; %d.%d.%d is required).\n",
packet->uqmVersion.major, packet->uqmVersion.minor, packet->uqmVersion.major, packet->uqmVersion.minor,
@@ -662,7 +662,7 @@ PacketHandler_Checksum(NetConnection *conn, const Packet_Checksum *packet) {
int int
PacketHandler_Abort(NetConnection *conn, const Packet_Abort *packet) { PacketHandler_Abort(NetConnection *conn, const Packet_Abort *packet) {
abortFeedback(conn->player, packet->reason); abortFeedback(conn, packet->reason);
return -1; return -1;
// Close connection. // Close connection.
+2 -2
View File
@@ -83,7 +83,7 @@ Netplay_connectionReset(NetConnection *conn, NetplayResetReason reason,
case NetState_endingBattle: case NetState_endingBattle:
case NetState_endingBattle2: case NetState_endingBattle2:
case NetState_endMelee: case NetState_endMelee:
resetFeedback(conn->player, reason, byRemote); resetFeedback(conn, reason, byRemote);
break; break;
} }
} }
@@ -147,9 +147,9 @@ Netplay_remoteReset(NetConnection *conn, NetplayResetReason reason) {
conn->stateFlags.reset.remoteReset = true; conn->stateFlags.reset.remoteReset = true;
if (!conn->stateFlags.reset.localReset) { if (!conn->stateFlags.reset.localReset) {
Netplay_connectionReset(conn, reason, true);
sendReset(conn, reason); sendReset(conn, reason);
conn->stateFlags.reset.localReset = true; conn->stateFlags.reset.localReset = true;
Netplay_connectionReset(conn, reason, true);
} }
Netplay_resetConditionTriggered(conn); Netplay_resetConditionTriggered(conn);