|
|
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.