WWDisplay.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*****************************************************************************/
  2. /* ここから */
  3. /*****************************************************************************/
  4. #include "WWDisplayP.h"
  5. /*****************************************************************************/
  6. /* メンバ関数の定義 */
  7. /*****************************************************************************/
  8. /*===========================================================================*/
  9. /* メンバの取得 */
  10. /*===========================================================================*/
  11. WWColorMap WWDisplay_GetColorMap(WWDisplay d) { return (d->color_map); }
  12. WWPalette WWDisplay_GetPalette(WWDisplay d, int n) { return (d->palette[n]); }
  13. WWCharacter WWDisplay_GetCharacter(WWDisplay d, int n)
  14. { return (d->character[n]); }
  15. WWSprite WWDisplay_GetSprite(WWDisplay d, int n) { return (d->sprite[n]); }
  16. WWScreen WWDisplay_GetScreen(WWDisplay d, int n) { return (d->screen[n]); }
  17. WWLCDPanel WWDisplay_GetLCDPanel(WWDisplay d) { return (d->lcd_panel); }
  18. int WWDisplay_GetSpriteEnable(WWDisplay d) { return (d->sprite_enable); }
  19. int WWDisplay_GetSpriteWindowEnable(WWDisplay d)
  20. { return (d->sprite_window_enable); }
  21. int WWDisplay_GetBorder(WWDisplay d) { return (d->border); }
  22. int WWDisplay_GetForegroundColor(WWDisplay d) { return (d->foreground_color); }
  23. int WWDisplay_GetBackgroundColor(WWDisplay d) { return (d->background_color); }
  24. int WWDisplay_GetSpriteStart(WWDisplay d) { return (d->sprite_start); }
  25. int WWDisplay_GetSpriteCount(WWDisplay d) { return (d->sprite_count); }
  26. /*===========================================================================*/
  27. /* メンバの設定 */
  28. /*===========================================================================*/
  29. WWColorMap WWDisplay_SetColorMap(WWDisplay d, WWColorMap cm)
  30. { return (d->color_map = cm); }
  31. WWPalette WWDisplay_SetPalette(WWDisplay d, int n, WWPalette p)
  32. { return (d->palette[n] = p); }
  33. WWCharacter WWDisplay_SetCharacter(WWDisplay d, int n, WWCharacter c)
  34. { return (d->character[n] = c); }
  35. WWSprite WWDisplay_SetSprite(WWDisplay d, int n, WWSprite s)
  36. { return (d->sprite[n] = s); }
  37. WWScreen WWDisplay_SetScreen(WWDisplay d, int n, WWScreen s)
  38. { return (d->screen[n] = s); }
  39. WWLCDPanel WWDisplay_SetLCDPanel(WWDisplay d, WWLCDPanel p)
  40. { return (d->lcd_panel = p); }
  41. int WWDisplay_SetSpriteEnable(WWDisplay d, int f)
  42. { return (d->sprite_enable = f); }
  43. int WWDisplay_SetSpriteWindowEnable(WWDisplay d, int f)
  44. { return (d->sprite_window_enable = f); }
  45. int WWDisplay_SetBorder(WWDisplay d, int b) { return (d->border = b); }
  46. int WWDisplay_SetForegroundColor(WWDisplay d, int c)
  47. { return (d->foreground_color = c); }
  48. int WWDisplay_SetBackgroundColor(WWDisplay d, int c)
  49. { return (d->background_color = c); }
  50. int WWDisplay_SetSpriteStart(WWDisplay d, int n)
  51. { return (d->sprite_start = n); }
  52. int WWDisplay_SetSpriteCount(WWDisplay d, int n)
  53. { return (d->sprite_count = n); }
  54. /*===========================================================================*/
  55. /* オブジェクトの生成と消去 */
  56. /*===========================================================================*/
  57. WWDisplay WWDisplay_Create(int lcd_panel_width, int lcd_panel_height,
  58. int screen_width, int screen_height)
  59. {
  60. WWDisplay display;
  61. int i;
  62. display = (WWDisplay)malloc(sizeof(_WWDisplay));
  63. if (display == NULL) Error("WWDisplay_Create", "Cannot allocate memory.");
  64. WWDisplay_SetColorMap(display, WWColorMap_Create(NULL));
  65. for (i = 0; i < 16; i++) {
  66. WWDisplay_SetPalette(display, i,
  67. WWPalette_Create(i, NULL, ((i / 4) % 2) ? 1 : 0));
  68. }
  69. for (i = 0; i < 512; i++) {
  70. WWDisplay_SetCharacter(display, i, WWCharacter_Create(i, NULL));
  71. }
  72. for (i = 0; i < 128; i++) {
  73. WWDisplay_SetSprite(display, i,
  74. WWSprite_Create(i, 0, 0, 0, 0, 0, 0,
  75. WWDisplay_GetPalette(display, 0),
  76. WWDisplay_GetCharacter(display, 0)));
  77. }
  78. for (i = 0; i < 2; i++) {
  79. WWDisplay_SetScreen(display, i,
  80. WWScreen_Create(i, screen_width, screen_height,
  81. WWDisplay_GetPalette(display, 0),
  82. WWDisplay_GetCharacter(display, 0),
  83. 0, 0,
  84. lcd_panel_width, lcd_panel_height));
  85. }
  86. WWDisplay_SetLCDPanel(display, WWLCDPanel_Create(lcd_panel_width,
  87. lcd_panel_height));
  88. WWDisplay_SetSpriteEnable(display, 0);
  89. WWDisplay_SetSpriteWindowEnable(display, 0);
  90. WWDisplay_SetBorder(display, 0);
  91. WWDisplay_SetForegroundColor(display, 3);
  92. WWDisplay_SetBackgroundColor(display, 0);
  93. WWDisplay_SetSpriteStart(display, 0);
  94. WWDisplay_SetSpriteCount(display, 0);
  95. return (display);
  96. }
  97. WWDisplay WWDisplay_Destroy(WWDisplay display)
  98. {
  99. int i;
  100. if (display == NULL) return (NULL);
  101. if (WWDisplay_GetColorMap(display) != NULL)
  102. WWDisplay_SetColorMap(display,
  103. WWColorMap_Destroy(WWDisplay_GetColorMap(display)));
  104. for (i = 0; i < 16; i++) {
  105. if (WWDisplay_GetPalette(display, i) != NULL)
  106. WWDisplay_SetPalette(display, i,
  107. WWPalette_Destroy(WWDisplay_GetPalette(display, i))
  108. );
  109. }
  110. for (i = 0; i < 512; i++) {
  111. if (WWDisplay_GetCharacter(display, i) != NULL)
  112. WWDisplay_SetCharacter(display, i,
  113. WWCharacter_Destroy(WWDisplay_GetCharacter(display
  114. , i)));
  115. }
  116. for (i = 0; i < 128; i++) {
  117. if (WWDisplay_GetSprite(display, i) != NULL)
  118. WWDisplay_SetSprite(display, i,
  119. WWSprite_Destroy(WWDisplay_GetSprite(display, i)));
  120. }
  121. for (i = 0; i < 2; i++) {
  122. if (WWDisplay_GetScreen(display, i) != NULL)
  123. WWDisplay_SetScreen(display, i,
  124. WWScreen_Destroy(WWDisplay_GetScreen(display, i)));
  125. }
  126. if (WWDisplay_GetLCDPanel(display) != NULL)
  127. WWDisplay_SetLCDPanel(display,
  128. WWLCDPanel_Destroy(WWDisplay_GetLCDPanel(display)));
  129. free(display);
  130. return (NULL);
  131. }
  132. /*===========================================================================*/
  133. /* LCDパネルの描画 */
  134. /*===========================================================================*/
  135. static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen)
  136. {
  137. WWLCDPanel lcd_panel;
  138. int lcd_panel_width;
  139. int lcd_panel_height;
  140. int pixel;
  141. int x, y, px, py;
  142. int sx, sy, ex, ey;
  143. int mode;
  144. if (!WWScreen_GetEnable(screen)) return (0);
  145. lcd_panel = WWDisplay_GetLCDPanel(display);
  146. lcd_panel_width = WWLCDPanel_GetWidth( lcd_panel);
  147. lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel);
  148. if ( (WWScreen_GetMode(screen) == WWSCREEN_INSIDE_ONLY) ||
  149. (WWScreen_GetMode(screen) == WWSCREEN_OUTSIDE_ONLY) ) {
  150. sx = WWScreen_GetDrawX(screen);
  151. sy = WWScreen_GetDrawX(screen);
  152. /*
  153. * マニュアルの screen2_set_window() の説明には「表示領域の横幅と縦幅」と
  154. * 書いてあるが,実際には「表示領域の横幅+1と縦幅+1」で動作する
  155. * みたい?(未確認)なので,-1 しなくてよい?
  156. * もしくは,WonderWitch での実際の動作は,
  157. * ex = sx + WWScreen_GetDrawWidth( screen);
  158. * でなく
  159. * ex = WWScreen_GetDrawWidth( screen);
  160. * なのかもしれない.
  161. */
  162. #if 0
  163. ex = sx + WWScreen_GetDrawWidth( screen) - 1;
  164. ey = sy + WWScreen_GetDrawHeight(screen) - 1;
  165. #else
  166. ex = sx + WWScreen_GetDrawWidth( screen);
  167. ey = sy + WWScreen_GetDrawHeight(screen);
  168. #endif
  169. }
  170. mode = WWScreen_GetMode(screen);
  171. /* 以下はホットスポットになるので,そのうちループアンローリング */
  172. /* したほうがいいかも */
  173. for (y = 0; y < lcd_panel_height; y++) {
  174. for (x = 0; x < lcd_panel_width; x++) {
  175. px = x + WWScreen_GetRollX(screen);
  176. py = y + WWScreen_GetRollY(screen);
  177. if (mode == WWSCREEN_INSIDE_ONLY) {
  178. if (y > ey) {
  179. x = lcd_panel_width - 1; y = lcd_panel_height - 1; continue;
  180. }
  181. if (y < sy) { x = lcd_panel_width - 1; y = sy - 1; continue; }
  182. if (x > ex) { x = lcd_panel_width - 1; continue; }
  183. if (x < sx) { x = sx - 1; continue; }
  184. } else if (mode == WWSCREEN_OUTSIDE_ONLY) {
  185. if ( (x >= sx) && (x <= ex) && (y >= sy) && (y <= ey) ) {
  186. x = ex;
  187. continue;
  188. }
  189. }
  190. pixel = WWScreen_GetPixel(screen, px, py);
  191. /* 透明色の場合 */
  192. if (pixel == -1) continue;
  193. pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel);
  194. WWLCDPanel_SetPixel(lcd_panel, x, y, pixel);
  195. }
  196. }
  197. return (0);
  198. }
  199. static int WWDisplay_DrawSprite(WWDisplay display, WWSprite sprite)
  200. {
  201. int x, y;
  202. int pixel;
  203. for (y = 0; y < 8; y++) {
  204. for (x = 0; x < 8; x++) {
  205. pixel = WWSprite_GetPixel(sprite, x, y);
  206. /* 透明色の場合 */
  207. if (pixel == -1) continue;
  208. pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel);
  209. WWLCDPanel_SetPixel(WWDisplay_GetLCDPanel(display),
  210. WWSprite_GetX(sprite) + x,
  211. WWSprite_GetY(sprite) + y,
  212. pixel);
  213. }
  214. }
  215. return (0);
  216. }
  217. int WWDisplay_DrawLCDPanel(WWDisplay display)
  218. {
  219. WWLCDPanel lcd_panel;
  220. WWScreen screen;
  221. int x, y, i;
  222. int lcd_panel_width;
  223. int lcd_panel_height;
  224. WWColorMap color_map;
  225. int border;
  226. WWSprite sprite;
  227. lcd_panel = WWDisplay_GetLCDPanel(display);
  228. lcd_panel_width = WWLCDPanel_GetWidth(lcd_panel);
  229. lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel);
  230. color_map = WWDisplay_GetColorMap(display);
  231. border = WWDisplay_GetBorder(display);
  232. /* ボーダーカラーで埋める */
  233. for (x = 0; x < lcd_panel_width; x++) {
  234. for (y = 0; y < lcd_panel_height; y++) {
  235. WWLCDPanel_SetPixel(lcd_panel, x, y,
  236. WWColorMap_GetLCDColor(color_map, border));
  237. }
  238. }
  239. /* スクリーン1描画 */
  240. if (WWDisplay_GetSpriteEnable(display))
  241. WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 0));
  242. /* スプライト描画(スクリーン2より優先でないもの) */
  243. for (i = 0; i < WWDisplay_GetSpriteCount(display); i++) {
  244. sprite = WWDisplay_GetSprite(display,
  245. i + WWDisplay_GetSpriteStart(display));
  246. if (!WWSprite_GetPriority(sprite)) {
  247. WWDisplay_DrawSprite(display, sprite);
  248. }
  249. }
  250. /* スクリーン2描画 */
  251. if (WWDisplay_GetSpriteEnable(display))
  252. WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 1));
  253. /* スプライト描画(スクリーン2より優先なもの) */
  254. for (i = 0; i < WWDisplay_GetSpriteCount(display); i++) {
  255. sprite = WWDisplay_GetSprite(display,
  256. i + WWDisplay_GetSpriteStart(display));
  257. if (WWSprite_GetPriority(sprite)) {
  258. WWDisplay_DrawSprite(display, sprite);
  259. }
  260. }
  261. return (0);
  262. }
  263. /*****************************************************************************/
  264. /* ここまで */
  265. /*****************************************************************************/
  266. /*****************************************************************************/
  267. /* End of File. */
  268. /*****************************************************************************/