#! /usr/bin/perl

use strict;
use warnings FATAL => 'all';

my ($board_width, $board_height);
my ($screen_width, $screen_height);
my ($screen_a_base, $screen_b_base);

open(FILE, "< $ARGV[0]") or die "cannot read source: $!";
while (<FILE>) {
	my $i = $_;
	my $t;

	($t) = $i =~ /^BOARD_WIDTH\s+= (.*)/;
	$board_width = $t if (defined($t));

	($t) = $i =~ /^BOARD_HEIGHT\s+= (.*)/;
	$board_height = $t if (defined($t));

	($t) = $i =~ /^SCREEN_WIDTH\s+= (.*)/;
	$screen_width = $t if (defined($t));

	($t) = $i =~ /^SCREEN_HEIGHT\s+= (.*)/;
	$screen_height = $t if (defined($t));

	($t) = $i =~ /^SCREEN_A\s+= (.*)/;
	$screen_a_base = $t if (defined($t));

	($t) = $i =~ /^SCREEN_B\s+= (.*)/;
	$screen_b_base = $t if (defined($t));
}
close(FILE);

my $err = 0;
if (! defined($board_width)) {
	print STDERR "board width missing\n";
	$err = 1;
}
if (! defined($board_height)) {
	print STDERR "board height missing\n";
	$err = 1;
}
if (! defined($screen_width)) {
	print STDERR "screen width missing\n";
	$err = 1;
}
if (! defined($screen_height)) {
	print STDERR "screen height missing\n";
	$err = 1;
}
if (! defined($screen_a_base)) {
	print STDERR "screen a base missing\n";
	$err = 1;
}
if (! defined($screen_b_base)) {
	print STDERR "screen b base missing\n";
	$err = 1;
}
($err) && exit(1);

print <<EOF;
; created with life2-init.pl
; don't edit this file, you'll just end up losing your changes




EOF


foreach my $screen ("a", "b") {
	my $source = "SCREEN_\u$screen";
	my $o_screen = $screen;
	$o_screen =~ tr/ab/ba/;
	my $target = "SCREEN_\u$o_screen";

	my $or = $screen eq "a" ? "#16" : "#128";

	print <<EOF;
init_round_$screen:
	; a1
	lda	#<($source)
	sta	ptr_a1 + 1
	lda	#>($source)
	sta	ptr_a1 + 2
	; a2
	lda	#<($source + 1)
	sta	ptr_a2 + 1
	lda	#>($source + 1)
	sta	ptr_a2 + 2
	; a3
	lda	#<($source +     SCREEN_WIDTH)
	sta	ptr_a3 + 1
	lda	#>($source +     SCREEN_WIDTH)
	sta	ptr_a3 + 2
	; a4
	lda	#<($source + 1 + SCREEN_WIDTH)
	sta	ptr_a4 + 1
	lda	#>($source + 1 + SCREEN_WIDTH)
	sta	ptr_a4 + 2

	; b1
	lda	#<($source + 1)
	sta	ptr_b1 + 1
	lda	#>($source + 1)
	sta	ptr_b1 + 2
	; b2
	lda	#<($source + 2)
	sta	ptr_b2 + 1
	lda	#>($source + 2)
	sta	ptr_b2 + 2
	; b3
	lda	#<($source + 1 + SCREEN_WIDTH)
	sta	ptr_b3 + 1
	lda	#>($source + 1 + SCREEN_WIDTH)
	sta	ptr_b3 + 2
	; b4
	lda	#<($source + 2 + SCREEN_WIDTH)
	sta	ptr_b4 + 1
	lda	#>($source + 2 + SCREEN_WIDTH)
	sta	ptr_b4 + 2

	; c1
	lda	#<($source +     SCREEN_WIDTH)
	sta	ptr_c1 + 1
	lda	#>($source +     SCREEN_WIDTH)
	sta	ptr_c1 + 2
	; c2
	lda	#<($source + 1 + SCREEN_WIDTH)
	sta	ptr_c2 + 1
	lda	#>($source + 1 + SCREEN_WIDTH)
	sta	ptr_c2 + 2
	; c3
	lda	#<($source +     SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_c3 + 1
	lda	#>($source +     SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_c3 + 2
	; c4
	lda	#<($source + 1 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_c4 + 1
	lda	#>($source + 1 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_c4 + 2

	; d1
	lda	#<($source + 1 + SCREEN_WIDTH)
	sta	ptr_d1 + 1
	lda	#>($source + 1 + SCREEN_WIDTH)
	sta	ptr_d1 + 2
	; d2
	lda	#<($source + 2 + SCREEN_WIDTH)
	sta	ptr_d2 + 1
	lda	#>($source + 2 + SCREEN_WIDTH)
	sta	ptr_d2 + 2
	; d3
	lda	#<($source + 1 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_d3 + 1
	lda	#>($source + 1 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_d3 + 2
	; d4
	lda	#<($source + 2 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_d4 + 1
	lda	#>($source + 2 + SCREEN_WIDTH + SCREEN_WIDTH)
	sta	ptr_d4 + 2

	; t
	lda	#<($target + 1 + SCREEN_WIDTH)
	sta	ptr_t + 1
	lda	#>($target + 1 + SCREEN_WIDTH)
	sta	ptr_t + 2

	; swap char ram/rom
	lda	53272
	and	#\$0f
	ora	$or
	sta	53272

copy_borders_$screen:
	; horizontal
EOF
	for (my $x = 0; $x < $board_width / 2; $x++) {
		print <<EOF;
	lda	$source + $x + 1 + SCREEN_WIDTH
	sta	$source + $x + 1 + ((BOARD_HEIGHT / 2 + 1) * SCREEN_WIDTH)
	lda	$source + $x + 1 + (BOARD_HEIGHT / 2 * SCREEN_WIDTH)
	sta	$source + $x + 1

EOF
	}

	print <<EOF;

	; vertical
EOF
	for (my $y = 0; $y < $board_height / 2; $y++) {
		print <<EOF;
	lda	$source + 1 + $y * SCREEN_WIDTH + SCREEN_WIDTH
	sta	$source + 1 + $y * SCREEN_WIDTH + SCREEN_WIDTH + (BOARD_WIDTH / 2)
	lda	$source + BOARD_WIDTH / 2 + $y * SCREEN_WIDTH + SCREEN_WIDTH
	sta	$source + $y * SCREEN_WIDTH + SCREEN_WIDTH

EOF
	}

	print <<EOF;

	; corners
	lda	$source + 1 + SCREEN_WIDTH
	sta	$source + 1 + BOARD_WIDTH / 2 + (BOARD_HEIGHT / 2 + 1) * SCREEN_WIDTH

	lda	$source + BOARD_WIDTH / 2 + SCREEN_WIDTH
	sta	$source + (BOARD_HEIGHT / 2 + 1) * SCREEN_WIDTH

	lda	$source + 1 + (BOARD_HEIGHT / 2) * SCREEN_WIDTH
	sta	$source + BOARD_WIDTH / 2 + 1

	lda	$source + BOARD_WIDTH / 2 + (BOARD_HEIGHT / 2) * SCREEN_WIDTH
	sta	$source

	rts


EOF
}
