少し前に、一本ソースでとりあえず書いてみました。
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 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(); } }