引数を定数に

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

引数を定数に

#1

投稿記事 by リアカー » 3年前

質問です。DXライブラリを使用してサウンドノベル風の文字表示ができるプログラムを作りたいと思っています。
汎用的にこれを使えるようにするため、下記コード(http://dxlib.o.oo7.jp/dxprogram.html 参照)の
MOJI_SIZE と STRBUF_WINDTH と STRBUF_HEIGHT の値を
引数によって変えたいと思っています(メイン関数は自作関数にします)

しかし、それらは#defineによって定義されているので、値を引数によって変えられません。
また、その定数は配列の添字に使ってることもあり、なかなかうまくいきません。

ちなみにグローバル変数をなくすため、無理やりKaigyou関数をメインの中に入れて、
StringBufはmallocを使って動的確保をしようとも試しましたが、”char * は int * 型に変換できない”、大量に”無効な間接参照”などとエラーをはかれられました
(自分がmallocに関して知識が浅薄すぎただけかもしれませんが…)

どうすれば解決できるでしょうか。よろしくお願いします。言葉足らずでしたらもうしわけありません。

環境:windows 10 , コンパイラ:BCCDevoper

コード:

#include "DxLib.h"
#include <math.h>

// 文字のサイズ
#define MOJI_SIZE 24

// 仮想テキストバッファの横サイズ縦サイズ
#define STRBUF_WIDTH	24
#define STRBUF_HEIGHT	20

char StringBuf[ STRBUF_HEIGHT ][ STRBUF_WIDTH * 2 + 1 ] ;	// 仮想テキストバッファ
int CursorX , CursorY ;						// 仮想画面上での文字表示カーソルの位置
int SP , CP ;							// 参照する文字列番号と文字列中の文字ポインタ
int EndFlag ;							// 終了フラグ
int KeyWaitFlag ;						// ボタン押し待ちフラグ
int Count ;							// フレームカウンタ

char String[][ 256 ] =
{
	" ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組む",
	"ことである。B" ,
	"@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B",
	"変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか",
	"なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B" ,
	"C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が",
	"つけば後はそこからは掘り下げ、広げていけば良いわけで、Bプログラムの参考書を",
	"読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム",
	"を打ってみることが大事である。E",
} ;

void Kaigyou( void ) ;		// テキストバッファの改行処理関数


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						 LPSTR lpCmdLine, int nCmdShow ) //ここは自作関数化する
{
	char OneMojiBuf[ 3 ] ;	// 1文字分一時記憶配列
	int i , j ;

	SetGraphMode( 640 , 480 , 16 ) ;
	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;				// エラーが起きたら直ちに終了
	}

	// 描画位置の初期位置セット
	CursorX = 0 ;
	CursorY = 0 ;
	
	// 参照文字位置をセット
	SP = 0 ;	// 1行目の
	CP = 0 ;	// 0文字

	// フォントのサイズセット
	SetFontSize( MOJI_SIZE ) ;

	// 描画先を裏画面にセット
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// フレームカウンタ初期化
	Count = 0 ;

	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// サウンドノベル風文字列描画処理を行う
		// ただし終了フラグが1だった場合は処理をしない
		if( EndFlag == 0 )
		{
			char  Moji ;

			// ボタン押し待ちフラグがたっていた場合はボタンが押されるまでここで終了
			if( KeyWaitFlag == 1 )
			{
				if( ProcessMessage() == 0 && CheckHitKeyAll() != 0 ) 
				{
					// ボタンが押されていたら解除
					KeyWaitFlag = 0 ;
				}
			}
			else
			{
				// 文字の描画
				Moji = String[ SP ][ CP ] ;
				switch( Moji )
				{
				case '@' :	// 改行文字

					// 改行処理および参照文字位置を一つ進める
					Kaigyou() ;
					CP ++ ;

					break ;

				case 'B' :	// ボタン押し待ち文字

					// ボタンが離されるまで待つ
					while( ProcessMessage() == 0 && CheckHitKeyAll() != 0 ){}

					// ボタン押し待ちフラグをたてる
					KeyWaitFlag = 1 ;
					CP ++ ;

					break ;

				case 'E' :	// 終了文字

					// 終了フラグを立てるおよび参照文字位置を一つ進める
					EndFlag = 1 ;
					CP ++ ;

					break ;

				case 'C' :	// クリア文字

					// 仮想テキストバッファを初期化して描画文字位置を初期位置に戻すおよび参照文字位置を一つ進める
					for( i = 0 ; i < STRBUF_HEIGHT ; i ++ )
					{
						for( j = 0 ; j < STRBUF_WIDTH * 2 ; j ++ )
						{
							StringBuf[ i ][ j ] = 0 ;
						}
					}

					CursorY = 0 ;
					CursorX = 0 ;
					CP ++ ;

					break ;

				default :	// その他の文字

					// 1文字分抜き出す
					OneMojiBuf[ 0 ] = String[ SP ][ CP ] ;
					OneMojiBuf[ 1 ] = String[ SP ][ CP + 1 ] ;
					OneMojiBuf[ 2 ] = '\0' ;

					// 1文字テキストバッファに代入
					StringBuf[ CursorY ][ CursorX * 2 ] = OneMojiBuf[ 0 ] ;
					StringBuf[ CursorY ][ CursorX * 2 + 1 ] = OneMojiBuf[ 1 ] ;

					// 参照文字位置を2バイト勧める
					CP += 2 ;

					// カーソルを一文字文進める
					CursorX ++ ;

					// テキストバッファ横幅からはみ出たら改行する
					if( CursorX >= STRBUF_WIDTH ) Kaigyou() ;

					break ;
				}

				// 参照文字列の終端まで行っていたら参照文字列を進める
				if( String[ SP ][ CP ] == '\0' )
				{
					SP ++ ;
					CP = 0 ;
				}
			}
		}

		// 画面のクリア
		ClearDrawScreen() ;

		// 背景エフェクトの描画
		{
			int Color ;

			Color = ( int )( sin( Count / 100.0 ) * 80.0 + 125.0 ) ;
			DrawBox( 0 , 0 , 640 , 480 , GetColor( Color , 0 , 0 ) , TRUE ) ;
			Count ++ ;
		}

		// テキストバッファの描画
		for( i = 0 ; i < STRBUF_HEIGHT ; i ++ )
		{
			DrawString( 8 , i * MOJI_SIZE , StringBuf[ i ] , GetColor( 255 , 255 , 255 ) ) ;
		}

		// 裏画面の内容を表画面に反映させる
		ScreenFlip() ;
	}

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;					// ソフトの終了
}



// 改行関数
void Kaigyou( void )
{
	// 描画行位置を一つ下げる
	CursorY ++ ;

	// 描画列を最初に戻す
	CursorX = 0 ;

	// もしテキストバッファ縦幅からはみ出るならテキストバッファを縦スクロールさせる
	if( CursorY >= STRBUF_HEIGHT )
	{
		int i , j ;

		for( i = 1 ; i < STRBUF_HEIGHT ; i ++ )
		{
			for( j = 0 ; j < STRBUF_WIDTH * 2 ; j ++ )
			{
				StringBuf[ i - 1 ][ j ] = StringBuf[ i ][ j ] ;
			}
		}

		// 描画行位置を一つあげる
		CursorY -- ;
	}
}

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 引数を定数に

#2

投稿記事 by みけCAT » 3年前

この処理を行うクラスを作り、MOJI_SIZE、STRBUF_WINDTH、STRBUF_HEIGHTにあたる値をコンストラクタの引数で指定し、
コンストラクタで指定されたサイズに従ってstd::vectorなどを用いて必要な領域を確保する、みたいにするといいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

inemaru
記事: 108
登録日時: 3年前

Re: 引数を定数に

#3

投稿記事 by inemaru » 3年前

C++(C++11)ですが、実装例です。
あまり綺麗に書けていませんがご了承ください。
Windows10 VS2013(マルチバイト文字)環境で作成しました。

標準ライブラリSTL(std)のvectorとstringを使用すれば
割と楽に解決できると思われます。

開発環境が違うのでコピペで動かない可能性あります。

コード:

#include "DxLib.h"
#include <iostream>
#include <vector>
#include <string>

// DXライブラリ簡易ラップクラス
class DxLibApp final
{
public:
	// コンストラクタ
	DxLibApp(const char* pWindowText) try
		: windowWidth_(640)
		, windowHeight_(480)
		, colorBitDepth_(16)
	{
		// null文字の場合はウィンドウテキストを設定しない
		if (pWindowText != nullptr){
			DxLib::SetWindowText(pWindowText);
		}
		// 各種初期化
		SetGraphMode(windowWidth_, windowHeight_, colorBitDepth_);
		ChangeWindowMode(TRUE);
		// 初期化に失敗したら例外を投げて強制終了
		if (DxLib_Init() == -1){
			throw "DXライブラリの初期化に失敗しました。";
		}
		SetDrawScreen(DX_SCREEN_BACK);
	}
	catch (char* str) {
		std::cerr << str << std::endl;
	}

	// デストラクタ
	~DxLibApp(){
		DxLib_End();
	}
public:
	// ループ条件
	static bool ProcessLoop(){
		return (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0);
	}
	// ウィンドウ横幅取得
	inline const int& GetWindowWidth() const{
		return windowWidth_;
	}
	// ウィンドウ縦幅取得
	inline const int& GetWindowHeight() const{
		return windowHeight_;
	}

private:
	int windowWidth_;		// ウィンドウ横幅
	int windowHeight_;		// ウィンドウ縦幅
	int colorBitDepth_;		// カラービット数
};

// 背景エフェクト管理用のクラス
class BackGroundEffect final
{
public:
	// コンストラクタ
	BackGroundEffect(const int& windowWidth, const int& windowHeight)
		: refWindowWidth_(windowWidth)
		, refWindowHeight_(windowHeight)
		, frameCount_(0)
	{}
	// デストラクタ
	~BackGroundEffect(){}
public:
	// 更新
	void Update(){
		// サンプルをCPP向けに書き換えただけ
		int Color = static_cast<int>(sin(frameCount_ / 100.0) * 80.0 + 125.0);
		DrawBox(0, 0, refWindowWidth_, refWindowHeight_, GetColor(Color, 0, 0), TRUE);
		++frameCount_;
	}

private:
	const int& refWindowWidth_;		// ウィンドウ横幅の参照
	const int& refWindowHeight_;	// ウィンドウ縦幅の参照
	int frameCount_;				// フレームカウンタ
};

// ノベルテキスト管理用のクラス
class NovelText final
{
public:
	// コンストラクタ
	NovelText(const int& windowWidth, const int& windowHeight)
		: refWindowWidth_(windowWidth)
		, refWindowHeight_(windowHeight)
		, fontSize_(24)
		, fontColor_(GetColor(255, 255, 255))
		, seekPos_(0)
		, lineCount_(0)
		, novelText_()
		, drawTextList_()
		, tmpKeyWord_()
	{
		SetFontSize(fontSize_);	// フォントサイズを指定する
	}
	// デストラクタ
	~NovelText(){}
public:
	// 初期化
	void Initialize(){
		// ノベルテキスト本文
		novelText_ += " ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組むことである。B";
		novelText_ += "@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B";
		novelText_ += "変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか";
		novelText_ += "なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B";
		novelText_ += "C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が";
		novelText_ += "つけば後はそこからは掘り下げ、広げていけば良いわけで、Bプログラムの参考書を";
		novelText_ += "読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム";
		novelText_ += "を打ってみることが大事である。E";
		// 一行追加
		drawTextList_.emplace_back("");
	}

	// 更新
	void Update(){
		_Calc();
		_Draw();
	}

private:
	// 計算
	void _Calc(){
		// 特殊文字を処理する
		switch (*tmpKeyWord_.c_str()){
		case '@':	// 改行文字
			_AddLine();
			break;
		case 'B':	// ボタン押し待ち文字
			WaitKey();
			break;
		case 'E':{	// 終了文字
				// 終了文字が来たので計算をせず戻す
			}
			return;
		case 'C':{	// クリア文字
			lineCount_ = 0;					// 文字の格納先を0に戻す
			drawTextList_.clear();			// すべての行を削除する
			drawTextList_.emplace_back("");	// 最初の一行を追加する
		}
		break;
		default:	// その他の文字
			break;
		}
		tmpKeyWord_.clear();	// 使い終わったので空にする
		// 画面外にはみ出す場合は格納行を変更する
		if (GetDrawStringWidth(drawTextList_[lineCount_].c_str(), drawTextList_[lineCount_].size()) > (refWindowWidth_ - fontSize_)){
			_AddLine();
		}
		// 表示する文字列に一文字ずつ追加する
		drawTextList_[lineCount_] += _PopString();
	}

	// 描画
	void _Draw(){
		// 現在存在する行を描画する
		for (unsigned index = 0; index < drawTextList_.size(); ++index){
			DrawString(0, fontSize_ * index, drawTextList_[index].c_str(), fontColor_);
		}
	}

	// 元になるテキストから一文字ずつ取り出す
	std::string _PopString(){
		unsigned int char_size;	// 文字のサイズ保存用
		unsigned char tmpChar;	// 一時保存文字
		if (seekPos_ < static_cast<int>(novelText_.size())){
			// UTF-8エンコードの文字判定(定番)
			tmpChar = novelText_[seekPos_];
			if (tmpChar < 0x80){
				char_size = 1;
			}
			else if (tmpChar < 0xE0){
				char_size = 2;
			}
			else if (tmpChar < 0xF0){
				char_size = 3;
			}
			else{
				char_size = 4;
			}
			// 取得した一文字を一時保存
			std::string tmpStr = novelText_.substr(seekPos_, char_size);
			// 特殊文字の場合の判定
			switch (*tmpStr.c_str())
			{
			case '@':	// 改行文字
			case 'B':	// ボタン押し待ち文字
			case 'E':	// 終了文字
			case 'C':	// クリア文字
				tmpKeyWord_ = tmpStr;	// 特殊文字を一時保存
				tmpStr.clear();			// 特殊文字は表示しないのでクリア
				break;
			default:	// その他の文字
				break;
			}
			seekPos_ += char_size;	// 一文字分シークする
			return tmpStr;	// 取得した一文字を返す
		}
		// テキストの範囲を超えたので空文字を返す
		return nullptr;
	}

	// 行の追加
	void _AddLine(){
		++lineCount_;	// 格納行を次へ
		drawTextList_.emplace_back("");	// 空文字を追加して配列を延長
	}

private:
	const int& refWindowWidth_;				// ウィンドウ横幅の参照
	const int& refWindowHeight_;			// ウィンドウ縦幅の参照
	int fontSize_;							// フォントサイズ
	unsigned int fontColor_;				// フォント色
	unsigned int seekPos_;					// 表示文字のインデックス
	unsigned int lineCount_;				// 文字列の格納行
	std::string novelText_;					// 元になるテキスト
	std::vector<std::string> drawTextList_;	// 実際に表示する文字列
	std::string tmpKeyWord_;				// 特殊文字の一時保存
};

// エントリーポイント
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// 初期化
	DxLibApp app("サウンドノベル風の文字表示");
	BackGroundEffect bgEffect(app.GetWindowWidth(), app.GetWindowHeight());
	NovelText novelText(app.GetWindowWidth(), app.GetWindowHeight());
	novelText.Initialize();

	// メインループ
	while (DxLibApp::ProcessLoop()){
		// ESCキーで終了
		if (CheckHitKey(KEY_INPUT_ESCAPE)){
			break;
		}
		// 背景エフェクトの更新
		bgEffect.Update();
		// ノベル文字の更新
		novelText.Update();
	}

	return 0;
}
アルゴリズムは、サンプルソースと異なります。
動的配列に文字列を格納して行き、
画面外に行きそうな場合や改行処理が入ったときは
動的配列に、空文字を格納して配列を増やしています。

リアカー

Re: 引数を定数に

#4

投稿記事 by リアカー » 3年前

>みけCAT さん
>inemaru さん

ご回答ありがとう御座います。
つまりC++で実装すればできる、ということでしょうか。
しかし、そうなると私Cの知識しかないので、、、、
なんとかCでするのは無理ですかね?

また、一つのプロジェクトの中に複数の言語(CとC++)を使うのはできるんですかね?

ちなみにinemaruさんのプログラムをコピペしてみると、かなり多くエラーがでました。
(未定義の構造体”DxLibApp” , 宣言の構文エラーなど)

アバター
usao
記事: 1573
登録日時: 6年前

Re: 引数を定数に

#5

投稿記事 by usao » 3年前

「なんかやろうとしたけどエラー吐かれました どうすれば解決できる?」 とか言われましても.


>なんとかCでするのは無理ですかね?

目的の処理に必要なデータをとりあえず構造体にでもまとめて,
あとはそのデータを{初期化,更新}等するための関数群を用意すればよいのでは.
オフトピック
実用し難い形で書かれているサンプルコードとかいうのを どうにかしてほぼそのまま使いまわそう として四苦八苦するよりも,
そのサンプルがやってる処理の中に「参考になること」があるなら,そこだけを参考にして,
自分が使いやすい形のものを新規で作ってしまった方が早いと思うけど.

inemaru
記事: 108
登録日時: 3年前

Re: 引数を定数に

#6

投稿記事 by inemaru » 3年前

Borland C++ 5.5.1(BCCDevoperのコンパイラ)は
結構古いので2000年以降に制定された規約は判断できないみたいです。

前回貼ったコードは、
C++11(2011年に標準化)に対応しているコンパイラが必須ですので
コンパイルエラーするのはコンパイラの問題です。

同じ環境を再現するのが、手間だったので
とりあえず、古い規約を調べつつサンプルコードを
書き換えてみました。

STL自体がC++で実装されているので
以下のコードは、古い規約で書いたC言語風C++コードです。

コンパイル可能か確認できてないので、
動けばラッキーくらいの気分でお願いします。

コード:

// main.cpp
#include "DxLib.h"
#include <math.h>

// インクルード関連でエラーしたら
// ↓のコメントアウトを外す
//#define INCLUDE_SWITCH

#ifdef INCLUDE_SWITCH
// 普通にSTLが使用できる場合
#include <string>
#include <vector>
#else
// 古いSTLが使用されていた場合
#include <string.stl>
#include <vector.h>
#endif

// 文字のサイズ
int MOJI_SIZE;	// 24

// 仮想テキストバッファの横サイズ縦サイズ
int STRBUF_WIDTH;    //24
int STRBUF_HEIGHT;   //20

//char StringBuf[STRBUF_HEIGHT][STRBUF_WIDTH * 2 + 1];	// 仮想テキストバッファ
std::vector< std::vector<char> > StringBuf;

int CursorX, CursorY;              // 仮想画面上での文字表示カーソルの位置
int SP, CP;                        // 参照する文字列番号と文字列中の文字ポインタ
int EndFlag;                       // 終了フラグ
int KeyWaitFlag;                   // ボタン押し待ちフラグ
int Count;                         // フレームカウンタ

char String[][256] = {
	" ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組む",
	"ことである。B",
	"@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B",
	"変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか",
	"なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B",
	"C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が",
	"つけば後はそこからは掘り下げ、広げていけば良いわけで、Bプログラムの参考書を",
	"読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム",
	"を打ってみることが大事である。E",
};

void Kaigyou(void);      // テキストバッファの改行処理関数
void ResizeStringBuffer(unsigned heightSize, unsigned widthSize);	// 仮想テキストバッファサイズ変更

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow) //ここは自作関数化する
{
	char OneMojiBuf[3];  // 1文字分一時記憶配列
	int i, j;

	ChangeWindowMode(TRUE);

	SetGraphMode(640, 480, 16);
	if (DxLib_Init() == -1) {  // DXライブラリ初期化処理
		return -1;             // エラーが起きたら直ちに終了
	}

	// 初期値を設定
	MOJI_SIZE = 24;
	STRBUF_WIDTH = 24;
	STRBUF_HEIGHT = 20;
	ResizeStringBuffer(STRBUF_WIDTH, STRBUF_WIDTH * 2 + 1);

	// 描画位置の初期位置セット
	CursorX = 0;
	CursorY = 0;

	// 参照文字位置をセット
	SP = 0;    // 1行目の
	CP = 0;    // 0文字

	// フォントのサイズセット
	SetFontSize(MOJI_SIZE);

	// 描画先を裏画面にセット
	SetDrawScreen(DX_SCREEN_BACK);

	// フレームカウンタ初期化
	Count = 0;

	// ループ
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		// サウンドノベル風文字列描画処理を行う
		// ただし終了フラグが1だった場合は処理をしない
		if (EndFlag == 0) {
			char  Moji;

			// ボタン押し待ちフラグがたっていた場合はボタンが押されるまでここで終了
			if (KeyWaitFlag == 1) {
				if (ProcessMessage() == 0 && CheckHitKeyAll() != 0) {
					// ボタンが押されていたら解除
					KeyWaitFlag = 0;
				}
			} else {
				// 文字の描画
				Moji = String[SP][CP];
				switch (Moji) {
				case '@':  // 改行文字

					// 改行処理および参照文字位置を一つ進める
					Kaigyou();
					CP++;

					break;

				case 'B':  // ボタン押し待ち文字

					// ボタンが離されるまで待つ
					while (ProcessMessage() == 0 && CheckHitKeyAll() != 0) {}

					// ボタン押し待ちフラグをたてる
					KeyWaitFlag = 1;
					CP++;

					break;

				case 'E':  // 終了文字

					// 終了フラグを立てるおよび参照文字位置を一つ進める
					EndFlag = 1;
					CP++;

					break;

				case 'C':  // クリア文字

					// 仮想テキストバッファを初期化して描画文字位置を初期位置に戻すおよび参照文字位置を一つ進める
					for (i = 0; i < STRBUF_HEIGHT; i++) {
						for (j = 0; j < STRBUF_WIDTH * 2; j++) {
							StringBuf[i][j] = 0;
						}
					}

					CursorY = 0;
					CursorX = 0;
					CP++;

					break;

				default:   // その他の文字

					// 1文字分抜き出す
					OneMojiBuf[0] = String[SP][CP];
					OneMojiBuf[1] = String[SP][CP + 1];
					OneMojiBuf[2] = '\0';

					// 1文字テキストバッファに代入
					StringBuf[CursorY][CursorX * 2] = OneMojiBuf[0];
					StringBuf[CursorY][CursorX * 2 + 1] = OneMojiBuf[1];

					// 参照文字位置を2バイト勧める
					CP += 2;

					// カーソルを一文字文進める
					CursorX++;

					// テキストバッファ横幅からはみ出たら改行する
					if (CursorX >= STRBUF_WIDTH) {
						Kaigyou();
					}

					break;
				}

				// 参照文字列の終端まで行っていたら参照文字列を進める
				if (String[SP][CP] == '\0') {
					SP++;
					CP = 0;
				}
			}
		}
		// 画面のクリア
		ClearDrawScreen();

		// 背景エフェクトの描画
		{
			int Color;

			Color = (int)(sin(Count / 100.0) * 80.0 + 125.0);
			DrawBox(0, 0, 640, 480, GetColor(Color, 0, 0), TRUE);
			Count++;
		}
		// テキストバッファの描画
		for (i = 0; i < STRBUF_HEIGHT; i++) {
			DrawString(8, i * MOJI_SIZE, &StringBuf[i][0], GetColor(255, 255, 255));
		}
		// 裏画面の内容を表画面に反映させる
		ScreenFlip();
	}

	DxLib_End();               // DXライブラリ使用の終了処理

	return 0;                  // ソフトの終了
}

// 改行関数
void Kaigyou(void)
{
	// 描画行位置を一つ下げる
	CursorY++;
	// 描画列を最初に戻す
	CursorX = 0;
	// もしテキストバッファ縦幅からはみ出るならテキストバッファを縦スクロールさせる
	if (CursorY >= STRBUF_HEIGHT) {
		int i, j;
		for (i = 1; i < STRBUF_HEIGHT; i++) {
			for (j = 0; j < STRBUF_WIDTH * 2; j++) {
				StringBuf[i - 1][j] = StringBuf[i][j];
			}
		}
		// 描画行位置を一つあげる
		CursorY--;
	}
}

// 仮想テキストバッファサイズ変更
void ResizeStringBuffer(unsigned heightSize, unsigned widthSize)
{
	unsigned index;
	StringBuf.resize(heightSize);
	for (index = 0; index < heightSize; ++index) {
		StringBuf[index].resize(widthSize);
	}
}

リアカー さんが書きました: また、一つのプロジェクトの中に複数の言語(CとC++)を使うのはできるんですかね?
基本的に、C言語のソースコードはC++のコンパイラでコンパイルできます。
BCCDevoperのコンパイラである Borland C++ 5.5.1 はC++コンパイラなので
CとC++の共存は可能だと思われます。
(ただ、開発環境によってはできないこともあるようなので、絶対ではないです。)

リアカー

Re: 引数を定数に

#7

投稿記事 by リアカー » 3年前

ご返信ありがとう御座います。
>usao さん
構造体ですか…。私構造体の知識が浅薄なのでこれを機にその勉強もさせていただこうと思います。

また、Offtopic読ませて頂きました。
すいません。確かに今回、私のプログラミングへの姿勢がまずかったように思います。
「参考にできる部分は参考にして、あとは自分で頑張る」という姿勢をこれからはとるように
したいと思います。ありがとうございました。

>nemaru さん
私の環境でも書いて下さったコードは通り、問題なく実行できました。ありがとうございました。
C++のコードということで理解できない点もありますが、だいたいは把握することができました。
ちなみに私の環境でもちゃんと調べましたところ、CとC++は共存できるようです。


皆様ご回答ありがとうございました。今回は自分の根本的な甘さも見えたような気もします。
勉強すべき点が分かったので、それをこれから頑張ろうと思います。
とりあえずこのスレは解決とさせていただきます。
ありがとうございました。

アバター
usao
記事: 1573
登録日時: 6年前

Re: 引数を定数に

#8

投稿記事 by usao » 3年前

オフトピック
>すいません。確かに今回、私のプログラミングへの姿勢がまずかったように思います。

いや,姿勢がどうのという類の話ではなく,
単純に,
・他人が書いたコードそのものを流用すべく修正する作業
・他人の(方法とか処理手順とかの)アイデアだけをパクって自前コード書く作業
の面倒さを天秤にかけたら,今回のやつくらいの内容であれば,後者の方が楽なのではないかな(と思いました)
というだけの話ですよ.

リアカー

Re: 引数を定数に

#9

投稿記事 by リアカー » 3年前

オフトピック
なるほどそういうことだったんですね。
わかりました。

閉鎖

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