WWDisplay.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*****************************************************************************/
  2. /* ここから */
  3. /*****************************************************************************/
  4. #include "wonx_include/disp.h"
  5. #include "wonx_include/text.h"
  6. #include "WWDisplayP.h"
  7. #include "WonX.h"
  8. /*****************************************************************************/
  9. /* メンバ関数の定義 */
  10. /*****************************************************************************/
  11. /*===========================================================================*/
  12. /* メンバの取得 */
  13. /*===========================================================================*/
  14. WWColorMap WWDisplay_GetColorMap(WWDisplay d) { return (d->color_map); }
  15. WWPalette WWDisplay_GetPalette(WWDisplay d, int n) { return (d->palette[n]); }
  16. WWCharacter WWDisplay_GetCharacter(WWDisplay d, int n)
  17. { return (d->character[n]); }
  18. WWSprite WWDisplay_GetSprite(WWDisplay d, int n) { return (d->sprite[n]); }
  19. WWScreen WWDisplay_GetScreen(WWDisplay d, int n) { return (d->screen[n]); }
  20. WWLCDPanel WWDisplay_GetLCDPanel(WWDisplay d) { return (d->lcd_panel); }
  21. WWText WWDisplay_GetText(WWDisplay d) { return (d->text); }
  22. WWCursor WWDisplay_GetCursor(WWDisplay d) { return (d->cursor); }
  23. int WWDisplay_GetSpriteEnable(WWDisplay d) { return (d->sprite_enable); }
  24. int WWDisplay_GetSpriteWindowEnable(WWDisplay d)
  25. { return (d->sprite_window_enable); }
  26. int WWDisplay_GetSpriteWindowX(WWDisplay d)
  27. { return (d->sprite_window_x); }
  28. int WWDisplay_GetSpriteWindowY(WWDisplay d)
  29. { return (d->sprite_window_y); }
  30. int WWDisplay_GetSpriteWindowWidth(WWDisplay d)
  31. { return (d->sprite_window_width); }
  32. int WWDisplay_GetSpriteWindowHeight(WWDisplay d)
  33. { return (d->sprite_window_height); }
  34. int WWDisplay_GetBorder(WWDisplay d) { return (d->border); }
  35. int WWDisplay_GetForegroundColor(WWDisplay d) { return (d->foreground_color); }
  36. int WWDisplay_GetBackgroundColor(WWDisplay d) { return (d->background_color); }
  37. int WWDisplay_GetSpriteStart(WWDisplay d) { return (d->sprite_start); }
  38. int WWDisplay_GetSpriteCount(WWDisplay d) { return (d->sprite_count); }
  39. /*===========================================================================*/
  40. /* メンバの設定 */
  41. /*===========================================================================*/
  42. WWColorMap WWDisplay_SetColorMap(WWDisplay d, WWColorMap cm)
  43. { return (d->color_map = cm); }
  44. WWPalette WWDisplay_SetPalette(WWDisplay d, int n, WWPalette p)
  45. { return (d->palette[n] = p); }
  46. WWCharacter WWDisplay_SetCharacter(WWDisplay d, int n, WWCharacter c)
  47. { return (d->character[n] = c); }
  48. WWSprite WWDisplay_SetSprite(WWDisplay d, int n, WWSprite s)
  49. { return (d->sprite[n] = s); }
  50. WWScreen WWDisplay_SetScreen(WWDisplay d, int n, WWScreen s)
  51. { return (d->screen[n] = s); }
  52. WWLCDPanel WWDisplay_SetLCDPanel(WWDisplay d, WWLCDPanel p)
  53. { return (d->lcd_panel = p); }
  54. WWText WWDisplay_SetText(WWDisplay d, WWText p)
  55. { return (d->text = p); }
  56. WWCursor WWDisplay_SetCursor(WWDisplay d, WWCursor p)
  57. { return (d->cursor = p); }
  58. int WWDisplay_SetSpriteEnable(WWDisplay d, int f)
  59. { return (d->sprite_enable = f); }
  60. int WWDisplay_SetSpriteWindowEnable(WWDisplay d, int f)
  61. { return (d->sprite_window_enable = f); }
  62. int WWDisplay_SetSpriteWindowX(WWDisplay d, int n)
  63. { return (d->sprite_window_x = n); }
  64. int WWDisplay_SetSpriteWindowY(WWDisplay d, int n)
  65. { return (d->sprite_window_y = n); }
  66. int WWDisplay_SetSpriteWindowWidth(WWDisplay d, int n)
  67. { return (d->sprite_window_width = n); }
  68. int WWDisplay_SetSpriteWindowHeight(WWDisplay d, int n)
  69. { return (d->sprite_window_height = n); }
  70. int WWDisplay_SetBorder(WWDisplay d, int b) { return (d->border = b); }
  71. int WWDisplay_SetForegroundColor(WWDisplay d, int c)
  72. { return (d->foreground_color = c); }
  73. int WWDisplay_SetBackgroundColor(WWDisplay d, int c)
  74. { return (d->background_color = c); }
  75. int WWDisplay_SetSpriteStart(WWDisplay d, int n)
  76. { return (d->sprite_start = n); }
  77. int WWDisplay_SetSpriteCount(WWDisplay d, int n)
  78. { return (d->sprite_count = n); }
  79. /*===========================================================================*/
  80. /* オブジェクトの生成と消去 */
  81. /*===========================================================================*/
  82. WWDisplay WWDisplay_Create(int lcd_panel_width, int lcd_panel_height,
  83. int screen_width, int screen_height)
  84. {
  85. WWDisplay display;
  86. int i;
  87. static int default_lcd_colors[] = {
  88. 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0f
  89. };
  90. static struct palette_colors {
  91. int colors[4];
  92. } default_palette_colors[] = {
  93. {{0, 3, 5, 7}}, {{2, 3, 5, 7}}, {{0, 0, 0, 7}}, {{2, 0, 0, 7}},
  94. {{0, 0, 3, 7}}, {{0, 7, 7, 7}}, {{0, 7, 7, 7}}, {{0, 0, 2, 7}},
  95. {{2, 5, 7, 7}}, {{7, 7, 7, 7}}, {{7, 6, 5, 7}}, {{3, 7, 5, 7}},
  96. {{0, 0, 4, 7}}, {{0, 0, 0, 7}}, {{0, 7, 7, 5}}, {{0, 7, 3, 7}}
  97. };
  98. display = (WWDisplay)malloc(sizeof(_WWDisplay));
  99. if (display == NULL)
  100. WonX_Error("WWDisplay_Create", "Cannot allocate memory.");
  101. WWDisplay_SetColorMap(display, WWColorMap_Create(default_lcd_colors));
  102. for (i = 0; i < 16; i++) {
  103. WWDisplay_SetPalette(display, i,
  104. WWPalette_Create(i,
  105. default_palette_colors[i].colors,
  106. ((i / 4) % 2) ? 1 : 0));
  107. }
  108. for (i = 0; i < 512; i++) {
  109. WWDisplay_SetCharacter(display, i, WWCharacter_Create(i, NULL));
  110. }
  111. for (i = 0; i < 128; i++) {
  112. WWDisplay_SetSprite(display, i,
  113. WWSprite_Create(i, 0, 0, 0, 0, 0, 0,
  114. WWDisplay_GetPalette(display, 0),
  115. WWDisplay_GetCharacter(display, 0)));
  116. }
  117. for (i = 0; i < 2; i++) {
  118. WWDisplay_SetScreen(display, i,
  119. WWScreen_Create(i, screen_width, screen_height,
  120. WWDisplay_GetPalette(display, 0),
  121. WWDisplay_GetCharacter(display, 0),
  122. 0, 0,
  123. lcd_panel_width, lcd_panel_height));
  124. }
  125. WWDisplay_SetLCDPanel(display, WWLCDPanel_Create(lcd_panel_width,
  126. lcd_panel_height));
  127. /* デフォルトのテキスト表示用パレットは0 */
  128. WWDisplay_SetText(display,
  129. WWText_Create(WWDisplay_GetScreen(display, SCREEN2),
  130. 0, 0,
  131. TEXT_SCREEN_WIDTH, TEXT_SCREEN_HEIGHT,
  132. WWDisplay_GetPalette(display, 0)));
  133. /*
  134. * WWDisplay_GetPalette() を呼び出すので,パレットを設定してから
  135. * カーソルの設定を行うこと.
  136. * デフォルトのカーソルパレットは1
  137. */
  138. WWDisplay_SetCursor(display,
  139. WWCursor_Create(WWDisplay_GetPalette(display, 1)));
  140. WWDisplay_SetSpriteEnable(display, 0);
  141. WWDisplay_SetSpriteWindowEnable(display, 0);
  142. WWDisplay_SetSpriteWindowX( display, 0);
  143. WWDisplay_SetSpriteWindowY( display, 0);
  144. WWDisplay_SetSpriteWindowWidth( display, lcd_panel_width);
  145. WWDisplay_SetSpriteWindowHeight(display, lcd_panel_height);
  146. WWDisplay_SetBorder(display, 0);
  147. WWDisplay_SetForegroundColor(display, 3);
  148. WWDisplay_SetBackgroundColor(display, 0);
  149. WWDisplay_SetSpriteStart(display, 0);
  150. WWDisplay_SetSpriteCount(display, 0);
  151. return (display);
  152. }
  153. WWDisplay WWDisplay_Destroy(WWDisplay display)
  154. {
  155. int i;
  156. if (display == NULL) return (NULL);
  157. if (WWDisplay_GetColorMap(display) != NULL)
  158. WWDisplay_SetColorMap(display,
  159. WWColorMap_Destroy(WWDisplay_GetColorMap(display)));
  160. for (i = 0; i < 16; i++) {
  161. if (WWDisplay_GetPalette(display, i) != NULL)
  162. WWDisplay_SetPalette(display, i,
  163. WWPalette_Destroy(WWDisplay_GetPalette(display, i))
  164. );
  165. }
  166. for (i = 0; i < 512; i++) {
  167. if (WWDisplay_GetCharacter(display, i) != NULL)
  168. WWDisplay_SetCharacter(display, i,
  169. WWCharacter_Destroy(WWDisplay_GetCharacter(display
  170. , i)));
  171. }
  172. for (i = 0; i < 128; i++) {
  173. if (WWDisplay_GetSprite(display, i) != NULL)
  174. WWDisplay_SetSprite(display, i,
  175. WWSprite_Destroy(WWDisplay_GetSprite(display, i)));
  176. }
  177. for (i = 0; i < 2; i++) {
  178. if (WWDisplay_GetScreen(display, i) != NULL)
  179. WWDisplay_SetScreen(display, i,
  180. WWScreen_Destroy(WWDisplay_GetScreen(display, i)));
  181. }
  182. if (WWDisplay_GetLCDPanel(display) != NULL)
  183. WWDisplay_SetLCDPanel(display,
  184. WWLCDPanel_Destroy(WWDisplay_GetLCDPanel(display)));
  185. if (WWDisplay_GetText(display) != NULL)
  186. WWDisplay_SetText(display,
  187. WWText_Destroy(WWDisplay_GetText(display)));
  188. if (WWDisplay_GetCursor(display) != NULL)
  189. WWDisplay_SetCursor(display,
  190. WWCursor_Destroy(WWDisplay_GetCursor(display)));
  191. free(display);
  192. return (NULL);
  193. }
  194. /*===========================================================================*/
  195. /* LCDパネルの描画 */
  196. /*===========================================================================*/
  197. static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen,
  198. WWCursor cursor)
  199. {
  200. WWLCDPanel lcd_panel;
  201. int lcd_panel_width;
  202. int lcd_panel_height;
  203. int pixel;
  204. int x, y, px, py;
  205. int sx = 0, sy = 0, ex = 0, ey = 0;
  206. int mode;
  207. if (!WWScreen_GetEnable(screen)) return (0);
  208. lcd_panel = WWDisplay_GetLCDPanel(display);
  209. lcd_panel_width = WWLCDPanel_GetWidth( lcd_panel);
  210. lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel);
  211. if ( (WWScreen_GetMode(screen) == WW_SCREEN_INSIDE_ONLY) ||
  212. (WWScreen_GetMode(screen) == WW_SCREEN_OUTSIDE_ONLY) ) {
  213. sx = WWScreen_GetDrawX(screen);
  214. sy = WWScreen_GetDrawX(screen);
  215. /*
  216. * マニュアルの screen2_set_window() の説明には「表示領域の横幅と縦幅」と
  217. * 書いてあるが,実際には「表示領域の横幅+1と縦幅+1」で動作する
  218. * みたい?(未確認)なので,-1 しなくてよい?
  219. * もしくは,WonderWitch での実際の動作は,
  220. * ex = sx + WWScreen_GetDrawWidth( screen);
  221. * でなく
  222. * ex = WWScreen_GetDrawWidth( screen);
  223. * なのかもしれない.
  224. */
  225. #if 0
  226. ex = sx + WWScreen_GetDrawWidth( screen) - 1;
  227. ey = sy + WWScreen_GetDrawHeight(screen) - 1;
  228. #else
  229. ex = sx + WWScreen_GetDrawWidth( screen);
  230. ey = sy + WWScreen_GetDrawHeight(screen);
  231. #endif
  232. }
  233. mode = WWScreen_GetMode(screen);
  234. /* 以下はホットスポットになるので,そのうちループアンローリング */
  235. /* したほうがいいかも */
  236. for (y = 0; y < lcd_panel_height; y++) {
  237. if (mode == WW_SCREEN_INSIDE_ONLY) {
  238. if (y > ey) { break; }
  239. if (y < sy) { y = sy - 1; continue; }
  240. }
  241. py = y + WWScreen_GetRollY(screen);
  242. for (x = 0; x < lcd_panel_width; x++) {
  243. if (mode == WW_SCREEN_INSIDE_ONLY) {
  244. if (x > ex) { x = lcd_panel_width - 1; continue; }
  245. if (x < sx) { x = sx - 1; continue; }
  246. } else if (mode == WW_SCREEN_OUTSIDE_ONLY) {
  247. if ( (x >= sx) && (x <= ex) && (y >= sy) && (y <= ey) ) {
  248. x = ex;
  249. continue;
  250. }
  251. }
  252. px = x + WWScreen_GetRollX(screen);
  253. /* 透明色の場合には,-1が返ってくる */
  254. pixel = WWScreen_GetPixel(screen, px, py, cursor);
  255. /* 透明色の場合 */
  256. if (pixel == -1) continue;
  257. pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel);
  258. WWLCDPanel_SetPixel(lcd_panel, x, y, pixel);
  259. }
  260. }
  261. return (0);
  262. }
  263. static int WWDisplay_DrawSprite(WWDisplay display, WWSprite sprite)
  264. {
  265. int x, y, lcd_x, lcd_y;
  266. int sx, sy, ex, ey;
  267. int pixel, outside;
  268. sx = WWDisplay_GetSpriteWindowX(display) - 1;
  269. sy = WWDisplay_GetSpriteWindowY(display) - 1;
  270. /* 以下は WWDisplay_DrawScreen() に合わせた */
  271. #if 0
  272. ex = sx + WWDisplay_GetSpriteWindowWidth(display) - 1;
  273. ey = sy + WWDisplay_GetSpriteWindowHeight(display) - 1;
  274. #else
  275. ex = sx + WWDisplay_GetSpriteWindowWidth(display);
  276. ey = sy + WWDisplay_GetSpriteWindowHeight(display);
  277. #endif
  278. for (y = 0; y < 8; y++) {
  279. for (x = 0; x < 8; x++) {
  280. pixel = WWSprite_GetPixel(sprite, x, y); /* 透明色は-1が返ってくる */
  281. /* 透明色の場合 */
  282. if (pixel == -1) continue;
  283. lcd_x = WWSprite_GetX(sprite) + x;
  284. lcd_y = WWSprite_GetY(sprite) + y;
  285. if (WWDisplay_GetSpriteWindowEnable(display)) {
  286. if ( (lcd_x < sx) || (lcd_y < sy) || (lcd_x > ex) || (lcd_y > ey) )
  287. outside = 1;
  288. else
  289. outside = 0;
  290. if (WWSprite_GetClipping(sprite)) { /* ウインドウの外側部分を表示 */
  291. if (!outside) continue;
  292. } else { /* ウインドウの内側部分を表示 */
  293. if (outside) continue;
  294. }
  295. }
  296. pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel);
  297. WWLCDPanel_SetPixel(WWDisplay_GetLCDPanel(display), lcd_x, lcd_y, pixel);
  298. }
  299. }
  300. return (0);
  301. }
  302. int WWDisplay_DrawLCDPanel(WWDisplay display)
  303. {
  304. WWLCDPanel lcd_panel;
  305. int x, y, i;
  306. int lcd_panel_width;
  307. int lcd_panel_height;
  308. WWColorMap color_map;
  309. int border;
  310. WWScreen screen;
  311. WWSprite sprite;
  312. WWCursor cursor;
  313. lcd_panel = WWDisplay_GetLCDPanel(display);
  314. lcd_panel_width = WWLCDPanel_GetWidth( lcd_panel);
  315. lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel);
  316. color_map = WWDisplay_GetColorMap(display);
  317. border = WWDisplay_GetBorder(display);
  318. /* ボーダーカラーで埋める */
  319. for (x = 0; x < lcd_panel_width; x++) {
  320. for (y = 0; y < lcd_panel_height; y++) {
  321. WWLCDPanel_SetPixel(lcd_panel, x, y,
  322. WWColorMap_GetLCDColor(color_map, border));
  323. }
  324. }
  325. /* スクリーン1描画 */
  326. screen = WWDisplay_GetScreen(display, 0);
  327. if (WWText_GetScreen(WWDisplay_GetText(display)) == screen)
  328. cursor = WWDisplay_GetCursor(display);
  329. else
  330. cursor = NULL;
  331. WWDisplay_DrawScreen(display, screen, cursor);
  332. /* スプライト描画(スクリーン2より優先でないもの) */
  333. /* 重なった場合は,番号の若いものが手前に表示される */
  334. if (WWDisplay_GetSpriteEnable(display)) {
  335. for (i = WWDisplay_GetSpriteCount(display) - 1; i >= 0; i--) {
  336. sprite = WWDisplay_GetSprite(display,
  337. i + WWDisplay_GetSpriteStart(display));
  338. if (!WWSprite_GetPriority(sprite)) {
  339. WWDisplay_DrawSprite(display, sprite);
  340. }
  341. }
  342. }
  343. /* スクリーン2描画 */
  344. screen = WWDisplay_GetScreen(display, 1);
  345. if (WWText_GetScreen(WWDisplay_GetText(display)) == screen)
  346. cursor = WWDisplay_GetCursor(display);
  347. else
  348. cursor = NULL;
  349. WWDisplay_DrawScreen(display, screen, cursor);
  350. /* スプライト描画(スクリーン2より優先なもの) */
  351. /* 重なった場合は,番号の若いものが手前に表示される */
  352. if (WWDisplay_GetSpriteEnable(display)) {
  353. for (i = WWDisplay_GetSpriteCount(display) - 1; i >= 0; i--) {
  354. sprite = WWDisplay_GetSprite(display,
  355. i + WWDisplay_GetSpriteStart(display));
  356. if (WWSprite_GetPriority(sprite)) {
  357. WWDisplay_DrawSprite(display, sprite);
  358. }
  359. }
  360. }
  361. return (0);
  362. }
  363. /*****************************************************************************/
  364. /* ここまで */
  365. /*****************************************************************************/
  366. /*****************************************************************************/
  367. /* End of File. */
  368. /*****************************************************************************/