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
sta shouldPreloadSound
gameLoop_skipPreload anop
; The following is the network poll code which runs when not playing a game
lda gameState
bne gameLoop_skipNetwork
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
lda globalScoreAge
beq gameLoop_skipScoreAgeDec
dec a
sta globalScoreAge
gameLoop_skipScoreAgeDec anop
jsl checkKeyboard
@ -686,6 +708,7 @@ setGameNotRunning entry
jsl spiderInitLevel
jsl fleaInitLevel
jsl addRandomMushrooms
stz displayGlobalHighScores
jmp staticGameBoard
@ -695,6 +718,11 @@ staticGameBoard entry
lda #TILE_STATE_DIRTY
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
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
@ -817,7 +845,133 @@ staticGameBoard entry
_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
_setGameTile TILE_EMPTY
_setGameTile TILE_EMPTY
@ -1043,5 +1197,7 @@ shouldQuit dc i2'1'
borderColour dc i2'0'
frameCount dc i2'0'
shouldPreloadSound dc i2'0'
displayGlobalHighScores dc i2'0'
highScoreCountdown dc i2'0'
end

View File

@ -8,7 +8,6 @@
use strict;
use integer;
# main
@ -86,6 +85,13 @@ $gEquates{"NUM_FLEA_FREQS"} = 120;
$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 @gTileScreenOffset = (0) 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"});
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
{
my ($fh, $symbol, @data) = @_;
@ -505,6 +523,7 @@ sub initFleaFreqs
}
loadNetworkSettings();
initTiles();
initNonGameTiles();
initFleaFreqs();
@ -612,6 +631,11 @@ foreach my $equate (sort keys %gEquates)
print $fh "#define $equate " . $gEquates{$equate} . "\n";
}
foreach my $equate (sort keys %gNetworkDefines)
{
print $fh "#define $equate " . $gNetworkDefines{$equate} . "\n";
}
$text = << "EOF";

View File

@ -218,6 +218,78 @@ _dirtyNonGameTile_skip&SYSCNT anop
jsl asciiToTileType
jsr setGameTile
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

View File

@ -14,7 +14,9 @@
#include <types.h>
#include "globalScores.h"
#include "tileData.h"
segment "highscores";
// Defines
@ -25,6 +27,8 @@
#define RESPONSE_TYPE_SCORES 1
#define RESPONSE_TYPE_STATUS 2
#define GLOBAL_SCORE_REFRESH_TIME (15 * 60 * 60)
// Types
@ -80,7 +84,31 @@ typedef struct tStatusResponse {
typedef enum tGameNetworkState {
GAME_NETWORK_CONNECT_FAILED = 0,
GAME_NETWORK_UNCONNECTED,
/* All states below this should have Marinetti disconnected */
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;
@ -88,8 +116,43 @@ typedef enum tGameNetworkState {
Boolean networkToolsStarted = FALSE;
Boolean networkStartedConnected = FALSE;
Boolean hasGlobalHighScores = FALSE;
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
@ -107,6 +170,11 @@ Word blah(void)
void initNetwork(void)
{
networkToolsStarted = FALSE;
if ((NETWORK_SERVER == NULL) ||
(NETWORK_SERVERPORT == 0))
return;
LoadOneTool(54, 0x200); // Load Marinetti
if (toolerror())
return;
@ -148,6 +216,31 @@ void shutdownNetwork(void)
if (!networkToolsStarted)
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) &&
(gameNetworkState > GAME_NETWORK_UNCONNECTED)) {
TCPIPDisconnect(TRUE, NULL);
@ -162,12 +255,19 @@ void shutdownNetwork(void)
void pollNetwork(void)
{
Word errorCode;
if (!networkToolsStarted)
return;
TCPIPPoll();
switch (gameNetworkState) {
case GAME_NETWORK_SOCKET_ERROR:
case GAME_NETWORK_LOOKUP_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;
case GAME_NETWORK_UNCONNECTED:
@ -181,7 +281,133 @@ void pollNetwork(void)
break;
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;
}
}

View File

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

View File

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