1本ソースをFXPモジュールとして分離し、
ファイル読み書きの状態遷移からFXPモジュールを呼び出して
選択実行するように変更しました。
メモリモジュール、ダンプモジュール、の統合確認も含めてます。
テストコードのビルドには先に公開した
メモリモジュール、ダンプモジュールを含める必要があります。
テストコードの動作的には
メモリダンプとFXPファイル読み書きを排他利用する動作となってます。
・メモリダンプ(セレクトボタンで表示/非表示)
モニタ中またはCPU実行中にリアルタイム表示を行う
・FXPファイル読み書き(スタートボタンでメニュー表示〜)
モニタ中、メニュー画面に従ってファイルのロード・セーブを行う
排他利用構造にしたので余ってるBGを2ndコンソールに割り当てる必要は無さそうです。
ファイラー動作、DMPフォーマット読み書きは検証中…。
後付し易い構造(のつもり)なので後回しです。><
ファイラーまで含めるなら
状態遷移の箇所は結構直しが必要っぽいですね。
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; } //---------------------------------------------------------------------------------