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


少し前に、一本ソースでとりあえず書いてみました。
NDS で FXP フォーマットを読み書きするコードです。
これだけでは単にFXPファイルの読み書き関数があるだけに過ぎず、
実際には状態遷移で動作を制御するコードがあってはじめて
実用できるものになるのではと。
テストには相変わらず id:yasuho さんのナイトライダーを読み込ませてます。(^^;


FATライブラリを使ってるので Makefile のライブラリインクルードに
FATライブラリを取り込むよう、以下のように記述を変更する必要があります。

LIBS	:= 	-lnds9

LIBS	:= 	-lfat -lnds9


メイク後、DLDIパッチは手動で当てる必要があります。


FATライブラリを使ったプログラムは実機確認必須です。
現状のNDSエミュレータでは、読み込み動作は問題ないのですが
書き込み動作を実機通り行うものがない為です。
動作を見てるとエミュレーション上で処理は行ってるみたいなのですが
出力が未対応なのだと思います。


それと、1.4.9のFATライブラリにはバグがあるっぽいです。
同一ソースにて1.5.0では望む通りの動作が行われたので、
1.4.9環境の方はご注意ください。


fxp module test

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

	fxp module test
	
	version 0.01
	Sep 09, 2009
	
	(C)2009 REGEKATSU

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

#include <nds.h>
#include <fat.h>

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


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

#define GMC4_MEMORY_SIZE 0x80
#define USER_MEMORY_SIZE 0x60


typedef struct{
	u8 memory[GMC4_MEMORY_SIZE];
	u8 pc;
	bool flag;
}MemoryStatus;


static MemoryStatus st_gmc4;


//読み書き対象となるファイル名
const char *LOAD_FILE = "/load.fxp";
const char *SAVE_FILE = "/save.fxp";


void drawMemory(void);


bool isCharHex(char);

//ファイル操作の正常終了は1、異常終了は0を返すものとする。
int loadFxp(char *data, const int size, const char *filename);
int saveFxp(const char *data, const int size, const char *filename);


//---------------------------------------------------------------------------------
void drawMemory(void){
//---------------------------------------------------------------------------------
	int i;
	
	for(i = 0;i < 16;i++){
		printf(" %02X:%1X %02X:%1X %02X:%1X %02X:%1X %02X:%1X %02X:%1X \n", 
			0x00 + i, st_gmc4.memory[0x00 + i], 
			0x10 + i, st_gmc4.memory[0x10 + i], 
			0x20 + i, st_gmc4.memory[0x20 + i], 
			0x30 + i, st_gmc4.memory[0x30 + i], 
			0x40 + i, st_gmc4.memory[0x40 + i], 
			0x50 + i, st_gmc4.memory[0x50 + i]);
	}
}


//---------------------------------------------------------------------------------
bool 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 loadFxp(char *data, const int size, const char *filename){
//---------------------------------------------------------------------------------
	
	//読み込みモード
	typedef enum{
		READ_CHAR = 0,
		READ_SKIP = 1
	}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(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 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;
	
}


//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	consoleDemoInit();
	
	//libfat利用のための初期化処理
	fatInitDefault();
	
	printf("FXP file Load/Save test\n\n");
	
	if(!loadFxp((char *)&st_gmc4.memory[0], USER_MEMORY_SIZE, LOAD_FILE)){
		printf("load fxp error.\n");
		return 1;
	}else{
		printf("load fxp success.\n");
	}
	
	drawMemory();
	
	if(!saveFxp((char *)&st_gmc4.memory[0], USER_MEMORY_SIZE,SAVE_FILE)){
		printf("save fxp error.\n");
		return 1;
	}else{
		printf("save fxp success.\n");
	}
	
	while(1) {
		swiWaitForVBlank();
	}
	
}