//**************************************************************
//
//						warai.c
//
//**************************************************************
#include	<Agb.h>
#include	"../../define.h"
#include	"../../m4aLib.h"

#include	"../mini.h"

#include	"include_datafiles.h"
#include	"../../global.h"
#include	"../../sub.h"
#include	"../../data.h"
#include "./Owario_face.h"

//--------------------------------------------------------------
//		定義
//--------------------------------------------------------------


// パーツのループまでの数
#define		PARTS_MAX	15


// パーツのスタート位置
#define		PARTS_X_START	36+24-8
#define		EYES_Y_START	16+40+32
#define		NOSE_Y_START	34+40+32
#define		MOUTH_Y_START	44+40+32

#define		PARTS_X_STATIC	122

// パーツの移動距離／２
#define		IDO_R			72

// パーツの最小値
#define		PARTS_SCALE_MIN	0x10

// パーツの大きさの最大値
#define		PARTS_SCALE_MAX		0x200


// まわすオブジェクトの数
#define		OBJECT_MAX		3


// 初期角速度
const int ROTATE_SPEED_START[3] = {150, 200, 250};

#define		PARTS_ZOOM_STAGE		30

// 回転させるオブジェクトの移動角度
#define		PARTS_ROTATE_MAX		0xC0	//0x80で180度 0xA0で225度
// 回転させるオブジェクトの最初の角度
#define		PARTS_ROTATE_START		0xE0	//



// 失敗時の固定パーツの振れ幅
#define		WARAI_KOTEI_IDO			1


//--------------------------------------------------------------
//		難易度などの設定
//--------------------------------------------------------------

#define		WARAI_SPEED_UP				0		// 1回成功で上がるスピード
#define		WARAI_MEDAL_COUNT			3		// 何点ごとにメダルがもらえるか
#define		WARAI_PARTS_UP_COUNT		10		// 何点ごとにパーツが増えるか
#define		WARAI_PARTS_MIN				3		// パーツの最低数（初期数）
#define		WARAI_SPEED_MAX				100		// シングル時の最高速度
#define		WARAI_SPEED_MIN				70		// 最低速度
#define		WARAI_WAIT_INTERVAL_MAX		48		// 最大表示時間（1/4にあたる）
#define		WARAI_WAIT_INTERVAL_MIN		3		// 最小表示時間
#define		WARAI_WAIT_INTERVAL_PACE	1		// このペースでINTERVALが減る
#define		WARAI_WAIT_INTERVAL_DOWN	5		// ペース毎にどれだけ減るか


//--------------------------------------------------------------
//		変数
//--------------------------------------------------------------

// パーツ関係
typedef struct
{
	s16	sX;
	s16	sY;
	s16	sScale;
	u8	ucChara;		// どの画像か
	u8	ucStatus;
	s16	sRotate32;		// <<5の角度
}WaraiPartsDef;

static WaraiPartsDef	WaraiParts[OBJECT_MAX];
static WaraiPartsDef	*WaraiPartsPtr[OBJECT_MAX];

static u8		ucWaraiPartsNo;		// 現在のパーツが何番目か
static u8		ucWaraiObjectNo;	// 出発したオブジェクトが何番目か
static u8		ucWaraiGameStatus;	// どのパーツが回っているか

static s16		sWaraiRotateSpeed;		// 回転速度
static s16		sWaraiRotateCounter32;
static u8		ucWaraiTimeCounter;

static u8		ucWaraiObjRndNum[PARTS_MAX];			// 各パーツをランダムに並べるための変数



// 移動用バックアップ
static s16		sWaraiPartsXBak, sWaraiPartsYBak;
static s16		sWaraiPartsScaleBak;

// 移動用変化定数
static s16		sWaraiHenkaX32;
static s16		sWaraiHenkaY32;
static s16		sWaraiHenkaScale32;

// 固定キャラクタ用データ
typedef struct
{
	s16	sX;
	s16	sY;
	u8	ucChara;
}WaraiKoteiDef;

static WaraiKoteiDef	KoteiEyes, KoteiNose, KoteiMouth;

static u16	usKoteiAnimTimer;		// 失敗時のアニメーション用

// パーツの種類
static u16		ucWaraiPartsNum;

// ランダム後のパーツのデータ格納場所
static int	iParts_Obj[PARTS_MAX];
static u8	ucWaraiPartsRndNum[PARTS_MAX];


// オブジェクト用
static MiniObj2Def	WaraiBar;		//　回るバー
static MiniObj2Def	WaraiLook;		//　ＬＯＯＫ！

// カウントダウン時のタイム
static s16	sWaraiWaitInterval;

// アタリのキャラが何番目か
static u8	ucWaraiAtariChara[3];


//--------------------------------------------------------------
//		データ
//--------------------------------------------------------------
enum
{
	WARAI_GAMESTART, WARAI_LOGO_SCALE_DOWN, WARAI_START_WAIT, WARAI_BLEND_DOWN, WARAI_BLEND_UP,
	WARAI_KEY_WAIT, WARAI_BLEND1, WARAI_EYE_ROLL, WARAI_EYE_SET, WARAI_NOSE_ROLL, WARAI_NOSE_SET,
	WARAI_MOUTH_ROLL, WARAI_MOUTH_SET, WARAI_SEISAN, WARAI_GAMEOVER
};

enum
{
	EYES, NOSE, MOUTH, NOPARTS
};

enum
{
	EASY, NORMAL, HARD
};

// ゲームオーバーシーケンス
enum
{
	WARAI_GO_KAO_YURE, WARAI_GO_LOGO, WARAI_GO_WAIT
};

// 精算シーケンス
enum
{
	WARAI_SEISAN_KAO_CHANGE, WARAI_SEISAN_SCORE_UP,  WARAI_SEISAN_WAIT_1 , WARAI_SEISAN_MEDAL_UP, 
	WARAI_SEISAN_WAIT_2, WARAI_SEISAN_BLEND_DOWN, WARAI_SEISAN_BLEND_UP
};


const int Parts_Obj[PARTS_MAX] = {
	(int)wario_face_Obj_09, (int)wario_face_Obj_0a, (int)wario_face_Obj_0b,
	(int)wario_face_Obj_0c, (int)wario_face_Obj_0d, (int)wario_face_Obj_0e,
	(int)wario_face_Obj_0f, (int)wario_face_Obj_10, (int)wario_face_Obj_11,
	(int)wario_face_Obj_12, (int)wario_face_Obj_13, (int)wario_face_Obj_14,
	(int)wario_face_Obj_15, (int)wario_face_Obj_16, (int)wario_face_Obj_17,
};


//--------------------------------------------------------------
//		外部関数
//--------------------------------------------------------------

extern int MiniRandomCreate(void);

//--------------------------------------------------------------
//		Local関数
//--------------------------------------------------------------
void	MiniWaraiInit01(void);
void	MiniWaraiOamCreate(void);
void	MiniWaraiVblk(void);


static void	WaraiLoopInit(void);
static int	WaraiKey(void);
static void	WaraiObjRoll(void);
static int	WaraiObjSet(void);
static void	WaraiSort(void);
static void	WaraiCharaSet(void);
static void WaraiRandomNoSet(void);
static void	WaraiKoteiCharaSet(void);
static void	WaraiKoteiCharaSet2(void);
static int	WaraiKoteiCharaOrder(u8	charatemp);
static void WaraiPartsRandomSet(void);
static void	WaraiScoreSet(void);

static int WaraiSeisan();
static int WaraiGameover();
static void WaraiKaoYure(void);
static void WaraiKaoChange(void);

//==============================================================
//		メインルーチン
//==============================================================
int WaraiMain()
{
	int i;

	switch(ucMiniSeq)
	{
		case WARAI_GAMESTART:
			if(MiniWait(40))
			{
				ucMiniSeq++;
			}
			break;
		
		case WARAI_LOGO_SCALE_DOWN:
			MiniLogo.usScale -= MINI_LOGO_SCALE_SPEED;
			if(MiniLogo.usScale < 0x20)
			{
				MiniLogo.usScale = 0x20;
				MiniLogo.ucStatus = 0;
				ucMiniSeq++;
			}
			break;
		
		case WARAI_START_WAIT:
			if(MiniWait(60))	ucMiniSeq++;
			break;

		case WARAI_BLEND_DOWN:		// ワリオの顔が消える
			usFadeTimer++;
			if(usFadeTimer&0x01)	break;
			//2フレームごとに↓を実行
			if(cMiniEva > 0)
			{
				cMiniEvb++;
				cMiniEva--;
			}
			else
			{
				// 固定キャラのセット
				KoteiEyes.ucChara = ucWaraiAtariChara[0];		// 目は０がアタリ
				KoteiNose.ucChara = ucWaraiAtariChara[1];		// 鼻は１がアタリ
				KoteiMouth.ucChara = ucWaraiAtariChara[2];		// 口は２がアタリ

				WaraiKoteiCharaSet2();
				ucMiniSeq++;
			}
			break;

		case WARAI_BLEND_UP:	// あわせる顔が現れる
			usFadeTimer++;
			if(usFadeTimer&0x01)	break;
			if(cMiniEva < 16)
			{
				cMiniEvb--;
				cMiniEva++;
			}
			else
			{
				ucMiniSeq++;
			}
			break;
		
		case WARAI_KEY_WAIT:
			usMiniDemoCount++;
			if(usMiniDemoCount == sWaraiWaitInterval * 4)	// ゲームスタート
			{
				usMiniDemoCount = 0;
				m4aSongNumStart(S_GAME_BARBER_COUNT_0);
				m4aSongNumStart(S_GAME_BARBER_FACE_OUT);
				ucMiniSeq++;
			}
			else if(usMiniDemoCount % sWaraiWaitInterval == 0)
			{
				m4aSongNumStart(S_GAME_BARBER_COUNT_1);
			}
			break;

		case WARAI_BLEND1:
			usFadeTimer++;
			if(usFadeTimer&0x01)	break;
			//2フレームごとに↓を実行
			if(cMiniEva > 0)
			{
				cMiniEvb++;
				cMiniEva--;
			}
			else
			{
				cMiniEvb = 0;
				cMiniEva = 16;
				ucWaraiGameStatus = EYES;
				ucMiniSeq++;
			}
			break;

		case WARAI_EYE_ROLL:
			WaraiObjRoll();
			if(WaraiKey())
			{
				WaraiSort();
				for(i=1; i<OBJECT_MAX; i++)
				{
					WaraiPartsPtr[i]->sX = 1000;		// 飛ばす
				}
				m4aSongNumStart(S_GAME_BARBER_PUSH_1);
				KoteiEyes.ucChara = WaraiPartsPtr[0]->ucChara;
				sWaraiPartsXBak = WaraiPartsPtr[0]->sX;
				sWaraiPartsYBak = WaraiPartsPtr[0]->sY;
				sWaraiPartsScaleBak = WaraiPartsPtr[0]->sScale;
				sWaraiRotateCounter32 = 0;

				WaraiKoteiCharaSet();

				ucMiniSeq++;
			}
			break;
			
		case WARAI_EYE_SET:
			if(WaraiObjSet()==1)
			{
				ucMiniSeq++;
				WaraiRandomNoSet();
				ucWaraiGameStatus = NOSE;
				for(i=0; i<OBJECT_MAX; i++)		// 大きさ初期化
				{
					WaraiParts[i].sRotate32 = PARTS_ROTATE_START<<5;
					WaraiParts[i].sScale = 0;
				}
			}
			break;
			
		case WARAI_NOSE_ROLL:
			WaraiObjRoll();
			if(WaraiKey())
			{
				WaraiSort();
				for(i=1; i<OBJECT_MAX; i++)
				{
					WaraiPartsPtr[i]->sX = 1000;		// 飛ばす
				}
				m4aSongNumStart(S_GAME_BARBER_PUSH_2);
				KoteiNose.ucChara = WaraiPartsPtr[0]->ucChara;
				sWaraiPartsXBak = WaraiPartsPtr[0]->sX;
				sWaraiPartsYBak = WaraiPartsPtr[0]->sY;
				sWaraiPartsScaleBak = WaraiPartsPtr[0]->sScale;
				sWaraiRotateCounter32 = 0;
				WaraiKoteiCharaSet();
				ucMiniSeq++;
			}
			break;
			
		case WARAI_NOSE_SET:
			if(WaraiObjSet())
			{
				ucMiniSeq++;
				WaraiRandomNoSet();
				ucWaraiGameStatus = MOUTH;
				for(i=0; i<OBJECT_MAX; i++)		// 大きさ初期化
				{
					WaraiParts[i].sRotate32 = PARTS_ROTATE_START<<5;
					WaraiParts[i].sScale = 0;
				}
			}
			break;

		case WARAI_MOUTH_ROLL:
			WaraiObjRoll();
			if(WaraiKey())
			{
				WaraiSort();
				for(i=1; i<OBJECT_MAX; i++)
				{
					WaraiPartsPtr[i]->sX = 1000;		// 飛ばす
				}
				m4aSongNumStart(S_GAME_BARBER_PUSH_3);
				KoteiMouth.ucChara = WaraiPartsPtr[0]->ucChara;
				sWaraiPartsXBak = WaraiPartsPtr[0]->sX;
				sWaraiPartsYBak = WaraiPartsPtr[0]->sY;
				sWaraiPartsScaleBak = WaraiPartsPtr[0]->sScale;
				sWaraiRotateCounter32 = 0;
				WaraiKoteiCharaSet();
				ucMiniSeq++;
			}
			break;
			
		case WARAI_MOUTH_SET:
			if(WaraiObjSet())
			{
				if(KoteiEyes.ucChara == ucWaraiAtariChara[0]
				&& KoteiNose.ucChara == ucWaraiAtariChara[1]
				&& KoteiMouth.ucChara == ucWaraiAtariChara[2])
				// 全部のパーツが正解のとき
				{
					m4aSongNumStart(S_GAME_BARBER_OK1);
					ucMiniSeq++;
				} else {
					m4aSongNumStart(S_GAME_BARBER_OUT1);
					ucMiniSeq = WARAI_GAMEOVER;
					// 音フェイドアウト
					m4aMPlayFadeOut(mplay_table[song_table[M_BGM_MINIGAME_FACEMAKE].ms].ma, M4A_FADEOUT_17);
				}
			}
			break;
		
		case WARAI_SEISAN:			// 得点加算
			if(WaraiSeisan())	ucMiniSeq = WARAI_KEY_WAIT;
			break;

		case WARAI_GAMEOVER:		// スロットがそろわなかったとき
			if(WaraiGameover())		return 1;
			break;
	}

	return 0;
}

//--------------------------------------------------------------
//				追加Ｖブランク
//--------------------------------------------------------------
void MiniWaraiVblk()
{

	*(vu16*)REG_BLDALPHA = (cMiniEvb<<8)|cMiniEva;

}


//==============================================================
//		初期設定
//==============================================================
void MiniWaraiInit01()
{
	int i,j;

//	*(vu16*)REG_IE ^= V_BLANK_INTR_FLAG;		//Vﾌﾞﾗﾝｸ割込不許可
//	*(vu16*)REG_DISPCNT = DISP_LCDC_OFF;		//LCDC OFF

	/*---------------------パレットデータ転送--------------------------*/
	DmaCopy(3, warai_bg_Palette, BG_PLTT, 0x200, 16);
	DmaWait(3);
	DmaCopy(3, warai_obj_Palette, OBJ_PLTT, 0x200, 16);
	DmaWait(3);

	/*---------------------BGデータ転送--------------------------*/
	DmaCopy(3, warai_bg_Char, BG_VRAM, sizeof(warai_bg_Char), 16);
	DmaWait(3);
	
	/*---------------------OBJデータ転送--------------------------*/
	DmaCopy(3, warai_obj_Char, OBJ_MODE0_VRAM, sizeof(warai_obj_Char), 16);
	DmaWait(3);

	DmaCopy(3, warai_eyes_Char, OBJ_MODE0_VRAM+0x3000, 0x4000, 16);		// 最初は目
	DmaWait(3);

	// ワリオの固定顔データを転送
	for(i=0; i<4; i++)
	{
		DmaCopy(3, warai_eyes_Char+i*0x400, OBJ_MODE0_VRAM+0x7000+i*0x400, 0x100, 16);
		DmaWait(3);
		DmaCopy(3, warai_nose_Char+i*0x400, OBJ_MODE0_VRAM+0x7100+i*0x400, 0x100, 16);
		DmaWait(3);
		DmaCopy(3, warai_mouth_Char+i*0x400, OBJ_MODE0_VRAM+0x7200+i*0x400, 0x100, 16);
		DmaWait(3);
	}

	/*---------------------スクリーンデータ転送--------------------------*/
	DmaCopy(3, warai_bg01_Screen, BG_VRAM+0xc000, 0x800, 16);	// ステータス
	DmaWait(3);
	DmaCopy(3, warai_bg02_Screen, BG_VRAM+0xd000, 0x800, 16);	// ワリオの顔
	DmaWait(3);

	/*---------------------各BGをセット--------------------------*/
	*(vu16*)REG_BG0CNT = BG_COLOR_16 | BG_SCREEN_SIZE_0 | BG_PRIORITY_0	// ステータス
		| (24 << BG_SCREEN_BASE_SHIFT) | (0 << BG_CHAR_BASE_SHIFT);

	/*---------------------各BGをセット--------------------------*/
	*(vu16*)REG_BG1CNT = BG_COLOR_16 | BG_SCREEN_SIZE_0 | BG_PRIORITY_1	// ワリオの顔
		| (26 << BG_SCREEN_BASE_SHIFT) | (0 << BG_CHAR_BASE_SHIFT);


// スクリーンの初期位置
	*(vu16*)REG_BG0VOFS = 0;
	*(vu16*)REG_BG0HOFS = 0;
	*(vu16*)REG_BG1VOFS = 0;
	*(vu16*)REG_BG1HOFS = 0;

// スコア表示のセット
	usMiniScore = 0;
	ucMiniHighScoreFlg = OFF;

	WaraiScoreSet();

// スピード
	sWaraiRotateSpeed = WARAI_SPEED_MIN;


//モード1
	*(vu16*)REG_DISPCNT = DISP_OBJ_ON |DISP_MODE_0 
	| DISP_OBJ_CHAR_2D_MAP | DISP_BG0_ON | DISP_BG1_ON;

// フェイド初期化
	Select_Fade_Init();
	*(vu16*)REG_BLDY = 0;

//パーツの変数
	ucWaraiTimeCounter =0;
	sWaraiRotateCounter32 = 0;
	ucWaraiPartsNo = 0;
	ucWaraiObjectNo = 0;
	ucWaraiGameStatus = EYES;

	ucWaraiPartsNum = WARAI_PARTS_MIN;

	for(i=0; i<OBJECT_MAX; i++)
	{
		WaraiParts[i].sRotate32 =  PARTS_ROTATE_START<<5;

		//位置
		WaraiParts[i].sX = 1000;			// 飛ばす
		WaraiParts[i].sY = EYES_Y_START;	// 最初は目から
		WaraiParts[i].sRotate32 = PARTS_ROTATE_START<<5;
		WaraiParts[i].sScale = 0;
		WaraiParts[i].ucStatus = OFF;
	}

	// データをポインタで指し示す
	for(i=0; i<OBJECT_MAX; i++)	WaraiPartsPtr[i]=&WaraiParts[i];


// カウントダウンのWAIT値
	sWaraiWaitInterval = WARAI_WAIT_INTERVAL_MAX;


// 固定パーツ
	KoteiEyes.sX = PARTS_X_STATIC;
	KoteiEyes.sY = EYES_Y_START;
	KoteiEyes.ucChara = 0;
	KoteiNose.sX = PARTS_X_STATIC;
	KoteiNose.sY = NOSE_Y_START;
	KoteiNose.ucChara = 0;
	KoteiMouth.sX = PARTS_X_STATIC;
	KoteiMouth.sY = MOUTH_Y_START;
	KoteiMouth.ucChara = 0;

	usKoteiAnimTimer = 0;

// オブジェクト関係
	//回るバー
	WaraiBar.usAnmTimer = 0;
	WaraiBar.usAnmPat = 0;

	//ＬＯＯＫ
	WaraiLook.usAnmTimer = 0;
	WaraiLook.usAnmPat = 0;
	
	//メダル
	MiniMedal.usAnmTimer = 0;
	MiniMedal.usAnmPat = 0;
	ucMiniMedalFlg = OFF;

	//ロゴ
	MiniLogo.sX = 120;
	MiniLogo.sY = 64;
	MiniLogo.usScale = 0x200;
	MiniLogo.ucStatus = 1;		// ゲームスタート

// シーケンス
	ucMiniSeq = 0;
	ucMiniSeqBak = 0;
	ucMiniDemoSeq = 0;
	usMiniDemoCount = 0;

// ブレンド用変数
	cMiniEvb = 0;
	cMiniEva = 16;

//αブレンディング
	*(vu16*)REG_BLDCNT = BLD_BG1_2ND	//第２対象
					| BLD_A_BLEND_MODE;	//αブレンド
//					| BLD_OBJ_1ST;		//第１対象

	*(vu16*)REG_BLDALPHA = (cMiniEvb<<8)|cMiniEva;


//サウンド
	m4aSongNumStartOrChange(M_BGM_MINIGAME_FACEMAKE);


// パーツをランダムにセット
	WaraiPartsRandomSet();

// ランダム順列作成
	WaraiRandomNoSet();

// アタリのキャラ
	for(i=0; i<3; i++)
	{
		ucWaraiAtariChara[i] = MiniRandomCreate() % ucWaraiPartsNum;
	}


//Ｖブランク割込許可
//	*(vu16*)REG_IE |= V_BLANK_INTR_FLAG;

}

//==============================================================
//		ループ後の初期化
//==============================================================
static void WaraiLoopInit()
{
	int i,j;
	

// オブジェクトデータ転送
	DmaCopy(3, warai_eyes_Char, OBJ_MODE0_VRAM+0x3000, 0x4000, 16);		// 最初は目


/************************ 難易度アップ *******************************/

	// スピードアップ
	sWaraiRotateSpeed += WARAI_SPEED_UP;
	if(sWaraiRotateSpeed > WARAI_SPEED_MAX)		sWaraiRotateSpeed = WARAI_SPEED_MAX;

	// メダルがもらえる回ごとにスピードが2倍
//	if(usMiniScore % WARAI_MEDAL_COUNT == WARAI_MEDAL_COUNT-1)	sWaraiRotateSpeed *= 2;

	// 2倍の次の回は戻る
//	if(usMiniScore % WARAI_MEDAL_COUNT == 0)	sWaraiRotateSpeed /= 2;

	// パーツが増える
	if(usMiniScore % WARAI_PARTS_UP_COUNT == 0)
	{
		ucWaraiPartsNum++;
		if(ucWaraiPartsNum > PARTS_MAX)	ucWaraiPartsNum = PARTS_MAX;
	}

	// カウントダウンのペースが減る
	if(usMiniScore % WARAI_WAIT_INTERVAL_PACE == 0)	sWaraiWaitInterval -= WARAI_WAIT_INTERVAL_DOWN;
	if(sWaraiWaitInterval < WARAI_WAIT_INTERVAL_MIN)	sWaraiWaitInterval = WARAI_WAIT_INTERVAL_MAX;


//ＬＯＯＫ
	WaraiLook.usAnmTimer = 0;
	WaraiLook.usAnmPat = 0;


//パーツの変数
	ucWaraiTimeCounter =0;
	sWaraiRotateCounter32 = 0;
	ucWaraiPartsNo = 0;
	ucWaraiObjectNo = 0;
	ucWaraiGameStatus = EYES;


	usKoteiAnimTimer = 0;

// 固定キャラの座標を戻す
	KoteiEyes.sY = EYES_Y_START;
	KoteiNose.sY = NOSE_Y_START;
	KoteiMouth.sY = MOUTH_Y_START;


// パーツをランダムにセット
	WaraiPartsRandomSet();

// ランダム順列作成
	WaraiRandomNoSet();

	for(i=0; i<OBJECT_MAX; i++)
	{
		WaraiParts[i].sRotate32 = PARTS_ROTATE_START<<5;
		
		//位置
		WaraiParts[i].sX = 1000;			// 飛ばす
		WaraiParts[i].sY = EYES_Y_START;	// 最初は目から
		WaraiParts[i].sRotate32 = PARTS_ROTATE_START<<5;
		WaraiParts[i].sScale = ((((_Sin(WaraiParts[i].sRotate32>>5)+(1<<8))/2)*PARTS_SCALE_MAX)>>8);;
		WaraiParts[i].ucStatus = OFF;
	}

	// データをポインタで指し示す
	for(i=0; i<OBJECT_MAX; i++)	WaraiPartsPtr[i]=&WaraiParts[i];

	// 固定キャラのセット
	// アタリのキャラ
	for(i=0; i<3; i++)
	{
		ucWaraiAtariChara[i] = MiniRandomCreate() % ucWaraiPartsNum;
	}

	KoteiEyes.ucChara = ucWaraiAtariChara[0];
	KoteiNose.ucChara = ucWaraiAtariChara[1];
	KoteiMouth.ucChara = ucWaraiAtariChara[2];

	WaraiKoteiCharaSet2();
}


//==============================================================
//		コントローラ処理
//==============================================================
static int WaraiKey()
{
	int i,j;
	

	#ifdef	SEL_DEBUG
	/*---------------------実験用回転速度変化---------------*/
	if (usCont & R_BUTTON)
	{
		sWaraiRotateSpeed++;
		if(sWaraiRotateSpeed > 500)		sWaraiRotateSpeed = 500;
	}
	if (usCont & L_BUTTON)
	{
		sWaraiRotateSpeed--;
		if(sWaraiRotateSpeed < 0)		sWaraiRotateSpeed = 0;
	}
	#endif

   /*-----------------------回転開始・ストップ---------------------------*/
    if(usTrg & A_BUTTON)
    {
		return 1;
	}

    return 0;
}

//--------------------------------------------------------------
//                 パーツの動きの計算
//--------------------------------------------------------------
static void	WaraiObjRoll()
{
	int i, j;
	
	if(WaraiParts[0].ucStatus == OFF)
	{
		WaraiCharaSet();			// 一番最初にRAM転送
		WaraiParts[0].ucStatus = ON;
	}

	for(i=0; i<OBJECT_MAX; i++)
	{
		if(WaraiParts[i].ucStatus)		// スイッチオンなら
		{
			WaraiParts[i].sRotate32 += sWaraiRotateSpeed;
			if(WaraiParts[i].sRotate32 >(0xFF<<5))	WaraiParts[i].sRotate32-=(0xFF<<5);
			WaraiParts[i].sX = PARTS_X_START + IDO_R -(IDO_R*(_Cos(WaraiParts[i].sRotate32>>5))>>8);
			WaraiParts[i].sScale = ((((_Sin(WaraiParts[i].sRotate32>>5)+(1<<8))/2)*PARTS_SCALE_MAX)>>8);
		}
	}



	if(sWaraiRotateCounter32==0)	// 一定周期で初期化
	{
		WaraiParts[ucWaraiObjectNo].sRotate32 = PARTS_ROTATE_START<<5;
		WaraiParts[ucWaraiObjectNo].sX = PARTS_X_START 
		+ IDO_R -(IDO_R*(_Cos(WaraiParts[ucWaraiObjectNo].sRotate32>>5))>>8); // 位置
		WaraiParts[ucWaraiObjectNo].ucStatus = ON;
		WaraiParts[ucWaraiObjectNo].sScale = ((((_Sin(WaraiParts[ucWaraiObjectNo].sRotate32>>5)
		+(1<<8))/2)*PARTS_SCALE_MAX)>>8);
		WaraiParts[ucWaraiObjectNo].ucChara = ucWaraiObjRndNum[ucWaraiPartsNo];

		// 正解の音
		//if(WaraiParts[ucWaraiObjectNo].ucChara==ucWaraiAtariChara[0]&&
		if(ucMiniSeq==WARAI_EYE_ROLL)	m4aSongNumStart(S_GAME_BARBER_RING_1);
		//if(WaraiParts[ucWaraiObjectNo].ucChara==ucWaraiAtariChara[1]&&
		if(ucMiniSeq==WARAI_NOSE_ROLL)	m4aSongNumStart(S_GAME_BARBER_RING_2);
		//if(WaraiParts[ucWaraiObjectNo].ucChara==ucWaraiAtariChara[2]&&
		if(ucMiniSeq==WARAI_MOUTH_ROLL)	m4aSongNumStart(S_GAME_BARBER_RING_3);
	}



	sWaraiRotateCounter32 += sWaraiRotateSpeed;
	if(sWaraiRotateCounter32 >= ((PARTS_ROTATE_MAX<<5)/OBJECT_MAX))	//半円は0x80
	{
		sWaraiRotateCounter32 = 0;
		ucWaraiObjectNo++;
		ucWaraiPartsNo++;
		if(ucWaraiObjectNo>=OBJECT_MAX)	ucWaraiObjectNo = 0;
		if(ucWaraiPartsNo>=ucWaraiPartsNum)	ucWaraiPartsNo = 0;
	}
}
//--------------------------------------------------------------
//                 パーツのセッティングデモ
//--------------------------------------------------------------
static int	WaraiObjSet()
{
	int i, j;
	
	if(ucWaraiTimeCounter==0)
	{
		sWaraiHenkaScale32 = ((sWaraiPartsScaleBak - 0x100)<<5) / PARTS_ZOOM_STAGE;
		sWaraiHenkaX32 = ((PARTS_X_STATIC - sWaraiPartsXBak)<<5) / PARTS_ZOOM_STAGE;
		
		switch(ucMiniSeq)
		{
			case WARAI_EYE_SET:
				sWaraiHenkaY32 = ((EYES_Y_START-sWaraiPartsYBak)<<5) / PARTS_ZOOM_STAGE;
				break;
			case WARAI_NOSE_SET:
				sWaraiHenkaY32 = ((NOSE_Y_START-sWaraiPartsYBak)<<5) / PARTS_ZOOM_STAGE;
				break;
			case WARAI_MOUTH_SET:
				sWaraiHenkaY32 = ((MOUTH_Y_START-sWaraiPartsYBak)<<5) / PARTS_ZOOM_STAGE;
				break;
		}
	}


	ucWaraiTimeCounter++;

	WaraiPartsPtr[0]->sScale = sWaraiPartsScaleBak - ((sWaraiHenkaScale32*ucWaraiTimeCounter)>>5);
	WaraiPartsPtr[0]->sX = sWaraiPartsXBak + ((sWaraiHenkaX32*ucWaraiTimeCounter)>>5);
	WaraiPartsPtr[0]->sY = sWaraiPartsYBak + ((sWaraiHenkaY32*ucWaraiTimeCounter)>>5);
	

	//次のシーケンスへ
	if(ucWaraiTimeCounter == PARTS_ZOOM_STAGE)
	{
		if(ucMiniSeq == WARAI_EYE_SET && WaraiPartsPtr[0]->ucChara == ucWaraiAtariChara[0]
		|| ucMiniSeq == WARAI_NOSE_SET && WaraiPartsPtr[0]->ucChara == ucWaraiAtariChara[1]
		|| ucMiniSeq == WARAI_MOUTH_SET && WaraiPartsPtr[0]->ucChara == ucWaraiAtariChara[2])
		{
			m4aSongNumStart(S_GAME_BARBER_PUSH_OK);
		} else
		{
			m4aSongNumStart(S_GAME_BARBER_PUSH_BAD);
		}
		
		for(i=0; i<OBJECT_MAX; i++)
		{
			WaraiParts[i].ucStatus = OFF;
			switch(ucMiniSeq)
			{
				case WARAI_EYE_SET:
					WaraiParts[i].sY = (NOSE_Y_START);
					break;
				case WARAI_NOSE_SET:
					WaraiParts[i].sY = (MOUTH_Y_START);
					break;
			}
		}
		WaraiPartsPtr[0]->sX = 1000;		// 飛ばす
		ucWaraiTimeCounter=0;
		ucWaraiObjectNo = 0;
		ucWaraiPartsNo = 0;

		return 1;
	}
	
	return 0;
}


//--------------------------------------------------------------
//                 キャラクタデータの転送
//--------------------------------------------------------------
static void	WaraiCharaSet()
{
	int i;
	
	switch(ucMiniSeq)
	{
		case WARAI_NOSE_ROLL:
			DmaCopy(3, warai_nose_Char, OBJ_MODE0_VRAM+0x3000, 0x4000, 16);		// 鼻を転送
			break;

		case WARAI_MOUTH_ROLL:
			DmaCopy(3, warai_mouth_Char, OBJ_MODE0_VRAM+0x3000, 0x4000, 16);		// 口を転送
			break;
	};
}
//--------------------------------------------------------------
//                 固定用のキャラクタの転送
//--------------------------------------------------------------
static void	WaraiKoteiCharaSet()
{
	int i, j, temp10, temp1, destp, srcp, chara;

	switch(ucMiniSeq)
	{
		case WARAI_EYE_ROLL:
			chara = WaraiKoteiCharaOrder(KoteiEyes.ucChara);
			temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
			temp1 = chara % 4;
			srcp = (int)warai_eyes_Char+temp10*0x1000+temp1*0x100;
			destp = OBJ_MODE0_VRAM+0x7000;
			break;
		case WARAI_NOSE_ROLL:
			chara = WaraiKoteiCharaOrder(KoteiNose.ucChara);
			temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
			temp1 = chara % 4;
			srcp = (int)warai_nose_Char+temp10*0x1000+temp1*0x100;
			destp = OBJ_MODE0_VRAM+0x7100;
			break;
		case WARAI_MOUTH_ROLL:
			chara = WaraiKoteiCharaOrder(KoteiMouth.ucChara);
			temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
			temp1 = chara % 4;
			srcp = (int)warai_mouth_Char+temp10*0x1000+temp1*0x100;
			destp = OBJ_MODE0_VRAM+0x7200;
			break;
	}

	for(i=0; i<4; i++)
	{
		DmaCopy(3, srcp+i*0x400, destp+i*0x400, 0x100, 16);
		DmaWait(3);
	}
}

//--------------------------------------------------------------
//                 固定用のキャラクタの転送２
//--------------------------------------------------------------
static void	WaraiKoteiCharaSet2()
{
	int i, j, temp10, temp1, destp, srcp, chara;

	chara = WaraiKoteiCharaOrder(KoteiEyes.ucChara);
	temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
	temp1 = chara % 4;
	srcp = (int)warai_eyes_Char+temp10*0x1000+temp1*0x100;
	destp = OBJ_MODE0_VRAM+0x7000;

	for(i=0; i<4; i++)
	{
		DmaCopy(3, srcp+i*0x400, destp+i*0x400, 0x100, 16);
		DmaWait(3);
	}

	chara = WaraiKoteiCharaOrder(KoteiNose.ucChara);
	temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
	temp1 = chara % 4;
	srcp = (int)warai_nose_Char+temp10*0x1000+temp1*0x100;
	destp = OBJ_MODE0_VRAM+0x7100;

	for(i=0; i<4; i++)
	{
		DmaCopy(3, srcp+i*0x400, destp+i*0x400, 0x100, 16);
		DmaWait(3);
	}

	chara = WaraiKoteiCharaOrder(KoteiMouth.ucChara);
	temp10 = chara / 4;		// 固定オブジェクト用のVRAMにキャラデータを転送
	temp1 = chara % 4;
	srcp = (int)warai_mouth_Char+temp10*0x1000+temp1*0x100;
	destp = OBJ_MODE0_VRAM+0x7200;

	for(i=0; i<4; i++)
	{
		DmaCopy(3, srcp+i*0x400, destp+i*0x400, 0x100, 16);
		DmaWait(3);
	}
}


//--------------------------------------------------------------
//                 固定用のキャラクタの転送の前準備
//--------------------------------------------------------------
static int WaraiKoteiCharaOrder(u8	charatemp)
{
	int i, chara;
	
	// 最初はワリオ
	chara = 0;
	
	if(charatemp)	chara = ucWaraiPartsRndNum[charatemp-1]+1;
	
	return chara;
}

//==============================================================
//		ランダム順列作成ルーチン
//==============================================================
static void WaraiRandomNoSet(void)
{
	int i, j, d;

	// 0から現在のオブジェクト種類までのランダム
	for(i=0; i<ucWaraiPartsNum; i++)		ucWaraiObjRndNum[i] = i;
	for(i=ucWaraiPartsNum-1; i>0; i--) {
		j=MiniRandomCreate() % i;
		d = ucWaraiObjRndNum[i];
		ucWaraiObjRndNum[i]=ucWaraiObjRndNum[j];
		ucWaraiObjRndNum[j]=d;
	}
}

//==============================================================
//		ランダムパーツサクセイルーチン
//==============================================================
static void WaraiPartsRandomSet(void)
{
	int i, j, d;
	
	// 最初は必ずワリオパーツ
	iParts_Obj[0] = Parts_Obj[0];
	
	// パーツにランダムにセット
	for(i=0; i<PARTS_MAX-1; i++)		ucWaraiPartsRndNum[i] = i;
	for(i=PARTS_MAX-2; i>0; i--)
	{
		j=MiniRandomCreate() % i;
		d = ucWaraiPartsRndNum[i];
		ucWaraiPartsRndNum[i]=ucWaraiPartsRndNum[j];
		ucWaraiPartsRndNum[j]=d;
	}

	for(i=1; i<PARTS_MAX; i++)
	{
		iParts_Obj[i] = Parts_Obj[ucWaraiPartsRndNum[i-1]+1];
	}
}

//==============================================================
//		ソートルーチン
//==============================================================
static void	WaraiSort(void)
{
	int s,i,j;
	s16 max;
	WaraiPartsDef *t;
	
	for(i=0; i<OBJECT_MAX; i++)	WaraiPartsPtr[i]=&WaraiParts[i];	// データをポインタで指し示す
	
	for(i=0; i<OBJECT_MAX-1; i++) {
		max = WaraiPartsPtr[i]->sScale;		// 大きさでソート
		s = i;
		for (j=i+1; j<OBJECT_MAX; j++) {
			if ((WaraiPartsPtr[j]->sScale) > max) {
				max = WaraiPartsPtr[j]->sScale;
				s = j;
			}
		}
		t=WaraiPartsPtr[i];
		WaraiPartsPtr[i]=WaraiPartsPtr[s];
		WaraiPartsPtr[s]=t;		// ポインタの交換
	}
}

//==============================================================
//		スコアセット
//==============================================================
static void	WaraiScoreSet(void)
{
	// メダル表示
	if(ucMiniMedalFlg)
	{
		SelMedalSet(usTotalGoldMedal, (u32)(warai_bg_Char)+0x1180, 0x60);
	} else
	{
		SelMedalSet(usTotalGoldMedal, (u32)(warai_bg_Char)+0x820, 0x60);
	}
	

	// スコア表示
		SelMedalSet(usMiniScore, (u32)(warai_bg_Char)+0x120, 0xE0);
		
	// ハイスコア表示
		MiniScoreSet(usMiniBestScore[MINI_WARAI_GAME], (u32)(warai_bg_Char)+0xd80, 0x980);
}


//==============================================================
//		ＯＡＭ作成ルーチン
//==============================================================

void MiniWaraiOamCreate(void)
{
u16		data;
u16		*oam;
u16		*anm;
s16		pa, pb, pc, pd;
int		h, i, j, n;

	i = 0;
	n = ucCntObj;		// OAMのカウント



	

//OamBufの作成
	oam = (u16*)(OamBuf+ucCntObj);


// ロゴ
	if(MiniLogo.ucStatus)
	{
		if(MiniLogo.ucStatus == 1)		anm = (u16*)wario_face_Anm_15[0].uiObjAddr;	// ゲームスタート
		if(MiniLogo.ucStatus == 2)		anm = (u16*)wario_face_Anm_14[0].uiObjAddr;	// ゲームオーバー
		n += *(u16*)anm++;
		for( ; i < n; i++)
		{
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].VPos = (data+MiniLogo.sY-16)&0xff;
			OamBuf[i].AffineMode = ST_OAM_AFFINE_TWICE; //回転拡縮フラグON、倍角フラグON
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].HPos = (data+MiniLogo.sX-32)&0x1ff;
			OamBuf[i].AffineParamNo_L = 0;
			
			*(u16*)(oam++) = *(u16*)anm++;
			OamBuf[i].Priority = 0;
			oam++;
		}

	    pa = FixMul(  _Cos(0), FixInverse(MiniLogo.usScale) );
	    pb = FixMul(  _Sin(0), FixInverse(MiniLogo.usScale) );
	    pc = FixMul( -_Sin(0), FixInverse(MiniLogo.usScale) );
	    pd = FixMul(  _Cos(0), FixInverse(MiniLogo.usScale) );

		OamBuf[0].AffineParam = *(u16*)(&pa);
		OamBuf[1].AffineParam = *(u16*)(&pb);
		OamBuf[2].AffineParam = *(u16*)(&pc);
		OamBuf[3].AffineParam = *(u16*)(&pd);
	}

// ＬＯＯＫ！
	if(ucMiniSeq == WARAI_KEY_WAIT || ucMiniSeq == WARAI_BLEND_UP)
	{
		WaraiLook.usAnmTimer++;
		if(wario_face_Anm_17[WaraiLook.usAnmPat].ucTimer < WaraiLook.usAnmTimer)
		{
			WaraiLook.usAnmTimer = 1;
			WaraiLook.usAnmPat++;
			if(wario_face_Anm_17[WaraiLook.usAnmPat].ucTimer == 0)
			{
				WaraiLook.usAnmPat = 0;
			}
		}
		anm = (u16*)wario_face_Anm_17[WaraiLook.usAnmPat].uiObjAddr;	//オブジェクトのデータ
		n += *(u16*)anm++;
		for( ; i < n; i++)
		{
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].VPos = (data+64)&0xff;
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].HPos = (data+140)&0x1ff;
			*(u16*)(oam++) = *(u16*)anm++;
			OamBuf[i].Priority = 1;
			oam++;
		}
	}


//パネル
	if(ucMiniSeq > WARAI_BLEND1)
	{
		for(h=0; h<OBJECT_MAX; h++)
		{
			if(WaraiPartsPtr[h]->sX != 1000)
			{
				
				switch(ucMiniSeq)
				{
					case WARAI_NOSE_ROLL:
					case WARAI_MOUTH_ROLL:
					case WARAI_EYE_ROLL:
						// 並び替え
						WaraiSort();
					case WARAI_NOSE_SET:
					case WARAI_MOUTH_SET:
					case WARAI_EYE_SET:
					default:
						anm = (u16*)(iParts_Obj[WaraiPartsPtr[h]->ucChara]);
						break;
				}


				n += *(u16*)anm++;
				for( ; i < n; i++)
				{
					data = *(u16*)anm++;
					*(u16*)(oam++) = data;
					OamBuf[i].VPos = (data+(WaraiPartsPtr[h]->sY)-16)&0xff;
					OamBuf[i].AffineMode = ST_OAM_AFFINE_TWICE; //回転拡縮フラグON、倍角フラグON
					data = *(u16*)anm++;
					*(u16*)(oam++) = data;
					OamBuf[i].HPos = (data+(WaraiPartsPtr[h]->sX)-32)&0x1ff;
					OamBuf[i].AffineParamNo_L = h+1;
					
					*(u16*)(oam++) = *(u16*)anm++;
					OamBuf[i].Priority = 0;
					if(ucMiniSeq > WARAI_NOSE_SET) {				// パレット変更
						OamBuf[i].Pltt++;
						OamBuf[i].Pltt++;
					} else if (ucMiniSeq > WARAI_EYE_SET) {
						OamBuf[i].Pltt++;
					}
					oam++;
				}

			    pa = FixMul(  _Cos(0), FixInverse(WaraiPartsPtr[h]->sScale) );
			    pb = FixMul(  _Sin(0), FixInverse(WaraiPartsPtr[h]->sScale) );
			    pc = FixMul( -_Sin(0), FixInverse(WaraiPartsPtr[h]->sScale) );
			    pd = FixMul(  _Cos(0), FixInverse(WaraiPartsPtr[h]->sScale) );

				// 拡大縮小の上限・下限
				if(WaraiPartsPtr[h]->sScale > 0x200)
				{
				    pa = FixMul(  _Cos(0), FixInverse(PARTS_SCALE_MAX) );
				   	pb = FixMul(  _Sin(0), FixInverse(PARTS_SCALE_MAX) );
				   	pc = FixMul( -_Sin(0), FixInverse(PARTS_SCALE_MAX) );
			    	pd = FixMul(  _Cos(0), FixInverse(PARTS_SCALE_MAX) );
			    } else if(WaraiPartsPtr[h]->sScale < PARTS_SCALE_MIN)
				{
				    pa = FixMul(  _Cos(0), FixInverse(PARTS_SCALE_MIN) );
				   	pb = FixMul(  _Sin(0), FixInverse(PARTS_SCALE_MIN) );
				   	pc = FixMul( -_Sin(0), FixInverse(PARTS_SCALE_MIN) );
			    	pd = FixMul(  _Cos(0), FixInverse(PARTS_SCALE_MIN) );
			    }

				OamBuf[4*(h+1)+0].AffineParam = *(u16*)(&pa);
				OamBuf[4*(h+1)+1].AffineParam = *(u16*)(&pb);
				OamBuf[4*(h+1)+2].AffineParam = *(u16*)(&pc);
				OamBuf[4*(h+1)+3].AffineParam = *(u16*)(&pd);
			}
		}
	}


// 固定オブジェクト
	// 鼻
	if(ucMiniSeq < WARAI_EYE_ROLL || ucMiniSeq > WARAI_NOSE_SET)
	{
		anm = (u16*)((int)wario_face_Obj_19);
		n += *(u16*)anm++;
		for( ; i < n; i++)
		{
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].VPos = (data+(KoteiNose.sY))&0xff;
			OamBuf[i].ObjMode = ST_OAM_OBJ_BLEND;
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].HPos = (data+(KoteiNose.sX))&0x1ff;
			*(u16*)(oam++) = *(u16*)anm++;
			OamBuf[i].Priority = 1;
			oam++;
		}
	}

	// 目
	if(ucMiniSeq < WARAI_EYE_ROLL || ucMiniSeq > WARAI_EYE_SET)
	{
		anm = (u16*)((int)wario_face_Obj_18);
		n += *(u16*)anm++;
		for( ; i < n; i++)
		{
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].VPos = (data+(KoteiEyes.sY))&0xff;
			OamBuf[i].ObjMode = ST_OAM_OBJ_BLEND;
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].HPos = (data+(KoteiEyes.sX))&0x1ff;
			*(u16*)(oam++) = *(u16*)anm++;
			OamBuf[i].Priority = 1;
			oam++;
		}
	}

	// 口
	if(ucMiniSeq < WARAI_EYE_ROLL || ucMiniSeq > WARAI_MOUTH_SET)
	{
		anm = (u16*)((int)wario_face_Obj_1a);
		n += *(u16*)anm++;
		for( ; i < n; i++)
		{
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].VPos = (data+(KoteiMouth.sY))&0xff;
			OamBuf[i].ObjMode = ST_OAM_OBJ_BLEND;
			data = *(u16*)anm++;
			*(u16*)(oam++) = data;
			OamBuf[i].HPos = (data+(KoteiMouth.sX))&0x1ff;
			*(u16*)(oam++) = *(u16*)anm++;
			OamBuf[i].Priority = 1;
			oam++;
		}
	}

	// メダル
	if(ucMiniMedalFlg)
	{
		MiniMedal.usAnmTimer++;
		if(wario_face_Anm_01[MiniMedal.usAnmPat].ucTimer < MiniMedal.usAnmTimer)
		{
			MiniMedal.usAnmTimer = 1;
			MiniMedal.usAnmPat++;
			if(wario_face_Anm_01[MiniMedal.usAnmPat].ucTimer == 0)
			{
				MiniMedal.usAnmPat = 0;
				MiniMedal.usAnmTimer = 0;
				ucMiniMedalFlg = OFF;
				WaraiScoreSet();
			}
		}
	}
	
	anm = (u16*)wario_face_Anm_01[MiniMedal.usAnmPat].uiObjAddr;	//オブジェクトのデータ
	n += *(u16*)anm++;
	for( ; i < n; i++)
	{
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].VPos = (data+24)&0xff;
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].HPos = (data+21)&0x1ff;
		*(u16*)(oam++) = *(u16*)anm++;
		OamBuf[i].Priority = 0;
		oam++;
	}


	// 回るバー
	WaraiBar.usAnmTimer++;
	if(wario_face_Anm_00[WaraiBar.usAnmPat].ucTimer < WaraiBar.usAnmTimer)
	{
		WaraiBar.usAnmTimer = 1;
		WaraiBar.usAnmPat++;
		if(wario_face_Anm_00[WaraiBar.usAnmPat].ucTimer == 0)
		{
			WaraiBar.usAnmPat = 0;
		}
	}
	anm = (u16*)wario_face_Anm_00[WaraiBar.usAnmPat].uiObjAddr;	//オブジェクトのデータ
	n += *(u16*)anm++;
	for( ; i < n; i++)
	{
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].VPos = (data+112)&0xff;
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].HPos = (data+16)&0x1ff;
		*(u16*)(oam++) = *(u16*)anm++;
		OamBuf[i].Priority = 1;
		oam++;
	}
	anm = (u16*)wario_face_Anm_00[WaraiBar.usAnmPat].uiObjAddr;	//オブジェクトのデータ
	n += *(u16*)anm++;
	for( ; i < n; i++)
	{
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].VPos = (data+112)&0xff;
		data = *(u16*)anm++;
		*(u16*)(oam++) = data;
		OamBuf[i].HPos = (data+224)&0x1ff;
		*(u16*)(oam++) = *(u16*)anm++;
		OamBuf[i].Priority = 1;
		oam++;
	}

	ucCntObj = n;
}


//==============================================================
//		精算処理
//==============================================================
static int WaraiSeisan()
{
	switch(ucMiniDemoSeq)
	{
		case WARAI_SEISAN_KAO_CHANGE:
			usMiniDemoCount++;
			
			WaraiKaoYure();
			if(usMiniDemoCount > 60)
			{
				ucMiniDemoSeq++;
				usMiniDemoCount = 0;
			}
			break;

		case WARAI_SEISAN_SCORE_UP:
			usMiniScore++;		// スコアアップ
			if(usMiniScore>999)
			{
				usMiniScore=999;
			} else
			{
				m4aSongNumStart(S_GAME_POINT_1);
			}
			if(usMiniScore > usMiniBestScore[MINI_WARAI_GAME])	// ハイスコアセット
			{
				ucMiniHighScoreFlg = ON;
				usMiniBestScore[MINI_WARAI_GAME] = usMiniScore;
			}
			WaraiScoreSet();
			
			WaraiKaoYure();
			ucMiniDemoSeq++;
			break;
			
		case WARAI_SEISAN_WAIT_1:
			usMiniDemoCount++;
			WaraiKaoYure();
			if(usMiniDemoCount>20)
			{
				usMiniDemoCount = 0;
				ucMiniDemoSeq++;
			}
			break;
		
		case WARAI_SEISAN_MEDAL_UP:
			if(usMiniScore % WARAI_MEDAL_COUNT == 0)
			{
				usTotalGoldMedal++;
				if(usTotalGoldMedal>999)
				{
					usTotalGoldMedal = 999;
				} else
				{
					m4aSongNumStart(S_GAME_MEDAL_1);
					ucMiniMedalFlg = ON;
				}
			}
			WaraiScoreSet();

			ucMiniDemoSeq++;
			WaraiKaoYure();
			break;

		case WARAI_SEISAN_WAIT_2:
			usMiniDemoCount++;
			WaraiKaoYure();
			if(usMiniDemoCount>20)
			{
				usMiniDemoCount = 0;
				ucMiniDemoSeq++;
			}
			break;
			
		case WARAI_SEISAN_BLEND_DOWN:
			usMiniDemoCount++;
			if(usMiniDemoCount&0x01)	break;
			//2フレームごとに↓を実行
			if(cMiniEva > 0)
			{
				cMiniEvb++;
				cMiniEva--;
			}
			else
			{
				WaraiLoopInit();
				usMiniDemoCount = 0;
				ucMiniDemoSeq++;
			}
			break;

		case WARAI_SEISAN_BLEND_UP:
			usMiniDemoCount++;
			if(usMiniDemoCount&0x01)	break;
			if(cMiniEva < 16)
			{
				cMiniEvb--;
				cMiniEva++;
			}
			else
			{
				usMiniDemoCount = 0;
				ucMiniDemoSeq = 0;
				return 1;
			}
			break;
	}

	return 0;
}

// かお変化
static void WaraiKaoChange()
{
	usKoteiAnimTimer++;
	if(usKoteiAnimTimer%16 == 0)
	{
		DmaCopy(3, wario_face_Char, OBJ_MODE0_VRAM+0x7000, 0x1000, 16);
	} else if(usKoteiAnimTimer%16 == 8)
	{
		int i;
		// ワリオの固定顔データを転送
		for(i=0; i<4; i++)
		{
			DmaCopy(3, warai_eyes_Char+i*0x400, OBJ_MODE0_VRAM+0x7000+i*0x400, 0x100, 16);
			DmaWait(3);
			DmaCopy(3, warai_nose_Char+i*0x400, OBJ_MODE0_VRAM+0x7100+i*0x400, 0x100, 16);
			DmaWait(3);
			DmaCopy(3, warai_mouth_Char+i*0x400, OBJ_MODE0_VRAM+0x7200+i*0x400, 0x100, 16);
			DmaWait(3);
		}
	}
}
//==============================================================
//		ゲームオーバー処理
//==============================================================
static int WaraiGameover()
{
	switch(ucMiniDemoSeq)
	{
		case WARAI_GO_KAO_YURE:
			usMiniDemoCount++;

		//	WaraiKaoYure();
			if(usMiniDemoCount > 120)
			{
				ucMiniDemoSeq++;
				usMiniDemoCount = 0;
				MiniLogo.ucStatus = 2;
			}
			break;
		case WARAI_GO_LOGO:
		//	WaraiKaoYure();
			MiniLogo.usScale += MINI_LOGO_SCALE_SPEED;
			if(MiniLogo.usScale > 0x200)
			{
				m4aSongNumStart(S_GAME_BB_GAME_START);
				MiniLogo.usScale = 0x200;
				ucMiniDemoSeq++;
			}
			break;
		case WARAI_GO_WAIT:
			if(MiniWait(60))
			{
				ucMiniDemoSeq = 0;
				return 1;
			}
			break;
	}
	
	return 0;
}

// かおゆれ
static void WaraiKaoYure()
{
	usKoteiAnimTimer++;
	if(usKoteiAnimTimer%16 < 4)
	{
		KoteiEyes.sY += WARAI_KOTEI_IDO;
		KoteiNose.sY -= WARAI_KOTEI_IDO;
		KoteiMouth.sY += WARAI_KOTEI_IDO;
	} else if(usKoteiAnimTimer%16 < 12 && usKoteiAnimTimer%16 > 7)
	{
		KoteiEyes.sY -= WARAI_KOTEI_IDO;
		KoteiNose.sY += WARAI_KOTEI_IDO;
		KoteiMouth.sY -= WARAI_KOTEI_IDO;
	}
}
