【緊急】【サウンドノベル】順番にファイルを読み込む方法

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

【緊急】【サウンドノベル】順番にファイルを読み込む方法

#1

投稿記事 by かけだしプログラマー » 15年前

はじめまして、龍神録プログラミングの館でプログラミングを勉強しています。なにかしらバグや動作不良が起こっても自己解決してきましたが、今回どうやってもうまくいかないので質問させていただきます。

龍神録プログラミングの支館さんの『サウンドノベルシステムを実装しよう』で特定のCSVファイルをvoid fantasy_check()で読み込んでいますが、読み込む回数分だけ関数を用意したくないのでファイルパスを char str[64]に格納して読み込ませたいと思っています。
具体的にはnovel_0.csvのファイルを読み込みノベル処理が終了し、次回読み込み時にはnovel_1.csvを読み込むようにしてやりたいのです。
丁度龍神録プログラミング48章のBGM読み込みのような感じです。。

何度か試したもののポインターに関する知識があやふやなせいかなかなかうまくいきません。
現在のコードを貼り付けておきますのでどなたか回答おねがいします(__)

あと関数の引数はポインター変数を必ず渡さないといけないのでしょうか?
&でアドレスを直で渡すのではいけないのでしょうか、まだ勉強不足なので基礎が微妙です。

-------------------------------------------------------------------------------------------
【目的】
strにファイルパスを格納して、ノベル処理終了と同時にflagのカウントに対応したファイルを読み込ませる。

【環境】
Microsoft Visual C++ 2010 Express
DXライブラリ ver 3.02

-------------------------------------------------------------------------------------------

コード:

#include "../include/GV.h"

char str[64];				// アドレス格納用変数
int flag = 0;				//	フラグ

//ストーリーデータの読み込み
void fantasy_load(const char *str)
{
    int i, n, s;                // カウンタ
    int num = 0;                // カウンタ
    int fp;                     // ファイルポインタ
    char buffer[256];           // 文字バッファ
    char token[10][256];        // 文字バッファ

    // ファイルオープン
    if( ( fp = FileRead_open( str ) ) == NULL ) {
        // エラー処理
    }

    // ファイル終端まで読み込む
    while(FileRead_eof(fp) == 0 && num < 49) {
        
        // 1行読み込む
        if( FileRead_gets( buffer, 256, fp ) == -1 )
            continue;

        // 先頭文字が「/」ならスキップ
        if( buffer[0] == '/' )
            continue;

        // CSV形式ファイル分割
        n = 0; s = 0;

        for(i = 0; i < 256; i++) {
            if( buffer[i] == ',' ) {
                token[n][s] = '\0';
                s = 0;
                n++;
                continue;
            }

            if( buffer[i] == '\0' ) {
                token[n][s] = '\0';
                n++;
                break;
            }

            token[n][s] = buffer[i];
            s++;
        }

        // 種類
        story[num].type = atoi(token[0]);
        // 名前
        strcpy_s(story[num].name, 50, token[1]);
        // 表情
        story[num].look = atoi( token[2] );
        // 本文
        strcpy_s(story[num].story, 256, token[3]);
        num++;
    }

    story[num].story[0] = '\0';
    
    FileRead_close(fp);
}

void fantasy_disp()
{
    static int num;
    static int len;
    
    char buf[256];
    
    strcpy_s(buf, 256, story[num].story);

    if(CheckStatePad(configpad.shot) == 1){
        if( buf[len] == '\0' )
        {
            len  = 0;
            ++num;
        }
    }

    if(CheckStatePad(configpad.bom)%5 == 4) {
            len  = 0;
            ++num;
    }
    
    // 本文が無かったら終了
    if(buf[0] == '\0') {
        num = 0;
        len = 0;
        func_state = 100;
        
        return;
    }


    for(int i = 0; i < 2 && buf[len] != '\0'; ++i) {
        switch( buf[len] ) {
        case '\0':
            break;

        default:
            ++len;
            break;
        }
    }

    buf[len] = '\0';
    
    /* ▼ ラノベ描画 */
    // 背景を暗く
    SetDrawBlendMode(DX_BLENDMODE_ALPHA , 80);
    DrawBox(FX , FY , FX+FMX , FY+FMY , color[1] , TRUE);
    DrawBox(FX , 410 , FX+FMX , FY+FMY , color[0] , TRUE);
    SetDrawBlendMode(DX_BLENDMODE_NOBLEND , 0);

	//画像
	if (story[num].type==0)
    DrawGraph(  FX, FMY-250 ,img_cutin[0],TRUE);
    if (story[num].type==1)
    DrawGraph(  FX + 20, FMY-250 ,img_cutin[1],TRUE);

    // 名前
    DrawFormatStringToHandle(FX + 20, FMY - 30, color[0] , font[0], story[num].name);
    // 本文
    DrawFormatStringToHandle(FX + 30 , FMY - 10, color[0] , font[0], buf);
}

void enter_story(){
	 sprintf(str,"../dat/csv/novel/novel_%d.csv",flag);
}
//ノベル処理制御
void fantasy_check(){
    //ステージカウント1649の時に指定のファイルを読み込みノベル処理へ
    if(stage_count == boss.appear_count[flag]) {    //カウント1649
		enter_story();
        fantasy_load(str); //指定のファイルを読み込んで
        func_state = 103;             //ノベル処理に移行する
    }
	flag++;                           //ノベル処理終了後カウントアップ
} 


アバター
bitter_fox
記事: 607
登録日時: 15年前
住所: 大阪府

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#2

投稿記事 by bitter_fox » 15年前

かけだしプログラマー さんが書きました: 何度か試したもののポインターに関する知識があやふやなせいかなかなかうまくいきません。
何がうまくいかないのかが解らないので、詳細にお願いします。

また、掲載していただいたプログラムが部分的すぎて全体の流れが解らないので、どういった流れで動くのかを教えていただけますでしょうか?

かけだしプログラマー

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#3

投稿記事 by かけだしプログラマー » 15年前

言葉足らずですみませんでした、プログラムのベースは龍神録プログラミングで配布されているものに支館さんで掲載されていたコードを追加したものです。

実行しようとしてるのはステージカウントとdefine.cppで指定したボス出現時間が同じであれば、str配列にcsvのファイルパスをコピーしてcsvに記述されているノベル処理を行うといったものです。

うまくいかない点はノベル処理が開始されないといったところです。ビルドした際にはエラーは出ませんがノベル処理が実行されません。
試しに132行目のstr配列にコピーという部分を削除、140行目にファイルパス自体を書き込むとノベル処理が実行されました。

かけだしプログラマー

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#4

投稿記事 by かけだしプログラマー » 15年前

>> 実行しようとしてるのはステージカウントとdefine.cppで指定したボス出現時間が同じであれば、str配列にcsvのファイルパスをコピーしてcsvに記述されているノベル処理を行うといったものです。


define.cppではなくini.cppの初期化関数内での指定でした。

アバター
bitter_fox
記事: 607
登録日時: 15年前
住所: 大阪府

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#5

投稿記事 by bitter_fox » 15年前

これって、fantasy_load関数が何回も呼ばれる構造ですか?

もしそうなのであれば、(そうでなくても一応やってみてくださいw)

コード:

void fantasy_load(const char *str)
{
    int num = 0;                // カウンタ
    // 略
}
ここのnumを

コード:

static int num = 0;
にしてみてください。

[hr][追記]
fantasy_loadのエラー処理も実装しておいてください。(returnだけでも実装しておいてください。)

かけだしプログラマー

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#6

投稿記事 by かけだしプログラマー » 15年前

返事が遅れて申し訳ありません。

時間をおいて冷静に考えた結果自己解決できました。
グローバル変数のflagを新たに追加し、ノベル処理が終わるごとにカウントアップすることで順番どおりにファイルを読み込むことができました。

bitter_foxさんの言うとおりstaticの追加・エラー処理も実装しました。
遅くまでお付き合いくださってありがとうございます。

またなにか不明な点がありましたら質問させていただきます。

伊集院電一郎

Re: 【緊急】【サウンドノベル】順番にファイルを読み込む方法

#7

投稿記事 by 伊集院電一郎 » 15年前

char strがグローバル変数になってるので
7行目→void fantasy_load();
140行目→ fantasy_load();
定義の部分→void fantasy_load();
とすればできると思います

char strをローカル変数としてポインタ使う場合は
3行目消す
void enter_story(){
char str[64];
sprintf(str,"../dat/csv/novel/novel_%d.csv",flag);
fantasy_load(&str);
}
16行目→ if( ( fp = FileRead_open( *str ) ) == NULL ) {

て感じで

閉鎖

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