#include #include #include #include #include #define DEBUG_MODE 0 #define MAX_LABEL 100 //ラベルの最大数 #define MAX_TEMP_BUFFER 10000 //テンポラリ最大 #define MAX_SCRIPT_LINE 3000 //スクリプトの最大行 char DataTemp[MAX_TEMP_BUFFER];//テンポラリ int DataAdr[MAX_SCRIPT_LINE];//スクリプトの行数 char WinName[16]="";//人物の名前 char WinMessage[80]="";//表示するメッセージ int WinMesCount=0;//表示中のメッセージのカウント int WinMesMax=0;//メッセージの文字数 int LabelNum[MAX_LABEL];//ラベルの行番号 char LabelName[MAX_LABEL][20];//ラベルの名前 char MesParam[20][50];//分割された命令の引数(最大20) int MesParamCount;//分割の数 int ScriptAdr=0;//スクリプトのポインタ int ScriptAdrMax=0;//最大スクリプト行 enum CODE_LIST{ C_GOTO=2, C_JUMP=3, C_GOTOTEXT=4, C_JUMPTEXT=5, C_CJUMP=6, C_WAIT=7, C_PARAMETER=8, C_IF=9, C_END=99, C_CG=20, C_BG=21, C_CHAR=22, C_CHARCLEAR=23, C_EFFECTCG=24, C_EFFECT=25, C_FO=26, C_FI=27, C_SHAKE=28, C_FLASH=29, C_SOUND=40, C_SOUNDSTOP=41, C_SE=42, }; //------------------------------------------------------------- void ScriptInit() {//ステータス初期化する //新規にファイルを読んだ時に実行するとよい int a; for(a=0;a0){ DataAdr[Adr]=a-b;//1行の最初のアドレス #if DEBUG_MODE { char* p=&DataTemp[DataAdr[Adr]]; char t[100]; strncpy(t,p,b); t[b]=0; printf("[%s]\n",t); } #endif ScriptAdrMax++; if(ScriptAdrMax>MAX_SCRIPT_LINE) return false; Adr++;b=0;//次の行設定 } }else if(c!=0x0a){//改行コード以外なら b++;//次の文字へ } if(Adr>=MAX_SCRIPT_LINE) return false;//行をオーバーした } if(b>0){//残りの文字 DataAdr[Adr]=a-b;//1行の最初のアドレス #if DEBUG_MODE { char* p=&DataTemp[DataAdr[Adr]]; char t[100]; strncpy(t,p,b); t[b]=0; printf("[%s]\n",t); } #endif ScriptAdrMax++; if(ScriptAdrMax>MAX_SCRIPT_LINE) return false; } ScriptAdr=0; printf("スクリプト行数=%d\n",ScriptAdrMax); return true; } void SetMessage(char* mes,int nameflag) {//メッセージのセット char* p=mes; int x=0; if(nameflag==1){ //名前の取得 while(*p!=0){ if(*p!=32){ WinName[x++]=*p++; }else{ WinName[x]=0;//終端 p++;break; } } }else{ WinName[0]=0;//名前なし } //セリフの取得 x=0; while(*p!=0){ WinMessage[x++]=*p++; } WinMessage[x]=0;//終端 WinMesMax=strlen(WinMessage); WinMesCount=0; } int MessageTask() {//メッセージの処理 //文字を1文字ずつ表示させます。 //表示中は1を返し、終端にきたら0を返します。 char out[100]; int EndFlag=0; out[0]=0; if(WinMesMax==0){ return 0; } Sleep(20);//表示のウェイト if(WinMesCount==0 && WinName[0]!=0){ sprintf(out,"%s 「",WinName); } //全角は2文字、半角は1文字を取り出す char m[3]={0}; m[0]=WinMessage[WinMesCount++]; if((m[0]&0x80)!=0 && (m[0]<(char)0xa1 || m[0]>(char)0xdf)) m[1]=WinMessage[WinMesCount++]; strcat(out,m); if(WinMesCount>=WinMesMax){ if(WinName[0]!=0) strcat(out,"」"); strcat(out,"\n"); WinMesMax=0;//メッセージ終端で終わり EndFlag=0; }else{ EndFlag=1; } printf("%s",out); return EndFlag; } bool IsMessage() { if(WinMesMax>0) return true;//表示するメッセージがある else return false;//ない } bool SetLabel() {//ラベルの定義 int a,max=0; char* p,*p2; //初期化 for(a=0;aMAX_LABEL){ return false; } } } ScriptAdr=0; return true; } int GetLabel(char* m) {//ラベルの取得 int a; for(a=0;amax) break; outtext=(char*)out+count*len;//次のアドレス }else{ *outtext++=*text; } text++; } *outtext=0; //返す値は区切った数 return count+1; } int Decode(char* mes) {//翻訳 if(mes[0]!='&'){ return 0;//命令ではなかった } int adr=0; char* p=mes+1; int num=0; //処理しやすいように分割 MesParamCount=WordSplit(mes+1,(char**)MesParam,sizeof(MesParam[0]),20); //命令ごとに分岐 if(strcmp(MesParam[0],"GOTO")==0){ return C_GOTO; } if(strcmp(MesParam[0],"JUMP")==0){ return C_JUMP; } if(strcmp(MesParam[0],"END")==0){ return C_END; } return -1; } int ScriptTask(char* scriptdata) {//スクリプト判定 int code=Decode(scriptdata); char* MessageText=scriptdata; int a; if(NextScriptData()==false) return 1;//最後まで達した switch(code){ case C_END://終了 return 1; break; case C_GOTO://ジャンプ ScriptAdr=GetLabel(MesParam[1]); return 0; break; case C_JUMP://選択肢表示 { for(a=1;a='1' && ch<='9'){ ScriptAdr=GetLabel(MesParam[(ch-'0')*2]);//アドレスをセット break; } } return 0; } break; default://メッセージ表示 if(MessageText[0]=='#'){ SetMessage(MessageText+1,1);//セリフ }else{ SetMessage(MessageText,0);//文章 } break; } return 0; } int main() { int result; //初期設定 if(ScriptRead()==false){//ここでファイルから読み出し printf("ファイルがありません。もしくはスクリプト最大行数を越えました。\n"); exit(0); } if(SetLabel()==false){//ラベル設定 printf("ラベル登録限界に達しました\n"); exit(0); } printf("スクリプト開始します。\n"); //メインループ char out[200]; //メインループ while(1){//先頭のコードを見る char* scdata=GetScriptData(out);//1行読み込み if(scdata[0]==0){ if(NextScriptData()==false) break;//最後までいった continue;//何もなければスキップ } result=ScriptTask(scdata);//スクリプト実行 if(result==1) break;//終了 while(IsMessage()==true){ result=MessageTask(); if(result==0){ getch();//入力待ち } } } printf("\nスクリプト終了します。\n"); getch();//入力待ち return 0; }