WWDisplay.c 13 KB

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