
//2D图形引擎

//注意事项:
//*  Z8*Z8容易溢出

//初版: 2013年5月
//实现图标的创建 旋转和显示

//V1: 2013年7月17日
//把接口参数(坐标)从Z16改为Z32,按照库的编写规则规范化
//修正了图标装载的BUG,避免Z8*Z8的溢出

//V1: 2014年1月9日
//源代码改为标准C语言格式

//V2: 2015年5月1日
//准备去掉code专用显示函数, 因为现在base和code合并了... 非常好
//已经改好了
//测试成功非正方形图片的旋转, 改正了一些小BUG

unit GUI
{
	public const uint16 ID = 0;
	
	//[i] linkinterface_map map;
	public link unit map {}
	
	//[i] var_int16 Line;
	public int16 Line;
	//[i] var_int16 Column;
	public int16 Column;
	
	//[i] struct icon;
	public struct icon
	{
		uint8 Type;
		int8 CharWidth;
		uint8 ColumnL;
		uint8 ColumnH;
		uint8 area;
		uint8 d0;
		uint8 d1;
		uint8 d2;
		uint8 d3;
		
		[uint8*?] buffer;
	}
	//[i] linksysconst_uint16 OS_BufferLength;
	public const int16 OS_BufferLength = 0;
	
	[uint8*OS_BufferLength] icon_buffer;
	uint16 HeapStart;
	
	//---------------------------------------------------
	//[i] function_void OS_init;
	public void OS_init()
	{
		Line = map.LineNumber;
		Column = map.AreaNumber * 8;
		HeapStart = 0;
	}
	//---------------------------------------------------
	//[i] function_void Clear;
	public void Clear()
	{
		map.Clear();
	}
	//---------------------------------------------------
	//[i] function_void DrawIcon bitmap int32 int32;
	public void DrawIcon( struct icon icon, int32 XX, int32 YY )
	{
		int16 X = (int16)XX;
		int16 Y = (int16)YY;
		int16 AreaY;
		uint8 OffsetY;
		SawToothMod( Y, AreaY, OffsetY );
		
		uint16 YBlockNumber = icon.area / 8;
		
		//行列遍历输出图标
		uint16 BufferIndex = 0;
		for( uint8 i = 0; i < icon.ColumnL; i + 1 ) {
			BufferIndex = i;
			uint8 LastData = 0;
			for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
				uint16 data = icon.buffer[BufferIndex];
				data << OffsetY;
				data.0(uint8) = data.0(uint8) | LastData;
				LastData = data.8(uint8);
				map.set_pos( X + (int)i, AreaY + (int)YN );
				map.set_uint8( data.0(uint8) );
				BufferIndex + icon.ColumnL;
			}
			map.set_pos( X + (int)i, AreaY + (int)YBlockNumber );
			map.set_uint8( LastData );
		}
	}
	//---------------------------------------------------
	//[i] function_bitmap OS_CreateIcon int32 int32;
	public struct icon OS_CreateIcon( int32 l, int32 c )
	{
		->struct icon temp -> icon_buffer[HeapStart];
		temp.ColumnL = (uint)(int8)(int16)l;
		temp.area = (uint)(int8)(int16)c;
		
		HeapStart + (uint16)(uint)(2 + l * (c / 8));
		return temp;
	}
	//---------------------------------------------------
	///[i] function_void LoadIcon bitmap bitmap;
	public void LoadIcon( [#.code uint8*?] buffer, struct icon icon )
	{
		uint16 n = icon.ColumnL;
		n * (icon.area / 8);
		for(uint16 i = 0; i < n; i + 1 ) {
			icon.buffer[i] = buffer[i + 2];
		}
	}
	//---------------------------------------------------
	//[i] function_void CopyIcon bitmap bitmap;
	public void CopyIcon( struct icon SourceIcon, struct icon TargetIcon )
	{
		uint16 n = SourceIcon.ColumnL;
		n * (SourceIcon.area / 8);
		for(uint16 i = 0; i < n; i + 1 ) {
			TargetIcon.buffer[i] = SourceIcon.buffer[i];
		}
	}
	//---------------------------------------------------
	//[i] function_void RolRightIcon bitmap bitmap;
	public void RolRightIcon( struct icon SourceIcon, struct icon TargetIcon )
	{
		uint16 XBlockNumber = SourceIcon.ColumnL / 8;
		uint16 YBlockNumber = SourceIcon.area / 8;
		
		//行列遍历
		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
			for( uint16 XN = 0; XN < XBlockNumber; XN + 1 ) {
				uint16 newYN = XN;
				uint16 newXN = YBlockNumber - YN - 1;
				->[uint8*?] SourcePoint -> SourceIcon.buffer[YN * SourceIcon.ColumnL + XN * 8];
				->[uint8*?] TargetPoint -> TargetIcon.buffer[newYN * TargetIcon.ColumnL + newXN * 8];
				uint8 D0 = SourcePoint[0];
				uint8 D1 = SourcePoint[1];
				uint8 D2 = SourcePoint[2];
				uint8 D3 = SourcePoint[3];
				uint8 D4 = SourcePoint[4];
				uint8 D5 = SourcePoint[5];
				uint8 D6 = SourcePoint[6];
				uint8 D7 = SourcePoint[7];
				for( int8 i = 0; i < 8; i + 1 ) {
					uint8 TD;
					TD.0(bit) = D0.7(bit); D0 << 1;
					TD.1(bit) = D1.7(bit); D1 << 1;
					TD.2(bit) = D2.7(bit); D2 << 1;
					TD.3(bit) = D3.7(bit); D3 << 1;
					TD.4(bit) = D4.7(bit); D4 << 1;
					TD.5(bit) = D5.7(bit); D5 << 1;
					TD.6(bit) = D6.7(bit); D6 << 1;
					TD.7(bit) = D7.7(bit); D7 << 1;
					TargetPoint[i] = TD;
				}
			}
		}
	}
	//---------------------------------------------------
	//[i] function_void RolLeftIcon bitmap bitmap;
	public void RolLeftIcon( struct icon SourceIcon, struct icon TargetIcon )
	{
		uint16 XBlockNumber = SourceIcon.ColumnL / 8;
		uint16 YBlockNumber = SourceIcon.area / 8;
		
		//行列遍历
		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
			for( uint16 XN = 0; XN < XBlockNumber; XN + 1 ) {
				uint16 newXN = YN;
				uint16 newYN = XBlockNumber - XN - 1;
				->[uint8*?] SourcePoint -> SourceIcon.buffer[YN * SourceIcon.ColumnL + XN * 8];
				->[uint8*?] TargetPoint -> TargetIcon.buffer[newYN * TargetIcon.ColumnL + newXN * 8];
				uint8 D0 = SourcePoint[0];
				uint8 D1 = SourcePoint[1];
				uint8 D2 = SourcePoint[2];
				uint8 D3 = SourcePoint[3];
				uint8 D4 = SourcePoint[4];
				uint8 D5 = SourcePoint[5];
				uint8 D6 = SourcePoint[6];
				uint8 D7 = SourcePoint[7];
				for( int8 i = 7; i >= 0; i - 1 ) {
					uint8 TD;
					TD.7(bit) = D0.7(bit); D0 << 1;
					TD.6(bit) = D1.7(bit); D1 << 1;
					TD.5(bit) = D2.7(bit); D2 << 1;
					TD.4(bit) = D3.7(bit); D3 << 1;
					TD.3(bit) = D4.7(bit); D4 << 1;
					TD.2(bit) = D5.7(bit); D5 << 1;
					TD.1(bit) = D6.7(bit); D6 << 1;
					TD.0(bit) = D7.7(bit); D7 << 1;
					TargetPoint[i] = TD;
				}
			}
		}
	}
	//---------------------------------------------------
	//[i] function_void SwapLineIcon bitmap bitmap;
	public void SwapLineIcon( struct icon SourceIcon, struct icon TargetIcon )
	{
		uint16 YBlockNumber = SourceIcon.area / 8;
		
		//行列遍历
		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
			for( int8 i = 0; (uint)i < SourceIcon.ColumnL; i + 1 ) {
				uint8 d = SourceIcon.buffer[YN * SourceIcon.ColumnL + (uint)i];
				uint8 swapData;
				swapData.0(bit) = d.7(bit);
				swapData.1(bit) = d.6(bit);
				swapData.2(bit) = d.5(bit);
				swapData.3(bit) = d.4(bit);
				swapData.4(bit) = d.3(bit);
				swapData.5(bit) = d.2(bit);
				swapData.6(bit) = d.1(bit);
				swapData.7(bit) = d.0(bit);
				TargetIcon.buffer[(YBlockNumber - YN - 1) * SourceIcon.ColumnL + (uint)i] = swapData;
			}
		}
	}
	//---------------------------------------------------
	//[i] function_void SwapColumnIcon bitmap bitmap;
	public void SwapColumnIcon( struct icon SourceIcon, struct icon TargetIcon )
	{
		uint16 YBlockNumber = SourceIcon.area / 8;
		
		//行列遍历
		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
			for( int8 i = 0; (uint)i < SourceIcon.ColumnL; i + 1 ) {
				uint8 d = SourceIcon.buffer[YN * SourceIcon.ColumnL + (uint)i];
				TargetIcon.buffer[YN * SourceIcon.ColumnL + (SourceIcon.ColumnL - (uint)i - 1)] = d;
			}
		}
	}
	//---------------------------------------------------
	///[i] function_void DrawIcon bitmap int32 int32;
//	public void DrawIcon000( struct icon icon, int32 XX, int32 YY )
//	{
//		int16 X = (int16)XX;
//		int16 Y = (int16)YY;
//		int16 AreaY;
//		uint8 OffsetY;
//		SawToothMod( Y, AreaY, OffsetY );
		
//		uint16 YBlockNumber = icon.Column / 8;
		
//		//行列遍历输出图标
//		int16 BufferIndex = 0;
//		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
//			for( int8 i = 0; (uint)i < icon.Line; i + 1 ) {
//				uint16 data = icon.buffer[BufferIndex];
//				data << OffsetY;
//				uint16 BackData;
//				BackData.0(uint8) = map.get_uint8( X + i, AreaY + (int)YN );
//				BackData.8(uint8) = map.get_uint8( X + i, AreaY + (int)YN + 1 );
//				data ^ BackData;
//				map.set_uint8( X + i, AreaY + (int)YN, data.0(uint8) );
//				map.set_uint8( X + i, AreaY + (int)YN + 1, data.8(uint8) );
//				BufferIndex + 1;
//			}
//		}
//	}
	//---------------------------------------------------
	//[i] function_void HitIcon bitmap int32 int32;
	public bool HitIcon( struct icon icon, int32 XX, int32 YY )
	{
//		int16 X = (int16)XX;
//		int16 Y = (int16)YY;
//		int16 AreaY;
//		uint8 OffsetY;
//		SawToothMod( Y, AreaY, OffsetY );
		
//		uint16 YBlockNumber = icon.Column / 8;
		
//		//行列遍历检查图标是否和背景碰撞
//		int16 BufferIndex = 0;
//		for( uint16 YN = 0; YN < YBlockNumber; YN + 1 ) {
//			for( int8 i = 0; (uint)i < icon.Line; i + 1 ) {
//				uint16 data = icon.buffer[BufferIndex];
//				data << OffsetY;
//				uint16 BackData;
//				BackData.0(uint8) = map.get_uint8( X + i, AreaY + (int)YN );
//				BackData.8(uint8) = map.get_uint8( X + i, AreaY + (int)YN + 1 );
//				if( data & BackData != 0 ) return true;
//				BufferIndex + 1;
//			}
//		}
//		return false;
	}
	//---------------------------------------------------
	//锯齿取模函数, 计算一个数除以8的锯齿除法和锯齿余数(不是内置除法和取余)
	void SawToothMod( int16 n, #.base int16 Area, #.base uint8 Offset )
	{
		if( n > 0 ) {
			Area = n / 8;
			Offset = (uint)(int8)(n % 8);
		}
		else {
			Area = n / 8 - 1;
			Offset = 8 - (uint)(int8)(-n % 8);
		}
	}
	//---------------------------------------------------
	//锯齿取模函数, 计算一个数除以8的锯齿除法和锯齿余数(不是内置除法和取余)
	void SawToothMod16( int16 n, #.base int16 Area, #.base uint8 Offset )
	{
		if( n > 0 ) {
			Area = n / 16;
			Offset = (uint)(int8)(n % 16);
		}
		else {
			Area = n / 16 - 1;
			Offset = 16 - (uint)(int8)(-n % 16);
		}
	}
}

#.GUI = driver;







