xoreos  0.0.5
ltrfile.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/strutil.h"
26 
27 #include "src/aurora/ltrfile.h"
28 #include "src/aurora/resman.h"
29 
30 static const uint32 kLTRID = MKTAG('L', 'T', 'R', ' ');
31 static const uint32 kVersion10 = MKTAG('V', '1', '.', '0');
32 
33 // TODO: Check for non-latin language alphabets
34 static const char *kLetters28 = "abcdefghijklmnopqrstuvwxyz'-";
35 static const char *kLetters26 = "abcdefghijklmnopqrstuvwxyz";
36 
37 namespace Aurora {
38 
41  load(*stream);
42 }
43 
45  load(stream);
46 }
47 
48 size_t LTRFile::getLetterCount() const {
49  return _letterCount;
50 }
51 
52 Common::UString LTRFile::generateRandomName(size_t maxLetters) const {
53  // TODO: There is a lot of data yet unused in the letter files.
54  Common::UString name;
55  float probability;
56  int firstLetterIndex = 0;
57  int secondLetterIndex = 0;
58 
59  if (maxLetters < 4)
60  throw Common::Exception(
61  "Invalid maximal letters. A name has to be at least 4 letters, %i given",
62  static_cast<int>(maxLetters));
63 
64  // Get the first three letters.
65  probability = static_cast<float>(std::rand())/RAND_MAX;
66  for (int i = 0; i < _letterCount; ++i) {
67  if (_singleLetters.start[i] > probability) {
68  // Make the first letter upper case.
69  name += Common::UString::toUpper(static_cast<uint32>(_alphabet[i]));
70  firstLetterIndex = i;
71  break;
72  }
73  }
74 
75  probability = static_cast<float>(std::rand())/RAND_MAX;
76  for (int i = 0; i < _letterCount; ++i) {
77  if (_doubleLetters[firstLetterIndex].start[i] > probability) {
78  name += _alphabet[i];
79  secondLetterIndex = i;
80  break;
81  }
82  }
83 
84  probability = static_cast<float>(std::rand())/RAND_MAX;
85  for (int i = 0; i < _letterCount; ++i) {
86  if (_tripleLetters[firstLetterIndex][secondLetterIndex].start[i] > probability) {
87  name += _alphabet[i];
88  firstLetterIndex = secondLetterIndex;
89  secondLetterIndex = i;
90  break;
91  }
92  }
93 
94  // Generate as much letters as max letters minus start letters minus end letters plus one are given.
95  const size_t length = (maxLetters > 4) ? (std::rand() % (maxLetters - 3)) : 0;
96 
97  for (size_t i = 0; i < length; ++i) {
98  probability = static_cast<float>(std::rand())/RAND_MAX;
99  for (int j = 0; j < _letterCount; ++j) {
100  if (_tripleLetters[firstLetterIndex][secondLetterIndex].mid[j] > probability) {
101  name += _alphabet[j];
102  firstLetterIndex = secondLetterIndex;
103  secondLetterIndex = j;
104  break;
105  }
106  }
107  }
108 
109  // Append end letter.
110  probability = static_cast<float>(std::rand())/RAND_MAX;
111  for (int j = 0; j < _letterCount; ++j) {
112  if (_tripleLetters[firstLetterIndex][secondLetterIndex].end[j] > probability) {
113  name += _alphabet[j];
114  break;
115  }
116  }
117 
118  return name;
119 }
120 
122  readHeader(stream);
123 
124  if (_id != kLTRID)
125  throw Common::Exception("Not a LTR file (%s)", Common::debugTag(_id).c_str());
126 
127  if (_version != kVersion10)
128  throw Common::Exception("Unsupported LTR file version %s", Common::debugTag(_version).c_str());
129 
130  _letterCount = stream.readByte();
131  switch (_letterCount) {
132  case 26:
133  _alphabet.reset(new char[26]);
134  memcpy(_alphabet.get(), kLetters26, 26);
135  break;
136  case 28:
137  _alphabet.reset(new char[28]);
138  memcpy(_alphabet.get(), kLetters28, 28);
139  break;
140  default:
141  throw Common::Exception("Unsupported Letter count %i", _letterCount);
142  }
143 
145  _singleLetters.mid.reset(new float[_letterCount]);
146  _singleLetters.end.reset(new float[_letterCount]);
147  for (int i = 0; i < _letterCount; ++i)
148  _singleLetters.start[i] = stream.readIEEEFloatLE();
149  for (int i = 0; i < _letterCount; ++i)
150  _singleLetters.mid[i] = stream.readIEEEFloatLE();
151  for (int i = 0; i < _letterCount; ++i)
152  _singleLetters.end[i] = stream.readIEEEFloatLE();
153 
155  for (int i = 0; i < _letterCount; ++i) {
156  _doubleLetters[i].start.reset(new float[_letterCount]);
157  _doubleLetters[i].mid.reset(new float[_letterCount]);
158  _doubleLetters[i].end.reset(new float[_letterCount]);
159  for (int j = 0; j < _letterCount; ++j)
160  _doubleLetters[i].start[j] = stream.readIEEEFloatLE();
161  for (int j = 0; j < _letterCount; ++j)
162  _doubleLetters[i].mid[j] = stream.readIEEEFloatLE();
163  for (int j = 0; j < _letterCount; ++j)
164  _doubleLetters[i].end[j] = stream.readIEEEFloatLE();
165  }
166 
168  for (int i = 0; i < _letterCount; ++i) {
169  _tripleLetters[i].reset(new LetterSet[_letterCount]);
170  for (int j = 0; j < _letterCount; ++j) {
171  _tripleLetters[i][j].start.reset(new float[_letterCount]);
172  _tripleLetters[i][j].mid.reset(new float[_letterCount]);
173  _tripleLetters[i][j].end.reset(new float[_letterCount]);
174  for (int k = 0; k < _letterCount; ++k)
175  _tripleLetters[i][j].start[k] = stream.readIEEEFloatLE();
176  for (int k = 0; k < _letterCount; ++k)
177  _tripleLetters[i][j].mid[k] = stream.readIEEEFloatLE();
178  for (int k = 0; k < _letterCount; ++k)
179  _tripleLetters[i][j].end[k] = stream.readIEEEFloatLE();
180  }
181  }
182 }
183 
184 } // End of namespace Aurora
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
static const char * kLetters26
Definition: ltrfile.cpp:35
A class holding an UTF-8 string.
Definition: ustring.h:48
static const char * kLetters28
Definition: ltrfile.cpp:34
Common::ScopedArray< float > mid
Definition: ltrfile.h:60
Common::ScopedArray< float > end
Definition: ltrfile.h:61
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
static const uint32 kVersion10
Definition: erfwriter.cpp:31
Utility templates and functions for working with strings and streams.
static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le)
Read the header out of a stream.
Definition: aurorafile.cpp:53
Letter combo probability information.
Definition: types.h:101
Common::ScopedArray< Common::ScopedArray< LetterSet > > _tripleLetters
Definition: ltrfile.h:69
Common::UString generateRandomName(size_t maxLetters) const
Generate a random name from the ltr file.
Definition: ltrfile.cpp:52
LetterSet _singleLetters
Definition: ltrfile.h:67
uint32 _id
The file&#39;s ID.
Definition: aurorafile.h:77
LTRFile(const Common::UString &ltr)
Definition: ltrfile.cpp:39
StackException Exception
Definition: error.h:59
uint32 _version
The file&#39;s version.
Definition: aurorafile.h:78
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:230
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
Common::ScopedArray< float > start
Definition: ltrfile.h:59
uint32_t uint32
Definition: types.h:204
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
Definition: strutil.cpp:117
Common::ScopedArray< char > _alphabet
Definition: ltrfile.h:64
size_t getLetterCount() const
Get the letter count utilized by the ltr file.
Definition: ltrfile.cpp:48
static const uint32 kVersion10
Definition: ltrfile.cpp:31
A scoped array pointer, allowing array-y access and array deletion.
Definition: scopedptr.h:137
void load(Common::SeekableReadStream &stream)
Definition: ltrfile.cpp:121
UString toUpper() const
Return an uppercased copy of the string.
Definition: ustring.cpp:491
static const uint32 kLTRID
Definition: ltrfile.cpp:30
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Common::ScopedArray< LetterSet > _doubleLetters
Definition: ltrfile.h:68
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
File for creating random names in the character generation.
The global resource manager for Aurora resources.
uint8 _letterCount
Definition: ltrfile.h:65