BuGS/BuGS/tileData.pl

509 lines
17 KiB
Perl
Executable File

#!/usr/bin/perl
# tileData.pl
# BuGS
#
# Created by Jeremy Rand on 2020-11-03.
# Copyright © 2020 Jeremy Rand. All rights reserved.
use strict;
use integer;
# main
die "$0: Expected one argument pointing to the gen directory" if ($#ARGV != 0);
my $gGenDir = $ARGV[0];
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;
$gEquates{"SCREEN_BYTES_PER_ROW"} = $gEquates{"SCREEN_PIXELS_WIDE"} / $gEquates{"SCREEN_PIXELS_PER_BYTE"};
$gEquates{"TILE_PIXEL_WIDTH"} = 8;
$gEquates{"TILE_PIXEL_HEIGHT"} = 8;
$gEquates{"TILE_BYTE_WIDTH"} = $gEquates{"TILE_PIXEL_WIDTH"} / $gEquates{"SCREEN_PIXELS_PER_BYTE"};
$gEquates{"TOTAL_TILES_WIDE"} = $gEquates{"SCREEN_PIXELS_WIDE"} / $gEquates{"TILE_PIXEL_WIDTH"};
$gEquates{"TOTAL_TILES_TALL"} = $gEquates{"SCREEN_PIXELS_TALL"} / $gEquates{"TILE_PIXEL_HEIGHT"};
$gEquates{"TOTAL_NUM_TILES"} = $gEquates{"TOTAL_TILES_WIDE"} * $gEquates{"TOTAL_TILES_TALL"};
$gEquates{"GAME_NUM_TILES_WIDE"} = 25;
$gEquates{"GAME_NUM_TILES_TALL"} = $gEquates{"TOTAL_TILES_TALL"};
$gEquates{"NUM_GAME_TILES"} = $gEquates{"GAME_NUM_TILES_WIDE"} * $gEquates{"GAME_NUM_TILES_TALL"};
$gEquates{"SIZEOF_TILE_INFO"} = 2;
$gEquates{"RHS_NUM_TILES_WIDE"} = 2;
$gEquates{"NUM_RHS_NON_GAMES_TILES"} = $gEquates{"RHS_NUM_TILES_WIDE"} * $gEquates{"TOTAL_TILES_TALL"};
$gEquates{"RHS_FIRST_TILE"} = $gEquates{"NUM_GAME_TILES"};
$gEquates{"RHS_FIRST_TILE_OFFSET"} = $gEquates{"RHS_FIRST_TILE"} * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"LHS_NUM_TILES_WIDE"} = $gEquates{"TOTAL_TILES_WIDE"} - $gEquates{"GAME_NUM_TILES_WIDE"} - $gEquates{"RHS_NUM_TILES_WIDE"};
$gEquates{"NUM_LHS_NON_GAMES_TILES"} = $gEquates{"LHS_NUM_TILES_WIDE"} * $gEquates{"TOTAL_TILES_TALL"};
$gEquates{"LHS_FIRST_TILE"} = $gEquates{"RHS_FIRST_TILE"} + $gEquates{"NUM_RHS_NON_GAMES_TILES"};
$gEquates{"LHS_FIRST_TILE_OFFSET"} = $gEquates{"LHS_FIRST_TILE"} * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"NUM_NON_GAME_TILES"} = $gEquates{"NUM_RHS_NON_GAMES_TILES"} + $gEquates{"NUM_LHS_NON_GAMES_TILES"};
$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{"SPIDER_DISTANCE_900"} = $gEquates{"SCREEN_BYTES_PER_ROW"} * $gEquates{"TILE_PIXEL_HEIGHT"} * 2;
$gEquates{"SPIDER_DISTANCE_600"} = $gEquates{"SCREEN_BYTES_PER_ROW"} * $gEquates{"TILE_PIXEL_HEIGHT"} * 5;
$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;
$gEquates{"P1_SCORE_ONES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 6) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P1_SCORE_TENS_OFFSET"} = $gEquates{"P1_SCORE_ONES_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P1_SCORE_HUNDREDS_OFFSET"} = $gEquates{"P1_SCORE_TENS_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P1_SCORE_THOUSANDS_OFFSET"} = $gEquates{"P1_SCORE_HUNDREDS_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P1_SCORE_FIRST_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 6)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P1_LIVES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 9) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_SCORE_ONES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 19) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_SCORE_TENS_OFFSET"} = $gEquates{"P2_SCORE_ONES_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_SCORE_HUNDREDS_OFFSET"} = $gEquates{"P2_SCORE_TENS_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_SCORE_THOUSANDS_OFFSET"} = $gEquates{"P2_SCORE_HUNDREDS_OFFSET"} - $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_SCORE_FIRST_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 19)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"P2_LIVES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 22) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"HIGH_SCORE_ONES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 13) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
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"};
our @gTileAbove = ("INVALID_TILE_NUM") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileBelow = ("INVALID_TILE_NUM") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileLeft = ("INVALID_TILE_NUM") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileRight = ("INVALID_TILE_NUM") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileBitOffset = (0) x $gEquates{"NUM_GAME_TILES"};
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 ($fh, $symbol, @data) = @_;
print $fh "\n";
print $fh "\n";
print $fh "$symbol anop\n";
for my $index (0 .. $#data)
{
print $fh " dc i2'$data[$index]'\t; Index $index\n";
}
}
sub gameXYToTileOffset
{
my ($x, $y) = @_;
return (($y * $gEquates{"GAME_NUM_TILES_WIDE"}) + $x) * $gEquates{"SIZEOF_TILE_INFO"};
}
sub rhsXYToTileOffset
{
my ($x, $y) = @_;
return ($gEquates{"RHS_FIRST_TILE"} + ($y * $gEquates{"RHS_NUM_TILES_WIDE"}) + $x) * $gEquates{"SIZEOF_TILE_INFO"};
}
sub lhsXYToTileNum
{
my ($x, $y) = @_;
return $gEquates{"LHS_FIRST_TILE"} + ($y * $gEquates{"LHS_NUM_TILES_WIDE"}) + $x;
}
sub lhsXYToTileOffset
{
my ($x, $y) = @_;
return lhsXYToTileNum($x, $y) * $gEquates{"SIZEOF_TILE_INFO"};
}
sub addDirtyNonGameTile
{
my ($tileNum) = @_;
if ($gTileDirty[$tileNum] eq "TILE_STATE_CLEAN")
{
my $tileOffset = $tileNum * $gEquates{"SIZEOF_TILE_INFO"};
my $dirtyIndex = $gNumDirtyNonGameTiles / $gEquates{"SIZEOF_TILE_INFO"};
$gTileDirty[$tileNum] = "TILE_STATE_DIRTY";
$gDirtyNonGameTiles[$dirtyIndex] = $tileOffset;
$gNumDirtyNonGameTiles += $gEquates{"SIZEOF_TILE_INFO"};
}
}
sub addLhsGameTile
{
my ($x, $y, $tileType) = @_;
my $tileNum = lhsXYToTileNum($x, $y);
$gTileType[$tileNum] = $tileType;
addDirtyNonGameTile($tileNum);
}
sub addLhsGameString
{
my ($x, $y, $string) = @_;
foreach my $char (split('', $string)) {
if ($char =~ /^[0-9]$/)
{
addLhsGameTile($x, $y, "TILE_NUMBER_$char");
}
elsif ($char eq ":")
{
addLhsGameTile($x, $y, "TILE_SYMBOL_COLON");
}
elsif ($char ne " ")
{
addLhsGameTile($x, $y, "TILE_LETTER_$char");
}
$x++;
}
}
sub screenAddressForTileAtXY
{
my ($x, $y) = @_;
return $gEquates{"SCREEN_ADDRESS"} + ($gEquates{"SCREEN_BYTES_PER_ROW"} * $y) + ($x / $gEquates{"SCREEN_PIXELS_PER_BYTE"}) + 3;
}
sub initTiles
{
my($tileX, $tileY, $lastOffset);
my $tileIndex = 0;
my $bitOffset = 0;
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);
}
if ($tileY != $gEquates{"TOTAL_TILES_TALL"} - 1)
{
$gTileBelow[$lhsTileIndex] = lhsXYToTileOffset($tileX, $tileY + 1);
}
if ($tileX != 0)
{
$gTileLeft[$lhsTileIndex] = lhsXYToTileOffset($tileX - 1, $tileY);
}
if ($tileX == $gEquates{"LHS_NUM_TILES_WIDE"} - 1)
{
$gTileRight[$lhsTileIndex] = gameXYToTileOffset(0, $tileY);
}
else
{
$gTileRight[$lhsTileIndex] = lhsXYToTileOffset($tileX + 1, $tileY);
}
$lhsTileIndex++;
$lastOffset += $gEquates{"TILE_BYTE_WIDTH"};
}
for ($tileX = 0; $tileX < $gEquates{"GAME_NUM_TILES_WIDE"}; $tileX++)
{
$gTileScreenOffset[$tileIndex] = $lastOffset;
$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);
}
if ($tileY != $gEquates{"TOTAL_TILES_TALL"} - 1)
{
$gTileBelow[$tileIndex] = gameXYToTileOffset($tileX, $tileY + 1);
}
if ($tileX == 0)
{
$gTileLeft[$tileIndex] = lhsXYToTileOffset($gEquates{"LHS_NUM_TILES_WIDE"} - 1, $tileY);
}
else
{
$gTileLeft[$tileIndex] = gameXYToTileOffset($tileX - 1, $tileY);
}
if ($tileX == $gEquates{"GAME_NUM_TILES_WIDE"} - 1)
{
$gTileRight[$tileIndex] = rhsXYToTileOffset(0, $tileY);
}
else
{
$gTileRight[$tileIndex] = gameXYToTileOffset($tileX + 1, $tileY);
}
$tileIndex++;
if ($bitMask == 0x8000)
{
$bitOffset += $gEquates{"SIZEOF_TILE_INFO"} = 2;
$bitMask = 1;
}
else
{
$bitMask <<= 1;
}
$lastOffset += $gEquates{"TILE_BYTE_WIDTH"};
}
for ($tileX = 0; $tileX < $gEquates{"RHS_NUM_TILES_WIDE"}; $tileX++)
{
$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);
}
if ($tileY != $gEquates{"TOTAL_TILES_TALL"} - 1)
{
$gTileBelow[$rhsTileIndex] = rhsXYToTileOffset($tileX, $tileY + 1);
}
if ($tileX == 0)
{
$gTileLeft[$rhsTileIndex] = gameXYToTileOffset($gEquates{"GAME_NUM_TILES_WIDE"} - 1, $tileY);
}
else
{
$gTileLeft[$rhsTileIndex] = rhsXYToTileOffset($tileX - 1, $tileY);
}
if ($tileX != $gEquates{"RHS_NUM_TILES_WIDE"} - 1)
{
$gTileRight[$rhsTileIndex] = rhsXYToTileOffset($tileX + 1, $tileY);
}
$rhsTileIndex++;
$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"};
}
}
sub initNonGameTiles
{
my $x;
my $y;
$x = $gEquates{"LHS_NUM_TILES_WIDE"} / 2;
$y = 0;
addLhsGameTile($x, $y, "TILE_LETTER_B");
$x++;
addLhsGameTile($x, $y, "TILE_LETTER_WHITE_U");
$x++;
addLhsGameTile($x, $y, "TILE_LETTER_GREEN_G");
$x++;
addLhsGameTile($x, $y, "TILE_LETTER_GREEN_S");
$x = 0;
$y = 3;
addLhsGameString($x, $y, "PLAYER 1");
$x = 2;
$y = 5;
addLhsGameString($x, $y, "SCORE:");
$x = 2;
$y = 8;
addLhsGameString($x, $y, "LIVES:");
$x = 0;
$y = 12;
addLhsGameString($x, $y, "HIGH SCORE:");
$x = $gEquates{"LHS_NUM_TILES_WIDE"} - 2;
$y = 13;
addLhsGameString($x, $y, "0");
$x = 0;
$y = 16;
addLhsGameString($x, $y, "PLAYER 2");
$x = 2;
$y = 18;
addLhsGameString($x, $y, "SCORE:");
$x = 2;
$y = 21;
addLhsGameString($x, $y, "LIVES:");
}
initTiles();
initNonGameTiles();
# Generate the tileData.s file
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
tileData data
using globalData
EOF
print $fh $text;
foreach my $equate (sort keys %gEquates)
{
print $fh "$equate\tgequ " . $gEquates{$equate} . "\n";
}
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);
$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;
printTileData($fh, "screenToTileOffset", @gScreenToTileOffset);
$text = << "EOF";
end
EOF
print $fh $text;
close($fh);
# Generate the tileData.h file
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 $fh "#define $equate " . $gEquates{$equate} . "\n";
}
$text = << "EOF";
#endif /* define _GUARD_PROJECTBuGS_FILEtileData_ */
EOF
print $fh $text;
close($fh);