FXPファイル読み書きっぽい何か。2


1本ソースをFXPモジュールとして分離し、
ファイル読み書きの状態遷移からFXPモジュールを呼び出して
選択実行するように変更しました。
メモリモジュール、ダンプモジュール、の統合確認も含めてます。
テストコードのビルドには先に公開した
メモリモジュール、ダンプモジュールを含める必要があります。


テストコードの動作的には
メモリダンプとFXPファイル読み書きを排他利用する動作となってます。


・メモリダンプ(セレクトボタンで表示/非表示)
 モニタ中またはCPU実行中にリアルタイム表示を行う
・FXPファイル読み書き(スタートボタンでメニュー表示〜)
 モニタ中、メニュー画面に従ってファイルのロード・セーブを行う


排他利用構造にしたので余ってるBGを2ndコンソールに割り当てる必要は無さそうです。
ファイラー動作、DMPフォーマット読み書きは検証中…。
後付し易い構造(のつもり)なので後回しです。><
ファイラーまで含めるなら
状態遷移の箇所は結構直しが必要っぽいですね。


file sequence test


main.c

/*---------------------------------------------------------------------------------

	file sequence test
	
	version 0.01
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#include <nds.h>
#include <stdio.h>

#include "file.h"

#include "dump.h"
#include "memory.h"


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

typedef enum{
	MAIN_LOOP,
	MAIN_FILE,
}MAIN_SEQ;


typedef struct{
	u16 act;
}MainSeq;


static MainSeq st_main_seq = {MAIN_LOOP};


//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	consoleDemoInit();
	
	Memory_ClearAll();
	
	while(1) {
		swiWaitForVBlank();
		
		scanKeys();
		
		Dump_UpdateDump();
		
		switch(st_main_seq.act){
			
		case MAIN_LOOP:
			if((keysDown() & KEY_START) && (Dump_IsStopDump())){
				st_main_seq.act = MAIN_FILE;
			}else if(keysDown() & KEY_SELECT){
				Dump_SwitchDump();
			}
			break;
			
		case MAIN_FILE:
			File_Update();
			if(File_IsExit()){
				st_main_seq.act = MAIN_LOOP;
			}
			break;
			
		}
		
	}
	
}

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


file.h

/*---------------------------------------------------------------------------------

	file sequence header
	
	version 0.01
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _FILE_H_
#define _FILE_H_


#ifdef __cplusplus
extern "C" {
#endif


void File_Update(void);
bool File_IsExit(void);


#ifdef __cplusplus
}
#endif

#endif	// _FILE_H_


filePrivate.h

/*---------------------------------------------------------------------------------

	file sequence private header
	
	version 0.01
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _FILE_PRIVATE_H_
#define _FILE_PRIVATE_H_


#include <nds/ndstypes.h>
#include <nds/arm9/input.h>
#include <fat.h>

#include <stdio.h>

#include "memory.h"
#include "file.h"
#include "fxp.h"


typedef enum{
	FILE_INIT,
	FILE_MENU,
	FILE_LOAD,
	FILE_SAVE,
	FILE_END,
	FILE_EXIT
}FILE_SEQ;


typedef struct{
	u16 act;
}FileSeq;


#ifdef __cplusplus
extern "C" {
#endif


void file_Init(void);
void file_Menu(void);
void file_Load(void);
void file_Save(void);
void file_End(void);
void file_Exit(void);


#ifdef __cplusplus
}
#endif

#endif	// _FILE_PRIVATE_H_


file.c

/*---------------------------------------------------------------------------------

	file sequence routine
	
	version 0.01
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#include "filePrivate.h"


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


static FileSeq st_file_seq = {FILE_INIT};


//---------------------------------------------------------------------------------
void file_Init(void){
//---------------------------------------------------------------------------------
	
	fatInitDefault();
	
	printf("\x01b[2J");
	printf("\x01b[0;0HFXP file Load/Save menu");
	printf("\x01b[1;3HLoad fxp file");
	printf("\x01b[2;3HSave fxp file");
	
	st_file_seq.act = FILE_MENU;
}

//---------------------------------------------------------------------------------
void file_Menu(void){
//---------------------------------------------------------------------------------
	
	static int cursor = 0;
	
	if(keysDown() & (KEY_UP | KEY_DOWN)){
		
		printf("\x01b[%d;2H ", cursor + 1);
		
		if(cursor){
			cursor = 0;
		}else{
			cursor = 1;
		}
		
		printf("\x01b[%d;2H>", cursor + 1);
		
	}
	
	if(keysDown() & KEY_A){
		
		printf("\x01b[3;4H     fxp file ok?");
		
		if(!cursor){
			printf("\x01b[3;4HLoad");
			st_file_seq.act = FILE_LOAD;
		}else{
			printf("\x01b[3;4HSave");
			st_file_seq.act = FILE_SAVE;
		}
		
		printf("\x01b[1B");
	}
	
	if(keysDown() & KEY_START){
		st_file_seq.act = FILE_EXIT;
	}
	
}

//---------------------------------------------------------------------------------
void file_Load(void){
//---------------------------------------------------------------------------------
	
	//load ok
	if(keysDown() & KEY_A){
		
		printf("\n\x01b[2C");
		
		if(!Fxp_LoadFxp((char*)&st_gmc4.memory[0], USER_MEMORY_SIZE, LOAD_FILE_NAME)){
			printf("load fxp error.\n");
		}else{
			printf("load fxp success.\n");
		}
		
		st_file_seq.act = FILE_END;
	}
	
	//load cancel
	if(keysDown() & KEY_B){
		printf("\x01b[1A");
		printf("\x01b[2K");
		st_file_seq.act = FILE_MENU;
	}
	
}

//---------------------------------------------------------------------------------
void file_Save(void){
//---------------------------------------------------------------------------------
	
	//save ok
	if(keysDown() & KEY_A){
		
		printf("\n\x01b[2C");
		
		if(!Fxp_SaveFxp((char*)&st_gmc4.memory[0], USER_MEMORY_SIZE,SAVE_FILE_NAME)){
			printf("save fxp error.\n");
		}else{
			printf("save fxp success.\n");
		}
		
		st_file_seq.act = FILE_END;
	}
	
	//save cancel
	if(keysDown() & KEY_B){
		printf("\x01b[1A");
		printf("\x01b[2K");
		st_file_seq.act = FILE_MENU;
	}
	
}

//---------------------------------------------------------------------------------
void file_End(void){
//---------------------------------------------------------------------------------
	if(keysDown() & (KEY_A | KEY_START))
		st_file_seq.act = FILE_EXIT;
}

//---------------------------------------------------------------------------------
void file_Exit(void){
//---------------------------------------------------------------------------------
	printf("\x01b[2J");
	st_file_seq.act = FILE_INIT;
}



//---------------------------------------------------------------------------------
void File_Update(void) {
//---------------------------------------------------------------------------------
	
	switch(st_file_seq.act){
		
	case FILE_INIT:
		file_Init();
		break;
		
	case FILE_MENU:
		file_Menu();
		break;
		
	case FILE_LOAD:
		file_Load();
		break;
		
	case FILE_SAVE:
		file_Save();
		break;
		
	case FILE_END:
		file_End();
		break;
		
	case FILE_EXIT:
		file_Exit();
		break;
		
	default:
		break;
		
	}
	
}

//---------------------------------------------------------------------------------
bool File_IsExit(void){
//---------------------------------------------------------------------------------
	return (st_file_seq.act == FILE_INIT) ? true:false;
}

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


fxp.h

/*---------------------------------------------------------------------------------

	fxp module header
	
	version 0.02
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _FXP_H_
#define _FXP_H_


//読み書き対象となるファイル名
#define LOAD_FILE_NAME "/load.fxp"
#define SAVE_FILE_NAME "/save.fxp"


#ifdef __cplusplus
extern "C" {
#endif


//ファイル操作の正常終了は1、異常終了は0とする
int Fxp_LoadFxp(char *data, const int size, const char *filename);
int Fxp_SaveFxp(const char *data, const int size, const char *filename);


#ifdef __cplusplus
}
#endif

#endif	// _FXP_H_


fxpPrivate.h

/*---------------------------------------------------------------------------------

	fxp module private header
	
	version 0.02
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _FXP_PRIVATE_H_
#define _FXP_PRIVATE_H_


#include <nds/ndstypes.h>

#include <stdio.h>
#include <stdlib.h>

#include "fxp.h"


#ifdef __cplusplus
extern "C" {
#endif


bool fxp_IsCharHex(char);


#ifdef __cplusplus
}
#endif

#endif	// _FXP_PRIVATE_H_


fxp.c

/*---------------------------------------------------------------------------------

	fxp module routine
	
	version 0.02
	Oct 12, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/

#include "fxpPrivate.h"


const char *LOAD_FILE = LOAD_FILE_NAME;
const char *SAVE_FILE = SAVE_FILE_NAME;


//---------------------------------------------------------------------------------
bool fxp_IsCharHex(char c){
//---------------------------------------------------------------------------------
	bool ans;
	
	if(((c >= '0') && (c <= '9'))||
		((c >= 'a') && (c <= 'f'))||
		((c >= 'A') && (c <= 'F'))){
		ans = true;
	}else{
		ans = false;
	}
	
	return ans;
}


//---------------------------------------------------------------------------------
int Fxp_LoadFxp(char *data, const int size, const char *filename){
//---------------------------------------------------------------------------------
	
	//読み込みモード
	typedef enum{
		READ_CHAR,
		READ_SKIP
	}READ_MODE;
	
	READ_MODE read_mode = READ_CHAR;
	
	FILE *fp;
	char buf;
	
	int i;
	
	fp = fopen(filename, "r");
	if(fp == NULL){
		return 0;
	}
	
	i = 0;
	
	while(!feof(fp)){
		buf = fgetc(fp);
		
		switch (read_mode){
		case READ_CHAR:
			
			if(buf == '<'){
				read_mode = READ_SKIP;
			}else if(fxp_IsCharHex(buf)){
				
				if(i < size){
					data[i] = (char)strtol(&buf, NULL, 16);
					i++;
				}
			}
			break;
			
		case READ_SKIP:
		
			if(buf == '>'){
				read_mode = READ_CHAR;
			}
			break;
		}
		
	}
	
	fclose(fp);
	free(fp);
	
	return 1;
}

//---------------------------------------------------------------------------------
int Fxp_SaveFxp(const char *data, const int size, const char *filename){
//---------------------------------------------------------------------------------
	FILE *fp;
	
	const char *str1 = "<?xml version=\"1.0\"?>";
	const char *str2 = "<ArrayOfString xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
	const char *str3 = "<string>";
	const char *str4 = "</string>";
	const char *str5 = "</ArrayOfString>";

	int i;
	
	fp = fopen(filename, "w");
	
	if(fp == NULL){
		return 0;
	}
	
	
	fprintf(fp, "%s\n", str1);
	fprintf(fp, "%s\n", str2);
	
	for(i = 0;i < size;i++){
		fprintf(fp, "  %s%X%s\n", str3, data[i], str4);
	}
	
	fprintf(fp, "%s\n", str5);
	
	fclose(fp);
	free(fp);
	
	return 1;
}

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