.exe を開いて書き込むことができませんと言うエラーが直せません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
奥兵

.exe を開いて書き込むことができませんと言うエラーが直せません。

#1

投稿記事 by 奥兵 » 14年前

現在サイトを参考にしてゲーム用の簡易スクリプトを作成しているのですが、デバッグして実行するとプログラムが終了してもプロセスが残ることがあります。
LINK : fatal error LNK1168: ファイル C:\Users\okubyou\Documents\Visual Studio 2008\Projects\ProtoScript\Debug\ProtoScript.exe を開いて書き込むことができません。
とでて実行できないか、もしくは実行はできてもプロセスがどんどんたまっていってしまいます。

どなたか問題点のご指摘をおねがいします。

プログラミング歴は半年程度。
環境はVC2008 DxLib使用 OSは7です

コード:


#include <stdio.h>
#include <string.h>

#include "DxLib.h"

#define SCRIPT_MAX_LINE 1000
#define SCRIPT_MAX_STRING_LENGTH 300
#define GRAPHIC_MAX 10

//#define Choice1 300
//#define Choice2 332
//#define Choice3 
//#define Choice4

int Key[256];

struct GraphData{
		int GraphHandle;
		int GraphX;
		int GraphY;
};

typedef struct ScriptInformation_tag {
        int maxLineNumber;                      //スクリプト行数
        int currentLine;                        //現在何行目を実行しているか
        const char* filename;           //ファイル名
        char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
} ScriptInformation;



int gpUpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 0にする
                }
        }
        return 0;
}
//handle
//graphic 

/*
↓グラフィックをいくらか貯めて特定の引数で呼ばれた場合一括して表示
 上限は適当に10か20程度で
 
	グラフィックハンドルが渡されたら内部の配列に収納。
	
	特定の方法で内部の配列内のハンドルをクリア

	方法は適当に考えて。
	↑ for example {

	 *引数を追加して、モード分け
	 仮なので 魔法の数字で ぽぽぽぽ~ん
	 0 配列内容表示 1 配列へハンドル渡して表示 2  
	 -1 所定のハンドルの削除 
		
	 *X,Yの引数に特定の値を渡してハンドル渡すと
	   格納されたハンドルと同じ物を探し
	
	}

	よく考えたら X,Y座標も持つので構造体配列で・・・
 
*/

//modeは試験実装 仕様は問題があれば即時変更
// 0:全件表示  1:画像追加並び表示 2:リスト内の画像  
int dGraph(char* gHandle,int Gx,int Gy,int mode,int Gz){

	static GraphData graphD[GRAPHIC_MAX];
	
	static GraphData graphB[GRAPHIC_MAX];
	

	//int hdl=LoadGraph(gHandle);
	//DrawGraph(0,0,hdl,TRUE);
	//					ScreenFlip();
	//					WaitKey();
		 			 

				for(int i=0;i<GRAPHIC_MAX;i++){
					
					if(Gz==1){
						if(graphD[i].GraphHandle==0){
								if(gHandle!=0){
							
									graphD[i].GraphHandle=LoadGraph(gHandle);
								
										i=GRAPHIC_MAX;
								}
						}
					}

					if(Gz==2){
						if(graphB[i].GraphHandle==0){
								if(gHandle!=0){
							
									graphB[i].GraphHandle=LoadGraph(gHandle);
								
										i=GRAPHIC_MAX;
								}
						}
					}



				}
		 

			if(mode==0||mode==1){	 
				for(int i=0;i<GRAPHIC_MAX;i++){
					if(graphB[i].GraphHandle!=0){
						
						DrawGraph(graphB[i].GraphX,graphB[i].GraphY,graphB[i].GraphHandle,TRUE);
						 
					}
				}

				for(int i=0;i<GRAPHIC_MAX;i++){
					if(graphD[i].GraphHandle!=0){
						
						DrawGraph(graphD[i].GraphX,graphD[i].GraphY,graphD[i].GraphHandle,TRUE);
						 
					}
				}
			}
				
	

	//ScreenFlip();
	//WaitKey();

	return 1;
}

int Print(char* string){

	int buck;
	buck=LoadGraph("img/back.png");
	

	char KeyBuf[ 256 ] ;
	GetHitKeyStateAll( KeyBuf ) ;

	//↓テスト用仮
	//ClearDrawScreen() ;
	
	int x=40;
	int y=500;
	static char* string1;
	static char* string2;
	
	dGraph(0,0,0,0,0);//描画
	//ScreenFlip();



	SetDrawBlendMode( DX_BLENDMODE_ALPHA,  196 );		//ブレンドモードをα(128/255)に設定
	DrawGraph(0,400,buck,FALSE); //画像の描画
	SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );		//ブレンドモードをオフ
	
	ScreenFlip();
	 

	//ここに メッセージ ボックスの処理を追加

	if(string!=NULL){
		string2=string1;
		string1=string;
	}

	if(string2==NULL){
		string2="";
	}
	SetFontSize( 32 ) ;

	

	//DrawFormatString(x,y+26,GetColor(255,255,255),"%s",string2);

	

	DrawFormatString(x,y,GetColor(255,255,255),"%s",string1);
	
	for(;;){
		GetHitKeyStateAll( KeyBuf ) ;
		int key=WaitKey();


		if((key== KEY_INPUT_RETURN  )||(key==KEY_INPUT_SPACE )){
				break;
		}
	}
	
	return 0;
}
int Select(char *str1,char *str2,char *str3){
		
	int crs;
	int breaker=0;
	int key=0;
	int buck=LoadGraph("img/back.png");

	static int crsy=128;
	//char Key[ 256 ] ;

	int line1=128;
	int line2=192;
	int line3=256;
	  
	crs=LoadGraph("img/crs.png");
	

		ClearDrawScreen() ;	 
		//GetHitKeyStateAll( Key ) ;



	 


	for(;breaker==0;){

		dGraph(0,0,0,0,0);//描画

		SetDrawBlendMode( DX_BLENDMODE_ALPHA,  196 );		//ブレンドモードをα(128/255)に設定
		DrawGraph(0,100,buck,FALSE); //画像の描画
		SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );		//ブレンドモードをオフ

		
			DrawGraph(0,crsy,crs,TRUE);//カーソル描画

		DrawFormatString(100,line1,GetColor(255,255,255)," %s",str1);
		DrawFormatString(100,192,GetColor(255,255,255)," %s",str2);
		if(str3!=0){
			DrawFormatString(100,256,GetColor(255,255,255)," %s",str3);
		}
			 
		ScreenFlip();

		int key=WaitKey();
		
		ClearDrawScreen() ;

		if(key== KEY_INPUT_DOWN ){

				if(crsy==line2){
					if(str3!=0){
						crsy=line3;	
					}else{
						crsy=line1;
					}
				}else if(crsy==line1){
					crsy=192;
				}else if(crsy==line3){
					crsy=line1;
				}
			}
			if(key==KEY_INPUT_UP){
				if(crsy==line1){
					if(str3!=0){
						crsy=line3;
					}else{
						crsy=line2;
					}
				}else if(crsy==line2){
					crsy=line1;
				}else{
					crsy=line2;
				}
			}

			if(key==KEY_INPUT_RETURN){
				if(crsy==line1){
					return 1;
				}
				if(crsy==line2){
					return 2;
				}
				if(crsy==line3){
					return 3;
				}
				//return;
				breaker=1;

			}
	
			 
	}
	

	
	return 0;

}
//文字列分割(1行の最大文字数は SCRIPT_MAX_STRING_LENGTH)
//src : 分割したい文字列
//dest: 分割された文字列
//delim: 区切り文字
//splitNum : 最大分割数
void splitString(const char* src, char* dest[], const char* delim, int splitNum)
{
        int i;
        char* cp;
        char* copySrc;

		char *nexttoken;

        //元の文章をコピーする
        copySrc = (char*)malloc( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1);
		//↓危険↓ 第二引数 適当です →修正されました
        strncpy_s( copySrc,( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1), src, SCRIPT_MAX_STRING_LENGTH );
       // strncpy( copySrc, src, SCRIPT_MAX_STRING_LENGTH );
		// DrawFormatString(300,400,GetColor(255,255,0),"%d",(sizeof(int)* SCRIPT_MAX_STRING_LENGTH+1));
		cp = copySrc;


        //strtokを使って copySrc をdelim区切りで分割する
        for( i = 0; i < splitNum ; i++ ) {
                //分割対象文字列が無くなるまで分割
                if( (dest[i] = strtok_s(cp,delim,&nexttoken)) == NULL ) {
                        break;
                }
                //2回目にstrtokを呼び出す時は,cpをNULLにする
                cp = NULL;
        }
        //分割された文字列の最後の要素はNULLとしておく
        dest[i] = NULL;
		
}

int loadScript(const char* filename, ScriptInformation* scriptInfo)
{
        int pos;
        char c;
        //スクリプトファイル
        FILE* fp;
			
        //スクリプト情報を初期化
        memset( scriptInfo , 0, sizeof(ScriptInformation) );

        //スクリプトファイルを開く
	       // fp = 
		fopen_s(&fp,filename,"r");
        if( fp == NULL ) {
                //ファイル読み込みに失敗
              //  printf("スクリプト %s を読み込めませんでした\n", filename);
                return -1;
        }

        //script書き込み時に使用
        pos = 0;

        for( ;; ) {
                //一文字読み込み
                c = fgetc	( fp );
                //ファイルの終わりかどうか
                if( feof( fp ) ) {
                        break;
                }
				
				//文章先頭の空白部分を読み飛ばす
                while( (c == ' ' || c == '\t') && pos == 0 && !feof( fp ) ) {
                        c = fgetc( fp );
                }

                if( pos >= SCRIPT_MAX_STRING_LENGTH - 1 ) {
                        //1行の文字数が多すぎる
                        printf("error: 文字数が多すぎます (%d行目)", scriptInfo->currentLine );
                        return -1;
                }

                //改行文字が出てきた場合,次の行へ移動
                if( c == '\n' ) {
					//空行は読み飛ばす
                        if( pos == 0 ) {

                               continue;
                        }

                        //\0を文字列の最後に付ける
                        scriptInfo->script[ scriptInfo->currentLine ][ pos ] = '\0';
                        //次の行に移動
                        scriptInfo->currentLine++;
                        //書き込み位置を0にする
                        pos = 0;
                }else {
                        //書き込み
                        scriptInfo->script[ scriptInfo->currentLine ][ pos ] = c;
                        //文字書き込み位置をずらす
                        pos++;
                }
        }

		//最大行数
        scriptInfo->maxLineNumber = scriptInfo->currentLine;
        //読み込み中の行を0にする
        scriptInfo->currentLine = 0;
        //スクリプトファイル名を設定
        scriptInfo->filename = filename;

		//fclose(fp);

		return 0;
}
//指定したラベルがある行数を探す
//戻り値 正の数: 指定したラベルの行番号 -1: エラー
int searchScriptLabel(const char* label, ScriptInformation* scriptInfo)
{
        //分割されたスクリプト文
        char* message[100];
        //文字列分割時の区切り文字
        const char* delim = " ";
        int i, line = -1;

        for( i = 0; i < scriptInfo->maxLineNumber; i++ ) { 
                //スクリプト分割
                splitString( scriptInfo->script[i] , message, delim, 100 );

                //分割に失敗した場合
                if( message[0] == NULL ) {
                        return -1;
                }

                //指定したラベルを探す
                if( strncmp(message[0], "@@label", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                        if( strncmp(message[1], label, SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                                //指定したラベルが見つかった時
                                line = i;
                                break;
                        }
                }
        }

        return line;
}
int decodeScript(const char* scriptMessage, ScriptInformation* scriptInfo)
{

		//Select内戻り値
		int sel=0;
		//int i, selectNum, choice, line;
		int i,line;
        //分割されたスクリプト文
        char* message[100];
		 //条件分岐用
        char* selectMessage[10];
        char* select[10][2];
		memset(select,0,sizeof(select));
		 
        //文字列分割時の区切り文字
        const char* delim = " ";
		const char* selectDelim = "@@";
        
        //スクリプト分割
        splitString( scriptMessage, message, delim, 100 );

        //分割に失敗した場合
        if( message[0] == NULL ) {
                return 0;
        }
        //scriptの仕様
        //
        //@@message 文字列
        //--- 文字列をメッセージとして表示する
        //
        //@@drawgraph x y filename 
        //--- filenameで指定した画像ファイルを(x, y)の位置に表示

        //message[0] が @@message の時は,メッセージ命令が来たと判断
        if( strncmp(message[0], "@@message", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                //DrawFormatString(0,200,GetColor(255,255,0),"メッセージ : %s", message[1] );
				//DrawFormatString(0,200,GetColor(255,255,0),"%d", scriptInfo->currentLine);
				Print(message[1]);
				

                return 1;
        }else if(  strncmp(message[0], "@@drawgraph", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
               DrawFormatString(0,220,GetColor(255,255,0),"画像 %s 表示 -- x座標 : %d, y座標 : %d", 
                        message[3], atoi( message[1] ), atoi( message[2] ) );
				dGraph(message[3], atoi( message[1] ), atoi( message[2] ),1,atoi(message[4]));
			//	DrawFormatString(0,220,GetColor(255,255,0),"%d",atoi(message[4]));
			//ScreenFlip();
			//WaitKey();
                return 1;
        }else if( strncmp(message[0], "@@select", SCRIPT_MAX_STRING_LENGTH) == 0 ) {

                for(i = 0; message[i + 1] != NULL; i++ ) {
                        //条件を条件文章とジャンプラベルとに分ける
                        splitString( message[i + 1], selectMessage, selectDelim, 2 );
                        //条件文章
                        select[i][0] = selectMessage[0];//分岐文
				 
                        //ラベル
                        select[i][1] = selectMessage[1];//ラベル
					
                }
				//DrawFormatString(0,220,GetColor(255,255,0),"TEST");	 
			//	DrawFormatString(100,128,GetColor(255,255,255)," %s",(select[3][0]));
			//	ScreenFlip();
			//	WaitKey();				
				sel=Select((select[0][0]),(select[1][0]),(select[2][0]));//ここエラーです。
				//DrawFormatString(100,92,GetColor(255,0,0),"セレクトからの戻り値 %d",sel);
				//ScreenFlip();
				//WaitKey();
				for(int i=0;i<3;i++){
					if(i==sel-1){//ラベルが何行目にあるかを取得
						line = searchScriptLabel( select[i][1], scriptInfo );
						/*
						DrawFormatString(100,128,GetColor(255,255,255),"サーチスクプトラインからの戻り値 %d",line);
						DrawFormatString(100,164,GetColor(0,255,255),"カレントライン %d",scriptInfo->currentLine);
						DrawFormatString(100,200,GetColor(255,0,255),"iのループ %d 飛び先 %s",i,select[i][1]);
						ScreenFlip();
						WaitKey();
						*/
			          //指定したラベルが見つからなかった
				        if( line == -1 ) {
					        DrawFormatString(0,0,GetColor(255,0,0),"スクリプトエラー:指定したラベルが見つかりませんでした(%d行目)",
																										scriptInfo->currentLine );
							return 0;
						}
				       //読み取り中の行番号をラベルの行に移動
					    scriptInfo->currentLine = line;
						//DrawFormatString(0,120,GetColor(255,0,255),"カレントライン %d ",scriptInfo->currentLine);
						return 1;				
					}
				}
                //分岐数
				 
               // selectNum = i;

				if(sel!=0){
			 
					return 1;
				}
			 
				return 0;

        }else if( strncmp(message[0], "@@goto", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
				//DrawFormatString(0,26,GetColor(255,0,0)," ");
                //ラベルが何行目にあるかを取得
                line = searchScriptLabel( message[1], scriptInfo );
                //指定したラベルが見つからなかった
                if( line == -1 ) {
                        DrawFormatString(0,0,GetColor(255,0,0),"スクリプトエラー:指定したラベルが見つかりませんでした(%d行目)",
                                scriptInfo->currentLine );
                        return 0;
                }
                //読み取り中の行番号をラベルの行に移動
                scriptInfo->currentLine = line;
				//DrawFormatString(0,120,GetColor(255,0,255),"カレントライン %d ",scriptInfo->currentLine);
				return 1;
        }else if( strncmp(message[0], "@@label", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                //ラベルの場合はなにもしない
				return 1;
			
        }else {
         //      DrawFormatString(0,120,GetColor(255,0,255),"スクリプトエラー(%d行目)\n", scriptInfo->currentLine);
		//	   WaitKey();
                return -1;
        }

        //注意点: エラー処理を行っていない ( message[2] )が存在しなかった場合など
        //例えば messageの全要素を全てNULL で埋めておき,message[2] がNULLの場合は
        //エラー処理を行うなどの手が考えられる

        // DrawFormatString(0,200,GetColor(255,255,0),"sitataka");
        return 0;
}
void printElements(char* elem[])
{
        int i;
        for(i=0;elem[i]!= NULL;i++){
                 DrawFormatString(0,i*16+200,GetColor(255,255,0),"%d : %s", i + 1, elem[i] );
        }
}

int main()
{
		
        //int i;
		//int line;
		int checker=1;
        ScriptInformation script;
		//char* dest[100];
        const char* delim = " ";


        loadScript( "test.txt", &script );

		for(;;script.currentLine++ ){
			ProcessMessage();

			//gpUpdateKey();
			ClearDrawScreen();

			//↓スクリプト解析 分岐
			checker=decodeScript( script.script[script.currentLine],&script );
			/*
			if(checker==0){

				script.currentLine--;
			}else if(checker==-1){
				break;
			
			}
			*/
		};	
		//line = searchScriptLabel("TEST", &script );
		//DrawFormatString(0,300,GetColor(255,0,255)," %d ",  script.currentLine);
		
        return 0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

	SetGraphMode( 800 , 600 , 32 ) ;//ウィンドウサイズ

	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
   
	

	main();


	DxLib_End();
	
	return 0;
} 


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#2

投稿記事 by softya(ソフト屋) » 14年前

基本骨格として、足りない部分があります。

こちらを参考にしていただきたいのですが、
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/01_09.html

ProcessMessage()の戻り値が0出はない場合はwhileループを抜ける必要があります。
現状抜けないのでプログラムが終了しないのだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

奥兵

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#3

投稿記事 by 奥兵 » 14年前

とりあえずメインとなるループの条件にProcessMessage()==0を仕込んでみましたが、実行してみるとやはりプロセスが残ってしまいます。

コード:

int main()
{
		
        //int i;
		//int line;
		int checker=1;
        ScriptInformation script;
		//char* dest[100];
        const char* delim = " ";


        loadScript( "test.txt", &script );
                //↓ここです
		for(;ProcessMessage()==0;script.currentLine++ ){
			 
			//gpUpdateKey();
			ClearDrawScreen();

			//↓スクリプト解析 分岐
			checker=decodeScript( script.script[script.currentLine],&script );
			/*
			if(checker==0){

				script.currentLine--;
			}else if(checker==-1){
				break;
			
			}
			*/
		};	
		//line = searchScriptLabel("TEST", &script );
		//DrawFormatString(0,300,GetColor(255,0,255)," %d ",  script.currentLine);
		
        return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#4

投稿記事 by softya(ソフト屋) » 14年前

もう一箇所、問題を見つけました。

for(;breaker==0;){
でループしていますが、こういうループはしてはいけません。
必ずmainに戻るようにしてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

奥兵

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#5

投稿記事 by 奥兵 » 14年前

素早い御返事ありがとうございます。
ご指摘いただいた部分を直してみたのですが、やはりプロセスが残ってしまいました。

コード:

#include <stdio.h>
#include <string.h>

#include "DxLib.h"

#define SCRIPT_MAX_LINE 1000
#define SCRIPT_MAX_STRING_LENGTH 300
#define GRAPHIC_MAX 10

//#define Choice1 300
//#define Choice2 332
//#define Choice3 
//#define Choice4

int Key[256];

struct GraphData{
		int GraphHandle;
		int GraphX;
		int GraphY;
};

typedef struct ScriptInformation_tag {
        int maxLineNumber;                      //スクリプト行数
        int currentLine;                        //現在何行目を実行しているか
        const char* filename;           //ファイル名
        char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
} ScriptInformation;



int gpUpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 0にする
                }
        }
        return 0;
}
//handle
//graphic 

/*
↓グラフィックをいくらか貯めて特定の引数で呼ばれた場合一括して表示
 上限は適当に10か20程度で
 
	グラフィックハンドルが渡されたら内部の配列に収納。
	
	特定の方法で内部の配列内のハンドルをクリア

	方法は適当に考えて。
	↑ for example {

	 *引数を追加して、モード分け
	 仮なので 魔法の数字で ぽぽぽぽ~ん
	 0 配列内容表示 1 配列へハンドル渡して表示 2  
	 -1 所定のハンドルの削除 
		
	 *X,Yの引数に特定の値を渡してハンドル渡すと
	   格納されたハンドルと同じ物を探し
	
	}

	よく考えたら X,Y座標も持つので構造体配列で・・・
 
*/

//modeは試験実装 仕様は問題があれば即時変更
// 0:全件表示  1:画像追加並び表示 2:リスト内の画像  
int dGraph(char* gHandle,int Gx,int Gy,int mode,int Gz){

	static GraphData graphD[GRAPHIC_MAX];
	
	static GraphData graphB[GRAPHIC_MAX];
	

	//int hdl=LoadGraph(gHandle);
	//DrawGraph(0,0,hdl,TRUE);
	//					ScreenFlip();
	//					WaitKey();
		 			 

				for(int i=0;i<GRAPHIC_MAX;i++){
					
					if(Gz==1){
						if(graphD[i].GraphHandle==0){
								if(gHandle!=0){
							
									graphD[i].GraphHandle=LoadGraph(gHandle);
								
										i=GRAPHIC_MAX;
								}
						}
					}

					if(Gz==2){
						if(graphB[i].GraphHandle==0){
								if(gHandle!=0){
							
									graphB[i].GraphHandle=LoadGraph(gHandle);
								
										i=GRAPHIC_MAX;
								}
						}
					}



				}
		 

			if(mode==0||mode==1){	 
				for(int i=0;i<GRAPHIC_MAX;i++){
					if(graphB[i].GraphHandle!=0){
						
						DrawGraph(graphB[i].GraphX,graphB[i].GraphY,graphB[i].GraphHandle,TRUE);
						 
					}
				}

				for(int i=0;i<GRAPHIC_MAX;i++){
					if(graphD[i].GraphHandle!=0){
						
						DrawGraph(graphD[i].GraphX,graphD[i].GraphY,graphD[i].GraphHandle,TRUE);
						 
					}
				}
			}
				
	

	//ScreenFlip();
	//WaitKey();

	return 1;
}

int Print(char* string){

	int buck;
	buck=LoadGraph("img/back.png");
	

	char KeyBuf[ 256 ] ;
	GetHitKeyStateAll( KeyBuf ) ;

	//↓テスト用仮
	//ClearDrawScreen() ;
	
	int x=40;
	int y=500;
	static char* string1;
	static char* string2;
	
	dGraph(0,0,0,0,0);//描画
	//ScreenFlip();



	SetDrawBlendMode( DX_BLENDMODE_ALPHA,  196 );		//ブレンドモードをα(128/255)に設定
	DrawGraph(0,400,buck,FALSE); //画像の描画
	SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );		//ブレンドモードをオフ
	
	ScreenFlip();
	 

	//ここに メッセージ ボックスの処理を追加

	if(string!=NULL){
		string2=string1;
		string1=string;
	}

	if(string2==NULL){
		string2="";
	}
	SetFontSize( 32 ) ;

	

	//DrawFormatString(x,y+26,GetColor(255,255,255),"%s",string2);

	

	DrawFormatString(x,y,GetColor(255,255,255),"%s",string1);
	
	for(;;){
		GetHitKeyStateAll( KeyBuf ) ;
		int key=WaitKey();


		if((key== KEY_INPUT_RETURN  )||(key==KEY_INPUT_SPACE )){
				break;
		}
	}
	
	return 0;
}
int Select(char *str1,char *str2,char *str3){
		
	int crs;
	int breaker=0;
	//int key=0;
	int buck=LoadGraph("img/back.png");

	static int crsy=128;
	//char Key[ 256 ] ;

	int line1=128;
	int line2=192;
	int line3=256;
	  
	crs=LoadGraph("img/crs.png");
	

		ClearDrawScreen() ;	 
		//GetHitKeyStateAll( Key ) ;



	 


//	for(;breaker==0;){

		dGraph(0,0,0,0,0);//描画

		SetDrawBlendMode( DX_BLENDMODE_ALPHA,  196 );		//ブレンドモードをα(128/255)に設定
		DrawGraph(0,100,buck,FALSE); //画像の描画
		SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );		//ブレンドモードをオフ

		
			DrawGraph(0,crsy,crs,TRUE);//カーソル描画

		DrawFormatString(100,line1,GetColor(255,255,255)," %s",str1);
		DrawFormatString(100,192,GetColor(255,255,255)," %s",str2);
		if(str3!=0){
			DrawFormatString(100,256,GetColor(255,255,255)," %s",str3);
		}
			 
		ScreenFlip();

		int key=WaitKey();
		
		ClearDrawScreen() ;

		if(key== KEY_INPUT_DOWN ){

				if(crsy==line2){
					if(str3!=0){
						crsy=line3;	
					}else{
						crsy=line1;
					}
				}else if(crsy==line1){
					crsy=192;
				}else if(crsy==line3){
					crsy=line1;
				}
			}
			if(key==KEY_INPUT_UP){
				if(crsy==line1){
					if(str3!=0){
						crsy=line3;
					}else{
						crsy=line2;
					}
				}else if(crsy==line2){
					crsy=line1;
				}else{
					crsy=line2;
				}
			}

			if(key==KEY_INPUT_RETURN){
				if(crsy==line1){
					return 1;
				}
				if(crsy==line2){
					return 2;
				}
				if(crsy==line3){
					return 3;
				}
				//return;
				breaker=1;

			}
	
			 
//	}
	

	
	return 0;

}
//文字列分割(1行の最大文字数は SCRIPT_MAX_STRING_LENGTH)
//src : 分割したい文字列
//dest: 分割された文字列
//delim: 区切り文字
//splitNum : 最大分割数
void splitString(const char* src, char* dest[], const char* delim, int splitNum)
{
        int i;
        char* cp;
        char* copySrc;

		char *nexttoken;

        //元の文章をコピーする
        copySrc = (char*)malloc( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1);
		//↓危険↓ 第二引数 適当です →修正されました
        strncpy_s( copySrc,( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1), src, SCRIPT_MAX_STRING_LENGTH );
       // strncpy( copySrc, src, SCRIPT_MAX_STRING_LENGTH );
		// DrawFormatString(300,400,GetColor(255,255,0),"%d",(sizeof(int)* SCRIPT_MAX_STRING_LENGTH+1));
		cp = copySrc;


        //strtokを使って copySrc をdelim区切りで分割する
        for( i = 0; i < splitNum ; i++ ) {
                //分割対象文字列が無くなるまで分割
                if( (dest[i] = strtok_s(cp,delim,&nexttoken)) == NULL ) {
                        break;
                }
                //2回目にstrtokを呼び出す時は,cpをNULLにする
                cp = NULL;
        }
        //分割された文字列の最後の要素はNULLとしておく
        dest[i] = NULL;
		
}

int loadScript(const char* filename, ScriptInformation* scriptInfo)
{
        int pos;
        char c;
        //スクリプトファイル
        FILE* fp;
			
        //スクリプト情報を初期化
        memset( scriptInfo , 0, sizeof(ScriptInformation) );

        //スクリプトファイルを開く
	       // fp = 
		fopen_s(&fp,filename,"r");
        if( fp == NULL ) {
                //ファイル読み込みに失敗
              //  printf("スクリプト %s を読み込めませんでした\n", filename);
                return -1;
        }

        //script書き込み時に使用
        pos = 0;

        for( ;; ) {
                //一文字読み込み
                c = fgetc	( fp );
                //ファイルの終わりかどうか
                if( feof( fp ) ) {
                        break;
                }
				
				//文章先頭の空白部分を読み飛ばす
                while( (c == ' ' || c == '\t') && pos == 0 && !feof( fp ) ) {
                        c = fgetc( fp );
                }

                if( pos >= SCRIPT_MAX_STRING_LENGTH - 1 ) {
                        //1行の文字数が多すぎる
                        printf("error: 文字数が多すぎます (%d行目)", scriptInfo->currentLine );
                        return -1;
                }

                //改行文字が出てきた場合,次の行へ移動
                if( c == '\n' ) {
					//空行は読み飛ばす
                        if( pos == 0 ) {

                               continue;
                        }

                        //\0を文字列の最後に付ける
                        scriptInfo->script[ scriptInfo->currentLine ][ pos ] = '\0';
                        //次の行に移動
                        scriptInfo->currentLine++;
                        //書き込み位置を0にする
                        pos = 0;
                }else {
                        //書き込み
                        scriptInfo->script[ scriptInfo->currentLine ][ pos ] = c;
                        //文字書き込み位置をずらす
                        pos++;
                }
        }

		//最大行数
        scriptInfo->maxLineNumber = scriptInfo->currentLine;
        //読み込み中の行を0にする
        scriptInfo->currentLine = 0;
        //スクリプトファイル名を設定
        scriptInfo->filename = filename;

		fclose(fp);

		return 0;
}
//指定したラベルがある行数を探す
//戻り値 正の数: 指定したラベルの行番号 -1: エラー
int searchScriptLabel(const char* label, ScriptInformation* scriptInfo)
{
        //分割されたスクリプト文
        char* message[100];
        //文字列分割時の区切り文字
        const char* delim = " ";
        int i, line = -1;

        for( i = 0; i < scriptInfo->maxLineNumber; i++ ) { 
                //スクリプト分割
                splitString( scriptInfo->script[i] , message, delim, 100 );

                //分割に失敗した場合
                if( message[0] == NULL ) {
                        return -1;
                }

                //指定したラベルを探す
                if( strncmp(message[0], "@@label", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                        if( strncmp(message[1], label, SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                                //指定したラベルが見つかった時
                                line = i;
                                break;
                        }
                }
        }

        return line;
}
int decodeScript(const char* scriptMessage, ScriptInformation* scriptInfo)
{

		//Select内戻り値
		int sel=0;
		//int i, selectNum, choice, line;
		int i,line;
        //分割されたスクリプト文
        char* message[100];
		 //条件分岐用
        char* selectMessage[10];
        char* select[10][2];
		memset(select,0,sizeof(select));
		 
        //文字列分割時の区切り文字
        const char* delim = " ";
		const char* selectDelim = "@@";
        
        //スクリプト分割
        splitString( scriptMessage, message, delim, 100 );

        //分割に失敗した場合
        if( message[0] == NULL ) {
                return 0;
        }
        //scriptの仕様
        //
        //@@message 文字列
        //--- 文字列をメッセージとして表示する
        //
        //@@drawgraph x y filename 
        //--- filenameで指定した画像ファイルを(x, y)の位置に表示

        //message[0] が @@message の時は,メッセージ命令が来たと判断
        if( strncmp(message[0], "@@message", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                //DrawFormatString(0,200,GetColor(255,255,0),"メッセージ : %s", message[1] );
				//DrawFormatString(0,200,GetColor(255,255,0),"%d", scriptInfo->currentLine);
				Print(message[1]);
				

                return 1;
        }else if(  strncmp(message[0], "@@drawgraph", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
               DrawFormatString(0,220,GetColor(255,255,0),"画像 %s 表示 -- x座標 : %d, y座標 : %d", 
                        message[3], atoi( message[1] ), atoi( message[2] ) );
				dGraph(message[3], atoi( message[1] ), atoi( message[2] ),1,atoi(message[4]));
			//	DrawFormatString(0,220,GetColor(255,255,0),"%d",atoi(message[4]));
			//ScreenFlip();
			//WaitKey();
                return 1;
        }else if( strncmp(message[0], "@@select", SCRIPT_MAX_STRING_LENGTH) == 0 ) {

                for(i = 0; message[i + 1] != NULL; i++ ) {
                        //条件を条件文章とジャンプラベルとに分ける
                        splitString( message[i + 1], selectMessage, selectDelim, 2 );
                        //条件文章
                        select[i][0] = selectMessage[0];//分岐文
				 
                        //ラベル
                        select[i][1] = selectMessage[1];//ラベル
					
                }
				//DrawFormatString(0,220,GetColor(255,255,0),"TEST");	 
			//	DrawFormatString(100,128,GetColor(255,255,255)," %s",(select[3][0]));
			//	ScreenFlip();
			//	WaitKey();				
				sel=Select((select[0][0]),(select[1][0]),(select[2][0]));
				if(sel==0){
					return 2;
				}
				//DrawFormatString(100,92,GetColor(255,0,0),"セレクトからの戻り値 %d",sel);
				//ScreenFlip();
				//WaitKey();
				for(int i=0;i<3;i++){
					if(i==sel-1){//ラベルが何行目にあるかを取得
						line = searchScriptLabel( select[i][1], scriptInfo );
						/*
						DrawFormatString(100,128,GetColor(255,255,255),"サーチスクプトラインからの戻り値 %d",line);
						DrawFormatString(100,164,GetColor(0,255,255),"カレントライン %d",scriptInfo->currentLine);
						DrawFormatString(100,200,GetColor(255,0,255),"iのループ %d 飛び先 %s",i,select[i][1]);
						ScreenFlip();
						WaitKey();
						*/
			          //指定したラベルが見つからなかった
				        if( line == -1 ) {
					        DrawFormatString(0,0,GetColor(255,0,0),"スクリプトエラー:指定したラベルが見つかりませんでした(%d行目)",
																										scriptInfo->currentLine );
							return 0;
						}
				       //読み取り中の行番号をラベルの行に移動
					    scriptInfo->currentLine = line;
						//DrawFormatString(0,120,GetColor(255,0,255),"カレントライン %d ",scriptInfo->currentLine);
						return 1;				
					}
				}
                //分岐数
				 
               // selectNum = i;

				if(sel!=0){
			 
					return 1;
				}
			 
				return 0;

        }else if( strncmp(message[0], "@@goto", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
				//DrawFormatString(0,26,GetColor(255,0,0)," ");
                //ラベルが何行目にあるかを取得
                line = searchScriptLabel( message[1], scriptInfo );
                //指定したラベルが見つからなかった
                if( line == -1 ) {
                        DrawFormatString(0,0,GetColor(255,0,0),"スクリプトエラー:指定したラベルが見つかりませんでした(%d行目)",
                                scriptInfo->currentLine );
                        return 0;
                }
                //読み取り中の行番号をラベルの行に移動
                scriptInfo->currentLine = line;
				//DrawFormatString(0,120,GetColor(255,0,255),"カレントライン %d ",scriptInfo->currentLine);
				return 1;
        }else if( strncmp(message[0], "@@label", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
                //ラベルの場合はなにもしない
				return 1;
			
        }else {
         //      DrawFormatString(0,120,GetColor(255,0,255),"スクリプトエラー(%d行目)\n", scriptInfo->currentLine);
		//	   WaitKey();
                return -1;
        }

        //注意点: エラー処理を行っていない ( message[2] )が存在しなかった場合など
        //例えば messageの全要素を全てNULL で埋めておき,message[2] がNULLの場合は
        //エラー処理を行うなどの手が考えられる

        // DrawFormatString(0,200,GetColor(255,255,0),"sitataka");
        return 0;
}
void printElements(char* elem[])
{
        int i;
        for(i=0;elem[i]!= NULL;i++){
                 DrawFormatString(0,i*16+200,GetColor(255,255,0),"%d : %s", i + 1, elem[i] );
        }
}

int main()
{
		
        //int i;
		//int line;
		int checker=1;
        ScriptInformation script;
		//char* dest[100];
        const char* delim = " ";


        loadScript( "test.txt", &script );

		for(;ProcessMessage()==0&&checker==1;script.currentLine++ ){
			 
			//gpUpdateKey();
			ClearDrawScreen();

			//↓スクリプト解析 分岐
			checker=decodeScript( script.script[script.currentLine],&script );
			
			if(checker==2){
				script.currentLine--;
				checker=1;
			}
			//else if(checker==-1){
			//	break;
			
			//}
			
		};	
		//line = searchScriptLabel("TEST", &script );
		//DrawFormatString(0,300,GetColor(255,0,255)," %d ",  script.currentLine);
		
        return 0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

	SetGraphMode( 800 , 600 , 32 ) ;//ウィンドウサイズ

	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
   
	

	main();


	DxLib_End();
	
	return 0;
} 

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#6

投稿記事 by softya(ソフト屋) » 14年前

このループで待っているのが原因ですね。

コード:

    for(;;){
        GetHitKeyStateAll( KeyBuf ) ;
        int key=WaitKey();
 
 
        if((key== KEY_INPUT_RETURN  )||(key==KEY_INPUT_SPACE )){
                break;
        }
    }
かならず、mainのfor(;ProcessMessage()==0&&checker==1;script.currentLine++ ){に戻る必要があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

奥兵

Re: .exe を開いて書き込むことができませんと言うエラーが直せません。

#7

投稿記事 by 奥兵 » 14年前

ご指摘いただいた部分を直したら治りました。
何度も素早く教えていただいてありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る