/****************************************************************************/
/*																			*/
/*		｢乙女座｣用プラグインツールサンプル									*/
/*																			*/
/*		未使用パレットを前詰めにするプラグインツール(16色と256色専用)		*/
/*		16色の場合、0番〜15番までの未使用ﾊﾟﾚｯﾄを前詰めにします。			*/
/*		256色の場合、1番〜254番までの未使用ﾊﾟﾚｯﾄを前詰めにします。			*/
/*																			*/
/*		※これは、エフェクト系ツールでイメージをダイレクトに操作する例		*/
/*		　です。															*/
/*		※まぁ、大したソースではないので、流用したければ御事由にお使い		*/
/*		  下さい｡															*/
/****************************************************************************/

/*--------------------------------------------------------------------------*/
/*		乙女座用画像エフェクターの作成方法									*/
/*																			*/
/*	○大まかな流れ															*/
/*	  乙女座本体からイメージのアドレスを貰い、指定した範囲にエフェクトを	*/
/*	  行います。イメージを直接操作していますので、アドレスを破壊したら、	*/
/*	  乙女座も暴走します。													*/
/*																			*/
/*	○注意事項																*/
/*	  tpspin.hをincludeして下さい｡											*/
/*	  マロックは(char *)pi_data->func1を使用して下さい｡						*/
/*	  フリーは(void *)pi_data->func2を使用して下さい｡						*/
/*	  エラーはヘッダーにあるPI_ERROR_XXXXXをセットして返して下さい｡			*/
/*	  ワーク等に使うローカルﾊﾞｯﾌｧのﾎﾟｲﾝﾀｰはﾌﾟﾗｸﾞｲﾝﾂｰﾙ内で宣言して下さい｡	*/
/*	  また、使い終わったら必ず開放して下さい｡								*/
/*																			*/
/*	○本体に返すパラメーター												*/
/*	　特になし																*/
/*																			*/
/*--------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <wgb.h>
#include <egb.h>
#include <mos.h>
#include "tpspin.h"


#define PI_MALLOC( size )	((char*)pi_data->func1(size))
#define PI_FREE( buf )		(pi_data->func2(buf))
#define FNAME				(pi_data->fname)

/****************************************************************************/
int		pinHead(int, void *, void *, void *, void *);
int		APL_exec();
void	main();
/****************************************************************************/

const char longname[] = "パレット圧縮 for OTOMEZA";
const char shortname[] = "OT";
PI_TYPE		*pi_type;
PI_DATA		*pi_data;
PI_IMAGE	*pi_imge;
PI_PARA		*pi_para;
FRAME		*ret_fr;						/* 画像転送範囲			*/
char		*guiEgbPtr;
char		*g_para;

int pinHead(int service, void *arg1, void *arg2, void *arg3, void *arg4)
{
	FRAME	fr;
	int		ret;
	
	ret = 0;
	switch (service) {
	case 0:											/* 正式名称			*/
		strcpy((char *)arg1, longname);
		break;
	case 1:											/* 省略名称			*/
		strcpy((char *)arg1, shortname);
		break;
	case 2:											/* 初期化			*/
		pi_type = (PI_TYPE *)arg1;
		strcpy((* pi_type).name, longname);			/* モジュール名		*/
		(* pi_type).type = PI_EFFC_ALL;				/* Type				*/
		(* pi_type).env1 = 0;						/* 環境設定フラグ	*/
		(* pi_type).env2 = 0;						/* リザーブフラグ	*/
		break;
	case 3:											/* 実行				*/
		/*--------------------------------------------------------------*/
		/* 必要なパラメータをコピーしておく								*/
		/*--------------------------------------------------------------*/
		pi_data = (PI_DATA *)arg1;
		pi_imge = (PI_IMAGE *)arg2;
		pi_para = (PI_PARA *)arg3;
		ret_fr  = (FRAME *)arg4;
		if( (* pi_para).type != PI_EFFC_ALL )	//  形式の確認
			break;
		g_para  = (* pi_para).gpara;
		fr.lupx = WORD(g_para + 0);				// 描画座標の退避
		fr.lupy = WORD(g_para + 2);
		fr.rdwx = WORD(g_para + 4);
		fr.rdwy = WORD(g_para + 6);
		guiEgbPtr = pi_imge->egbWork;			//	EGBワーク
		/*--------------------------------------------------------------*/
		/* 実行部の呼び出し(パラメータ形式は自由)						*/
		/*--------------------------------------------------------------*/
		ret = APL_exec();
		if( ret < 0 ){
			return( -1 );
		}
		break;
	case 4:											/* 終了				*/
		break ;
	case 5:											/* データ			*/
		break;
	}
	return ret;
}

/****************************************************************************/
/*	パレットをソートする。													*/
/****************************************************************************/

int APL_exec()
{
	int i,j,k;
	int bpp;
	int col,col_max;
	int x,y;
	int w,h;
	int	p;
	unsigned char flg[256],ary[256];
	char *palt,*newpalt;
	char *vram;
	
	bpp = pi_imge->pix;
	if( bpp != 4 &&
		bpp != 8 ) return -1;
	palt = pi_imge->clut;
	vram = pi_imge->image;
	if( vram == NULL ) return -1;
	
	col_max = ( bpp == 4 ? 16 : 256 );
	memset(flg,0x00,col_max);
	
	x = pi_imge->size.x;
	y = pi_imge->size.y;
	w = (x+31)/32*32;
	h = y;
	k = ( bpp == 4 ? w/2 : w );
	if( bpp == 4 ) {
		for(j=0;j<y;j++) {
			for(i=0;i<x/2;i++) {
				p = BYTE( vram + j*k+i );
				col = p&0x0f;
				flg[col] = 1;
				col = (p&0xf0)>>4;
				flg[col] = 1;
			}
		}
		j = 0;
		for(i=0;i<col_max;i++) {
			if( flg[i] == 1 ) {
				ary[i] = j;
				j++;
			}
		}
		for(i=0;i<col_max;i++) {
			if( flg[i] == 0 ) {
				ary[i] = j;
				j++;
			}
		}
	} else {
		for(j=0;j<y;j++) {
			for(i=0;i<x;i++) {
				col = BYTE( vram + j*k+i );
				flg[col] = 1;
			}
		}
		ary[0] = 0;
		ary[255] = 255;
		j = 1;
		for(i=1;i<col_max-1;i++) {
			if( flg[i] == 1 ) {
				ary[i] = j;
				j++;
			}
		}
		for(i=1;i<col_max-1;i++) {
			if( flg[i] == 0 ) {
				ary[i] = j;
				j++;
			}
		}
	}
	newpalt = PI_MALLOC( col_max*8+4 );
	memcpy(newpalt,palt,col_max*8+4);
	for(i=0;i<col_max;i++) {
		j = ary[i];
		newpalt[j*8  +4+4] = palt[i*8  +4+4];
		newpalt[j*8+1+4+4] = palt[i*8+1+4+4];
		newpalt[j*8+2+4+4] = palt[i*8+2+4+4];
	}
	memcpy(palt,newpalt,col_max*8+4);
	if( bpp == 4 ) {
		for(j=0;j<y;j++) {
			for(i=0;i<(x+1)/2;i++) {
				col = BYTE( vram + j*k+i );
				BYTE( vram + i+j*k ) = (ary[(col&0xf0)>>4]<<4) + ary[col&0x0f];
			}
		}
	} else {
		for(j=0;j<y;j++) {
			for(i=0;i<x;i++) {
				col = BYTE( vram + j*k+i );
				BYTE( vram + i+j*k ) = ary[col];
			}
		}
	}
	PI_FREE( newpalt );
	
	return 0;
}

void main(){}
