~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to ext/armips/Commands/CDirectiveData.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "stdafx.h"
 
2
#include "Commands/CDirectiveData.h"
 
3
#include "Core/Common.h"
 
4
#include "Core/FileManager.h"
 
5
 
 
6
//
 
7
// TableCommand
 
8
//
 
9
 
 
10
TableCommand::TableCommand(const std::wstring& fileName, TextFile::Encoding encoding)
 
11
{
 
12
        if (fileExists(fileName) == false)
 
13
        {
 
14
                Logger::printError(Logger::Error,L"Table file \"%s\" does not exist",fileName);
 
15
                return;
 
16
        }
 
17
 
 
18
        if (table.load(fileName,encoding) == false)
 
19
        {
 
20
                Logger::printError(Logger::Error,L"Invalid table file \"%s\"",fileName);
 
21
                return;
 
22
        }
 
23
}
 
24
 
 
25
bool TableCommand::Validate()
 
26
{
 
27
        Global.Table = table;
 
28
        return false;
 
29
}
 
30
 
 
31
 
 
32
//
 
33
// CDirectiveData
 
34
//
 
35
 
 
36
CDirectiveData::CDirectiveData()
 
37
{
 
38
        mode = EncodingMode::Invalid;
 
39
        writeTermination = false;
 
40
        endianness = Arch->getEndianness();
 
41
}
 
42
 
 
43
CDirectiveData::~CDirectiveData()
 
44
{
 
45
 
 
46
}
 
47
 
 
48
void CDirectiveData::setNormal(std::vector<Expression>& entries, size_t unitSize, bool ascii)
 
49
{
 
50
        switch (unitSize)
 
51
        {
 
52
        case 1:
 
53
                if (ascii)
 
54
                        this->mode = EncodingMode::Ascii;
 
55
                else
 
56
                        this->mode = EncodingMode::U8;
 
57
                break;
 
58
        case 2:
 
59
                this->mode = EncodingMode::U16;
 
60
                break;
 
61
        case 4:
 
62
                this->mode = EncodingMode::U32;
 
63
                break;
 
64
        default:
 
65
                Logger::printError(Logger::Error,L"Invalid data unit size %d",unitSize);
 
66
                return;
 
67
        }
 
68
        
 
69
        this->entries = entries;
 
70
        this->writeTermination = false;
 
71
        normalData.reserve(entries.size());
 
72
}
 
73
 
 
74
void CDirectiveData::setFloat(std::vector<Expression>& entries)
 
75
{
 
76
        this->mode = EncodingMode::Float;
 
77
        this->entries = entries;
 
78
        this->writeTermination = false;
 
79
}
 
80
 
 
81
void CDirectiveData::setSjis(std::vector<Expression>& entries, bool terminate)
 
82
{
 
83
        this->mode = EncodingMode::Sjis;
 
84
        this->entries = entries;
 
85
        this->writeTermination = terminate;
 
86
}
 
87
 
 
88
void CDirectiveData::setCustom(std::vector<Expression>& entries, bool terminate)
 
89
{
 
90
        this->mode = EncodingMode::Custom;
 
91
        this->entries = entries;
 
92
        this->writeTermination = terminate;
 
93
}
 
94
 
 
95
size_t CDirectiveData::getUnitSize() const
 
96
{
 
97
        switch (mode)
 
98
        {
 
99
        case EncodingMode::U8:
 
100
        case EncodingMode::Ascii:
 
101
        case EncodingMode::Sjis:
 
102
        case EncodingMode::Custom:
 
103
                return 1;
 
104
        case EncodingMode::U16:
 
105
                return 2;
 
106
        case EncodingMode::U32:
 
107
        case EncodingMode::Float:
 
108
                return 4;
 
109
        }
 
110
 
 
111
        return 0;
 
112
}
 
113
 
 
114
size_t CDirectiveData::getDataSize() const
 
115
{
 
116
        switch (mode)
 
117
        {
 
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();
 
127
        }
 
128
 
 
129
        return 0;
 
130
}
 
131
 
 
132
void CDirectiveData::encodeCustom(EncodingTable& table)
 
133
{
 
134
        customData.clear();
 
135
        for (size_t i = 0; i < entries.size(); i++)
 
136
        {
 
137
                ExpressionValue value = entries[i].evaluate();
 
138
                if (!value.isValid())
 
139
                {
 
140
                        Logger::queueError(Logger::Error,L"Invalid expression");
 
141
                        continue;
 
142
                }
 
143
                
 
144
                if (value.isInt())
 
145
                {
 
146
                        customData.appendByte((u8)value.intValue);
 
147
                } else if (value.isString())
 
148
                {
 
149
                        ByteArray encoded = table.encodeString(value.strValue,false);
 
150
                        if (encoded.size() == 0 && value.strValue.size() > 0)
 
151
                        {
 
152
                                Logger::queueError(Logger::Error,L"Failed to encode \"%s\"",value.strValue);
 
153
                        }
 
154
                        customData.append(encoded);
 
155
                } else {
 
156
                        Logger::queueError(Logger::Error,L"Invalid expression type");
 
157
                }
 
158
        }
 
159
 
 
160
        if (writeTermination)
 
161
        {
 
162
                ByteArray encoded = table.encodeTermination();
 
163
                customData.append(encoded);
 
164
        }
 
165
}
 
166
 
 
167
void CDirectiveData::encodeSjis()
 
168
{
 
169
        static EncodingTable sjisTable;
 
170
        if (sjisTable.isLoaded() == false)
 
171
        {
 
172
                unsigned char hexBuffer[2];
 
173
                
 
174
                sjisTable.setTerminationEntry((unsigned char*)"\0",1);
 
175
 
 
176
                for (unsigned short SJISValue = 0x0001; SJISValue < 0x0100; SJISValue++)
 
177
                {
 
178
                        wchar_t unicodeValue = sjisToUnicode(SJISValue);
 
179
                        if (unicodeValue != 0xFFFF)
 
180
                        {
 
181
                                hexBuffer[0] = SJISValue & 0xFF;
 
182
                                sjisTable.addEntry(hexBuffer, 1, unicodeValue);
 
183
                        }
 
184
                }
 
185
                for (unsigned short SJISValue = 0x8100; SJISValue < 0xEF00; SJISValue++)
 
186
                {
 
187
                        wchar_t unicodeValue = sjisToUnicode(SJISValue);
 
188
                        if (unicodeValue != 0xFFFF)
 
189
                        {
 
190
                                hexBuffer[0] = (SJISValue >> 8) & 0xFF;
 
191
                                hexBuffer[1] = SJISValue & 0xFF;
 
192
                                sjisTable.addEntry(hexBuffer, 2, unicodeValue);
 
193
                        }
 
194
                }
 
195
        }
 
196
 
 
197
        encodeCustom(sjisTable);
 
198
}
 
199
 
 
200
void CDirectiveData::encodeFloat()
 
201
{
 
202
        normalData.clear();
 
203
        for (size_t i = 0; i < entries.size(); i++)
 
204
        {
 
205
                ExpressionValue value = entries[i].evaluate();
 
206
                if (!value.isValid())
 
207
                {
 
208
                        Logger::queueError(Logger::Error,L"Invalid expression");
 
209
                        continue;
 
210
                }
 
211
 
 
212
                if (value.isInt())
 
213
                {
 
214
                        u32 num = getFloatBits((float)value.intValue);
 
215
                        normalData.push_back(num);
 
216
                } else if (value.isFloat())
 
217
                {
 
218
                        u32 num = getFloatBits((float)value.floatValue);
 
219
                        normalData.push_back(num);
 
220
                } else {
 
221
                        Logger::queueError(Logger::Error,L"Invalid expression type");
 
222
                }
 
223
        }
 
224
}
 
225
 
 
226
void CDirectiveData::encodeNormal()
 
227
{
 
228
        normalData.clear();
 
229
        for (size_t i = 0; i < entries.size(); i++)
 
230
        {
 
231
                ExpressionValue value = entries[i].evaluate();
 
232
                if (!value.isValid())
 
233
                {
 
234
                        Logger::queueError(Logger::Error,L"Invalid expression");
 
235
                        continue;
 
236
                }
 
237
 
 
238
                if (value.isString())
 
239
                {
 
240
                        bool hadNonAscii = false;
 
241
                        for (size_t l = 0; l < value.strValue.size(); l++)
 
242
                        {
 
243
                                u64 num = value.strValue[l];
 
244
                                normalData.push_back((u32)num);
 
245
 
 
246
                                if (num >= 0x80 && hadNonAscii == false)
 
247
                                {
 
248
                                        Logger::printError(Logger::Warning,L"Non-ASCII character in data directive. Use .string instead");
 
249
                                        hadNonAscii = true;
 
250
                                }
 
251
                        }
 
252
                } else if (value.isInt())
 
253
                {
 
254
                        u64 num = value.intValue;
 
255
                        normalData.push_back((u32)num);
 
256
                } else if (value.isFloat() && mode == EncodingMode::U32)
 
257
                {
 
258
                        u32 num = getFloatBits((float)value.floatValue);
 
259
                        normalData.push_back(num);
 
260
                } else {
 
261
                        Logger::queueError(Logger::Error,L"Invalid expression type");
 
262
                }
 
263
        }
 
264
}
 
265
 
 
266
bool CDirectiveData::Validate()
 
267
{
 
268
        position = g_fileManager->getVirtualAddress();
 
269
 
 
270
        size_t oldSize = getDataSize();
 
271
        switch (mode)
 
272
        {
 
273
        case EncodingMode::U8:
 
274
        case EncodingMode::U16:
 
275
        case EncodingMode::U32:
 
276
        case EncodingMode::Ascii:
 
277
                encodeNormal();
 
278
                break;
 
279
        case EncodingMode::Float:
 
280
                encodeFloat();
 
281
                break;
 
282
        case EncodingMode::Sjis:
 
283
                encodeSjis();
 
284
                break;
 
285
        case EncodingMode::Custom:
 
286
                encodeCustom(Global.Table);
 
287
                break;
 
288
        default:
 
289
                Logger::queueError(Logger::Error,L"Invalid encoding type");
 
290
                break;
 
291
        }
 
292
 
 
293
        g_fileManager->advanceMemory(getDataSize());
 
294
        return oldSize != getDataSize();
 
295
}
 
296
 
 
297
void CDirectiveData::Encode() const
 
298
{
 
299
        switch (mode)
 
300
        {
 
301
        case EncodingMode::Sjis:
 
302
        case EncodingMode::Custom:
 
303
                g_fileManager->write(customData.data(),customData.size());
 
304
                break;
 
305
        case EncodingMode::U8:
 
306
        case EncodingMode::Ascii:
 
307
                for (auto value: normalData)
 
308
                {
 
309
                        g_fileManager->writeU8((u8)value);
 
310
                }
 
311
                break;
 
312
        case EncodingMode::U16:
 
313
                for (auto value: normalData)
 
314
                {
 
315
                        g_fileManager->writeU16((u16)value);
 
316
                }
 
317
                break;
 
318
        case EncodingMode::U32:
 
319
        case EncodingMode::Float:
 
320
                for (auto value: normalData)
 
321
                {
 
322
                        g_fileManager->writeU32((u32)value);
 
323
                }
 
324
                break;
 
325
        }
 
326
}
 
327
 
 
328
void CDirectiveData::writeTempData(TempData& tempData) const
 
329
{
 
330
        size_t size = (getUnitSize()*2+3)*getDataSize()+20;
 
331
        wchar_t* str = new wchar_t[size];
 
332
        wchar_t* start = str;
 
333
 
 
334
        switch (mode)
 
335
        {
 
336
        case EncodingMode::Sjis:
 
337
        case EncodingMode::Custom:
 
338
                str += swprintf(str,20,L".byte ");
 
339
 
 
340
                for (size_t i = 0; i < customData.size(); i++)
 
341
                {
 
342
                        str += swprintf(str,20,L"0x%02X,",(u8)customData[i]);
 
343
                }
 
344
                break;
 
345
        case EncodingMode::U8:
 
346
        case EncodingMode::Ascii:
 
347
                str += swprintf(str,20,L".byte ");
 
348
                
 
349
                for (size_t i = 0; i < normalData.size(); i++)
 
350
                {
 
351
                        str += swprintf(str,20,L"0x%02X,",(u8)normalData[i]);
 
352
                }
 
353
                break;
 
354
        case EncodingMode::U16:
 
355
                str += swprintf(str,20,L".halfword ");
 
356
 
 
357
                for (size_t i = 0; i < normalData.size(); i++)
 
358
                {
 
359
                        str += swprintf(str,20,L"0x%04X,",(u16)normalData[i]);
 
360
                }
 
361
                break;
 
362
        case EncodingMode::U32:
 
363
        case EncodingMode::Float:
 
364
                str += swprintf(str,20,L".word ");
 
365
 
 
366
                for (size_t i = 0; i < normalData.size(); i++)
 
367
                {
 
368
                        str += swprintf(str,20,L"0x%08X,",(u32)normalData[i]);
 
369
                }
 
370
                break;
 
371
        }
 
372
 
 
373
        *(str-1) = 0;
 
374
        tempData.writeLine(position,start);
 
375
        delete[] start;
 
376
}
 
377
 
 
378
void CDirectiveData::writeSymData(SymbolData& symData) const
 
379
{
 
380
        switch (mode)
 
381
        {
 
382
        case EncodingMode::Ascii:
 
383
                symData.addData(position,getDataSize(),SymbolData::DataAscii);
 
384
                break;
 
385
        case EncodingMode::U8:
 
386
        case EncodingMode::Sjis:
 
387
        case EncodingMode::Custom:
 
388
                symData.addData(position,getDataSize(),SymbolData::Data8);
 
389
                break;
 
390
        case EncodingMode::U16:
 
391
                symData.addData(position,getDataSize(),SymbolData::Data16);
 
392
                break;
 
393
        case EncodingMode::U32:
 
394
        case EncodingMode::Float:
 
395
                symData.addData(position,getDataSize(),SymbolData::Data32);
 
396
                break;
 
397
        }
 
398
}