Initial commit
This commit is contained in:
185
engines/ags/shared/ac/words_dictionary.cpp
Normal file
185
engines/ags/shared/ac/words_dictionary.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/* 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
|
||||
Reference in New Issue
Block a user