//----------------------------------------------------------------------------------------------
//
//  sConsole.h : スプライト描画用コンソール
//  X-BASIC' v2.0
//
//  Created by AIG-Soft(iMac) on 2013/04/29.
//  Copyright (c) 2013年 AIG-Soft. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "libs.h"
#import "Console.h"
#import <CoreGraphics/CoreGraphics.h>
#import "main.h"
#include <stdlib.h> // malloc/free
#import "rgbhsv.h"

//----------------------------------------------------------------------------------------------
// スプライト＆ＢＧ共通
//----------------------------------------------------------------------------------------------

// パターン定義数；これはワークエリアのサイズだけなので比較的自由に変更できる
#define	MAX_SPRITE_PATTERNS	512

// 1パターンサイズ : スプライト&BG共通
#define	SPRITE_WIDTH	16
#define	SPRITE_HEIGHT	16
#define SPRITE_ELEMENTS	(SPRITE_WIDTH*SPRITE_HEIGHT)	// 必要要素数

//----------------------------------------------------------------------------------------------
// スプライト
//----------------------------------------------------------------------------------------------

enum {	// スプライトパターン定義形式
	SPRITE_IOS=0,	// 要素は実色
	SPRITE_X68		// 要素はパレットコード
};

// パレットブロック
#define	MAX_SPRITE_PALET_BLOCKS		32	// パレットブロックの数;[1～]を使う。[0]はX68ではテキストパレットで予約されているので利用禁止
#define	MAX_SPRITE_PALET_1BLOCK		16	// 1パレットブロック内に定義できる色の数(4bit)
#define DEFAULT_SPRITE_PALET_BLOCK	1	// デフォルト スプライト パレットブロック
#define DEFAULT_SPRITE_PATTERN		0	// 初期化時のデフォルト スプライト パターン

enum { // 優先順位
	SPRITE_PRW_HIDE		=0,	// 非表示
	SPRITE_PRW_BG0BG1SP	,	// BG0>BG1>SP
	SPRITE_PRW_BG0SPBG1	,	// BG0>SP>BG1
	SPRITE_PRW_SPBG0BG1	,	// SP>BG0>BG1
	// 	BG0>BG1は変更できない
};

// 反転状態
#define SPRITE_FLIP_NONE				0
#define SPRITE_FLIP_HORIZONTAL			BIT0
#define SPRITE_FLIP_VERTICAL			BIT1
#define SPRITE_FLIP_HORIZONTAL_VERTICAL	(SPRITE_FLIP_HORIZONTAL|SPRITE_FLIP_VERTICAL)

typedef struct { // パターンジスタ
	// サイズを減らすため、できるだけshortを使う
	SWord	fflip;			// 反転;SPRITE_FLIP_*
	SWord	paletBlock;		// パレットブロック;iOS型の時は無視される
	SWord	ptrn;			// パターン番号;0～MAX_SPRITE_PATTERNS-1
} PatternRegs;

typedef struct { // スプライトスクロールレジスタ(プレーン別)
	// サイズを減らすため、できるだけshortを使う
	int			xpos;		// 表示座標x
	int			ypos;		// 表示座標y
	// 座標は<0～>=画面幅まで自由。ただし、<0や>=画面幅の部分は表示されない
	SWord		prw;		// 優先順位;SPRITE_PRW_*
	PatternRegs	ptnRegs;	// １パターンの属性
} SpriteRegs;

// 同時表示枚数；表示速度に直結する
#define	MAX_SPRITE_PLANE	256

//----------------------------------------------------------------------------------------------
// BG
//----------------------------------------------------------------------------------------------

#define	MAX_BG_SCREEN			2	// BG画面数；プログラム内にやむを得ず即値記述部分があるので変更できない
#define	MAX_BG_TEXTPAGE			2	// BGテキストページ数
#define DEFAULT_BG_PALET_BLOCK	1	// デフォルト BGパレットブロック
#define DEFAULT_BG_PATTERN		1	// 初期化時のデフォルト BGパターン

// BG画面サイズ
#define	BG_WIDTH		2048
#define	BG_HEIGHT		2048
#define BG_BYTE1LINE	(BG_WIDTH*PIXELBYTE)

// テキストページサイズ
#define	BG_TEXT_PAGE_WIDTH	(BG_WIDTH/SPRITE_WIDTH)		// 128
#define	BG_TEXT_PAGE_HEIGHT	(BG_HEIGHT/SPRITE_HEIGHT)	// 128
// 128*128=16384マスあるが、スプライトパターンは512個しかない

// BGスクロールレジスタ(BG画面別)
typedef struct {
	// サイズを減らすため、できるだけshortを使う
	int		xpos;			// 表示座標x
	int		ypos;			// 表示座標y
	// 座標は<0～>=画面幅まで自由。ただし、<0や>=画面幅の部分は表示されない
	SWord	textPage;		// テキストページの割り付け
	BOOL	fdisp;			// 各BGの表示設定 ; YES=表示 , NO=非表示
	ULong	*lpixel;		// ピクセルワーク
} BGRegs;

//----------------------------------------------------------------------------------------------
// クラス定義
//----------------------------------------------------------------------------------------------

@interface sConsole : Console
{
	// 表示属性
	BOOL	fDisableBG0SPBG1;	// YES=スプライトの表示優先順位でBG0>SP>BG1を無効にする(BG0>BG1>SPとみなす)
								// BG用ワークの量が1/3で済む
	BOOL	fBGupdate1st;		// BG初回絶対更新の印

	// スプライトパターン定義形式
	char	spriteType[MAX_SPRITE_PATTERNS];	// iOS型/X68型

	// パターンデータ
	// 1要素はr/g/b/alphaの実色またはパレットコード
	// パレットコードの時はr=palet code,g/b/alpha=0
	// 4*512*16*16=512KB
	ULong	sprite_pattern[MAX_SPRITE_PATTERNS][SPRITE_HEIGHT][SPRITE_WIDTH];
	// そのスプライトパターンがBG内で使われている回数(SPv1.7)
	int		cntPatternInBG[MAX_SPRITE_PATTERNS];	// BGtext0/1総合
	
	// パレットブロック
	ULong	x68_sprite_palet[MAX_SPRITE_PALET_BLOCKS][MAX_SPRITE_PALET_1BLOCK];
	// そのパレットブロックがBG内で使われている回数(SPv1.7)
	int		cntPaletInBG[MAX_SPRITE_PALET_BLOCKS];	// BGtext0/1総合

	// スプライトスクロールレジスタ(プレーンごと)
	// 512*16=8KB
	SpriteRegs		spriteRegs[MAX_SPRITE_PLANE];

	// BGテキストページ
	// 2*128*128*sizeof(PatternRegs)=192KB
	PatternRegs 	BGtextPage[MAX_BG_TEXTPAGE][BG_TEXT_PAGE_HEIGHT][BG_TEXT_PAGE_WIDTH];
	
	// BGスクロールレジスタ(画面別)
	SWord	BGpages;					// 有効な全BGページ数
	BGRegs	BGscreen[MAX_BG_SCREEN];	// BGページ情報

	// ビットマップワーク用
	ULong 	*lpixel;		// 全合成画面 : Context内ビットマップを使うため常に有効
	ULong	*BG01lpixel;	// NULLの時はワーク未確保
}
@property (nonatomic) BOOL fhalt;			// YES=表示処理を停止 , NO=即時表示する
@property (nonatomic) BOOL fspriteBGDisp;	// NO=スプライト/BG画面を表示しない , YES=表示する

//----------------------------------------------------------------------------------------------
// X-BASIC'の同名関数と引数や動作が一致するわけではない

// 初期化関数
-(BOOL)initSprite;
-(BOOL)allocBG;
-(void)freeSprite;
-(void)freeBG;

// スプライト
-(void)sp_init;
-(void)sp_priority:(SWord)prw pl1:(SWord)pl1 pl2:(SWord)pl2;
-(void)sp_clr:(SWord)sp1 sp2:(SWord)sp2;
-(void)sp_def:(SWord)sp ptn:(ULong *)ptn type:(char)type;
-(int )sp_pat:(SWord)sp ptn:(ULong *)ptn size1:(int)size1;
-(ULong)sp_color:(SWord)p col:(ULong)col paletBlock:(SWord)pb;
-(int )sp_stat:(SWord)pl dataType:(int)dataType;
-(void)sp_setting:(SWord)pl x:(int)x y:(int)y sp:(SWord)sp paletBlock:(SWord)pb flip:(SWord)flip prw:(SWord)prw fomitX:(BOOL)fomitX fomitY:(BOOL)fomitY;
-(int)sp_image:(NSString *)fname ofstx:(SWord)ofstx ofsty:(SWord)ofsty pwx:(int *)pwx pwy:(int *)pwy tsp:(SWord)tsp tpl:(SWord)tpl
				 sx:(int)sx sy:(int)sy fomitSX:(BOOL)fomitSX fomitSY:(BOOL)fomitSY prw:(SWord)prw fblack:(BOOL)fblack;
-(BOOL)setFDisableBG0SPBG1:(BOOL)fDisableBG0SPBG1_;

// バックグラウンド
-(void)bg_fill:(SWord)pg sp:(SWord)sp paletBlock:(SWord)pb flip:(SWord)flip;
-(void)bg_put:(SWord)pg x:(int)x y:(int)y sp:(SWord)sp paletBlock:(SWord)pb flip:(SWord)flip;
-(BOOL)bg_set:(SWord)scrnNo page:(SWord)pg fdisp:(BOOL)fdisp;
-(void)bg_scroll:(SWord)scrnNo x:(int)x y:(int)y fomitX:(BOOL)fomitX fomitY:(BOOL)fomitY;
-(PatternRegs *)bg_get:(SWord)pg x:(int)x y:(int)y;
-(int )bg_stat:(SWord)scrnNo dataType:(int)dataType;

@end

//----------------------------------------------------------------------------------------------

