D'angband  0.0.0
Deeangband
 全て クラス 名前空間 ファイル 関数 変数 型定義 列挙型 列挙値 フレンド マクロ定義 ページ
GameSurfaceSDL.cpp
[詳解]
1 
9 #include <vector>
10 #include <string>
11 #include "stdafx.h"
12 #include "GameSurfaceSDL.h"
13 
14 namespace Deeangband
15 {
16 
17  std::string toUTF8(LPCSTR str)
18  {
19  const int cchWideChar = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
20  std::vector<WCHAR> lpw(cchWideChar);
21 
22  const int nUnicodeCount = ::MultiByteToWideChar(CP_ACP, 0, str, -1, &lpw[0], cchWideChar);
23  if(nUnicodeCount <= 0)
24  {
25  return "";
26  }
27 
28  const int cchMultiByte = ::WideCharToMultiByte(CP_UTF8, 0, &lpw[0], -1, NULL, 0, NULL, NULL);
29  std::vector<CHAR> lpa(cchMultiByte);
30 
31  const int nMultiCount = ::WideCharToMultiByte(CP_UTF8, 0, &lpw[0], -1, &lpa[0], cchMultiByte, NULL, NULL);
32  if(nMultiCount <= 0)
33  {
34  return "";
35  }
36  return std::string(&lpa[0]);
37  }
38 
39  GameSurfaceSDL::GameSurfaceSDL(GameWorld *gameWorld) : GameSurface(gameWorld)
40  {
41  if(SDL_Init(SDL_INIT_VIDEO) < 0) return;
42  window = SDL_CreateWindow(GAME_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE);
43  SDL_GetWindowSurface(window);
44  if(!window) return;
45 
46  if(TTF_Init() == -1) return;
47  if(IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) return;
48 
49  initInterfaces();
50 
51  viewCreaturePtr = NULL;
52  viewFieldPtr = NULL;
53 
54  windowSurface = SDL_GetWindowSurface(window);
55 
56  return;
57  }
58 
59  GameSurfaceSDL::‾GameSurfaceSDL(void)
60  {
61  IMG_Quit();
62  TTF_Quit();
63  SDL_Quit();
64  return;
65  }
66 
67  void GameSurfaceSDL::pushAnyKey(void)
68  {
69  SDL_Event event;
70  do
71  {
72  this->Redraw();
73  SDL_PollEvent(&event);
74  } while(event.type != SDL_KEYDOWN);
75  }
76 
77  void GameSurfaceSDL::initInterfaces(void)
78  {
79  font = TTF_OpenFont("ttf¥¥ipam.ttf", 18);
80  src.x = 0;
81  src.y = 0;
82  src.w = 300;
83  src.h = 200;
84  title.x = 0;
85  title.y = 0;
86  title.w = 512;
87  title.h = 512;
88  color.r = 255;
89  color.g = 223;
90  color.b = 200;
91  color.a = 255;
92 
93  if(!font)
94  {
95  OutputDebugString(L"Failed: loading .ttf files.¥n");
96  exit(1);
97  }
98 
99  rwop = SDL_RWFromFile("img¥¥Title.png", "rb");
100  error = IMG_GetError();
101  titleSurface = IMG_LoadPNG_RW(rwop);
102 
103  renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
104  }
105 
106  void GameSurfaceSDL::Redraw()
107  {
108  SDL_Rect rect = {0, 0, 0, 0};
109 
110  SDL_GetWindowSize(window, &rect.w, &rect.h);
111  SDL_SetRenderDrawColor(renderer, 100, 100, 0, 255);
112  SDL_FillRect(windowSurface, &rect, SDL_MapRGBA(windowSurface->format, 50, 20, 10, 255));
113  SDL_BlitSurface(titleSurface, &title, windowSurface, &title);
114 
115  if(this->viewFieldPtr) this->drawField(gameWorld, viewFieldPtr, 0, 0, 20, 20);
116  if(this->sideStatusCreatutePtr) this->drawSideCreatureStatus();
117  if(this->viewCreaturePtr) this->drawCreatureStatus(viewCreaturePtr);
118  if(this->currentMessage.size() > 0) this->drawMessage();
119 
120  SDL_UpdateWindowSurface(window);
121 
122  return;
123  }
124 
125  void GameSurfaceSDL::ViewCreatureStatus(Creature *creaturePtr)
126  {
127  this->viewCreaturePtr = creaturePtr;
128  pushAnyKey();
129  this->viewCreaturePtr = NULL;
130  }
131 
132  void GameSurfaceSDL::SetSideStatusCreature(Creature *creaturePtr)
133  {
134  this->sideStatusCreatutePtr = creaturePtr;
135  if(creaturePtr) this->updateSideCreatureStatus(creaturePtr);
136  }
137 
138  void GameSurfaceSDL::SetField(Field *fieldPtr)
139  {
140  this->viewFieldPtr = fieldPtr;
141  }
142 
143  void GameSurfaceSDL::drawCreatureStatus(Creature *creaturePtr)
144  {
145  int id;
146 
147  enum CREATURE_STATUS_VIEW_POSITION
148  {
149  POS_NAME,
150  POS_LEVEL,
151  POS_HP,
152  POS_MP,
153  POS_AC,
154  POS_EV,
155  POS_VO,
156  POS_STR,
157  POS_INT,
158  POS_WIS,
159  POS_DEX,
160  POS_CON,
161  POS_CHA,
162  POS_SOUL,
163  POS_GOOD,
164  POS_EVIL,
165  POS_ORDER,
166  POS_CHAOS,
167  POS_BALANCE,
168  POS_HEIGHT,
169  POS_WEIGHT,
170  POS_BODY_SIZE,
171  POS_MAX
172  };
173 
174  SDL_Rect CreatureStatusViewPosition[POS_MAX] =
175  {
176  {10, 10, 0, 0},
177  {10, 30, 0, 0},
178  {10, 50, 0, 0},
179  {10, 70, 0, 0},
180  {10, 90, 0, 0},
181  {10, 110, 0, 0},
182  {10, 130, 0, 0},
183  {200, 30, 0, 0},
184  {200, 50, 0, 0},
185  {200, 70, 0, 0},
186  {200, 90, 0, 0},
187  {200, 110, 0, 0},
188  {200, 130, 0, 0},
189  {200, 150, 0, 0},
190  {200, 170, 0, 0},
191  {200, 190, 0, 0},
192  {200, 210, 0, 0},
193  {200, 230, 0, 0},
194  {200, 250, 0, 0},
195  {10, 150, 0, 0},
196  {10, 170, 0, 0},
197  {10, 190, 0, 0},
198  };
199 
200  SDL_Rect CreatureStatusViewRect[POS_MAX];
201 
202  const int STATUS_BUFSIZE = 100;
203  char statusBuf[POS_MAX][STATUS_BUFSIZE];
204  SDL_Surface *statusSurface[POS_MAX];
205 
206  SDL_Rect masterRect = {10, 10, 490, 450};
207 
208  sprintf_s(statusBuf[POS_NAME], STATUS_BUFSIZE, "名前:%s", creaturePtr->GetName().c_str());
209  sprintf_s(statusBuf[POS_LEVEL], STATUS_BUFSIZE, "LV:%3d", creaturePtr->GetLevel());
210  sprintf_s(statusBuf[POS_HP], STATUS_BUFSIZE, "HP:%5d/%5d", creaturePtr->GetCurHP(), creaturePtr->GetMaxHP());
211  sprintf_s(statusBuf[POS_MP], STATUS_BUFSIZE, "MP:%5d/%5d", creaturePtr->GetCurMP(), creaturePtr->GetMaxMP());
212  sprintf_s(statusBuf[POS_AC], STATUS_BUFSIZE, "AC:%4d", creaturePtr->GetArmorSaving());
213  sprintf_s(statusBuf[POS_EV], STATUS_BUFSIZE, "EV:%4d", creaturePtr->GetEvasionSaving());
214  sprintf_s(statusBuf[POS_VO], STATUS_BUFSIZE, "VO:%4d", creaturePtr->GetVolitionSaving());
215  sprintf_s(statusBuf[POS_GOOD], STATUS_BUFSIZE, " 善 :%4d", creaturePtr->GetDiscipilneRank(DISCIPLINE_TYPE_GOOD));
216  sprintf_s(statusBuf[POS_EVIL], STATUS_BUFSIZE, " 悪 :%4d", creaturePtr->GetDiscipilneRank(DISCIPLINE_TYPE_EVIL));
217  sprintf_s(statusBuf[POS_ORDER], STATUS_BUFSIZE, "秩序:%4d", creaturePtr->GetDiscipilneRank(DISCIPLINE_TYPE_ORDER));
218  sprintf_s(statusBuf[POS_CHAOS], STATUS_BUFSIZE, "混沌:%4d", creaturePtr->GetDiscipilneRank(DISCIPLINE_TYPE_CHAOS));
219  sprintf_s(statusBuf[POS_BALANCE], STATUS_BUFSIZE, "天秤:%4d", creaturePtr->GetDiscipilneRank(DISCIPLINE_TYPE_BALANCE));
220  sprintf_s(statusBuf[POS_STR], STATUS_BUFSIZE, "腕力:%4d", creaturePtr->GetCurrentStatus(CS_STR));
221  sprintf_s(statusBuf[POS_INT], STATUS_BUFSIZE, "知力:%4d", creaturePtr->GetCurrentStatus(CS_INT));
222  sprintf_s(statusBuf[POS_WIS], STATUS_BUFSIZE, "賢さ:%4d", creaturePtr->GetCurrentStatus(CS_WIS));
223  sprintf_s(statusBuf[POS_DEX], STATUS_BUFSIZE, "器用:%4d", creaturePtr->GetCurrentStatus(CS_DEX));
224  sprintf_s(statusBuf[POS_CON], STATUS_BUFSIZE, "耐久:%4d", creaturePtr->GetCurrentStatus(CS_CON));
225  sprintf_s(statusBuf[POS_CHA], STATUS_BUFSIZE, "魅力:%4d", creaturePtr->GetCurrentStatus(CS_CHA));
226  sprintf_s(statusBuf[POS_SOUL], STATUS_BUFSIZE, "ソウル:%4d", creaturePtr->GetCurrentSoul());
227  sprintf_s(statusBuf[POS_HEIGHT], STATUS_BUFSIZE, "身長:%13s", GameElement::HeightFormat(creaturePtr->GetHeight()).c_str());
228  sprintf_s(statusBuf[POS_WEIGHT], STATUS_BUFSIZE, "体重:%13s", GameElement::WeightFormat(creaturePtr->GetWeight()).c_str());
229  sprintf_s(statusBuf[POS_BODY_SIZE], STATUS_BUFSIZE, "体格:%3d", creaturePtr->GetSize());
230 
231  for(id = 0; id < POS_MAX; id++)
232  {
233  statusSurface[id] = TTF_RenderUTF8_Blended(font, toUTF8(statusBuf[id]).c_str(), color);
234  CreatureStatusViewRect[id].x = 0;
235  CreatureStatusViewRect[id].y = 0;
236  CreatureStatusViewRect[id].w = statusSurface[id]->w;
237  CreatureStatusViewRect[id].h = statusSurface[id]->h;
238  CreatureStatusViewPosition[id].x += masterRect.x;
239  CreatureStatusViewPosition[id].y += masterRect.y;
240  }
241 
242  SDL_FillRect(windowSurface, &masterRect, SDL_MapRGBA(windowSurface->format, 0, 0, 0, 120));
243 
244  for(id = 0; id < POS_MAX; id++)
245  {
246  SDL_BlitSurface(statusSurface[id], &CreatureStatusViewRect[id], windowSurface, &CreatureStatusViewPosition[id]);
247  }
248 
249  for(id = 0; id < POS_MAX; id++)
250  {
251  SDL_FreeSurface(statusSurface[id]);
252  }
253  return;
254  }
255 
256  void GameSurfaceSDL::updateSideCreatureStatus(Creature *creaturePtr)
257  {
258  int id;
259 
260  enum CREATURE_SIDE_STATUS_VIEW_POSITION
261  {
262  POS_NAME,
263  POS_LEVEL,
264  POS_HP,
265  POS_MP,
266  POS_AC,
267  POS_EV,
268  POS_VO,
269  POS_STR,
270  POS_INT,
271  POS_WIS,
272  POS_DEX,
273  POS_CON,
274  POS_CHA,
275  POS_SOUL,
276  POS_MAX
277  };
278 
279  SDL_Rect CreatureStatusViewPosition[POS_MAX] =
280  {
281  {10, 10, 0, 0},
282  {10, 30, 0, 0},
283  {10, 50, 0, 0},
284  {10, 70, 0, 0},
285  {10, 90, 0, 0},
286  {10, 110, 0, 0},
287  {10, 130, 0, 0},
288  {200, 30, 0, 0},
289  {200, 50, 0, 0},
290  {200, 70, 0, 0},
291  {200, 90, 0, 0},
292  {200, 110, 0, 0},
293  {200, 130, 0, 0},
294  {200, 150, 0, 0},
295  };
296 
297  SDL_Rect CreatureStatusViewRect[POS_MAX];
298 
299  const int STATUS_BUFSIZE = 100;
300  char statusBuf[POS_MAX][STATUS_BUFSIZE];
301  SDL_Surface *statusSurface[POS_MAX];
302 
303  SDL_Rect masterRect = {0, 0, 180, 350};
304 
305  creatureStatusSurface = SDL_CreateRGBSurface(0, 490, 450, 32, 0, 0, 0, 0);
306 
307  sprintf_s(statusBuf[POS_NAME], STATUS_BUFSIZE, "名前:%s", creaturePtr->GetName().c_str());
308  sprintf_s(statusBuf[POS_LEVEL], STATUS_BUFSIZE, "LV:%3d", creaturePtr->GetLevel());
309  sprintf_s(statusBuf[POS_HP], STATUS_BUFSIZE, "HP:%5d/%5d", creaturePtr->GetCurHP(), creaturePtr->GetMaxHP());
310  sprintf_s(statusBuf[POS_MP], STATUS_BUFSIZE, "MP:%5d/%5d", creaturePtr->GetCurMP(), creaturePtr->GetMaxMP());
311  sprintf_s(statusBuf[POS_AC], STATUS_BUFSIZE, "AC:%4d", creaturePtr->GetArmorSaving());
312  sprintf_s(statusBuf[POS_EV], STATUS_BUFSIZE, "EV:%4d", creaturePtr->GetEvasionSaving());
313  sprintf_s(statusBuf[POS_VO], STATUS_BUFSIZE, "VO:%4d", creaturePtr->GetVolitionSaving());
314  sprintf_s(statusBuf[POS_STR], STATUS_BUFSIZE, "腕力:%4d", creaturePtr->GetCurrentStatus(CS_STR));
315  sprintf_s(statusBuf[POS_INT], STATUS_BUFSIZE, "知力:%4d", creaturePtr->GetCurrentStatus(CS_INT));
316  sprintf_s(statusBuf[POS_WIS], STATUS_BUFSIZE, "賢さ:%4d", creaturePtr->GetCurrentStatus(CS_WIS));
317  sprintf_s(statusBuf[POS_DEX], STATUS_BUFSIZE, "器用:%4d", creaturePtr->GetCurrentStatus(CS_DEX));
318  sprintf_s(statusBuf[POS_CON], STATUS_BUFSIZE, "耐久:%4d", creaturePtr->GetCurrentStatus(CS_CON));
319  sprintf_s(statusBuf[POS_CHA], STATUS_BUFSIZE, "魅力:%4d", creaturePtr->GetCurrentStatus(CS_CHA));
320  sprintf_s(statusBuf[POS_SOUL], STATUS_BUFSIZE, "ソウル:%4d", creaturePtr->GetCurrentSoul());
321 
322  for(id = 0; id < POS_MAX; id++)
323  {
324  statusSurface[id] = TTF_RenderUTF8_Blended(font, toUTF8(statusBuf[id]).c_str(), color);
325  CreatureStatusViewRect[id].x = 0;
326  CreatureStatusViewRect[id].y = 0;
327  CreatureStatusViewRect[id].w = statusSurface[id]->w;
328  CreatureStatusViewRect[id].h = statusSurface[id]->h;
329  CreatureStatusViewPosition[id].x += masterRect.x;
330  CreatureStatusViewPosition[id].y += masterRect.y;
331  }
332 
333  SDL_FillRect(creatureStatusSurface, &masterRect, SDL_MapRGBA(creatureStatusSurface->format, 0, 0, 0, 120));
334 
335  for(id = 0; id < POS_MAX; id++)
336  {
337  SDL_BlitSurface(statusSurface[id], &CreatureStatusViewRect[id], creatureStatusSurface, &CreatureStatusViewPosition[id]);
338  }
339 
340  for(id = 0; id < POS_MAX; id++)
341  {
342  SDL_FreeSurface(statusSurface[id]);
343  }
344  return;
345 
346  }
347 
348  void GameSurfaceSDL::drawSideCreatureStatus(void)
349  {
350  SDL_Rect masterRect = {0, 0, 180, 350};
351  SDL_Rect posRect = {10, 120, 0, 0};
352  SDL_BlitSurface(creatureStatusSurface, &masterRect, windowSurface, &posRect);
353  }
354 
355  GAME_COMMAND GameSurfaceSDL::GetCommand(void)
356  {
357  SDL_Event event;
358  SDL_Keycode key;
359 
360  while (SDL_PollEvent(&event))
361  {
362  this->Redraw();
363  switch(event.type)
364  {
365 
366  case SDL_KEYDOWN:
367  {
368  key=event.key.keysym.sym;
369 
370  switch(key)
371  {
372  case SDLK_ESCAPE:
373  return GAME_COMMAND_EXIT;
374  case SDLK_c:
376  case SDLK_F11:
378  case SDLK_F12:
380  case SDLK_k:
381  return GAME_COMMAND_NORTH;
382  case SDLK_u:
384  case SDLK_l:
385  return GAME_COMMAND_EAST;
386  case SDLK_n:
388  case SDLK_j:
389  return GAME_COMMAND_SOUTH;
390  case SDLK_b:
392  case SDLK_h:
393  return GAME_COMMAND_WEST;
394  case SDLK_y:
396  case SDLK_s:
397  return GAME_COMMAND_STAY;
398  }
399 
400  }
401  break;
402 
403  case SDL_QUIT:
404  return GAME_COMMAND_EXIT;
405  break;
406 
407  }
408  }
409 
410  return GAME_COMMAND_REDRAW;
411  }
412 
413  void GameSurfaceSDL::drawField(GameWorld *gameWorld, Field *fieldPtr, int x, int y, int w, int h)
414  {
415  SDL_Rect symbolRect = {0, 0, 30, 30};
416  SDL_Surface *symbolSurface;
417  char symBuf[5];
418  std::map<ID, boost::shared_ptr<Creature>>::iterator creatureIt;
419 
420  int px, py;
421  for(py = y; py < y + h; py++)
422  {
423  for(px = x; px < x + w; px++)
424  {
425  if(px < fieldPtr->GetWidth() && py < fieldPtr->GetHeight())
426  {
427  TAG tag = fieldPtr->GetSquare(px, py)->GetFloorTag();
428  Color symColor = gameWorld->GetFloor(tag)->GetSymbolColor();
429  Color backColor = gameWorld->GetFloor(tag)->GetBackColor();
430  SDL_Color sdlSymCol = {(Uint8)symColor.GetRed(), (Uint8)symColor.GetGreen(), (Uint8)symColor.GetBlue(), (Uint8)symColor.GetAlpha()};
431  SDL_Rect blitRect = {240 + px * 24, py * 24 , 24, 24};
432  SDL_FillRect(windowSurface, &blitRect, SDL_MapRGBA(windowSurface->format, (Uint8)backColor.GetRed(), (Uint8)backColor.GetGreen(), (Uint8)backColor.GetBlue(), (Uint8)backColor.GetAlpha()));
433  sprintf_s(symBuf, 5, "%s", gameWorld->GetFloor(tag)->GetSymbol().c_str());
434  symbolSurface = TTF_RenderUTF8_Blended(font, toUTF8(symBuf).c_str(), sdlSymCol);
435  blitRect.x += (24 - symbolSurface->w) / 2;
436  blitRect.y += (24 - symbolSurface->h) / 2;
437  SDL_BlitSurface(symbolSurface, &symbolRect, windowSurface, &blitRect);
438  SDL_FreeSurface(symbolSurface);
439  }
440  }
441  }
442 
443  for(creatureIt = gameWorld->GetCreatureList()->begin(); creatureIt != gameWorld->GetCreatureList()->end(); creatureIt++)
444  {
445  Color symColor = creatureIt->second->GetSymbolColor();
446  SDL_Color sdlSymCol = {(Uint8)symColor.GetRed(), (Uint8)symColor.GetGreen(), (Uint8)symColor.GetBlue(), (Uint8)symColor.GetAlpha()};
447  sprintf_s(symBuf, 5, "%s", creatureIt->second->GetSymbol().c_str());
448  SDL_Rect blitRect = {240 + creatureIt->second->GetPosition().GetX() * 24, creatureIt->second->GetPosition().GetY() * 24 , 24, 24};
449  symbolSurface = TTF_RenderUTF8_Blended(font, toUTF8(symBuf).c_str(), sdlSymCol);
450  blitRect.x += (24 - symbolSurface->w) / 2;
451  blitRect.y += (24 - symbolSurface->h) / 2;
452  SDL_BlitSurface(symbolSurface, &symbolRect, windowSurface, &blitRect);
453  SDL_FreeSurface(symbolSurface);
454  }
455  }
456 
457  void GameSurfaceSDL::FocusField(int x, int y)
458  {
459  this->focusPoint.Set(x, y);
460  }
461 
462  void GameSurfaceSDL::FocusField(Coordinates coord)
463  {
464  this->focusPoint.Set(coord.GetX(), coord.GetY());
465  }
466 
467  void GameSurfaceSDL::drawMessage(void)
468  {
469  SDL_Rect messageRect = {0, 0, 800, 100};
470  SDL_Rect messagePositon = {220, 8, 0, 0};
471  SDL_Rect windowRect = {212, 4, 800, 26};
472  SDL_FillRect(windowSurface, &windowRect, SDL_MapRGBA(messageSurface->format, 0, 0, 0, 120));
473  SDL_BlitSurface(messageSurface, &messageRect, windowSurface, &messagePositon);
474  //SDL_FreeSurface(messageSurface);
475  }
476 
477  void GameSurfaceSDL::Message(std::string message)
478  {
479  this->currentMessage = message;
480  messageSurface = TTF_RenderUTF8_Blended(font, toUTF8(this->currentMessage.c_str()).c_str(), color);
481  pushAnyKey();
482  this->currentMessage.erase();
483  SDL_FreeSurface(messageSurface);
484  }
485 
486 }
std::string TAG
ゲーム要素文字列ID
Definition: Deeangband.h:144
#define WINDOW_HEIGHT
Definition: Deeangband.h:7
#define WINDOW_WIDTH
Definition: Deeangband.h:6
GAME_COMMAND
Definition: Deeangband.h:23
#define GAME_TITLE
Definition: Deeangband.h:5
標準のシステム インクルード ファイルのインクルード ファイル、または 参照回数が多く、かつあまり変更さ...
std::string toUTF8(LPCSTR str)
修養属性:秩序
Definition: Discipline.h:24
GameSurfaceSDLクラスとその他付随要素のプロトタイプ
修養属性:混沌
Definition: Discipline.h:25