ハートに16連射。(15)


ストップウォッチモードです。
実機では 1/100 秒まで計れるのですが僕の書くコードは VSYNC 周期を基準としてるので
実際に10ミリ秒は刻んでおらず、 1/60 秒中、その時の10ミリ秒値に近い値を表示してそれらしく振舞ってます。


ビルドには下記ソース以外に、
「ハートに16連射。(12)」に記した全てのモジュールが必要だったり…。


ハートに16連射。(12)
http://d.hatena.ne.jp/dumbo001/20100201/p1


stopMode module test


main.c

/*---------------------------------------------------------------------------------
	
	shtwatch
	stopMode module test
	
	version 0.01
	Feb 02, 2010
	
	By. REGEKATSU
	
---------------------------------------------------------------------------------*/

#include <string.h>
#include <nds/ndstypes.h>
#include <nds/interrupts.h>
#include <nds/system.h>
#include <nds/arm9/input.h>
#include "Bg.h"
#include "Spr.h"
#include "State.h"
#include "StopMode.h"


typedef enum{
	MAIN_INIT, 
	MAIN_RESET, 
	MAIN_EXEC
}MAIN_ACT;

typedef struct{
	u16 act;
}MainStatus;

static MainStatus st_main;


void main_Init(void);
void main_Reset(void);
bool main_IsReset(void);


//---------------------------------------------------------------------------------
int main(void){
//---------------------------------------------------------------------------------
	
	lcdSwap();
	
	while(1) {
		swiWaitForVBlank();
		scanKeys();
		
		Spr_Update();
		
		if(main_IsReset()){
			st_main.act = MAIN_RESET;
		}
		
		switch(st_main.act){
			
		case MAIN_INIT:
			main_Init();
			st_main.act = MAIN_RESET;
			break;
			
		case MAIN_RESET:
			main_Reset();
			st_main.act = MAIN_EXEC;
			break;
			
		case MAIN_EXEC:
			StopMode_Update();
			
			if(StopMode_IsExit()){
				return 0;
			}
			break;
			
		}
		
	}
	
}

//---------------------------------------------------------------------------------
void main_Init(void){
//---------------------------------------------------------------------------------
	
	memset(&st_main, 0, sizeof(st_main));
	Bg_Init();
	Spr_Init();
	State_Init();
	
	Bg_DrawConsString(0, 0, "stopMode module test\n\nversion 0.01\nFeb 02, 2010\n\nBy. REGEKATSU\n\n\n");
	
}

//---------------------------------------------------------------------------------
void main_Reset(void){
//---------------------------------------------------------------------------------
	
	StopMode_Clear();
	
}

//---------------------------------------------------------------------------------
bool main_IsReset(void){
//---------------------------------------------------------------------------------
	
	bool ans = false;
	
	u32 keys;
	
	if(keysDown() & (KEY_L | KEY_R | KEY_SELECT | KEY_START)){
		
		keys = keysDown() | keysHeld();
		keys = keys & (KEY_L | KEY_R | KEY_SELECT | KEY_START);
		
		if(keys == (KEY_L | KEY_R | KEY_SELECT | KEY_START)){
			ans = true;
		}
		
	}
	
	return ans;
	
}

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


stopMode.h

/*---------------------------------------------------------------------------------
	
	shtwatch
	stopMode module header
	
	version 0.01
	Feb 02, 2010
	
	By. REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _STOP_MODE_H_
#define _STOP_MODE_H_


#ifdef __cplusplus
extern "C" {
#endif


void StopMode_Clear(void);
void StopMode_Update(void);
bool StopMode_IsExit(void);


#ifdef __cplusplus
}
#endif

#endif	//_STOP_MODE_H_


stopMode.c

/*---------------------------------------------------------------------------------
	
	shtwatch
	stopMode module routine
	
	version 0.01
	Feb 02, 2010
	
	By. REGEKATSU
	
---------------------------------------------------------------------------------*/

#include <stdio.h>//debug print
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <nds/ndstypes.h>
#include <nds/arm9/input.h>
#include "StopMode.h"
#include "Spr.h"


//ten msec table
const static int ten_msecond[2][60] = {
	
	//round_down
	{
		 0,  1,  3,  5,  6,  8, 
		10, 11, 13, 15, 16, 18, 
		20, 21, 23, 25, 26, 28, 
		30, 31, 33, 35, 36, 38, 
		40, 41, 43, 45, 46, 48, 
		50, 51, 53, 55, 56, 58, 
		60, 61, 63, 65, 66, 68, 
		70, 71, 73, 75, 76, 78, 
		80, 81, 83, 85, 86, 88, 
		90, 91, 93, 95, 96, 98
	}, 
	//round_up
	{
		 0,  2,  4,  5,  7,  9, 
		10, 12, 14, 15, 17, 19, 
		20, 22, 24, 25, 27, 29, 
		30, 32, 34, 35, 37, 39, 
		40, 42, 44, 45, 47, 49, 
		50, 52, 54, 55, 57, 59, 
		60, 62, 64, 65, 67, 69, 
		70, 72, 74, 75, 77, 79, 
		80, 82, 84, 85, 87, 89, 
		90, 92, 94, 95, 97, 99
	}
	
};


typedef enum{
	STOP_MODE_INIT, 
	STOP_MODE_EXEC, 
	STOP_MODE_EXIT
}STOP_MODE_ACT;

typedef struct{
	
	u16 act;
	
	bool is_exec_count;
	bool is_draw_count;
	
	int frame;
	int second;
	int minute;
	
}StopModeStatus;

static StopModeStatus st_stop_mode;


void stopMode_Init(void);
void stopMode_Exec(void);
void stopMode_Exit(void);
void stopMode_ExecCount(void);
void stopMode_ClearCount(void);
void stopMode_DrawCount(void);


//---------------------------------------------------------------------------------
void StopMode_Clear(void){
//---------------------------------------------------------------------------------
	
	stopMode_Exit();
	
}

//---------------------------------------------------------------------------------
void StopMode_Update(void){
//---------------------------------------------------------------------------------
	
	switch(st_stop_mode.act){
		
	case STOP_MODE_INIT:
		stopMode_Init();
		break;
		
	case STOP_MODE_EXEC:
		stopMode_Exec();
		break;
		
	case STOP_MODE_EXIT:
		stopMode_Exit();
		break;
		
	}
	
}

//---------------------------------------------------------------------------------
void stopMode_Init(void){
//---------------------------------------------------------------------------------
	
	memset(&st_stop_mode, 0, sizeof(st_stop_mode));
	srand(time(NULL));
	
	st_stop_mode.is_exec_count = false;
	st_stop_mode.is_draw_count = true;
	
	Spr_SetColon(3);
	Spr_SetCursor(BIT(2));
	stopMode_DrawCount();
	
	st_stop_mode.act = STOP_MODE_EXEC;
	
}

//---------------------------------------------------------------------------------
void stopMode_Exec(void){
//---------------------------------------------------------------------------------
	
	stopMode_ExecCount();
	
	if( (keysDown() & KEY_A) && ( (keysCurrent() & ~KEY_A) == 0) ){
		
		if(st_stop_mode.is_exec_count == false){
			st_stop_mode.is_exec_count = true;
			
		}else if(st_stop_mode.is_exec_count == true){
			st_stop_mode.is_exec_count = false;
			
		}
		
		if(st_stop_mode.is_draw_count == false){
			st_stop_mode.is_exec_count = true;
			st_stop_mode.is_draw_count = true;
			Spr_SetCursor(BIT(2));
			
		}
		
	}
	
	
	if( (keysDown() & KEY_B) && ( (keysCurrent() & ~KEY_B) == 0) ){
		
		if(st_stop_mode.is_exec_count == false){
			stopMode_ClearCount();
			
		}else if(st_stop_mode.is_exec_count == true){
			st_stop_mode.is_draw_count = false;
			
		}
		
		if(st_stop_mode.is_draw_count == false){
			st_stop_mode.is_draw_count = true;
			stopMode_DrawCount();
			st_stop_mode.is_draw_count = false;
			
		}
		
	}
	
	
	if( (keysDown() & KEY_SELECT) && ( (keysCurrent() & ~KEY_SELECT) == 0) ){
		st_stop_mode.act = STOP_MODE_EXIT;
	}
	
}

//---------------------------------------------------------------------------------
void stopMode_Exit(void){
//---------------------------------------------------------------------------------
	
	Spr_Clear();
	st_stop_mode.act = STOP_MODE_INIT;
	
}

//---------------------------------------------------------------------------------
void stopMode_ExecCount(void){
//---------------------------------------------------------------------------------
	
	if(st_stop_mode.is_exec_count == false) return;
	
	
	if(st_stop_mode.frame < 59){
		st_stop_mode.frame++;
	}else{
		st_stop_mode.frame = 0;
		
		if(st_stop_mode.second < 59){
			st_stop_mode.second++;
		}else{
			st_stop_mode.second = 0;
			
			if(st_stop_mode.minute < 59){
				st_stop_mode.minute++;
			}
			
		}
		
	}
	
	if(st_stop_mode.frame == 59 && st_stop_mode.second == 59 && st_stop_mode.minute == 59){
		st_stop_mode.is_exec_count = false;
	}
	
	stopMode_DrawCount();
	
}

//---------------------------------------------------------------------------------
void stopMode_ClearCount(void){
//---------------------------------------------------------------------------------
	
	if(st_stop_mode.is_exec_count == false){
		st_stop_mode.frame = 0;
		st_stop_mode.second = 0;
		st_stop_mode.minute = 0;
	}
	
	stopMode_DrawCount();
	
}

//---------------------------------------------------------------------------------
void stopMode_DrawCount(void){
//---------------------------------------------------------------------------------
	
	if(st_stop_mode.is_draw_count == true){
		
		int rnd = rand() % 2;
		
		//カウントオーバー時の処置("59:59 99"としてカウントを終了させる。)。
		if(st_stop_mode.frame == 59 && st_stop_mode.second == 59 && st_stop_mode.minute == 59){
			rnd = 1;
		}
		
		//debug print
		printf("\x01b[9;0H%02d:%02d %02d", 
			st_stop_mode.minute, 
			st_stop_mode.second, 
			ten_msecond[rnd][st_stop_mode.frame]);
		
		Spr_SetNumber(SEG_SECOND, ten_msecond[rnd][st_stop_mode.frame], true);
		Spr_SetNumber(SEG_MINUTE, st_stop_mode.second, true);
		Spr_SetNumber(SEG_HOUR, st_stop_mode.minute, true);
		
	}else{
		
		if(st_stop_mode.frame == 0){
			Spr_SetCursor(0);
		}else if(st_stop_mode.frame == 30){
			Spr_SetCursor(BIT(2));
		}
		
	}
	
}

//---------------------------------------------------------------------------------
bool StopMode_IsExit(void){
//---------------------------------------------------------------------------------
	
	return (st_stop_mode.act == STOP_MODE_INIT) ? true:false;
	
}

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