mirror of https://github.com/jeremysrand/BuGS.git
More work isolating the global high score code from the game so it can be made a generic library.
This commit is contained in:
parent
b8b9089aa2
commit
37faafb698
|
@ -9,6 +9,12 @@
|
||||||
#ifndef _GUARD_PROJECTBuGS_FILEgame_
|
#ifndef _GUARD_PROJECTBuGS_FILEgame_
|
||||||
#define _GUARD_PROJECTBuGS_FILEgame_
|
#define _GUARD_PROJECTBuGS_FILEgame_
|
||||||
|
|
||||||
|
|
||||||
|
#include "tileData.h"
|
||||||
|
|
||||||
|
// These are globals used from assembly.
|
||||||
|
extern char globalScoreInfo[GAME_NUM_TILES_WIDE + 1];
|
||||||
|
|
||||||
// These are assembly functions called from C.
|
// These are assembly functions called from C.
|
||||||
|
|
||||||
extern void game(void);
|
extern void game(void);
|
||||||
|
@ -18,6 +24,7 @@ extern void uploadSpin1(void);
|
||||||
extern void uploadSpin2(void);
|
extern void uploadSpin2(void);
|
||||||
extern void uploadSpin3(void);
|
extern void uploadSpin3(void);
|
||||||
extern void displayConnectionString(void);
|
extern void displayConnectionString(void);
|
||||||
|
extern void displayScorePosition(void);
|
||||||
extern void swapStereoChannels(void);
|
extern void swapStereoChannels(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,6 @@ updateScorpion_explosionDone anop
|
||||||
|
|
||||||
|
|
||||||
setScorpionSpeed entry
|
setScorpionSpeed entry
|
||||||
; TODO - Call this code with each level to set the scorpion speed
|
|
||||||
cmp #SPRITE_SPEED_FAST
|
cmp #SPRITE_SPEED_FAST
|
||||||
beq setScorpionSpeed_fast
|
beq setScorpionSpeed_fast
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,14 @@ _drawDirtyGameRow_wait&rowNum anop
|
||||||
; offset numbers.
|
; offset numbers.
|
||||||
;
|
;
|
||||||
; Also according to that technote, it looks like these numbers are different
|
; Also according to that technote, it looks like these numbers are different
|
||||||
; in PAL mode. TODO - Do I need something here to handle PAL correctly? I
|
; in PAL mode. Do I need something here to handle PAL correctly? I switched
|
||||||
; switched my GS to 50Hz mode (startup/reboot with option held down to get the
|
; my GS to 50Hz mode (startup/reboot with option held down to get the menu)
|
||||||
; menu) and I didnt't detect any graphics glitches at all. I did notice that
|
; and I didnt't detect any graphics glitches at all. I did notice that the
|
||||||
; the game is noticably easier because things run a bit slower. If I do an
|
; game is noticably easier because things run a bit slower. If I do an online
|
||||||
; online score system, I should record whether a score was gotten at 50Hz vs
|
; score system, I should record whether a score was gotten at 50Hz vs 60Hz.
|
||||||
; 60Hz.
|
; (and in fact, I have since implemented online high scores and record the
|
||||||
|
; frequency at which the game was played)
|
||||||
|
|
||||||
lda >VERTICAL_COUNTER ; load the counter value
|
lda >VERTICAL_COUNTER ; load the counter value
|
||||||
and #$80ff ; mask out the VBL bits
|
and #$80ff ; mask out the VBL bits
|
||||||
asl a ; shift the word around
|
asl a ; shift the word around
|
||||||
|
|
|
@ -140,6 +140,7 @@ typedef enum tGameNetworkState {
|
||||||
|
|
||||||
typedef struct tGameNetworkGlobals {
|
typedef struct tGameNetworkGlobals {
|
||||||
Boolean networkStartedConnected;
|
Boolean networkStartedConnected;
|
||||||
|
tHighScoreInitParams initParams;
|
||||||
tGameNetworkState gameNetworkState;
|
tGameNetworkState gameNetworkState;
|
||||||
dnrBuffer domainNameResolution;
|
dnrBuffer domainNameResolution;
|
||||||
srBuff tcpStatus;
|
srBuff tcpStatus;
|
||||||
|
@ -152,7 +153,6 @@ typedef struct tGameNetworkGlobals {
|
||||||
tHighScoreRequestWithHash highScoreRequest;
|
tHighScoreRequestWithHash highScoreRequest;
|
||||||
Boolean hasHighScoreToSend;
|
Boolean hasHighScoreToSend;
|
||||||
tStatusResponse setHighScoreResponse;
|
tStatusResponse setHighScoreResponse;
|
||||||
tHighScoreInitParams initParams;
|
|
||||||
uint16_t errorCode;
|
uint16_t errorCode;
|
||||||
uint16_t timeout;
|
uint16_t timeout;
|
||||||
} tGameNetworkGlobals;
|
} tGameNetworkGlobals;
|
||||||
|
@ -167,11 +167,11 @@ static tGameNetworkGlobals * networkGlobals = NULL;
|
||||||
|
|
||||||
// The following globals are accessed by name from assembly so are not in the
|
// The following globals are accessed by name from assembly so are not in the
|
||||||
// tGameNetworkGlobals structure.
|
// tGameNetworkGlobals structure.
|
||||||
|
// TODO - Make real interfaces for these things.
|
||||||
Boolean hasGlobalHighScores = FALSE;
|
Boolean hasGlobalHighScores = FALSE;
|
||||||
tScoresResponse highScoreResponse;
|
tScoresResponse highScoreResponse;
|
||||||
Word globalScoreAge = 0;
|
Word globalScoreAge = 0; // TODO - Replace this with a call to a MiscTool function?
|
||||||
tSetHighScoreRequestWithHash setHighScoreRequest;
|
tSetHighScoreRequestWithHash setHighScoreRequest;
|
||||||
char globalScoreInfo[26];
|
|
||||||
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
|
@ -383,7 +383,7 @@ void pollNetwork(void)
|
||||||
|
|
||||||
case GAME_NETWORK_UNCONNECTED:
|
case GAME_NETWORK_UNCONNECTED:
|
||||||
if (networkGlobals->initParams.displayConnectionString != NULL)
|
if (networkGlobals->initParams.displayConnectionString != NULL)
|
||||||
networkGlobals->initParams.displayConnectionString();
|
networkGlobals->initParams.displayConnectionString(TRUE);
|
||||||
TCPIPConnect(NULL);
|
TCPIPConnect(NULL);
|
||||||
if ((!toolerror()) &&
|
if ((!toolerror()) &&
|
||||||
(TCPIPGetConnectStatus())) {
|
(TCPIPGetConnectStatus())) {
|
||||||
|
@ -391,6 +391,8 @@ void pollNetwork(void)
|
||||||
} else {
|
} else {
|
||||||
networkGlobals->gameNetworkState = GAME_NETWORK_CONNECT_FAILED;
|
networkGlobals->gameNetworkState = GAME_NETWORK_CONNECT_FAILED;
|
||||||
}
|
}
|
||||||
|
if (networkGlobals->initParams.displayConnectionString != NULL)
|
||||||
|
networkGlobals->initParams.displayConnectionString(FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GAME_NETWORK_CONNECTED:
|
case GAME_NETWORK_CONNECTED:
|
||||||
|
@ -721,16 +723,9 @@ BOOLEAN sendHighScore(void)
|
||||||
if (networkGlobals->gameNetworkState != GAME_NETWORK_TCP_UNCONNECTED)
|
if (networkGlobals->gameNetworkState != GAME_NETWORK_TCP_UNCONNECTED)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
sprintf(globalScoreInfo, " %u OF %u SCORES", networkGlobals->setHighScoreResponse.position, networkGlobals->setHighScoreResponse.numberOfScores);
|
if (networkGlobals->initParams.scorePosition != NULL)
|
||||||
for (cycleCount = strlen(globalScoreInfo); cycleCount < sizeof(globalScoreInfo); cycleCount++) {
|
networkGlobals->initParams.scorePosition(networkGlobals->setHighScoreResponse.position,
|
||||||
globalScoreInfo[cycleCount] = ' ';
|
networkGlobals->setHighScoreResponse.numberOfScores);
|
||||||
}
|
|
||||||
globalScoreInfo[25] = '\0'; // TODO - Get rid of hard coded value...
|
|
||||||
displayScorePosition();
|
|
||||||
|
|
||||||
for (cycleCount = 4 * 60; cycleCount > 0; cycleCount--) {
|
|
||||||
networkGlobals->initParams.waitForVbl();
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct tHighScore
|
typedef struct tHighScore
|
||||||
{
|
{
|
||||||
char scoreText[10];
|
char scoreText[10];
|
||||||
|
@ -19,31 +20,100 @@ typedef struct tHighScore
|
||||||
unsigned long score;
|
unsigned long score;
|
||||||
} tHighScore;
|
} tHighScore;
|
||||||
|
|
||||||
extern char globalScoreInfo[26]; /* TODO - Get rid of this global and the hard coded length */
|
|
||||||
|
|
||||||
typedef struct tHighScoreInitParams
|
typedef struct tHighScoreInitParams
|
||||||
{
|
{
|
||||||
|
/* This structure is initialized by the game and passed by pointer to the high score code. It consists of
|
||||||
|
a series of data members and a series of callbacks which are provided by the game.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is the memory manager ID of the game. */
|
||||||
unsigned int userId;
|
unsigned int userId;
|
||||||
const char * scoreServer; /* Pascal string of the hostname of the score server. */
|
|
||||||
|
/* This is a Pascal string (not a C string) of the hostname of the score server to connect to. */
|
||||||
|
const char * scoreServer;
|
||||||
|
|
||||||
|
/* This is the TCP port number of the score server to connect to. */
|
||||||
unsigned int scorePort;
|
unsigned int scorePort;
|
||||||
|
|
||||||
|
/* These two 32-bit values are the shared secrets used by the connect between the game and the score server
|
||||||
|
which is used to try to reduce the amount of game score hacking.
|
||||||
|
*/
|
||||||
unsigned long secret1;
|
unsigned long secret1;
|
||||||
unsigned long secret2;
|
unsigned long secret2;
|
||||||
|
|
||||||
void (*displayConnectionString)(void); /* This function should display a message to the user that the network is being brought up. */
|
|
||||||
void (*waitForVbl)(void); /* This function should wait for the next VBL and is used to poll the network and limit upload time for a high score. */
|
/* This function should display a message to the user that the network is being brought up and they should
|
||||||
void (*uploadSpin)(int); /* This argument iterates over 0, 1, 2, 3 and then back to 0, 1, 2, etc and is intended to show some kind of spinner to the user
|
be patient when the argument is TRUE and when the argument is FALSE, it should clear that message. This
|
||||||
while uploading a high score. */
|
function shouldn't block and just put something on the screen to say that the connection is being brought
|
||||||
|
up or clear that message. It is called sometimes (rarely) by pollNetwork(). It is called with argument
|
||||||
|
TRUE and will always be called with FALSE sometime after that.
|
||||||
|
*/
|
||||||
|
void (*displayConnectionString)(BOOLEAN display);
|
||||||
|
|
||||||
|
/* This function should wait for the next VBL and is used to poll the network and limit upload time for a
|
||||||
|
high score.
|
||||||
|
*/
|
||||||
|
void (*waitForVbl)(void);
|
||||||
|
|
||||||
|
/* This argument iterates over 0, 1, 2, 3 and then back to 0, 1, 2, etc and is intended to show some kind
|
||||||
|
of spinner to the user while uploading a high score to the server. This function shouldn't block for
|
||||||
|
any real amount of time and just cause something on the screen to change to make sure the player doesn't
|
||||||
|
think something has hung while the upload is in progress. It is called when sendHighScore() is called
|
||||||
|
by the game.
|
||||||
|
*/
|
||||||
|
void (*uploadSpin)(int);
|
||||||
|
|
||||||
|
/* When a score is successfully uploaded to the server, this function will be called with the position
|
||||||
|
of this player's score among the total number of scores recorded for this game. This information
|
||||||
|
should be displayed to the user. The function can block while this information is being displayed
|
||||||
|
and that message should be cleaned up before the function returns to the caller. This function is
|
||||||
|
called by sendHighScore().
|
||||||
|
*/
|
||||||
|
void (*scorePosition)(unsigned int position, unsigned int numberOfScores);
|
||||||
} tHighScoreInitParams;
|
} tHighScoreInitParams;
|
||||||
|
|
||||||
extern void initNetwork(tHighScoreInitParams * params);
|
|
||||||
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.
|
/* Call this function once at launch. The pointer to the parameters is copied so the structure does not need
|
||||||
extern void displayScorePosition(void);
|
to remain valid after the call to this function.
|
||||||
|
*/
|
||||||
|
extern void initNetwork(tHighScoreInitParams * params);
|
||||||
|
|
||||||
|
|
||||||
|
/* Call this when a game is about to start. It will interrupt any network operation in progress and get ready for
|
||||||
|
a quiet period where polling will stop until the game is over. That way, all CPU time can be focused on the game.
|
||||||
|
This function may call the waitForVbl() callback.
|
||||||
|
*/
|
||||||
|
extern void disconnectNetwork(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Call this every frame refresh period when a game is _not_ in progress. This does any network operations required
|
||||||
|
to download high scores. During this function call, the displayConnectionString() callback may be called.
|
||||||
|
*/
|
||||||
|
extern void pollNetwork(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Call this function once when the game is quitting. */
|
||||||
|
extern void shutdownNetwork(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Call this function when the player has a high score that should be recorded online. This function will return
|
||||||
|
TRUE if the network is up and a high score can be sent and if so, the game should call sendHighScore() to send
|
||||||
|
the high score. If FALSE is returned, then the user is playing while offline and no attempt should be made to
|
||||||
|
send the high score.
|
||||||
|
*/
|
||||||
|
extern BOOLEAN canSendHighScore(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Assuming canSendHighScore() returned TRUE, the game can call this function to actually try to send the high score
|
||||||
|
to the server. If this function returns TRUE, then the score was successfully sent to the server. If FALSE
|
||||||
|
is returned, then an error has occurred. The game can offer the user the option to retry to the upload of the
|
||||||
|
score and if the user would like to retry, just call sendHighScore() again. During this function call, the
|
||||||
|
waitForVbl(), uploadSpin() and scorePosition() callbacks may be called.
|
||||||
|
|
||||||
|
TODO - Pass the score as an argument rather than through globals.
|
||||||
|
*/
|
||||||
|
extern BOOLEAN sendHighScore(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* define _GUARD_PROJECTBuGS_FILEglobalScores_ */
|
#endif /* define _GUARD_PROJECTBuGS_FILEglobalScores_ */
|
||||||
|
|
30
BuGS/main.c
30
BuGS/main.c
|
@ -31,6 +31,9 @@
|
||||||
unsigned int myUserId;
|
unsigned int myUserId;
|
||||||
unsigned int randomSeed;
|
unsigned int randomSeed;
|
||||||
|
|
||||||
|
// This symbol is used also from assembly directly so be careful with it...
|
||||||
|
char globalScoreInfo[GAME_NUM_TILES_WIDE + 1];
|
||||||
|
|
||||||
|
|
||||||
/* Implementation */
|
/* Implementation */
|
||||||
|
|
||||||
|
@ -66,6 +69,30 @@ void uploadSpin(int val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scorePosition(unsigned int position, unsigned int numberOfScores)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(globalScoreInfo, " %u OF %u SCORES", position, numberOfScores);
|
||||||
|
for (i = strlen(globalScoreInfo); i < sizeof(globalScoreInfo); i++) {
|
||||||
|
globalScoreInfo[i] = ' ';
|
||||||
|
}
|
||||||
|
globalScoreInfo[GAME_NUM_TILES_WIDE] = '\0';
|
||||||
|
displayScorePosition();
|
||||||
|
|
||||||
|
for (i = 6 * 60; i > 0; i--) {
|
||||||
|
waitForVbl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void showConnectionString(BOOLEAN display)
|
||||||
|
{
|
||||||
|
if (display)
|
||||||
|
displayConnectionString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
static tHighScoreInitParams highScoreInitParams;
|
static tHighScoreInitParams highScoreInitParams;
|
||||||
|
@ -102,9 +129,10 @@ int main(void)
|
||||||
highScoreInitParams.secret1 = NETWORK_SERVERSECRET1;
|
highScoreInitParams.secret1 = NETWORK_SERVERSECRET1;
|
||||||
highScoreInitParams.secret2 = NETWORK_SERVERSECRET2;
|
highScoreInitParams.secret2 = NETWORK_SERVERSECRET2;
|
||||||
|
|
||||||
highScoreInitParams.displayConnectionString = displayConnectionString;
|
highScoreInitParams.displayConnectionString = showConnectionString;
|
||||||
highScoreInitParams.waitForVbl = waitForVbl;
|
highScoreInitParams.waitForVbl = waitForVbl;
|
||||||
highScoreInitParams.uploadSpin = uploadSpin;
|
highScoreInitParams.uploadSpin = uploadSpin;
|
||||||
|
highScoreInitParams.scorePosition = scorePosition;
|
||||||
|
|
||||||
initNetwork(&highScoreInitParams);
|
initNetwork(&highScoreInitParams);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue