Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Scene/Scene.cpp
1163 views
1
#include "RSDK/Core/RetroEngine.hpp"
2
3
using namespace RSDK;
4
5
#if RETRO_REV0U
6
#include "Legacy/SceneLegacy.cpp"
7
#endif
8
9
uint8 RSDK::tilesetPixels[TILESET_SIZE * 4];
10
11
ScanlineInfo *RSDK::scanlines = NULL;
12
TileLayer RSDK::tileLayers[LAYER_COUNT];
13
CollisionMask RSDK::collisionMasks[CPATH_COUNT][TILE_COUNT * 4];
14
TileInfo RSDK::tileInfo[CPATH_COUNT][TILE_COUNT * 4];
15
16
#if RETRO_REV02
17
bool32 RSDK::forceHardReset = false;
18
#endif
19
char RSDK::currentSceneFolder[0x10];
20
char RSDK::currentSceneID[0x10];
21
22
SceneInfo RSDK::sceneInfo;
23
24
void RSDK::LoadSceneFolder()
25
{
26
#if RETRO_PLATFORM == RETRO_ANDROID
27
ShowLoadingIcon();
28
#endif
29
30
#if RETRO_USE_MOD_LOADER
31
// run this before the game actually unloads all the objects & scene assets
32
RunModCallbacks(MODCB_ONSTAGEUNLOAD, NULL);
33
#endif
34
35
sceneInfo.timeCounter = 0;
36
sceneInfo.minutes = 0;
37
sceneInfo.seconds = 0;
38
sceneInfo.milliseconds = 0;
39
40
// clear draw groups
41
for (int32 i = 0; i < DRAWGROUP_COUNT; ++i) {
42
drawGroups[i].entityCount = 0;
43
drawGroups[i].layerCount = 0;
44
}
45
46
// Clear Type groups
47
for (int32 i = 0; i < TYPEGROUP_COUNT; ++i) {
48
typeGroups[i].entryCount = 0;
49
}
50
51
#if RETRO_REV02
52
// Unload debug values
53
ClearViewableVariables();
54
55
// "unload" tint table
56
tintLookupTable = NULL;
57
#endif
58
59
// Unload TileLayers
60
for (int32 l = 0; l < LAYER_COUNT; ++l) {
61
MEM_ZERO(tileLayers[l]);
62
for (int32 c = 0; c < CAMERA_COUNT; ++c) tileLayers[l].drawGroup[c] = -1;
63
}
64
65
SceneListInfo *list = &sceneInfo.listCategory[sceneInfo.activeCategory];
66
#if RETRO_REV02
67
if (strcmp(currentSceneFolder, sceneInfo.listData[sceneInfo.listPos].folder) == 0 && !forceHardReset) {
68
// Reload
69
DefragmentAndGarbageCollectStorage(DATASET_STG);
70
sceneInfo.filter = sceneInfo.listData[sceneInfo.listPos].filter;
71
PrintLog(PRINT_NORMAL, "Reloading Scene \"%s - %s\" with filter %d", list->name, sceneInfo.listData[sceneInfo.listPos].name,
72
sceneInfo.listData[sceneInfo.listPos].filter);
73
74
#if RETRO_USE_MOD_LOADER
75
// reload object hooks
76
for (int32 h = 0; h < (int32)objectHookList.size(); ++h) {
77
for (int32 i = 0; i < objectClassCount; ++i) {
78
if (HASH_MATCH_MD5(objectClassList[i].hash, objectHookList[h].hash)) {
79
if (objectHookList[h].staticVars && objectClassList[i].staticVars)
80
*objectHookList[h].staticVars = *objectClassList[i].staticVars;
81
break;
82
}
83
}
84
}
85
#endif
86
87
return;
88
}
89
#endif
90
91
#if !RETRO_REV02
92
if (strcmp(currentSceneFolder, sceneInfo.listData[sceneInfo.listPos].folder) == 0) {
93
// Reload
94
DefragmentAndGarbageCollectStorage(DATASET_STG);
95
PrintLog(PRINT_NORMAL, "Reloading Scene \"%s - %s\"", list->name, sceneInfo.listData[sceneInfo.listPos].name);
96
97
#if RETRO_USE_MOD_LOADER
98
// reload object hooks
99
for (int32 h = 0; h < (int32)objectHookList.size(); ++h) {
100
for (int32 i = 0; i < objectClassCount; ++i) {
101
if (HASH_MATCH_MD5(objectClassList[i].hash, objectHookList[h].hash)) {
102
if (objectHookList[h].staticVars && objectClassList[i].staticVars)
103
*objectHookList[h].staticVars = *objectClassList[i].staticVars;
104
break;
105
}
106
}
107
}
108
#endif
109
return;
110
}
111
#endif
112
113
// Unload stage 3DScenes & models
114
Clear3DScenes();
115
116
// Unload stage sprite animations
117
ClearSpriteAnimations();
118
119
// Unload stage surfaces
120
ClearGfxSurfaces();
121
122
// Unload stage sfx & audio channels
123
ClearStageSfx();
124
125
// Unload stage objects
126
ClearStageObjects();
127
128
// Clear draw groups
129
for (int32 l = 0; l < DRAWGROUP_COUNT; ++l) {
130
MEM_ZERO(drawGroups[l]);
131
drawGroups[l].sorted = false;
132
}
133
134
// Clear stage storage
135
DefragmentAndGarbageCollectStorage(DATASET_STG);
136
DefragmentAndGarbageCollectStorage(DATASET_SFX);
137
138
for (int32 s = 0; s < SCREEN_COUNT; ++s) {
139
screens[s].position.x = 0;
140
screens[s].position.y = 0;
141
}
142
143
SceneListEntry *sceneEntry = &sceneInfo.listData[sceneInfo.listPos];
144
strcpy(currentSceneFolder, sceneEntry->folder);
145
146
#if RETRO_REV02
147
forceHardReset = false;
148
sceneInfo.filter = sceneEntry->filter;
149
PrintLog(PRINT_NORMAL, "Loading Scene \"%s - %s\" with filter %d", list->name, sceneEntry->name, sceneEntry->filter);
150
#endif
151
152
#if !RETRO_REV02
153
PrintLog(PRINT_NORMAL, "Loading Scene \"%s - %s\"", list->name, sceneEntry->name);
154
#endif
155
156
char fullFilePath[0x40];
157
158
// Load TileConfig
159
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Stages/%s/TileConfig.bin", currentSceneFolder);
160
LoadTileConfig(fullFilePath);
161
162
// Load StageConfig
163
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Stages/%s/StageConfig.bin", currentSceneFolder);
164
165
FileInfo info;
166
InitFileInfo(&info);
167
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
168
uint32 sig = ReadInt32(&info, false);
169
170
if (sig != RSDK_SIGNATURE_CFG) {
171
CloseFile(&info);
172
return;
173
}
174
175
sceneInfo.useGlobalObjects = ReadInt8(&info);
176
sceneInfo.classCount = 0;
177
178
if (sceneInfo.useGlobalObjects) {
179
for (int32 o = 0; o < globalObjectCount; ++o) stageObjectIDs[o] = globalObjectIDs[o];
180
sceneInfo.classCount = globalObjectCount;
181
}
182
else {
183
for (int32 o = 0; o < TYPE_DEFAULT_COUNT; ++o) stageObjectIDs[o] = globalObjectIDs[o];
184
185
sceneInfo.classCount = TYPE_DEFAULT_COUNT;
186
}
187
188
uint8 objectCount = ReadInt8(&info);
189
for (int32 o = 0; o < objectCount; ++o) {
190
ReadString(&info, textBuffer);
191
192
RETRO_HASH_MD5(hash);
193
GEN_HASH_MD5_BUFFER(textBuffer, hash);
194
195
stageObjectIDs[sceneInfo.classCount] = 0;
196
for (int32 id = 0; id < objectClassCount; ++id) {
197
if (HASH_MATCH_MD5(hash, objectClassList[id].hash)) {
198
stageObjectIDs[sceneInfo.classCount] = id;
199
sceneInfo.classCount++;
200
}
201
}
202
}
203
204
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
205
ObjectClass *objClass = &objectClassList[stageObjectIDs[o]];
206
if (objClass->staticVars && !*objClass->staticVars) {
207
AllocateStorage((void **)objClass->staticVars, objClass->staticClassSize, DATASET_STG, true);
208
209
#if RETRO_REV0U
210
if (objClass->staticLoad)
211
objClass->staticLoad(*objClass->staticVars);
212
else
213
LoadStaticVariables((uint8 *)*objClass->staticVars, objClass->hash, sizeof(Object));
214
215
#else
216
LoadStaticVariables((uint8 *)*objClass->staticVars, objClass->hash, sizeof(Object));
217
#endif
218
219
#if RETRO_USE_MOD_LOADER
220
// even though the static load event is rev0U only, this point in the engine is "static loading"
221
RunModCallbacks(MODCB_ONSTATICLOAD, (void *)objClass);
222
#endif
223
224
#if RETRO_USE_MOD_LOADER
225
for (ModInfo &mod : modList) {
226
if (mod.staticVars.find(objClass->hash) != mod.staticVars.end()) {
227
auto sVars = mod.staticVars.at(objClass->hash);
228
RegisterStaticVariables((void **)sVars.staticVars, sVars.name.c_str(), sVars.size);
229
}
230
}
231
#endif
232
233
(*objClass->staticVars)->classID = o;
234
if (o >= TYPE_DEFAULT_COUNT)
235
(*objClass->staticVars)->active = ACTIVE_NORMAL;
236
}
237
}
238
239
for (int32 p = 0; p < PALETTE_BANK_COUNT; ++p) {
240
activeStageRows[p] = ReadInt16(&info);
241
242
for (int32 r = 0; r < 0x10; ++r) {
243
if ((activeStageRows[p] >> r & 1)) {
244
for (int32 c = 0; c < 0x10; ++c) {
245
uint8 red = ReadInt8(&info);
246
uint8 green = ReadInt8(&info);
247
uint8 blue = ReadInt8(&info);
248
stagePalette[p][(r << 4) + c] = rgb32To16_B[blue] | rgb32To16_G[green] | rgb32To16_R[red];
249
}
250
}
251
else {
252
for (int32 c = 0; c < 0x10; ++c) stagePalette[p][(r << 4) + c] = 0;
253
}
254
}
255
}
256
257
uint8 sfxCount = ReadInt8(&info);
258
char sfxPath[0x100];
259
for (int32 i = 0; i < sfxCount; ++i) {
260
ReadString(&info, sfxPath);
261
uint8 maxConcurrentPlays = ReadInt8(&info);
262
LoadSfx(sfxPath, maxConcurrentPlays, SCOPE_STAGE);
263
}
264
265
CloseFile(&info);
266
}
267
268
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Stages/%s/16x16Tiles.gif", currentSceneFolder);
269
LoadStageGIF(fullFilePath);
270
271
#if RETRO_USE_MOD_LOADER
272
for (int32 h = 0; h < (int32)objectHookList.size(); ++h) {
273
for (int32 i = 0; i < objectClassCount; ++i) {
274
if (HASH_MATCH_MD5(objectClassList[i].hash, objectHookList[h].hash)) {
275
if (objectHookList[h].staticVars && objectClassList[i].staticVars)
276
*objectHookList[h].staticVars = *objectClassList[i].staticVars;
277
break;
278
}
279
}
280
}
281
#endif
282
}
283
void RSDK::LoadSceneAssets()
284
{
285
#if RETRO_PLATFORM == RETRO_ANDROID
286
ShowLoadingIcon();
287
#endif
288
289
memset(objectEntityList, 0, ENTITY_COUNT * sizeof(EntityBase));
290
291
SceneListEntry *sceneEntry = &sceneInfo.listData[sceneInfo.listPos];
292
char fullFilePath[0x40];
293
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Stages/%s/Scene%s.bin", currentSceneFolder, sceneEntry->id);
294
295
dataStorage[DATASET_TMP].usedStorage = 0;
296
297
for (int32 s = 0; s < SCREEN_COUNT; ++s) screens[s].waterDrawPos = screens[s].size.y;
298
299
if (screens[0].size.y > 0)
300
memset(gfxLineBuffer, 0, screens[0].size.y * sizeof(uint8));
301
302
memset(tileLayers, 0, LAYER_COUNT * sizeof(TileLayer));
303
304
// Reload palette
305
for (int32 b = 0; b < 8; ++b) {
306
for (int32 r = 0; r < 0x10; ++r) {
307
if ((activeGlobalRows[b] >> r & 1)) {
308
for (int32 c = 0; c < 0x10; ++c) fullPalette[b][(r << 4) + c] = globalPalette[b][(r << 4) + c];
309
}
310
311
if ((activeStageRows[b] >> r & 1)) {
312
for (int32 c = 0; c < 0x10; ++c) fullPalette[b][(r << 4) + c] = stagePalette[b][(r << 4) + c];
313
}
314
}
315
}
316
317
FileInfo info;
318
InitFileInfo(&info);
319
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
320
uint32 sig = ReadInt32(&info, false);
321
322
if (sig != RSDK_SIGNATURE_SCN) {
323
CloseFile(&info);
324
return;
325
}
326
327
// Editor Metadata
328
329
// I'm leaving this section here so that the "format" can be documented, since the official code is 3 lines and just skips it lol
330
331
/*
332
uint8 unknown1 = ReadInt8(&info); // usually 3, sometimes 4, LRZ1 (old) is 2
333
334
uint8 b = ReadInt8(&info);
335
uint8 g = ReadInt8(&info);
336
uint8 r = ReadInt8(&info);
337
uint8 a = ReadInt8(&info);
338
color backgroundColor1 = (a << 24) | (r << 16) | (g << 8) | (b << 0);
339
340
b = ReadInt8(&info);
341
g = ReadInt8(&info);
342
r = ReadInt8(&info);
343
a = ReadInt8(&info);
344
color backgroundColor2 = (a << 24) | (r << 16) | (g << 8) | (b << 0);
345
346
uint8 unknown2 = ReadInt8(&info); // always 1 afaik
347
uint8 unknown3 = ReadInt8(&info); // always 1 afaik
348
uint8 unknown4 = ReadInt8(&info); // always 4 afaik
349
uint8 unknown5 = ReadInt8(&info); // always 0 afaik
350
uint8 unknown6 = ReadInt8(&info); // always 1 afaik
351
uint8 unknown7 = ReadInt8(&info); // always 4 afaik
352
uint8 unknown8 = ReadInt8(&info); // always 0 afaik
353
354
char stampName[0x20];
355
ReadString(&info, stampName);
356
357
uint8 unknown9 = ReadInt8(&info); // usually 3, 4, or 5
358
*/
359
360
// Skip over Metadata, since we won't be using it at all in-game
361
Seek_Cur(&info, 0x10);
362
uint8 strLen = ReadInt8(&info);
363
Seek_Cur(&info, strLen + 1);
364
365
// Tile Layers
366
uint8 layerCount = ReadInt8(&info);
367
for (int32 l = 0; l < layerCount; ++l) {
368
TileLayer *layer = &tileLayers[l];
369
370
// Tests in RetroED & comparing images of the RSDKv5 editor we have puts this as the most likely use for this (otherwise unused) variable
371
bool32 visibleInEditor = ReadInt8(&info) != 0;
372
(void)visibleInEditor; // unused
373
374
ReadString(&info, textBuffer);
375
GEN_HASH_MD5_BUFFER(textBuffer, layer->name);
376
377
layer->type = ReadInt8(&info);
378
layer->drawGroup[0] = ReadInt8(&info);
379
for (int32 s = 1; s < CAMERA_COUNT; ++s) layer->drawGroup[s] = layer->drawGroup[0];
380
381
layer->xsize = ReadInt16(&info);
382
int32 shift = 1;
383
int32 shift2 = 1;
384
int32 val = 0;
385
do {
386
shift = shift2;
387
val = 1 << shift2++;
388
} while (val < layer->xsize);
389
layer->widthShift = shift;
390
391
layer->ysize = ReadInt16(&info);
392
shift = 1;
393
shift2 = 1;
394
val = 0;
395
do {
396
shift = shift2;
397
val = 1 << shift2++;
398
} while (val < layer->ysize);
399
layer->heightShift = shift;
400
401
layer->parallaxFactor = ReadInt16(&info);
402
layer->scrollSpeed = ReadInt16(&info) << 8;
403
layer->scrollPos = 0;
404
405
layer->layout = NULL;
406
if (layer->xsize || layer->ysize) {
407
AllocateStorage((void **)&layer->layout, sizeof(uint16) * (1UL << layer->widthShift) * (1UL << layer->heightShift), DATASET_STG, true);
408
memset(layer->layout, 0xFF, sizeof(uint16) * (1UL << layer->widthShift) * (1UL << layer->heightShift));
409
}
410
411
int32 size = layer->xsize;
412
if (size <= layer->ysize)
413
size = layer->ysize;
414
AllocateStorage((void **)&layer->lineScroll, TILE_SIZE * size, DATASET_STG, true);
415
416
layer->scrollInfoCount = ReadInt16(&info);
417
for (int32 s = 0; s < layer->scrollInfoCount; ++s) {
418
layer->scrollInfo[s].parallaxFactor = ReadInt16(&info);
419
layer->scrollInfo[s].scrollSpeed = ReadInt16(&info) << 8;
420
layer->scrollInfo[s].scrollPos = 0;
421
layer->scrollInfo[s].tilePos = 0;
422
layer->scrollInfo[s].deform = ReadInt8(&info);
423
424
// this isn't used anywhere in-engine, and is never set in the files. so as you might expect, no one knows what it is for!
425
layer->scrollInfo[s].unknown = ReadInt8(&info);
426
}
427
428
uint8 *scrollIndexes = NULL;
429
ReadCompressed(&info, (uint8 **)&scrollIndexes);
430
memcpy(layer->lineScroll, scrollIndexes, TILE_SIZE * size * sizeof(uint8));
431
#if !RETRO_USE_ORIGINAL_CODE
432
RemoveStorageEntry((void **)&scrollIndexes);
433
#endif
434
scrollIndexes = NULL;
435
436
uint8 *tileLayout = NULL;
437
ReadCompressed(&info, (uint8 **)&tileLayout);
438
439
int32 id = 0;
440
for (int32 y = 0; y < layer->ysize; ++y) {
441
for (int32 x = 0; x < layer->xsize; ++x) {
442
layer->layout[x + (y << layer->widthShift)] = (tileLayout[id + 1] << 8) + tileLayout[id + 0];
443
id += 2;
444
}
445
}
446
447
#if !RETRO_USE_ORIGINAL_CODE
448
RemoveStorageEntry((void **)&tileLayout);
449
#endif
450
tileLayout = NULL;
451
}
452
453
// Objects
454
uint8 objectCount = ReadInt8(&info);
455
editableVarList = NULL;
456
AllocateStorage((void **)&editableVarList, sizeof(EditableVarInfo) * EDITABLEVAR_COUNT, DATASET_TMP, false);
457
458
#if RETRO_REV02
459
EntityBase *tempEntityList = NULL;
460
AllocateStorage((void **)&tempEntityList, SCENEENTITY_COUNT * sizeof(EntityBase), DATASET_TMP, true);
461
#endif
462
463
for (int32 i = 0; i < objectCount; ++i) {
464
RETRO_HASH_MD5(objHash);
465
objHash[0] = ReadInt32(&info, false);
466
objHash[1] = ReadInt32(&info, false);
467
objHash[2] = ReadInt32(&info, false);
468
objHash[3] = ReadInt32(&info, false);
469
470
int32 classID = 0;
471
for (int32 o = 0; o < sceneInfo.classCount; ++o) {
472
if (HASH_MATCH_MD5(objHash, objectClassList[stageObjectIDs[o]].hash)) {
473
classID = o;
474
break;
475
}
476
}
477
478
#if !RETRO_USE_ORIGINAL_CODE
479
if (!classID && i >= TYPE_DEFAULT_COUNT)
480
PrintLog(PRINT_NORMAL, "Object Class %d is unimplemented!", i);
481
#endif
482
483
ObjectClass *objectClass = &objectClassList[stageObjectIDs[classID]];
484
485
uint8 varCount = ReadInt8(&info);
486
EditableVarInfo *varList = NULL;
487
AllocateStorage((void **)&varList, sizeof(EditableVarInfo) * varCount, DATASET_TMP, false);
488
editableVarCount = 0;
489
if (classID) {
490
#if RETRO_REV02
491
SetEditableVar(VAR_UINT8, "filter", classID, offsetof(Entity, filter));
492
#endif
493
494
#if RETRO_USE_MOD_LOADER
495
currentObjectID = classID;
496
#endif
497
498
if (objectClass->serialize)
499
objectClass->serialize();
500
}
501
502
for (int32 e = 1; e < varCount; ++e) {
503
RETRO_HASH_MD5(varHash);
504
varHash[0] = ReadInt32(&info, false);
505
varHash[1] = ReadInt32(&info, false);
506
varHash[2] = ReadInt32(&info, false);
507
varHash[3] = ReadInt32(&info, false);
508
509
int32 varID = 0;
510
MEM_ZERO(varList[e]);
511
for (int32 v = 0; v < editableVarCount; ++v) {
512
if (HASH_MATCH_MD5(varHash, editableVarList[v].hash)) {
513
varID = v;
514
HASH_COPY_MD5(varList[e].hash, editableVarList[v].hash);
515
varList[e].offset = editableVarList[v].offset;
516
varList[e].active = true;
517
break;
518
}
519
}
520
521
editableVarList[varID].type = varList[e].type = ReadInt8(&info);
522
}
523
524
uint16 entityCount = ReadInt16(&info);
525
for (int32 e = 0; e < entityCount; ++e) {
526
uint16 slotID = ReadInt16(&info);
527
528
EntityBase *entity = NULL;
529
530
#if RETRO_REV02
531
if (slotID < SCENEENTITY_COUNT)
532
entity = &objectEntityList[slotID + RESERVE_ENTITY_COUNT];
533
else
534
entity = &tempEntityList[slotID - SCENEENTITY_COUNT];
535
#else
536
entity = &objectEntityList[slotID + RESERVE_ENTITY_COUNT];
537
#endif
538
539
entity->classID = classID;
540
#if RETRO_REV02
541
entity->filter = 0xFF;
542
#endif
543
entity->position.x = ReadInt32(&info, false);
544
entity->position.y = ReadInt32(&info, false);
545
546
uint8 *entityBuffer = (uint8 *)entity;
547
548
uint8 tempBuffer[0x10];
549
for (int32 v = 1; v < varCount; ++v) {
550
switch (varList[v].type) {
551
case VAR_UINT8:
552
case VAR_INT8:
553
if (varList[v].active)
554
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(int8));
555
else
556
ReadBytes(&info, tempBuffer, sizeof(int8));
557
break;
558
559
case VAR_UINT16:
560
case VAR_INT16:
561
if (varList[v].active)
562
#if !RETRO_USE_ORIGINAL_CODE
563
*(int16 *)&entityBuffer[varList[v].offset] = ReadInt16(&info);
564
#else
565
// This only works as intended on little-endian CPUs.
566
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(int16));
567
#endif
568
else
569
ReadBytes(&info, tempBuffer, sizeof(int16));
570
break;
571
572
case VAR_UINT32:
573
case VAR_INT32:
574
if (varList[v].active)
575
#if !RETRO_USE_ORIGINAL_CODE
576
*(int32 *)&entityBuffer[varList[v].offset] = ReadInt32(&info, false);
577
#else
578
// This only works as intended on little-endian CPUs.
579
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(int32));
580
#endif
581
else
582
ReadBytes(&info, tempBuffer, sizeof(int32));
583
break;
584
585
// not entirely sure on specifics here, should always be sizeof(int32) but it having a unique type implies it isn't always
586
case VAR_ENUM:
587
if (varList[v].active)
588
#if !RETRO_USE_ORIGINAL_CODE
589
*(int32 *)&entityBuffer[varList[v].offset] = ReadInt32(&info, false);
590
#else
591
// This only works as intended on little-endian CPUs.
592
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(int32));
593
#endif
594
else
595
ReadBytes(&info, tempBuffer, sizeof(int32));
596
break;
597
598
case VAR_BOOL:
599
if (varList[v].active)
600
#if !RETRO_USE_ORIGINAL_CODE
601
*(bool32 *)&entityBuffer[varList[v].offset] = (bool32)ReadInt32(&info, false);
602
#else
603
// This only works as intended on little-endian CPUs.
604
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(bool32));
605
#endif
606
else
607
ReadBytes(&info, tempBuffer, sizeof(bool32));
608
break;
609
610
case VAR_STRING:
611
if (varList[v].active) {
612
String *string = (String *)&entityBuffer[varList[v].offset];
613
uint16 len = ReadInt16(&info);
614
615
InitString(string, "", len);
616
for (string->length = 0; string->length < len; ++string->length) string->chars[string->length] = ReadInt16(&info);
617
}
618
else {
619
Seek_Cur(&info, ReadInt16(&info) * sizeof(uint16));
620
}
621
break;
622
623
case VAR_VECTOR2:
624
if (varList[v].active) {
625
#if !RETRO_USE_ORIGINAL_CODE
626
*(int32 *)&entityBuffer[varList[v].offset] = ReadInt32(&info, false);
627
*(int32 *)&entityBuffer[varList[v].offset + sizeof(int32)] = ReadInt32(&info, false);
628
#else
629
// This only works as intended on little-endian CPUs.
630
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(int32));
631
ReadBytes(&info, &entityBuffer[varList[v].offset + sizeof(int32)], sizeof(int32));
632
#endif
633
}
634
else {
635
ReadBytes(&info, tempBuffer, sizeof(int32)); // x
636
ReadBytes(&info, tempBuffer, sizeof(int32)); // y
637
}
638
break;
639
640
// Never used in mania so we don't know for sure, but it's our best guess!
641
case VAR_FLOAT:
642
if (varList[v].active)
643
#if !RETRO_USE_ORIGINAL_CODE
644
*(float *)&entityBuffer[varList[v].offset] = ReadSingle(&info);
645
#else
646
// This only works as intended on little-endian CPUs.
647
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(float));
648
#endif
649
else
650
ReadBytes(&info, tempBuffer, sizeof(float));
651
break;
652
653
case VAR_COLOR:
654
if (varList[v].active)
655
#if !RETRO_USE_ORIGINAL_CODE
656
*(color *)&entityBuffer[varList[v].offset] = ReadInt32(&info, false);
657
#else
658
// This only works as intended on little-endian CPUs.
659
ReadBytes(&info, &entityBuffer[varList[v].offset], sizeof(color));
660
#endif
661
else
662
ReadBytes(&info, tempBuffer, sizeof(color));
663
break;
664
}
665
}
666
}
667
668
#if !RETRO_USE_ORIGINAL_CODE
669
RemoveStorageEntry((void **)&varList);
670
varList = NULL;
671
#endif
672
}
673
674
#if RETRO_REV02
675
// handle filter and stuff
676
EntityBase *entity = &objectEntityList[RESERVE_ENTITY_COUNT];
677
int32 activeSlot = RESERVE_ENTITY_COUNT;
678
for (int32 i = RESERVE_ENTITY_COUNT; i < SCENEENTITY_COUNT + RESERVE_ENTITY_COUNT; ++i) {
679
if (sceneInfo.filter & entity->filter) {
680
if (i != activeSlot) {
681
memcpy(&objectEntityList[activeSlot], entity, sizeof(EntityBase));
682
memset(entity, 0, sizeof(EntityBase));
683
}
684
685
++activeSlot;
686
}
687
else {
688
memset(entity, 0, sizeof(EntityBase));
689
}
690
691
entity++;
692
}
693
694
for (int32 i = 0; i < SCENEENTITY_COUNT; ++i) {
695
if (sceneInfo.filter & tempEntityList[i].filter)
696
memcpy(&objectEntityList[activeSlot++], &tempEntityList[i], sizeof(EntityBase));
697
698
if (activeSlot >= SCENEENTITY_COUNT + RESERVE_ENTITY_COUNT)
699
break;
700
}
701
702
#if !RETRO_USE_ORIGINAL_CODE
703
RemoveStorageEntry((void **)&tempEntityList);
704
#endif
705
tempEntityList = NULL;
706
#endif
707
708
#if !RETRO_USE_ORIGINAL_CODE
709
RemoveStorageEntry((void **)&editableVarList);
710
#endif
711
editableVarList = NULL;
712
713
CloseFile(&info);
714
}
715
#if RETRO_USE_MOD_LOADER
716
LoadGameXML(true); // override the stage palette *somewhere* idfk
717
#endif
718
}
719
void RSDK::LoadTileConfig(char *filepath)
720
{
721
FileInfo info;
722
InitFileInfo(&info);
723
724
if (LoadFile(&info, filepath, FMODE_RB)) {
725
uint32 sig = ReadInt32(&info, false);
726
if (sig != RSDK_SIGNATURE_TIL) {
727
CloseFile(&info);
728
return;
729
}
730
731
uint8 *buffer = NULL;
732
ReadCompressed(&info, &buffer);
733
734
int32 bufPos = 0;
735
for (int32 p = 0; p < CPATH_COUNT; ++p) {
736
// No Flip/Stored in file
737
for (int32 t = 0; t < TILE_COUNT; ++t) {
738
uint8 maskHeights[0x10];
739
uint8 maskActive[0x10];
740
741
memcpy(maskHeights, buffer + bufPos, TILE_SIZE * sizeof(uint8));
742
bufPos += TILE_SIZE;
743
memcpy(maskActive, buffer + bufPos, TILE_SIZE * sizeof(uint8));
744
bufPos += TILE_SIZE;
745
746
bool32 yFlip = buffer[bufPos++];
747
tileInfo[p][t].floorAngle = buffer[bufPos++];
748
tileInfo[p][t].lWallAngle = buffer[bufPos++];
749
tileInfo[p][t].rWallAngle = buffer[bufPos++];
750
tileInfo[p][t].roofAngle = buffer[bufPos++];
751
tileInfo[p][t].flag = buffer[bufPos++];
752
753
if (yFlip) {
754
for (int32 c = 0; c < TILE_SIZE; c++) {
755
if (maskActive[c]) {
756
collisionMasks[p][t].floorMasks[c] = 0x00;
757
collisionMasks[p][t].roofMasks[c] = maskHeights[c];
758
}
759
else {
760
collisionMasks[p][t].floorMasks[c] = 0xFF;
761
collisionMasks[p][t].roofMasks[c] = 0xFF;
762
}
763
}
764
765
// LWall rotations
766
for (int32 c = 0; c < TILE_SIZE; ++c) {
767
int32 h = 0;
768
while (true) {
769
if (h == TILE_SIZE) {
770
collisionMasks[p][t].lWallMasks[c] = 0xFF;
771
break;
772
}
773
774
uint8 m = collisionMasks[p][t].roofMasks[h];
775
if (m != 0xFF && c <= m) {
776
collisionMasks[p][t].lWallMasks[c] = h;
777
break;
778
}
779
else {
780
++h;
781
if (h <= -1)
782
break;
783
}
784
}
785
}
786
787
// RWall rotations
788
for (int32 c = 0; c < TILE_SIZE; ++c) {
789
int32 h = TILE_SIZE - 1;
790
while (true) {
791
if (h == -1) {
792
collisionMasks[p][t].rWallMasks[c] = 0xFF;
793
break;
794
}
795
796
uint8 m = collisionMasks[p][t].roofMasks[h];
797
if (m != 0xFF && c <= m) {
798
collisionMasks[p][t].rWallMasks[c] = h;
799
break;
800
}
801
else {
802
--h;
803
if (h >= TILE_SIZE)
804
break;
805
}
806
}
807
}
808
}
809
else // Regular Tile
810
{
811
// Collision heights
812
for (int32 c = 0; c < TILE_SIZE; ++c) {
813
if (maskActive[c]) {
814
collisionMasks[p][t].floorMasks[c] = maskHeights[c];
815
collisionMasks[p][t].roofMasks[c] = 0x0F;
816
}
817
else {
818
collisionMasks[p][t].floorMasks[c] = 0xFF;
819
collisionMasks[p][t].roofMasks[c] = 0xFF;
820
}
821
}
822
823
// LWall rotations
824
for (int32 c = 0; c < TILE_SIZE; ++c) {
825
int32 h = 0;
826
while (true) {
827
if (h == TILE_SIZE) {
828
collisionMasks[p][t].lWallMasks[c] = 0xFF;
829
break;
830
}
831
832
uint8 m = collisionMasks[p][t].floorMasks[h];
833
if (m != 0xFF && c >= m) {
834
collisionMasks[p][t].lWallMasks[c] = h;
835
break;
836
}
837
else {
838
++h;
839
if (h <= -1)
840
break;
841
}
842
}
843
}
844
845
// RWall rotations
846
for (int32 c = 0; c < TILE_SIZE; ++c) {
847
int32 h = TILE_SIZE - 1;
848
while (true) {
849
if (h == -1) {
850
collisionMasks[p][t].rWallMasks[c] = 0xFF;
851
break;
852
}
853
854
uint8 m = collisionMasks[p][t].floorMasks[h];
855
if (m != 0xFF && c >= m) {
856
collisionMasks[p][t].rWallMasks[c] = h;
857
break;
858
}
859
else {
860
--h;
861
if (h >= TILE_SIZE)
862
break;
863
}
864
}
865
}
866
}
867
}
868
869
// FlipX
870
for (int32 t = 0; t < TILE_COUNT; ++t) {
871
int32 off = (FLIP_X * TILE_COUNT);
872
tileInfo[p][t + off].flag = tileInfo[p][t].flag;
873
tileInfo[p][t + off].floorAngle = -tileInfo[p][t].floorAngle;
874
tileInfo[p][t + off].lWallAngle = -tileInfo[p][t].rWallAngle;
875
tileInfo[p][t + off].roofAngle = -tileInfo[p][t].roofAngle;
876
tileInfo[p][t + off].rWallAngle = -tileInfo[p][t].lWallAngle;
877
878
for (int32 c = 0; c < TILE_SIZE; ++c) {
879
int32 h = collisionMasks[p][t].lWallMasks[c];
880
if (h == 0xFF)
881
collisionMasks[p][t + off].rWallMasks[c] = 0xFF;
882
else
883
collisionMasks[p][t + off].rWallMasks[c] = 0xF - h;
884
885
h = collisionMasks[p][t].rWallMasks[c];
886
if (h == 0xFF)
887
collisionMasks[p][t + off].lWallMasks[c] = 0xFF;
888
else
889
collisionMasks[p][t + off].lWallMasks[c] = 0xF - h;
890
891
collisionMasks[p][t + off].floorMasks[c] = collisionMasks[p][t].floorMasks[0xF - c];
892
collisionMasks[p][t + off].roofMasks[c] = collisionMasks[p][t].roofMasks[0xF - c];
893
}
894
}
895
896
// FlipY
897
for (int32 t = 0; t < TILE_COUNT; ++t) {
898
int32 off = (FLIP_Y * TILE_COUNT);
899
tileInfo[p][t + off].flag = tileInfo[p][t].flag;
900
tileInfo[p][t + off].floorAngle = -0x80 - tileInfo[p][t].roofAngle;
901
tileInfo[p][t + off].lWallAngle = -0x80 - tileInfo[p][t].lWallAngle;
902
tileInfo[p][t + off].roofAngle = -0x80 - tileInfo[p][t].floorAngle;
903
tileInfo[p][t + off].rWallAngle = -0x80 - tileInfo[p][t].rWallAngle;
904
905
for (int32 c = 0; c < TILE_SIZE; ++c) {
906
int32 h = collisionMasks[p][t].roofMasks[c];
907
if (h == 0xFF)
908
collisionMasks[p][t + off].floorMasks[c] = 0xFF;
909
else
910
collisionMasks[p][t + off].floorMasks[c] = 0xF - h;
911
912
h = collisionMasks[p][t].floorMasks[c];
913
if (h == 0xFF)
914
collisionMasks[p][t + off].roofMasks[c] = 0xFF;
915
else
916
collisionMasks[p][t + off].roofMasks[c] = 0xF - h;
917
918
collisionMasks[p][t + off].lWallMasks[c] = collisionMasks[p][t].lWallMasks[0xF - c];
919
collisionMasks[p][t + off].rWallMasks[c] = collisionMasks[p][t].rWallMasks[0xF - c];
920
}
921
}
922
923
// FlipXY
924
for (int32 t = 0; t < TILE_COUNT; ++t) {
925
int32 off = (FLIP_XY * TILE_COUNT);
926
int32 offY = (FLIP_Y * TILE_COUNT);
927
tileInfo[p][t + off].flag = tileInfo[p][t + offY].flag;
928
tileInfo[p][t + off].floorAngle = -tileInfo[p][t + offY].floorAngle;
929
tileInfo[p][t + off].lWallAngle = -tileInfo[p][t + offY].rWallAngle;
930
tileInfo[p][t + off].roofAngle = -tileInfo[p][t + offY].roofAngle;
931
tileInfo[p][t + off].rWallAngle = -tileInfo[p][t + offY].lWallAngle;
932
933
for (int32 c = 0; c < TILE_SIZE; ++c) {
934
int32 h = collisionMasks[p][t + offY].lWallMasks[c];
935
if (h == 0xFF)
936
collisionMasks[p][t + off].rWallMasks[c] = 0xFF;
937
else
938
collisionMasks[p][t + off].rWallMasks[c] = 0xF - h;
939
940
h = collisionMasks[p][t + offY].rWallMasks[c];
941
if (h == 0xFF)
942
collisionMasks[p][t + off].lWallMasks[c] = 0xFF;
943
else
944
collisionMasks[p][t + off].lWallMasks[c] = 0xF - h;
945
946
collisionMasks[p][t + off].floorMasks[c] = collisionMasks[p][t + offY].floorMasks[0xF - c];
947
collisionMasks[p][t + off].roofMasks[c] = collisionMasks[p][t + offY].roofMasks[0xF - c];
948
}
949
}
950
}
951
952
#if !RETRO_USE_ORIGINAL_CODE
953
RemoveStorageEntry((void **)&buffer);
954
buffer = NULL;
955
#endif
956
CloseFile(&info);
957
}
958
}
959
void RSDK::LoadStageGIF(char *filepath)
960
{
961
ImageGIF tileset;
962
963
if (tileset.Load(filepath, true) && tileset.width == TILE_SIZE && tileset.height <= TILE_COUNT * TILE_SIZE) {
964
tileset.pixels = tilesetPixels;
965
tileset.Load(NULL, false);
966
967
for (int32 r = 0; r < 0x10; ++r) {
968
// only overwrite inactive rows
969
if (!(activeStageRows[0] >> r & 1) && !(activeGlobalRows[0] >> r & 1)) {
970
for (int32 c = 0; c < 0x10; ++c) {
971
uint8 red = (tileset.palette[(r << 4) + c] >> 0x10);
972
uint8 green = (tileset.palette[(r << 4) + c] >> 0x08);
973
uint8 blue = (tileset.palette[(r << 4) + c] >> 0x00);
974
fullPalette[0][(r << 4) + c] = rgb32To16_B[blue] | rgb32To16_G[green] | rgb32To16_R[red];
975
}
976
}
977
}
978
979
// Flip X
980
uint8 *srcPixels = tilesetPixels;
981
uint8 *dstPixels = &tilesetPixels[(FLIP_X * TILESET_SIZE) + (TILE_SIZE - 1)];
982
for (int32 t = 0; t < 0x400 * TILE_SIZE; ++t) {
983
for (int32 r = 0; r < TILE_SIZE; ++r) {
984
*dstPixels-- = *srcPixels++;
985
}
986
987
dstPixels += (TILE_SIZE * 2);
988
}
989
990
// Flip Y
991
srcPixels = tilesetPixels;
992
for (int32 t = 0; t < 0x400; ++t) {
993
dstPixels = &tilesetPixels[(FLIP_Y * TILESET_SIZE) + (t * TILE_DATASIZE) + (TILE_DATASIZE - TILE_SIZE)];
994
for (int32 y = 0; y < TILE_SIZE; ++y) {
995
for (int32 x = 0; x < TILE_SIZE; ++x) {
996
*dstPixels++ = *srcPixels++;
997
}
998
999
dstPixels -= (TILE_SIZE * 2);
1000
}
1001
}
1002
1003
// Flip XY
1004
srcPixels = &tilesetPixels[(FLIP_Y * TILESET_SIZE)];
1005
dstPixels = &tilesetPixels[(FLIP_XY * TILESET_SIZE) + (TILE_SIZE - 1)];
1006
for (int32 t = 0; t < 0x400 * TILE_SIZE; ++t) {
1007
for (int32 r = 0; r < TILE_SIZE; ++r) {
1008
*dstPixels-- = *srcPixels++;
1009
}
1010
1011
dstPixels += (TILE_SIZE * 2);
1012
}
1013
1014
#if RETRO_USE_ORIGINAL_CODE
1015
tileset.palette = NULL;
1016
tileset.decoder = NULL;
1017
#endif
1018
tileset.pixels = NULL;
1019
}
1020
}
1021
1022
void RSDK::ProcessParallaxAutoScroll()
1023
{
1024
for (int32 l = 0; l < LAYER_COUNT; ++l) {
1025
TileLayer *layer = &tileLayers[l];
1026
1027
if (layer->layout) {
1028
layer->scrollPos += layer->scrollSpeed;
1029
1030
for (int32 s = 0; s < layer->scrollInfoCount; ++s) layer->scrollInfo[s].scrollPos += layer->scrollInfo[s].scrollSpeed;
1031
}
1032
}
1033
}
1034
void RSDK::ProcessParallax(TileLayer *layer)
1035
{
1036
if (!layer->xsize || !layer->ysize)
1037
return;
1038
1039
int32 pixelWidth = TILE_SIZE * layer->xsize;
1040
int32 pixelHeight = TILE_SIZE * layer->ysize;
1041
ScanlineInfo *scanline = scanlines;
1042
ScrollInfo *scrollInfo = layer->scrollInfo;
1043
1044
switch (layer->type) {
1045
default: break;
1046
1047
case LAYER_HSCROLL: {
1048
for (int32 i = 0; i < layer->scrollInfoCount; ++i) {
1049
scrollInfo->tilePos = scrollInfo->scrollPos + (currentScreen->position.x * scrollInfo->parallaxFactor << 8);
1050
1051
int16 tilePos = FROM_FIXED(scrollInfo->tilePos) % pixelWidth;
1052
if (tilePos < 0)
1053
tilePos += pixelWidth;
1054
scrollInfo->tilePos = TO_FIXED(tilePos);
1055
1056
++scrollInfo;
1057
}
1058
1059
int16 scrollPos =
1060
FROM_FIXED((int32)((layer->scrollPos + (layer->parallaxFactor * currentScreen->position.y << 8)) & 0xFFFF0000)) % pixelHeight;
1061
if (scrollPos < 0)
1062
scrollPos += pixelHeight;
1063
1064
uint8 *lineScrollPtr = &layer->lineScroll[scrollPos];
1065
1066
// Above water
1067
int32 *deformationData = &layer->deformationData[(scrollPos + (uint16)layer->deformationOffset) & 0x1FF];
1068
for (int32 i = 0; i < currentScreen->waterDrawPos; ++i) {
1069
scanline->position.x = layer->scrollInfo[*lineScrollPtr].tilePos;
1070
if (layer->scrollInfo[*lineScrollPtr].deform)
1071
scanline->position.x += TO_FIXED(*deformationData);
1072
1073
scanline->position.y = TO_FIXED(scrollPos++);
1074
1075
deformationData++;
1076
if (scrollPos == pixelHeight) {
1077
lineScrollPtr = layer->lineScroll;
1078
scrollPos = 0;
1079
}
1080
else {
1081
++lineScrollPtr;
1082
}
1083
scanline++;
1084
}
1085
1086
// Under water
1087
deformationData = &layer->deformationDataW[(scrollPos + (uint16)layer->deformationOffsetW) & 0x1FF];
1088
for (int32 i = currentScreen->waterDrawPos; i < currentScreen->size.y; ++i) {
1089
scanline->position.x = layer->scrollInfo[*lineScrollPtr].tilePos;
1090
if (layer->scrollInfo[*lineScrollPtr].deform)
1091
scanline->position.x += TO_FIXED(*deformationData);
1092
1093
scanline->position.y = TO_FIXED(scrollPos++);
1094
1095
deformationData++;
1096
if (scrollPos == pixelHeight) {
1097
lineScrollPtr = layer->lineScroll;
1098
scrollPos = 0;
1099
}
1100
else {
1101
++lineScrollPtr;
1102
}
1103
scanline++;
1104
}
1105
break;
1106
}
1107
1108
case LAYER_VSCROLL: {
1109
for (int32 i = 0; i < layer->scrollInfoCount; ++i) {
1110
scrollInfo->tilePos = scrollInfo->scrollPos + (currentScreen->position.y * scrollInfo->parallaxFactor << 8);
1111
scrollInfo->tilePos = TO_FIXED(FROM_FIXED(scrollInfo->tilePos) % pixelHeight);
1112
1113
++scrollInfo;
1114
}
1115
1116
int16 scrollPos =
1117
FROM_FIXED((int32)((layer->scrollPos + (layer->parallaxFactor * currentScreen->position.x << 8)) & 0xFFFF0000)) % pixelWidth;
1118
if (scrollPos < 0)
1119
scrollPos += pixelWidth;
1120
1121
uint8 *lineScrollPtr = &layer->lineScroll[scrollPos];
1122
1123
// Above water
1124
for (int32 i = 0; i < currentScreen->size.x; ++i) {
1125
scanline->position.x = TO_FIXED(scrollPos++);
1126
scanline->position.y = layer->scrollInfo[*lineScrollPtr].tilePos;
1127
1128
if (scrollPos == pixelWidth) {
1129
lineScrollPtr = layer->lineScroll;
1130
scrollPos = 0;
1131
}
1132
else {
1133
++lineScrollPtr;
1134
}
1135
1136
scanline++;
1137
}
1138
break;
1139
}
1140
1141
case LAYER_ROTOZOOM: {
1142
int16 scrollPosX =
1143
FROM_FIXED((int32)((layer->scrollPos + (layer->parallaxFactor * currentScreen->position.x << 8)) & 0xFFFF0000)) % pixelWidth;
1144
if (scrollPosX < 0)
1145
scrollPosX += pixelWidth;
1146
1147
int16 scrollPosY =
1148
FROM_FIXED((int32)((layer->scrollPos + (layer->parallaxFactor * currentScreen->position.y << 8)) & 0xFFFF0000)) % pixelHeight;
1149
if (scrollPosY < 0)
1150
scrollPosY += pixelHeight;
1151
1152
for (int32 i = 0; i < currentScreen->size.y; ++i) {
1153
scanline->position.x = TO_FIXED(scrollPosX);
1154
scanline->position.y = TO_FIXED(scrollPosY++);
1155
scanline->deform.x = TO_FIXED(1);
1156
scanline->deform.y = TO_FIXED(0);
1157
1158
scanline++;
1159
}
1160
break;
1161
}
1162
1163
case LAYER_BASIC: {
1164
for (int32 i = 0; i < layer->scrollInfoCount; ++i) {
1165
scrollInfo->tilePos = scrollInfo->scrollPos + (currentScreen->position.x * scrollInfo->parallaxFactor << 8);
1166
1167
int16 tilePos = FROM_FIXED(scrollInfo->tilePos) % pixelWidth;
1168
if (tilePos < 0)
1169
tilePos += pixelWidth;
1170
scrollInfo->tilePos = TO_FIXED(tilePos);
1171
1172
++scrollInfo;
1173
}
1174
1175
int16 scrollPos =
1176
FROM_FIXED((int32)((layer->scrollPos + (layer->parallaxFactor * currentScreen->position.y << 8)) & 0xFFFF0000)) % pixelHeight;
1177
if (scrollPos < 0)
1178
scrollPos += pixelHeight;
1179
1180
uint8 *lineScrollPtr = &layer->lineScroll[scrollPos];
1181
1182
// Above water
1183
for (int32 i = 0; i < currentScreen->waterDrawPos; ++i) {
1184
scanline->position.x = layer->scrollInfo[*lineScrollPtr].tilePos;
1185
scanline->position.y = TO_FIXED(scrollPos++);
1186
1187
if (scrollPos == pixelHeight) {
1188
lineScrollPtr = layer->lineScroll;
1189
scrollPos = 0;
1190
}
1191
else {
1192
++lineScrollPtr;
1193
}
1194
scanline++;
1195
}
1196
1197
// Under water
1198
for (int32 i = currentScreen->waterDrawPos; i < currentScreen->size.y; ++i) {
1199
scanline->position.x = layer->scrollInfo[*lineScrollPtr].tilePos;
1200
scanline->position.y = TO_FIXED(scrollPos++);
1201
1202
if (scrollPos == pixelHeight) {
1203
lineScrollPtr = layer->lineScroll;
1204
scrollPos = 0;
1205
}
1206
else {
1207
++lineScrollPtr;
1208
}
1209
1210
scanline++;
1211
}
1212
break;
1213
}
1214
}
1215
}
1216
1217
void RSDK::ProcessSceneTimer()
1218
{
1219
if (sceneInfo.timeEnabled) {
1220
sceneInfo.timeCounter += 100;
1221
1222
if (sceneInfo.timeCounter >= 6000) {
1223
sceneInfo.timeCounter -= 6025;
1224
1225
if (++sceneInfo.seconds >= 60) {
1226
sceneInfo.seconds = 0;
1227
1228
if (++sceneInfo.minutes >= 60)
1229
sceneInfo.minutes = 0;
1230
}
1231
}
1232
1233
sceneInfo.milliseconds = sceneInfo.timeCounter / 60; // 60 == refreshRate
1234
}
1235
}
1236
1237
void RSDK::SetScene(const char *categoryName, const char *sceneName)
1238
{
1239
RETRO_HASH_MD5(catHash);
1240
GEN_HASH_MD5(categoryName, catHash);
1241
1242
RETRO_HASH_MD5(scnHash);
1243
GEN_HASH_MD5(sceneName, scnHash);
1244
1245
for (int32 i = 0; i < sceneInfo.categoryCount; ++i) {
1246
if (HASH_MATCH_MD5(sceneInfo.listCategory[i].hash, catHash)) {
1247
sceneInfo.activeCategory = i;
1248
sceneInfo.listPos = sceneInfo.listCategory[i].sceneOffsetStart;
1249
1250
for (int32 s = 0; s < sceneInfo.listCategory[i].sceneCount; ++s) {
1251
if (HASH_MATCH_MD5(sceneInfo.listData[sceneInfo.listCategory[i].sceneOffsetStart + s].hash, scnHash)) {
1252
sceneInfo.listPos = sceneInfo.listCategory[i].sceneOffsetStart + s;
1253
break;
1254
}
1255
}
1256
1257
break;
1258
}
1259
}
1260
}
1261
1262
void RSDK::CopyTileLayer(uint16 dstLayerID, int32 dstStartX, int32 dstStartY, uint16 srcLayerID, int32 srcStartX, int32 srcStartY, int32 countX,
1263
int32 countY)
1264
{
1265
if (dstLayerID < LAYER_COUNT && srcLayerID < LAYER_COUNT) {
1266
TileLayer *dstLayer = &tileLayers[dstLayerID];
1267
TileLayer *srcLayer = &tileLayers[srcLayerID];
1268
1269
if (dstStartX >= 0 && dstStartX < dstLayer->xsize && dstStartY >= 0 && dstStartY < dstLayer->ysize) {
1270
if (srcStartX >= 0 && srcStartX < srcLayer->xsize && srcStartY >= 0 && srcStartY < srcLayer->ysize) {
1271
if (dstStartX + countX > dstLayer->xsize)
1272
countX = dstLayer->xsize - dstStartX;
1273
1274
if (dstStartY + countY > dstLayer->ysize)
1275
countY = dstLayer->ysize - dstStartY;
1276
1277
if (srcStartX + countX > srcLayer->xsize)
1278
countX = srcLayer->xsize - srcStartX;
1279
1280
if (srcStartY + countY > srcLayer->ysize)
1281
countY = srcLayer->ysize - srcStartY;
1282
1283
for (int32 y = 0; y < countY; ++y) {
1284
for (int32 x = 0; x < countX; ++x) {
1285
uint16 tile = srcLayer->layout[(x + srcStartX) + ((y + srcStartY) << srcLayer->widthShift)];
1286
dstLayer->layout[(x + dstStartX) + ((y + dstStartY) << dstLayer->widthShift)] = tile;
1287
}
1288
}
1289
}
1290
}
1291
}
1292
}
1293
1294
void RSDK::DrawLayerHScroll(TileLayer *layer)
1295
{
1296
if (!layer->xsize || !layer->ysize)
1297
return;
1298
1299
int32 lineTileCount = (currentScreen->pitch >> 4) - 1;
1300
uint8 *lineBuffer = &gfxLineBuffer[currentScreen->clipBound_Y1];
1301
ScanlineInfo *scanline = &scanlines[currentScreen->clipBound_Y1];
1302
uint16 *frameBuffer = &currentScreen->frameBuffer[currentScreen->pitch * currentScreen->clipBound_Y1];
1303
1304
for (int32 cy = currentScreen->clipBound_Y1; cy < currentScreen->clipBound_Y2; ++cy) {
1305
int32 x = scanline->position.x;
1306
int32 y = scanline->position.y;
1307
int32 tileX = FROM_FIXED(x);
1308
uint16 *activePalette = fullPalette[*lineBuffer++];
1309
1310
if (tileX >= TILE_SIZE * layer->xsize)
1311
x = TO_FIXED(tileX - TILE_SIZE * layer->xsize);
1312
else if (tileX < 0)
1313
x = TO_FIXED(tileX + TILE_SIZE * layer->xsize);
1314
1315
int32 tileRemain = TILE_SIZE - (FROM_FIXED(x) & 0xF);
1316
int32 sheetX = FROM_FIXED(x) & 0xF;
1317
int32 sheetY = TILE_SIZE * (FROM_FIXED(y) & 0xF);
1318
int32 lineRemain = currentScreen->pitch;
1319
1320
int32 tx = x >> 20;
1321
uint16 *layout = &layer->layout[tx + ((y >> 20) << layer->widthShift)];
1322
lineRemain -= tileRemain;
1323
1324
if (*layout >= 0xFFFF) {
1325
frameBuffer += tileRemain;
1326
}
1327
else {
1328
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetY + sheetX];
1329
for (int32 x = 0; x < tileRemain; ++x) {
1330
if (*pixels)
1331
*frameBuffer = activePalette[*pixels];
1332
++pixels;
1333
++frameBuffer;
1334
}
1335
}
1336
1337
for (int32 l = 0; l < lineTileCount; ++l) {
1338
++layout;
1339
1340
if (++tx == layer->xsize) {
1341
tx = 0;
1342
layout -= layer->xsize;
1343
}
1344
1345
if (*layout < 0xFFFF) {
1346
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetY];
1347
1348
uint8 index = *pixels;
1349
if (index)
1350
*frameBuffer = activePalette[index];
1351
1352
index = pixels[1];
1353
if (index)
1354
frameBuffer[1] = activePalette[index];
1355
1356
index = pixels[2];
1357
if (index)
1358
frameBuffer[2] = activePalette[index];
1359
1360
index = pixels[3];
1361
if (index)
1362
frameBuffer[3] = activePalette[index];
1363
1364
index = pixels[4];
1365
if (index)
1366
frameBuffer[4] = activePalette[index];
1367
1368
index = pixels[5];
1369
if (index)
1370
frameBuffer[5] = activePalette[index];
1371
1372
index = pixels[6];
1373
if (index)
1374
frameBuffer[6] = activePalette[index];
1375
1376
index = pixels[7];
1377
if (index)
1378
frameBuffer[7] = activePalette[index];
1379
1380
index = pixels[8];
1381
if (index)
1382
frameBuffer[8] = activePalette[index];
1383
1384
index = pixels[9];
1385
if (index)
1386
frameBuffer[9] = activePalette[index];
1387
1388
index = pixels[10];
1389
if (index)
1390
frameBuffer[10] = activePalette[index];
1391
1392
index = pixels[11];
1393
if (index)
1394
frameBuffer[11] = activePalette[index];
1395
1396
index = pixels[12];
1397
if (index)
1398
frameBuffer[12] = activePalette[index];
1399
1400
index = pixels[13];
1401
if (index)
1402
frameBuffer[13] = activePalette[index];
1403
1404
index = pixels[14];
1405
if (index)
1406
frameBuffer[14] = activePalette[index];
1407
1408
index = pixels[15];
1409
if (index)
1410
frameBuffer[15] = activePalette[index];
1411
}
1412
1413
frameBuffer += TILE_SIZE;
1414
lineRemain -= TILE_SIZE;
1415
}
1416
1417
while (lineRemain > 0) {
1418
++layout;
1419
1420
if (++tx == layer->xsize) {
1421
tx = 0;
1422
layout -= layer->xsize;
1423
}
1424
1425
tileRemain = lineRemain >= TILE_SIZE ? TILE_SIZE : lineRemain;
1426
1427
if (*layout >= 0xFFFF) {
1428
frameBuffer += tileRemain;
1429
}
1430
else {
1431
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetY];
1432
for (int32 x = 0; x < tileRemain; ++x) {
1433
if (*pixels)
1434
*frameBuffer = activePalette[*pixels];
1435
++pixels;
1436
++frameBuffer;
1437
}
1438
}
1439
1440
lineRemain -= TILE_SIZE;
1441
}
1442
1443
++scanline;
1444
}
1445
}
1446
void RSDK::DrawLayerVScroll(TileLayer *layer)
1447
{
1448
if (!layer->xsize || !layer->ysize)
1449
return;
1450
1451
int32 lineTileCount = (currentScreen->size.y >> 4) - 1;
1452
uint16 *frameBuffer = &currentScreen->frameBuffer[currentScreen->clipBound_X1];
1453
ScanlineInfo *scanline = &scanlines[currentScreen->clipBound_X1];
1454
uint16 *activePalette = fullPalette[gfxLineBuffer[0]];
1455
1456
for (int32 cx = currentScreen->clipBound_X1; cx < currentScreen->clipBound_X2; ++cx) {
1457
int32 x = scanline->position.x;
1458
int32 y = scanline->position.y;
1459
int32 ty = FROM_FIXED(y);
1460
1461
if (ty >= TILE_SIZE * layer->ysize)
1462
y -= TO_FIXED(TILE_SIZE * layer->ysize);
1463
else if (ty < 0)
1464
y += TO_FIXED(TILE_SIZE * layer->ysize);
1465
1466
int32 tileRemain = TILE_SIZE - (FROM_FIXED(y) & 0xF);
1467
int32 sheetX = FROM_FIXED(x) & 0xF;
1468
int32 sheetY = FROM_FIXED(y) & 0xF;
1469
int32 lineRemain = currentScreen->size.y;
1470
1471
uint16 *layout = &layer->layout[(x >> 20) + ((y >> 20) << layer->widthShift)];
1472
lineRemain -= tileRemain;
1473
1474
if (*layout >= 0xFFFF) {
1475
frameBuffer += currentScreen->pitch * tileRemain;
1476
}
1477
else {
1478
uint8 *pixels = &tilesetPixels[TILE_SIZE * (sheetY + TILE_SIZE * (*layout & 0xFFF)) + sheetX];
1479
for (int32 y = 0; y < tileRemain; ++y) {
1480
if (*pixels)
1481
*frameBuffer = activePalette[*pixels];
1482
pixels += TILE_SIZE;
1483
frameBuffer += currentScreen->pitch;
1484
}
1485
}
1486
1487
ty = y >> 20;
1488
for (int32 l = 0; l < lineTileCount; ++l) {
1489
layout += layer->xsize;
1490
1491
if (++ty == layer->ysize) {
1492
ty = 0;
1493
layout -= layer->ysize << layer->widthShift;
1494
}
1495
1496
if (*layout >= 0xFFFF) {
1497
frameBuffer += TILE_SIZE * currentScreen->pitch;
1498
}
1499
else {
1500
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetX];
1501
1502
if (*pixels)
1503
*frameBuffer = activePalette[*pixels];
1504
1505
if (pixels[0x10])
1506
frameBuffer[currentScreen->pitch * 1] = activePalette[pixels[0x10]];
1507
1508
if (pixels[0x20])
1509
frameBuffer[currentScreen->pitch * 2] = activePalette[pixels[0x20]];
1510
1511
if (pixels[0x30])
1512
frameBuffer[currentScreen->pitch * 3] = activePalette[pixels[0x30]];
1513
1514
if (pixels[0x40])
1515
frameBuffer[currentScreen->pitch * 4] = activePalette[pixels[0x40]];
1516
1517
if (pixels[0x50])
1518
frameBuffer[currentScreen->pitch * 5] = activePalette[pixels[0x50]];
1519
1520
if (pixels[0x60])
1521
frameBuffer[currentScreen->pitch * 6] = activePalette[pixels[0x60]];
1522
1523
if (pixels[0x70])
1524
frameBuffer[currentScreen->pitch * 7] = activePalette[pixels[0x70]];
1525
1526
if (pixels[0x80])
1527
frameBuffer[currentScreen->pitch * 8] = activePalette[pixels[0x80]];
1528
1529
if (pixels[0x90])
1530
frameBuffer[currentScreen->pitch * 9] = activePalette[pixels[0x90]];
1531
1532
if (pixels[0xA0])
1533
frameBuffer[currentScreen->pitch * 10] = activePalette[pixels[0xA0]];
1534
1535
if (pixels[0xB0])
1536
frameBuffer[currentScreen->pitch * 11] = activePalette[pixels[0xB0]];
1537
1538
if (pixels[0xC0])
1539
frameBuffer[currentScreen->pitch * 12] = activePalette[pixels[0xC0]];
1540
1541
if (pixels[0xD0])
1542
frameBuffer[currentScreen->pitch * 13] = activePalette[pixels[0xD0]];
1543
1544
if (pixels[0xE0])
1545
frameBuffer[currentScreen->pitch * 14] = activePalette[pixels[0xE0]];
1546
1547
if (pixels[0xF0])
1548
frameBuffer[currentScreen->pitch * 15] = activePalette[pixels[0xF0]];
1549
1550
frameBuffer += currentScreen->pitch * TILE_SIZE;
1551
}
1552
1553
lineRemain -= TILE_SIZE;
1554
}
1555
1556
while (lineRemain > 0) {
1557
layout += layer->xsize;
1558
1559
if (++ty == layer->ysize) {
1560
ty = 0;
1561
layout -= layer->ysize << layer->widthShift;
1562
}
1563
1564
tileRemain = lineRemain >= TILE_SIZE ? TILE_SIZE : lineRemain;
1565
if (*layout >= 0xFFFF) {
1566
frameBuffer += currentScreen->pitch * sheetY;
1567
}
1568
else {
1569
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetX];
1570
for (int32 y = 0; y < tileRemain; ++y) {
1571
if (*pixels)
1572
*frameBuffer = activePalette[*pixels];
1573
1574
pixels += TILE_SIZE;
1575
frameBuffer += currentScreen->pitch;
1576
}
1577
}
1578
1579
lineRemain -= TILE_SIZE;
1580
}
1581
1582
frameBuffer -= currentScreen->pitch * currentScreen->size.y;
1583
1584
++scanline;
1585
++frameBuffer;
1586
}
1587
}
1588
void RSDK::DrawLayerRotozoom(TileLayer *layer)
1589
{
1590
if (!layer->xsize || !layer->ysize)
1591
return;
1592
1593
uint16 *layout = layer->layout;
1594
uint8 *lineBuffer = &gfxLineBuffer[currentScreen->clipBound_Y1];
1595
ScanlineInfo *scanline = &scanlines[currentScreen->clipBound_Y1];
1596
uint16 *frameBuffer = &currentScreen->frameBuffer[currentScreen->clipBound_X1 + currentScreen->clipBound_Y1 * currentScreen->pitch];
1597
1598
int32 width = (TILE_SIZE << layer->widthShift) - 1;
1599
int32 height = (TILE_SIZE << layer->heightShift) - 1;
1600
int32 lineSize = currentScreen->clipBound_X2 - currentScreen->clipBound_X1;
1601
1602
for (int32 cy = currentScreen->clipBound_Y1; cy < currentScreen->clipBound_Y2; ++cy) {
1603
int32 posX = scanline->position.x;
1604
int32 posY = scanline->position.y;
1605
1606
uint16 *activePalette = fullPalette[*lineBuffer];
1607
++lineBuffer;
1608
int32 fbOffset = currentScreen->pitch - lineSize;
1609
1610
for (int32 cx = 0; cx < lineSize; ++cx) {
1611
int32 tx = posX >> 20;
1612
int32 ty = posY >> 20;
1613
int32 x = FROM_FIXED(posX) & 0xF;
1614
int32 y = FROM_FIXED(posY) & 0xF;
1615
1616
uint16 tile = layout[((width >> 4) & tx) + (((height >> 4) & ty) << layer->widthShift)] & 0xFFF;
1617
uint8 idx = tilesetPixels[TILE_SIZE * (y + TILE_SIZE * tile) + x];
1618
1619
if (idx)
1620
*frameBuffer = activePalette[idx];
1621
1622
posX += scanline->deform.x;
1623
posY += scanline->deform.y;
1624
++frameBuffer;
1625
}
1626
1627
frameBuffer += fbOffset;
1628
++scanline;
1629
}
1630
}
1631
void RSDK::DrawLayerBasic(TileLayer *layer)
1632
{
1633
if (!layer->xsize || !layer->ysize)
1634
return;
1635
1636
if (currentScreen->clipBound_X1 >= currentScreen->clipBound_X2 || currentScreen->clipBound_Y1 >= currentScreen->clipBound_Y2)
1637
return;
1638
1639
uint16 *activePalette = fullPalette[0];
1640
if (currentScreen->clipBound_X1 < currentScreen->clipBound_X2 && currentScreen->clipBound_Y1 < currentScreen->clipBound_Y2) {
1641
int32 lineSize = (currentScreen->clipBound_X2 - currentScreen->clipBound_X1) >> 4;
1642
1643
ScanlineInfo *scanline = &scanlines[currentScreen->clipBound_Y1];
1644
1645
int32 tx = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) >> 4;
1646
int32 ty = FROM_FIXED(scanline->position.y) >> 4;
1647
int32 sheetY = FROM_FIXED(scanline->position.y) & 0xF;
1648
int32 sheetX = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) & 0xF;
1649
int32 tileRemainX = TILE_SIZE - sheetX;
1650
int32 tileRemainY = TILE_SIZE - sheetY;
1651
1652
uint16 *frameBuffer = &currentScreen->frameBuffer[currentScreen->clipBound_X1 + currentScreen->clipBound_Y1 * currentScreen->pitch];
1653
uint16 *layout = &layer->layout[tx + (ty << layer->widthShift)];
1654
1655
// Remaining pixels on top
1656
{
1657
if (*layout == 0xFFFF) {
1658
frameBuffer += TILE_SIZE - sheetX;
1659
}
1660
else {
1661
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + TILE_SIZE * sheetY + sheetX];
1662
1663
for (int32 y = 0; y < tileRemainY; ++y) {
1664
for (int32 x = 0; x < tileRemainX; ++x) {
1665
if (*pixels)
1666
*frameBuffer = activePalette[*pixels];
1667
++pixels;
1668
++frameBuffer;
1669
}
1670
1671
pixels += sheetX;
1672
frameBuffer += currentScreen->pitch - tileRemainX;
1673
}
1674
1675
frameBuffer += tileRemainX - currentScreen->pitch * tileRemainY;
1676
}
1677
1678
++layout;
1679
if (++tx == layer->xsize) {
1680
tx = 0;
1681
layout -= layer->xsize;
1682
}
1683
1684
for (int32 x = 0; x < lineSize; ++x) {
1685
if (*layout == 0xFFFF) {
1686
frameBuffer += TILE_SIZE;
1687
}
1688
else {
1689
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + TILE_SIZE * sheetY];
1690
for (int32 y = 0; y < tileRemainY; ++y) {
1691
uint8 index = *pixels;
1692
if (index)
1693
*frameBuffer = activePalette[index];
1694
1695
index = pixels[1];
1696
if (index)
1697
frameBuffer[1] = activePalette[index];
1698
1699
index = pixels[2];
1700
if (index)
1701
frameBuffer[2] = activePalette[index];
1702
1703
index = pixels[3];
1704
if (index)
1705
frameBuffer[3] = activePalette[index];
1706
1707
index = pixels[4];
1708
if (index)
1709
frameBuffer[4] = activePalette[index];
1710
1711
index = pixels[5];
1712
if (index)
1713
frameBuffer[5] = activePalette[index];
1714
1715
index = pixels[6];
1716
if (index)
1717
frameBuffer[6] = activePalette[index];
1718
1719
index = pixels[7];
1720
if (index)
1721
frameBuffer[7] = activePalette[index];
1722
1723
index = pixels[8];
1724
if (index)
1725
frameBuffer[8] = activePalette[index];
1726
1727
index = pixels[9];
1728
if (index)
1729
frameBuffer[9] = activePalette[index];
1730
1731
index = pixels[10];
1732
if (index)
1733
frameBuffer[10] = activePalette[index];
1734
1735
index = pixels[11];
1736
if (index)
1737
frameBuffer[11] = activePalette[index];
1738
1739
index = pixels[12];
1740
if (index)
1741
frameBuffer[12] = activePalette[index];
1742
1743
index = pixels[13];
1744
if (index)
1745
frameBuffer[13] = activePalette[index];
1746
1747
index = pixels[14];
1748
if (index)
1749
frameBuffer[14] = activePalette[index];
1750
1751
index = pixels[15];
1752
if (index)
1753
frameBuffer[15] = activePalette[index];
1754
1755
frameBuffer += currentScreen->pitch;
1756
pixels += TILE_SIZE;
1757
}
1758
1759
frameBuffer += TILE_SIZE - currentScreen->pitch * tileRemainY;
1760
}
1761
1762
++layout;
1763
if (++tx == layer->xsize) {
1764
tx = 0;
1765
layout -= layer->xsize;
1766
}
1767
}
1768
1769
if (*layout == 0xFFFF) {
1770
frameBuffer += currentScreen->pitch * tileRemainY;
1771
}
1772
else {
1773
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + TILE_SIZE * sheetY];
1774
1775
for (int32 y = 0; y < tileRemainY; ++y) {
1776
for (int32 x = 0; x < sheetX; ++x) {
1777
if (*pixels)
1778
*frameBuffer = activePalette[*pixels];
1779
++pixels;
1780
++frameBuffer;
1781
}
1782
1783
pixels += tileRemainX;
1784
frameBuffer += currentScreen->pitch - sheetX;
1785
}
1786
}
1787
}
1788
1789
// We've drawn a single line of pixels, increase our variables
1790
frameBuffer += sheetX + -TILE_SIZE * lineSize - TILE_SIZE;
1791
scanline += tileRemainY;
1792
if (++ty == layer->ysize)
1793
ty = 0;
1794
1795
// Draw the bulk of the tiles
1796
int32 lineTileCount = ((currentScreen->clipBound_Y2 - currentScreen->clipBound_Y1) >> 4) - 1;
1797
for (int32 l = 0; l < lineTileCount; ++l) {
1798
sheetX = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) & 0xF;
1799
tx = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) >> 4;
1800
tileRemainX = TILE_SIZE - sheetX;
1801
layout = &layer->layout[tx + (ty << layer->widthShift)];
1802
1803
// Draw any stray pixels on the left
1804
if (*layout == 0xFFFF) {
1805
frameBuffer += tileRemainX;
1806
}
1807
else {
1808
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetX];
1809
1810
for (int32 y = 0; y < TILE_SIZE; ++y) {
1811
for (int32 x = 0; x < tileRemainX; ++x) {
1812
if (*pixels)
1813
*frameBuffer = activePalette[*pixels];
1814
++pixels;
1815
++frameBuffer;
1816
}
1817
1818
pixels += sheetX;
1819
frameBuffer += currentScreen->pitch - tileRemainX;
1820
}
1821
1822
frameBuffer += tileRemainX - TILE_SIZE * currentScreen->pitch;
1823
}
1824
++layout;
1825
if (++tx == layer->xsize) {
1826
tx = 0;
1827
layout -= layer->xsize;
1828
}
1829
1830
// Draw the bulk of the tiles on this line
1831
for (int32 x = 0; x < lineSize; ++x) {
1832
if (*layout == 0xFFFF) {
1833
frameBuffer += TILE_SIZE;
1834
}
1835
else {
1836
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF)];
1837
1838
for (int32 y = 0; y < TILE_SIZE; ++y) {
1839
uint8 index = *pixels;
1840
if (index)
1841
*frameBuffer = activePalette[index];
1842
1843
index = pixels[1];
1844
if (index)
1845
frameBuffer[1] = activePalette[index];
1846
1847
index = pixels[2];
1848
if (index)
1849
frameBuffer[2] = activePalette[index];
1850
1851
index = pixels[3];
1852
if (index)
1853
frameBuffer[3] = activePalette[index];
1854
1855
index = pixels[4];
1856
if (index)
1857
frameBuffer[4] = activePalette[index];
1858
1859
index = pixels[5];
1860
if (index)
1861
frameBuffer[5] = activePalette[index];
1862
1863
index = pixels[6];
1864
if (index)
1865
frameBuffer[6] = activePalette[index];
1866
1867
index = pixels[7];
1868
if (index)
1869
frameBuffer[7] = activePalette[index];
1870
1871
index = pixels[8];
1872
if (index)
1873
frameBuffer[8] = activePalette[index];
1874
1875
index = pixels[9];
1876
if (index)
1877
frameBuffer[9] = activePalette[index];
1878
1879
index = pixels[10];
1880
if (index)
1881
frameBuffer[10] = activePalette[index];
1882
1883
index = pixels[11];
1884
if (index)
1885
frameBuffer[11] = activePalette[index];
1886
1887
index = pixels[12];
1888
if (index)
1889
frameBuffer[12] = activePalette[index];
1890
1891
index = pixels[13];
1892
if (index)
1893
frameBuffer[13] = activePalette[index];
1894
1895
index = pixels[14];
1896
if (index)
1897
frameBuffer[14] = activePalette[index];
1898
1899
index = pixels[15];
1900
if (index)
1901
frameBuffer[15] = activePalette[index];
1902
1903
pixels += TILE_SIZE;
1904
frameBuffer += currentScreen->pitch;
1905
}
1906
1907
frameBuffer -= TILE_SIZE * currentScreen->pitch;
1908
frameBuffer += TILE_SIZE;
1909
}
1910
1911
++layout;
1912
if (++tx == layer->xsize) {
1913
tx = 0;
1914
layout -= layer->xsize;
1915
}
1916
}
1917
1918
// Draw any stray pixels on the right
1919
if (*layout == 0xFFFF) {
1920
frameBuffer += TILE_SIZE * currentScreen->pitch;
1921
}
1922
else {
1923
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF)];
1924
1925
for (int32 y = 0; y < TILE_SIZE; ++y) {
1926
for (int32 x = 0; x < sheetX; ++x) {
1927
if (*pixels)
1928
*frameBuffer = activePalette[*pixels];
1929
++pixels;
1930
++frameBuffer;
1931
}
1932
1933
pixels += tileRemainX;
1934
frameBuffer += currentScreen->pitch - sheetX;
1935
}
1936
}
1937
++layout;
1938
if (++tx == layer->xsize) {
1939
tx = 0;
1940
layout -= layer->xsize;
1941
}
1942
1943
// We've drawn a single line, increase our variables
1944
scanline += TILE_SIZE;
1945
frameBuffer += sheetX + -TILE_SIZE * lineSize - TILE_SIZE;
1946
if (++ty == layer->ysize)
1947
ty = 0;
1948
}
1949
1950
// Remaining pixels on bottom
1951
{
1952
tx = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) >> 4;
1953
sheetX = (currentScreen->clipBound_X1 + FROM_FIXED(scanline->position.x)) & 0xF;
1954
tileRemainX = TILE_SIZE - sheetX;
1955
layout = &layer->layout[tx + (ty << layer->widthShift)];
1956
1957
if (*layout != 0xFFFF) {
1958
frameBuffer += tileRemainX;
1959
}
1960
else {
1961
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF) + sheetX];
1962
1963
for (int32 y = 0; y < sheetY; ++y) {
1964
for (int32 x = 0; x < tileRemainX; ++x) {
1965
if (*pixels)
1966
*frameBuffer = activePalette[*pixels];
1967
++pixels;
1968
++frameBuffer;
1969
}
1970
1971
pixels += sheetX;
1972
frameBuffer += currentScreen->pitch - tileRemainX;
1973
}
1974
1975
frameBuffer += tileRemainX - currentScreen->pitch * sheetY;
1976
}
1977
++layout;
1978
if (++tx == layer->xsize) {
1979
tx = 0;
1980
layout -= layer->xsize;
1981
}
1982
1983
for (int32 x = 0; x < lineSize; ++x) {
1984
if (*layout == 0xFFFF) {
1985
frameBuffer += TILE_SIZE;
1986
}
1987
else {
1988
uint8 *pixels = &tilesetPixels[TILE_DATASIZE * (*layout & 0xFFF)];
1989
for (int32 y = 0; y < sheetY; ++y) {
1990
uint8 index = *pixels;
1991
if (index)
1992
*frameBuffer = activePalette[index];
1993
1994
index = pixels[1];
1995
if (index)
1996
frameBuffer[1] = activePalette[index];
1997
1998
index = pixels[2];
1999
if (index)
2000
frameBuffer[2] = activePalette[index];
2001
2002
index = pixels[3];
2003
if (index)
2004
frameBuffer[3] = activePalette[index];
2005
2006
index = pixels[4];
2007
if (index)
2008
frameBuffer[4] = activePalette[index];
2009
2010
index = pixels[5];
2011
if (index)
2012
frameBuffer[5] = activePalette[index];
2013
2014
index = pixels[6];
2015
if (index)
2016
frameBuffer[6] = activePalette[index];
2017
2018
index = pixels[7];
2019
if (index)
2020
frameBuffer[7] = activePalette[index];
2021
2022
index = pixels[8];
2023
if (index)
2024
frameBuffer[8] = activePalette[index];
2025
2026
index = pixels[9];
2027
if (index)
2028
frameBuffer[9] = activePalette[index];
2029
2030
index = pixels[10];
2031
if (index)
2032
frameBuffer[10] = activePalette[index];
2033
2034
index = pixels[11];
2035
if (index)
2036
frameBuffer[11] = activePalette[index];
2037
2038
index = pixels[12];
2039
if (index)
2040
frameBuffer[12] = activePalette[index];
2041
2042
index = pixels[13];
2043
if (index)
2044
frameBuffer[13] = activePalette[index];
2045
2046
index = pixels[14];
2047
if (index)
2048
frameBuffer[14] = activePalette[index];
2049
2050
index = pixels[15];
2051
if (index)
2052
frameBuffer[15] = activePalette[index];
2053
2054
pixels += TILE_SIZE;
2055
frameBuffer += currentScreen->pitch;
2056
}
2057
2058
frameBuffer += TILE_SIZE - currentScreen->pitch * sheetY;
2059
}
2060
2061
++layout;
2062
if (++tx == layer->xsize) {
2063
tx = 0;
2064
layout -= layer->xsize;
2065
}
2066
}
2067
2068
if (*layout != 0xFFFF) {
2069
uint8 *pixels = &tilesetPixels[256 * (*layout & 0xFFF)];
2070
2071
for (int32 y = 0; y < sheetY; ++y) {
2072
for (int32 x = 0; x < sheetX; ++x) {
2073
if (*pixels)
2074
*frameBuffer = activePalette[*pixels];
2075
++pixels;
2076
++frameBuffer;
2077
}
2078
2079
pixels += tileRemainX;
2080
}
2081
2082
frameBuffer += currentScreen->pitch - sheetX;
2083
}
2084
}
2085
}
2086
}
2087
2088