-
Notifications
You must be signed in to change notification settings - Fork 0
/
SMAP.bt
199 lines (156 loc) · 6.16 KB
/
SMAP.bt
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//------------------------------------------------
//--- 010 Editor v11.0.1 Binary Template
//
// File: SMAP.bt
// Authors: Florian Eßl
// Version:
// Purpose: SRPG95 File format
// Category: Games
// File Mask: SMAP_*.DAT
// ID Bytes:
// History: https://github.com/florianessl/srpg95-fileformat
//------------------------------------------------
//TODO: document the different types of EventCommands and their arguments
//TODO: figure out, how to map SMAP.map_data values to tileset data
#include "ObjectData.inc.bt"
typedef struct EventDeclaration {
char internal_name[8];
int first_chunk;
int length_data; //The length of an event will be padded to the next 100
// (e.g. 115 -> actually takes 200 bytes of space)
} eventdeclaration_ <optimize=false>;
typedef struct EventCommand {
byte command_id;
short length;
byte unk_byte; //TODO
byte command_data[500]; //Fixed size array since Binary Template scripting is a little bit limited
} eventcommand_ <optimize=false>;
typedef struct Event {
char event_name[36];
char zero_padding_0[64];
uint length_commands; //length in bytes
local int count_commands;
local EventCommand commands[5000]; //Fixed size array since Binary Template scripting is a little bit limited
} event_ <optimize=false>;
byte[] ReadEventData(int ev_chunks[], int pos, int padded_size, int current_chunk_pos) {
local byte eventData[padded_size];
local int i = 0; j = 0;
local int offset = 0;
while (current_chunk_pos != -2) {
offset = 0;
for (j = 0; j < current_chunk_pos; j++) {
if (ev_chunks[j] == -1)
offset++;
}
Printf(" Chunk Offset: %d\n", offset);
for (j = 0; j < 100; j++) {
FSeek(pos + (current_chunk_pos - offset) * 100 + j);
eventData[i * 100 + j] = ReadByte();
}
current_chunk_pos = ev_chunks[current_chunk_pos];
Printf(" Curr Chunk Pos: %d\n", current_chunk_pos);
i++;
}
return eventData;
}
//SMAP%03d.DAT
struct SMAP {
char name[20];
char zero_padding_0[12];
int width;
int height;
int tileset;
int winCondition;
char music_camp[48];
char music_player_turn[48];
char music_enemy_turn[48];
char music_player_battle[48];
char music_enemy_battle[48];
char music_boss_battle[48];
char music_map_complete[48];
char music_game_over[48];
int camp_before_battle;
int camp_shop_items[100];
int count_shop_items;
int count_prev_character;
int prev_character_startpos_x[20]; //only 15 are used
int prev_character_startpos_y[20]; //only 15 are used
int important_characters[15];
char unk1_0[20];
int count_important_characters;
int camp_background;
int unk_int;
char unk2_0[8];
int camp_allow_party_change;
char unk3_0[80];
//Always 40*40 (maximum), even if a smaller map size has been chosen
short map_data[1600];
char unk4_0[12];
Object objects[100]; //first one is always empty (base 1 index)
//Stores event chunk adresses. event data is split into chunks of 100 bytes.
int ev_chunks[5000];
local int pos<hidden=true>;
pos = FTell();
local int count_ev_declarations<hidden=true>;
count_ev_declarations = 0;
local int i <hidden=true>, j<hidden=true>, k<hidden=true>;
for (k = 0; k < 5000; k++) {
if (ReadByte() == 0) {
FSeek(FTell() + 16);
continue;
}
count_ev_declarations++;
FSeek(FTell() + 16);
}
FSeek(pos);
EventDeclaration ev_declarations[5000];
//This marks the end of the static part of the format
//Event data is read into a local array "events" with the arrays
// Event.commands and EventCommand.command_data set to arbitrarily high sizes
// (since 010 Binary Template scripting is very limited)
//Check "Show local variables" in 010s variable view to see them
pos = FTell();
local int padded_size <hidden=true>,
current_chunk_pos <hidden=true>;
i = 0;
local Event events[count_ev_declarations];
local byte eventData[];
local int bytesRead <hidden=true>;
for (k = 0; k < 5000; k++) {
if (ev_declarations[k].internal_name[0] == 0)
continue;
//while (ev_declarations[i].internal_name[0] != 0) {
current_chunk_pos = ev_declarations[k].first_chunk;
Printf("Parsing Chunked Event Data\n");
padded_size = ev_declarations[k].length_data + (100 - ev_declarations[k].length_data % 100);
Printf("First Chunk Position: %d\n", current_chunk_pos);
Printf("Length: %d \n", ev_declarations[k].length_data);
Printf("Padded data size: %d\n", padded_size);
eventData = ReadEventData(ev_chunks, pos, padded_size, current_chunk_pos);
bytesRead = 0;
for (j = 0; j < 36; j++)
events[i].event_name[j] = eventData[j];
bytesRead = 36;
for (j = 0; j < 64; j++)
events[i].zero_padding_0[j] = eventData[bytesRead + j];
bytesRead += 64;
events[i].length_commands = ((uint)eventData[bytesRead + 1]) << 8;
events[i].length_commands += ((ubyte)eventData[bytesRead]);
bytesRead += 4;
events[i].count_commands = 0;
Printf("Event name: %s\n", events[i].event_name);
while ( bytesRead < ev_declarations[k].length_data) {
events[i].commands[events[i].count_commands].command_id = eventData[bytesRead];
events[i].commands[events[i].count_commands].length = ((ushort)eventData[bytesRead + 2]) << 8;
events[i].commands[events[i].count_commands].length += ((ubyte)eventData[bytesRead + 1]);
for (j = 0; j < events[i].commands[events[i].count_commands].length; j++) {
events[i].commands[events[i].count_commands].command_data[j] = eventData[bytesRead + 4 + j];
}
//Not part of this binary template: parsing the EventCommand data
bytesRead += events[i].commands[events[i].count_commands].length + 4;
events[i].count_commands++;
}
Printf("\n");
i++;
}
} smap <optimize=false>;