Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Graphics/Legacy/DrawingLegacy.cpp
1163 views
1
2
3
#include "v3/DrawingLegacyv3.cpp"
4
#include "v4/DrawingLegacyv4.cpp"
5
6
int32 RSDK::Legacy::SCREEN_XSIZE = 424;
7
int32 RSDK::Legacy::SCREEN_CENTERX = 424 / 2;
8
9
RSDK::Legacy::DrawListEntry RSDK::Legacy::drawListEntries[LEGACY_DRAWLAYER_COUNT];
10
11
int32 RSDK::Legacy::gfxDataPosition;
12
RSDK::Legacy::GFXSurface RSDK::Legacy::gfxSurface[LEGACY_SURFACE_COUNT];
13
uint8 RSDK::Legacy::graphicData[LEGACY_GFXDATA_SIZE];
14
15
uint16 RSDK::Legacy::blendLookupTable[0x20 * 0x100];
16
uint16 RSDK::Legacy::subtractLookupTable[0x20 * 0x100];
17
uint16 RSDK::Legacy::tintLookupTable[0x10000];
18
19
void RSDK::Legacy::GenerateBlendLookupTable()
20
{
21
for (int32 y = 0; y < 0x100; y++) {
22
for (int32 x = 0; x < 0x20; x++) {
23
blendLookupTable[x + (0x20 * y)] = y * x >> 8;
24
subtractLookupTable[x + (0x20 * y)] = y * (0x1F - x) >> 8;
25
}
26
}
27
28
for (int32 i = 0; i < 0x10000; i++) {
29
int32 tintValue = ((i & 0x1F) + ((i & 0x7E0) >> 6) + ((i & 0xF800) >> 11)) / 3 + 6;
30
tintLookupTable[i] = 0x841 * MIN(tintValue, 0x1F);
31
}
32
}
33
34
void RSDK::Legacy::ClearScreen(uint8 index)
35
{
36
uint16 color = activePalette[index];
37
uint16 *framebuffer = currentScreen->frameBuffer;
38
39
int32 cnt = GFX_LINESIZE * SCREEN_YSIZE;
40
while (cnt--) {
41
*framebuffer = color;
42
++framebuffer;
43
}
44
}
45
46
void RSDK::Legacy::DrawHLineScrollLayer(int32 layerID)
47
{
48
TileLayer *layer = &stageLayouts[activeTileLayers[layerID]];
49
if (!layer->xsize || !layer->ysize)
50
return;
51
52
int32 screenwidth16 = (GFX_LINESIZE >> 4) - 1;
53
int32 layerwidth = layer->xsize;
54
int32 layerheight = layer->ysize;
55
bool32 aboveMidPoint = layerID >= tLayerMidPoint;
56
57
uint8 *lineScroll;
58
int32 *deformationData;
59
int32 *deformationDataW;
60
61
int32 yscrollOffset = 0;
62
if (activeTileLayers[layerID]) { // BG Layer
63
int32 yScroll = yScrollOffset * layer->parallaxFactor >> 8;
64
int32 fullheight = layerheight << 7;
65
layer->scrollPos += layer->scrollSpeed;
66
if (layer->scrollPos > fullheight << 16)
67
layer->scrollPos -= fullheight << 16;
68
yscrollOffset = (yScroll + (layer->scrollPos >> 16)) % fullheight;
69
layerheight = fullheight >> 7;
70
lineScroll = layer->lineScroll;
71
deformationData = &bgDeformationData2[(uint8)(yscrollOffset + layer->deformationOffset)];
72
deformationDataW = &bgDeformationData3[(uint8)(yscrollOffset + waterDrawPos + layer->deformationOffsetW)];
73
}
74
else { // FG Layer
75
lastXSize = layer->xsize;
76
yscrollOffset = yScrollOffset;
77
lineScroll = layer->lineScroll;
78
for (int32 i = 0; i < LEGACY_PARALLAX_COUNT; ++i) hParallax.linePos[i] = xScrollOffset;
79
deformationData = &bgDeformationData0[(uint8)(yscrollOffset + layer->deformationOffset)];
80
deformationDataW = &bgDeformationData1[(uint8)(yscrollOffset + waterDrawPos + layer->deformationOffsetW)];
81
}
82
83
if (layer->type == LAYER_HSCROLL) {
84
if (lastXSize != layerwidth) {
85
int32 fullLayerwidth = layerwidth << 7;
86
for (int32 i = 0; i < hParallax.entryCount; ++i) {
87
hParallax.linePos[i] = xScrollOffset * hParallax.parallaxFactor[i] >> 8;
88
if (hParallax.scrollPos[i] > fullLayerwidth << 16)
89
hParallax.scrollPos[i] -= fullLayerwidth << 16;
90
if (hParallax.scrollPos[i] < 0)
91
hParallax.scrollPos[i] += fullLayerwidth << 16;
92
hParallax.linePos[i] += hParallax.scrollPos[i] >> 16;
93
hParallax.linePos[i] %= fullLayerwidth;
94
}
95
}
96
int32 w = -1;
97
if (activeTileLayers[layerID])
98
w = layerwidth;
99
lastXSize = w;
100
}
101
102
uint16 *frameBuffer = currentScreen->frameBuffer;
103
uint8 *lineBuffer = gfxLineBuffer;
104
int32 tileYPos = yscrollOffset % (layerheight << 7);
105
if (tileYPos < 0)
106
tileYPos += layerheight << 7;
107
uint8 *scrollIndex = &lineScroll[tileYPos];
108
int32 tileY16 = tileYPos & 0xF;
109
int32 chunkY = tileYPos >> 7;
110
int32 tileY = (tileYPos & 0x7F) >> 4;
111
112
// Draw Above Water (if applicable)
113
int32 drawableLines[2] = { waterDrawPos, SCREEN_YSIZE - waterDrawPos };
114
for (int32 i = 0; i < 2; ++i) {
115
while (drawableLines[i]--) {
116
activePalette = fullPalette[*lineBuffer];
117
lineBuffer++;
118
119
int32 chunkX = hParallax.linePos[*scrollIndex];
120
if (i == 0) {
121
if (hParallax.deform[*scrollIndex])
122
chunkX += *deformationData;
123
++deformationData;
124
}
125
else {
126
if (hParallax.deform[*scrollIndex])
127
chunkX += *deformationDataW;
128
++deformationDataW;
129
}
130
++scrollIndex;
131
132
int32 fullLayerwidth = layerwidth << 7;
133
if (chunkX < 0)
134
chunkX += fullLayerwidth;
135
if (chunkX >= fullLayerwidth)
136
chunkX -= fullLayerwidth;
137
138
int32 chunkXPos = chunkX >> 7;
139
int32 tilePxXPos = chunkX & 0xF;
140
int32 tileXPxRemain = TILE_SIZE - tilePxXPos;
141
int32 chunk = (layer->tiles[(chunkX >> 7) + (chunkY << 8)] << 6) + ((chunkX & 0x7F) >> 4) + 8 * tileY;
142
int32 tileOffsetY = TILE_SIZE * tileY16;
143
int32 tileOffsetYFlipX = TILE_SIZE * tileY16 + 0xF;
144
int32 tileOffsetYFlipY = TILE_SIZE * (0xF - tileY16);
145
int32 tileOffsetYFlipXY = TILE_SIZE * (0xF - tileY16) + 0xF;
146
int32 lineRemain = GFX_LINESIZE;
147
148
uint8 *pixels = NULL;
149
int32 tilePxLineCnt = tileXPxRemain;
150
151
// Draw the first tile to the left
152
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
153
lineRemain -= tilePxLineCnt;
154
switch (tiles128x128.direction[chunk]) {
155
case FLIP_NONE:
156
pixels = &tilesetGFXData[tileOffsetY + tiles128x128.gfxDataPos[chunk] + tilePxXPos];
157
while (tilePxLineCnt--) {
158
if (*pixels > 0)
159
*frameBuffer = activePalette[*pixels];
160
++frameBuffer;
161
++pixels;
162
}
163
break;
164
165
case FLIP_X:
166
167
pixels = &tilesetGFXData[tileOffsetYFlipX + tiles128x128.gfxDataPos[chunk] - tilePxXPos];
168
while (tilePxLineCnt--) {
169
if (*pixels > 0)
170
*frameBuffer = activePalette[*pixels];
171
++frameBuffer;
172
--pixels;
173
}
174
break;
175
176
case FLIP_Y:
177
pixels = &tilesetGFXData[tileOffsetYFlipY + tiles128x128.gfxDataPos[chunk] + tilePxXPos];
178
while (tilePxLineCnt--) {
179
if (*pixels > 0)
180
*frameBuffer = activePalette[*pixels];
181
++frameBuffer;
182
++pixels;
183
}
184
break;
185
186
case FLIP_XY:
187
pixels = &tilesetGFXData[tileOffsetYFlipXY + tiles128x128.gfxDataPos[chunk] - tilePxXPos];
188
while (tilePxLineCnt--) {
189
if (*pixels > 0)
190
*frameBuffer = activePalette[*pixels];
191
++frameBuffer;
192
--pixels;
193
}
194
break;
195
196
default: break;
197
}
198
}
199
else {
200
frameBuffer += tilePxLineCnt;
201
lineRemain -= tilePxLineCnt;
202
}
203
204
// Draw the bulk of the tiles
205
int32 chunkTileX = ((chunkX & 0x7F) >> 4) + 1;
206
int32 tilesPerLine = screenwidth16;
207
while (tilesPerLine--) {
208
if (chunkTileX < 8) {
209
++chunk;
210
}
211
else {
212
if (++chunkXPos == layerwidth)
213
chunkXPos = 0;
214
215
chunkTileX = 0;
216
chunk = (layer->tiles[chunkXPos + (chunkY << 8)] << 6) + 8 * tileY;
217
}
218
lineRemain -= TILE_SIZE;
219
220
// Loop Unrolling (faster but messier code)
221
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
222
switch (tiles128x128.direction[chunk]) {
223
case FLIP_NONE:
224
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetY];
225
if (*pixels > 0)
226
*frameBuffer = activePalette[*pixels];
227
++frameBuffer;
228
++pixels;
229
230
if (*pixels > 0)
231
*frameBuffer = activePalette[*pixels];
232
++frameBuffer;
233
++pixels;
234
235
if (*pixels > 0)
236
*frameBuffer = activePalette[*pixels];
237
++frameBuffer;
238
++pixels;
239
240
if (*pixels > 0)
241
*frameBuffer = activePalette[*pixels];
242
++frameBuffer;
243
++pixels;
244
245
if (*pixels > 0)
246
*frameBuffer = activePalette[*pixels];
247
++frameBuffer;
248
++pixels;
249
250
if (*pixels > 0)
251
*frameBuffer = activePalette[*pixels];
252
++frameBuffer;
253
++pixels;
254
255
if (*pixels > 0)
256
*frameBuffer = activePalette[*pixels];
257
++frameBuffer;
258
++pixels;
259
260
if (*pixels > 0)
261
*frameBuffer = activePalette[*pixels];
262
++frameBuffer;
263
++pixels;
264
265
if (*pixels > 0)
266
*frameBuffer = activePalette[*pixels];
267
++frameBuffer;
268
++pixels;
269
270
if (*pixels > 0)
271
*frameBuffer = activePalette[*pixels];
272
++frameBuffer;
273
++pixels;
274
275
if (*pixels > 0)
276
*frameBuffer = activePalette[*pixels];
277
++frameBuffer;
278
++pixels;
279
280
if (*pixels > 0)
281
*frameBuffer = activePalette[*pixels];
282
++frameBuffer;
283
++pixels;
284
285
if (*pixels > 0)
286
*frameBuffer = activePalette[*pixels];
287
++frameBuffer;
288
++pixels;
289
290
if (*pixels > 0)
291
*frameBuffer = activePalette[*pixels];
292
++frameBuffer;
293
++pixels;
294
295
if (*pixels > 0)
296
*frameBuffer = activePalette[*pixels];
297
++frameBuffer;
298
++pixels;
299
300
if (*pixels > 0)
301
*frameBuffer = activePalette[*pixels];
302
++frameBuffer;
303
break;
304
305
case FLIP_X:
306
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipX];
307
if (*pixels > 0)
308
*frameBuffer = activePalette[*pixels];
309
++frameBuffer;
310
--pixels;
311
312
if (*pixels > 0)
313
*frameBuffer = activePalette[*pixels];
314
++frameBuffer;
315
--pixels;
316
317
if (*pixels > 0)
318
*frameBuffer = activePalette[*pixels];
319
++frameBuffer;
320
--pixels;
321
322
if (*pixels > 0)
323
*frameBuffer = activePalette[*pixels];
324
++frameBuffer;
325
--pixels;
326
327
if (*pixels > 0)
328
*frameBuffer = activePalette[*pixels];
329
++frameBuffer;
330
--pixels;
331
332
if (*pixels > 0)
333
*frameBuffer = activePalette[*pixels];
334
++frameBuffer;
335
--pixels;
336
337
if (*pixels > 0)
338
*frameBuffer = activePalette[*pixels];
339
++frameBuffer;
340
--pixels;
341
342
if (*pixels > 0)
343
*frameBuffer = activePalette[*pixels];
344
++frameBuffer;
345
--pixels;
346
347
if (*pixels > 0)
348
*frameBuffer = activePalette[*pixels];
349
++frameBuffer;
350
--pixels;
351
352
if (*pixels > 0)
353
*frameBuffer = activePalette[*pixels];
354
++frameBuffer;
355
--pixels;
356
357
if (*pixels > 0)
358
*frameBuffer = activePalette[*pixels];
359
++frameBuffer;
360
--pixels;
361
362
if (*pixels > 0)
363
*frameBuffer = activePalette[*pixels];
364
++frameBuffer;
365
--pixels;
366
367
if (*pixels > 0)
368
*frameBuffer = activePalette[*pixels];
369
++frameBuffer;
370
--pixels;
371
372
if (*pixels > 0)
373
*frameBuffer = activePalette[*pixels];
374
++frameBuffer;
375
--pixels;
376
377
if (*pixels > 0)
378
*frameBuffer = activePalette[*pixels];
379
++frameBuffer;
380
--pixels;
381
382
if (*pixels > 0)
383
*frameBuffer = activePalette[*pixels];
384
++frameBuffer;
385
break;
386
387
case FLIP_Y:
388
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipY];
389
if (*pixels > 0)
390
*frameBuffer = activePalette[*pixels];
391
++frameBuffer;
392
++pixels;
393
394
if (*pixels > 0)
395
*frameBuffer = activePalette[*pixels];
396
++frameBuffer;
397
++pixels;
398
399
if (*pixels > 0)
400
*frameBuffer = activePalette[*pixels];
401
++frameBuffer;
402
++pixels;
403
404
if (*pixels > 0)
405
*frameBuffer = activePalette[*pixels];
406
++frameBuffer;
407
++pixels;
408
409
if (*pixels > 0)
410
*frameBuffer = activePalette[*pixels];
411
++frameBuffer;
412
++pixels;
413
414
if (*pixels > 0)
415
*frameBuffer = activePalette[*pixels];
416
++frameBuffer;
417
++pixels;
418
419
if (*pixels > 0)
420
*frameBuffer = activePalette[*pixels];
421
++frameBuffer;
422
++pixels;
423
424
if (*pixels > 0)
425
*frameBuffer = activePalette[*pixels];
426
++frameBuffer;
427
++pixels;
428
429
if (*pixels > 0)
430
*frameBuffer = activePalette[*pixels];
431
++frameBuffer;
432
++pixels;
433
434
if (*pixels > 0)
435
*frameBuffer = activePalette[*pixels];
436
++frameBuffer;
437
++pixels;
438
439
if (*pixels > 0)
440
*frameBuffer = activePalette[*pixels];
441
++frameBuffer;
442
++pixels;
443
444
if (*pixels > 0)
445
*frameBuffer = activePalette[*pixels];
446
++frameBuffer;
447
++pixels;
448
449
if (*pixels > 0)
450
*frameBuffer = activePalette[*pixels];
451
++frameBuffer;
452
++pixels;
453
454
if (*pixels > 0)
455
*frameBuffer = activePalette[*pixels];
456
++frameBuffer;
457
++pixels;
458
459
if (*pixels > 0)
460
*frameBuffer = activePalette[*pixels];
461
++frameBuffer;
462
++pixels;
463
464
if (*pixels > 0)
465
*frameBuffer = activePalette[*pixels];
466
++frameBuffer;
467
break;
468
469
case FLIP_XY:
470
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipXY];
471
if (*pixels > 0)
472
*frameBuffer = activePalette[*pixels];
473
++frameBuffer;
474
--pixels;
475
476
if (*pixels > 0)
477
*frameBuffer = activePalette[*pixels];
478
++frameBuffer;
479
--pixels;
480
481
if (*pixels > 0)
482
*frameBuffer = activePalette[*pixels];
483
++frameBuffer;
484
--pixels;
485
486
if (*pixels > 0)
487
*frameBuffer = activePalette[*pixels];
488
++frameBuffer;
489
--pixels;
490
491
if (*pixels > 0)
492
*frameBuffer = activePalette[*pixels];
493
++frameBuffer;
494
--pixels;
495
496
if (*pixels > 0)
497
*frameBuffer = activePalette[*pixels];
498
++frameBuffer;
499
--pixels;
500
501
if (*pixels > 0)
502
*frameBuffer = activePalette[*pixels];
503
++frameBuffer;
504
--pixels;
505
506
if (*pixels > 0)
507
*frameBuffer = activePalette[*pixels];
508
++frameBuffer;
509
--pixels;
510
511
if (*pixels > 0)
512
*frameBuffer = activePalette[*pixels];
513
++frameBuffer;
514
--pixels;
515
516
if (*pixels > 0)
517
*frameBuffer = activePalette[*pixels];
518
++frameBuffer;
519
--pixels;
520
521
if (*pixels > 0)
522
*frameBuffer = activePalette[*pixels];
523
++frameBuffer;
524
--pixels;
525
526
if (*pixels > 0)
527
*frameBuffer = activePalette[*pixels];
528
++frameBuffer;
529
--pixels;
530
531
if (*pixels > 0)
532
*frameBuffer = activePalette[*pixels];
533
++frameBuffer;
534
--pixels;
535
536
if (*pixels > 0)
537
*frameBuffer = activePalette[*pixels];
538
++frameBuffer;
539
--pixels;
540
541
if (*pixels > 0)
542
*frameBuffer = activePalette[*pixels];
543
++frameBuffer;
544
--pixels;
545
546
if (*pixels > 0)
547
*frameBuffer = activePalette[*pixels];
548
++frameBuffer;
549
break;
550
}
551
}
552
else {
553
frameBuffer += TILE_SIZE;
554
}
555
++chunkTileX;
556
}
557
558
// Draw any remaining tiles
559
while (lineRemain > 0) {
560
if (chunkTileX++ < 8) {
561
++chunk;
562
}
563
else {
564
chunkTileX = 0;
565
if (++chunkXPos == layerwidth)
566
chunkXPos = 0;
567
568
chunk = (layer->tiles[chunkXPos + (chunkY << 8)] << 6) + 8 * tileY;
569
}
570
571
tilePxLineCnt = lineRemain >= TILE_SIZE ? TILE_SIZE : lineRemain;
572
lineRemain -= tilePxLineCnt;
573
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
574
switch (tiles128x128.direction[chunk]) {
575
case FLIP_NONE:
576
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetY];
577
while (tilePxLineCnt--) {
578
if (*pixels > 0)
579
*frameBuffer = activePalette[*pixels];
580
++frameBuffer;
581
++pixels;
582
}
583
break;
584
585
case FLIP_X:
586
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipX];
587
while (tilePxLineCnt--) {
588
if (*pixels > 0)
589
*frameBuffer = activePalette[*pixels];
590
++frameBuffer;
591
--pixels;
592
}
593
break;
594
595
case FLIP_Y:
596
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipY];
597
while (tilePxLineCnt--) {
598
if (*pixels > 0)
599
*frameBuffer = activePalette[*pixels];
600
++frameBuffer;
601
++pixels;
602
}
603
break;
604
605
case FLIP_XY:
606
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetYFlipXY];
607
while (tilePxLineCnt--) {
608
if (*pixels > 0)
609
*frameBuffer = activePalette[*pixels];
610
++frameBuffer;
611
--pixels;
612
}
613
break;
614
615
default: break;
616
}
617
}
618
else {
619
frameBuffer += tilePxLineCnt;
620
}
621
}
622
623
if (++tileY16 >= TILE_SIZE) {
624
tileY16 = 0;
625
++tileY;
626
}
627
628
if (tileY >= 8) {
629
if (++chunkY == layerheight) {
630
chunkY = 0;
631
scrollIndex -= 0x80 * layerheight;
632
}
633
tileY = 0;
634
}
635
}
636
}
637
}
638
void RSDK::Legacy::DrawVLineScrollLayer(int32 layerID)
639
{
640
TileLayer *layer = &stageLayouts[activeTileLayers[layerID]];
641
if (!layer->xsize || !layer->ysize)
642
return;
643
644
int32 layerwidth = layer->xsize;
645
int32 layerheight = layer->ysize;
646
bool aboveMidPoint = layerID >= tLayerMidPoint;
647
648
uint8 *lineScroll;
649
int32 *deformationData;
650
651
int32 xscrollOffset = 0;
652
if (activeTileLayers[layerID]) { // BG Layer
653
int32 xScroll = xScrollOffset * layer->parallaxFactor >> 8;
654
int32 fullLayerwidth = layerwidth << 7;
655
layer->scrollPos += layer->scrollSpeed;
656
if (layer->scrollPos > fullLayerwidth << 16)
657
layer->scrollPos -= fullLayerwidth << 16;
658
xscrollOffset = (xScroll + (layer->scrollPos >> 16)) % fullLayerwidth;
659
layerwidth = fullLayerwidth >> 7;
660
lineScroll = layer->lineScroll;
661
deformationData = &bgDeformationData2[(uint8)(xscrollOffset + layer->deformationOffset)];
662
}
663
else { // FG Layer
664
lastYSize = layer->ysize;
665
xscrollOffset = xScrollOffset;
666
lineScroll = layer->lineScroll;
667
vParallax.linePos[0] = yScrollOffset;
668
vParallax.deform[0] = true;
669
deformationData = &bgDeformationData0[(uint8)(xScrollOffset + layer->deformationOffset)];
670
}
671
672
if (layer->type == LAYER_VSCROLL) {
673
if (lastYSize != layerheight) {
674
int32 fullLayerheight = layerheight << 7;
675
for (int32 i = 0; i < vParallax.entryCount; ++i) {
676
vParallax.linePos[i] = yScrollOffset * vParallax.parallaxFactor[i] >> 8;
677
678
vParallax.scrollPos[i] += vParallax.scrollPos[i] << 16;
679
if (vParallax.scrollPos[i] > fullLayerheight << 16)
680
vParallax.scrollPos[i] -= fullLayerheight << 16;
681
682
vParallax.linePos[i] += vParallax.scrollPos[i] >> 16;
683
vParallax.linePos[i] %= fullLayerheight;
684
}
685
layerheight = fullLayerheight >> 7;
686
}
687
lastYSize = layerheight;
688
}
689
690
uint16 *frameBuffer = currentScreen->frameBuffer;
691
activePalette = fullPalette[gfxLineBuffer[0]];
692
int32 tileXPos = xscrollOffset % (layerheight << 7);
693
if (tileXPos < 0)
694
tileXPos += layerheight << 7;
695
uint8 *scrollIndex = &lineScroll[tileXPos];
696
int32 chunkX = tileXPos >> 7;
697
int32 tileX16 = tileXPos & 0xF;
698
int32 tileX = (tileXPos & 0x7F) >> 4;
699
700
// Draw Above Water (if applicable)
701
int32 drawableLines = SCREEN_XSIZE;
702
while (drawableLines--) {
703
int32 chunkY = vParallax.linePos[*scrollIndex];
704
if (vParallax.deform[*scrollIndex])
705
chunkY += *deformationData;
706
++deformationData;
707
++scrollIndex;
708
709
int32 fullLayerHeight = layerheight << 7;
710
if (chunkY < 0)
711
chunkY += fullLayerHeight;
712
if (chunkY >= fullLayerHeight)
713
chunkY -= fullLayerHeight;
714
715
int32 chunkYPos = chunkY >> 7;
716
int32 tileY = chunkY & 0xF;
717
int32 tileYPxRemain = TILE_SIZE - tileY;
718
int32 chunk = (layer->tiles[chunkX + (chunkY >> 7 << 8)] << 6) + tileX + 8 * ((chunkY & 0x7F) >> 4);
719
int32 tileOffsetXFlipX = 0xF - tileX16;
720
int32 tileOffsetXFlipY = tileX16 + SCREEN_YSIZE;
721
int32 tileOffsetXFlipXY = 0xFF - tileX16;
722
int32 lineRemain = SCREEN_YSIZE;
723
724
uint8 *pixels = NULL;
725
int32 tilePxLineCnt = tileYPxRemain;
726
727
// Draw the first tile to the left
728
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
729
lineRemain -= tilePxLineCnt;
730
switch (tiles128x128.direction[chunk]) {
731
case FLIP_NONE:
732
pixels = &tilesetGFXData[TILE_SIZE * tileY + tileX16 + tiles128x128.gfxDataPos[chunk]];
733
while (tilePxLineCnt--) {
734
if (*pixels > 0)
735
*frameBuffer = activePalette[*pixels];
736
frameBuffer += GFX_LINESIZE;
737
pixels += TILE_SIZE;
738
}
739
break;
740
741
case FLIP_X:
742
pixels = &tilesetGFXData[TILE_SIZE * tileY + tileOffsetXFlipX + tiles128x128.gfxDataPos[chunk]];
743
while (tilePxLineCnt--) {
744
if (*pixels > 0)
745
*frameBuffer = activePalette[*pixels];
746
frameBuffer += GFX_LINESIZE;
747
pixels += TILE_SIZE;
748
}
749
break;
750
751
case FLIP_Y:
752
pixels = &tilesetGFXData[tileOffsetXFlipY + tiles128x128.gfxDataPos[chunk] - TILE_SIZE * tileY];
753
while (tilePxLineCnt--) {
754
if (*pixels > 0)
755
*frameBuffer = activePalette[*pixels];
756
frameBuffer += GFX_LINESIZE;
757
pixels -= TILE_SIZE;
758
}
759
break;
760
761
case FLIP_XY:
762
pixels = &tilesetGFXData[tileOffsetXFlipXY + tiles128x128.gfxDataPos[chunk] - TILE_SIZE * tileY];
763
while (tilePxLineCnt--) {
764
if (*pixels > 0)
765
*frameBuffer = activePalette[*pixels];
766
frameBuffer += GFX_LINESIZE;
767
pixels -= TILE_SIZE;
768
}
769
break;
770
771
default: break;
772
}
773
}
774
else {
775
frameBuffer += GFX_LINESIZE * tileYPxRemain;
776
lineRemain -= tilePxLineCnt;
777
}
778
779
// Draw the bulk of the tiles
780
int32 chunkTileY = ((chunkY & 0x7F) >> 4) + 1;
781
int32 tilesPerLine = (SCREEN_YSIZE >> 4) - 1;
782
783
while (tilesPerLine--) {
784
if (chunkTileY < 8) {
785
chunk += 8;
786
}
787
else {
788
if (++chunkYPos == layerheight)
789
chunkYPos = 0;
790
791
chunkTileY = 0;
792
chunk = (layer->tiles[chunkX + (chunkYPos << 8)] << 6) + tileX;
793
}
794
lineRemain -= TILE_SIZE;
795
796
// Loop Unrolling (faster but messier code)
797
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
798
switch (tiles128x128.direction[chunk]) {
799
case FLIP_NONE:
800
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileX16];
801
if (*pixels > 0)
802
*frameBuffer = activePalette[*pixels];
803
frameBuffer += GFX_LINESIZE;
804
pixels += TILE_SIZE;
805
806
if (*pixels > 0)
807
*frameBuffer = activePalette[*pixels];
808
frameBuffer += GFX_LINESIZE;
809
pixels += TILE_SIZE;
810
811
if (*pixels > 0)
812
*frameBuffer = activePalette[*pixels];
813
frameBuffer += GFX_LINESIZE;
814
pixels += TILE_SIZE;
815
816
if (*pixels > 0)
817
*frameBuffer = activePalette[*pixels];
818
frameBuffer += GFX_LINESIZE;
819
pixels += TILE_SIZE;
820
821
if (*pixels > 0)
822
*frameBuffer = activePalette[*pixels];
823
frameBuffer += GFX_LINESIZE;
824
pixels += TILE_SIZE;
825
826
if (*pixels > 0)
827
*frameBuffer = activePalette[*pixels];
828
frameBuffer += GFX_LINESIZE;
829
pixels += TILE_SIZE;
830
831
if (*pixels > 0)
832
*frameBuffer = activePalette[*pixels];
833
frameBuffer += GFX_LINESIZE;
834
pixels += TILE_SIZE;
835
836
if (*pixels > 0)
837
*frameBuffer = activePalette[*pixels];
838
frameBuffer += GFX_LINESIZE;
839
pixels += TILE_SIZE;
840
841
if (*pixels > 0)
842
*frameBuffer = activePalette[*pixels];
843
frameBuffer += GFX_LINESIZE;
844
pixels += TILE_SIZE;
845
846
if (*pixels > 0)
847
*frameBuffer = activePalette[*pixels];
848
frameBuffer += GFX_LINESIZE;
849
pixels += TILE_SIZE;
850
851
if (*pixels > 0)
852
*frameBuffer = activePalette[*pixels];
853
frameBuffer += GFX_LINESIZE;
854
pixels += TILE_SIZE;
855
856
if (*pixels > 0)
857
*frameBuffer = activePalette[*pixels];
858
frameBuffer += GFX_LINESIZE;
859
pixels += TILE_SIZE;
860
861
if (*pixels > 0)
862
*frameBuffer = activePalette[*pixels];
863
frameBuffer += GFX_LINESIZE;
864
pixels += TILE_SIZE;
865
866
if (*pixels > 0)
867
*frameBuffer = activePalette[*pixels];
868
frameBuffer += GFX_LINESIZE;
869
pixels += TILE_SIZE;
870
871
if (*pixels > 0)
872
*frameBuffer = activePalette[*pixels];
873
frameBuffer += GFX_LINESIZE;
874
pixels += TILE_SIZE;
875
876
if (*pixels > 0)
877
*frameBuffer = activePalette[*pixels];
878
frameBuffer += GFX_LINESIZE;
879
break;
880
881
case FLIP_X:
882
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipX];
883
if (*pixels > 0)
884
*frameBuffer = activePalette[*pixels];
885
frameBuffer += GFX_LINESIZE;
886
pixels += TILE_SIZE;
887
888
if (*pixels > 0)
889
*frameBuffer = activePalette[*pixels];
890
frameBuffer += GFX_LINESIZE;
891
pixels += TILE_SIZE;
892
893
if (*pixels > 0)
894
*frameBuffer = activePalette[*pixels];
895
frameBuffer += GFX_LINESIZE;
896
pixels += TILE_SIZE;
897
898
if (*pixels > 0)
899
*frameBuffer = activePalette[*pixels];
900
frameBuffer += GFX_LINESIZE;
901
pixels += TILE_SIZE;
902
903
if (*pixels > 0)
904
*frameBuffer = activePalette[*pixels];
905
frameBuffer += GFX_LINESIZE;
906
pixels += TILE_SIZE;
907
908
if (*pixels > 0)
909
*frameBuffer = activePalette[*pixels];
910
frameBuffer += GFX_LINESIZE;
911
pixels += TILE_SIZE;
912
913
if (*pixels > 0)
914
*frameBuffer = activePalette[*pixels];
915
frameBuffer += GFX_LINESIZE;
916
pixels += TILE_SIZE;
917
918
if (*pixels > 0)
919
*frameBuffer = activePalette[*pixels];
920
frameBuffer += GFX_LINESIZE;
921
pixels += TILE_SIZE;
922
923
if (*pixels > 0)
924
*frameBuffer = activePalette[*pixels];
925
frameBuffer += GFX_LINESIZE;
926
pixels += TILE_SIZE;
927
928
if (*pixels > 0)
929
*frameBuffer = activePalette[*pixels];
930
frameBuffer += GFX_LINESIZE;
931
pixels += TILE_SIZE;
932
933
if (*pixels > 0)
934
*frameBuffer = activePalette[*pixels];
935
frameBuffer += GFX_LINESIZE;
936
pixels += TILE_SIZE;
937
938
if (*pixels > 0)
939
*frameBuffer = activePalette[*pixels];
940
frameBuffer += GFX_LINESIZE;
941
pixels += TILE_SIZE;
942
943
if (*pixels > 0)
944
*frameBuffer = activePalette[*pixels];
945
frameBuffer += GFX_LINESIZE;
946
pixels += TILE_SIZE;
947
948
if (*pixels > 0)
949
*frameBuffer = activePalette[*pixels];
950
frameBuffer += GFX_LINESIZE;
951
pixels += TILE_SIZE;
952
953
if (*pixels > 0)
954
*frameBuffer = activePalette[*pixels];
955
frameBuffer += GFX_LINESIZE;
956
pixels += TILE_SIZE;
957
958
if (*pixels > 0)
959
*frameBuffer = activePalette[*pixels];
960
frameBuffer += GFX_LINESIZE;
961
break;
962
963
case FLIP_Y:
964
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipY];
965
if (*pixels > 0)
966
*frameBuffer = activePalette[*pixels];
967
frameBuffer += GFX_LINESIZE;
968
pixels -= TILE_SIZE;
969
970
if (*pixels > 0)
971
*frameBuffer = activePalette[*pixels];
972
frameBuffer += GFX_LINESIZE;
973
pixels -= TILE_SIZE;
974
975
if (*pixels > 0)
976
*frameBuffer = activePalette[*pixels];
977
frameBuffer += GFX_LINESIZE;
978
pixels -= TILE_SIZE;
979
980
if (*pixels > 0)
981
*frameBuffer = activePalette[*pixels];
982
frameBuffer += GFX_LINESIZE;
983
pixels -= TILE_SIZE;
984
985
if (*pixels > 0)
986
*frameBuffer = activePalette[*pixels];
987
frameBuffer += GFX_LINESIZE;
988
pixels -= TILE_SIZE;
989
990
if (*pixels > 0)
991
*frameBuffer = activePalette[*pixels];
992
frameBuffer += GFX_LINESIZE;
993
pixels -= TILE_SIZE;
994
995
if (*pixels > 0)
996
*frameBuffer = activePalette[*pixels];
997
frameBuffer += GFX_LINESIZE;
998
pixels -= TILE_SIZE;
999
1000
if (*pixels > 0)
1001
*frameBuffer = activePalette[*pixels];
1002
frameBuffer += GFX_LINESIZE;
1003
pixels -= TILE_SIZE;
1004
1005
if (*pixels > 0)
1006
*frameBuffer = activePalette[*pixels];
1007
frameBuffer += GFX_LINESIZE;
1008
pixels -= TILE_SIZE;
1009
1010
if (*pixels > 0)
1011
*frameBuffer = activePalette[*pixels];
1012
frameBuffer += GFX_LINESIZE;
1013
pixels -= TILE_SIZE;
1014
1015
if (*pixels > 0)
1016
*frameBuffer = activePalette[*pixels];
1017
frameBuffer += GFX_LINESIZE;
1018
pixels -= TILE_SIZE;
1019
1020
if (*pixels > 0)
1021
*frameBuffer = activePalette[*pixels];
1022
frameBuffer += GFX_LINESIZE;
1023
pixels -= TILE_SIZE;
1024
1025
if (*pixels > 0)
1026
*frameBuffer = activePalette[*pixels];
1027
frameBuffer += GFX_LINESIZE;
1028
pixels -= TILE_SIZE;
1029
1030
if (*pixels > 0)
1031
*frameBuffer = activePalette[*pixels];
1032
frameBuffer += GFX_LINESIZE;
1033
pixels -= TILE_SIZE;
1034
1035
if (*pixels > 0)
1036
*frameBuffer = activePalette[*pixels];
1037
frameBuffer += GFX_LINESIZE;
1038
pixels -= TILE_SIZE;
1039
1040
if (*pixels > 0)
1041
*frameBuffer = activePalette[*pixels];
1042
frameBuffer += GFX_LINESIZE;
1043
break;
1044
1045
case FLIP_XY:
1046
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipXY];
1047
if (*pixels > 0)
1048
*frameBuffer = activePalette[*pixels];
1049
frameBuffer += GFX_LINESIZE;
1050
pixels -= TILE_SIZE;
1051
1052
if (*pixels > 0)
1053
*frameBuffer = activePalette[*pixels];
1054
frameBuffer += GFX_LINESIZE;
1055
pixels -= TILE_SIZE;
1056
1057
if (*pixels > 0)
1058
*frameBuffer = activePalette[*pixels];
1059
frameBuffer += GFX_LINESIZE;
1060
pixels -= TILE_SIZE;
1061
1062
if (*pixels > 0)
1063
*frameBuffer = activePalette[*pixels];
1064
frameBuffer += GFX_LINESIZE;
1065
pixels -= TILE_SIZE;
1066
1067
if (*pixels > 0)
1068
*frameBuffer = activePalette[*pixels];
1069
frameBuffer += GFX_LINESIZE;
1070
pixels -= TILE_SIZE;
1071
1072
if (*pixels > 0)
1073
*frameBuffer = activePalette[*pixels];
1074
frameBuffer += GFX_LINESIZE;
1075
pixels -= TILE_SIZE;
1076
1077
if (*pixels > 0)
1078
*frameBuffer = activePalette[*pixels];
1079
frameBuffer += GFX_LINESIZE;
1080
pixels -= TILE_SIZE;
1081
1082
if (*pixels > 0)
1083
*frameBuffer = activePalette[*pixels];
1084
frameBuffer += GFX_LINESIZE;
1085
pixels -= TILE_SIZE;
1086
1087
if (*pixels > 0)
1088
*frameBuffer = activePalette[*pixels];
1089
frameBuffer += GFX_LINESIZE;
1090
pixels -= TILE_SIZE;
1091
1092
if (*pixels > 0)
1093
*frameBuffer = activePalette[*pixels];
1094
frameBuffer += GFX_LINESIZE;
1095
pixels -= TILE_SIZE;
1096
1097
if (*pixels > 0)
1098
*frameBuffer = activePalette[*pixels];
1099
frameBuffer += GFX_LINESIZE;
1100
pixels -= TILE_SIZE;
1101
1102
if (*pixels > 0)
1103
*frameBuffer = activePalette[*pixels];
1104
frameBuffer += GFX_LINESIZE;
1105
pixels -= TILE_SIZE;
1106
1107
if (*pixels > 0)
1108
*frameBuffer = activePalette[*pixels];
1109
frameBuffer += GFX_LINESIZE;
1110
pixels -= TILE_SIZE;
1111
1112
if (*pixels > 0)
1113
*frameBuffer = activePalette[*pixels];
1114
frameBuffer += GFX_LINESIZE;
1115
pixels -= TILE_SIZE;
1116
1117
if (*pixels > 0)
1118
*frameBuffer = activePalette[*pixels];
1119
frameBuffer += GFX_LINESIZE;
1120
pixels -= TILE_SIZE;
1121
1122
if (*pixels > 0)
1123
*frameBuffer = activePalette[*pixels];
1124
frameBuffer += GFX_LINESIZE;
1125
break;
1126
}
1127
}
1128
else {
1129
frameBuffer += GFX_LINESIZE * TILE_SIZE;
1130
}
1131
++chunkTileY;
1132
}
1133
1134
// Draw any remaining tiles
1135
while (lineRemain > 0) {
1136
if (chunkTileY < 8) {
1137
chunk += 8;
1138
}
1139
else {
1140
if (++chunkYPos == layerheight)
1141
chunkYPos = 0;
1142
1143
chunkTileY = 0;
1144
chunk = (layer->tiles[chunkX + (chunkYPos << 8)] << 6) + tileX;
1145
}
1146
1147
tilePxLineCnt = lineRemain >= TILE_SIZE ? TILE_SIZE : lineRemain;
1148
lineRemain -= tilePxLineCnt;
1149
1150
if (tiles128x128.visualPlane[chunk] == (uint8)aboveMidPoint) {
1151
switch (tiles128x128.direction[chunk]) {
1152
case FLIP_NONE:
1153
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileX16];
1154
while (tilePxLineCnt--) {
1155
if (*pixels > 0)
1156
*frameBuffer = activePalette[*pixels];
1157
frameBuffer += GFX_LINESIZE;
1158
pixels += TILE_SIZE;
1159
}
1160
break;
1161
1162
case FLIP_X:
1163
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipX];
1164
while (tilePxLineCnt--) {
1165
if (*pixels > 0)
1166
*frameBuffer = activePalette[*pixels];
1167
frameBuffer += GFX_LINESIZE;
1168
pixels += TILE_SIZE;
1169
}
1170
break;
1171
1172
case FLIP_Y:
1173
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipY];
1174
while (tilePxLineCnt--) {
1175
if (*pixels > 0)
1176
*frameBuffer = activePalette[*pixels];
1177
frameBuffer += GFX_LINESIZE;
1178
pixels -= TILE_SIZE;
1179
}
1180
break;
1181
1182
case FLIP_XY:
1183
pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk] + tileOffsetXFlipXY];
1184
while (tilePxLineCnt--) {
1185
if (*pixels > 0)
1186
*frameBuffer = activePalette[*pixels];
1187
frameBuffer += GFX_LINESIZE;
1188
pixels -= TILE_SIZE;
1189
}
1190
break;
1191
1192
default: break;
1193
}
1194
}
1195
else {
1196
frameBuffer += GFX_LINESIZE * tilePxLineCnt;
1197
}
1198
chunkTileY++;
1199
}
1200
1201
if (++tileX16 >= TILE_SIZE) {
1202
tileX16 = 0;
1203
++tileX;
1204
}
1205
1206
if (tileX >= 8) {
1207
if (++chunkX == layerwidth) {
1208
chunkX = 0;
1209
scrollIndex -= 0x80 * layerwidth;
1210
}
1211
tileX = 0;
1212
}
1213
1214
frameBuffer -= GFX_FBUFFERMINUSONE;
1215
}
1216
}
1217
void RSDK::Legacy::Draw3DFloorLayer(int32 layerID)
1218
{
1219
TileLayer *layer = &stageLayouts[activeTileLayers[layerID]];
1220
if (!layer->xsize || !layer->ysize)
1221
return;
1222
1223
int32 layerWidth = layer->xsize << 7;
1224
int32 layerHeight = layer->ysize << 7;
1225
int32 layerYPos = layer->ypos;
1226
int32 layerZPos = layer->zpos;
1227
int32 sinValue = sinM7LookupTable[layer->angle];
1228
int32 cosValue = cosM7LookupTable[layer->angle];
1229
uint8 *lineBuffer = &gfxLineBuffer[(SCREEN_YSIZE / 2) + 12];
1230
uint16 *frameBuffer = &currentScreen->frameBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
1231
int32 layerXPos = layer->xpos >> 4;
1232
int32 ZBuffer = layerZPos >> 4;
1233
1234
for (int32 i = 4; i < 112; ++i) {
1235
if (!(i & 1)) {
1236
activePalette = fullPalette[*lineBuffer];
1237
lineBuffer++;
1238
}
1239
int32 XBuffer = layerYPos / (i << 9) * -cosValue >> 8;
1240
int32 YBuffer = sinValue * (layerYPos / (i << 9)) >> 8;
1241
int32 XPos = layerXPos + (3 * sinValue * (layerYPos / (i << 9)) >> 2) - XBuffer * SCREEN_CENTERX;
1242
int32 YPos = ZBuffer + (3 * cosValue * (layerYPos / (i << 9)) >> 2) - YBuffer * SCREEN_CENTERX;
1243
int32 lineBuffer = 0;
1244
while (lineBuffer < GFX_LINESIZE) {
1245
int32 tileX = XPos >> 12;
1246
int32 tileY = YPos >> 12;
1247
if (tileX > -1 && tileX < layerWidth && tileY > -1 && tileY < layerHeight) {
1248
int32 chunk = tile3DFloorBuffer[(YPos >> 16 << 8) + (XPos >> 16)];
1249
uint8 *pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk]];
1250
switch (tiles128x128.direction[chunk]) {
1251
case FLIP_NONE: pixels += TILE_SIZE * (tileY & 0xF) + (tileX & 0xF); break;
1252
case FLIP_X: pixels += TILE_SIZE * (tileY & 0xF) + 15 - (tileX & 0xF); break;
1253
case FLIP_Y: pixels += (tileX & 0xF) + SCREEN_YSIZE - TILE_SIZE * (tileY & 0xF); break;
1254
case FLIP_XY: pixels += 15 - (tileX & 0xF) + SCREEN_YSIZE - TILE_SIZE * (tileY & 0xF); break;
1255
default: break;
1256
}
1257
1258
if (*pixels > 0)
1259
*frameBuffer = activePalette[*pixels];
1260
}
1261
++frameBuffer;
1262
++lineBuffer;
1263
1264
XPos += XBuffer;
1265
YPos += YBuffer;
1266
}
1267
}
1268
}
1269
void RSDK::Legacy::Draw3DSkyLayer(int32 layerID)
1270
{
1271
TileLayer *layer = &stageLayouts[activeTileLayers[layerID]];
1272
if (!layer->xsize || !layer->ysize)
1273
return;
1274
1275
int32 layerWidth = layer->xsize << 7;
1276
int32 layerHeight = layer->ysize << 7;
1277
int32 layerYPos = layer->ypos;
1278
int32 sinValue = sinM7LookupTable[layer->angle & 0x1FF];
1279
int32 cosValue = cosM7LookupTable[layer->angle & 0x1FF];
1280
uint16 *frameBuffer = &currentScreen->frameBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
1281
uint8 *lineBuffer = &gfxLineBuffer[((SCREEN_YSIZE / 2) + 12)];
1282
int32 layerXPos = layer->xpos >> 4;
1283
int32 layerZPos = layer->zpos >> 4;
1284
for (int32 i = TILE_SIZE / 2; i < SCREEN_YSIZE - TILE_SIZE; ++i) {
1285
if (!(i & 1)) {
1286
activePalette = fullPalette[*lineBuffer];
1287
lineBuffer++;
1288
}
1289
1290
int32 xBuffer = layerYPos / (i << 8) * -cosValue >> 9;
1291
int32 yBuffer = sinValue * (layerYPos / (i << 8)) >> 9;
1292
int32 XPos = layerXPos + (3 * sinValue * (layerYPos / (i << 8)) >> 2) - xBuffer * GFX_LINESIZE;
1293
int32 YPos = layerZPos + (3 * cosValue * (layerYPos / (i << 8)) >> 2) - yBuffer * GFX_LINESIZE;
1294
int32 lineBuffer = 0;
1295
1296
while (lineBuffer < GFX_LINESIZE * 2) {
1297
int32 tileX = XPos >> 12;
1298
int32 tileY = YPos >> 12;
1299
if (tileX > -1 && tileX < layerWidth && tileY > -1 && tileY < layerHeight) {
1300
int32 chunk = tile3DFloorBuffer[(YPos >> 16 << 8) + (XPos >> 16)];
1301
uint8 *pixels = &tilesetGFXData[tiles128x128.gfxDataPos[chunk]];
1302
1303
switch (tiles128x128.direction[chunk]) {
1304
case FLIP_NONE: pixels += TILE_SIZE * (tileY & 0xF) + (tileX & 0xF); break;
1305
case FLIP_X: pixels += TILE_SIZE * (tileY & 0xF) + 0xF - (tileX & 0xF); break;
1306
case FLIP_Y: pixels += (tileX & 0xF) + SCREEN_YSIZE - TILE_SIZE * (tileY & 0xF); break;
1307
case FLIP_XY: pixels += 0xF - (tileX & 0xF) + SCREEN_YSIZE - TILE_SIZE * (tileY & 0xF); break;
1308
default: break;
1309
}
1310
1311
if (*pixels > 0)
1312
*frameBuffer = activePalette[*pixels];
1313
}
1314
1315
if (lineBuffer & 1)
1316
++frameBuffer;
1317
1318
lineBuffer++;
1319
XPos += xBuffer;
1320
YPos += yBuffer;
1321
}
1322
1323
if (!(i & 1))
1324
frameBuffer -= GFX_LINESIZE;
1325
}
1326
}
1327
1328
void RSDK::Legacy::DrawRectangle(int32 XPos, int32 YPos, int32 width, int32 height, int32 R, int32 G, int32 B, int32 A)
1329
{
1330
if (A > 0xFF)
1331
A = 0xFF;
1332
1333
if (width + XPos > GFX_LINESIZE)
1334
width = GFX_LINESIZE - XPos;
1335
if (XPos < 0) {
1336
width += XPos;
1337
XPos = 0;
1338
}
1339
1340
if (height + YPos > SCREEN_YSIZE)
1341
height = SCREEN_YSIZE - YPos;
1342
if (YPos < 0) {
1343
height += YPos;
1344
YPos = 0;
1345
}
1346
1347
if (width <= 0 || height <= 0 || A <= 0)
1348
return;
1349
1350
int32 pitch = GFX_LINESIZE - width;
1351
uint16 *frameBufferPtr = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1352
uint16 clr = PACK_RGB888(R, G, B);
1353
1354
if (A == 0xFF) {
1355
int32 h = height;
1356
while (h--) {
1357
int32 w = width;
1358
while (w--) {
1359
*frameBufferPtr = clr;
1360
++frameBufferPtr;
1361
}
1362
frameBufferPtr += pitch;
1363
}
1364
}
1365
else {
1366
uint16 *fbufferBlend = &blendLookupTable[0x20 * (0xFF - A)];
1367
uint16 *pixelBlend = &blendLookupTable[0x20 * A];
1368
1369
int32 h = height;
1370
while (h--) {
1371
int32 w = width;
1372
while (w--) {
1373
int32 R = (fbufferBlend[(*frameBufferPtr & 0xF800) >> 11] + pixelBlend[(clr & 0xF800) >> 11]) << 11;
1374
int32 G = (fbufferBlend[(*frameBufferPtr & 0x7E0) >> 6] + pixelBlend[(clr & 0x7E0) >> 6]) << 6;
1375
int32 B = fbufferBlend[*frameBufferPtr & 0x1F] + pixelBlend[clr & 0x1F];
1376
1377
*frameBufferPtr = R | G | B;
1378
++frameBufferPtr;
1379
}
1380
frameBufferPtr += pitch;
1381
}
1382
}
1383
}
1384
1385
void RSDK::Legacy::DrawTintRectangle(int32 XPos, int32 YPos, int32 width, int32 height)
1386
{
1387
if (width + XPos > GFX_LINESIZE)
1388
width = GFX_LINESIZE - XPos;
1389
if (XPos < 0) {
1390
width += XPos;
1391
XPos = 0;
1392
}
1393
1394
if (height + YPos > SCREEN_YSIZE)
1395
height = SCREEN_YSIZE - YPos;
1396
if (YPos < 0) {
1397
height += YPos;
1398
YPos = 0;
1399
}
1400
if (width < 0 || height < 0)
1401
return;
1402
int32 yOffset = GFX_LINESIZE - width;
1403
for (uint16 *frameBufferPtr = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];; frameBufferPtr += yOffset) {
1404
height--;
1405
if (height < 0)
1406
break;
1407
int32 w = width;
1408
while (w--) {
1409
*frameBufferPtr = tintLookupTable[*frameBufferPtr];
1410
++frameBufferPtr;
1411
}
1412
}
1413
}
1414
void RSDK::Legacy::DrawScaledTintMask(int32 direction, int32 XPos, int32 YPos, int32 pivotX, int32 pivotY, int32 scaleX, int32 scaleY, int32 width,
1415
int32 height, int32 sprX, int32 sprY, int32 sheetID)
1416
{
1417
int32 roundedYPos = 0;
1418
int32 roundedXPos = 0;
1419
int32 truescaleX = 4 * scaleX;
1420
int32 truescaleY = 4 * scaleY;
1421
int32 widthM1 = width - 1;
1422
int32 trueXPos = XPos - (truescaleX * pivotX >> 11);
1423
int32 trueYPos = YPos - (truescaleY * pivotY >> 11);
1424
width = truescaleX * width >> 11;
1425
height = truescaleY * height >> 11;
1426
int32 finalscaleX = (int32)(float)((float)(2048.0 / (float)truescaleX) * 2048.0);
1427
int32 finalscaleY = (int32)(float)((float)(2048.0 / (float)truescaleY) * 2048.0);
1428
1429
if (width + trueXPos > GFX_LINESIZE) {
1430
width = GFX_LINESIZE - trueXPos;
1431
}
1432
1433
if (direction) {
1434
if (trueXPos < 0) {
1435
widthM1 -= trueXPos * -finalscaleX >> 11;
1436
roundedXPos = (uint16)trueXPos * -(int16)finalscaleX & 0x7FF;
1437
width += trueXPos;
1438
trueXPos = 0;
1439
}
1440
}
1441
else if (trueXPos < 0) {
1442
sprX += trueXPos * -finalscaleX >> 11;
1443
roundedXPos = (uint16)trueXPos * -(int16)finalscaleX & 0x7FF;
1444
width += trueXPos;
1445
trueXPos = 0;
1446
}
1447
1448
if (height + trueYPos > SCREEN_YSIZE) {
1449
height = SCREEN_YSIZE - trueYPos;
1450
}
1451
if (trueYPos < 0) {
1452
sprY += trueYPos * -finalscaleY >> 11;
1453
roundedYPos = (uint16)trueYPos * -(int16)finalscaleY & 0x7FF;
1454
height += trueYPos;
1455
trueYPos = 0;
1456
}
1457
1458
if (width <= 0 || height <= 0)
1459
return;
1460
1461
GFXSurface *surface = &gfxSurface[sheetID];
1462
int32 pitch = GFX_LINESIZE - width;
1463
int32 gfxwidth = surface->width;
1464
// uint8 *lineBuffer = &gfxLineBuffer[trueYPos];
1465
uint8 *gfxData = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
1466
uint16 *frameBufferPtr = &currentScreen->frameBuffer[trueXPos + GFX_LINESIZE * trueYPos];
1467
if (direction == FLIP_X) {
1468
uint8 *gfxDataPtr = &gfxData[widthM1];
1469
int32 gfxPitch = 0;
1470
while (height--) {
1471
int32 roundXPos = roundedXPos;
1472
int32 w = width;
1473
while (w--) {
1474
if (*gfxDataPtr > 0)
1475
*frameBufferPtr = tintLookupTable[*frameBufferPtr];
1476
int32 offsetX = finalscaleX + roundXPos;
1477
gfxDataPtr -= offsetX >> 11;
1478
gfxPitch += offsetX >> 11;
1479
roundXPos = offsetX & 0x7FF;
1480
++frameBufferPtr;
1481
}
1482
frameBufferPtr += pitch;
1483
int32 offsetY = finalscaleY + roundedYPos;
1484
gfxDataPtr += gfxPitch + (offsetY >> 11) * gfxwidth;
1485
roundedYPos = offsetY & 0x7FF;
1486
gfxPitch = 0;
1487
}
1488
}
1489
else {
1490
int32 gfxPitch = 0;
1491
int32 h = height;
1492
while (h--) {
1493
int32 roundXPos = roundedXPos;
1494
int32 w = width;
1495
while (w--) {
1496
if (*gfxData > 0)
1497
*frameBufferPtr = tintLookupTable[*frameBufferPtr];
1498
int32 offsetX = finalscaleX + roundXPos;
1499
gfxData += offsetX >> 11;
1500
gfxPitch += offsetX >> 11;
1501
roundXPos = offsetX & 0x7FF;
1502
++frameBufferPtr;
1503
}
1504
frameBufferPtr += pitch;
1505
int32 offsetY = finalscaleY + roundedYPos;
1506
gfxData += (offsetY >> 11) * gfxwidth - gfxPitch;
1507
roundedYPos = offsetY & 0x7FF;
1508
gfxPitch = 0;
1509
}
1510
}
1511
}
1512
1513
void RSDK::Legacy::DrawSprite(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 sheetID)
1514
{
1515
if (width + XPos > GFX_LINESIZE)
1516
width = GFX_LINESIZE - XPos;
1517
if (XPos < 0) {
1518
sprX -= XPos;
1519
width += XPos;
1520
XPos = 0;
1521
}
1522
if (height + YPos > SCREEN_YSIZE)
1523
height = SCREEN_YSIZE - YPos;
1524
if (YPos < 0) {
1525
sprY -= YPos;
1526
height += YPos;
1527
YPos = 0;
1528
}
1529
if (width <= 0 || height <= 0)
1530
return;
1531
1532
GFXSurface *surface = &gfxSurface[sheetID];
1533
int32 pitch = GFX_LINESIZE - width;
1534
int32 gfxPitch = surface->width - width;
1535
uint8 *lineBuffer = &gfxLineBuffer[YPos];
1536
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
1537
uint16 *frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1538
1539
while (height--) {
1540
activePalette = fullPalette[*lineBuffer];
1541
lineBuffer++;
1542
1543
int32 w = width;
1544
while (w--) {
1545
if (*pixels > 0)
1546
*frameBuffer = activePalette[*pixels];
1547
++pixels;
1548
++frameBuffer;
1549
}
1550
1551
frameBuffer += pitch;
1552
pixels += gfxPitch;
1553
}
1554
}
1555
1556
void RSDK::Legacy::DrawSpriteFlipped(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 direction, int32 sheetID)
1557
{
1558
int32 widthFlip = width;
1559
int32 heightFlip = height;
1560
1561
if (width + XPos > GFX_LINESIZE) {
1562
width = GFX_LINESIZE - XPos;
1563
}
1564
if (XPos < 0) {
1565
sprX -= XPos;
1566
width += XPos;
1567
widthFlip += XPos + XPos;
1568
XPos = 0;
1569
}
1570
if (height + YPos > SCREEN_YSIZE) {
1571
height = SCREEN_YSIZE - YPos;
1572
}
1573
if (YPos < 0) {
1574
sprY -= YPos;
1575
height += YPos;
1576
heightFlip += YPos + YPos;
1577
YPos = 0;
1578
}
1579
if (width <= 0 || height <= 0)
1580
return;
1581
1582
GFXSurface *surface = &gfxSurface[sheetID];
1583
int32 pitch;
1584
int32 gfxPitch;
1585
uint8 *lineBuffer;
1586
uint8 *pixels;
1587
uint16 *frameBuffer;
1588
switch (direction) {
1589
case FLIP_NONE:
1590
pitch = GFX_LINESIZE - width;
1591
gfxPitch = surface->width - width;
1592
lineBuffer = &gfxLineBuffer[YPos];
1593
pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
1594
frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1595
1596
while (height--) {
1597
activePalette = fullPalette[*lineBuffer];
1598
lineBuffer++;
1599
1600
int32 w = width;
1601
while (w--) {
1602
if (*pixels > 0)
1603
*frameBuffer = activePalette[*pixels];
1604
++pixels;
1605
++frameBuffer;
1606
}
1607
1608
frameBuffer += pitch;
1609
pixels += gfxPitch;
1610
}
1611
break;
1612
1613
case FLIP_X:
1614
pitch = GFX_LINESIZE - width;
1615
gfxPitch = width + surface->width;
1616
lineBuffer = &gfxLineBuffer[YPos];
1617
pixels = &graphicData[widthFlip - 1 + sprX + surface->width * sprY + surface->dataPosition];
1618
frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1619
while (height--) {
1620
activePalette = fullPalette[*lineBuffer];
1621
1622
lineBuffer++;
1623
int32 w = width;
1624
while (w--) {
1625
if (*pixels > 0)
1626
*frameBuffer = activePalette[*pixels];
1627
--pixels;
1628
++frameBuffer;
1629
}
1630
1631
frameBuffer += pitch;
1632
pixels += gfxPitch;
1633
}
1634
break;
1635
1636
case FLIP_Y:
1637
pitch = GFX_LINESIZE - width;
1638
gfxPitch = width + surface->width;
1639
lineBuffer = &gfxLineBuffer[YPos];
1640
pixels = &graphicData[sprX + surface->width * (sprY + heightFlip - 1) + surface->dataPosition];
1641
frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1642
while (height--) {
1643
activePalette = fullPalette[*lineBuffer];
1644
lineBuffer++;
1645
1646
int32 w = width;
1647
while (w--) {
1648
if (*pixels > 0)
1649
*frameBuffer = activePalette[*pixels];
1650
++pixels;
1651
++frameBuffer;
1652
}
1653
1654
frameBuffer += pitch;
1655
pixels -= gfxPitch;
1656
}
1657
break;
1658
1659
case FLIP_XY:
1660
pitch = GFX_LINESIZE - width;
1661
gfxPitch = surface->width - width;
1662
lineBuffer = &gfxLineBuffer[YPos];
1663
pixels = &graphicData[widthFlip - 1 + sprX + surface->width * (sprY + heightFlip - 1) + surface->dataPosition];
1664
frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
1665
while (height--) {
1666
activePalette = fullPalette[*lineBuffer];
1667
lineBuffer++;
1668
1669
int32 w = width;
1670
while (w--) {
1671
if (*pixels > 0)
1672
*frameBuffer = activePalette[*pixels];
1673
--pixels;
1674
++frameBuffer;
1675
}
1676
1677
frameBuffer += pitch;
1678
pixels -= gfxPitch;
1679
}
1680
break;
1681
1682
default: break;
1683
}
1684
}
1685
void RSDK::Legacy::DrawSpriteScaled(int32 direction, int32 XPos, int32 YPos, int32 pivotX, int32 pivotY, int32 scaleX, int32 scaleY, int32 width,
1686
int32 height, int32 sprX, int32 sprY, int32 sheetID)
1687
{
1688
int32 roundedYPos = 0;
1689
int32 roundedXPos = 0;
1690
int32 truescaleX = 4 * scaleX;
1691
int32 truescaleY = 4 * scaleY;
1692
int32 widthM1 = width - 1;
1693
int32 trueXPos = XPos - (truescaleX * pivotX >> 11);
1694
int32 trueYPos = YPos - (truescaleY * pivotY >> 11);
1695
width = truescaleX * width >> 11;
1696
height = truescaleY * height >> 11;
1697
int32 finalscaleX = (int32)(float)((float)(2048.0 / (float)truescaleX) * 2048.0);
1698
int32 finalscaleY = (int32)(float)((float)(2048.0 / (float)truescaleY) * 2048.0);
1699
if (width + trueXPos > GFX_LINESIZE) {
1700
width = GFX_LINESIZE - trueXPos;
1701
}
1702
1703
if (direction) {
1704
if (trueXPos < 0) {
1705
widthM1 -= trueXPos * -finalscaleX >> 11;
1706
roundedXPos = (uint16)trueXPos * -(int16)finalscaleX & 0x7FF;
1707
width += trueXPos;
1708
trueXPos = 0;
1709
}
1710
}
1711
else if (trueXPos < 0) {
1712
sprX += trueXPos * -finalscaleX >> 11;
1713
roundedXPos = (uint16)trueXPos * -(int16)finalscaleX & 0x7FF;
1714
width += trueXPos;
1715
trueXPos = 0;
1716
}
1717
1718
if (height + trueYPos > SCREEN_YSIZE) {
1719
height = SCREEN_YSIZE - trueYPos;
1720
}
1721
if (trueYPos < 0) {
1722
sprY += trueYPos * -finalscaleY >> 11;
1723
roundedYPos = (uint16)trueYPos * -(int16)finalscaleY & 0x7FF;
1724
height += trueYPos;
1725
trueYPos = 0;
1726
}
1727
1728
if (width <= 0 || height <= 0)
1729
return;
1730
1731
GFXSurface *surface = &gfxSurface[sheetID];
1732
int32 pitch = GFX_LINESIZE - width;
1733
int32 gfxwidth = surface->width;
1734
uint8 *lineBuffer = &gfxLineBuffer[trueYPos];
1735
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
1736
uint16 *frameBuffer = &currentScreen->frameBuffer[trueXPos + GFX_LINESIZE * trueYPos];
1737
1738
if (direction == FLIP_X) {
1739
uint8 *pixelsPtr = &pixels[widthM1];
1740
int32 gfxPitch = 0;
1741
1742
while (height--) {
1743
activePalette = fullPalette[*lineBuffer];
1744
lineBuffer++;
1745
1746
int32 roundXPos = roundedXPos;
1747
int32 w = width;
1748
while (w--) {
1749
if (*pixelsPtr > 0)
1750
*frameBuffer = activePalette[*pixelsPtr];
1751
int32 offsetX = finalscaleX + roundXPos;
1752
pixelsPtr -= offsetX >> 11;
1753
gfxPitch += offsetX >> 11;
1754
roundXPos = offsetX & 0x7FF;
1755
++frameBuffer;
1756
}
1757
1758
frameBuffer += pitch;
1759
int32 offsetY = finalscaleY + roundedYPos;
1760
pixelsPtr += gfxPitch + (offsetY >> 11) * gfxwidth;
1761
roundedYPos = offsetY & 0x7FF;
1762
gfxPitch = 0;
1763
}
1764
}
1765
else {
1766
int32 gfxPitch = 0;
1767
int32 h = height;
1768
while (h--) {
1769
activePalette = fullPalette[*lineBuffer];
1770
lineBuffer++;
1771
1772
int32 roundXPos = roundedXPos;
1773
int32 w = width;
1774
while (w--) {
1775
if (*pixels > 0)
1776
*frameBuffer = activePalette[*pixels];
1777
int32 offsetX = finalscaleX + roundXPos;
1778
pixels += offsetX >> 11;
1779
gfxPitch += offsetX >> 11;
1780
roundXPos = offsetX & 0x7FF;
1781
++frameBuffer;
1782
}
1783
1784
frameBuffer += pitch;
1785
int32 offsetY = finalscaleY + roundedYPos;
1786
pixels += (offsetY >> 11) * gfxwidth - gfxPitch;
1787
roundedYPos = offsetY & 0x7FF;
1788
gfxPitch = 0;
1789
}
1790
}
1791
}
1792
void RSDK::Legacy::DrawSpriteRotated(int32 direction, int32 XPos, int32 YPos, int32 pivotX, int32 pivotY, int32 sprX, int32 sprY, int32 width,
1793
int32 height, int32 rotation, int32 sheetID)
1794
{
1795
int32 sprXPos = (pivotX + sprX) << 9;
1796
int32 sprYPos = (pivotY + sprY) << 9;
1797
int32 fullwidth = width + sprX;
1798
int32 fullheight = height + sprY;
1799
int32 angle = rotation & 0x1FF;
1800
if (angle < 0)
1801
angle += 0x200;
1802
if (angle)
1803
angle = 0x200 - angle;
1804
int32 sine = sin512LookupTable[angle];
1805
int32 cosine = cos512LookupTable[angle];
1806
int32 xPositions[4];
1807
int32 yPositions[4];
1808
1809
if (direction == FLIP_X) {
1810
xPositions[0] = XPos + ((sine * (-pivotY - 2) + cosine * (pivotX + 2)) >> 9);
1811
yPositions[0] = YPos + ((cosine * (-pivotY - 2) - sine * (pivotX + 2)) >> 9);
1812
xPositions[1] = XPos + ((sine * (-pivotY - 2) + cosine * (pivotX - width - 2)) >> 9);
1813
yPositions[1] = YPos + ((cosine * (-pivotY - 2) - sine * (pivotX - width - 2)) >> 9);
1814
xPositions[2] = XPos + ((sine * (height - pivotY + 2) + cosine * (pivotX + 2)) >> 9);
1815
yPositions[2] = YPos + ((cosine * (height - pivotY + 2) - sine * (pivotX + 2)) >> 9);
1816
int32 a = pivotX - width - 2;
1817
int32 b = height - pivotY + 2;
1818
xPositions[3] = XPos + ((sine * b + cosine * a) >> 9);
1819
yPositions[3] = YPos + ((cosine * b - sine * a) >> 9);
1820
}
1821
else {
1822
xPositions[0] = XPos + ((sine * (-pivotY - 2) + cosine * (-pivotX - 2)) >> 9);
1823
yPositions[0] = YPos + ((cosine * (-pivotY - 2) - sine * (-pivotX - 2)) >> 9);
1824
xPositions[1] = XPos + ((sine * (-pivotY - 2) + cosine * (width - pivotX + 2)) >> 9);
1825
yPositions[1] = YPos + ((cosine * (-pivotY - 2) - sine * (width - pivotX + 2)) >> 9);
1826
xPositions[2] = XPos + ((sine * (height - pivotY + 2) + cosine * (-pivotX - 2)) >> 9);
1827
yPositions[2] = YPos + ((cosine * (height - pivotY + 2) - sine * (-pivotX - 2)) >> 9);
1828
int32 a = width - pivotX + 2;
1829
int32 b = height - pivotY + 2;
1830
xPositions[3] = XPos + ((sine * b + cosine * a) >> 9);
1831
yPositions[3] = YPos + ((cosine * b - sine * a) >> 9);
1832
}
1833
1834
int32 left = GFX_LINESIZE;
1835
for (int32 i = 0; i < 4; ++i) {
1836
if (xPositions[i] < left)
1837
left = xPositions[i];
1838
}
1839
if (left < 0)
1840
left = 0;
1841
1842
int32 right = 0;
1843
for (int32 i = 0; i < 4; ++i) {
1844
if (xPositions[i] > right)
1845
right = xPositions[i];
1846
}
1847
if (right > GFX_LINESIZE)
1848
right = GFX_LINESIZE;
1849
int32 maxX = right - left;
1850
1851
int32 top = SCREEN_YSIZE;
1852
for (int32 i = 0; i < 4; ++i) {
1853
if (yPositions[i] < top)
1854
top = yPositions[i];
1855
}
1856
if (top < 0)
1857
top = 0;
1858
1859
int32 bottom = 0;
1860
for (int32 i = 0; i < 4; ++i) {
1861
if (yPositions[i] > bottom)
1862
bottom = yPositions[i];
1863
}
1864
if (bottom > SCREEN_YSIZE)
1865
bottom = SCREEN_YSIZE;
1866
int32 maxY = bottom - top;
1867
1868
if (maxX <= 0 || maxY <= 0)
1869
return;
1870
1871
GFXSurface *surface = &gfxSurface[sheetID];
1872
int32 pitch = GFX_LINESIZE - maxX;
1873
int32 lineSize = surface->widthShift;
1874
uint16 *frameBuffer = &currentScreen->frameBuffer[left + GFX_LINESIZE * top];
1875
uint8 *lineBuffer = &gfxLineBuffer[top];
1876
int32 startX = left - XPos;
1877
int32 startY = top - YPos;
1878
int32 shiftPivot = (sprX << 9) - 1;
1879
int32 shiftheight = (sprY << 9) - 1;
1880
fullwidth <<= 9;
1881
fullheight <<= 9;
1882
uint8 *pixels = &graphicData[surface->dataPosition];
1883
if (cosine < 0 || sine < 0)
1884
sprYPos += sine + cosine;
1885
1886
if (direction == FLIP_X) {
1887
int32 drawX = sprXPos - (cosine * startX - sine * startY) - 0x100;
1888
int32 drawY = cosine * startY + sprYPos + sine * startX;
1889
while (maxY--) {
1890
activePalette = fullPalette[*lineBuffer];
1891
lineBuffer++;
1892
1893
int32 finalX = drawX;
1894
int32 finalY = drawY;
1895
int32 w = maxX;
1896
while (w--) {
1897
if (finalX > shiftPivot && finalX < fullwidth && finalY > shiftheight && finalY < fullheight) {
1898
uint8 index = pixels[(finalY >> 9 << lineSize) + (finalX >> 9)];
1899
if (index > 0)
1900
*frameBuffer = activePalette[index];
1901
}
1902
++frameBuffer;
1903
finalX -= cosine;
1904
finalY += sine;
1905
}
1906
1907
drawX += sine;
1908
drawY += cosine;
1909
frameBuffer += pitch;
1910
}
1911
}
1912
else {
1913
int32 drawX = sprXPos + cosine * startX - sine * startY;
1914
int32 drawY = cosine * startY + sprYPos + sine * startX;
1915
while (maxY--) {
1916
activePalette = fullPalette[*lineBuffer];
1917
lineBuffer++;
1918
1919
int32 finalX = drawX;
1920
int32 finalY = drawY;
1921
int32 w = maxX;
1922
while (w--) {
1923
if (finalX > shiftPivot && finalX < fullwidth && finalY > shiftheight && finalY < fullheight) {
1924
uint8 index = pixels[(finalY >> 9 << lineSize) + (finalX >> 9)];
1925
if (index > 0)
1926
*frameBuffer = activePalette[index];
1927
}
1928
++frameBuffer;
1929
finalX += cosine;
1930
finalY += sine;
1931
}
1932
1933
drawX -= sine;
1934
drawY += cosine;
1935
frameBuffer += pitch;
1936
}
1937
}
1938
}
1939
1940
void RSDK::Legacy::DrawSpriteRotozoom(int32 direction, int32 XPos, int32 YPos, int32 pivotX, int32 pivotY, int32 sprX, int32 sprY, int32 width,
1941
int32 height, int32 rotation, int32 scale, int32 sheetID)
1942
{
1943
if (scale == 0)
1944
return;
1945
1946
int32 sprXPos = (pivotX + sprX) << 9;
1947
int32 sprYPos = (pivotY + sprY) << 9;
1948
int32 fullwidth = width + sprX;
1949
int32 fullheight = height + sprY;
1950
int32 angle = rotation & 0x1FF;
1951
if (angle < 0)
1952
angle += 0x200;
1953
if (angle)
1954
angle = 0x200 - angle;
1955
int32 sine = scale * sin512LookupTable[angle] >> 9;
1956
int32 cosine = scale * cos512LookupTable[angle] >> 9;
1957
int32 xPositions[4];
1958
int32 yPositions[4];
1959
1960
if (direction == FLIP_X) {
1961
xPositions[0] = XPos + ((sine * (-pivotY - 2) + cosine * (pivotX + 2)) >> 9);
1962
yPositions[0] = YPos + ((cosine * (-pivotY - 2) - sine * (pivotX + 2)) >> 9);
1963
xPositions[1] = XPos + ((sine * (-pivotY - 2) + cosine * (pivotX - width - 2)) >> 9);
1964
yPositions[1] = YPos + ((cosine * (-pivotY - 2) - sine * (pivotX - width - 2)) >> 9);
1965
xPositions[2] = XPos + ((sine * (height - pivotY + 2) + cosine * (pivotX + 2)) >> 9);
1966
yPositions[2] = YPos + ((cosine * (height - pivotY + 2) - sine * (pivotX + 2)) >> 9);
1967
int32 a = pivotX - width - 2;
1968
int32 b = height - pivotY + 2;
1969
xPositions[3] = XPos + ((sine * b + cosine * a) >> 9);
1970
yPositions[3] = YPos + ((cosine * b - sine * a) >> 9);
1971
}
1972
else {
1973
xPositions[0] = XPos + ((sine * (-pivotY - 2) + cosine * (-pivotX - 2)) >> 9);
1974
yPositions[0] = YPos + ((cosine * (-pivotY - 2) - sine * (-pivotX - 2)) >> 9);
1975
xPositions[1] = XPos + ((sine * (-pivotY - 2) + cosine * (width - pivotX + 2)) >> 9);
1976
yPositions[1] = YPos + ((cosine * (-pivotY - 2) - sine * (width - pivotX + 2)) >> 9);
1977
xPositions[2] = XPos + ((sine * (height - pivotY + 2) + cosine * (-pivotX - 2)) >> 9);
1978
yPositions[2] = YPos + ((cosine * (height - pivotY + 2) - sine * (-pivotX - 2)) >> 9);
1979
int32 a = width - pivotX + 2;
1980
int32 b = height - pivotY + 2;
1981
xPositions[3] = XPos + ((sine * b + cosine * a) >> 9);
1982
yPositions[3] = YPos + ((cosine * b - sine * a) >> 9);
1983
}
1984
int32 truescale = (int32)(float)((float)(512.0 / (float)scale) * 512.0);
1985
sine = truescale * sin512LookupTable[angle] >> 9;
1986
cosine = truescale * cos512LookupTable[angle] >> 9;
1987
1988
int32 left = GFX_LINESIZE;
1989
for (int32 i = 0; i < 4; ++i) {
1990
if (xPositions[i] < left)
1991
left = xPositions[i];
1992
}
1993
if (left < 0)
1994
left = 0;
1995
1996
int32 right = 0;
1997
for (int32 i = 0; i < 4; ++i) {
1998
if (xPositions[i] > right)
1999
right = xPositions[i];
2000
}
2001
if (right > GFX_LINESIZE)
2002
right = GFX_LINESIZE;
2003
int32 maxX = right - left;
2004
2005
int32 top = SCREEN_YSIZE;
2006
for (int32 i = 0; i < 4; ++i) {
2007
if (yPositions[i] < top)
2008
top = yPositions[i];
2009
}
2010
if (top < 0)
2011
top = 0;
2012
2013
int32 bottom = 0;
2014
for (int32 i = 0; i < 4; ++i) {
2015
if (yPositions[i] > bottom)
2016
bottom = yPositions[i];
2017
}
2018
if (bottom > SCREEN_YSIZE)
2019
bottom = SCREEN_YSIZE;
2020
int32 maxY = bottom - top;
2021
2022
if (maxX <= 0 || maxY <= 0)
2023
return;
2024
2025
GFXSurface *surface = &gfxSurface[sheetID];
2026
int32 pitch = GFX_LINESIZE - maxX;
2027
int32 lineSize = surface->widthShift;
2028
uint16 *frameBuffer = &currentScreen->frameBuffer[left + GFX_LINESIZE * top];
2029
uint8 *lineBuffer = &gfxLineBuffer[top];
2030
int32 startX = left - XPos;
2031
int32 startY = top - YPos;
2032
int32 shiftPivot = (sprX << 9) - 1;
2033
int32 shiftheight = (sprY << 9) - 1;
2034
fullwidth <<= 9;
2035
fullheight <<= 9;
2036
uint8 *pixels = &graphicData[surface->dataPosition];
2037
if (cosine < 0 || sine < 0)
2038
sprYPos += sine + cosine;
2039
2040
if (direction == FLIP_X) {
2041
int32 drawX = sprXPos - (cosine * startX - sine * startY) - (truescale >> 1);
2042
int32 drawY = cosine * startY + sprYPos + sine * startX;
2043
while (maxY--) {
2044
activePalette = fullPalette[*lineBuffer];
2045
lineBuffer++;
2046
2047
int32 finalX = drawX;
2048
int32 finalY = drawY;
2049
int32 w = maxX;
2050
while (w--) {
2051
if (finalX > shiftPivot && finalX < fullwidth && finalY > shiftheight && finalY < fullheight) {
2052
uint8 index = pixels[(finalY >> 9 << lineSize) + (finalX >> 9)];
2053
if (index > 0)
2054
*frameBuffer = activePalette[index];
2055
}
2056
2057
++frameBuffer;
2058
finalX -= cosine;
2059
finalY += sine;
2060
}
2061
2062
drawX += sine;
2063
drawY += cosine;
2064
frameBuffer += pitch;
2065
}
2066
}
2067
else {
2068
int32 drawX = sprXPos + cosine * startX - sine * startY;
2069
int32 drawY = cosine * startY + sprYPos + sine * startX;
2070
while (maxY--) {
2071
activePalette = fullPalette[*lineBuffer];
2072
lineBuffer++;
2073
2074
int32 finalX = drawX;
2075
int32 finalY = drawY;
2076
int32 w = maxX;
2077
while (w--) {
2078
if (finalX > shiftPivot && finalX < fullwidth && finalY > shiftheight && finalY < fullheight) {
2079
uint8 index = pixels[(finalY >> 9 << lineSize) + (finalX >> 9)];
2080
if (index > 0)
2081
*frameBuffer = activePalette[index];
2082
}
2083
2084
++frameBuffer;
2085
finalX += cosine;
2086
finalY += sine;
2087
}
2088
2089
drawX -= sine;
2090
drawY += cosine;
2091
frameBuffer += pitch;
2092
}
2093
}
2094
}
2095
2096
void RSDK::Legacy::DrawBlendedSprite(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 sheetID)
2097
{
2098
if (width + XPos > GFX_LINESIZE)
2099
width = GFX_LINESIZE - XPos;
2100
if (XPos < 0) {
2101
sprX -= XPos;
2102
width += XPos;
2103
XPos = 0;
2104
}
2105
if (height + YPos > SCREEN_YSIZE)
2106
height = SCREEN_YSIZE - YPos;
2107
if (YPos < 0) {
2108
sprY -= YPos;
2109
height += YPos;
2110
YPos = 0;
2111
}
2112
if (width <= 0 || height <= 0)
2113
return;
2114
2115
GFXSurface *surface = &gfxSurface[sheetID];
2116
int32 pitch = GFX_LINESIZE - width;
2117
int32 gfxPitch = surface->width - width;
2118
uint8 *lineBuffer = &gfxLineBuffer[YPos];
2119
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
2120
uint16 *frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
2121
2122
while (height--) {
2123
activePalette = fullPalette[*lineBuffer];
2124
lineBuffer++;
2125
2126
int32 w = width;
2127
while (w--) {
2128
if (*pixels > 0)
2129
*frameBuffer = ((activePalette[*pixels] & 0xF7DE) >> 1) + ((*frameBuffer & 0xF7DE) >> 1);
2130
++pixels;
2131
++frameBuffer;
2132
}
2133
2134
frameBuffer += pitch;
2135
pixels += gfxPitch;
2136
}
2137
}
2138
void RSDK::Legacy::DrawAlphaBlendedSprite(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 alpha, int32 sheetID)
2139
{
2140
if (alpha > 0xFF)
2141
alpha = 0xFF;
2142
2143
if (width + XPos > GFX_LINESIZE)
2144
width = GFX_LINESIZE - XPos;
2145
if (XPos < 0) {
2146
sprX -= XPos;
2147
width += XPos;
2148
XPos = 0;
2149
}
2150
if (height + YPos > SCREEN_YSIZE)
2151
height = SCREEN_YSIZE - YPos;
2152
if (YPos < 0) {
2153
sprY -= YPos;
2154
height += YPos;
2155
YPos = 0;
2156
}
2157
if (width <= 0 || height <= 0 || alpha <= 0)
2158
return;
2159
2160
GFXSurface *surface = &gfxSurface[sheetID];
2161
int32 pitch = GFX_LINESIZE - width;
2162
int32 gfxPitch = surface->width - width;
2163
uint8 *lineBuffer = &gfxLineBuffer[YPos];
2164
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
2165
uint16 *frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
2166
if (alpha == 0xFF) {
2167
while (height--) {
2168
activePalette = fullPalette[*lineBuffer];
2169
lineBuffer++;
2170
2171
int32 w = width;
2172
while (w--) {
2173
if (*pixels > 0)
2174
*frameBuffer = activePalette[*pixels];
2175
++pixels;
2176
++frameBuffer;
2177
}
2178
2179
frameBuffer += pitch;
2180
pixels += gfxPitch;
2181
}
2182
}
2183
else {
2184
uint16 *fbufferBlend = &blendLookupTable[0x20 * (0xFF - alpha)];
2185
uint16 *pixelBlend = &blendLookupTable[0x20 * alpha];
2186
2187
while (height--) {
2188
activePalette = fullPalette[*lineBuffer];
2189
lineBuffer++;
2190
2191
int32 w = width;
2192
while (w--) {
2193
if (*pixels > 0) {
2194
uint16 color = activePalette[*pixels];
2195
2196
int32 R = (fbufferBlend[(*frameBuffer & 0xF800) >> 11] + pixelBlend[(color & 0xF800) >> 11]) << 11;
2197
int32 G = (fbufferBlend[(*frameBuffer & 0x7E0) >> 6] + pixelBlend[(color & 0x7E0) >> 6]) << 6;
2198
int32 B = fbufferBlend[*frameBuffer & 0x1F] + pixelBlend[color & 0x1F];
2199
2200
*frameBuffer = R | G | B;
2201
}
2202
++pixels;
2203
++frameBuffer;
2204
}
2205
2206
frameBuffer += pitch;
2207
pixels += gfxPitch;
2208
}
2209
}
2210
}
2211
void RSDK::Legacy::DrawAdditiveBlendedSprite(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 alpha, int32 sheetID)
2212
{
2213
if (alpha > 0xFF)
2214
alpha = 0xFF;
2215
2216
if (width + XPos > GFX_LINESIZE)
2217
width = GFX_LINESIZE - XPos;
2218
2219
if (XPos < 0) {
2220
sprX -= XPos;
2221
width += XPos;
2222
XPos = 0;
2223
}
2224
2225
if (height + YPos > SCREEN_YSIZE)
2226
height = SCREEN_YSIZE - YPos;
2227
2228
if (YPos < 0) {
2229
sprY -= YPos;
2230
height += YPos;
2231
YPos = 0;
2232
}
2233
2234
if (width <= 0 || height <= 0 || alpha <= 0)
2235
return;
2236
2237
uint16 *blendTablePtr = &blendLookupTable[0x20 * alpha];
2238
GFXSurface *surface = &gfxSurface[sheetID];
2239
int32 pitch = GFX_LINESIZE - width;
2240
int32 gfxPitch = surface->width - width;
2241
uint8 *lineBuffer = &gfxLineBuffer[YPos];
2242
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
2243
uint16 *frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
2244
2245
while (height--) {
2246
activePalette = fullPalette[*lineBuffer];
2247
lineBuffer++;
2248
2249
int32 w = width;
2250
while (w--) {
2251
if (*pixels > 0) {
2252
uint16 color = activePalette[*pixels];
2253
2254
int32 R = MIN((blendTablePtr[(color & 0xF800) >> 11] << 11) + (*frameBuffer & 0xF800), 0xF800);
2255
int32 G = MIN((blendTablePtr[(color & 0x7E0) >> 6] << 6) + (*frameBuffer & 0x7E0), 0x7E0);
2256
int32 B = MIN(blendTablePtr[color & 0x1F] + (*frameBuffer & 0x1F), 0x1F);
2257
2258
*frameBuffer = R | G | B;
2259
}
2260
2261
++pixels;
2262
++frameBuffer;
2263
}
2264
2265
frameBuffer += pitch;
2266
pixels += gfxPitch;
2267
}
2268
}
2269
void RSDK::Legacy::DrawSubtractiveBlendedSprite(int32 XPos, int32 YPos, int32 width, int32 height, int32 sprX, int32 sprY, int32 alpha, int32 sheetID)
2270
{
2271
if (alpha > 0xFF)
2272
alpha = 0xFF;
2273
2274
if (width + XPos > GFX_LINESIZE)
2275
width = GFX_LINESIZE - XPos;
2276
if (XPos < 0) {
2277
sprX -= XPos;
2278
width += XPos;
2279
XPos = 0;
2280
}
2281
if (height + YPos > SCREEN_YSIZE)
2282
height = SCREEN_YSIZE - YPos;
2283
if (YPos < 0) {
2284
sprY -= YPos;
2285
height += YPos;
2286
YPos = 0;
2287
}
2288
if (width <= 0 || height <= 0 || alpha <= 0)
2289
return;
2290
2291
uint16 *subBlendTable = &subtractLookupTable[0x20 * alpha];
2292
GFXSurface *surface = &gfxSurface[sheetID];
2293
int32 pitch = GFX_LINESIZE - width;
2294
int32 gfxPitch = surface->width - width;
2295
uint8 *lineBuffer = &gfxLineBuffer[YPos];
2296
uint8 *pixels = &graphicData[sprX + surface->width * sprY + surface->dataPosition];
2297
uint16 *frameBuffer = &currentScreen->frameBuffer[XPos + GFX_LINESIZE * YPos];
2298
2299
while (height--) {
2300
activePalette = fullPalette[*lineBuffer];
2301
lineBuffer++;
2302
2303
int32 w = width;
2304
while (w--) {
2305
if (*pixels > 0) {
2306
uint16 color = activePalette[*pixels];
2307
2308
int32 R = MAX((*frameBuffer & 0xF800) - (subBlendTable[(color & 0xF800) >> 11] << 11), 0);
2309
int32 G = MAX((*frameBuffer & 0x7E0) - (subBlendTable[(color & 0x7E0) >> 6] << 6), 0);
2310
int32 B = MAX((*frameBuffer & 0x1F) - subBlendTable[color & 0x1F], 0);
2311
2312
*frameBuffer = R | G | B;
2313
}
2314
++pixels;
2315
++frameBuffer;
2316
}
2317
frameBuffer += pitch;
2318
pixels += gfxPitch;
2319
}
2320
}
2321
2322
void RSDK::Legacy::DrawFace(void *v, uint32 color)
2323
{
2324
Vertex *verts = (Vertex *)v;
2325
int32 alpha = (color & 0x7F000000) >> 23;
2326
if (alpha < 1)
2327
return;
2328
2329
if (alpha > 0xFF)
2330
alpha = 0xFF;
2331
2332
if (verts[0].x < 0 && verts[1].x < 0 && verts[2].x < 0 && verts[3].x < 0)
2333
return;
2334
2335
if (verts[0].x > GFX_LINESIZE && verts[1].x > GFX_LINESIZE && verts[2].x > GFX_LINESIZE && verts[3].x > GFX_LINESIZE)
2336
return;
2337
2338
if (verts[0].y < 0 && verts[1].y < 0 && verts[2].y < 0 && verts[3].y < 0)
2339
return;
2340
2341
if (verts[0].y > SCREEN_YSIZE && verts[1].y > SCREEN_YSIZE && verts[2].y > SCREEN_YSIZE && verts[3].y > SCREEN_YSIZE)
2342
return;
2343
2344
if (verts[0].x == verts[1].x && verts[1].x == verts[2].x && verts[2].x == verts[3].x)
2345
return;
2346
2347
if (verts[0].y == verts[1].y && verts[1].y == verts[2].y && verts[2].y == verts[3].y)
2348
return;
2349
2350
int32 vertexA = 0;
2351
int32 vertexB = 1;
2352
int32 vertexC = 2;
2353
int32 vertexD = 3;
2354
if (verts[1].y < verts[0].y) {
2355
vertexA = 1;
2356
vertexB = 0;
2357
}
2358
if (verts[2].y < verts[vertexA].y) {
2359
int32 temp = vertexA;
2360
vertexA = 2;
2361
vertexC = temp;
2362
}
2363
if (verts[3].y < verts[vertexA].y) {
2364
int32 temp = vertexA;
2365
vertexA = 3;
2366
vertexD = temp;
2367
}
2368
if (verts[vertexC].y < verts[vertexB].y) {
2369
int32 temp = vertexB;
2370
vertexB = vertexC;
2371
vertexC = temp;
2372
}
2373
if (verts[vertexD].y < verts[vertexB].y) {
2374
int32 temp = vertexB;
2375
vertexB = vertexD;
2376
vertexD = temp;
2377
}
2378
if (verts[vertexD].y < verts[vertexC].y) {
2379
int32 temp = vertexC;
2380
vertexC = vertexD;
2381
vertexD = temp;
2382
}
2383
2384
int32 faceTop = verts[vertexA].y;
2385
int32 faceBottom = verts[vertexD].y;
2386
if (faceTop < 0)
2387
faceTop = 0;
2388
if (faceBottom > SCREEN_YSIZE)
2389
faceBottom = SCREEN_YSIZE;
2390
for (int32 i = faceTop; i < faceBottom; ++i) {
2391
faceLineStart[i] = 100000;
2392
faceLineEnd[i] = -100000;
2393
}
2394
2395
ProcessScanEdge(&verts[vertexA], &verts[vertexB]);
2396
ProcessScanEdge(&verts[vertexA], &verts[vertexC]);
2397
ProcessScanEdge(&verts[vertexA], &verts[vertexD]);
2398
ProcessScanEdge(&verts[vertexB], &verts[vertexC]);
2399
ProcessScanEdge(&verts[vertexC], &verts[vertexD]);
2400
ProcessScanEdge(&verts[vertexB], &verts[vertexD]);
2401
2402
uint16 color16 = PACK_RGB888(((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF));
2403
uint16 *frameBuffer = &currentScreen->frameBuffer[GFX_LINESIZE * faceTop];
2404
2405
if (alpha == 0xFF) {
2406
while (faceTop < faceBottom) {
2407
int32 startX = faceLineStart[faceTop];
2408
int32 endX = faceLineEnd[faceTop];
2409
if (startX >= GFX_LINESIZE || endX <= 0) {
2410
frameBuffer += GFX_LINESIZE;
2411
}
2412
else {
2413
if (startX < 0)
2414
startX = 0;
2415
if (endX > GFX_LINESIZE_MINUSONE)
2416
endX = GFX_LINESIZE_MINUSONE;
2417
uint16 *frameBufferPtr = &frameBuffer[startX];
2418
frameBuffer += GFX_LINESIZE;
2419
int32 vertexwidth = endX - startX + 1;
2420
while (vertexwidth--) {
2421
*frameBufferPtr = color16;
2422
++frameBufferPtr;
2423
}
2424
}
2425
++faceTop;
2426
}
2427
}
2428
else {
2429
uint16 *fbufferBlend = &blendLookupTable[0x20 * (0xFF - alpha)];
2430
uint16 *pixelBlend = &blendLookupTable[0x20 * alpha];
2431
2432
while (faceTop < faceBottom) {
2433
int32 startX = faceLineStart[faceTop];
2434
int32 endX = faceLineEnd[faceTop];
2435
if (startX >= GFX_LINESIZE || endX <= 0) {
2436
frameBuffer += GFX_LINESIZE;
2437
}
2438
else {
2439
if (startX < 0)
2440
startX = 0;
2441
if (endX > GFX_LINESIZE_MINUSONE)
2442
endX = GFX_LINESIZE_MINUSONE;
2443
uint16 *framebufferPtr = &frameBuffer[startX];
2444
frameBuffer += GFX_LINESIZE;
2445
int32 vertexwidth = endX - startX + 1;
2446
while (vertexwidth--) {
2447
int32 R = (fbufferBlend[(*framebufferPtr & 0xF800) >> 11] + pixelBlend[(color16 & 0xF800) >> 11]) << 11;
2448
int32 G = (fbufferBlend[(*framebufferPtr & 0x7E0) >> 6] + pixelBlend[(color16 & 0x7E0) >> 6]) << 6;
2449
int32 B = fbufferBlend[*framebufferPtr & 0x1F] + pixelBlend[color16 & 0x1F];
2450
2451
*framebufferPtr = R | G | B;
2452
++framebufferPtr;
2453
}
2454
}
2455
++faceTop;
2456
}
2457
}
2458
}
2459
void RSDK::Legacy::DrawTexturedFace(void *v, uint8 sheetID)
2460
{
2461
Vertex *verts = (Vertex *)v;
2462
2463
if (verts[0].x < 0 && verts[1].x < 0 && verts[2].x < 0 && verts[3].x < 0)
2464
return;
2465
if (verts[0].x > GFX_LINESIZE && verts[1].x > GFX_LINESIZE && verts[2].x > GFX_LINESIZE && verts[3].x > GFX_LINESIZE)
2466
return;
2467
if (verts[0].y < 0 && verts[1].y < 0 && verts[2].y < 0 && verts[3].y < 0)
2468
return;
2469
if (verts[0].y > SCREEN_YSIZE && verts[1].y > SCREEN_YSIZE && verts[2].y > SCREEN_YSIZE && verts[3].y > SCREEN_YSIZE)
2470
return;
2471
if (verts[0].x == verts[1].x && verts[1].x == verts[2].x && verts[2].x == verts[3].x)
2472
return;
2473
if (verts[0].y == verts[1].y && verts[1].y == verts[2].y && verts[2].y == verts[3].y)
2474
return;
2475
2476
int32 vertexA = 0;
2477
int32 vertexB = 1;
2478
int32 vertexC = 2;
2479
int32 vertexD = 3;
2480
if (verts[1].y < verts[0].y) {
2481
vertexA = 1;
2482
vertexB = 0;
2483
}
2484
if (verts[2].y < verts[vertexA].y) {
2485
int32 temp = vertexA;
2486
vertexA = 2;
2487
vertexC = temp;
2488
}
2489
if (verts[3].y < verts[vertexA].y) {
2490
int32 temp = vertexA;
2491
vertexA = 3;
2492
vertexD = temp;
2493
}
2494
if (verts[vertexC].y < verts[vertexB].y) {
2495
int32 temp = vertexB;
2496
vertexB = vertexC;
2497
vertexC = temp;
2498
}
2499
if (verts[vertexD].y < verts[vertexB].y) {
2500
int32 temp = vertexB;
2501
vertexB = vertexD;
2502
vertexD = temp;
2503
}
2504
if (verts[vertexD].y < verts[vertexC].y) {
2505
int32 temp = vertexC;
2506
vertexC = vertexD;
2507
vertexD = temp;
2508
}
2509
2510
int32 faceTop = verts[vertexA].y;
2511
int32 faceBottom = verts[vertexD].y;
2512
if (faceTop < 0)
2513
faceTop = 0;
2514
if (faceBottom > SCREEN_YSIZE)
2515
faceBottom = SCREEN_YSIZE;
2516
for (int32 i = faceTop; i < faceBottom; ++i) {
2517
faceLineStart[i] = 100000;
2518
faceLineEnd[i] = -100000;
2519
}
2520
2521
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexB]);
2522
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexC]);
2523
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexD]);
2524
ProcessScanEdgeUV(&verts[vertexB], &verts[vertexC]);
2525
ProcessScanEdgeUV(&verts[vertexC], &verts[vertexD]);
2526
ProcessScanEdgeUV(&verts[vertexB], &verts[vertexD]);
2527
2528
uint16 *frameBuffer = &currentScreen->frameBuffer[GFX_LINESIZE * faceTop];
2529
uint8 *pixels = &graphicData[gfxSurface[sheetID].dataPosition];
2530
int32 shiftwidth = gfxSurface[sheetID].widthShift;
2531
uint8 *lineBuffer = &gfxLineBuffer[faceTop];
2532
2533
while (faceTop < faceBottom) {
2534
activePalette = fullPalette[*lineBuffer];
2535
lineBuffer++;
2536
2537
int32 startX = faceLineStart[faceTop];
2538
int32 endX = faceLineEnd[faceTop];
2539
int32 UPos = faceLineStartU[faceTop];
2540
int32 VPos = faceLineStartV[faceTop];
2541
if (startX >= GFX_LINESIZE || endX <= 0) {
2542
frameBuffer += GFX_LINESIZE;
2543
}
2544
else {
2545
int32 posDifference = endX - startX;
2546
int32 bufferedUPos = 0;
2547
int32 bufferedVPos = 0;
2548
if (endX == startX) {
2549
bufferedUPos = 0;
2550
bufferedVPos = 0;
2551
}
2552
else {
2553
bufferedUPos = (faceLineEndU[faceTop] - UPos) / posDifference;
2554
bufferedVPos = (faceLineEndV[faceTop] - VPos) / posDifference;
2555
}
2556
if (endX > GFX_LINESIZE_MINUSONE)
2557
posDifference = GFX_LINESIZE_MINUSONE - startX;
2558
if (startX < 0) {
2559
posDifference += startX;
2560
UPos -= startX * bufferedUPos;
2561
VPos -= startX * bufferedVPos;
2562
startX = 0;
2563
}
2564
2565
uint16 *framebufferPtr = &frameBuffer[startX];
2566
frameBuffer += GFX_LINESIZE;
2567
2568
int32 counter = posDifference + 1;
2569
while (counter--) {
2570
if (UPos < 0)
2571
UPos = 0;
2572
if (VPos < 0)
2573
VPos = 0;
2574
uint16 index = pixels[(VPos >> 16 << shiftwidth) + (UPos >> 16)];
2575
if (index > 0)
2576
*framebufferPtr = activePalette[index];
2577
framebufferPtr++;
2578
UPos += bufferedUPos;
2579
VPos += bufferedVPos;
2580
}
2581
}
2582
++faceTop;
2583
}
2584
}
2585
2586
void RSDK::Legacy::v4::DrawObjectAnimation(void *objScr, void *ent, int32 XPos, int32 YPos)
2587
{
2588
ObjectScript *objectScript = (ObjectScript *)objScr;
2589
Entity *entity = (Entity *)ent;
2590
SpriteAnimation *sprAnim = &animationList[objectScript->animFile->aniListOffset + entity->animation];
2591
SpriteFrame *frame = &animFrames[sprAnim->frameListOffset + entity->frame];
2592
int32 rotation = 0;
2593
2594
switch (sprAnim->rotationStyle) {
2595
case ROTSTYLE_NONE:
2596
switch (entity->direction) {
2597
case FLIP_NONE:
2598
DrawSpriteFlipped(frame->pivotX + XPos, frame->pivotY + YPos, frame->width, frame->height, frame->sprX, frame->sprY, FLIP_NONE,
2599
frame->sheetID);
2600
break;
2601
2602
case FLIP_X:
2603
DrawSpriteFlipped(XPos - frame->width - frame->pivotX, frame->pivotY + YPos, frame->width, frame->height, frame->sprX,
2604
frame->sprY, FLIP_X, frame->sheetID);
2605
break;
2606
case FLIP_Y:
2607
2608
DrawSpriteFlipped(frame->pivotX + XPos, YPos - frame->height - frame->pivotY, frame->width, frame->height, frame->sprX,
2609
frame->sprY, FLIP_Y, frame->sheetID);
2610
break;
2611
2612
case FLIP_XY:
2613
DrawSpriteFlipped(XPos - frame->width - frame->pivotX, YPos - frame->height - frame->pivotY, frame->width, frame->height,
2614
frame->sprX, frame->sprY, FLIP_XY, frame->sheetID);
2615
break;
2616
2617
default: break;
2618
}
2619
break;
2620
2621
case ROTSTYLE_FULL:
2622
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width, frame->height,
2623
entity->rotation, frame->sheetID);
2624
break;
2625
2626
case ROTSTYLE_45DEG:
2627
if (entity->rotation >= 0x100)
2628
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width,
2629
frame->height, 0x200 - ((0x214 - entity->rotation) >> 6 << 6), frame->sheetID);
2630
else
2631
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width,
2632
frame->height, (entity->rotation + 20) >> 6 << 6, frame->sheetID);
2633
break;
2634
2635
case ROTSTYLE_STATICFRAMES: {
2636
if (entity->rotation >= 0x100)
2637
rotation = 8 - ((532 - entity->rotation) >> 6);
2638
else
2639
rotation = (entity->rotation + 20) >> 6;
2640
int32 frameID = entity->frame;
2641
switch (rotation) {
2642
case 0: // 0 deg
2643
case 8: // 360 deg
2644
rotation = 0x00;
2645
break;
2646
2647
case 1: // 45 deg
2648
frameID += sprAnim->frameCount;
2649
if (entity->direction)
2650
rotation = 0;
2651
else
2652
rotation = 0x80;
2653
break;
2654
2655
case 2: // 90 deg
2656
rotation = 0x80;
2657
break;
2658
2659
case 3: // 135 deg
2660
frameID += sprAnim->frameCount;
2661
if (entity->direction)
2662
rotation = 0x80;
2663
else
2664
rotation = 0x100;
2665
break;
2666
2667
case 4: // 180 deg
2668
rotation = 0x100;
2669
break;
2670
2671
case 5: // 225 deg
2672
frameID += sprAnim->frameCount;
2673
if (entity->direction)
2674
rotation = 0x100;
2675
else
2676
rotation = 384;
2677
break;
2678
2679
case 6: // 270 deg
2680
rotation = 384;
2681
break;
2682
2683
case 7: // 315 deg
2684
frameID += sprAnim->frameCount;
2685
if (entity->direction)
2686
rotation = 384;
2687
else
2688
rotation = 0;
2689
break;
2690
2691
default: break;
2692
}
2693
2694
frame = &animFrames[sprAnim->frameListOffset + frameID];
2695
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width, frame->height,
2696
rotation, frame->sheetID);
2697
break;
2698
}
2699
2700
default: break;
2701
}
2702
}
2703
2704
void RSDK::Legacy::v4::DrawFadedFace(void *v, uint32 color, uint32 fogColor, int32 alpha)
2705
{
2706
Vertex *verts = (Vertex *)v;
2707
if (alpha > 0xFF)
2708
alpha = 0xFF;
2709
2710
if (alpha < 1)
2711
return;
2712
2713
if (verts[0].x < 0 && verts[1].x < 0 && verts[2].x < 0 && verts[3].x < 0)
2714
return;
2715
2716
if (verts[0].x > GFX_LINESIZE && verts[1].x > GFX_LINESIZE && verts[2].x > GFX_LINESIZE && verts[3].x > GFX_LINESIZE)
2717
return;
2718
2719
if (verts[0].y < 0 && verts[1].y < 0 && verts[2].y < 0 && verts[3].y < 0)
2720
return;
2721
2722
if (verts[0].y > SCREEN_YSIZE && verts[1].y > SCREEN_YSIZE && verts[2].y > SCREEN_YSIZE && verts[3].y > SCREEN_YSIZE)
2723
return;
2724
2725
if (verts[0].x == verts[1].x && verts[1].x == verts[2].x && verts[2].x == verts[3].x)
2726
return;
2727
2728
if (verts[0].y == verts[1].y && verts[1].y == verts[2].y && verts[2].y == verts[3].y)
2729
return;
2730
2731
int32 vertexA = 0;
2732
int32 vertexB = 1;
2733
int32 vertexC = 2;
2734
int32 vertexD = 3;
2735
if (verts[1].y < verts[0].y) {
2736
vertexA = 1;
2737
vertexB = 0;
2738
}
2739
if (verts[2].y < verts[vertexA].y) {
2740
int32 temp = vertexA;
2741
vertexA = 2;
2742
vertexC = temp;
2743
}
2744
if (verts[3].y < verts[vertexA].y) {
2745
int32 temp = vertexA;
2746
vertexA = 3;
2747
vertexD = temp;
2748
}
2749
if (verts[vertexC].y < verts[vertexB].y) {
2750
int32 temp = vertexB;
2751
vertexB = vertexC;
2752
vertexC = temp;
2753
}
2754
if (verts[vertexD].y < verts[vertexB].y) {
2755
int32 temp = vertexB;
2756
vertexB = vertexD;
2757
vertexD = temp;
2758
}
2759
if (verts[vertexD].y < verts[vertexC].y) {
2760
int32 temp = vertexC;
2761
vertexC = vertexD;
2762
vertexD = temp;
2763
}
2764
2765
int32 faceTop = verts[vertexA].y;
2766
int32 faceBottom = verts[vertexD].y;
2767
if (faceTop < 0)
2768
faceTop = 0;
2769
if (faceBottom > SCREEN_YSIZE)
2770
faceBottom = SCREEN_YSIZE;
2771
for (int32 i = faceTop; i < faceBottom; ++i) {
2772
faceLineStart[i] = 100000;
2773
faceLineEnd[i] = -100000;
2774
}
2775
2776
ProcessScanEdge(&verts[vertexA], &verts[vertexB]);
2777
ProcessScanEdge(&verts[vertexA], &verts[vertexC]);
2778
ProcessScanEdge(&verts[vertexA], &verts[vertexD]);
2779
ProcessScanEdge(&verts[vertexB], &verts[vertexC]);
2780
ProcessScanEdge(&verts[vertexC], &verts[vertexD]);
2781
ProcessScanEdge(&verts[vertexB], &verts[vertexD]);
2782
2783
uint16 color16 = PACK_RGB888(((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF));
2784
uint16 fogColor16 = PACK_RGB888(((fogColor >> 16) & 0xFF), ((fogColor >> 8) & 0xFF), ((fogColor >> 0) & 0xFF));
2785
2786
uint16 *frameBuffer = &currentScreen->frameBuffer[GFX_LINESIZE * faceTop];
2787
uint16 *fbufferBlend = &blendLookupTable[0x20 * (0xFF - alpha)];
2788
uint16 *pixelBlend = &blendLookupTable[0x20 * alpha];
2789
2790
while (faceTop < faceBottom) {
2791
int32 startX = faceLineStart[faceTop];
2792
int32 endX = faceLineEnd[faceTop];
2793
if (startX >= GFX_LINESIZE || endX <= 0) {
2794
frameBuffer += GFX_LINESIZE;
2795
}
2796
else {
2797
if (startX < 0)
2798
startX = 0;
2799
if (endX > GFX_LINESIZE_MINUSONE)
2800
endX = GFX_LINESIZE_MINUSONE;
2801
2802
uint16 *frameBufferPtr = &frameBuffer[startX];
2803
frameBuffer += GFX_LINESIZE;
2804
int32 vertexwidth = endX - startX + 1;
2805
while (vertexwidth--) {
2806
int32 R = (fbufferBlend[(fogColor16 & 0xF800) >> 11] + pixelBlend[(color16 & 0xF800) >> 11]) << 11;
2807
int32 G = (fbufferBlend[(fogColor16 & 0x7E0) >> 6] + pixelBlend[(color16 & 0x7E0) >> 6]) << 6;
2808
int32 B = fbufferBlend[fogColor16 & 0x1F] + pixelBlend[color16 & 0x1F];
2809
2810
*frameBufferPtr = R | G | B;
2811
++frameBufferPtr;
2812
}
2813
}
2814
2815
++faceTop;
2816
}
2817
}
2818
void RSDK::Legacy::v4::DrawTexturedFaceBlended(void *v, uint8 sheetID)
2819
{
2820
Vertex *verts = (Vertex *)v;
2821
if (verts[0].x < 0 && verts[1].x < 0 && verts[2].x < 0 && verts[3].x < 0)
2822
return;
2823
2824
if (verts[0].x > GFX_LINESIZE && verts[1].x > GFX_LINESIZE && verts[2].x > GFX_LINESIZE && verts[3].x > GFX_LINESIZE)
2825
return;
2826
2827
if (verts[0].y < 0 && verts[1].y < 0 && verts[2].y < 0 && verts[3].y < 0)
2828
return;
2829
2830
if (verts[0].y > SCREEN_YSIZE && verts[1].y > SCREEN_YSIZE && verts[2].y > SCREEN_YSIZE && verts[3].y > SCREEN_YSIZE)
2831
return;
2832
2833
if (verts[0].x == verts[1].x && verts[1].x == verts[2].x && verts[2].x == verts[3].x)
2834
return;
2835
2836
if (verts[0].y == verts[1].y && verts[1].y == verts[2].y && verts[2].y == verts[3].y)
2837
return;
2838
2839
int32 vertexA = 0;
2840
int32 vertexB = 1;
2841
int32 vertexC = 2;
2842
int32 vertexD = 3;
2843
if (verts[1].y < verts[0].y) {
2844
vertexA = 1;
2845
vertexB = 0;
2846
}
2847
if (verts[2].y < verts[vertexA].y) {
2848
int32 temp = vertexA;
2849
vertexA = 2;
2850
vertexC = temp;
2851
}
2852
if (verts[3].y < verts[vertexA].y) {
2853
int32 temp = vertexA;
2854
vertexA = 3;
2855
vertexD = temp;
2856
}
2857
if (verts[vertexC].y < verts[vertexB].y) {
2858
int32 temp = vertexB;
2859
vertexB = vertexC;
2860
vertexC = temp;
2861
}
2862
if (verts[vertexD].y < verts[vertexB].y) {
2863
int32 temp = vertexB;
2864
vertexB = vertexD;
2865
vertexD = temp;
2866
}
2867
if (verts[vertexD].y < verts[vertexC].y) {
2868
int32 temp = vertexC;
2869
vertexC = vertexD;
2870
vertexD = temp;
2871
}
2872
2873
int32 faceTop = verts[vertexA].y;
2874
int32 faceBottom = verts[vertexD].y;
2875
if (faceTop < 0)
2876
faceTop = 0;
2877
if (faceBottom > SCREEN_YSIZE)
2878
faceBottom = SCREEN_YSIZE;
2879
for (int32 i = faceTop; i < faceBottom; ++i) {
2880
faceLineStart[i] = 100000;
2881
faceLineEnd[i] = -100000;
2882
}
2883
2884
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexB]);
2885
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexC]);
2886
ProcessScanEdgeUV(&verts[vertexA], &verts[vertexD]);
2887
ProcessScanEdgeUV(&verts[vertexB], &verts[vertexC]);
2888
ProcessScanEdgeUV(&verts[vertexC], &verts[vertexD]);
2889
ProcessScanEdgeUV(&verts[vertexB], &verts[vertexD]);
2890
2891
uint16 *frameBuffer = &currentScreen->frameBuffer[GFX_LINESIZE * faceTop];
2892
uint8 *pixels = &graphicData[gfxSurface[sheetID].dataPosition];
2893
int32 shiftwidth = gfxSurface[sheetID].widthShift;
2894
uint8 *lineBuffer = &gfxLineBuffer[faceTop];
2895
while (faceTop < faceBottom) {
2896
activePalette = fullPalette[*lineBuffer];
2897
lineBuffer++;
2898
2899
int32 startX = faceLineStart[faceTop];
2900
int32 endX = faceLineEnd[faceTop];
2901
int32 UPos = faceLineStartU[faceTop];
2902
int32 VPos = faceLineStartV[faceTop];
2903
2904
if (startX >= GFX_LINESIZE || endX <= 0) {
2905
frameBuffer += GFX_LINESIZE;
2906
}
2907
else {
2908
int32 posDifference = endX - startX;
2909
int32 bufferedUPos = 0;
2910
int32 bufferedVPos = 0;
2911
if (endX == startX) {
2912
bufferedUPos = 0;
2913
bufferedVPos = 0;
2914
}
2915
else {
2916
bufferedUPos = (faceLineEndU[faceTop] - UPos) / posDifference;
2917
bufferedVPos = (faceLineEndV[faceTop] - VPos) / posDifference;
2918
}
2919
2920
if (endX > GFX_LINESIZE_MINUSONE)
2921
posDifference = GFX_LINESIZE_MINUSONE - startX;
2922
2923
if (startX < 0) {
2924
posDifference += startX;
2925
UPos -= startX * bufferedUPos;
2926
VPos -= startX * bufferedVPos;
2927
startX = 0;
2928
}
2929
2930
uint16 *framebufferPtr = &frameBuffer[startX];
2931
frameBuffer += GFX_LINESIZE;
2932
int32 counter = posDifference;
2933
while (counter--) {
2934
if (UPos < 0)
2935
UPos = 0;
2936
if (VPos < 0)
2937
VPos = 0;
2938
uint16 index = pixels[(VPos >> 16 << shiftwidth) + (UPos >> 16)];
2939
if (index > 0)
2940
*framebufferPtr = ((activePalette[index] & 0xF7BC) >> 1) + ((*framebufferPtr & 0xF7BC) >> 1);
2941
framebufferPtr++;
2942
UPos += bufferedUPos;
2943
VPos += bufferedVPos;
2944
}
2945
}
2946
++faceTop;
2947
}
2948
}
2949
2950
void RSDK::Legacy::v3::DrawObjectAnimation(void *objScr, void *ent, int32 XPos, int32 YPos)
2951
{
2952
ObjectScript *objectScript = (ObjectScript *)objScr;
2953
Entity *entity = (Entity *)ent;
2954
SpriteAnimation *sprAnim = &animationList[objectScript->animFile->aniListOffset + entity->animation];
2955
SpriteFrame *frame = &animFrames[sprAnim->frameListOffset + entity->frame];
2956
int32 rotation = 0;
2957
2958
switch (sprAnim->rotationStyle) {
2959
case ROTSTYLE_NONE:
2960
switch (entity->direction) {
2961
case FLIP_NONE:
2962
DrawSpriteFlipped(frame->pivotX + XPos, frame->pivotY + YPos, frame->width, frame->height, frame->sprX, frame->sprY, FLIP_NONE,
2963
frame->sheetID);
2964
break;
2965
2966
case FLIP_X:
2967
DrawSpriteFlipped(XPos - frame->width - frame->pivotX, frame->pivotY + YPos, frame->width, frame->height, frame->sprX,
2968
frame->sprY, FLIP_X, frame->sheetID);
2969
break;
2970
case FLIP_Y:
2971
2972
DrawSpriteFlipped(frame->pivotX + XPos, YPos - frame->height - frame->pivotY, frame->width, frame->height, frame->sprX,
2973
frame->sprY, FLIP_Y, frame->sheetID);
2974
break;
2975
2976
case FLIP_XY:
2977
DrawSpriteFlipped(XPos - frame->width - frame->pivotX, YPos - frame->height - frame->pivotY, frame->width, frame->height,
2978
frame->sprX, frame->sprY, FLIP_XY, frame->sheetID);
2979
break;
2980
2981
default: break;
2982
}
2983
break;
2984
2985
case ROTSTYLE_FULL:
2986
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width, frame->height,
2987
entity->rotation, frame->sheetID);
2988
break;
2989
2990
case ROTSTYLE_45DEG:
2991
if (entity->rotation >= 0x100)
2992
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width,
2993
frame->height, 0x200 - ((0x214 - entity->rotation) >> 6 << 6), frame->sheetID);
2994
else
2995
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width,
2996
frame->height, (entity->rotation + 20) >> 6 << 6, frame->sheetID);
2997
break;
2998
2999
case ROTSTYLE_STATICFRAMES: {
3000
if (entity->rotation >= 0x100)
3001
rotation = 8 - ((532 - entity->rotation) >> 6);
3002
else
3003
rotation = (entity->rotation + 20) >> 6;
3004
int32 frameID = entity->frame;
3005
switch (rotation) {
3006
case 0: // 0 deg
3007
case 8: // 360 deg
3008
rotation = 0x00;
3009
break;
3010
3011
case 1: // 45 deg
3012
frameID += sprAnim->frameCount;
3013
if (entity->direction)
3014
rotation = 0;
3015
else
3016
rotation = 0x80;
3017
break;
3018
3019
case 2: // 90 deg
3020
rotation = 0x80;
3021
break;
3022
3023
case 3: // 135 deg
3024
frameID += sprAnim->frameCount;
3025
if (entity->direction)
3026
rotation = 0x80;
3027
else
3028
rotation = 0x100;
3029
break;
3030
3031
case 4: // 180 deg
3032
rotation = 0x100;
3033
break;
3034
3035
case 5: // 225 deg
3036
frameID += sprAnim->frameCount;
3037
if (entity->direction)
3038
rotation = 0x100;
3039
else
3040
rotation = 384;
3041
break;
3042
3043
case 6: // 270 deg
3044
rotation = 384;
3045
break;
3046
3047
case 7: // 315 deg
3048
frameID += sprAnim->frameCount;
3049
if (entity->direction)
3050
rotation = 384;
3051
else
3052
rotation = 0;
3053
break;
3054
3055
default: break;
3056
}
3057
3058
frame = &animFrames[sprAnim->frameListOffset + frameID];
3059
DrawSpriteRotated(entity->direction, XPos, YPos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY, frame->width, frame->height,
3060
rotation, frame->sheetID);
3061
break;
3062
}
3063
3064
default: break;
3065
}
3066
}
3067
3068
void RSDK::Legacy::DrawTextMenuEntry(void *menu, int32 rowID, int32 XPos, int32 YPos, int32 textHighlight)
3069
{
3070
TextMenu *tMenu = (TextMenu *)menu;
3071
int32 id = tMenu->entryStart[rowID];
3072
for (int32 i = 0; i < tMenu->entrySize[rowID]; ++i) {
3073
DrawSprite(XPos + (i << 3) - (((tMenu->entrySize[rowID] % 2) & (tMenu->alignment == 2)) * 4), YPos, 8, 8, ((tMenu->textData[id] & 0xF) << 3),
3074
((tMenu->textData[id] >> 4) << 3) + textHighlight, textMenuSurfaceNo);
3075
id++;
3076
}
3077
}
3078
void RSDK::Legacy::DrawStageTextEntry(void *menu, int32 rowID, int32 XPos, int32 YPos, int32 textHighlight)
3079
{
3080
TextMenu *tMenu = (TextMenu *)menu;
3081
int32 id = tMenu->entryStart[rowID];
3082
for (int32 i = 0; i < tMenu->entrySize[rowID]; ++i) {
3083
if (i == tMenu->entrySize[rowID] - 1) {
3084
DrawSprite(XPos + (i << 3), YPos, 8, 8, ((tMenu->textData[id] & 0xF) << 3), ((tMenu->textData[id] >> 4) << 3), textMenuSurfaceNo);
3085
}
3086
else {
3087
DrawSprite(XPos + (i << 3), YPos, 8, 8, ((tMenu->textData[id] & 0xF) << 3), ((tMenu->textData[id] >> 4) << 3) + textHighlight,
3088
textMenuSurfaceNo);
3089
}
3090
id++;
3091
}
3092
}
3093
void RSDK::Legacy::DrawBlendedTextMenuEntry(void *menu, int32 rowID, int32 XPos, int32 YPos, int32 textHighlight)
3094
{
3095
TextMenu *tMenu = (TextMenu *)menu;
3096
int32 id = tMenu->entryStart[rowID];
3097
for (int32 i = 0; i < tMenu->entrySize[rowID]; ++i) {
3098
DrawBlendedSprite(XPos + (i << 3), YPos, 8, 8, ((tMenu->textData[id] & 0xF) << 3), ((tMenu->textData[id] >> 4) << 3) + textHighlight,
3099
textMenuSurfaceNo);
3100
id++;
3101
}
3102
}
3103
void RSDK::Legacy::DrawTextMenu(void *menu, int32 XPos, int32 YPos)
3104
{
3105
TextMenu *tMenu = (TextMenu *)menu;
3106
int32 cnt = 0;
3107
3108
if (tMenu->visibleRowCount > 0) {
3109
cnt = (int32)(tMenu->visibleRowCount + tMenu->visibleRowOffset);
3110
}
3111
else {
3112
tMenu->visibleRowOffset = 0;
3113
cnt = (int32)tMenu->rowCount;
3114
}
3115
3116
if (tMenu->selectionCount == 3) {
3117
tMenu->selection2 = -1;
3118
for (int32 i = 0; i < tMenu->selection1 + 1; ++i) {
3119
if (tMenu->entryHighlight[i]) {
3120
tMenu->selection2 = i;
3121
}
3122
}
3123
}
3124
3125
switch (tMenu->alignment) {
3126
case 0:
3127
for (int32 i = (int32)tMenu->visibleRowOffset; i < cnt; ++i) {
3128
switch (tMenu->selectionCount) {
3129
case 1:
3130
if (i == tMenu->selection1)
3131
DrawTextMenuEntry(tMenu, i, XPos, YPos, 128);
3132
else
3133
DrawTextMenuEntry(tMenu, i, XPos, YPos, 0);
3134
break;
3135
3136
case 2:
3137
if (i == tMenu->selection1 || i == tMenu->selection2)
3138
DrawTextMenuEntry(tMenu, i, XPos, YPos, 128);
3139
else
3140
DrawTextMenuEntry(tMenu, i, XPos, YPos, 0);
3141
break;
3142
3143
case 3:
3144
if (i == tMenu->selection1)
3145
DrawTextMenuEntry(tMenu, i, XPos, YPos, 128);
3146
else
3147
DrawTextMenuEntry(tMenu, i, XPos, YPos, 0);
3148
3149
if (i == tMenu->selection2 && i != tMenu->selection1)
3150
DrawStageTextEntry(tMenu, i, XPos, YPos, 128);
3151
break;
3152
}
3153
YPos += 8;
3154
}
3155
break;
3156
3157
case 1:
3158
for (int32 i = (int32)tMenu->visibleRowOffset; i < cnt; ++i) {
3159
int32 entryX = XPos - (tMenu->entrySize[i] << 3);
3160
switch (tMenu->selectionCount) {
3161
case 1:
3162
if (i == tMenu->selection1)
3163
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3164
else
3165
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3166
break;
3167
3168
case 2:
3169
if (i == tMenu->selection1 || i == tMenu->selection2)
3170
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3171
else
3172
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3173
break;
3174
3175
case 3:
3176
if (i == tMenu->selection1)
3177
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3178
else
3179
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3180
3181
if (i == tMenu->selection2 && i != tMenu->selection1)
3182
DrawStageTextEntry(tMenu, i, entryX, YPos, 128);
3183
break;
3184
}
3185
YPos += 8;
3186
}
3187
break;
3188
3189
case 2:
3190
for (int32 i = (int32)tMenu->visibleRowOffset; i < cnt; ++i) {
3191
int32 entryX = XPos - (tMenu->entrySize[i] >> 1 << 3);
3192
switch (tMenu->selectionCount) {
3193
case 1:
3194
if (i == tMenu->selection1)
3195
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3196
else
3197
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3198
break;
3199
case 2:
3200
if (i == tMenu->selection1 || i == tMenu->selection2)
3201
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3202
else
3203
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3204
break;
3205
case 3:
3206
if (i == tMenu->selection1)
3207
DrawTextMenuEntry(tMenu, i, entryX, YPos, 128);
3208
else
3209
DrawTextMenuEntry(tMenu, i, entryX, YPos, 0);
3210
3211
if (i == tMenu->selection2 && i != tMenu->selection1)
3212
DrawStageTextEntry(tMenu, i, entryX, YPos, 128);
3213
break;
3214
}
3215
YPos += 8;
3216
}
3217
break;
3218
3219
default: break;
3220
}
3221
}
3222
3223