This build has the player moving in X and Y directions and with cleaner handling of the dirty tile to remove the inefficiencies. The good news is that there is no longer any performance problem at 2.8 MHz now that the inefficient dirty tile handling has been removed. The bad news is that they player leaves garbage behind indicating some kind of problem with dirty tile marking. But it is close.

This commit is contained in:
Jeremy Rand 2020-11-05 00:21:46 -05:00
parent bb66ef4b03
commit edcddc0bd8
5 changed files with 129 additions and 72 deletions

View File

@ -78,7 +78,7 @@
9D33970024AEFBF2003222B3 /* segments.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = segments.s; sourceTree = "<group>"; };
9D33970124AF9D55003222B3 /* sprites.macros */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprites.macros; sourceTree = "<group>"; };
9D47CBE02547BEDB00CDA5CB /* gameMushroom.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameMushroom.s; sourceTree = "<group>"; };
9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; };
9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; };
9D47CCBA25525C1A00CDA5CB /* tileData.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = tileData.pl; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
9D62AF3B249871A300348F45 /* colour.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = colour.s; sourceTree = "<group>"; };
9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };

View File

@ -122,7 +122,7 @@ $(GENDIR)/tileData.s: tileData.pl Makefile
# add rules in genclean to remove those generated files when you
# clean your build.
genclean:
$(RM) $(GENDIR)/tileData.s $(GENDIR)/tileData.h
$(RM) $(GENDIR)/tileData.s $(GENDIR)/screenData.s $(GENDIR)/tileData.h
# Do not change anything else below here...
include make/tail.mk

View File

@ -13,14 +13,7 @@
gamePlayer start
using globalData
using tileData
PLAYER_TILES_HIGH equ 7
MOUSE_MAX_X equ GAME_NUM_TILES_WIDE*TILE_PIXEL_WIDTH-TILE_PIXEL_WIDTH
MOUSE_MAX_Y equ GAME_NUM_TILES_TALL*TILE_PIXEL_HEIGHT-TILE_PIXEL_HEIGHT
STARTING_MOUSE_X equ GAME_NUM_TILES_WIDE*TILE_PIXEL_WIDTH/2
STARTING_MOUSE_Y equ MOUSE_MAX_Y
using screenData
initPlayer entry
lda #STARTING_MOUSE_X
@ -110,51 +103,51 @@ updatePlayer_doneY anop
sta mouseDown
updatePlayer_skipDeltas anop
lda mouseY
asl a
tay
lda mouseX
lsr a
bcs updatePlayer_shift
adc #$9834
adc mouseYAddress,y
sta mouseAddress
tay
jsl drawShip
bra updatePlayer_dirty
updatePlayer_shift anop
adc #$9833
adc mouseYAddress,y
sta mouseAddress
dec a
tay
jsl drawShipShift
bra updatePlayer_dirty
updatePlayer_dirty anop
lda mouseAddress
sec
sbc #SCREEN_ADDRESS
and #$fff8
tax
lda >screenToTileOffset,x
tax
lda #TILE_STATE_DIRTY
sta tileDirty+1200
sta tileDirty+1202
sta tileDirty+1204
sta tileDirty+1206
sta tileDirty+1208
sta tileDirty+1210
sta tileDirty+1212
sta tileDirty+1214
sta tileDirty+1216
sta tileDirty+1218
sta tileDirty+1220
sta tileDirty+1222
sta tileDirty+1224
sta tileDirty+1226
sta tileDirty+1228
sta tileDirty+1230
sta tileDirty+1232
sta tileDirty+1234
sta tileDirty+1236
sta tileDirty+1238
sta tileDirty+1240
sta tileDirty+1242
sta tileDirty+1244
sta tileDirty+1246
sta tileDirty+1248
sta tileDirty,x
ldy tileRight,x
sta tileDirty,y
ldy tileBelow,x
cpy #INVALID_TILE_NUM
beq updatePlayer_done
sta tileDirty,y
ldx tileRight,y
sta tileDirty,x
updatePlayer_done anop
rtl
mouseX dc i2'0'
mouseY dc i2'0'
mouseDown dc i2'0'
mouseAddress dc i2'0'
end

View File

@ -8,7 +8,6 @@ s6d2 =
s7d1 = /Users/jrand/Library/Developer/Xcode/DerivedData/BuGS-bffpexoblaghkzcbtjtzxeulnuto/Build/Products/Debug/BuGS.2mg
g_limit_speed = 3
bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00

View File

@ -19,7 +19,7 @@ our %gEquates;
# These are global equates which will also become defines in the C header file. Also, these will drive the other
# data that is generated by this script.
$gEquates{"SCREEN_ADDRESS"} = 0x2000;
$gEquates{"SCREEN_PIXELS_WIDE"} = 320;
$gEquates{"SCREEN_PIXELS_TALL"} = 200;
$gEquates{"SCREEN_PIXELS_PER_BYTE"} = 2;
@ -55,6 +55,12 @@ $gEquates{"SPIDER_MAX_NUM_POSSIBLE_ROWS"} = 10;
$gEquates{"SPIDER_STARTING_TOP_ROW"} = $gEquates{"GAME_NUM_TILES_TALL"} - $gEquates{"SPIDER_MAX_NUM_POSSIBLE_ROWS"};
$gEquates{"SPIDER_STARTING_TOP_ROW_OFFSET"} = $gEquates{"SPIDER_STARTING_TOP_ROW"} * $gEquates{"GAME_NUM_TILES_WIDE"} * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"PLAYER_TILES_HIGH"} = 7;
$gEquates{"MOUSE_MAX_X"} = (($gEquates{"GAME_NUM_TILES_WIDE"} - 1) * $gEquates{"TILE_PIXEL_WIDTH"}) + 1;
$gEquates{"MOUSE_MAX_Y"} = (($gEquates{"PLAYER_TILES_HIGH"} - 1) * $gEquates{"TILE_PIXEL_HEIGHT"}) + 1;
$gEquates{"STARTING_MOUSE_X"} = $gEquates{"MOUSE_MAX_X"} / 2;
$gEquates{"STARTING_MOUSE_Y"} = $gEquates{"MOUSE_MAX_Y"} - 1;
our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"};
@ -68,20 +74,21 @@ our @gTileBitMask = (0) x $gEquates{"NUM_GAME_TILES"};
our @gDirtyNonGameTiles = ("INVALID_TILE_NUM") x $gEquates{"NUM_NON_GAME_TILES"};
our $gNumDirtyNonGameTiles = 0;
our @gMouseYAddress = (0) x $gEquates{"MOUSE_MAX_Y"};
our @gScreenToTileOffset = (0) x ($gEquates{"SCREEN_PIXELS_TALL"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"});
sub printTileData
{
my ($symbol, @data) = @_;
my ($fh, $symbol, @data) = @_;
print $fh "\n";
print $fh "\n";
print $fh "$symbol anop\n";
print TILEDATA_S << "EOF";
$symbol anop
EOF
for my $tileNum (0 .. $#data)
for my $index (0 .. $#data)
{
print TILEDATA_S " dc i2'$data[$tileNum]'\t; Tile number $tileNum\n";
print $fh " dc i2'$data[$index]'\t; Index $index\n";
}
}
@ -169,7 +176,7 @@ sub screenAddressForTileAtXY
{
my ($x, $y) = @_;
return 0x2000 + ($gEquates{"SCREEN_BYTES_PER_ROW"} * $y) + ($x / $gEquates{"SCREEN_PIXELS_PER_BYTE"}) + 3;
return $gEquates{"SCREEN_ADDRESS"} + ($gEquates{"SCREEN_BYTES_PER_ROW"} * $y) + ($x / $gEquates{"SCREEN_PIXELS_PER_BYTE"}) + 3;
}
@ -181,15 +188,26 @@ sub initTiles
my $bitMask = 1;
my $rhsTileIndex = $gEquates{"RHS_FIRST_TILE"};
my $lhsTileIndex = $gEquates{"LHS_FIRST_TILE"};
my $screenOffset = 0;
for ($tileY = 0; $tileY < $gEquates{"TOTAL_TILES_TALL"}; $tileY++)
{
$screenOffset = ($tileY * $gEquates{"TILE_PIXEL_HEIGHT"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"});
$lastOffset = screenAddressForTileAtXY(0, $tileY * $gEquates{"TILE_PIXEL_HEIGHT"});
for ($tileX = 0; $tileX < $gEquates{"LHS_NUM_TILES_WIDE"}; $tileX++)
{
$gTileScreenOffset[$lhsTileIndex] = $lastOffset;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $lhsTileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0)
{
$gTileAbove[$lhsTileIndex] = lhsXYToTileOffset($tileX, $tileY - 1);
@ -225,6 +243,15 @@ sub initTiles
$gTileBitOffset[$tileIndex] = $bitOffset;
$gTileBitMask[$tileIndex] = $bitMask;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $tileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0)
{
$gTileAbove[$tileIndex] = gameXYToTileOffset($tileX, $tileY - 1);
@ -272,6 +299,15 @@ sub initTiles
{
$gTileScreenOffset[$rhsTileIndex] = $lastOffset;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $rhsTileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0)
{
$gTileAbove[$rhsTileIndex] = rhsXYToTileOffset($tileX, $tileY - 1);
@ -301,6 +337,14 @@ sub initTiles
$lastOffset += $gEquates{"TILE_BYTE_WIDTH"};
}
}
# Calculate the memory address of the 0th row of the player's mouse position.
$lastOffset = $gEquates{"SCREEN_ADDRESS"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * $gEquates{"TILE_BYTE_WIDTH"}) + (($gEquates{"GAME_NUM_TILES_TALL"} - $gEquates{"PLAYER_TILES_HIGH"}) * $gEquates{"TILE_PIXEL_HEIGHT"} * $gEquates{"SCREEN_BYTES_PER_ROW"});
for (my $y = 0; $y < $gEquates{"MOUSE_MAX_Y"}; $y++)
{
$gMouseYAddress[$y] = $lastOffset;
$lastOffset += $gEquates{"SCREEN_BYTES_PER_ROW"};
}
}
@ -381,9 +425,8 @@ initTiles();
initNonGameTiles();
# Generate the tileData.s file
open(TILEDATA_S, "> $gGenDir/tileData.s") or die "$0: Unable to open $gGenDir/tileData.s for writing, $!";
print TILEDATA_S << "EOF";
open my $fh, ">", "$gGenDir/tileData.s" or die "$0: Unable to open $gGenDir/tileData.s for writing, $!";
my $text = << "EOF";
case on
mcopy tilesData.macros
keep tilesData
@ -392,56 +435,78 @@ tileData data
using globalData
EOF
print $fh $text;
foreach my $equate (sort keys %gEquates)
{
print TILEDATA_S "$equate\tgequ " . $gEquates{$equate} . "\n";
print $fh "$equate\tgequ " . $gEquates{$equate} . "\n";
}
printTileData("tileDirty", @gTileDirty);
printTileData("tileScreenOffset", @gTileScreenOffset);
printTileData("tileType", @gTileType);
printTileData("tileAbove", @gTileAbove);
printTileData("tileBelow", @gTileBelow);
printTileData("tileLeft", @gTileLeft);
printTileData("tileRight", @gTileRight);
printTileData("tileBitOffset", @gTileBitOffset);
printTileData("tileBitMask", @gTileBitMask);
printTileData("dirtyNonGameTiles", @gDirtyNonGameTiles);
printTileData($fh, "tileDirty", @gTileDirty);
printTileData($fh, "tileScreenOffset", @gTileScreenOffset);
printTileData($fh, "tileType", @gTileType);
printTileData($fh, "tileAbove", @gTileAbove);
printTileData($fh, "tileBelow", @gTileBelow);
printTileData($fh, "tileLeft", @gTileLeft);
printTileData($fh, "tileRight", @gTileRight);
printTileData($fh, "tileBitOffset", @gTileBitOffset);
printTileData($fh, "tileBitMask", @gTileBitMask);
printTileData($fh, "dirtyNonGameTiles", @gDirtyNonGameTiles);
printTileData($fh, "mouseYAddress", @gMouseYAddress);
print TILEDATA_S << "EOF";
$text = << "EOF";
numDirtyNonGameTiles dc i2'$gNumDirtyNonGameTiles'
end
EOF
print $fh $text;
close($fh);
# Generate the screenData.s file
open $fh, ">", "$gGenDir/screenData.s" or die "$0: Unable to open $gGenDir/screenData.s for writing, $!";
$text = << "EOF";
case on
mcopy screenData.macros
keep screenData
screenData data screenDataSeg
EOF
print $fh $text;
close(TILEDATA_S);
printTileData($fh, "screenToTileOffset", @gScreenToTileOffset);
$text = << "EOF";
end
EOF
print $fh $text;
close($fh);
# Generate the tileData.h file
open(TILEDATA_H, "> $gGenDir/tileData.h") or die "$0: Unable to open $gGenDir/tileData.h for writing, $!";
print TILEDATA_H << "EOF";
open $fh, ">", "$gGenDir/tileData.h" or die "$0: Unable to open $gGenDir/tileData.h for writing, $!";
$text = << "EOF";
#ifndef _GUARD_PROJECTBuGS_FILEtileData_
#define _GUARD_PROJECTBuGS_FILEtileData_
EOF
print $fh $text;
foreach my $equate (sort keys %gEquates)
{
print TILEDATA_H "#define $equate " . $gEquates{$equate} . "\n";
print $fh "#define $equate " . $gEquates{$equate} . "\n";
}
print TILEDATA_H << "EOF";
$text = << "EOF";
#endif /* define _GUARD_PROJECTBuGS_FILEtileData_ */
EOF
close(TILEDATA_H);
print $fh $text;
close($fh);