From 08be64a61c92f668c9f8859ef0546fde296d2666 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Mon, 28 Jun 2021 00:03:32 -0400 Subject: [PATCH] Add some more prompts to be clearer when the network is busy. Allow the user to retry uploading their score. Even if things go wrong, add a retry mechanism so that we will try to get the network connection up after three minutes. --- BuGS/game.s | 30 +++++++++++++++ BuGS/globalScores.c | 60 ++++++++++++++++++++++++++---- BuGS/globalScores.h | 11 ++++++ BuGS/score.s | 89 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 7 deletions(-) diff --git a/BuGS/game.s b/BuGS/game.s index 7c2c4bb..b34cea9 100644 --- a/BuGS/game.s +++ b/BuGS/game.s @@ -1123,6 +1123,36 @@ staticGameBoard_cont anop rtl +displayConnectionString entry + ldx #GAME_NUM_TILES_WIDE*2 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_C + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_C + _overwriteGameTile TILE_LETTER_T + _overwriteGameTile TILE_LETTER_I + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_LETTER_G + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_T + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_T + _overwriteGameTile TILE_LETTER_W + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_LETTER_K + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + rtl + + checkKeyboard entry checkKey_loop2 anop short i,m diff --git a/BuGS/globalScores.c b/BuGS/globalScores.c index fccec8b..33c728a 100644 --- a/BuGS/globalScores.c +++ b/BuGS/globalScores.c @@ -33,6 +33,7 @@ #define GLOBAL_SCORE_REFRESH_TIME (15 * 60 * 60) #define SHUTDOWN_NETWORK_TIMEOUT (2 * 60) #define READ_NETWORK_TIMEOUT (5 * 60) +#define NETWORK_RETRY_TIMEOUT (3 * 60 * 60) // Types @@ -348,6 +349,7 @@ void pollNetwork(void) switch (networkGlobals->gameNetworkState) { case GAME_NETWORK_SOCKET_ERROR: displayNetworkError("SOCKET", "ERROR"); + networkGlobals->timeout = NETWORK_RETRY_TIMEOUT; break; case GAME_NETWORK_LOOKUP_FAILED: @@ -356,20 +358,28 @@ void pollNetwork(void) case GAME_NETWORK_CONNECT_FAILED: displayNetworkError("CONNECT", "FAILED"); + networkGlobals->timeout = NETWORK_RETRY_TIMEOUT; break; case GAME_NETWORK_PROTOCOL_FAILED: abortConnection(); displayNetworkError("PROTOCOL", "FAILED"); + networkGlobals->timeout = NETWORK_RETRY_TIMEOUT; break; case GAME_NETWORK_FAILURE: // All of the different failure modes except protocol failure above end up here ultimately. And the state // machine stays here once it arrives here. + if (networkGlobals->timeout > 0) { + networkGlobals->timeout--; + if (networkGlobals->timeout == 0) + networkGlobals->gameNetworkState = GAME_NETWORK_TCP_UNCONNECTED; + } break; case GAME_NETWORK_UNCONNECTED: - TCPIPConnect(NULL); // TODO - Perhaps some feedback here would be a better user experience so maybe I should provide some kind of display function. + displayConnectionString(); + TCPIPConnect(NULL); if ((!toolerror()) && (TCPIPGetConnectStatus())) { networkGlobals->gameNetworkState = GAME_NETWORK_CONNECTED; @@ -640,20 +650,56 @@ void pollNetwork(void) } -void sendHighScore(void) +BOOLEAN canSendHighScore(void) { if (networkGlobals == NULL) - return; + return FALSE; - if (networkGlobals->gameNetworkState < GAME_NETWORK_TCP_UNCONNECTED) - return; + if (networkGlobals->gameNetworkState < GAME_NETWORK_TCP_UNCONNECTED) { + if ((networkGlobals->gameNetworkState == GAME_NETWORK_FAILURE) && + (networkGlobals->timeout > 0)) + return TRUE; + + return FALSE; + } + + return TRUE; +} + +BOOLEAN sendHighScore(void) +{ + uint16_t cycleCount = 0; networkGlobals->hasHighScoreToSend = TRUE; + if (networkGlobals->gameNetworkState < GAME_NETWORK_TCP_UNCONNECTED) + networkGlobals->gameNetworkState = GAME_NETWORK_TCP_UNCONNECTED; + do { waitForVbl(); pollNetwork(); - // TODO - Provide some feedback that the score is being uploaded here. - // TODO - If there is a timeout, or a failure of some kind, perhaps ask the user if they would like to retry. + cycleCount++; + + if ((cycleCount & 0x7) == 0) { + switch (cycleCount & 0x18) { + case 0x00: + uploadSpin1(); + break; + + case 0x08: + uploadSpin2(); + break; + + case 0x10: + uploadSpin1(); + break; + + case 0x18: + uploadSpin2(); + break; + } + } } while (networkGlobals->gameNetworkState > GAME_NETWORK_TCP_UNCONNECTED); + + return (networkGlobals->gameNetworkState == GAME_NETWORK_TCP_UNCONNECTED); } diff --git a/BuGS/globalScores.h b/BuGS/globalScores.h index 146063c..5f727e3 100644 --- a/BuGS/globalScores.h +++ b/BuGS/globalScores.h @@ -10,6 +10,9 @@ #define _GUARD_PROJECTBuGS_FILEglobalScores_ +#include + + typedef struct tHighScore { char scoreText[10]; @@ -23,6 +26,14 @@ extern void initNetwork(void); extern void disconnectNetwork(void); extern void pollNetwork(void); extern void shutdownNetwork(void); +extern BOOLEAN canSendHighScore(void); +extern BOOLEAN sendHighScore(void); + +// These are actually assembly functions called from the C code. +extern void uploadSpin1(void); +extern void uploadSpin2(void); +extern void uploadSpin3(void); +extern void displayConnectionString(void); #endif /* define _GUARD_PROJECTBuGS_FILEglobalScores_ */ diff --git a/BuGS/score.s b/BuGS/score.s index 61bd49c..8c0e1b1 100644 --- a/BuGS/score.s +++ b/BuGS/score.s @@ -773,11 +773,100 @@ checkHighScore_doneInitials anop lda settings+SETTINGS_HIGH_SCORE_OFFSET+HIGH_SCORE_WHO_OFFSET-1,y sta setHighScoreRequest+4 jsl saveSettings + jsl canSendHighScore + bne checkHighScore_retry + brl checkHighScore_doneNetwork + +checkHighScore_retry anop + ldx #GAME_NUM_TILES_WIDE*22+2 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_U + _overwriteGameTile TILE_LETTER_P + _overwriteGameTile TILE_LETTER_L + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_LETTER_A + _overwriteGameTile TILE_LETTER_D + _overwriteGameTile TILE_LETTER_I + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_LETTER_G + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_S + _overwriteGameTile TILE_LETTER_C + _overwriteGameTile TILE_LETTER_O + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_SOLID1 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY jsl sendHighScore + beq checkHighScore_retryPrompt + brl checkHighScore_doneNetwork + +checkHighScore_retryPrompt anop + ldx #GAME_NUM_TILES_WIDE*22+2 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_F + _overwriteGameTile TILE_LETTER_A + _overwriteGameTile TILE_LETTER_I + _overwriteGameTile TILE_LETTER_L + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_D + _overwriteGameTile TILE_SYMBOL_COLON + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_LETTER_E + _overwriteGameTile TILE_LETTER_T + _overwriteGameTile TILE_LETTER_R + _overwriteGameTile TILE_LETTER_Y + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_LETTER_Y + _overwriteGameTile TILE_SYMBOL_COLON + _overwriteGameTile TILE_LETTER_N + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + + jsl waitForKey + and #$df + cmp #'N' + beq checkHighScore_doneNetwork + cmp #'Y' + bne checkHighScore_doRetry + brl checkHighScore_retry +checkHighScore_doRetry anop + brl checkHighScore_retryPrompt + +checkHighScore_doneNetwork anop jsl updateHighScore sec rtl + +uploadSpin1 entry + ldx #GAME_NUM_TILES_WIDE*22+36 + _overwriteGameTile TILE_SOLID1 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + rtl + + +uploadSpin2 entry + ldx #GAME_NUM_TILES_WIDE*22+36 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_SOLID1 + _overwriteGameTile TILE_EMPTY + rtl + + +uploadSpin3 entry + ldx #GAME_NUM_TILES_WIDE*22+36 + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_EMPTY + _overwriteGameTile TILE_SOLID1 + rtl + scoreIndex dc i2'0'