mirror of https://github.com/jeremysrand/BuGS.git
Retrieve global high scores from the Internet and display them in the game.
This commit is contained in:
parent
4b76293125
commit
5e26684fd2
158
BuGS/game.s
158
BuGS/game.s
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
62
BuGS/main.c
62
BuGS/main.c
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue