-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathROMUtils.h
142 lines (118 loc) · 5.81 KB
/
ROMUtils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef ROMUTILS_H
#define ROMUTILS_H
#include <QString>
#include <map>
#include <functional>
#include <cstring>
#include <string>
#include <vector>
#include "WL4Constants.h"
#include "LevelComponents/AnimatedTile8x8Group.h"
#include "LevelComponents/Tileset.h"
#include "LevelComponents/EntitySet.h"
#include "LevelComponents/Entity.h"
#include "LevelComponents/Layer.h"
#define CHUNK_TYPE_COUNT 0x17
namespace ROMUtils
{
struct ROMFileMetadata
{
unsigned int Length;
QString FilePath;
unsigned char *ROMDataPtr = nullptr;
};
// Global variables
extern struct ROMFileMetadata CurrentROMMetadata;
extern struct ROMFileMetadata TempROMMetadata;
extern struct ROMFileMetadata *ROMFileMetadata;
extern unsigned int SaveDataIndex;
extern LevelComponents::AnimatedTile8x8Group *animatedTileGroups[270];
extern LevelComponents::Tileset *singletonTilesets[92];
extern LevelComponents::Entity *entities[129];
extern LevelComponents::EntitySet *entitiessets[90];
extern const char *ChunkTypeString[CHUNK_TYPE_COUNT];
extern bool ChunkTypeAlignment[CHUNK_TYPE_COUNT];
enum SaveDataChunkType
{
InvalidationChunk = '\x00',
RoomHeaderChunkType = '\x01',
DoorChunkType = '\x02',
LayerChunkType = '\x03',
LevelNameChunkType = '\x04',
EntityListChunk = '\x05',
CameraPointerTableType = '\x06',
CameraBoundaryChunkType = '\x07',
PatchListChunk = '\x08',
PatchChunk = '\x09',
TilesetForegroundTile8x8DataChunkType = '\x0A',
TilesetMap16EventTableChunkType = '\x0B',
TilesetMap16TerrainChunkType = '\x0C',
TilesetMap16DataChunkType = '\x0D',
// the next one is not necessary, but i added it by accident -- ssp
TilesetPaletteDataChunkType = '\x0E',
EntityTile8x8DataChunkType = '\x0F',
EntityPaletteDataChunkType = '\x10',
EntitySetLoadTableChunkType = '\x11',
AssortedGraphicListChunkType = '\x12',
AssortedGraphicTile8x8DataChunkType = '\x13',
AssortedGraphicmappingChunkType = '\x14',
AssortedGraphicPaletteChunkType = '\x15',
AnimatedTileGroupTile8x8DataChunkType = '\x16',
};
enum ChunkAllocationStatus
{
Success = '\x00',
InsufficientSpace = '\x01',
NoMoreChunks = '\x02',
ProcessingError = '\x03'
};
struct SaveData
{
unsigned int ptr_addr;
unsigned int size;
unsigned char *data;
unsigned int index;
bool alignment; // false: do not perform special alignment of the save chunk
unsigned int dest_index; // 0: the address of the pointer that points to this chunk is in main ROM. Else, it is
// in another chunk
unsigned int old_chunk_addr; // address of the old chunk that was pointed to. This should point to the start of the chunk data, not the RATS tag
enum SaveDataChunkType ChunkType;
};
struct FreeSpaceRegion
{
unsigned int addr;
unsigned int size;
};
// Exposed helper functions
void FormatPathSeperators(QString &path);
// Global functions
void CleanUpTmpCurrentFileMetaData();
unsigned int IntFromData(int address);
unsigned int PointerFromData(int address);
unsigned int EndianReverse(unsigned int n);
void Tile8x8DataXFlip(unsigned char *source, unsigned char *destination);
void Tile8x8DataYFlip(unsigned char *source, unsigned char *destination);
unsigned int PackScreen(unsigned short *screenCharData, unsigned short *&outputCompressedData, bool skipzeros = true);
unsigned short *UnPackScreen(uint32_t address);
unsigned char *LayerRLEDecompress(int address, size_t outputSize);
unsigned int LayerRLECompress(unsigned int _layersize, unsigned short *LayerData, unsigned char **OutputCompressedData);
bool GetChunkType(unsigned int DataAddr, enum SaveDataChunkType &chunkType);
unsigned int GetChunkDataLength(unsigned int chunkheaderAddr);
unsigned int FindChunkInROM(unsigned char *ROMData, unsigned int ROMLength, unsigned int startAddr, enum SaveDataChunkType chunkType, bool anyChunk = false);
QVector<unsigned int> FindAllChunksInROM(unsigned char *ROMData, unsigned int ROMLength, unsigned int startAddr, enum SaveDataChunkType chunkType, bool anyChunk = false);
bool SaveFile(QString filePath, QVector<unsigned int> invalidationChunks,
std::function<ChunkAllocationStatus (unsigned char*, struct FreeSpaceRegion, struct SaveData*, bool, int*)> ChunkAllocator,
std::function<QString (unsigned char*, std::map<int, int>)> PostProcessingCallback);
bool SaveLevel(QString fileName);
void LoadPalette(QVector<QRgb> *palette, unsigned short *dataptr, bool notdisablefirstcolor = false);
unsigned short QRgbToData(QRgb paletteElement);
QRgb QRgbGrayScale(QRgb realcolor);
void GenerateAnimatedTileGroupChunks(int _globalAnimatedTileGroupId, QVector<struct ROMUtils::SaveData> &chunks);
void GenerateTilesetSaveChunks(int TilesetId, QVector<struct ROMUtils::SaveData> &chunks);
void GenerateEntitySaveChunks(int GlobalEntityId, QVector<struct ROMUtils::SaveData> &chunks);
void GenerateEntitySetSaveChunks(int EntitySetId, QVector<struct ROMUtils::SaveData> &chunks);
QString SaveDataAnalysis();
void StaticInitialization();
bool WriteChunkSanityCheck(const struct SaveData &chunk, const unsigned int chunk_addr, const QVector<unsigned int> &existChunks);
} // namespace ROMUtils
#endif // ROMUTILS_H