#include <string.h>
#include <stdlib.h>
#include "../DxLib.h"
#define CHAT_LINENUM 23 /* チャット中の文字列を表示する行数。*/
#define MAX_STRLENGTH 80 /* チャットで1行で入力できる文字数。*/
#define INPUT_LINE 25 /* チャットで入力領域となる画面上の行位置。*/
#define FONT_SIZE 16 /* フォントサイズ。*/
/* リングバッファ用構造体。*/
typedef struct xdata {
char screenString[MAX_STRLENGTH];
xdata *next;
} xdata;
//*** プロトタイプ宣言。***/
void screenStringAdd(xdata *list, char *addString);
void screenStringDraw(xdata *list, int num);
//*** グローバル変数。***/
int stringY; /* 文字列表示領域の次に文字列を表示する時の行位置。*/
int inputHandle; /* 入力ハンドル。*/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrecInstance, LPSTR lpCmdLine, int nCmdShow ) {
xdata base = { "", NULL };
xdata *list = &base;
int Rot = 0; /* マウススクロール合計量。ループごとに初期化しない。*/
int RotTmp;
int white = GetColor( 255, 255, 255 );
int black = GetColor( 0, 0, 0 );
/* ウィンドウ化を初期化処理。*/
if( ChangeWindowMode( TRUE ) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) {
return -1;
}
/* 描画先を裏画面に設定。*/
SetDrawScreen( DX_SCREEN_BACK ) ;
/* 文字列入力ハンドルを作成する。*/
inputHandle = MakeKeyInput(80, FALSE, FALSE, FALSE);
/* 作成した入力ハンドルをアクティブにする。*/
SetActiveKeyInput( inputHandle );
/* カーソルを点滅させるフラグを立てる。*/
SetKeyInputCursorBrinkFlag( TRUE );
/* 描画可能領域の制限。*/
SetDrawArea( 460, 0, 640, 480 );
/* チャットループ。*/
while( !(ProcessMessage()) ) {
/* 文字列入力。
/* 文字列の入力が終わっている場合は送信する。*/
if( CheckKeyInput( inputHandle ) == 1 ) {
char message[MAX_STRLENGTH];
/* 入力された文字列を取得する。*/
GetKeyInputString( message, inputHandle );
/* チャット文字列を追加する。*/
screenStringAdd( list, message );
/* 画面の内容を描画する。*/
screenStringDraw( list->next, stringY - CHAT_LINENUM );
Rot = stringY - CHAT_LINENUM;
/* 入力文字列を初期化する。*/
SetKeyInputString( "", inputHandle );
/* 再度inputHandleをアクティブにする。*/
SetActiveKeyInput( inputHandle );
}
/* マウススクロールした分だけずらして表示。*/
Rot -= RotTmp = GetMouseWheelRotVol();
/* スクロールしたら。*/
if( RotTmp != 0 ) {
/* ポインタを進める量の決定。*/
if( Rot < 0 ) {
Rot = 0;
}
if( stringY - CHAT_LINENUM <= 0 ) {
Rot = 0;
} else if( Rot > stringY - CHAT_LINENUM ) {
Rot = stringY - CHAT_LINENUM;
}
screenStringDraw(list->next, Rot);
}
/* チャット欄の描画。*/
DrawBox( 460, 1, 640, CHAT_LINENUM * FONT_SIZE + 2, white, FALSE );
/* 画面中に入力中の文字列を描画する。*/
DrawBox( 460, (INPUT_LINE - 2) * FONT_SIZE + 2, 640, 480, black, TRUE );
DrawKeyInputString( 460, INPUT_LINE * FONT_SIZE + 2, inputHandle );
DrawKeyInputModeString( 640, 480 );
/* 裏画面反映。*/
ScreenFlip();
/* 時間稼ぎ。*/
Sleep(32);
}
return 0;
}
//*** チャット文字列を追加する。***/
void screenStringAdd(xdata *list, char addString[]) {
xdata *data;
/* 入力した文字列をリストの末尾に追加。*/
data = (xdata *)malloc(sizeof(xdata));
if( data == NULL ) {
printfDx("メモリ確保失敗。\n");
exit(0);
}
/* ポインタがリストの末尾を指すようにする。*/
for( ; list->next; ) {
list = list->next;
}
strcpy(data->screenString, addString);
data->next = NULL;
list->next = data;
/* 格納する行を1つ進める。*/
stringY++;
return;
}
//* チャットの現在の状態を画面に表示する。*/
void screenStringDraw(xdata *list, int num) {
int white = GetColor( 255, 255, 255 );
int black = GetColor( 0, 0, 0 );
int i = 0;
/* numのマイナス対策。*/
if( num < 0 ) {
num = 0;
}
/* 指定した分だけポインタを進める。*/
for( ; num; num-- ) {
list = list->next;
}
/* チャット欄を黒で塗りつぶす。*/
DrawBox( 460, 0, 640, 480, black, TRUE );
/* チャット文字列を描画する。*/
for( ; list && i < CHAT_LINENUM; ) {
DrawString( 460 + 2, i * FONT_SIZE + 2, list->screenString, white );
list = list->next;
i++;
}
return;
}