#!/usr/local/bin/perl

;# 'turn' 僩儔儞僕僔儑儞梡偺曄宍梡僥乕僽儖傪嶌惉偡傞

;# 64x64 偺惓曽宍傪旽宍偵曄宍偡傞曄姺傪峫偊傞
;#                        侾侾侾侾侾侾侾侾侾侾俀俀俀俀俀俀俀俀俀俀俁俁
;#    侽侾俀俁係俆俇俈俉俋侽侾俀俁係俆俇俈俉俋侽侾俀俁係俆俇俈俉俋侽侾
;#  0 仠仠仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭
;#  1 仠乢仠仠丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒乛仭
;#  2 仠丒乢丒仠仠仠丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒乛丒仭
;#  3 仭仠丒乢丒丒丒仠仠丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒乛丒丒仭
;#  4 仭仠丒丒乢丒丒丒丒仠仠仠丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒乛丒丒丒仭
;#  5 仭仠丒丒丒乢丒丒丒丒丒丒仠仠丒丒丒丒丒丒丒丒丒丒丒丒乛丒丒丒丒仭
;#  6 仭仠丒丒丒丒乢丒丒丒丒丒丒丒仠仠丒丒丒丒丒丒丒丒丒乛丒丒丒丒丒仭
;#  7 仭仠丒丒丒丒丒乢丒丒丒丒丒丒丒丒仠仠仠丒丒丒丒丒乛丒丒丒丒丒丒仭
;#  8 仭丒仠丒丒丒丒丒乢丒丒丒丒丒丒丒丒丒丒仠仠丒丒乛丒丒丒丒丒丒丒仭
;#  9 仭丒仠丒丒丒丒丒丒乢丒丒丒丒丒丒丒丒丒丒丒仠仠仠丒丒丒兝丒丒丒仭
;# 10 仭丒仠丒丒丒丒丒丒丒乢丒丒丒丒丒丒丒丒丒丒乛丒丒仠仠丒伀丒丒丒仭
;# 11 仭丒仠丒丒丒丒丒丒丒丒乢丒丒丒丒丒丒丒丒乛丒丒丒丒丒仠仠丒丒丒仭
;# 12 仭丒仠丒丒丒丒丒丒丒丒丒乢丒丒丒丒丒丒乛丒丒丒丒丒丒丒仠丒丒丒仭
;# 13 仭丒丒仠丒丒丒丒丒丒丒丒丒乢丒丒丒丒乛丒丒丒丒丒丒丒丒仠丒丒丒仭
;# 14 仭丒丒仠丒丒丒丒丒丒丒丒丒丒乢丒丒乛丒丒丒丒丒丒丒丒丒丒仠丒丒仭
;# 15 仭丒丒仠丒丒丒丒丒丒丒丒丒丒丒乢乛丒丒丒丒丒丒丒丒丒丒丒仠丒丒仭
;# 16 仭丒丒仠丒丒丒丒丒丒丒丒丒丒丒乛乢丒丒丒丒丒丒丒丒丒丒丒仠丒丒仭
;# 17 仭丒丒仠丒丒丒丒丒丒丒丒丒丒乛丒丒乢丒丒丒丒丒丒丒丒丒丒仠丒丒仭
;# 18 仭丒丒丒仠丒丒丒丒丒丒丒丒乛丒丒丒丒乢丒丒丒丒丒丒丒丒丒仠丒丒仭
;# 19 仭丒丒丒仠丒丒丒丒丒丒丒乛丒丒丒丒丒丒乢丒丒丒丒丒丒丒丒丒仠丒仭
;# 20 仭丒丒丒仠仠丒丒丒丒丒乛丒丒丒丒丒丒丒丒乢丒丒丒丒丒丒丒丒仠丒仭
;# 21 仭丒丒丒仾丒仠仠丒丒乛丒丒丒丒丒丒丒丒丒丒乢丒丒丒丒丒丒丒仠丒仭
;# 22 仭丒丒丒兛丒丒丒仠仠仠丒丒丒丒丒丒丒丒丒丒丒乢丒丒丒丒丒丒仠丒仭
;# 23 仭丒丒丒丒丒丒丒乛丒丒仠仠丒丒丒丒丒丒丒丒丒丒乢丒丒丒丒丒仠丒仭
;# 24 仭丒丒丒丒丒丒乛丒丒丒丒丒仠仠仠丒丒丒丒丒丒丒丒乢丒丒丒丒丒仠仭
;# 25 仭丒丒丒丒丒乛丒丒丒丒丒丒丒丒丒仠仠丒丒丒丒丒丒丒乢丒丒丒丒仠仭
;# 26 仭丒丒丒丒乛丒丒丒丒丒丒丒丒丒丒丒丒仠仠丒丒丒丒丒丒乢丒丒丒仠仭
;# 27 仭丒丒丒乛丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒仠仠仠丒丒丒丒乢丒丒仠仭
;# 28 仭丒丒乛丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒仠仠丒丒丒乢丒仠仭
;# 29 仭丒乛丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒仠仠仠丒乢丒仠
;# 30 仭乛丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒丒仠仠乢仠
;# 31 仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仭仠仠

;# ( 偙偺恾偼 32x32 )

;# 偙偙偱帵偟偨仭偑丄仠偱帵偟偨旽宍偵曄宍偝傟傞丅
;# 曄姺偼僗僉儍儞儔僀儞 ( y 嵗昗 ) 偛偲偵媮傔傞丅

;# cpp 愭摢晹暘弌椡
open FH, ">../turntrans_table.cpp";

print FH <<EOF;
/* 'turn' 僩儔儞僕僔儑儞梡曄宍曄姺僥乕僽儖 */
/* 偙偺僼傽僀儖偼 mkturntranstable.pl 偵傛傝嶌惉偝傟傑偟偨 */

#include "turntrans_table.h"

const tTurnTransParams TurnTransParams[64][64] =
{
	/* { start, len, sx, sy, ex, ey, stepx, stepy } */

EOF


;# n = 0 偺僟儈乕僨乕僞弌椡

print FH "\t/* n = 0 (not used) */\n";
print FH "\t{\n";

for($y = 0; $y < 64; $y++)
{
	print FH ",\n" if $y != 0;
	printf FH "\t\t/* y = %2d */ {0, 0, 0, 0, 0, 0, 0, 0}", $y;
}
print FH "\n";
print FH "\t},\n";

for($n = 1; $n <= 62; $n++)
{
	;# $y (僗僉儍儞儔僀儞)
	@starts = ();
	@ends = ();
	@len = ();
	@sx = ();
	@sy = ();
	@ex = ();
	@ey = ();
	@stepx = ();
	@stepy = ();

	;# 兛揰丄兝揰偺寁嶼偵娭偟偰偼偁傑傝尩枾側幃傪梡偄側偄
	;# ( 尩枾偵寁嶼偡傞偲暯婥偱偼傒弌傞偙偲偵側傞 )
	;# 傑偁偪傚偭偲偖傜偄備偑傫偱偄偰傕偪偭偪傖偄偐傜婥偵側傜傫偼偢

	;# 兛揰傪寁嶼
	if($n < 32)
	{
		$p = int($n * $n / 31);
		$d = int(sin($p * 3.14159265358979 / 64)*4);
		$a_x = $p - $d;
		$a_y = 63 - $p - $d;
	}
	else
	{
		$p = 63 - int((63 - $n) * (63 - $n) / 31);
		$d = int(sin((63-$p) * 3.14159265358979 / 64)*4);
		$a_x = 63 - $p + $d;
		$a_y = $p + $d;
	}

	;# 兝揰傪寁嶼
	$b_x = 63 - $a_x;
	$b_y = 63 - $a_y;

	print FH "\t/* n = $n */\n";
	printf FH "\t/* 兛 = (%d, %d)  兝 = (%d, %d) */\n", $a_x, $a_y, $b_x, $b_y;


	for($y = 0; $y < 64; $y ++)
	{
		if($y <= $a_y)
		{
			;# (0,0) - (兛揰) 慄暘忋偺 x 嵗昗 $l 傪媮傔傞
			if($a_y == 0)
			{
				$l = 0;
			}
			else
			{
				$l = int($a_x * $y / $a_y);
			}
		}
		else
		{
			;# (兛揰) - (63,63) 慄暘忋偺 x 嵗昗 $l 傪媮傔傞
			if($a_y != 63)
			{
				$l = $a_x + int((63 - $a_x) * ($y - $a_y) / (63 - $a_y));
			}
			else
			{
				$l = 63;
			}
		}

		if($y <= $b_y)
		{
			;# (0,0) - (兝揰) 慄暘忋偺 x 嵗昗 $r 傪媮傔傞
			if($b_y == 0)
			{
				$r = 63;
			}
			else
			{
				$r = int($b_x * $y / $b_y);
			}
		}
		else
		{
			;# (兝揰) - (63,63) 慄暘忋偺 x 嵗昗 $r 傪媮傔傞
			if($b_y != 63)
			{
				$r = $b_x + int((63 - $b_x) * ($y - $b_y) / (63 - $b_y));
			}
			else
			{
				$r = 63;
			}
		}

		if($l > $r) { $r = $l; } ;# 岆嵎曗惓

		push(@starts, $l);
		push(@ends, $r);

		;# 挿偝 $len 傪媮傔傞
		$len = $r - $l + 1;

		push(@len, $len);

		;# 曄姺尦惓曽宍偺奐巒埵抲 $sx, $sy 傪媮傔傞
		if($y <= $a_y)
		{
			$sx = 0;
			$sy = int(63 * $y / $a_y) if $a_y;
			$sy = 0 if !$a_y;
		}
		else
		{
			$sx = int(63 * ($y - $a_y) / (63 - $a_y));
			$sy = 63;
		}

		push(@sx, $sx << 16);
		push(@sy, $sy << 16);

		;# 曄姺尦惓曽宍偺廔椆埵抲 $ex, $ey 傪媮傔傞
		if($y <= $b_y)
		{
			$ex = int(63 * $y / $b_y) if $b_y;
			$ex = 63 if !$b_y;
			$ey = 0;
		}
		else
		{
			$ex = 63;
			$ey = int(63 * ($y - $b_y) / (63 - $b_y));
		}

		push(@ex, $ex << 16);
		push(@ey, $ey << 16);

		;# 曄姺尦惓曽宍傪憱嵏偡傞偨傔偺 x, y 偺僗僥僢僾 傪
		;# 16bit栚偵彫悢揰傪帩偮屌掕彫悢揰悢偱媮傔傞
		if($len >= 2)
		{
			$stepx = int(($ex - $sx) / ($len-1) * 65536);
			$stepy = int(($ey - $sy) / ($len-1) * 65536);
		}
		else
		{
			$stepx = 0;
			$stepy = 0;
		}

		push(@stepx, $stepx);
		push(@stepy, $stepy);
	}

	;# 僨乕僞偺彂偒弌偟
	print FH "\t{\n";

	for($y = 0; $y < 64; $y++)
	{
		print FH ",\n" if $y != 0;
		printf FH "\t\t/* y = %2d */ /* l = %3d, r = %2d */ {%2d, %2d, %7d, %7d, %7d, %7d, %8d, %8d}",
			$y, $starts[$y], $ends[$y],
			$starts[$y], $len[$y],
			$sx[$y], $sy[$y], $ex[$y], $ey[$y],
			$stepx[$y], $stepy[$y];
	}

	print FH "\n";
	print FH "\t},\n";
}


;# n = 63 偺僟儈乕僨乕僞弌椡

print FH "\t/* n = 63 (not used) */\n";
print FH "\t{\n";

for($y = 0; $y < 64; $y++)
{
	print FH ",\n" if $y != 0;
	printf FH "\t\t/* y = %2d */ {0, 0, 0, 0, 0, 0, 0, 0}", $y;
}
print FH "\n";
print FH "\t}\n";


print FH "};\n";

;# 僿僢僟弌椡

open FH, ">../turntrans_table.h";

print FH <<EOF;
/* 'turn' 僩儔儞僕僔儑儞梡曄宍曄姺僥乕僽儖 */
/* 偙偺僼傽僀儖偼 mkturntranstable.pl 偵傛傝嶌惉偝傟傑偟偨 */

#ifndef turntrans_table_H
#define turntrans_table_H

#pragma pack(push, 4)
struct tTurnTransParams
{
	int start;
	int len;
	int sx; // source start x ( * 65536 )
	int sy; // source start y ( * 65536 )
	int ex; // source end x ( * 65536 )
	int ey; // source end y ( * 65536 )
	int stepx; // source step x ( * 65536 )
	int stepy; // source step y ( * 65536 )
};
#pragma pack(pop)

extern const tTurnTransParams TurnTransParams[64][64];


#endif

EOF



