BuGS/BuGS/tileData.pl

448 lines
12 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_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"};
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;
sub printTileData
{
my ($symbol, @data) = @_;
print TILEDATA_S << "EOF";
$symbol anop
EOF
for my $tileNum (0 .. $#data)
{
print TILEDATA_S " dc i2'$data[$tileNum]'\t; Tile number $tileNum\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 0x2000 + ($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"};
for ($tileY = 0; $tileY < $gEquates{"TOTAL_TILES_TALL"}; $tileY++)
{
$lastOffset = screenAddressForTileAtXY(0, $tileY * $gEquates{"TILE_PIXEL_HEIGHT"});
for ($tileX = 0; $tileX < $gEquates{"LHS_NUM_TILES_WIDE"}; $tileX++)
{
$gTileScreenOffset[$lhsTileIndex] = $lastOffset;
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;
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;
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"};
}
}
}
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 = $gEquates{"LHS_NUM_TILES_WIDE"} - 2;
$y = 6;
addLhsGameString($x, $y, "0");
$x = 2;
$y = 8;
addLhsGameString($x, $y, "LIVES:");
$x = $gEquates{"LHS_NUM_TILES_WIDE"} - 2;
$y = 9;
for (my $i = 0; $i < 3; $i++)
{
addLhsGameTile($x, $y, "TILE_PLAYER");
$x--;
}
$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 = $gEquates{"LHS_NUM_TILES_WIDE"} - 2;
$y = 19;
addLhsGameString($x, $y, "0");
$x = 2;
$y = 21;
addLhsGameString($x, $y, "LIVES:");
$x = $gEquates{"LHS_NUM_TILES_WIDE"} - 2;
$y = 22;
for (my $i = 0; $i < 3; $i++)
{
addLhsGameTile($x, $y, "TILE_PLAYER");
$x--;
}
}
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";
case on
mcopy tilesData.macros
keep tilesData
tileData data
using globalData
EOF
foreach my $equate (sort keys %gEquates)
{
print TILEDATA_S "$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);
print TILEDATA_S << "EOF";
numDirtyNonGameTiles dc i2'$gNumDirtyNonGameTiles'
end
EOF
close(TILEDATA_S);
# 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";
#ifndef _GUARD_PROJECTBuGS_FILEtileData_
#define _GUARD_PROJECTBuGS_FILEtileData_
EOF
foreach my $equate (sort keys %gEquates)
{
print TILEDATA_H "#define $equate " . $gEquates{$equate} . "\n";
}
print TILEDATA_H << "EOF";
#endif /* define _GUARD_PROJECTBuGS_FILEtileData_ */
EOF
close(TILEDATA_H);