mirror of https://github.com/jeremysrand/BuGS.git
448 lines
12 KiB
Perl
Executable File
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);
|