• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: 提交

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

修订版003e13d019f6752dbaa1a07bfa73ba3e55e534b4 (tree)
时间2018-09-19 04:54:58
作者K.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][FMTOWNS][SPRITE][WIP] Implementing sprite.

更改概述

差异

--- a/source/src/vm/fmtowns/towns_sprite.cpp
+++ b/source/src/vm/fmtowns/towns_sprite.cpp
@@ -7,106 +7,1873 @@
77 [ Sprite ]
88 */
99
10-#include "common.h"
10+#include "../../common.h"
1111 #include "./towns_sprite.h"
1212
1313 void TOWNS_SPRITE::initialize(void)
1414 {
15- for(i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
16- dirty_cache_16c[i] = false;
17- dirty_cache_32768c[i] = false;
18- cached_16c[i] = NULL;
19- cached_32768c[i] = NULL;
20- cached_16c[i] = new SPRITE_CACHE(true);
21- cached_256c[i] = new SPRITE_CACHE(false);
22- }
15+ memset(index_ram, 0x00, sizeof(index_ram));
16+ memset(pattern_ram, 0x00, sizeof(pattern_ram));
17+ memset(color_ram, 0x00, sizeof(color_ram));
2318
19+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
20+ memset(&(cache_index[i]), 0x00, sizeof(sprite_cache_t));
21+ cache_index[i].is_use = false;
22+ }
23+ last_put_cache_num = 0;
24+ reg_ctrl = 0x0000; // REG#00, #01
25+ reg_voffset = 0x0000; // REG#02, #03
26+ reg_hoffset = 0x0000; // REG#04, #05
27+ disp_page1 = false;
28+ disp_page0 = false;
29+ reg_spen = false;
30+ reg_addr = 0;
31+ memset(reg_data, 0x00, sizeof(reg_data));
32+ for(int i = 0; i < (sizeof(pattern_cached) / sizeof(bool)); i++) {
33+ pattern_cached[i] = false;
34+ }
35+ for(int i = 0; i < 256; i++) {
36+ color_cached[i] = false;
37+ }
2438 }
2539
26-void TOWNS_SPRITE::clear_cache(int num, bool n_16c)
40+void TOWNS_SPRITE::reset()
41+{
42+ // Clear RAMs?
43+ reg_ctrl = 0x0000; // REG#00, #01
44+ reg_voffset = 0x0000; // REG#02, #03
45+ reg_hoffset = 0x0000; // REG#04, #05
46+ disp_page1 = false;
47+ disp_page0 = false;
48+ reg_spen = false;
49+ reg_addr = 0;
50+ memset(reg_data, 0x00, sizeof(reg_data));
51+
52+}
53+void TOWNS_SPRITE::clear_cache(int num)
2754 {
2855 if(num >= TOWNS_SPRITE_CACHE_NUM) return;
2956 if(num < 0) return;
30- if(n_16c) {
31- if(cached_16c[num] != NULL) {
32- cached_16c[NUM]->clean();
57+ memset(&(cache_index[num]), 0x00, sizeof(sprite_cache_t));
58+ cache_index[num].is_use = false;
59+}
60+
61+void TOWNS_SPRITE::set_sprite_attribute(int table_num, uint16_t num_attr)
62+{
63+ if((table_num < 0) || (table_num > 1023)) return;
64+ uint16_t num = num_attr & 0x3ff;
65+ uint8_t rotate_type = (uint8_t)((num_attr & 0x7000) >> 12);
66+ bool halfx = ((num_attr & 0x0400) != 0);
67+ bool halfy = ((num_attr & 0x0800) != 0);
68+ bool enable_offset = ((num_attr & 0x8000) != 0);
69+ sprite_table[table_num].num = num;
70+ sprite_table[table_num].rotate_type = rotate_type;
71+ sprite_table[table_num].is_halfx = halfx;
72+ sprite_table[table_num].is_halfy = halfy;
73+ sprite_table[table_num].offset = enable_offset;
74+ sprite_table[table_num].attribute = num_attr & 0x7fff;
75+}
76+
77+void TOWNS_SPRITE::set_sprite_color(int table_num, uint16_t color_table_num)
78+{
79+ if((table_num < 0) || (table_num > 1023)) return;
80+ sprite_table[table_num].color = color_table_num & 0x0fff;
81+ sprite_table[table_num].is_32768 = ((color_table_num & 0x8000) == 0);
82+ sprite_table[table_num].is_impose = ((color_table_num & 0x4000) != 0);
83+ sprite_table[table_num].is_disp = ((color_table_num & 0x2000) != 0);
84+}
85+
86+void TOWNS_SPRITE::render_not_rotate(int num, uint16* dst_pixel, int width, int height, int stride)
87+{
88+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
89+ uint8_t* addr;
90+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
91+ uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
92+ if(sprite_table[num].is_32768) {
93+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
94+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
95+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
96+ int w = (cache_index[num].is_halfy) ? 8 : 16;
97+ int h = (cache_index[num].is_halfx) ? 8 : 16;
98+ uint16_t* p;
99+ uint16_t* m;
100+ uint8_t* q;
101+ uint16_t* dp;
102+ int yy = 0;
103+ uint8_t pixels[8];
104+ uint16_t masks[16];
105+ uint16_t tpixels[16];
106+ for(int y = 0; y < 16; y += ystep) {
107+ p = &(cache_pixel[yy << 4]);
108+ m = &(cache_mask[yy << 4]);
109+ q = &(qp[y << 4]);
110+ dp = &(dst_pixel[yy * stride]);
111+ if(cache_index[num].is_halfx) {
112+ for(int x = 0; x < 16; x++) {
113+ pixels[x] = q[x << 1];
114+ }
115+ for(int x = 0; x < 16; x++) {
116+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
117+ }
118+ for(int x = 0; x < 8; x++) {
119+ p[x] = pixels[x];
120+ }
121+ for(int x = 0; x < 8; x++) {
122+ m[x] = masks[x];
123+ }
124+ // Draw to buffer
125+ for(int x = 0; x < 8; x++) {
126+ tpixels[x] = dp[x] & masks[x];
127+ }
128+ for(int x = 0; x < 8; x++) {
129+ pixels[x] = pixels[x] & ~masks[x];
130+ }
131+ for(int x = 0; x < 8; x++) {
132+ dp[x] = pixels[x] | tpixels[x];
133+ }
134+ } else {
135+ for(int x = 0; x < 16; x++) {
136+ pixels[x] = q[x];
137+ }
138+ for(int x = 0; x < 16; x++) {
139+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
140+ }
141+ for(int x = 0; x < 16; x++) {
142+ p[x] = pixels[x];
143+ }
144+ for(int x = 0; x < 16; x++) {
145+ m[x] = masks[x];
146+ }
147+ // Draw to buffer
148+ for(int x = 0; x < 16; x++) {
149+ tpixels[x] = dp[x] & masks[x];
150+ }
151+ for(int x = 0; x < 16; x++) {
152+ pixels[x] = pixels[x] & ~masks[x];
153+ }
154+ for(int x = 0; x < 16; x++) {
155+ dp[x] = pixels[x] | tpixels[x];
156+ }
157+ }
158+ yy++;
159+ }
160+ } else {
161+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
162+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
163+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
164+ int w = (cache_index[num].is_halfy) ? 8 : 16;
165+ int h = (cache_index[num].is_halfx) ? 8 : 16;
166+ int color = sprite_table[num].color;
167+ if(color < 256) return;
168+ if(color > 511) return;
169+ color = color - 256;
170+ uint16_t* p;
171+ uint16_t* m;
172+ uint16_t* q;
173+ uint16_t* dp;
174+ int yy = 0;
175+ uint8_t pixels[16];
176+ uint8_t pixels_lo[16];
177+ uint8_t pixels_hi[16];
178+ uint16_t masks[16];
179+ uint16_t tpixels[16];
180+ uint16_t t2pixels[16];
181+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
182+ for(int y = 0; y < 16; y += ystep) {
183+ p = &(cache_pixel[yy << 4]);
184+ m = &(cache_mask[yy << 4]);
185+ q = (uint8_t*)qp;
186+ q = &q[y << 3];
187+ dp = &(dst_pixel[yy * stride]);
188+ if(cache_index[num].is_halfx) {
189+ for(int x = 0; x < 8; x++) {
190+ pixels[x] = q[x];
191+ }
192+ for(int x = 0; x < 8; x++) {
193+ pixels[x] = pixels[x] & 0xf0;
194+ }
195+
196+ for(int x = 0; x < 8; x++) {
197+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
198+ }
199+ for(int x = 0; x < 8; x++) {
200+ p[x] = color_index[pixels[x]];
201+ }
202+ for(int x = 0; x < 8; x++) {
203+ m[x] = masks[x];
204+ }
205+ // Draw to buffer
206+ for(int x = 0; x < 8; x++) {
207+ tpixels[x] = dp[x] & masks[x];
208+ }
209+ for(int x = 0; x < 8; x++) {
210+ pixels[x] = p[x] & ~masks[x];
211+ }
212+ for(int x = 0; x < 8; x++) {
213+ dp[x] = pixels[x] | tpixels[x];
214+ }
215+ } else {
216+ for(int x = 0; x < 8; x++) {
217+ pixels[x] = q[x];
218+ }
219+ for(int x = 0; x < 8; x++) {
220+ pixels_hi[x] = pixels[x] & 0xf0;
221+ }
222+ for(int x = 0; x < 8; x++) {
223+ pixels_lo[x] = pixels[x] & 0x0f;
224+ }
225+
226+ for(int x = 0; x < 8; x++) {
227+ masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
228+ }
229+ for(int x = 0; x < 8; x++) {
230+ masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
231+ }
232+ for(int x = 0; x < 8; x++) {
233+ p[x << 1] = color_index[pixels_hi[x]];
234+ p[(x << 1) + 1] = color_index[pixels_lo[x]];
235+ }
236+ for(int x = 0; x < 16; x++) {
237+ m[x] = masks[x];
238+ }
239+ // Draw to buffer
240+ for(int x = 0; x < 16; x++) {
241+ tpixels[x] = dp[x] & masks[x];
242+ }
243+ for(int x = 0; x < 16; x++) {
244+ t2pixels[x] = p[x] & ~masks[x];
245+ }
246+ for(int x = 0; x < 16; x++) {
247+ dp[x] = t2pixels[x] | tpixels[x];
248+ }
249+ }
250+ yy++;
251+ }
252+ }
253+}
254+
255+void TOWNS_SPRITE::render_mirror_180(int num, uint16* dst_pixel, int width, int height, int stride)
256+{
257+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
258+ uint8_t* addr;
259+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
260+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
261+ if(sprite_table[num].is_32768) {
262+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
263+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
264+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
265+ int w = (cache_index[num].is_halfy) ? 8 : 16;
266+ int h = (cache_index[num].is_halfx) ? 8 : 16;
267+ uint16_t* p;
268+ uint16_t* m;
269+ uint8_t* q;
270+ uint16_t* dp;
271+ int yy = 0;
272+ uint8_t pixels[8];
273+ uint16_t masks[16];
274+ uint16_t tpixels[16];
275+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
276+ for(int y = ybegin; y >= 0; y -= ystep) {
277+ p = &(cache_pixel[yy << 4]);
278+ m = &(cache_mask[yy << 4]);
279+ q = &(qp[y << 4]);
280+ dp = &(dst_pixel[yy * stride]);
281+ if(cache_index[num].is_halfx) {
282+ for(int x = 0; x < 16; x++) {
283+ pixels[x] = q[x << 1];
284+ }
285+ for(int x = 0; x < 16; x++) {
286+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
287+ }
288+ for(int x = 0; x < 8; x++) {
289+ p[x] = pixels[x];
290+ }
291+ for(int x = 0; x < 8; x++) {
292+ m[x] = masks[x];
293+ }
294+ // Draw to buffer
295+ for(int x = 0; x < 8; x++) {
296+ tpixels[x] = dp[x] & masks[x];
297+ }
298+ for(int x = 0; x < 8; x++) {
299+ pixels[x] = pixels[x] & ~masks[x];
300+ }
301+ for(int x = 0; x < 8; x++) {
302+ dp[x] = pixels[x] | tpixels[x];
303+ }
304+ } else {
305+ for(int x = 0; x < 16; x++) {
306+ pixels[x] = q[x];
307+ }
308+ for(int x = 0; x < 16; x++) {
309+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
310+ }
311+ for(int x = 0; x < 16; x++) {
312+ p[x] = pixels[x];
313+ }
314+ for(int x = 0; x < 16; x++) {
315+ m[x] = masks[x];
316+ }
317+ // Draw to buffer
318+ for(int x = 0; x < 16; x++) {
319+ tpixels[x] = dp[x] & masks[x];
320+ }
321+ for(int x = 0; x < 16; x++) {
322+ pixels[x] = pixels[x] & ~masks[x];
323+ }
324+ for(int x = 0; x < 16; x++) {
325+ dp[x] = pixels[x] | tpixels[x];
326+ }
327+ }
328+ yy++;
329+ }
330+ } else {
331+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
332+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
333+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
334+ int w = (cache_index[num].is_halfy) ? 8 : 16;
335+ int h = (cache_index[num].is_halfx) ? 8 : 16;
336+ int color = sprite_table[num].color;
337+ if(color < 256) return;
338+ if(color > 511) return;
339+ color = color - 256;
340+ uint16_t* p;
341+ uint16_t* m;
342+ uint16_t* q;
343+ uint16_t* dp;
344+ int yy = 0;
345+ uint8_t pixels[16];
346+ uint8_t pixels_lo[16];
347+ uint8_t pixels_hi[16];
348+ uint16_t masks[16];
349+ uint16_t tpixels[16];
350+ uint16_t t2pixels[16];
351+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
352+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
353+ for(int y = ybegin; y >= 0; y -= ystep) {
354+ p = &(cache_pixel[yy << 4]);
355+ m = &(cache_mask[yy << 4]);
356+ q = (uint8_t*)qp;
357+ q = &q[y << 3];
358+ dp = &(dst_pixel[yy * stride]);
359+ if(cache_index[num].is_halfx) {
360+ for(int x = 0; x < 8; x++) {
361+ pixels[x] = q[x];
362+ }
363+ for(int x = 0; x < 8; x++) {
364+ pixels[x] = pixels[x] & 0xf0;
365+ }
366+
367+ for(int x = 0; x < 8; x++) {
368+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
369+ }
370+ for(int x = 0; x < 8; x++) {
371+ p[x] = color_index[pixels[x]];
372+ }
373+ for(int x = 0; x < 8; x++) {
374+ m[x] = masks[x];
375+ }
376+ // Draw to buffer
377+ for(int x = 0; x < 8; x++) {
378+ tpixels[x] = dp[x] & masks[x];
379+ }
380+ for(int x = 0; x < 8; x++) {
381+ pixels[x] = p[x] & ~masks[x];
382+ }
383+ for(int x = 0; x < 8; x++) {
384+ dp[x] = pixels[x] | tpixels[x];
385+ }
386+ } else {
387+ for(int x = 0; x < 8; x++) {
388+ pixels[x] = q[x];
389+ }
390+ for(int x = 0; x < 8; x++) {
391+ pixels_hi[x] = pixels[x] & 0xf0;
392+ }
393+ for(int x = 0; x < 8; x++) {
394+ pixels_lo[x] = pixels[x] & 0x0f;
395+ }
396+
397+ for(int x = 0; x < 8; x++) {
398+ masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
399+ }
400+ for(int x = 0; x < 8; x++) {
401+ masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
402+ }
403+ for(int x = 0; x < 8; x++) {
404+ p[x << 1] = color_index[pixels_hi[x]];
405+ p[(x << 1) + 1] = color_index[pixels_lo[x]];
406+ }
407+ for(int x = 0; x < 16; x++) {
408+ m[x] = masks[x];
409+ }
410+ // Draw to buffer
411+ for(int x = 0; x < 16; x++) {
412+ tpixels[x] = dp[x] & masks[x];
413+ }
414+ for(int x = 0; x < 16; x++) {
415+ t2pixels[x] = p[x] & ~masks[x];
416+ }
417+ for(int x = 0; x < 16; x++) {
418+ dp[x] = t2pixels[x] | tpixels[x];
419+ }
420+ }
421+ yy++;
422+ }
423+ }
424+
425+}
426+
427+void TOWNS_SPRITE::render_mirror_0(int num, uint16* dst_pixel, int width, int height, int stride)
428+{
429+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
430+ uint8_t* addr;
431+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
432+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
433+ if(sprite_table[num].is_32768) {
434+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
435+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
436+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
437+ int w = (cache_index[num].is_halfy) ? 8 : 16;
438+ int h = (cache_index[num].is_halfx) ? 8 : 16;
439+ uint16_t* p;
440+ uint16_t* m;
441+ uint8_t* q;
442+ uint16_t* dp;
443+ int yy = 0;
444+ uint8_t pixels[8];
445+ uint16_t masks[16];
446+ uint16_t tpixels[16];
447+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
448+ for(int y = ybegin; y >= 0; y -= ystep) {
449+ p = &(cache_pixel[yy << 4]);
450+ m = &(cache_mask[yy << 4]);
451+ q = &(qp[y << 4]);
452+ dp = &(dst_pixel[yy * stride]);
453+ if(cache_index[num].is_halfx) {
454+ for(int x = 0; x < 16; x++) {
455+ pixels[x] = q[x << 1];
456+ }
457+ for(int x = 0; x < 16; x++) {
458+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
459+ }
460+ for(int x = 0; x < 8; x++) {
461+ p[x] = pixels[x];
462+ }
463+ for(int x = 0; x < 8; x++) {
464+ m[x] = masks[x];
465+ }
466+ // Draw to buffer
467+ for(int x = 0; x < 8; x++) {
468+ tpixels[x] = dp[x] & masks[x];
469+ }
470+ for(int x = 0; x < 8; x++) {
471+ pixels[x] = pixels[x] & ~masks[x];
472+ }
473+ for(int x = 0; x < 8; x++) {
474+ dp[7 - x] = pixels[x] | tpixels[x];
475+ }
476+ } else {
477+ for(int x = 0; x < 16; x++) {
478+ pixels[x] = q[x];
479+ }
480+ for(int x = 0; x < 16; x++) {
481+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
482+ }
483+ for(int x = 0; x < 16; x++) {
484+ p[x] = pixels[x];
485+ }
486+ for(int x = 0; x < 16; x++) {
487+ m[x] = masks[x];
488+ }
489+ // Draw to buffer
490+ for(int x = 0; x < 16; x++) {
491+ tpixels[x] = dp[x] & masks[x];
492+ }
493+ for(int x = 0; x < 16; x++) {
494+ pixels[x] = pixels[x] & ~masks[x];
495+ }
496+ for(int x = 0; x < 16; x++) {
497+ dp[15 - x] = pixels[x] | tpixels[x];
498+ }
499+ }
500+ yy++;
501+ }
502+ } else {
503+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
504+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
505+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
506+ int w = (cache_index[num].is_halfy) ? 8 : 16;
507+ int h = (cache_index[num].is_halfx) ? 8 : 16;
508+ int color = sprite_table[num].color;
509+ if(color < 256) return;
510+ if(color > 511) return;
511+ color = color - 256;
512+ uint16_t* p;
513+ uint16_t* m;
514+ uint16_t* q;
515+ uint16_t* dp;
516+ int yy = 0;
517+ uint8_t pixels[16];
518+ uint8_t pixels_lo[16];
519+ uint8_t pixels_hi[16];
520+ uint16_t masks[16];
521+ uint16_t tpixels[16];
522+ uint16_t t2pixels[16];
523+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
524+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
525+ for(int y = ybegin; y >= 0; y -= ystep) {
526+ p = &(cache_pixel[yy << 4]);
527+ m = &(cache_mask[yy << 4]);
528+ q = (uint8_t*)qp;
529+ q = &q[y << 3];
530+ dp = &(dst_pixel[yy * stride]);
531+ if(cache_index[num].is_halfx) {
532+ for(int x = 0; x < 8; x++) {
533+ pixels[x] = q[x];
534+ }
535+ for(int x = 0; x < 8; x++) {
536+ pixels[x] = pixels[x] & 0xf0;
537+ }
538+
539+ for(int x = 0; x < 8; x++) {
540+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
541+ }
542+ for(int x = 0; x < 8; x++) {
543+ p[x] = color_index[pixels[x]];
544+ }
545+ for(int x = 0; x < 8; x++) {
546+ m[x] = masks[x];
547+ }
548+ // Draw to buffer
549+ for(int x = 0; x < 8; x++) {
550+ tpixels[x] = dp[x] & masks[x];
551+ }
552+ for(int x = 0; x < 8; x++) {
553+ pixels[x] = p[x] & ~masks[x];
554+ }
555+ for(int x = 0; x < 8; x++) {
556+ dp[7 - x] = pixels[x] | tpixels[x];
557+ }
558+ } else {
559+ for(int x = 0; x < 8; x++) {
560+ pixels[x] = q[x];
561+ }
562+ for(int x = 0; x < 8; x++) {
563+ pixels_hi[x] = pixels[x] & 0xf0;
564+ }
565+ for(int x = 0; x < 8; x++) {
566+ pixels_lo[x] = pixels[x] & 0x0f;
567+ }
568+
569+ for(int x = 0; x < 8; x++) {
570+ masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
571+ }
572+ for(int x = 0; x < 8; x++) {
573+ masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
574+ }
575+ for(int x = 0; x < 8; x++) {
576+ p[x << 1] = color_index[pixels_hi[x]];
577+ p[(x << 1) + 1] = color_index[pixels_lo[x]];
578+ }
579+ for(int x = 0; x < 16; x++) {
580+ m[x] = masks[x];
581+ }
582+ // Draw to buffer
583+ for(int x = 0; x < 16; x++) {
584+ tpixels[x] = dp[x] & masks[x];
585+ }
586+ for(int x = 0; x < 16; x++) {
587+ t2pixels[x] = p[x] & ~masks[x];
588+ }
589+ for(int x = 0; x < 16; x++) {
590+ dp[15 - x] = t2pixels[x] | tpixels[x];
591+ }
592+ }
593+ yy++;
594+ }
595+ }
596+
597+}
598+
599+void TOWNS_SPRITE::render_rotate_180(int num, uint16* dst_pixel, int width, int height, int stride)
600+{
601+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
602+ uint8_t* addr;
603+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
604+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
605+ if(sprite_table[num].is_32768) {
606+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
607+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
608+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
609+ int w = (cache_index[num].is_halfy) ? 8 : 16;
610+ int h = (cache_index[num].is_halfx) ? 8 : 16;
611+ uint16_t* p;
612+ uint16_t* m;
613+ uint8_t* q;
614+ uint16_t* dp;
615+ int yy = 0;
616+ uint8_t pixels[8];
617+ uint16_t masks[16];
618+ uint16_t tpixels[16];
619+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
620+ for(int y = ybegin; y >= 0; y -= ystep) {
621+ p = &(cache_pixel[yy << 4]);
622+ m = &(cache_mask[yy << 4]);
623+ q = &(qp[y << 4]);
624+ dp = &(dst_pixel[yy * stride]);
625+ if(cache_index[num].is_halfx) {
626+ for(int x = 0; x < 16; x++) {
627+ pixels[x] = q[x << 1];
628+ }
629+ for(int x = 0; x < 16; x++) {
630+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
631+ }
632+ for(int x = 0; x < 8; x++) {
633+ p[x] = pixels[x];
634+ }
635+ for(int x = 0; x < 8; x++) {
636+ m[x] = masks[x];
637+ }
638+ // Draw to buffer
639+ for(int x = 0; x < 8; x++) {
640+ tpixels[x] = dp[x] & masks[x];
641+ }
642+ for(int x = 0; x < 8; x++) {
643+ pixels[x] = pixels[x] & ~masks[x];
644+ }
645+ for(int x = 0; x < 8; x++) {
646+ dp[7 - x] = pixels[x] | tpixels[x];
647+ }
648+ } else {
649+ for(int x = 0; x < 16; x++) {
650+ pixels[x] = q[x];
651+ }
652+ for(int x = 0; x < 16; x++) {
653+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
654+ }
655+ for(int x = 0; x < 16; x++) {
656+ p[x] = pixels[x];
657+ }
658+ for(int x = 0; x < 16; x++) {
659+ m[x] = masks[x];
660+ }
661+ // Draw to buffer
662+ for(int x = 0; x < 16; x++) {
663+ tpixels[x] = dp[x] & masks[x];
664+ }
665+ for(int x = 0; x < 16; x++) {
666+ pixels[x] = pixels[x] & ~masks[x];
667+ }
668+ for(int x = 0; x < 16; x++) {
669+ dp[15 - x] = pixels[x] | tpixels[x];
670+ }
671+ }
672+ yy++;
673+ }
674+ } else {
675+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
676+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
677+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
678+ int w = (cache_index[num].is_halfy) ? 8 : 16;
679+ int h = (cache_index[num].is_halfx) ? 8 : 16;
680+ int color = sprite_table[num].color;
681+ if(color < 256) return;
682+ if(color > 511) return;
683+ color = color - 256;
684+ uint16_t* p;
685+ uint16_t* m;
686+ uint16_t* q;
687+ uint16_t* dp;
688+ int yy = 0;
689+ uint8_t pixels[16];
690+ uint8_t pixels_lo[16];
691+ uint8_t pixels_hi[16];
692+ uint16_t masks[16];
693+ uint16_t tpixels[16];
694+ uint16_t t2pixels[16];
695+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
696+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
697+ for(int y = ybegin; y >= 0; y -= ystep) {
698+ p = &(cache_pixel[yy << 4]);
699+ m = &(cache_mask[yy << 4]);
700+ q = (uint8_t*)qp;
701+ q = &q[y << 3];
702+ dp = &(dst_pixel[yy * stride]);
703+ if(cache_index[num].is_halfx) {
704+ for(int x = 0; x < 8; x++) {
705+ pixels[x] = q[x];
706+ }
707+ for(int x = 0; x < 8; x++) {
708+ pixels[x] = pixels[x] & 0xf0;
709+ }
710+
711+ for(int x = 0; x < 8; x++) {
712+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
713+ }
714+ for(int x = 0; x < 8; x++) {
715+ p[x] = color_index[pixels[x]];
716+ }
717+ for(int x = 0; x < 8; x++) {
718+ m[x] = masks[x];
719+ }
720+ // Draw to buffer
721+ for(int x = 0; x < 8; x++) {
722+ tpixels[x] = dp[x] & masks[x];
723+ }
724+ for(int x = 0; x < 8; x++) {
725+ pixels[x] = p[x] & ~masks[x];
726+ }
727+ for(int x = 0; x < 8; x++) {
728+ dp[7 - x] = pixels[x] | tpixels[x];
729+ }
730+ } else {
731+ for(int x = 0; x < 8; x++) {
732+ pixels[x] = q[x];
733+ }
734+ for(int x = 0; x < 8; x++) {
735+ pixels_hi[x] = pixels[x] & 0xf0;
736+ }
737+ for(int x = 0; x < 8; x++) {
738+ pixels_lo[x] = pixels[x] & 0x0f;
739+ }
740+
741+ for(int x = 0; x < 8; x++) {
742+ masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
743+ }
744+ for(int x = 0; x < 8; x++) {
745+ masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
746+ }
747+ for(int x = 0; x < 8; x++) {
748+ p[x << 1] = color_index[pixels_hi[x]];
749+ p[(x << 1) + 1] = color_index[pixels_lo[x]];
750+ }
751+ for(int x = 0; x < 16; x++) {
752+ m[x] = masks[x];
753+ }
754+ // Draw to buffer
755+ for(int x = 0; x < 16; x++) {
756+ tpixels[x] = dp[x] & masks[x];
757+ }
758+ for(int x = 0; x < 16; x++) {
759+ t2pixels[x] = p[x] & ~masks[x];
760+ }
761+ for(int x = 0; x < 16; x++) {
762+ dp[15 - x] = t2pixels[x] | tpixels[x];
763+ }
764+ }
765+ yy++;
766+ }
767+ }
768+
769+}
770+
771+void TOWNS_SPRITE::render_mirror_270(int num, uint16* dst_pixel, int width, int height, int stride)
772+{
773+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
774+ uint8_t* addr;
775+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
776+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
777+ if(sprite_table[num].is_32768) {
778+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
779+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
780+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
781+ int w = (cache_index[num].is_halfy) ? 8 : 16;
782+ int h = (cache_index[num].is_halfx) ? 8 : 16;
783+ uint16_t* p;
784+ uint16_t* m;
785+ uint16_t* dp;
786+ int yy = 0;
787+ uint8_t pixels[8];
788+ uint16_t masks[16];
789+ uint16_t tpixels[16];
790+ uint16_t pcache[16];
791+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
792+ for(int y = ybegin; y >= 0; y -= ystep) {
793+ p = &(cache_pixel[yy << 4]);
794+ m = &(cache_mask[yy << 4]);
795+ for(int x = 0; x < 16; x++) {
796+ pcache[x] = qp[(x << 4) + y];
797+ }
798+ dp = &(dst_pixel[yy * stride]);
799+ if(cache_index[num].is_halfx) {
800+ for(int x = 0; x < 8; x++) {
801+ pixels[x] = pcache[x << 1];
802+ }
803+ for(int x = 0; x < 8; x++) {
804+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
805+ }
806+ for(int x = 0; x < 8; x++) {
807+ p[x] = pixels[x];
808+ }
809+ for(int x = 0; x < 8; x++) {
810+ m[x] = masks[x];
811+ }
812+ // Draw to buffer
813+ for(int x = 0; x < 8; x++) {
814+ tpixels[x] = dp[x] & masks[x];
815+ }
816+ for(int x = 0; x < 8; x++) {
817+ pixels[x] = pixels[x] & ~masks[x];
818+ }
819+ for(int x = 0; x < 8; x++) {
820+ dp[7 - x] = pixels[x] | tpixels[x];
821+ }
822+ } else {
823+ for(int x = 0; x < 16; x++) {
824+ pixels[x] = pcache[x];
825+ }
826+ for(int x = 0; x < 16; x++) {
827+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
828+ }
829+ for(int x = 0; x < 16; x++) {
830+ p[x] = pixels[x];
831+ }
832+ for(int x = 0; x < 16; x++) {
833+ m[x] = masks[x];
834+ }
835+ // Draw to buffer
836+ for(int x = 0; x < 16; x++) {
837+ tpixels[x] = dp[x] & masks[x];
838+ }
839+ for(int x = 0; x < 16; x++) {
840+ pixels[x] = pixels[x] & ~masks[x];
841+ }
842+ for(int x = 0; x < 16; x++) {
843+ dp[15 - x] = pixels[x] | tpixels[x];
844+ }
845+ }
846+ yy++;
847+ }
848+ } else {
849+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
850+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
851+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
852+ int w = (cache_index[num].is_halfy) ? 8 : 16;
853+ int h = (cache_index[num].is_halfx) ? 8 : 16;
854+ int color = sprite_table[num].color;
855+ if(color < 256) return;
856+ if(color > 511) return;
857+ color = color - 256;
858+ uint16_t* p;
859+ uint16_t* m;
860+ uint16_t* dp;
861+ int yy = 0;
862+ uint8_t pixels[16];
863+ uint8_t pixels_lo[16];
864+ uint8_t pixels_hi[16];
865+ uint16_t masks[16];
866+ uint16_t tpixels[16];
867+ uint16_t t2pixels[16];
868+ uint8_t pcache[16];
869+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
870+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
871+ for(int y = ybegin; y >= 0; y -= ystep) {
872+ p = &(cache_pixel[yy << 4]);
873+ m = &(cache_mask[yy << 4]);
874+ for(int x = 0; x < 8; x++) {
875+ pcache[x << 1] = qp[(x << 4) + y] & 0xf0;
876+ pcache[(x << 1) + 1] = qp[(x << 4) + y] & 0x0f;
877+ }
878+ dp = &(dst_pixel[yy * stride]);
879+ if(cache_index[num].is_halfx) {
880+ for(int x = 0; x < 8; x++) {
881+ pixels[x] = pcache[x << 1];
882+ }
883+ for(int x = 0; x < 8; x++) {
884+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
885+ }
886+ for(int x = 0; x < 8; x++) {
887+ p[x] = color_index[pixels[x]];
888+ }
889+ for(int x = 0; x < 8; x++) {
890+ m[x] = masks[x];
891+ }
892+ // Draw to buffer
893+ for(int x = 0; x < 8; x++) {
894+ tpixels[x] = dp[x] & masks[x];
895+ }
896+ for(int x = 0; x < 8; x++) {
897+ pixels[x] = p[x] & ~masks[x];
898+ }
899+ for(int x = 0; x < 8; x++) {
900+ dp[7 - x] = pixels[x] | tpixels[x];
901+ }
902+ } else {
903+ for(int x = 0; x < 16; x++) {
904+ pixels[x] = pcache[x];
905+ }
906+ for(int x = 0; x < 16; x++) {
907+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
908+ }
909+ for(int x = 0; x < 16; x++) {
910+ p[x] = color_index[pixels[x]];
911+ }
912+ for(int x = 0; x < 16; x++) {
913+ m[x] = masks[x];
914+ }
915+ // Draw to buffer
916+ for(int x = 0; x < 16; x++) {
917+ tpixels[x] = dp[x] & masks[x];
918+ }
919+ for(int x = 0; x < 16; x++) {
920+ t2pixels[x] = p[x] & ~masks[x];
921+ }
922+ for(int x = 0; x < 16; x++) {
923+ dp[15 - x] = t2pixels[x] | tpixels[x];
924+ }
925+ }
926+ yy++;
927+ }
928+ }
929+
930+}
931+
932+
933+void TOWNS_SPRITE::render_rotate_90(int num, uint16* dst_pixel, int width, int height, int stride)
934+{
935+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
936+ uint8_t* addr;
937+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
938+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
939+ if(sprite_table[num].is_32768) {
940+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
941+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
942+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
943+ int w = (cache_index[num].is_halfy) ? 8 : 16;
944+ int h = (cache_index[num].is_halfx) ? 8 : 16;
945+ uint16_t* p;
946+ uint16_t* m;
947+ uint16_t* dp;
948+ int yy = 0;
949+ uint8_t pixels[8];
950+ uint16_t masks[16];
951+ uint16_t tpixels[16];
952+ uint16_t pcache[16];
953+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
954+ for(int y = ybegin; y >= 0; y -= ystep) {
955+ p = &(cache_pixel[yy << 4]);
956+ m = &(cache_mask[yy << 4]);
957+ for(int x = 0; x < 16; x++) {
958+ pcache[x] = qp[(x << 4) + (15 - y)];
959+ }
960+ dp = &(dst_pixel[yy * stride]);
961+ if(cache_index[num].is_halfx) {
962+ for(int x = 0; x < 8; x++) {
963+ pixels[x] = pcache[x << 1];
964+ }
965+ for(int x = 0; x < 8; x++) {
966+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
967+ }
968+ for(int x = 0; x < 8; x++) {
969+ p[x] = pixels[x];
970+ }
971+ for(int x = 0; x < 8; x++) {
972+ m[x] = masks[x];
973+ }
974+ // Draw to buffer
975+ for(int x = 0; x < 8; x++) {
976+ tpixels[x] = dp[x] & masks[x];
977+ }
978+ for(int x = 0; x < 8; x++) {
979+ pixels[x] = pixels[x] & ~masks[x];
980+ }
981+ for(int x = 0; x < 8; x++) {
982+ dp[7 - x] = pixels[x] | tpixels[x];
983+ }
984+ } else {
985+ for(int x = 0; x < 16; x++) {
986+ pixels[x] = pcache[x];
987+ }
988+ for(int x = 0; x < 16; x++) {
989+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
990+ }
991+ for(int x = 0; x < 16; x++) {
992+ p[x] = pixels[x];
993+ }
994+ for(int x = 0; x < 16; x++) {
995+ m[x] = masks[x];
996+ }
997+ // Draw to buffer
998+ for(int x = 0; x < 16; x++) {
999+ tpixels[x] = dp[x] & masks[x];
1000+ }
1001+ for(int x = 0; x < 16; x++) {
1002+ pixels[x] = pixels[x] & ~masks[x];
1003+ }
1004+ for(int x = 0; x < 16; x++) {
1005+ dp[15 - x] = pixels[x] | tpixels[x];
1006+ }
1007+ }
1008+ yy++;
1009+ }
1010+ } else {
1011+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
1012+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
1013+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
1014+ int w = (cache_index[num].is_halfy) ? 8 : 16;
1015+ int h = (cache_index[num].is_halfx) ? 8 : 16;
1016+ int color = sprite_table[num].color;
1017+ if(color < 256) return;
1018+ if(color > 511) return;
1019+ color = color - 256;
1020+ uint16_t* p;
1021+ uint16_t* m;
1022+ uint16_t* dp;
1023+ int yy = 0;
1024+ uint8_t pixels[16];
1025+ uint8_t pixels_lo[16];
1026+ uint8_t pixels_hi[16];
1027+ uint16_t masks[16];
1028+ uint16_t tpixels[16];
1029+ uint16_t t2pixels[16];
1030+ uint8_t pcache[16];
1031+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
1032+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
1033+ for(int y = ybegin; y >= 0; y -= ystep) {
1034+ p = &(cache_pixel[yy << 4]);
1035+ m = &(cache_mask[yy << 4]);
1036+ for(int x = 0; x < 8; x++) {
1037+ pcache[x << 1] = qp[(x << 4) + (15 - y)] & 0xf0;
1038+ pcache[(x << 1) + 1] = qp[(x << 4) + (15 - y)] & 0x0f;
1039+ }
1040+ dp = &(dst_pixel[yy * stride]);
1041+ if(cache_index[num].is_halfx) {
1042+ for(int x = 0; x < 8; x++) {
1043+ pixels[x] = pcache[x << 1];
1044+ }
1045+ for(int x = 0; x < 8; x++) {
1046+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1047+ }
1048+ for(int x = 0; x < 8; x++) {
1049+ p[x] = color_index[pixels[x]];
1050+ }
1051+ for(int x = 0; x < 8; x++) {
1052+ m[x] = masks[x];
1053+ }
1054+ // Draw to buffer
1055+ for(int x = 0; x < 8; x++) {
1056+ tpixels[x] = dp[x] & masks[x];
1057+ }
1058+ for(int x = 0; x < 8; x++) {
1059+ pixels[x] = p[x] & ~masks[x];
1060+ }
1061+ for(int x = 0; x < 8; x++) {
1062+ dp[7 - x] = pixels[x] | tpixels[x];
1063+ }
1064+ } else {
1065+ for(int x = 0; x < 16; x++) {
1066+ pixels[x] = pcache[x];
1067+ }
1068+ for(int x = 0; x < 16; x++) {
1069+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1070+ }
1071+ for(int x = 0; x < 16; x++) {
1072+ p[x] = color_index[pixels[x]];
1073+ }
1074+ for(int x = 0; x < 16; x++) {
1075+ m[x] = masks[x];
1076+ }
1077+ // Draw to buffer
1078+ for(int x = 0; x < 16; x++) {
1079+ tpixels[x] = dp[x] & masks[x];
1080+ }
1081+ for(int x = 0; x < 16; x++) {
1082+ t2pixels[x] = p[x] & ~masks[x];
1083+ }
1084+ for(int x = 0; x < 16; x++) {
1085+ dp[15 - x] = t2pixels[x] | tpixels[x];
1086+ }
1087+ }
1088+ yy++;
1089+ }
1090+ }
1091+
1092+}
1093+
1094+void TOWNS_SPRITE::render_rotate_270(int num, uint16* dst_pixel, int width, int height, int stride)
1095+{
1096+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
1097+ uint8_t* addr;
1098+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
1099+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
1100+ if(sprite_table[num].is_32768) {
1101+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
1102+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
1103+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
1104+ int w = (cache_index[num].is_halfy) ? 8 : 16;
1105+ int h = (cache_index[num].is_halfx) ? 8 : 16;
1106+ uint16_t* p;
1107+ uint16_t* m;
1108+ uint16_t* dp;
1109+ int yy = 0;
1110+ uint8_t pixels[8];
1111+ uint16_t masks[16];
1112+ uint16_t tpixels[16];
1113+ uint16_t pcache[16];
1114+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
1115+ for(int y = ybegin; y >= 0; y -= ystep) {
1116+ p = &(cache_pixel[yy << 4]);
1117+ m = &(cache_mask[yy << 4]);
1118+ for(int x = 0; x < 16; x++) {
1119+ pcache[x] = qp[((15 - x) << 4) + y];
1120+ }
1121+ dp = &(dst_pixel[yy * stride]);
1122+ if(cache_index[num].is_halfx) {
1123+ for(int x = 0; x < 8; x++) {
1124+ pixels[x] = pcache[x << 1];
1125+ }
1126+ for(int x = 0; x < 8; x++) {
1127+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
1128+ }
1129+ for(int x = 0; x < 8; x++) {
1130+ p[x] = pixels[x];
1131+ }
1132+ for(int x = 0; x < 8; x++) {
1133+ m[x] = masks[x];
1134+ }
1135+ // Draw to buffer
1136+ for(int x = 0; x < 8; x++) {
1137+ tpixels[x] = dp[x] & masks[x];
1138+ }
1139+ for(int x = 0; x < 8; x++) {
1140+ pixels[x] = pixels[x] & ~masks[x];
1141+ }
1142+ for(int x = 0; x < 8; x++) {
1143+ dp[7 - x] = pixels[x] | tpixels[x];
1144+ }
1145+ } else {
1146+ for(int x = 0; x < 16; x++) {
1147+ pixels[x] = pcache[x];
1148+ }
1149+ for(int x = 0; x < 16; x++) {
1150+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
1151+ }
1152+ for(int x = 0; x < 16; x++) {
1153+ p[x] = pixels[x];
1154+ }
1155+ for(int x = 0; x < 16; x++) {
1156+ m[x] = masks[x];
1157+ }
1158+ // Draw to buffer
1159+ for(int x = 0; x < 16; x++) {
1160+ tpixels[x] = dp[x] & masks[x];
1161+ }
1162+ for(int x = 0; x < 16; x++) {
1163+ pixels[x] = pixels[x] & ~masks[x];
1164+ }
1165+ for(int x = 0; x < 16; x++) {
1166+ dp[15 - x] = pixels[x] | tpixels[x];
1167+ }
1168+ }
1169+ yy++;
1170+ }
1171+ } else {
1172+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
1173+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
1174+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
1175+ int w = (cache_index[num].is_halfy) ? 8 : 16;
1176+ int h = (cache_index[num].is_halfx) ? 8 : 16;
1177+ int color = sprite_table[num].color;
1178+ if(color < 256) return;
1179+ if(color > 511) return;
1180+ color = color - 256;
1181+ uint16_t* p;
1182+ uint16_t* m;
1183+ uint16_t* dp;
1184+ int yy = 0;
1185+ uint8_t pixels[16];
1186+ uint8_t pixels_lo[16];
1187+ uint8_t pixels_hi[16];
1188+ uint16_t masks[16];
1189+ uint16_t tpixels[16];
1190+ uint16_t t2pixels[16];
1191+ uint8_t pcache[16];
1192+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
1193+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
1194+ for(int y = ybegin; y >= 0; y -= ystep) {
1195+ p = &(cache_pixel[yy << 4]);
1196+ m = &(cache_mask[yy << 4]);
1197+ for(int x = 0; x < 8; x++) {
1198+ pcache[x << 1] = qp[((7 - x) << 4) + y] & 0xf0;
1199+ pcache[(x << 1) + 1] = qp[((7 - x) << 4) + y] & 0x0f;
1200+ }
1201+ dp = &(dst_pixel[yy * stride]);
1202+ if(cache_index[num].is_halfx) {
1203+ for(int x = 0; x < 8; x++) {
1204+ pixels[x] = pcache[x << 1];
1205+ }
1206+ for(int x = 0; x < 8; x++) {
1207+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1208+ }
1209+ for(int x = 0; x < 8; x++) {
1210+ p[x] = color_index[pixels[x]];
1211+ }
1212+ for(int x = 0; x < 8; x++) {
1213+ m[x] = masks[x];
1214+ }
1215+ // Draw to buffer
1216+ for(int x = 0; x < 8; x++) {
1217+ tpixels[x] = dp[x] & masks[x];
1218+ }
1219+ for(int x = 0; x < 8; x++) {
1220+ pixels[x] = p[x] & ~masks[x];
1221+ }
1222+ for(int x = 0; x < 8; x++) {
1223+ dp[7 - x] = pixels[x] | tpixels[x];
1224+ }
1225+ } else {
1226+ for(int x = 0; x < 16; x++) {
1227+ pixels[x] = pcache[x];
1228+ }
1229+ for(int x = 0; x < 16; x++) {
1230+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1231+ }
1232+ for(int x = 0; x < 16; x++) {
1233+ p[x] = color_index[pixels[x]];
1234+ }
1235+ for(int x = 0; x < 16; x++) {
1236+ m[x] = masks[x];
1237+ }
1238+ // Draw to buffer
1239+ for(int x = 0; x < 16; x++) {
1240+ tpixels[x] = dp[x] & masks[x];
1241+ }
1242+ for(int x = 0; x < 16; x++) {
1243+ t2pixels[x] = p[x] & ~masks[x];
1244+ }
1245+ for(int x = 0; x < 16; x++) {
1246+ dp[15 - x] = t2pixels[x] | tpixels[x];
1247+ }
1248+ }
1249+ yy++;
1250+ }
1251+ }
1252+
1253+}
1254+void TOWNS_SPRITE::render_mirror_90(int num, uint16* dst_pixel, int width, int height, int stride)
1255+{
1256+ uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
1257+ uint8_t* addr;
1258+ uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
1259+ uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
1260+ if(sprite_table[num].is_32768) {
1261+ addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
1262+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
1263+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
1264+ int w = (cache_index[num].is_halfy) ? 8 : 16;
1265+ int h = (cache_index[num].is_halfx) ? 8 : 16;
1266+ uint16_t* p;
1267+ uint16_t* m;
1268+ uint16_t* dp;
1269+ int yy = 0;
1270+ uint8_t pixels[8];
1271+ uint16_t masks[16];
1272+ uint16_t tpixels[16];
1273+ uint16_t pcache[16];
1274+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
1275+ for(int y = ybegin; y >= 0; y -= ystep) {
1276+ p = &(cache_pixel[yy << 4]);
1277+ m = &(cache_mask[yy << 4]);
1278+ for(int x = 0; x < 16; x++) {
1279+ pcache[x] = qp[((15 - x) << 4) + (15 - y)];
1280+ }
1281+ dp = &(dst_pixel[yy * stride]);
1282+ if(cache_index[num].is_halfx) {
1283+ for(int x = 0; x < 8; x++) {
1284+ pixels[x] = pcache[x << 1];
1285+ }
1286+ for(int x = 0; x < 8; x++) {
1287+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
1288+ }
1289+ for(int x = 0; x < 8; x++) {
1290+ p[x] = pixels[x];
1291+ }
1292+ for(int x = 0; x < 8; x++) {
1293+ m[x] = masks[x];
1294+ }
1295+ // Draw to buffer
1296+ for(int x = 0; x < 8; x++) {
1297+ tpixels[x] = dp[x] & masks[x];
1298+ }
1299+ for(int x = 0; x < 8; x++) {
1300+ pixels[x] = pixels[x] & ~masks[x];
1301+ }
1302+ for(int x = 0; x < 8; x++) {
1303+ dp[7 - x] = pixels[x] | tpixels[x];
1304+ }
1305+ } else {
1306+ for(int x = 0; x < 16; x++) {
1307+ pixels[x] = pcache[x];
1308+ }
1309+ for(int x = 0; x < 16; x++) {
1310+ masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
1311+ }
1312+ for(int x = 0; x < 16; x++) {
1313+ p[x] = pixels[x];
1314+ }
1315+ for(int x = 0; x < 16; x++) {
1316+ m[x] = masks[x];
1317+ }
1318+ // Draw to buffer
1319+ for(int x = 0; x < 16; x++) {
1320+ tpixels[x] = dp[x] & masks[x];
1321+ }
1322+ for(int x = 0; x < 16; x++) {
1323+ pixels[x] = pixels[x] & ~masks[x];
1324+ }
1325+ for(int x = 0; x < 16; x++) {
1326+ dp[15 - x] = pixels[x] | tpixels[x];
1327+ }
1328+ }
1329+ yy++;
331330 }
34- dirty_cache_16c[num] = false;
351331 } else {
36- if(cached_32768c[num] != NULL) {
37- cached_32768c[NUM]->clean();
1332+ addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
1333+ int ystep = (cache_index[num].is_halfy) ? 2 : 1;
1334+ int xstep = (cache_index[num].is_halfx) ? 2 : 1;
1335+ int w = (cache_index[num].is_halfy) ? 8 : 16;
1336+ int h = (cache_index[num].is_halfx) ? 8 : 16;
1337+ int color = sprite_table[num].color;
1338+ if(color < 256) return;
1339+ if(color > 511) return;
1340+ color = color - 256;
1341+ uint16_t* p;
1342+ uint16_t* m;
1343+ uint16_t* dp;
1344+ int yy = 0;
1345+ uint8_t pixels[16];
1346+ uint8_t pixels_lo[16];
1347+ uint8_t pixels_hi[16];
1348+ uint16_t masks[16];
1349+ uint16_t tpixels[16];
1350+ uint16_t t2pixels[16];
1351+ uint8_t pcache[16];
1352+ uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
1353+ int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
1354+ for(int y = ybegin; y >= 0; y -= ystep) {
1355+ p = &(cache_pixel[yy << 4]);
1356+ m = &(cache_mask[yy << 4]);
1357+ for(int x = 0; x < 8; x++) {
1358+ pcache[x << 1] = qp[((7 - x) << 4) + (15 - y)] & 0xf0;
1359+ pcache[(x << 1) + 1] = qp[((7 - x) << 4) + (15 - y)] & 0x0f;
1360+ }
1361+ dp = &(dst_pixel[yy * stride]);
1362+ if(cache_index[num].is_halfx) {
1363+ for(int x = 0; x < 8; x++) {
1364+ pixels[x] = pcache[x << 1];
1365+ }
1366+ for(int x = 0; x < 8; x++) {
1367+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1368+ }
1369+ for(int x = 0; x < 8; x++) {
1370+ p[x] = color_index[pixels[x]];
1371+ }
1372+ for(int x = 0; x < 8; x++) {
1373+ m[x] = masks[x];
1374+ }
1375+ // Draw to buffer
1376+ for(int x = 0; x < 8; x++) {
1377+ tpixels[x] = dp[x] & masks[x];
1378+ }
1379+ for(int x = 0; x < 8; x++) {
1380+ pixels[x] = p[x] & ~masks[x];
1381+ }
1382+ for(int x = 0; x < 8; x++) {
1383+ dp[7 - x] = pixels[x] | tpixels[x];
1384+ }
1385+ } else {
1386+ for(int x = 0; x < 16; x++) {
1387+ pixels[x] = pcache[x];
1388+ }
1389+ for(int x = 0; x < 16; x++) {
1390+ masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
1391+ }
1392+ for(int x = 0; x < 16; x++) {
1393+ p[x] = color_index[pixels[x]];
1394+ }
1395+ for(int x = 0; x < 16; x++) {
1396+ m[x] = masks[x];
1397+ }
1398+ // Draw to buffer
1399+ for(int x = 0; x < 16; x++) {
1400+ tpixels[x] = dp[x] & masks[x];
1401+ }
1402+ for(int x = 0; x < 16; x++) {
1403+ t2pixels[x] = p[x] & ~masks[x];
1404+ }
1405+ for(int x = 0; x < 16; x++) {
1406+ dp[15 - x] = t2pixels[x] | tpixels[x];
1407+ }
1408+ }
1409+ yy++;
381410 }
39- dirty_cache_32768c[num] = false;
40- }
1411+ }
1412+
411413 }
42-void TOWNS_SPRITE::do_put_sprite(int num)
1414+
1415+void TOWNS_SPRITE::render_sprite(int num, uint16* dst_pixel, int width, int height, int stride)
431416 {
441417 if(num < 0) return;
45- if(num > 1023) return;
46-
47- int _size;
48- uint16_t buffer[16 * 16];
49- uint16_t tmpbuf[16 * 16];
50-
51- if(is_16c[num]) {
52- if((num < 128) || (num > 1023)) return;
53- if((color_table_num[num] < 256) || (color_table_num[num] > 511)) return;
54-
55- memset(buffer, 0x00, sizeof(uint16_t) * 16 * 16);
56-
57- for(int i = 0; i < [TOWNS_SPRITE_CACHE_NUM]; i++) {
58- if(dirty_cache_16c[i]) {
59- if(cached_16c[i] != NULL) {
60- if(cached_16c[i]->query_cached_range(num, true)) {
61- if(cached_16c[i]->is_cached(true,
62- sux[i],
63- suy[i],
64- rotate[i],
65- &(color_table[color_table_num[num] * 2 * 16]))) { // Hit
66- uint16_t *p = cached_16c[i]->get_cache_address(sux[i], suy[i], rotate[i], &_size);
67- if(p != NULL) {
68- transfer_cache(i, num);
69- return;
70- }
1418+ if(num >= sprite_limit) return;
1419+ if(num >= 1024) return;
1420+ if(stride <= 0) return;
1421+ if(stride > 512) return;
1422+ if(!(sprite_table[num].is_disp)) return;
1423+
1424+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1425+ if(!(cache_index[i].is_use)) continue;
1426+ if(cache_index[i].attribute == sprite_table[num].attribute) {
1427+ if(cache_index[i].is_32768 == sprite_table[num].is_32768) {
1428+ if(cache_index[i].is_32768) {
1429+ //
1430+ int h = (cache_index[i].is_halfy) ? 8 : 16;
1431+ int w = (cache_index[i].is_halfx) ? 8 : 16;
1432+ if(height < h) h = height;
1433+ if(width < w) w = width;
1434+ uint16_t* pp = (uint16_t*)dst_pixel;
1435+ uint16_t* qp = (uint16_t*)(cache_index[i].pixels);
1436+ uint16_t* qm = (uint16_t*)(cache_index[i].masks);
1437+ uint16_t* ppp = pp;
1438+ int np = 0;
1439+
1440+ for(int y = 0; y < h; y++) {
1441+ uint16_t* rp = &qp[y << 4];
1442+ uint16_t* rm = &qm[y << 4];
1443+ ppp = pp;
1444+ for(x = 0; x < w; x++) {
1445+ uint16_t pixel = *rp;
1446+ uint16_t dpixel = *ppp;
1447+ pixel = pixel & *rm;
1448+ dpixel = dpixel & ~(*rm);
1449+ dpixel = dpixel | pixel;
1450+ *tp = dpixel;
1451+ ppp++;
1452+ }
1453+ pp = pp + stride;
1454+ }
1455+ return;
1456+ } else { // 16 colors
1457+ if(cache_index[i].color != sprite_table[num].color) continue;
1458+ if(cache_index[i].color < 256) continue;
1459+ if(cache_index[i].color > 511) continue;
1460+ //
1461+ int h = (cache_index[i].is_halfy) ? 8 : 16;
1462+ int w = (cache_index[i].is_halfx) ? 8 : 16;
1463+ if(height < h) h = height;
1464+ if(width < w) w = width;
1465+ uint16_t* pp = (uint16_t*)dst_pixel;
1466+ uint16_t* qp = (uint16_t*)(cache_index[i].pixels);
1467+ uint16_t* qm = (uint16_t*)(cache_index[i].masks);
1468+ uint16_t* ppp = pp;
1469+ int np = 0;
1470+
1471+ for(int y = 0; y < h; y++) {
1472+ uint16_t* rp = &qp[y << 4];
1473+ uint16_t* rm = &qm[y << 4];
1474+ ppp = pp;
1475+ for(x = 0; x < w; x++) {
1476+ uint16_t pixel = *rp;
1477+ uint16_t dpixel = *ppp;
1478+ pixel = pixel & *rm;
1479+ dpixel = dpixel & ~(*rm);
1480+ dpixel = dpixel | pixel;
1481+ *tp = dpixel;
1482+ ppp++;
711483 }
1484+ pp = pp + stride;
721485 }
1486+ return;
731487 }
741488 }
75- // Not hit
76- uint16_t *pp = (uint16_t *)(&pattern_table[2 * 4 * 16 * (num - 128)]);
77- _size = make_sprite(buffer, pp); // to, from
78- if(_size > 0) {
79- if(transfer_sprite_16(num, buffer, tmpbuf)) { // Put to VRAM
80- int cnum = try_register_cache(num, buffer); // TRY
81- if(cnum >= 0) {
82- if(cached_16c[cnum] != NULL) {
83- cached_16c[cnum]->set_cache(sux[num], suy[num], rotate[num], tmpbuf);
84- }
1489+ }
1490+ }
1491+ // Cache Not hit
1492+ int target_num = -1;
1493+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1494+ if(!(cache_index[i].is_use)) {
1495+ target_num = i;
1496+ break;
1497+ }
1498+ }
1499+ if(target_num < 0) {
1500+ target_num = (last_put_cache_num + 1) % TOWNS_SPRITE_CACHE_NUM;
1501+ }
1502+ last_put_cache_num = target_num;
1503+ memset(&(cache_index[target_num]), 0x00, sizeof(sprite_cache_t));
1504+ cache_index[target_num].is_use = true;
1505+ cache_index[target_num].attribute = sprite_table[num].attribute;
1506+ cache_index[target_num].is_32768 = sprite_table[num].is_32768;
1507+ cache_index[target_num].is_halfx = sprite_table[num].is_halfx;
1508+ cache_index[target_num].is_halfy = sprite_table[num].is_halfy;
1509+ cache_index[target_num].pixels = (uint16_t*)(&(cache_pixels[target_num][0]));
1510+ cache_index[target_num].masks = (uint16_t*)(&(cache_masks[target_num][0]));
1511+ cache_index[target_num].color = sprite_table[num].color;
1512+ cache_index[target_num].num = sprite_table[num].num;
1513+ color_cached[(cache_index[target_num].color) & 0xff] = true;
1514+ pattern_cached[sprite_table[num].num] = true; // OK?
1515+
1516+ switch(sprite_table[num].rotate){
1517+ case 0:
1518+ render_not_rotate(num, dst_pixel, width, height, stride);
1519+ break;
1520+ case 1:
1521+ render_mirror_180(num, dst_pixel, width, height, stride);
1522+ break;
1523+ case 2:
1524+ render_mirror_0(num, dst_pixel, width, height, stride);
1525+ break;
1526+ case 3:
1527+ render_rotate_180(num, dst_pixel, width, height, stride);
1528+ break;
1529+ case 4:
1530+ render_mirror_270(num, dst_pixel, width, height, stride);
1531+ break;
1532+ case 5:
1533+ render_rotate_90(num, dst_pixel, width, height, stride);
1534+ break;
1535+ case 6:
1536+ render_rotate_270(num, dst_pixel, width, height, stride);
1537+ break;
1538+ case 7:
1539+ render_mirror_90(num, dst_pixel, width, height, stride);
1540+ break;
1541+ default:
1542+ break;
1543+ }
1544+}
1545+
1546+void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data)
1547+{
1548+ reg_addr = addr & 7;
1549+ reg_data[reg_addr] = (uint8_t)data;
1550+
1551+ switch(reg_addr) {
1552+ case 0:
1553+ reg_index = ((uint16_t)(reg_data[0]) + (((uint16_t)(reg_data[1] & 0x03)) << 8));
1554+ break;
1555+ case 1:
1556+ reg_index = ((uint16_t)(reg_data[0]) + (((uint16_t)(reg_data[1] & 0x03)) << 8));
1557+ reg_spen = ((reg_data[1] & 0x80) != 0) ? true : false;
1558+ break;
1559+ case 2:
1560+ case 3:
1561+ reg_hoffset = ((uint16_t)(reg_data[2]) + (((uint16_t)(reg_data[3] & 0x01)) << 8));
1562+ break;
1563+ case 4:
1564+ case 5:
1565+ reg_voffset = ((uint16_t)(reg_data[4]) + (((uint16_t)(reg_data[5] & 0x01)) << 8));
1566+ break;
1567+ case 6:
1568+ disp_page0 = ((data & 0x01) != 0) ? true : false;
1569+ disp_page1 = ((data & 0x10) != 0) ? true : false;
1570+ break;
1571+ default:
1572+ break;
1573+ }
1574+}
1575+
1576+uint32_t TOWNS_SPRITE::read_io8(uint32_t addr)
1577+{
1578+ uint32_t val = 0xff;
1579+ reg_addr = addr & 7;
1580+ switch(reg_addr) {
1581+ case 0:
1582+ val = reg_index & 0xff;
1583+ break;
1584+ case 1:
1585+ val = (reg_index & 0x0300) >> 8;
1586+ val = val | ((reg_spen) ? 0x80 : 0x00);
1587+ break;
1588+ case 2:
1589+ val = reg_hoffset & 0xff;
1590+ break;
1591+ case 3:
1592+ val = (reg_hoffset & 0x0100) >> 8;
1593+ break;
1594+ case 4:
1595+ val = reg_voffset & 0xff;
1596+ break;
1597+ case 5:
1598+ val = (reg_voffset & 0x0100) >> 8;
1599+ break;
1600+ break;
1601+ case 6:
1602+ val = (disp_page0) ? 0x08 : 0x00;
1603+ val = val | ((disp_page1) ? 0x80 : 0x00);
1604+ break;
1605+ default:
1606+ val = 0x00;
1607+ break;
1608+ }
1609+ return val;
1610+}
1611+
1612+
1613+uint32_t TOWNS_SPRITE::read_data8(uint32_t addr)
1614+{
1615+ uint32_t nbank;
1616+ uint8_t* p8;
1617+ uint16_t val;
1618+ pair_t tval;
1619+ if((addr >= 0x81000000) && (addr < 0x81020000)) {
1620+ nbank = (addr & 0x1e000) >> 12;
1621+ } else {
1622+ nbank = 0; // OK?
1623+ }
1624+ switch(nbank) {
1625+ case 0:
1626+ case 1:
1627+ tval.w.l = index_ram[(addr & 0x1ffe) >> 1];
1628+ if((addr & 1) == 0) { // Lo
1629+ val = (uint16_t)(tval.b.l);
1630+ } else {
1631+ val = (uint16_t)(tval.b.h);
1632+ }
1633+ break;
1634+ case 2:
1635+ case 3:
1636+ tval.w.l = color_ram[(addr & 0x1ffe) >> 1];
1637+ if((addr & 1) == 0) { // Lo
1638+ val = (uint16_t)(tval.b.l);
1639+ } else {
1640+ val = (uint16_t)(tval.b.h);
1641+ }
1642+ break;
1643+ default:
1644+ p8 = &(pattern_ram[(addr & 0x1fffe) - 0x4000]);
1645+ if((addr & 1) == 0) { // Lo
1646+ val = p8[0];
1647+ } else {
1648+ val = p8[1];
1649+ }
1650+ break;
1651+ }
1652+ return (uint32_t)val;
1653+}
1654+
1655+uint32_t TOWNS_SPRITE::read_data16(uint32_t addr)
1656+{
1657+ uint32_t nbank;
1658+ uint8_t* p8;
1659+ pair_t tval;
1660+ uint16_t val;
1661+ if((addr >= 0x81000000) && (addr < 0x81020000)) {
1662+ nbank = (addr & 0x1e000) >> 12;
1663+ } else {
1664+ nbank = 0; // OK?
1665+ }
1666+ switch(nbank) {
1667+ case 0:
1668+ case 1:
1669+ val = (uint32_t)(index_ram[(addr & 0x1ffe) >> 1]);
1670+ break;
1671+ case 2:
1672+ case 3:
1673+ val = (uint32_t)(color_ram[(addr & 0x1ffe) >> 1]);
1674+ break;
1675+ default:
1676+ p8 = &(pattern_ram[(addr & 0x1fffe) - 0x4000]);
1677+ tval.b.l = p8[0];
1678+ tval.b.h = p8[1];
1679+ val = (uint32_t)(tval.w.l);
1680+ break;
1681+ }
1682+ return (uint32_t)val;
1683+}
1684+
1685+uint32_t TOWNS_SPRITE::read_data32(uint32_t addr)
1686+{
1687+ uint32_t hi, lo = 0;
1688+ lo = read_data16(addr);
1689+ if(addr < 0x8101fffe) hi = read_data16(addr + 2);
1690+ return ((hi << 16) & 0xffff0000) | (lo & 0x0000ffff);
1691+}
1692+
1693+void TOWNS_SPRITE::write_data8(uint32_t addr, uint32_t data)
1694+{
1695+ uint32_t nbank;
1696+ uint8_t* p8;
1697+ pair_t tval;
1698+ if((addr >= 0x81000000) && (addr < 0x81020000)) {
1699+ nbank = (addr & 0x1e000) >> 12;
1700+ } else {
1701+ nbank = 0; // OK?
1702+ }
1703+ switch(nbank) {
1704+ case 0:
1705+ case 1:
1706+ tval.w.l = index_ram[(addr & 0x1ffe) >> 1];
1707+ if((addr & 1) == 0) { // Lo
1708+ tval.b.l = (uint8_t)(data & 0xff);
1709+ } else {
1710+ tval.b.h = (uint8_t)(data & 0xff);
1711+ }
1712+ index_ram[(addr & 0x1ffe) >> 1] = tval.w.l;
1713+ break;
1714+ case 2:
1715+ case 3:
1716+ // ToDO: Discard cache
1717+ tval.w.l = color_ram[(addr & 0x1ffe) >> 1];
1718+ if((addr & 1) == 0) { // Lo
1719+ tval.b.l = (uint8_t)(data & 0xff);
1720+ } else {
1721+ tval.b.h = (uint8_t)(data & 0xff);
1722+ }
1723+ color_ram[(addr & 0x1ffe) >> 1] = tval.w.l;
1724+ if(color_cached[(addr & 0x1ffe) >> 5]) {
1725+ uint32_t nnum = (addr & 0x1ffe) >> 5;
1726+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1727+ if(cache_index[i].color == (uint16_t)(nnum + 256)) {
1728+ if(cache_index[i].is_use) {
1729+ clear_cache(i);
851730 }
861731 }
871732 }
88- }
89- } else { // 32768c
90- memset(buffer, 0x00, sizeof(uint16_t) * 16 * 16);
1733+ color_cached[nnum] = false;
1734+ }
1735+ break;
1736+ default:
1737+ // ToDO: Discard cache
1738+ p8 = &(pattern_ram[(addr & 0x1ffff) - 0x4000]);
1739+ *p8 = (uint8_t)(data & 0xff);
1740+ if(pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7]) {
1741+ uint32_t nnum = ((addr & 0x1fffe) - 0x4000) >> 7;
1742+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1743+ if(cache_index[i].num == (uint16_t)nnum) {
1744+ if(cache_index[i].is_use) {
1745+ clear_cache(i);
1746+ }
1747+ }
1748+ }
1749+ pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7] = false;
1750+ }
1751+ break;
1752+ }
1753+ return;
1754+}
911755
1756+void TOWNS_SPRITE::write_data16(uint32_t addr, uint32_t data)
1757+{
1758+ uint32_t nbank;
1759+ uint16_t* p;
1760+ pair_t tval;
1761+ if((addr >= 0x81000000) && (addr < 0x81020000)) {
1762+ nbank = (addr & 0x1e000) >> 12;
1763+ } else {
1764+ nbank = 0; // OK?
921765 }
1766+ switch(nbank) {
1767+ case 0:
1768+ case 1:
1769+ index_ram[(addr & 0x1ffe) >> 1] = (uint16_t)(data & 0xffff);
1770+ break;
1771+ case 2:
1772+ case 3:
1773+ // ToDO: Discard cache
1774+ color_ram[(addr & 0x1ffe) >> 1] = (uint16_t)(data & 0xffff);
1775+ if(color_cached[(addr & 0x1ffe) >> 5]) {
1776+ uint32_t nnum = (addr & 0x1ffe) >> 5;
1777+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1778+ if(cache_index[i].color == (uint16_t)(nnum + 256)) {
1779+ if(cache_index[i].is_use) {
1780+ clear_cache(i);
1781+ }
1782+ }
1783+ }
1784+ color_cached[nnum] = false;
1785+ }
1786+ break;
1787+ default:
1788+ // ToDO: Discard cache
1789+ tval.w.l = (uint16_t)data;
1790+ pattern_ram[(addr & 0x1fffe) - 0x4000] = tval.b.l;
1791+ pattern_ram[(addr & 0x1fffe) - 0x4000 + 1] = tval.b.h;
1792+ if(pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7]) {
1793+ uint32_t nnum = ((addr & 0x1fffe) - 0x4000) >> 7;
1794+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1795+ if(cache_index[i].num == (uint16_t)nnum) {
1796+ if(cache_index[i].is_use) {
1797+ clear_cache(i);
1798+ }
1799+ }
1800+ }
1801+ pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7] = false;
1802+ }
1803+ break;
1804+ }
1805+ return;
1806+}
1807+
1808+void TOWNS_SPRITE::write_data32(uint32_t addr, uint32_t data)
1809+{
1810+ pair_t t;
1811+ t.d = data;
1812+ write_data16(addr, (uint32_t)(t.w.l));
1813+ if(addr < 0x8101fffe) write_data16(addr + 2, (uint32_t)(t.w.h));
931814 }
941815
1816+
951817 #define STATE_VERSION 1
961818
1819+#include "../../statesub.h"
1820+
1821+void TOWNS_SPRITE::decl_state()
1822+{
1823+ enter_decl_state(STATE_VERSION);
1824+
1825+ DECL_STATE_ENTRY_UINT8(reg_addr);
1826+ DECL_STATE_ENTRY_1D_ARRAY(reg_data, 8);
1827+
1828+ DECL_STATE_ENTRY_BOOL(reg_spen);
1829+ DECL_STATE_ENTRY_UINT16(reg_index);
1830+ DECL_STATE_ENTRY_UINT16(reg_voffset);
1831+ DECL_STATE_ENTRY_UINT16(reg_hoffset);
1832+ DECL_STATE_ENTRY_BOOL(disp_page0);
1833+ DECL_STATE_ENTRY_BOOL(disp_page1);
1834+
1835+ DECL_STATE_ENTRY_INT32(sprite_limit);
1836+
1837+ DECL_STATE_ENTRY_1D_ARRAY(index_ram, sizeof(index_ram) / sizeof(uint16_t));
1838+ DECL_STATE_ENTRY_1D_ARRAY(pattern_ram, sizeof(pattern_ram) / sizeof(uint8_t));
1839+ DECL_STATE_ENTRY_1D_ARRAY(color_ram, sizeof(color_ram) / sizeof(uint16_t));
1840+
1841+ DECL_STATE_ENTRY_INT32(last_put_cache_num);
1842+ DECL_STATE_ENTRY_2D_ARRAY(cache_pixels, TOWNS_SPRITE_CACHE_NUM, 16 * 16);
1843+ DECL_STATE_ENTRY_2D_ARRAY(cache_masks, TOWNS_SPRITE_CACHE_NUM, 16 * 16);
1844+ DECL_STATE_ENTRY_1D_ARRAY(pattern_cached, (sizeof(pattern_cached) / sizeof(bool)));
1845+ DECL_STATE_ENTRY_1D_ARRAY(color_cached, (sizeof(pattern_cached) / sizeof(bool)));
1846+
1847+ DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_use), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1848+ DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].attribute), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1849+ DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_32768), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1850+ DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_halfx), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1851+ DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_halfy), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1852+ DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].color), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1853+ DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].num), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t));
1854+
1855+ leave_decl_state();
1856+
1857+}
971858 bool TOWNS_SPRITE::save_state(FILEIO *state_fio)
981859 {
99- state_fio->FputUint32(STATE_VERSION);
100- state_fio->FputInt32(this_device_id);
1860+ if(state_entry != NULL) {
1861+ state_entry->save_state(state_fio);
1862+ }
1011863 }
1021864
1031865 bool TOWNS_SPRITE::load_state(FILEIO *state_fio)
1041866 {
105- if(state_fio->FgetUint32() != STATE_VERSION) {
106- return false;
1867+ bool mb = false;
1868+ if(state_entry != NULL) {
1869+ mb = state_entry->load_state(state_fio);
1870+ this->out_debug_log(_T("Load State: SPRITE: id=%d stat=%s\n"), this_device_id, (mb) ? _T("OK") : _T("NG"));
1871+ if(!mb) return false;
1071872 }
108- if(state_fio->FgetInt32() != this_device_id) {
109- return false;
1873+ // If load state, clear cache.
1874+ for(i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
1875+ cache_index[i].pixels = (uint16_t*)(&(cache_pixels[i][0]));
1876+ cache_index[i].masks = (uint16_t*)(&(cache_masks[i][0]));
1101877 }
1111878 return true;
1121879 }
--- a/source/src/vm/fmtowns/towns_sprite.h
+++ b/source/src/vm/fmtowns/towns_sprite.h
@@ -17,88 +17,35 @@
1717
1818 class TOWNS_VRAM;
1919
20-class SPRITE_CACHE {
21-private:
22- int begin_num;
23- bool blank;
24- bool is_16colors; // 32768colors = false
25- bool used;
26-
27- uint16_t palette[16];
28- bool cached_x10x10[8];
29- bool cached_x05x10[8];
30- bool cached_x10x05[8];
31- bool cached_x05x05[8];
32- uint16_t data_x10x10[8][16 * 16];
33- uint16_t data_x05x10[8][8 * 16];
34- uint16_t data_x10x05[8][16 * 8];
35- uint16_t data_x05x05[8][8 * 8];
36- uint16_t color_table[16];
37-public:
38- SPRITE_CACHE(bool is_16c);
39- ~SPRITE_CACHE();
40-
41- uint16_t *get_cache_address(bool condense_x, bool condense_y, uint8_t rotate, uint32_t *size);
42- bool set_cache(bool condense_x, bool condense_y, uint8_t rotate, uint16_t *srcdata);
43-
44- int get_cached_num(void);
45- bool query_cached_range(int pos, bool is_16c);
46- bool get_cached_is_16c(void);
47-
48- bool is_cached(bool is_16c, bool condense_x, bool condense_y, uint8_t rotate, uint16_t *palette);
49- bool is_blank(void);
50- bool is_used(void);
51- void clean(void);
52- void set_num(int num, uint16_t *palette);
53-};
54-
5520 #define TOWNS_SPRITE_CACHE_NUM 512
5621
5722 class TOWNS_SPRITE : public DEVICE
5823 {
5924 private:
6025 TOWNS_VRAM *vram_head;
61-
62- int cache_size_16c;
63- int cache_size_32768c;
6426
65- // NEED ATOMIC witn MULTI-THREADED SPRITE
66- bool dirty_cache_16c[TOWNS_SPRITE_CACHE_NUM];
67- bool dirty_cache_32768c[TOWNS_SPRITE_CACHE_NUM];
68- SPRITE_CACHE *cached_16c[TOWNS_SPRITE_CACHE_NUM]; // ToDo
69- SPRITE_CACHE *cached_32768c[TOWNS_SPRITE_CACHE_NUM]; // ToDo
70-
71- bool dirty_color_table[256];
72- bool dirty_pattern_table[1024];
27+ // REGISTERS
28+ uint8_t reg_addr;
29+ uint8_t reg_data[8];
30+ // #0, #1
31+ bool reg_spen;
32+ uint16_t reg_index;
33+
34+ uint16_t reg_voffset;
35+ uint16_t reg_hoffset;
36+ bool disp_page0;
37+ bool disp_page1;
7338
74- int splite_limit;
75- int render_count;
76- bool bank0;
77-
78- uint16_t palettes[256][16];
39+ int32_t splite_limit;
7940
80- // Put address(16bit)
81- int xaddress[1024];
82- int yaddress[1024];
41+ uint16_t index_ram[4096]; // 1024 * 4
42+ uint16_t color_ram[4096]; // 16 * 256
43+ uint8_t pattern_ram[(65536 - (4096 * 2)) * 2];
8344
84- // Attribute(16bit)
85- bool check_offset[1024];
86- bool suy[1024];
87- bool sux[1024];
88- uint8_t rotate[1024];
89- uint32_t pattern_num[1024];
90-
91- // Color Table(16bit)
92- bool is_16c[1024];
93- bool is_impose[1024];
94- bool is_disp[1024];
95- uint16_t color_table_num[1024];
96-
97- uint8_t index_table[2 * 4 * 1024];
98- uint8_t color_table[2 * 16 * 256];
99- uint8_t pattern_table[2 * 16 * 16 * (256 - 32)];
45+ bool pattern_cached[((65536 - (4096 * 2)) * 2) / (8 * 16)];
46+ bool color_cached[256];
10047 protected:
101- void do_put_sprite(int num);
48+
10249
10350 public:
10451 TOWNS_SPRITE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {
Show on old repository browser