1 #include "gal.h"
2 #include "resnet.h"
3
4 GalRenderBackground GalRenderBackgroundFunction;
5 GalCalcPalette GalCalcPaletteFunction;
6 GalDrawBullet GalDrawBulletsFunction;
7 GalExtendTileInfo GalExtendTileInfoFunction;
8 GalExtendSpriteInfo GalExtendSpriteInfoFunction;
9 GalRenderFrame GalRenderFrameFunction;
10
11 INT32 GalScreenUnflipper = 0;
12
13 UINT8 GalFlipScreenX;
14 UINT8 GalFlipScreenY;
15 UINT8 *GalGfxBank;
16 UINT8 GalPaletteBank;
17 UINT8 GalSpriteClipStart;
18 UINT8 GalSpriteClipEnd;
19 UINT8 FroggerAdjust;
20 UINT8 GalBackgroundRed;
21 UINT8 GalBackgroundGreen;
22 UINT8 GalBackgroundBlue;
23 UINT8 GalBackgroundEnable;
24 UINT8 SfxTilemap;
25 UINT8 GalOrientationFlipX;
26 UINT8 GalColourDepth;
27 UINT8 DarkplntBulletColour;
28 UINT8 DambustrBgColour1;
29 UINT8 DambustrBgColour2;
30 UINT8 DambustrBgPriority;
31 UINT8 DambustrBgSplitLine;
32 UINT8 *RockclimTiles;
33 UINT16 RockclimScrollX;
34 UINT16 RockclimScrollY;
35
36 // Graphics decode helpers
37 INT32 CharPlaneOffsets[2] = { 0, 0x4000 };
38 INT32 CharXOffsets[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
39 INT32 CharYOffsets[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
40 INT32 SpritePlaneOffsets[2] = { 0, 0x4000 };
41 INT32 SpriteXOffsets[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 64, 65, 66, 67, 68, 69, 70, 71 };
42 INT32 SpriteYOffsets[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 128, 136, 144, 152, 160, 168, 176, 184 };
43
44 // Tile extend helpers
UpperExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)45 void UpperExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
46 {
47 *Code += 0x100;
48 }
49
PiscesExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)50 void PiscesExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
51 {
52 *Code |= GalGfxBank[0] << 8;
53 }
54
Batman2ExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)55 void Batman2ExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
56 {
57 if (*Code & 0x80) *Code |= GalGfxBank[0] << 8;
58 }
59
GmgalaxExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)60 void GmgalaxExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
61 {
62 *Code |= GalGfxBank[0] << 9;
63 }
64
MooncrstExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)65 void MooncrstExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
66 {
67 if (GalGfxBank[2] && (*Code & 0xc0) == 0x80) *Code = (*Code & 0x3f) | (GalGfxBank[0] << 6) | (GalGfxBank[1] << 7) | 0x0100;
68 }
69
MoonqsrExtendTileInfo(UINT16 * Code,INT32 *,INT32 Attr,INT32,INT32)70 void MoonqsrExtendTileInfo(UINT16 *Code, INT32*, INT32 Attr, INT32, INT32)
71 {
72 *Code |= (Attr & 0x20) << 3;
73 }
74
SkybaseExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)75 void SkybaseExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
76 {
77 *Code |= GalGfxBank[2] << 8;
78 }
79
JumpbugExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)80 void JumpbugExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
81 {
82 if ((*Code & 0xc0) == 0x80 && (GalGfxBank[2] & 0x01)) *Code += 128 + ((GalGfxBank[0] & 0x01) << 6) + ((GalGfxBank[1] & 0x01) << 7) + ((~GalGfxBank[4] & 0x01) << 8);
83 }
84
FroggerExtendTileInfo(UINT16 *,INT32 * Colour,INT32,INT32,INT32)85 void FroggerExtendTileInfo(UINT16*, INT32 *Colour, INT32, INT32, INT32)
86 {
87 *Colour = ((*Colour >> 1) & 0x03) | ((*Colour << 2) & 0x04);
88 }
89
MshuttleExtendTileInfo(UINT16 * Code,INT32 *,INT32 Attr,INT32,INT32)90 void MshuttleExtendTileInfo(UINT16 *Code, INT32*, INT32 Attr, INT32, INT32)
91 {
92 *Code |= (Attr & 0x30) << 4;
93 }
94
Fourin1ExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)95 void Fourin1ExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
96 {
97 *Code |= Fourin1Bank << 8;
98 }
99
MarinerExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32 x,INT32)100 void MarinerExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32 x, INT32)
101 {
102 UINT8 *Prom = GalProm + 0x120;
103
104 *Code |= (Prom[x] & 0x01) << 8;
105 }
106
MimonkeyExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)107 void MimonkeyExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
108 {
109 *Code |= (GalGfxBank[0] << 8) | (GalGfxBank[1] << 9);
110 }
111
DambustrExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32 x,INT32)112 void DambustrExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32 x, INT32)
113 {
114 if (GalGfxBank[0] == 0) {
115 *Code |= 0x300;
116 } else {
117 if (x == 28) {
118 *Code |= 0x300;
119 } else {
120 *Code &= 0xff;
121 }
122 }
123 }
124
Ad2083ExtendTileInfo(UINT16 * Code,INT32 * Colour,INT32 Attr,INT32,INT32)125 void Ad2083ExtendTileInfo(UINT16 *Code, INT32 *Colour, INT32 Attr, INT32, INT32)
126 {
127 INT32 Bank = Attr & 0x30;
128 *Code |= (Bank << 4);
129 *Colour |= ((Attr & 0x40) >> 3);
130 }
131
RacknrolExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32 x,INT32)132 void RacknrolExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32 x, INT32)
133 {
134 UINT8 Bank = GalGfxBank[x] & 7;
135 *Code |= Bank << 8;
136 }
137
HaremExtendTileInfo(UINT16 * Code,INT32 * color,INT32,INT32 x,INT32)138 void HaremExtendTileInfo(UINT16 *Code, INT32 *color, INT32, INT32 x, INT32)
139 {
140 UINT8 Bank = (GalGfxBank[1] >> (x / 4)) & 1;
141 *Code |= Bank * 0x200;
142 *color |= GAL_TMAP_OPAQUE; // all Opaque
143 }
144
NamenayoExtendTileInfo(UINT16 * code,INT32 * color,INT32 attr,INT32 x,INT32 y)145 void NamenayoExtendTileInfo(UINT16 *code, INT32 *color, INT32 attr, INT32 x, INT32 y)
146 {
147 if (~attr & 1) { // pf/hud
148 INT32 e_at = namenayo_extattr[y & 0x1f];
149 *code += (e_at & 0x38) << 5;
150 *color = (e_at & 0x07);
151 if (x < (0x1f - 8)) *color |= GAL_TMAP_OPAQUE; // pf: opaque, hud: transparent
152 } else {
153 // map
154 *code += ((attr & 0xfe) == 0x20) ? 0x400 : 0;
155 }
156 }
157
BagmanmcExtendTileInfo(UINT16 * Code,INT32 *,INT32,INT32,INT32)158 void BagmanmcExtendTileInfo(UINT16 *Code, INT32*, INT32, INT32, INT32)
159 {
160 *Code |= GalGfxBank[0] << 9;
161 }
162
163 // Sprite extend helpers
NamenayoExtendSpriteInfo(const UINT8 * base,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * code,UINT8 * color)164 void NamenayoExtendSpriteInfo(const UINT8 *base, INT32*, INT32*, UINT8*, UINT8*, UINT16 *code, UINT8 *color)
165 {
166 *code += (base[2] & 0x08) << 3;
167 *color += 0x08;
168 }
169
PacmanblExtendSpriteInfo(const UINT8 *,INT32 * sx,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)170 void PacmanblExtendSpriteInfo(const UINT8*, INT32 *sx, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
171 {
172 // Sprites on the topmost row of the maze are ok, everywhere else need
173 // their x-offset attenuated to keep sprites off of the maze walls. -dink dec.2020
174 if (*sx >= 18 && *sx <= 24) {
175 *sx += 1;
176 }
177 if (*sx >= 25 && *sx <= 29) {
178 *sx += 2;
179 }
180 if (*sx >= 30) {
181 *sx += 3;
182 }
183 }
184
UpperExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)185 void UpperExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
186 {
187 *Code += 0x40;
188 }
189
PiscesExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)190 void PiscesExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
191 {
192 *Code |= GalGfxBank[0] << 6;
193 }
194
GmgalaxExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)195 void GmgalaxExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
196 {
197 *Code |= (GalGfxBank[0] << 7) | 0x40;
198 }
199
MooncrstExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)200 void MooncrstExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
201 {
202 if (GalGfxBank[2] && (*Code & 0x30) == 0x20) *Code = (*Code & 0x0f) | (GalGfxBank[0] << 4) | (GalGfxBank[1] << 5) | 0x40;
203 }
204
MoonqsrExtendSpriteInfo(const UINT8 * Base,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)205 void MoonqsrExtendSpriteInfo(const UINT8 *Base, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
206 {
207 *Code |= (Base[2] & 0x20) << 1;
208 }
209
SkybaseExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)210 void SkybaseExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
211 {
212 *Code |= GalGfxBank[2] << 6;
213 }
214
RockclimExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)215 void RockclimExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
216 {
217 if ((*Code & 0x30) == 0x20) {
218 if (GalGfxBank[2] & 1) {
219 INT32 bank = (((GalGfxBank[0] & 1) << 5) | ((GalGfxBank[1] & 1) << 4));
220 *Code = (0x40 + bank) | (*Code & 0x0f);
221 }
222 }
223 }
224
JumpbugExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)225 void JumpbugExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
226 {
227 if ((*Code & 0x30) == 0x20 && (GalGfxBank[2] & 0x01) != 0) *Code += 32 + ((GalGfxBank[0] & 0x01) << 4) + ((GalGfxBank[1] & 0x01) << 5) + ((~GalGfxBank[4] & 0x01) << 6);
228 }
229
FroggerExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 *,UINT8 * Colour)230 void FroggerExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16*, UINT8 *Colour)
231 {
232 *Colour = ((*Colour >> 1) & 0x03) | ((*Colour << 2) & 0x04);
233 }
234
CalipsoExtendSpriteInfo(const UINT8 * Base,INT32 *,INT32 *,UINT8 * xFlip,UINT8 * yFlip,UINT16 * Code,UINT8 *)235 void CalipsoExtendSpriteInfo(const UINT8 *Base, INT32*, INT32*, UINT8 *xFlip, UINT8 *yFlip, UINT16 *Code, UINT8*)
236 {
237 *Code = Base[1];
238 *xFlip = 0;
239 *yFlip = 0;
240 }
241
MshuttleExtendSpriteInfo(const UINT8 * Base,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)242 void MshuttleExtendSpriteInfo(const UINT8 *Base, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
243 {
244 *Code |= (Base[2] & 0x30) << 2;
245 }
246
Fourin1ExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)247 void Fourin1ExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
248 {
249 *Code |= Fourin1Bank << 6;
250 }
251
DkongjrmExtendSpriteInfo(const UINT8 * Base,INT32 *,INT32 *,UINT8 * xFlip,UINT8 *,UINT16 * Code,UINT8 *)252 void DkongjrmExtendSpriteInfo(const UINT8 *Base, INT32*, INT32*, UINT8 *xFlip, UINT8*, UINT16 *Code, UINT8*)
253 {
254 *Code = (Base[1] & 0x7f) | 0x80;
255 *xFlip = 0;
256 }
257
MimonkeyExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)258 void MimonkeyExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
259 {
260 *Code |= (GalGfxBank[0] << 6) | (GalGfxBank[1] << 7);
261 }
262
Ad2083ExtendSpriteInfo(const UINT8 * Base,INT32 *,INT32 *,UINT8 * xFlip,UINT8 *,UINT16 * Code,UINT8 *)263 void Ad2083ExtendSpriteInfo(const UINT8 *Base, INT32*, INT32*, UINT8 *xFlip, UINT8*, UINT16 *Code, UINT8*)
264 {
265 *Code = (Base[1] & 0x7f) | ((Base[2] & 0x30) << 2);
266 *xFlip = 0;
267 }
268
BagmanmcExtendSpriteInfo(const UINT8 *,INT32 *,INT32 *,UINT8 *,UINT8 *,UINT16 * Code,UINT8 *)269 void BagmanmcExtendSpriteInfo(const UINT8*, INT32*, INT32*, UINT8*, UINT8*, UINT16 *Code, UINT8*)
270 {
271 *Code |= (GalGfxBank[0] << 7) | 0x40;
272 }
273
274 // Hardcode a Galaxian PROM for any games that are missing a PROM dump
HardCodeGalaxianPROM()275 void HardCodeGalaxianPROM()
276 {
277 GalProm[0x00]= 0x00;
278 GalProm[0x01]= 0x00;
279 GalProm[0x02]= 0x00;
280 GalProm[0x03]= 0xf6;
281 GalProm[0x04]= 0x00;
282 GalProm[0x05]= 0x16;
283 GalProm[0x06]= 0xc0;
284 GalProm[0x07]= 0x3f;
285 GalProm[0x08]= 0x00;
286 GalProm[0x09]= 0xd8;
287 GalProm[0x0a]= 0x07;
288 GalProm[0x0b]= 0x3f;
289 GalProm[0x0c]= 0x00;
290 GalProm[0x0d]= 0xc0;
291 GalProm[0x0e]= 0xc4;
292 GalProm[0x0f]= 0x07;
293 GalProm[0x10]= 0x00;
294 GalProm[0x11]= 0xc0;
295 GalProm[0x12]= 0xa0;
296 GalProm[0x13]= 0x07;
297 GalProm[0x14]= 0x00;
298 GalProm[0x15]= 0x00;
299 GalProm[0x16]= 0x00;
300 GalProm[0x17]= 0x07;
301 GalProm[0x18]= 0x00;
302 GalProm[0x19]= 0xf6;
303 GalProm[0x1a]= 0x07;
304 GalProm[0x1b]= 0xf0;
305 GalProm[0x1c]= 0x00;
306 GalProm[0x1d]= 0x76;
307 GalProm[0x1e]= 0x07;
308 GalProm[0x1f]= 0xc6;
309 }
310
HardCodeMooncrstPROM()311 void HardCodeMooncrstPROM()
312 {
313 GalProm[0x00]= 0x00;
314 GalProm[0x01]= 0x7a;
315 GalProm[0x02]= 0x36;
316 GalProm[0x03]= 0x07;
317 GalProm[0x04]= 0x00;
318 GalProm[0x05]= 0xf0;
319 GalProm[0x06]= 0x38;
320 GalProm[0x07]= 0x1f;
321 GalProm[0x08]= 0x00;
322 GalProm[0x09]= 0xc7;
323 GalProm[0x0a]= 0xf0;
324 GalProm[0x0b]= 0x3f;
325 GalProm[0x0c]= 0x00;
326 GalProm[0x0d]= 0xdb;
327 GalProm[0x0e]= 0xc6;
328 GalProm[0x0f]= 0x38;
329 GalProm[0x10]= 0x00;
330 GalProm[0x11]= 0x36;
331 GalProm[0x12]= 0x07;
332 GalProm[0x13]= 0xf0;
333 GalProm[0x14]= 0x00;
334 GalProm[0x15]= 0x33;
335 GalProm[0x16]= 0x3f;
336 GalProm[0x17]= 0xdb;
337 GalProm[0x18]= 0x00;
338 GalProm[0x19]= 0x3f;
339 GalProm[0x1a]= 0x57;
340 GalProm[0x1b]= 0xc6;
341 GalProm[0x1c]= 0x00;
342 GalProm[0x1d]= 0xc6;
343 GalProm[0x1e]= 0x3f;
344 GalProm[0x1f]= 0xff;
345 }
346
347 // Palette generation
348 #define RGB_MAXIMUM 224
349
GalaxianCalcPalette()350 void GalaxianCalcPalette()
351 {
352 static const INT32 RGBResistances[3] = {1000, 470, 220};
353 double rWeights[3], gWeights[3], bWeights[2];
354
355 compute_resistor_weights(0, RGB_MAXIMUM, -1.0, 3, &RGBResistances[0], rWeights, 470, 0, 3, &RGBResistances[0], gWeights, 470, 0, 2, &RGBResistances[1], bWeights, 470, 0);
356
357 // Colour PROM
358 for (INT32 i = 0; i < 32; i++) {
359 UINT8 Bit0, Bit1, Bit2, r, g, b;
360
361 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],0);
362 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],1);
363 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],2);
364 r = combine_3_weights(rWeights, Bit0, Bit1, Bit2);
365
366 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],3);
367 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],4);
368 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],5);
369 g = combine_3_weights(gWeights, Bit0, Bit1, Bit2);
370
371 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],6);
372 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],7);
373 b = combine_2_weights(bWeights, Bit0, Bit1);
374
375 GalPalette[i] = BurnHighCol(r, g, b, 0);
376 }
377
378 // Stars
379 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_STARS; i++) {
380 INT32 Bits, r, g, b;
381 INT32 Map[4] = {0x00, 0x88, 0xcc, 0xff};
382
383 Bits = (i >> 0) & 0x03;
384 r = Map[Bits];
385 Bits = (i >> 2) & 0x03;
386 g = Map[Bits];
387 Bits = (i >> 4) & 0x03;
388 b = Map[Bits];
389
390 GalPalette[i + GAL_PALETTE_STARS_OFFSET] = BurnHighCol(r, g, b, 0);
391 }
392
393 // Bullets
394 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_BULLETS - 1; i++) {
395 GalPalette[i + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0xff, 0);
396 }
397 GalPalette[GAL_PALETTE_NUM_COLOURS_BULLETS - 1 + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0x00, 0);
398 }
399
RockclimCalcPalette()400 void RockclimCalcPalette()
401 {
402 static const INT32 RGBResistances[3] = {1000, 470, 220};
403 double rWeights[3], gWeights[3], bWeights[2];
404
405 compute_resistor_weights(0, RGB_MAXIMUM, -1.0, 3, &RGBResistances[0], rWeights, 470, 0, 3, &RGBResistances[0], gWeights, 470, 0, 2, &RGBResistances[1], bWeights, 470, 0);
406
407 // Colour PROM
408 for (INT32 i = 0; i < 64; i++) {
409 UINT8 Bit0, Bit1, Bit2, r, g, b;
410
411 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],0);
412 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],1);
413 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],2);
414 r = combine_3_weights(rWeights, Bit0, Bit1, Bit2);
415
416 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],3);
417 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],4);
418 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],5);
419 g = combine_3_weights(gWeights, Bit0, Bit1, Bit2);
420
421 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],6);
422 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],7);
423 b = combine_2_weights(bWeights, Bit0, Bit1);
424
425 GalPalette[i] = BurnHighCol(r, g, b, 0);
426 }
427
428 // Stars
429 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_STARS; i++) {
430 INT32 Bits, r, g, b;
431 INT32 Map[4] = {0x00, 0x88, 0xcc, 0xff};
432
433 Bits = (i >> 0) & 0x03;
434 r = Map[Bits];
435 Bits = (i >> 2) & 0x03;
436 g = Map[Bits];
437 Bits = (i >> 4) & 0x03;
438 b = Map[Bits];
439
440 GalPalette[i + GAL_PALETTE_STARS_OFFSET] = BurnHighCol(r, g, b, 0);
441 }
442
443 // Bullets
444 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_BULLETS - 1; i++) {
445 GalPalette[i + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0xff, 0);
446 }
447 GalPalette[GAL_PALETTE_NUM_COLOURS_BULLETS - 1 + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0x00, 0);
448 }
449
MarinerCalcPalette()450 void MarinerCalcPalette()
451 {
452 GalaxianCalcPalette();
453
454 for (INT32 i = 0; i < 16; i++) {
455 INT32 b = 0x0e * BIT(i, 0) + 0x1f * BIT(i, 1) + 0x43 * BIT(i, 2) + 0x8f * BIT(i, 3);
456 GalPalette[i + GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(0, 0, b, 0);
457 }
458 }
459
StratgyxCalcPalette()460 void StratgyxCalcPalette()
461 {
462 GalaxianCalcPalette();
463
464 for (INT32 i = 0; i < 8; i++) {
465 INT32 r = BIT(i, 0) * 0x7c;
466 INT32 g = BIT(i, 1) * 0x3c;
467 INT32 b = BIT(i, 2) * 0x47;
468 GalPalette[i + GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(r, g, b, 0);
469 }
470 }
471
RescueCalcPalette()472 void RescueCalcPalette()
473 {
474 GalaxianCalcPalette();
475
476 for (INT32 i = 0; i < 128; i++) {
477 INT32 b = i * 2;
478 GalPalette[i + GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(0, 0, b, 0);
479 }
480 }
481
MinefldCalcPalette()482 void MinefldCalcPalette()
483 {
484 RescueCalcPalette();
485
486 for (INT32 i = 0; i < 128; i++) {
487 INT32 r = (INT32)(i * 1.5);
488 INT32 g = (INT32)(i * 0.75);
489 INT32 b = i / 2;
490 GalPalette[i + 128 + GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(r, g, b, 0);
491 }
492 }
493
DarkplntCalcPalette()494 void DarkplntCalcPalette()
495 {
496 static const INT32 RGBResistances[3] = {1000, 470, 220};
497 double rWeights[3], gWeights[3], bWeights[2];
498
499 compute_resistor_weights(0, RGB_MAXIMUM, -1.0, 3, &RGBResistances[0], rWeights, 470, 0, 3, &RGBResistances[0], gWeights, 470, 0, 2, &RGBResistances[1], bWeights, 470, 0);
500
501 // Colour PROM
502 for (INT32 i = 0; i < 32; i++) {
503 UINT8 Bit0, Bit1, Bit2, r, g, b;
504
505 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],0);
506 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],1);
507 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],2);
508 r = combine_3_weights(rWeights, Bit0, Bit1, Bit2);
509
510 g = 0;
511
512 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],3);
513 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],4);
514 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],5);
515 b = combine_2_weights(bWeights, Bit0, Bit1);
516
517 GalPalette[i] = BurnHighCol(r, g, b, 0);
518 }
519
520 // Stars
521 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_STARS; i++) {
522 INT32 Bits, r, g, b;
523 INT32 Map[4] = {0x00, 0x88, 0xcc, 0xff};
524
525 Bits = (i >> 0) & 0x03;
526 r = Map[Bits];
527 Bits = (i >> 2) & 0x03;
528 g = Map[Bits];
529 Bits = (i >> 4) & 0x03;
530 b = Map[Bits];
531
532 GalPalette[i + GAL_PALETTE_STARS_OFFSET] = BurnHighCol(r, g, b, 0);
533 }
534
535 // Bullets
536 GalPalette[0 + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xef, 0x00, 0x00, 0);
537 GalPalette[1 + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0x00, 0x00, 0xef, 0);
538 }
539
DambustrCalcPalette()540 void DambustrCalcPalette()
541 {
542 static const INT32 RGBResistances[3] = {1000, 470, 220};
543 double rWeights[3], gWeights[3], bWeights[2];
544
545 compute_resistor_weights(0, RGB_MAXIMUM, -1.0, 3, &RGBResistances[0], rWeights, 470, 0, 3, &RGBResistances[0], gWeights, 470, 0, 2, &RGBResistances[1], bWeights, 470, 0);
546
547 // Colour PROM
548 for (INT32 i = 0; i < 32; i++) {
549 UINT8 Bit0, Bit1, Bit2, r, g, b;
550
551 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],0);
552 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],1);
553 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],2);
554 b = combine_3_weights(rWeights, Bit0, Bit1, Bit2);
555
556 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],3);
557 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],4);
558 Bit2 = BIT(GalProm[i + (GalPaletteBank * 0x20)],5);
559 r = combine_3_weights(gWeights, Bit0, Bit1, Bit2);
560
561 Bit0 = BIT(GalProm[i + (GalPaletteBank * 0x20)],6);
562 Bit1 = BIT(GalProm[i + (GalPaletteBank * 0x20)],7);
563 g = combine_2_weights(bWeights, Bit0, Bit1);
564
565 GalPalette[i] = BurnHighCol(r, g, b, 0);
566 }
567
568 // Stars
569 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_STARS; i++) {
570 INT32 Bits, r, g, b;
571 INT32 Map[4] = {0x00, 0x88, 0xcc, 0xff};
572
573 Bits = (i >> 0) & 0x03;
574 r = Map[Bits];
575 Bits = (i >> 2) & 0x03;
576 g = Map[Bits];
577 Bits = (i >> 4) & 0x03;
578 b = Map[Bits];
579
580 GalPalette[i + GAL_PALETTE_STARS_OFFSET] = BurnHighCol(r, g, b, 0);
581 }
582
583 // Bullets
584 for (INT32 i = 0; i < GAL_PALETTE_NUM_COLOURS_BULLETS - 1; i++) {
585 GalPalette[i + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0xff, 0);
586 }
587 GalPalette[GAL_PALETTE_NUM_COLOURS_BULLETS - 1 + GAL_PALETTE_BULLETS_OFFSET] = BurnHighCol(0xff, 0xff, 0x00, 0);
588
589 for (INT32 i = 0; i < 8; i++) {
590 INT32 r = BIT(i, 0) * 0x47;
591 INT32 g = BIT(i, 1) * 0x47;
592 INT32 b = BIT(i, 2) * 0x4f;
593 GalPalette[i + GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(r, g, b, 0);
594 }
595 }
596
597 #undef RGB_MAXIMUM
598
599 // Background and Stars rendering
GalaxianDrawBackground()600 void GalaxianDrawBackground()
601 {
602 if (GalStarsEnable) GalaxianRenderStarLayer();
603 }
604
RockclimDrawBackground()605 void RockclimDrawBackground()
606 {
607 INT32 mx, my, Code, Colour, x, y, TileIndex = 0;
608
609 for (my = 0; my < 32; my++) {
610 for (mx = 0; mx < 64; mx++) {
611 Code = GalVideoRam2[TileIndex];
612 Colour = 0;
613
614 x = 8 * mx;
615 y = 8 * my;
616
617 x -= RockclimScrollX & 0x1ff;
618 y -= RockclimScrollY & 0xff;
619
620 if (x < -8) x += 512;
621 if (y < -8) y += 256;
622
623 y -= 16;
624
625 if (GalFlipScreenX) x = nScreenWidth - 8 - x;
626 if (GalFlipScreenY) y = nScreenHeight - 8 - y;
627
628 Draw8x8Tile(pTransDraw, Code, x, y, GalFlipScreenX, GalFlipScreenY, Colour, 4, 32, RockclimTiles);
629
630 TileIndex++;
631 }
632 }
633 }
634
JumpbugDrawBackground()635 void JumpbugDrawBackground()
636 {
637 if (GalStarsEnable) JumpbugRenderStarLayer();
638 }
639
FroggerDrawBackground()640 void FroggerDrawBackground()
641 {
642 GalPalette[GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(0, 0, 0x47, 0);
643
644 if (GalFlipScreenX) {
645 for (INT32 y = 0; y < nScreenHeight; y++) {
646 for (INT32 x = nScreenWidth - 1; x > 128 - 8; x--) {
647 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
648 }
649 }
650 } else {
651 for (INT32 y = 0; y < nScreenHeight; y++) {
652 for (INT32 x = 0; x < 128; x++) {
653 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
654 }
655 }
656 }
657 }
658
TurtlesDrawBackground()659 void TurtlesDrawBackground()
660 {
661 GalPalette[GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(GalBackgroundRed * 0x55, GalBackgroundGreen * 0x47, GalBackgroundBlue * 0x55, 0);
662
663 for (INT32 y = 0; y < nScreenHeight; y++) {
664 for (INT32 x = 0; x < nScreenWidth; x++) {
665 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
666 }
667 }
668 }
669
ScrambleDrawBackground()670 void ScrambleDrawBackground()
671 {
672 GalPalette[GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(0, 0, 0x56, 0);
673
674 if (GalBackgroundEnable) {
675 for (INT32 y = 0; y < nScreenHeight; y++) {
676 for (INT32 x = 0; x < nScreenWidth; x++) {
677 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
678 }
679 }
680 }
681
682 if (GalStarsEnable) ScrambleRenderStarLayer();
683 }
684
AnteaterDrawBackground()685 void AnteaterDrawBackground()
686 {
687 GalPalette[GAL_PALETTE_BACKGROUND_OFFSET] = BurnHighCol(0, 0, 0x56, 0);
688
689 if (GalBackgroundEnable) {
690 if (GalFlipScreenX) {
691 for (INT32 y = 0; y < nScreenHeight; y++) {
692 for (INT32 x = nScreenWidth - 1; x > 256 - 56; x--) {
693 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
694 }
695 }
696 } else {
697 for (INT32 y = 0; y < nScreenHeight; y++) {
698 for (INT32 x = 0; x < 56; x++) {
699 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET;
700 }
701 }
702 }
703 }
704 }
705
MarinerDrawBackground()706 void MarinerDrawBackground()
707 {
708 UINT8 *BgColourProm = GalProm + 0x20;
709 INT32 x;
710
711 if (GalFlipScreenX) {
712 for (x = 0; x < 32; x++) {
713 INT32 Colour;
714
715 if (x == 0) {
716 Colour = 0;
717 } else {
718 Colour = BgColourProm[0x20 + x - 1];
719 }
720
721 INT32 xStart = 8 * (31 - x);
722 for (INT32 sy = 0; sy < nScreenHeight; sy++) {
723 for (INT32 sx = xStart; sx < xStart + 8; sx++) {
724 pTransDraw[(sy * nScreenWidth) + sx] = GAL_PALETTE_BACKGROUND_OFFSET + Colour;
725 }
726 }
727 }
728 } else {
729 for (x = 0; x < 32; x++) {
730 INT32 Colour;
731
732 if (x == 31) {
733 Colour = 0;
734 } else {
735 Colour = BgColourProm[x + 1];
736 }
737
738 INT32 xStart = x * 8;
739 for (INT32 sy = 0; sy < nScreenHeight; sy++) {
740 for (INT32 sx = xStart; sx < xStart + 8; sx++) {
741 pTransDraw[(sy * nScreenWidth) + sx] = GAL_PALETTE_BACKGROUND_OFFSET + Colour;
742 }
743 }
744 }
745 }
746
747 if (GalStarsEnable) MarinerRenderStarLayer();
748 }
749
StratgyxDrawBackground()750 void StratgyxDrawBackground()
751 {
752 UINT8 *BgColourProm = GalProm + 0x20;
753
754 for (INT32 x = 0; x < 32; x++) {
755 INT32 xStart, Colour = 0;
756
757 if ((~BgColourProm[x] & 0x02) && GalBackgroundRed) Colour |= 0x01;
758 if ((~BgColourProm[x] & 0x02) && GalBackgroundGreen) Colour |= 0x02;
759 if ((~BgColourProm[x] & 0x01) && GalBackgroundBlue) Colour |= 0x04;
760
761 if (GalFlipScreenX) {
762 xStart = 8 * (31 - x);
763 } else {
764 xStart = 8 * x;
765 }
766
767 for (INT32 sy = 0; sy < nScreenHeight; sy++) {
768 for (INT32 sx = xStart; sx < xStart + 8; sx++) {
769 pTransDraw[(sy * nScreenWidth) + sx] = GAL_PALETTE_BACKGROUND_OFFSET + Colour;
770 }
771 }
772 }
773 }
774
RescueDrawBackground()775 void RescueDrawBackground()
776 {
777 if (GalBackgroundEnable) {
778 INT32 x;
779
780 for (x = 0; x < 128; x++) {
781 for (INT32 y = 0; y < nScreenHeight; y++) {
782 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET + x;
783 }
784 }
785
786 for (x = 0; x < 120; x++) {
787 for (INT32 y = 0; y < nScreenHeight; y++) {
788 pTransDraw[(y * nScreenWidth) + (x + 128)] = GAL_PALETTE_BACKGROUND_OFFSET + x + 8;
789 }
790 }
791
792 for (x = 0; x < 8; x++) {
793 for (INT32 y = 0; y < nScreenHeight; y++) {
794 pTransDraw[(y * nScreenWidth) + (x + 248)] = GAL_PALETTE_BACKGROUND_OFFSET;
795 }
796 }
797 }
798
799 if (GalStarsEnable) RescueRenderStarLayer();
800 }
801
MinefldDrawBackground()802 void MinefldDrawBackground()
803 {
804 if (GalBackgroundEnable) {
805 INT32 x;
806
807 for (x = 0; x < 128; x++) {
808 for (INT32 y = 0; y < nScreenHeight; y++) {
809 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET + x;
810 }
811 }
812
813 for (x = 0; x < 120; x++) {
814 for (INT32 y = 0; y < nScreenHeight; y++) {
815 pTransDraw[(y * nScreenWidth) + (x + 128)] = GAL_PALETTE_BACKGROUND_OFFSET + x + 128;
816 }
817 }
818
819 for (x = 0; x < 8; x++) {
820 for (INT32 y = 0; y < nScreenHeight; y++) {
821 pTransDraw[(y * nScreenWidth) + (x + 248)] = GAL_PALETTE_BACKGROUND_OFFSET;
822 }
823 }
824 }
825
826 if (GalStarsEnable) RescueRenderStarLayer();
827 }
828
DambustrDrawBackground()829 void DambustrDrawBackground()
830 {
831 INT32 xClipStart = GalFlipScreenX ? 254 - DambustrBgSplitLine : 0;
832 INT32 xClipEnd = GalFlipScreenX ? 0 : 254 - DambustrBgSplitLine;
833
834 for (INT32 x = 0; x < 256 - DambustrBgSplitLine; x++) {
835 if (DambustrBgPriority && (x < xClipStart || x > xClipEnd)) continue;
836 for (INT32 y = 0; y < nScreenHeight; y++) {
837 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET + ((GalFlipScreenX) ? DambustrBgColour2 : DambustrBgColour1);
838 }
839 }
840
841 for (INT32 x = 255; x > 256 - DambustrBgSplitLine; x--) {
842 if (DambustrBgPriority && (x < xClipStart || x > xClipEnd)) continue;
843 for (INT32 y = 0; y < nScreenHeight; y++) {
844 pTransDraw[(y * nScreenWidth) + x] = GAL_PALETTE_BACKGROUND_OFFSET + ((GalFlipScreenX) ? DambustrBgColour1 : DambustrBgColour2);
845 }
846 }
847
848 if (GalStarsEnable && !DambustrBgPriority) GalaxianRenderStarLayer();
849 }
850
851 // Char Layer rendering
GalRenderBgLayer(UINT8 * pVideoRam)852 static void GalRenderBgLayer(UINT8 *pVideoRam)
853 {
854 INT32 mx, my, Attr, Colour, x, y, TileIndex = 0, RamPos, DrawOpaque;
855 UINT16 Code;
856
857 for (my = 0; my < 32; my++) {
858 for (mx = 0; mx < 32; mx++) {
859 RamPos = TileIndex & 0x1f;
860 Code = pVideoRam[TileIndex];
861 Attr = GalSpriteRam[(RamPos * 2) + 1];
862 Colour = Attr & ((GalColourDepth == 3) ? 0x03 : 0x07);
863
864 if (GalExtendTileInfoFunction) GalExtendTileInfoFunction(&Code, &Colour, Attr, RamPos, TileIndex >> 5);
865
866 DrawOpaque = Colour & GAL_TMAP_OPAQUE; // extended tile info can tag Opaque this way
867 Colour &= ~GAL_TMAP_OPAQUE;
868
869 if (SfxTilemap) {
870 x = 8 * my;
871 y = 8 * mx;
872 } else {
873 x = 8 * mx;
874 y = 8 * my;
875 }
876
877 y -= 16;
878
879 if (GalFlipScreenX) x = nScreenWidth - 8 - x;
880 if (GalFlipScreenY) y = nScreenHeight - 8 - y;
881
882 INT32 px, py;
883
884 UINT32 nPalette = Colour << GalColourDepth;
885
886 for (py = 0; py < 8; py++) {
887 for (px = 0; px < 8; px++) {
888 UINT8 c = GalChars[(Code * 64) + (py * 8) + px];
889 if (GalFlipScreenX) c = GalChars[(Code * 64) + (py * 8) + (7 - px)];
890 if (GalFlipScreenY) c = GalChars[(Code * 64) + ((7 - py) * 8) + px];
891 if (GalFlipScreenX && GalFlipScreenY) c = GalChars[(Code * 64) + ((7 - py) * 8) + (7 - px)];
892
893 if (c || DrawOpaque) { // Harem, Namenayo has no transparency on this layer
894 INT32 xPos = x + px;
895 INT32 yPos = y + py;
896
897 if (SfxTilemap) {
898 if (GalFlipScreenX) {
899 xPos += GalScrollVals[mx];
900 } else {
901 xPos -= GalScrollVals[mx];
902 }
903
904 if (xPos < 0) xPos += 256;
905 if (xPos > 255) xPos -= 256;
906 } else {
907 if (GalFlipScreenY) {
908 yPos += GalScrollVals[mx];
909 } else {
910 yPos -= GalScrollVals[mx];
911 }
912
913 if (yPos < 0) yPos += 256;
914 if (yPos > 255) yPos -= 256;
915 }
916
917 if (GalOrientationFlipX) {
918 xPos = nScreenWidth - 1 - xPos;
919 }
920
921 if (yPos >= 0 && yPos < nScreenHeight) {
922 UINT16* pPixel = pTransDraw + (yPos * nScreenWidth);
923
924 if (xPos >= 0 && xPos < nScreenWidth) {
925 pPixel[xPos] = c | nPalette;
926 }
927 }
928 }
929 }
930 }
931
932 TileIndex++;
933 }
934 }
935 }
936
937 // Sprite Rendering
GalRenderSprites(const UINT8 * SpriteBase)938 static void GalRenderSprites(const UINT8 *SpriteBase)
939 {
940 INT32 SprNum;
941 INT32 ClipOfs = GalFlipScreenX ? 16 : 0;
942 INT32 xMin = GalSpriteClipStart - ClipOfs;
943 INT32 xMax = GalSpriteClipEnd - ClipOfs + 1;
944
945 for (SprNum = 7; SprNum >= 0; SprNum--) {
946 const UINT8 *Base = &SpriteBase[SprNum * 4];
947 UINT8 Base0 = FroggerAdjust ? ((Base[0] >> 4) | (Base[0] << 4)) : Base[0];
948 INT32 sy = 240 - (Base0 - (SprNum < 3));
949 UINT16 Code = Base[1] & 0x3f;
950 UINT8 xFlip = Base[1] & 0x40;
951 UINT8 yFlip = Base[1] & 0x80;
952 UINT8 Colour = Base[2] & ((GalColourDepth == 3) ? 0x03 : 0x07);
953 INT32 sx = Base[3];
954
955 if (GalExtendSpriteInfoFunction) GalExtendSpriteInfoFunction(Base, &sx, &sy, &xFlip, &yFlip, &Code, &Colour);
956
957 if (GalFlipScreenX) {
958 sx = 242 - sx;
959 xFlip = !xFlip;
960 }
961
962 if (sx < xMin || sx > xMax) continue;
963
964 if (GalFlipScreenY) {
965 sy = 240 - sy;
966 yFlip = !yFlip;
967 }
968
969 sy -= 16;
970
971 if (GalOrientationFlipX) {
972 sx = 242 - 1 - sx;
973 xFlip = !xFlip;
974 }
975
976 Draw16x16MaskTile(pTransDraw, Code, sx, sy, xFlip, yFlip, Colour, GalColourDepth, 0, 0, GalSprites);
977 }
978 }
979
980 // Bullet rendering
GalDrawPixel(INT32 x,INT32 y,INT32 Colour)981 static inline void GalDrawPixel(INT32 x, INT32 y, INT32 Colour)
982 {
983 if (y >= 0 && y < nScreenHeight && x >= 0 && x < nScreenWidth) {
984 pTransDraw[(y * nScreenWidth) + x] = Colour;
985 }
986 }
987
GalaxianDrawBullets(INT32 Offs,INT32 x,INT32 y)988 void GalaxianDrawBullets(INT32 Offs, INT32 x, INT32 y)
989 {
990 x -= 4;
991
992 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
993 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
994 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
995 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
996 }
997
TheendDrawBullets(INT32 Offs,INT32 x,INT32 y)998 void TheendDrawBullets(INT32 Offs, INT32 x, INT32 y)
999 {
1000 x -= 4;
1001
1002 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 7] = BurnHighCol(0xff, 0x00, 0xff, 0);
1003
1004 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
1005 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
1006 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
1007 GalDrawPixel(x++, y, GAL_PALETTE_BULLETS_OFFSET + Offs);
1008 }
1009
ScrambleDrawBullets(INT32,INT32 x,INT32 y)1010 void ScrambleDrawBullets(INT32, INT32 x, INT32 y)
1011 {
1012 x -= 6;
1013
1014 GalDrawPixel(x, y, GAL_PALETTE_BULLETS_OFFSET + 7);
1015 }
1016
MoonwarDrawBullets(INT32,INT32 x,INT32 y)1017 void MoonwarDrawBullets(INT32, INT32 x, INT32 y)
1018 {
1019 x -= 6;
1020
1021 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 7] = BurnHighCol(0xef, 0xef, 0x97, 0);
1022
1023 GalDrawPixel(x, y, GAL_PALETTE_BULLETS_OFFSET + 7);
1024 }
1025
MshuttleDrawBullets(INT32,INT32 x,INT32 y)1026 void MshuttleDrawBullets(INT32, INT32 x, INT32 y)
1027 {
1028 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 0] = BurnHighCol(0xff, 0xff, 0xff, 0);
1029 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 1] = BurnHighCol(0xff, 0xff, 0x00, 0);
1030 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 2] = BurnHighCol(0x00, 0xff, 0xff, 0);
1031 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 3] = BurnHighCol(0x00, 0xff, 0x00, 0);
1032 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 4] = BurnHighCol(0xff, 0x00, 0xff, 0);
1033 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 5] = BurnHighCol(0xff, 0x00, 0x00, 0);
1034 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 6] = BurnHighCol(0x00, 0x00, 0xff, 0);
1035 GalPalette[GAL_PALETTE_BULLETS_OFFSET + 7] = BurnHighCol(0x00, 0x00, 0x00, 0);
1036
1037 --x;
1038 GalDrawPixel(x, y, ((x & 0x40) == 0) ? GAL_PALETTE_BULLETS_OFFSET + + ((x >> 2) & 7) : GAL_PALETTE_BULLETS_OFFSET + + 4);
1039 --x;
1040 GalDrawPixel(x, y, ((x & 0x40) == 0) ? GAL_PALETTE_BULLETS_OFFSET + + ((x >> 2) & 7) : GAL_PALETTE_BULLETS_OFFSET + + 4);
1041 --x;
1042 GalDrawPixel(x, y, ((x & 0x40) == 0) ? GAL_PALETTE_BULLETS_OFFSET + + ((x >> 2) & 7) : GAL_PALETTE_BULLETS_OFFSET + + 4);
1043 --x;
1044 GalDrawPixel(x, y, ((x & 0x40) == 0) ? GAL_PALETTE_BULLETS_OFFSET + + ((x >> 2) & 7) : GAL_PALETTE_BULLETS_OFFSET + + 4);
1045 }
1046
DarkplntDrawBullets(INT32,INT32 x,INT32 y)1047 void DarkplntDrawBullets(INT32, INT32 x, INT32 y)
1048 {
1049 if (GalFlipScreenX) x++;
1050
1051 x -= 6;
1052
1053 GalDrawPixel(x, y, GAL_PALETTE_BULLETS_OFFSET + DarkplntBulletColour);
1054 }
1055
DambustrDrawBullets(INT32 Offs,INT32 x,INT32 y)1056 void DambustrDrawBullets(INT32 Offs, INT32 x, INT32 y)
1057 {
1058 INT32 Colour;
1059
1060 if (GalFlipScreenX) x++;
1061
1062 x -= 6;
1063
1064 for (INT32 i = 0; i < 2; i++) {
1065 if (Offs < 16) {
1066 Colour = GAL_PALETTE_BULLETS_OFFSET + 7;
1067 y--;
1068 } else {
1069 Colour = GAL_PALETTE_BULLETS_OFFSET;
1070 x--;
1071 }
1072 }
1073
1074 GalDrawPixel(x, y, Colour);
1075 }
1076
GalDrawBullets(const UINT8 * Base)1077 static void GalDrawBullets(const UINT8 *Base)
1078 {
1079 for (INT32 y = 0; y < nScreenHeight; y++) {
1080 UINT8 Shell = 0xff;
1081 UINT8 Missile = 0xff;
1082 UINT8 yEff;
1083 INT32 Which;
1084
1085 yEff = (GalFlipScreenY) ? (y + 16 - 1) ^ 255 : y + 16 - 1;
1086
1087 for (Which = 0; Which < 3; Which++) {
1088 if ((UINT8)(Base[Which * 4 + 1] + yEff) == 0xff) Shell = Which;
1089 }
1090
1091 yEff = (GalFlipScreenY) ? (y + 16) ^ 255 : y + 16;
1092
1093 for (Which = 3; Which < 8; Which++) {
1094 if ((UINT8)(Base[Which * 4 + 1] + yEff) == 0xff) {
1095 if (Which != 7) {
1096 Shell = Which;
1097 } else {
1098 Missile = Which;
1099 }
1100 }
1101 }
1102
1103 if (Shell != 0xff) GalDrawBulletsFunction(Shell, (GalOrientationFlipX) ? Base[Shell * 4 + 3] : 255 - Base[Shell * 4 + 3], y);
1104 if (Missile != 0xff) GalDrawBulletsFunction(Missile, (GalOrientationFlipX) ? Base[Missile * 4 + 3] : 255 - Base[Missile * 4 + 3], y);
1105 }
1106 }
1107
1108 // Add before BurnTransferCopy(); for the game you want to fix below & GalScreenUnflipper = 1 in game's init.
Coctail_Unflippy()1109 static void Coctail_Unflippy()
1110 {
1111 if (GalScreenUnflipper) {
1112 BurnTransferFlip(GalFlipScreenX, GalFlipScreenY);
1113 }
1114 }
1115
1116 // Render a frame
GalDraw()1117 INT32 GalDraw()
1118 {
1119 if (GalRenderFrameFunction) {
1120 GalRenderFrameFunction();
1121 } else {
1122 BurnTransferClear();
1123 GalCalcPaletteFunction();
1124
1125 if (nBurnLayer & 1 && GalRenderBackgroundFunction)
1126 GalRenderBackgroundFunction();
1127 if (nBurnLayer & 2)
1128 GalRenderBgLayer(GalVideoRam);
1129 if (nSpriteEnable & 1)
1130 GalRenderSprites(&GalSpriteRam[0x40]);
1131 if (nSpriteEnable & 2 && GalDrawBulletsFunction)
1132 GalDrawBullets(&GalSpriteRam[0x60]);
1133
1134 Coctail_Unflippy();
1135 BurnTransferCopy(GalPalette);
1136 }
1137
1138 return 0;
1139 }
1140
ZigZagRenderFrame()1141 void ZigZagRenderFrame()
1142 {
1143 BurnTransferClear();
1144 GalCalcPaletteFunction();
1145 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1146 GalRenderBgLayer(GalVideoRam);
1147 GalRenderSprites(&GalSpriteRam[0x40]);
1148 GalRenderSprites(&GalSpriteRam[0x40 + 0x20]);
1149 //if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0x60]);
1150 Coctail_Unflippy();
1151 BurnTransferCopy(GalPalette);
1152 }
1153
DkongjrmRenderFrame()1154 void DkongjrmRenderFrame()
1155 {
1156 BurnTransferClear();
1157 GalCalcPaletteFunction();
1158 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1159 GalRenderBgLayer(GalVideoRam);
1160 GalRenderSprites(&GalSpriteRam[0x40]);
1161 GalRenderSprites(&GalSpriteRam[0x60]);
1162 GalRenderSprites(&GalSpriteRam[0xc0]);
1163 GalRenderSprites(&GalSpriteRam[0xe0]);
1164 if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0x60]);
1165 Coctail_Unflippy();
1166 BurnTransferCopy(GalPalette);
1167 }
1168
DambustrRenderFrame()1169 void DambustrRenderFrame()
1170 {
1171 BurnTransferClear();
1172 GalCalcPaletteFunction();
1173 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1174 GalRenderBgLayer(GalVideoRam);
1175 GalRenderSprites(&GalSpriteRam[0x40]);
1176 if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0x60]);
1177 if (DambustrBgPriority) {
1178 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1179 memset(GalVideoRam2, 0x20, 0x400);
1180 for (INT32 i = 0; i < 32; i++) {
1181 INT32 Colour = GalSpriteRam[(i << 1) | 1] & 7;
1182 if (Colour > 3) {
1183 for (INT32 j = 0; j < 32; j++) GalVideoRam2[(32 * j) + i] = GalVideoRam[(32 * j) + i];
1184 }
1185 }
1186 GalRenderBgLayer(GalVideoRam2);
1187 }
1188 Coctail_Unflippy();
1189 BurnTransferCopy(GalPalette);
1190 }
1191
FantastcRenderFrame()1192 void FantastcRenderFrame()
1193 {
1194 BurnTransferClear();
1195 GalCalcPaletteFunction();
1196 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1197 GalRenderBgLayer(GalVideoRam);
1198 GalRenderSprites(&GalSpriteRam[0x40]);
1199 if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0xc0]);
1200 Coctail_Unflippy();
1201 BurnTransferCopy(GalPalette);
1202 }
1203
TimefgtrRenderFrame()1204 void TimefgtrRenderFrame()
1205 {
1206 BurnTransferClear();
1207 GalCalcPaletteFunction();
1208 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1209 GalRenderBgLayer(GalVideoRam);
1210 GalRenderSprites(&GalSpriteRam[0x040]); // MAME renders different sprite ram areas depending on screen-area - necessary?
1211 GalRenderSprites(&GalSpriteRam[0x140]);
1212 GalRenderSprites(&GalSpriteRam[0x240]);
1213 GalRenderSprites(&GalSpriteRam[0x340]);
1214 if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0xc0]);
1215 Coctail_Unflippy();
1216 BurnTransferCopy(GalPalette);
1217 }
1218
ScramblerRenderFrame()1219 void ScramblerRenderFrame()
1220 {
1221 BurnTransferClear();
1222 GalCalcPaletteFunction();
1223 if (GalRenderBackgroundFunction) GalRenderBackgroundFunction();
1224 GalRenderBgLayer(GalVideoRam);
1225 GalRenderSprites(&GalSpriteRam[0xc0]);
1226 if (GalDrawBulletsFunction) GalDrawBullets(&GalSpriteRam[0xe0]);
1227 Coctail_Unflippy();
1228 BurnTransferCopy(GalPalette);
1229 }
1230