186 lines
4.4 KiB
C++
186 lines
4.4 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/std/algorithm.h"
|
|
#include "ags/shared/ac/words_dictionary.h"
|
|
#include "ags/shared/util/stream.h"
|
|
#include "ags/shared/util/string_compat.h"
|
|
#include "ags/globals.h"
|
|
|
|
namespace AGS3 {
|
|
|
|
using namespace AGS::Shared;
|
|
|
|
WordsDictionary::WordsDictionary()
|
|
: num_words(0)
|
|
, word(nullptr)
|
|
, wordnum(nullptr) {
|
|
}
|
|
|
|
WordsDictionary::~WordsDictionary() {
|
|
free_memory();
|
|
}
|
|
|
|
void WordsDictionary::allocate_memory(int wordCount) {
|
|
num_words = wordCount;
|
|
if (num_words > 0) {
|
|
word = new char *[wordCount];
|
|
word[0] = new char[wordCount * MAX_PARSER_WORD_LENGTH];
|
|
wordnum = new short[wordCount];
|
|
for (int i = 1; i < wordCount; i++) {
|
|
word[i] = word[0] + MAX_PARSER_WORD_LENGTH * i;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WordsDictionary::free_memory() {
|
|
if (num_words > 0) {
|
|
delete[] word[0];
|
|
delete[] word;
|
|
delete[] wordnum;
|
|
word = nullptr;
|
|
wordnum = nullptr;
|
|
num_words = 0;
|
|
}
|
|
}
|
|
|
|
void WordsDictionary::sort() {
|
|
int aa, bb;
|
|
for (aa = 0; aa < num_words; aa++) {
|
|
for (bb = aa + 1; bb < num_words; bb++) {
|
|
if (((wordnum[aa] == wordnum[bb]) && (ags_stricmp(word[aa], word[bb]) > 0))
|
|
|| (wordnum[aa] > wordnum[bb])) {
|
|
short temp = wordnum[aa];
|
|
char tempst[30];
|
|
|
|
wordnum[aa] = wordnum[bb];
|
|
wordnum[bb] = temp;
|
|
snprintf(tempst, MAX_PARSER_WORD_LENGTH, "%s", word[aa]);
|
|
snprintf(word[aa], MAX_PARSER_WORD_LENGTH, "%s", word[bb]);
|
|
snprintf(word[bb], MAX_PARSER_WORD_LENGTH, "%s", tempst);
|
|
bb = aa;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int WordsDictionary::find_index(const char *wrem) {
|
|
int aa;
|
|
for (aa = 0; aa < num_words; aa++) {
|
|
if (ags_stricmp(wrem, word[aa]) == 0)
|
|
return aa;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void decrypt_text(char *toenc, size_t buf_sz) {
|
|
int adx = 0;
|
|
const char *p_end = toenc + buf_sz;
|
|
|
|
while (toenc < p_end) {
|
|
toenc[0] -= _G(passwencstring)[adx];
|
|
if (toenc[0] == 0)
|
|
break;
|
|
|
|
adx++;
|
|
toenc++;
|
|
|
|
if (adx > 10)
|
|
adx = 0;
|
|
}
|
|
}
|
|
|
|
void read_string_decrypt(Stream *in, char *buf, size_t buf_sz) {
|
|
size_t len = in->ReadInt32();
|
|
size_t slen = MIN(buf_sz - 1, len);
|
|
in->Read(buf, slen);
|
|
if (len > slen)
|
|
in->Seek(len - slen);
|
|
decrypt_text(buf, slen);
|
|
buf[slen] = 0;
|
|
}
|
|
|
|
String read_string_decrypt(Stream *in, std::vector<char> &dec_buf) {
|
|
size_t len = in->ReadInt32();
|
|
dec_buf.resize(len + 1);
|
|
in->Read(dec_buf.data(), len);
|
|
decrypt_text(dec_buf.data(), len);
|
|
dec_buf.back() = 0; // null terminate in case read string does not have one
|
|
return String(dec_buf.data());
|
|
}
|
|
|
|
void read_dictionary(WordsDictionary *dict, Stream *out) {
|
|
int ii;
|
|
|
|
dict->allocate_memory(out->ReadInt32());
|
|
for (ii = 0; ii < dict->num_words; ii++) {
|
|
read_string_decrypt(out, dict->word[ii], MAX_PARSER_WORD_LENGTH);
|
|
dict->wordnum[ii] = out->ReadInt16();
|
|
}
|
|
}
|
|
|
|
#if defined (OBSOLETE)
|
|
// TODO: not a part of wordsdictionary, move to obsoletes
|
|
void freadmissout(short *pptr, Stream *in) {
|
|
in->ReadArrayOfInt16(&pptr[0], 5);
|
|
in->ReadArrayOfInt16(&pptr[7], NUM_CONDIT - 7);
|
|
pptr[5] = pptr[6] = 0;
|
|
}
|
|
#endif
|
|
|
|
void encrypt_text(char *toenc) {
|
|
int adx = 0, tobreak = 0;
|
|
|
|
while (tobreak == 0) {
|
|
if (toenc[0] == 0)
|
|
tobreak = 1;
|
|
|
|
toenc[0] += _G(passwencstring)[adx];
|
|
adx++;
|
|
toenc++;
|
|
|
|
if (adx > 10)
|
|
adx = 0;
|
|
}
|
|
}
|
|
|
|
void write_string_encrypt(Stream *out, const char *s) {
|
|
int stlent = (int)strlen(s) + 1;
|
|
|
|
out->WriteInt32(stlent);
|
|
char *enc = ags_strdup(s);
|
|
encrypt_text(enc);
|
|
out->WriteArray(enc, stlent, 1);
|
|
free(enc);
|
|
}
|
|
|
|
void write_dictionary(WordsDictionary *dict, Stream *out) {
|
|
int ii;
|
|
|
|
out->WriteInt32(dict->num_words);
|
|
for (ii = 0; ii < dict->num_words; ii++) {
|
|
write_string_encrypt(out, dict->word[ii]);
|
|
out->WriteInt16(dict->wordnum[ii]);
|
|
}
|
|
}
|
|
|
|
} // namespace AGS3
|