Retrieve global high scores from the Internet and display them in the game.

This commit is contained in:
Jeremy Rand 2021-06-01 23:13:14 -04:00
parent 4b76293125
commit 5e26684fd2
6 changed files with 504 additions and 45 deletions

View File

@ -92,10 +92,32 @@ gameLoop anop
lda #1 lda #1
sta shouldPreloadSound sta shouldPreloadSound
gameLoop_skipPreload anop gameLoop_skipPreload anop
; The following is the network poll code which runs when not playing a game
lda gameState lda gameState
bne gameLoop_skipNetwork bne gameLoop_skipNetwork
jsl pollNetwork jsl pollNetwork
lda hasGlobalHighScores
beq gameLoop_skipNetwork
lda highScoreCountdown
beq gameLoop_swapHighScores
dec a
sta highScoreCountdown
bra gameLoop_skipNetwork
gameLoop_swapHighScores anop
lda #10*60
sta highScoreCountdown
lda displayGlobalHighScores
eor #1
sta displayGlobalHighScores
jsl staticGameBoard
gameLoop_skipNetwork anop gameLoop_skipNetwork anop
lda globalScoreAge
beq gameLoop_skipScoreAgeDec
dec a
sta globalScoreAge
gameLoop_skipScoreAgeDec anop
jsl checkKeyboard jsl checkKeyboard
@ -686,6 +708,7 @@ setGameNotRunning entry
jsl spiderInitLevel jsl spiderInitLevel
jsl fleaInitLevel jsl fleaInitLevel
jsl addRandomMushrooms jsl addRandomMushrooms
stz displayGlobalHighScores
jmp staticGameBoard jmp staticGameBoard
@ -695,6 +718,11 @@ staticGameBoard entry
lda #TILE_STATE_DIRTY lda #TILE_STATE_DIRTY
sta tileDirty+RHS_FIRST_TILE_OFFSET-GAME_NUM_TILES_WIDE-1 sta tileDirty+RHS_FIRST_TILE_OFFSET-GAME_NUM_TILES_WIDE-1
lda displayGlobalHighScores
beq staticGameBoard_localHighScores
jmp staticGameBoard_globalHighScores
staticGameBoard_localHighScores anop
ldx #GAME_NUM_TILES_WIDE*8+2 ldx #GAME_NUM_TILES_WIDE*8+2
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
@ -817,7 +845,133 @@ staticGameBoard entry
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
jmp staticGameBoard_Options
staticGameBoard_globalHighScores anop
ldx #GAME_NUM_TILES_WIDE*8+2
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_LETTER_G
_setGameTile TILE_LETTER_L
_setGameTile TILE_LETTER_O
_setGameTile TILE_LETTER_B
_setGameTile TILE_LETTER_A
_setGameTile TILE_LETTER_L
_setGameTile TILE_EMPTY
_setGameTile TILE_LETTER_H
_setGameTile TILE_LETTER_I
_setGameTile TILE_LETTER_G
_setGameTile TILE_LETTER_H
_setGameTile TILE_EMPTY
_setGameTile TILE_LETTER_S
_setGameTile TILE_LETTER_C
_setGameTile TILE_LETTER_O
_setGameTile TILE_LETTER_R
_setGameTile TILE_LETTER_E
_setGameTile TILE_LETTER_S
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*10+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 0
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*12+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 1
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*14+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 2
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*16+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 3
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*18+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 4
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*20+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 5
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*22+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 6
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*24+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 7
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*26+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 8
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
ldx #GAME_NUM_TILES_WIDE*28+2
_setGameTile TILE_EMPTY
_globalHighScoreRow 9
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
staticGameBoard_Options anop
ldx #GAME_NUM_TILES_WIDE*30+2 ldx #GAME_NUM_TILES_WIDE*30+2
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY _setGameTile TILE_EMPTY
@ -1043,5 +1197,7 @@ shouldQuit dc i2'1'
borderColour dc i2'0' borderColour dc i2'0'
frameCount dc i2'0' frameCount dc i2'0'
shouldPreloadSound dc i2'0' shouldPreloadSound dc i2'0'
displayGlobalHighScores dc i2'0'
highScoreCountdown dc i2'0'
end end

View File

@ -8,7 +8,6 @@
use strict; use strict;
use integer; use integer;
# main # main
@ -86,6 +85,13 @@ $gEquates{"NUM_FLEA_FREQS"} = 120;
$gEquates{"NUM_HIGH_SCORES"} = 10; $gEquates{"NUM_HIGH_SCORES"} = 10;
our %gNetworkDefines;
$gNetworkDefines{'NETWORK_SERVER'} = "NULL";
$gNetworkDefines{'NETWORK_SERVERPORT'} = 0;
$gNetworkDefines{'NETWORK_SERVERSECRET1'} = 0;
$gNetworkDefines{'NETWORK_SERVERSECRET2'} = 0;
our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"}; our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"}; our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"};
our @gTileType = ("TILE_EMPTY") x $gEquates{"TOTAL_NUM_TILES"}; our @gTileType = ("TILE_EMPTY") x $gEquates{"TOTAL_NUM_TILES"};
@ -109,6 +115,18 @@ our @gMouseXTileRight = (0) x $gEquates{"MOUSE_MAX_X"};
our @gScreenToTileOffset = (0) x ($gEquates{"SCREEN_PIXELS_TALL"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"}); our @gScreenToTileOffset = (0) x ($gEquates{"SCREEN_PIXELS_TALL"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"});
sub loadNetworkSettings
{
open my $fh, "<", $ENV{'HOME'} . "/.BuGS_scores.json" or return;
while (<$fh>)
{
if (/^\s+\"(Server\w*)\"\s+:\s+([-\"a-zA-Z0-9.]+),\s*$/) {
$gNetworkDefines{'NETWORK_' . uc($1)} = $2;
}
}
}
sub printTileData sub printTileData
{ {
my ($fh, $symbol, @data) = @_; my ($fh, $symbol, @data) = @_;
@ -505,6 +523,7 @@ sub initFleaFreqs
} }
loadNetworkSettings();
initTiles(); initTiles();
initNonGameTiles(); initNonGameTiles();
initFleaFreqs(); initFleaFreqs();
@ -612,6 +631,11 @@ foreach my $equate (sort keys %gEquates)
print $fh "#define $equate " . $gEquates{$equate} . "\n"; print $fh "#define $equate " . $gEquates{$equate} . "\n";
} }
foreach my $equate (sort keys %gNetworkDefines)
{
print $fh "#define $equate " . $gNetworkDefines{$equate} . "\n";
}
$text = << "EOF"; $text = << "EOF";

View File

@ -218,6 +218,78 @@ _dirtyNonGameTile_skip&SYSCNT anop
jsl asciiToTileType jsl asciiToTileType
jsr setGameTile jsr setGameTile
mend mend
macro
_globalHighScoreRow &nthScore
ldy #2+&nthScore*SETTINGS_HIGH_SCORE_SIZE
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
lda #TILE_EMPTY
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
iny
lda highScoreResponse,y
jsl asciiToTileType
jsr setGameTile
mend
; Update the score ; Update the score

View File

@ -14,7 +14,9 @@
#include <types.h> #include <types.h>
#include "globalScores.h" #include "globalScores.h"
#include "tileData.h"
segment "highscores";
// Defines // Defines
@ -25,6 +27,8 @@
#define RESPONSE_TYPE_SCORES 1 #define RESPONSE_TYPE_SCORES 1
#define RESPONSE_TYPE_STATUS 2 #define RESPONSE_TYPE_STATUS 2
#define GLOBAL_SCORE_REFRESH_TIME (15 * 60 * 60)
// Types // Types
@ -80,7 +84,31 @@ typedef struct tStatusResponse {
typedef enum tGameNetworkState { typedef enum tGameNetworkState {
GAME_NETWORK_CONNECT_FAILED = 0, GAME_NETWORK_CONNECT_FAILED = 0,
GAME_NETWORK_UNCONNECTED, GAME_NETWORK_UNCONNECTED,
/* All states below this should have Marinetti disconnected */
GAME_NETWORK_CONNECTED, GAME_NETWORK_CONNECTED,
GAME_NETWORK_RESOLVING_NAME,
/* These are all of the error states. Marinetti is still connected but the
TCP connection is closed and ipid released. */
GAME_NETWORK_LOOKUP_FAILED,
GAME_NETWORK_SOCKET_ERROR,
GAME_NETWORK_PROTOCOL_FAILED,
/* All of these states below here have an ipid open and the TCP connection is
open and in some state. */
GAME_NETWORK_WAITING_FOR_TCP,
/* All of these states below this point have the TCP connection established
and the score protocol is exchanging information. */
GAME_NETWORK_WAITING_FOR_HELLO,
GAME_NETWORK_REQUEST_SCORES,
GAME_NETWORK_WAITING_FOR_SCORES,
/* This is the "quiescent" state. The hello has been retrieved and scores
have been downloaded at least once. This is the only state where a
new high score can be uploaded safely. */
GAME_NETWORK_SCORES_RETRIEVED,
} tGameNetworkState; } tGameNetworkState;
@ -88,8 +116,43 @@ typedef enum tGameNetworkState {
Boolean networkToolsStarted = FALSE; Boolean networkToolsStarted = FALSE;
Boolean networkStartedConnected = FALSE; Boolean networkStartedConnected = FALSE;
Boolean hasGlobalHighScores = FALSE;
tGameNetworkState gameNetworkState = GAME_NETWORK_UNCONNECTED; tGameNetworkState gameNetworkState = GAME_NETWORK_UNCONNECTED;
dnrBuffer domainNameResolution;
srBuff tcpStatus;
Word ipid;
rrBuff readResponseBuf;
tHelloResponse helloResponse;
uint32_t bytesRead = 0;
md5WorkBlock hashWorkBlock;
uint32_t secrets[3] = { NETWORK_SERVERSECRET1, NETWORK_SERVERSECRET2, 0 };
tHighScoreRequestWithHash highScoreRequest;
tScoresResponse highScoreResponse = {
RESPONSE_TYPE_SCORES,
{
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0},
{ { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0'}, { 'A', 'A', 'A' }, 0}
}
};
Word globalScoreAge = 0;
// Extern from assembly code
extern void waitForVbl(void);
// Implementation // Implementation
@ -107,6 +170,11 @@ Word blah(void)
void initNetwork(void) void initNetwork(void)
{ {
networkToolsStarted = FALSE; networkToolsStarted = FALSE;
if ((NETWORK_SERVER == NULL) ||
(NETWORK_SERVERPORT == 0))
return;
LoadOneTool(54, 0x200); // Load Marinetti LoadOneTool(54, 0x200); // Load Marinetti
if (toolerror()) if (toolerror())
return; return;
@ -148,6 +216,31 @@ void shutdownNetwork(void)
if (!networkToolsStarted) if (!networkToolsStarted)
return; return;
if (gameNetworkState > GAME_NETWORK_WAITING_FOR_TCP) {
int i = 30;
TCPIPCloseTCP(ipid);
while (i > 0) {
waitForVbl();
TCPIPPoll();
if (TCPIPStatusTCP(ipid, &tcpStatus) != tcperrOK) {
i = 0;
break;
}
if (tcpStatus.srState == TCPSCLOSED)
break;
i--;
}
if (i == 0) {
TCPIPAbortTCP(ipid);
}
TCPIPLogout(ipid);
}
if ((!networkStartedConnected) && if ((!networkStartedConnected) &&
(gameNetworkState > GAME_NETWORK_UNCONNECTED)) { (gameNetworkState > GAME_NETWORK_UNCONNECTED)) {
TCPIPDisconnect(TRUE, NULL); TCPIPDisconnect(TRUE, NULL);
@ -162,12 +255,19 @@ void shutdownNetwork(void)
void pollNetwork(void) void pollNetwork(void)
{ {
Word errorCode;
if (!networkToolsStarted) if (!networkToolsStarted)
return; return;
TCPIPPoll();
switch (gameNetworkState) { switch (gameNetworkState) {
case GAME_NETWORK_SOCKET_ERROR:
case GAME_NETWORK_LOOKUP_FAILED:
case GAME_NETWORK_CONNECT_FAILED: case GAME_NETWORK_CONNECT_FAILED:
// If Marinetti cannot connect to the network, then nothing more to do... case GAME_NETWORK_PROTOCOL_FAILED:
// If we end up in these error states, there is nothing more to do...
break; break;
case GAME_NETWORK_UNCONNECTED: case GAME_NETWORK_UNCONNECTED:
@ -181,7 +281,133 @@ void pollNetwork(void)
break; break;
case GAME_NETWORK_CONNECTED: case GAME_NETWORK_CONNECTED:
// TODO - Write more code to make network requests. TCPIPDNRNameToIP("\p" NETWORK_SERVER, &domainNameResolution);
if (toolerror())
gameNetworkState = GAME_NETWORK_LOOKUP_FAILED;
else
gameNetworkState = GAME_NETWORK_RESOLVING_NAME;
break;
case GAME_NETWORK_RESOLVING_NAME:
if (domainNameResolution.DNRstatus == DNR_Pending)
break;
if (domainNameResolution.DNRstatus != DNR_OK) {
// TODO - I end up in here on the emulator. Find out why.
gameNetworkState = GAME_NETWORK_LOOKUP_FAILED;
break;
}
ipid = TCPIPLogin(myUserId, domainNameResolution.DNRIPaddress, NETWORK_SERVERPORT, 0, 64);
if (toolerror()) {
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
break;
}
if (TCPIPOpenTCP(ipid) != tcperrOK) {
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
break;
}
gameNetworkState = GAME_NETWORK_WAITING_FOR_TCP;
break;
case GAME_NETWORK_WAITING_FOR_TCP:
if (TCPIPStatusTCP(ipid, &tcpStatus) != tcperrOK) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
}
if ((tcpStatus.srState == TCPSSYNSENT) ||
(tcpStatus.srState == TCPSSYNRCVD))
break;
if (tcpStatus.srState != TCPSESTABLISHED) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
}
gameNetworkState = GAME_NETWORK_WAITING_FOR_HELLO;
bytesRead = 0;
break;
case GAME_NETWORK_WAITING_FOR_HELLO:
if (TCPIPReadTCP(ipid, 0, ((uint32_t)(&helloResponse)) + bytesRead, sizeof(helloResponse) - bytesRead, &readResponseBuf) != tcperrOK) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
}
bytesRead += readResponseBuf.rrBuffCount;
if (bytesRead < sizeof(helloResponse))
break;
if (bytesRead > sizeof(helloResponse)) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_PROTOCOL_FAILED;
}
if (helloResponse.responseType != RESPONSE_TYPE_HELLO) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_PROTOCOL_FAILED;
}
gameNetworkState = GAME_NETWORK_REQUEST_SCORES;
secrets[2] = helloResponse.nonce;
break;
case GAME_NETWORK_REQUEST_SCORES:
highScoreRequest.highScoreRequest.requestType = REQUEST_TYPE_GET_HIGH_SCORES;
md5Init(&hashWorkBlock);
md5Append(&hashWorkBlock, (Pointer)&secrets, sizeof(secrets));
md5Append(&hashWorkBlock, (Pointer)&(highScoreRequest.highScoreRequest), sizeof(highScoreRequest.highScoreRequest));
md5Finish(&hashWorkBlock, &(highScoreRequest.md5Digest[0]));
if (TCPIPWriteTCP(ipid, (Pointer)&highScoreRequest, sizeof(highScoreRequest), FALSE, FALSE) != tcperrOK) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
}
gameNetworkState = GAME_NETWORK_WAITING_FOR_SCORES;
bytesRead = 0;
break;
case GAME_NETWORK_WAITING_FOR_SCORES:
if (TCPIPReadTCP(ipid, 0, ((uint32_t)(&highScoreResponse)) + bytesRead, sizeof(highScoreResponse) - bytesRead, &readResponseBuf) != tcperrOK) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_SOCKET_ERROR;
}
bytesRead += readResponseBuf.rrBuffCount;
if (bytesRead < sizeof(highScoreResponse))
break;
if (bytesRead > sizeof(highScoreResponse)) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_PROTOCOL_FAILED;
}
if (highScoreResponse.responseType != RESPONSE_TYPE_SCORES) {
TCPIPAbortTCP(ipid);
TCPIPLogout(ipid);
gameNetworkState = GAME_NETWORK_PROTOCOL_FAILED;
}
globalScoreAge = GLOBAL_SCORE_REFRESH_TIME;
gameNetworkState = GAME_NETWORK_SCORES_RETRIEVED;
hasGlobalHighScores = TRUE;
break;
case GLOBAL_SCORE_REFRESH_TIME:
if (globalScoreAge == 0)
gameNetworkState = GAME_NETWORK_REQUEST_SCORES;
break; break;
} }
} }

View File

@ -17,6 +17,7 @@ typedef struct tHighScore
unsigned long score; unsigned long score;
} tHighScore; } tHighScore;
extern unsigned int myUserId;
extern void initNetwork(void); extern void initNetwork(void);
extern void pollNetwork(void); extern void pollNetwork(void);

View File

@ -45,7 +45,7 @@ typedef struct tSettingsData
/* Globals */ /* Globals */
unsigned int userid; unsigned int myUserId;
unsigned int randomSeed; unsigned int randomSeed;
tSettingsData settings = { tSettingsData settings = {
{ 'B', 'u', 'G', 'S' }, { 'B', 'u', 'G', 'S' },
@ -86,85 +86,65 @@ word randomMushroomOffset(void)
return (rand() % (NUM_GAME_TILES - GAME_NUM_TILES_WIDE)) * SIZEOF_TILE_INFO; return (rand() % (NUM_GAME_TILES - GAME_NUM_TILES_WIDE)) * SIZEOF_TILE_INFO;
} }
void loadSound(Word addr, Word soundNum)
void loadSpiderSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, SPIDER_SOUND); Handle handle = LoadResource(rRawSound, soundNum);
HLock(handle); HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle)); WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle); HUnlock(handle);
} }
void loadSpiderSound(Word addr)
{
loadSound(addr, SPIDER_SOUND);
}
void loadDeathSound(word addr) void loadDeathSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, DEATH_SOUND); loadSound(addr, DEATH_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadSegmentsSound(word addr) void loadSegmentsSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, SEGMENTS_SOUND); loadSound(addr, SEGMENTS_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadBonusSound(word addr) void loadBonusSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, BONUS_SOUND); loadSound(addr, BONUS_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadKillSound(word addr) void loadKillSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, KILL_SOUND); loadSound(addr, KILL_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadFireSound(word addr) void loadFireSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, FIRE_SOUND); loadSound(addr, FIRE_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadExtraLifeSound(word addr) void loadExtraLifeSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, EXTRA_LIFE_SOUND); loadSound(addr, EXTRA_LIFE_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadFleaSound(word addr) void loadFleaSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, FLEA_SOUND); loadSound(addr, FLEA_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
void loadScorpionSound(word addr) void loadScorpionSound(word addr)
{ {
Handle handle = LoadResource(rRawSound, SCORPION_SOUND); loadSound(addr, SCORPION_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
} }
@ -188,7 +168,7 @@ void allocateFilenameHandle(void)
{ {
GSString255Ptr filenamePtr; GSString255Ptr filenamePtr;
filenameHandle = NewHandle(sizeof(GSString255), userid, 0x8000, NULL); filenameHandle = NewHandle(sizeof(GSString255), myUserId, 0x8000, NULL);
HLock(filenameHandle); HLock(filenameHandle);
filenamePtr = (GSString255Ptr)(*filenameHandle); filenamePtr = (GSString255Ptr)(*filenameHandle);
filenamePtr->length = strlen(SETTINGS_FILENAME); filenamePtr->length = strlen(SETTINGS_FILENAME);
@ -323,19 +303,19 @@ int main(void)
int event; int event;
Ref toolStartupRef; Ref toolStartupRef;
userid = MMStartUp(); myUserId = MMStartUp();
TOOLFAIL("Unable to start memory manager"); TOOLFAIL("Unable to start memory manager");
TLStartUp(); TLStartUp();
TOOLFAIL("Unable to start tool locator"); TOOLFAIL("Unable to start tool locator");
toolStartupRef = StartUpTools(userid, refIsResource, TOOL_STARTUP); toolStartupRef = StartUpTools(myUserId, refIsResource, TOOL_STARTUP);
TOOLFAIL("Unable to start tools"); TOOLFAIL("Unable to start tools");
CompactMem(); CompactMem();
/* Allocate $1000 extra before the SHR screen so I can write sprites above the start of the /* Allocate $1000 extra before the SHR screen so I can write sprites above the start of the
screen without overwriting memory I do not own. */ screen without overwriting memory I do not own. */
NewHandle(0x9000, userid, attrLocked | attrFixed | attrAddr | attrBank, (Pointer)0x011000); NewHandle(0x9000, myUserId, attrLocked | attrFixed | attrAddr | attrBank, (Pointer)0x011000);
TOOLFAIL("Unable to allocate SHR screen"); TOOLFAIL("Unable to allocate SHR screen");
randomSeed = (int)time(NULL); randomSeed = (int)time(NULL);
@ -362,6 +342,6 @@ int main(void)
TLShutDown(); TLShutDown();
TOOLFAIL("Unable to shutdown tool locator"); TOOLFAIL("Unable to shutdown tool locator");
MMShutDown(userid); MMShutDown(myUserId);
TOOLFAIL("Unable to shutdown memory manager"); TOOLFAIL("Unable to shutdown memory manager");
} }