2
#include "Commands/CDirectiveData.h"
3
#include "Core/Common.h"
4
#include "Core/FileManager.h"
10
TableCommand::TableCommand(const std::wstring& fileName, TextFile::Encoding encoding)
12
if (fileExists(fileName) == false)
14
Logger::printError(Logger::Error,L"Table file \"%s\" does not exist",fileName);
18
if (table.load(fileName,encoding) == false)
20
Logger::printError(Logger::Error,L"Invalid table file \"%s\"",fileName);
25
bool TableCommand::Validate()
36
CDirectiveData::CDirectiveData()
38
mode = EncodingMode::Invalid;
39
writeTermination = false;
40
endianness = Arch->getEndianness();
43
CDirectiveData::~CDirectiveData()
48
void CDirectiveData::setNormal(std::vector<Expression>& entries, size_t unitSize, bool ascii)
54
this->mode = EncodingMode::Ascii;
56
this->mode = EncodingMode::U8;
59
this->mode = EncodingMode::U16;
62
this->mode = EncodingMode::U32;
65
Logger::printError(Logger::Error,L"Invalid data unit size %d",unitSize);
69
this->entries = entries;
70
this->writeTermination = false;
71
normalData.reserve(entries.size());
74
void CDirectiveData::setFloat(std::vector<Expression>& entries)
76
this->mode = EncodingMode::Float;
77
this->entries = entries;
78
this->writeTermination = false;
81
void CDirectiveData::setSjis(std::vector<Expression>& entries, bool terminate)
83
this->mode = EncodingMode::Sjis;
84
this->entries = entries;
85
this->writeTermination = terminate;
88
void CDirectiveData::setCustom(std::vector<Expression>& entries, bool terminate)
90
this->mode = EncodingMode::Custom;
91
this->entries = entries;
92
this->writeTermination = terminate;
95
size_t CDirectiveData::getUnitSize() const
99
case EncodingMode::U8:
100
case EncodingMode::Ascii:
101
case EncodingMode::Sjis:
102
case EncodingMode::Custom:
104
case EncodingMode::U16:
106
case EncodingMode::U32:
107
case EncodingMode::Float:
114
size_t CDirectiveData::getDataSize() const
118
case EncodingMode::Sjis:
119
case EncodingMode::Custom:
120
return customData.size();
121
case EncodingMode::U8:
122
case EncodingMode::Ascii:
123
case EncodingMode::U16:
124
case EncodingMode::U32:
125
case EncodingMode::Float:
126
return normalData.size()*getUnitSize();
132
void CDirectiveData::encodeCustom(EncodingTable& table)
135
for (size_t i = 0; i < entries.size(); i++)
137
ExpressionValue value = entries[i].evaluate();
138
if (!value.isValid())
140
Logger::queueError(Logger::Error,L"Invalid expression");
146
customData.appendByte((u8)value.intValue);
147
} else if (value.isString())
149
ByteArray encoded = table.encodeString(value.strValue,false);
150
if (encoded.size() == 0 && value.strValue.size() > 0)
152
Logger::queueError(Logger::Error,L"Failed to encode \"%s\"",value.strValue);
154
customData.append(encoded);
156
Logger::queueError(Logger::Error,L"Invalid expression type");
160
if (writeTermination)
162
ByteArray encoded = table.encodeTermination();
163
customData.append(encoded);
167
void CDirectiveData::encodeSjis()
169
static EncodingTable sjisTable;
170
if (sjisTable.isLoaded() == false)
172
unsigned char hexBuffer[2];
174
sjisTable.setTerminationEntry((unsigned char*)"\0",1);
176
for (unsigned short SJISValue = 0x0001; SJISValue < 0x0100; SJISValue++)
178
wchar_t unicodeValue = sjisToUnicode(SJISValue);
179
if (unicodeValue != 0xFFFF)
181
hexBuffer[0] = SJISValue & 0xFF;
182
sjisTable.addEntry(hexBuffer, 1, unicodeValue);
185
for (unsigned short SJISValue = 0x8100; SJISValue < 0xEF00; SJISValue++)
187
wchar_t unicodeValue = sjisToUnicode(SJISValue);
188
if (unicodeValue != 0xFFFF)
190
hexBuffer[0] = (SJISValue >> 8) & 0xFF;
191
hexBuffer[1] = SJISValue & 0xFF;
192
sjisTable.addEntry(hexBuffer, 2, unicodeValue);
197
encodeCustom(sjisTable);
200
void CDirectiveData::encodeFloat()
203
for (size_t i = 0; i < entries.size(); i++)
205
ExpressionValue value = entries[i].evaluate();
206
if (!value.isValid())
208
Logger::queueError(Logger::Error,L"Invalid expression");
214
u32 num = getFloatBits((float)value.intValue);
215
normalData.push_back(num);
216
} else if (value.isFloat())
218
u32 num = getFloatBits((float)value.floatValue);
219
normalData.push_back(num);
221
Logger::queueError(Logger::Error,L"Invalid expression type");
226
void CDirectiveData::encodeNormal()
229
for (size_t i = 0; i < entries.size(); i++)
231
ExpressionValue value = entries[i].evaluate();
232
if (!value.isValid())
234
Logger::queueError(Logger::Error,L"Invalid expression");
238
if (value.isString())
240
bool hadNonAscii = false;
241
for (size_t l = 0; l < value.strValue.size(); l++)
243
u64 num = value.strValue[l];
244
normalData.push_back((u32)num);
246
if (num >= 0x80 && hadNonAscii == false)
248
Logger::printError(Logger::Warning,L"Non-ASCII character in data directive. Use .string instead");
252
} else if (value.isInt())
254
u64 num = value.intValue;
255
normalData.push_back((u32)num);
256
} else if (value.isFloat() && mode == EncodingMode::U32)
258
u32 num = getFloatBits((float)value.floatValue);
259
normalData.push_back(num);
261
Logger::queueError(Logger::Error,L"Invalid expression type");
266
bool CDirectiveData::Validate()
268
position = g_fileManager->getVirtualAddress();
270
size_t oldSize = getDataSize();
273
case EncodingMode::U8:
274
case EncodingMode::U16:
275
case EncodingMode::U32:
276
case EncodingMode::Ascii:
279
case EncodingMode::Float:
282
case EncodingMode::Sjis:
285
case EncodingMode::Custom:
286
encodeCustom(Global.Table);
289
Logger::queueError(Logger::Error,L"Invalid encoding type");
293
g_fileManager->advanceMemory(getDataSize());
294
return oldSize != getDataSize();
297
void CDirectiveData::Encode() const
301
case EncodingMode::Sjis:
302
case EncodingMode::Custom:
303
g_fileManager->write(customData.data(),customData.size());
305
case EncodingMode::U8:
306
case EncodingMode::Ascii:
307
for (auto value: normalData)
309
g_fileManager->writeU8((u8)value);
312
case EncodingMode::U16:
313
for (auto value: normalData)
315
g_fileManager->writeU16((u16)value);
318
case EncodingMode::U32:
319
case EncodingMode::Float:
320
for (auto value: normalData)
322
g_fileManager->writeU32((u32)value);
328
void CDirectiveData::writeTempData(TempData& tempData) const
330
size_t size = (getUnitSize()*2+3)*getDataSize()+20;
331
wchar_t* str = new wchar_t[size];
332
wchar_t* start = str;
336
case EncodingMode::Sjis:
337
case EncodingMode::Custom:
338
str += swprintf(str,20,L".byte ");
340
for (size_t i = 0; i < customData.size(); i++)
342
str += swprintf(str,20,L"0x%02X,",(u8)customData[i]);
345
case EncodingMode::U8:
346
case EncodingMode::Ascii:
347
str += swprintf(str,20,L".byte ");
349
for (size_t i = 0; i < normalData.size(); i++)
351
str += swprintf(str,20,L"0x%02X,",(u8)normalData[i]);
354
case EncodingMode::U16:
355
str += swprintf(str,20,L".halfword ");
357
for (size_t i = 0; i < normalData.size(); i++)
359
str += swprintf(str,20,L"0x%04X,",(u16)normalData[i]);
362
case EncodingMode::U32:
363
case EncodingMode::Float:
364
str += swprintf(str,20,L".word ");
366
for (size_t i = 0; i < normalData.size(); i++)
368
str += swprintf(str,20,L"0x%08X,",(u32)normalData[i]);
374
tempData.writeLine(position,start);
378
void CDirectiveData::writeSymData(SymbolData& symData) const
382
case EncodingMode::Ascii:
383
symData.addData(position,getDataSize(),SymbolData::DataAscii);
385
case EncodingMode::U8:
386
case EncodingMode::Sjis:
387
case EncodingMode::Custom:
388
symData.addData(position,getDataSize(),SymbolData::Data8);
390
case EncodingMode::U16:
391
symData.addData(position,getDataSize(),SymbolData::Data16);
393
case EncodingMode::U32:
394
case EncodingMode::Float:
395
symData.addData(position,getDataSize(),SymbolData::Data32);