|
|
1.1 root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2:
3: /* plotter routines for user interfaces - used by console and gtk */
4:
5: #include "generator.h"
6: #include "vdp.h"
7:
8: #include "uiplot.h"
9:
10: uint32 uiplot_palcache[192];
11:
12: static int uiplot_redshift;
13: static int uiplot_greenshift;
14: static int uiplot_blueshift;
15:
16: void uiplot_setshifts(int redshift, int greenshift, int blueshift)
17: {
18: uiplot_redshift = redshift;
19: uiplot_greenshift = greenshift;
20: uiplot_blueshift = blueshift;
21: }
22:
23: /* uiplot_checkpalcache goes through the CRAM memory in the Genesis and
24: converts it to the uiplot_palcache table. The Genesis has 64 colours,
25: but we store three versions of the colour table into uiplot_palcache - a
26: normal, hilighted and dim version. The vdp_cramf buffer has 64
27: entries and is set to 1 when the game writes to CRAM, this means this
28: code skips entries that have not changed, unless 'flag' is set to 1 in
29: which case this updates all entries regardless. */
30:
31: void uiplot_checkpalcache(int flag)
32: {
33: unsigned int col;
34: uint8 *p;
35:
36: /* this code requires that there be at least 4 bits per colour, that
37: is, three bits that come from the console's palette, and one more bit
38: when we do a dim or bright colour, i.e. this code works with 12bpp
39: upwards */
40:
41: /* the flag forces it to do the update despite the vdp_cramf buffer */
42:
43: for (col = 0; col < 64; col++) { /* the CRAM has 64 colours */
44: if (!flag && !vdp_cramf[col])
45: continue;
46: vdp_cramf[col] = 0;
47: p = (uint8 *)vdp_cram + 2 * col; /* point p to the two-byte CRAM entry */
48: uiplot_palcache[col] = /* normal */
49: (p[0] & 0xE) << (uiplot_blueshift + 1) |
50: (p[1] & 0xE) << (uiplot_redshift + 1) |
51: ((p[1] & 0xE0) >> 4) << (uiplot_greenshift + 1);
52: uiplot_palcache[col + 64] = /* hilight */
53: (p[0] & 0xE) << uiplot_blueshift |
54: (p[1] & 0xE) << uiplot_redshift |
55: ((p[1] & 0xE0) >> 4) << uiplot_greenshift |
56: (16 << uiplot_blueshift) | (16 << uiplot_redshift) |
57: (16 << uiplot_greenshift);
58: uiplot_palcache[col + 128] = /* shadow */
59: (p[0] & 0xE) << uiplot_blueshift |
60: (p[1] & 0xE) << uiplot_redshift |
61: ((p[1] & 0xE0) >> 4) << uiplot_greenshift;
62: }
63: }
64:
65: /*** uiplot_convertdata - convert genesis data to 16 bit colour */
66:
67: /* must call uiplot_checkpalcache first */
68:
69: void uiplot_convertdata16(uint8 *indata, uint16 *outdata, unsigned int pixels)
70: {
71: unsigned int ui;
72: uint32 outdata1;
73: uint32 outdata2;
74: uint32 indata_val;
75:
76: /* not scaled, 16bpp - we do 4 pixels at a time */
77: for (ui = 0; ui < (pixels >> 2); ui++) {
78: indata_val = ((uint32 *)indata)[ui]; /* 4 bytes of in data */
79: outdata1 = (uiplot_palcache[indata_val & 0xff] |
80: uiplot_palcache[(indata_val >> 8) & 0xff] << 16);
81: outdata2 = (uiplot_palcache[(indata_val >> 16) & 0xff] |
82: uiplot_palcache[(indata_val >> 24) & 0xff] << 16);
83: #ifdef WORDS_BIGENDIAN
84: ((uint32 *)outdata)[(ui << 1)] = outdata2;
85: ((uint32 *)outdata)[(ui << 1) + 1] = outdata1;
86: #else
87: ((uint32 *)outdata)[(ui << 1)] = outdata1;
88: ((uint32 *)outdata)[(ui << 1) + 1] = outdata2;
89: #endif
90: }
91: }
92:
93: /*** uiplot_convertdata - convert genesis data to 32 bit colour ***/
94:
95: /* must call uiplot_checkpalcache first */
96:
97: void uiplot_convertdata32(uint8 *indata, uint32 *outdata, unsigned int pixels)
98: {
99: unsigned int ui;
100: uint32 outdata1;
101: uint32 outdata2;
102: uint32 outdata3;
103: uint32 outdata4;
104: uint32 indata_val;
105:
106: /* not scaled, 32bpp - we do 4 pixels at a time */
107: for (ui = 0; ui < pixels >> 2; ui++) {
108: indata_val = ((uint32 *)indata)[ui]; /* 4 bytes of in data */
109: outdata1 = uiplot_palcache[indata_val & 0xff];
110: outdata2 = uiplot_palcache[(indata_val >> 8) & 0xff];
111: outdata3 = uiplot_palcache[(indata_val >> 16) & 0xff];
112: outdata4 = uiplot_palcache[(indata_val >> 24) & 0xff];
113: #ifdef WORDS_BIGENDIAN
114: ((uint32 *)outdata)[(ui << 2)] = outdata4;
115: ((uint32 *)outdata)[(ui << 2) + 1] = outdata3;
116: ((uint32 *)outdata)[(ui << 2) + 2] = outdata2;
117: ((uint32 *)outdata)[(ui << 2) + 3] = outdata1;
118: #else
119: ((uint32 *)outdata)[(ui << 2)] = outdata1;
120: ((uint32 *)outdata)[(ui << 2) + 1] = outdata2;
121: ((uint32 *)outdata)[(ui << 2) + 2] = outdata3;
122: ((uint32 *)outdata)[(ui << 2) + 3] = outdata4;
123: #endif
124: }
125: }
126:
127: /*** uiplot_render16_x1 - copy to screen with delta changes (16 bit) ***/
128:
129: void uiplot_render16_x1(uint16 *linedata, uint16 *olddata, uint8 *screen,
130: unsigned int pixels)
131: {
132: unsigned int ui;
133: uint32 inval;
134:
135: for (ui = 0; ui < pixels >> 1; ui++) {
136: /* do two words of input data at a time */
137: inval = ((uint32 *)linedata)[ui];
138: if (inval != ((uint32 *)olddata)[ui])
139: ((uint32 *)screen)[ui] = inval;
140: }
141: }
142:
143: /*** uiplot_render32_x1 - copy to screen with delta changes (32 bit) ***/
144:
145: void uiplot_render32_x1(uint32 *linedata, uint32 *olddata, uint8 *screen,
146: unsigned int pixels)
147: {
148: unsigned int ui;
149: uint32 inval;
150:
151: for (ui = 0; ui < pixels; ui++) {
152: inval = linedata[ui];
153: if (inval != olddata[ui])
154: ((uint32 *)screen)[ui] = inval;
155: }
156: }
157:
158: /*** uiplot_render16_x2 - blow up screen image by two (16 bit) ***/
159:
160: void uiplot_render16_x2(uint16 *linedata, uint16 *olddata, uint8 *screen,
161: unsigned int linewidth, unsigned int pixels)
162: {
163: unsigned int ui;
164: uint32 inval, outval, mask;
165: uint8 *screen2 = screen + linewidth;
166:
167: mask = 0xffffffff;
168: for (ui = 0; ui < pixels >> 1; ui++) {
169: /* do two words of input data at a time */
170: inval = ((uint32 *)linedata)[ui];
171: if (olddata)
172: mask = inval ^ ((uint32 *)olddata)[ui]; /* check for changed data */
173: if (mask & 0xffff) {
174: /* write first two words */
175: outval = inval & 0xffff;
176: outval |= outval << 16;
177: #ifdef WORDS_BIGENDIAN
178: ((uint32 *)screen)[(ui << 1) + 1] = outval;
179: ((uint32 *)screen2)[(ui << 1) + 1] = outval;
180: #else
181: ((uint32 *)screen)[(ui << 1)] = outval;
182: ((uint32 *)screen2)[(ui << 1)] = outval;
183: #endif
184: }
185: if (mask & 0xffff0000) {
186: /* write second two words */
187: outval = inval & 0xffff0000;
188: outval |= outval >> 16;
189: #ifdef WORDS_BIGENDIAN
190: ((uint32 *)screen)[(ui << 1)] = outval;
191: ((uint32 *)screen2)[(ui << 1)] = outval;
192: #else
193: ((uint32 *)screen)[(ui << 1) + 1] = outval;
194: ((uint32 *)screen2)[(ui << 1) + 1] = outval;
195: #endif
196: }
197: }
198: }
199:
200: /*** uiplot_render32_x2 - blow up screen image by two (32 bit) ***/
201:
202: void uiplot_render32_x2(uint32 *linedata, uint32 *olddata, uint8 *screen,
203: unsigned int linewidth, unsigned int pixels)
204: {
205: unsigned int ui;
206: uint32 val;
207: uint8 *screen2 = screen + linewidth;
208:
209: if (olddata) {
210: for (ui = 0; ui < pixels; ui++) {
211: val = linedata[ui];
212: /* check for changed data */
213: if (val != olddata[ui]) {
214: ((uint32 *)screen)[(ui << 1) + 0] = val;
215: ((uint32 *)screen)[(ui << 1) + 1] = val;
216: ((uint32 *)screen2)[(ui << 1) + 0] = val;
217: ((uint32 *)screen2)[(ui << 1) + 1] = val;
218: }
219: }
220: } else {
221: for (ui = 0; ui < pixels; ui++) {
222: val = linedata[ui];
223: ((uint32 *)screen)[(ui << 1) + 0] = val;
224: ((uint32 *)screen)[(ui << 1) + 1] = val;
225: ((uint32 *)screen2)[(ui << 1) + 0] = val;
226: ((uint32 *)screen2)[(ui << 1) + 1] = val;
227: }
228: }
229: }
230:
231: /*** uiplot_render16_x2h - blow up by two in horizontal direction
232: only (16 bit) ***/
233:
234: void uiplot_render16_x2h(uint16 *linedata, uint16 *olddata, uint8 *screen,
235: unsigned int pixels)
236: {
237: unsigned int ui;
238: uint32 inval, outval, mask;
239:
240: mask = 0xffffffff;
241: for (ui = 0; ui < pixels >> 1; ui++) {
242: /* do two words of input data at a time */
243: inval = ((uint32 *)linedata)[ui];
244: if (olddata)
245: mask = inval ^ ((uint32 *)olddata)[ui]; /* check for changed data */
246: if (mask & 0xffff) {
247: /* write first two words */
248: outval = inval & 0xffff;
249: outval |= outval << 16;
250: #ifdef WORDS_BIGENDIAN
251: ((uint32 *)screen)[(ui << 1) + 1] = outval;
252: #else
253: ((uint32 *)screen)[(ui << 1)] = outval;
254: #endif
255: }
256: if (mask & 0xffff0000) {
257: /* write second two words */
258: outval = inval & 0xffff0000;
259: outval |= outval >> 16;
260: #ifdef WORDS_BIGENDIAN
261: ((uint32 *)screen)[(ui << 1)] = outval;
262: #else
263: ((uint32 *)screen)[(ui << 1) + 1] = outval;
264: #endif
265: }
266: }
267: }
268:
269: /*** uiplot_render32_x2h - blow up by two in horizontal direction
270: only (32 bit) ***/
271:
272: void uiplot_render32_x2h(uint32 *linedata, uint32 *olddata, uint8 *screen,
273: unsigned int pixels)
274: {
275: unsigned int ui;
276: uint32 val;
277:
278: for (ui = 0; ui < pixels; ui++) {
279: val = linedata[ui];
280: /* check for changed data */
281: if (!olddata || val != olddata[ui]) {
282: ((uint32 *)screen)[(ui << 1) + 0] = val;
283: ((uint32 *)screen)[(ui << 1) + 1] = val;
284: }
285: }
286: }
287:
288: /*** uiplot_irender16_weavefilter - take even and odd fields, filter and
289: plot (16 bit) ***/
290:
291: void uiplot_irender16_weavefilter(uint16 *evendata, uint16 *odddata,
292: uint8 *screen, unsigned int pixels)
293: {
294: unsigned int ui;
295: uint32 evenval, oddval, e_r, e_g, e_b, o_r, o_g, o_b;
296: uint32 outval, w1, w2;
297:
298: for (ui = 0; ui < pixels >> 1; ui++) {
299: evenval = ((uint32 *)evendata)[ui]; /* two words of input data */
300: oddval = ((uint32 *)odddata)[ui]; /* two words of input data */
301: e_r = (evenval >> uiplot_redshift) & 0x001f001f;
302: e_g = (evenval >> uiplot_greenshift) & 0x001f001f;
303: e_b = (evenval >> uiplot_blueshift) & 0x001f001f;
304: o_r = (oddval >> uiplot_redshift) & 0x001f001f;
305: o_g = (oddval >> uiplot_greenshift) & 0x001f001f;
306: o_b = (oddval >> uiplot_blueshift) & 0x001f001f;
307: outval = (((e_r + o_r) >> 1) & 0x001f001f) << uiplot_redshift |
308: (((e_g + o_g) >> 1) & 0x001f001f) << uiplot_greenshift |
309: (((e_b + o_b) >> 1) & 0x001f001f) << uiplot_blueshift;
310: w1 = (outval & 0xffff);
311: w1 |= w1 << 16;
312: w2 = outval & 0xffff0000;
313: w2 |= w2 >> 16;
314: #ifdef WORDS_BIGENDIAN
315: ((uint32 *)screen)[(ui << 1)] = w2;
316: ((uint32 *)screen)[(ui << 1) + 1] = w1;
317: #else
318: ((uint32 *)screen)[(ui << 1)] = w1;
319: ((uint32 *)screen)[(ui << 1) + 1] = w2;
320: #endif
321: }
322: }
323:
324: /*** uiplot_irender32_weavefilter - take even and odd fields, filter and
325: plot (32 bit) ***/
326:
327: void uiplot_irender32_weavefilter(uint32 *evendata, uint32 *odddata,
328: uint8 *screen, unsigned int pixels)
329: {
330: unsigned int ui;
331: uint32 evenval, oddval;
332:
333: for (ui = 0; ui < pixels; ui++) {
334: evenval = evendata[ui];
335: oddval = odddata[ui];
336: /* with 32-bit data we know that there are no touching bits */
337: ((uint32 *)screen)[(ui << 1) + 0] = (evenval >> 1) + (oddval >> 1);
338: ((uint32 *)screen)[(ui << 1) + 1] = (evenval >> 1) + (oddval >> 1);
339: }
340: }
341:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.