Initial commit
This commit is contained in:
183
engines/glk/jacl/constants.h
Normal file
183
engines/glk/jacl/constants.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#define MAX_WORDS 20
|
||||
#define STACK_SIZE 20
|
||||
#define MAX_UNDO 100
|
||||
#define MAX_OBJECTS 1000
|
||||
|
||||
/* LOCATION ATTRIBUTE VALUES */
|
||||
|
||||
#define VISITED 1
|
||||
#define DARK 2
|
||||
#define ON_WATER 4
|
||||
#define UNDER_WATER 8
|
||||
#define WITHOUT_AIR 16
|
||||
#define OUTDOORS 32
|
||||
#define MID_AIR 64
|
||||
#define TIGHT_ROPE 128
|
||||
#define POLLUTED 256
|
||||
#define SOLVED 512
|
||||
#define MID_WATER 1024
|
||||
#define DARKNESS 2048
|
||||
#define MAPPED 4096
|
||||
#define KNOWN 8192
|
||||
|
||||
/* OBJECT ATTRIBUTE VALUES */
|
||||
|
||||
#define CLOSED 1
|
||||
#define LOCKED 2
|
||||
#define DEAD 4
|
||||
#define IGNITABLE 8
|
||||
#define WORN 16
|
||||
#define CONCEALING 32
|
||||
#define LUMINOUS 64
|
||||
#define WEARABLE 128
|
||||
#define CLOSABLE 256
|
||||
#define LOCKABLE 512
|
||||
#define ANIMATE 1024
|
||||
#define LIQUID 2048
|
||||
#define CONTAINER 4096
|
||||
#define SURFACE 8192
|
||||
#define PLURAL 16384
|
||||
#define FLAMMABLE 32768
|
||||
#define BURNING 65536
|
||||
#define LOCATION 131072
|
||||
#define ON 262144
|
||||
#define DAMAGED 524288
|
||||
#define FEMALE 1048576
|
||||
#define POSSESSIVE 2097152
|
||||
#define OUT_OF_REACH 4194304
|
||||
#define TOUCHED 8388608
|
||||
#define SCORED 16777216
|
||||
#define SITTING 33554432
|
||||
#define NPC 67108864
|
||||
#define DONE 134217728
|
||||
#define GAS 268435456
|
||||
#define NO_TAB 536870912
|
||||
#define NOT_IMPORTANT 1073741824
|
||||
|
||||
/* LOCATION INTEGER ARRAY INDEXES */
|
||||
|
||||
#define NORTH_DIR 0
|
||||
#define SOUTH_DIR 1
|
||||
#define EAST_DIR 2
|
||||
#define WEST_DIR 3
|
||||
#define NORTHEAST_DIR 4
|
||||
#define NORTHWEST_DIR 5
|
||||
#define SOUTHEAST_DIR 6
|
||||
#define SOUTHWEST_DIR 7
|
||||
#define UP_DIR 8
|
||||
#define DOWN_DIR 9
|
||||
#define IN_DIR 10
|
||||
#define OUT_DIR 11
|
||||
|
||||
/* ALL UP, THERE ARE 16 OBJECT ELEMENTS, THESE 6
|
||||
ARE THE ONLY ONES ACCESSED BY THE INTERPRETER */
|
||||
|
||||
#define PARENT integer[0]
|
||||
#define QUANTITY integer[1]
|
||||
#define MASS integer[2]
|
||||
#define BEARING integer[3]
|
||||
#define VELOCITY integer[4]
|
||||
#define X integer[14]
|
||||
#define Y integer[15]
|
||||
|
||||
/* SYSTEM VARIABLES */
|
||||
|
||||
#define COMPASS integer_resolve("compass")
|
||||
#define DESTINATION integer_resolve("destination")
|
||||
#define TOTAL_MOVES integer_resolve("total_moves")
|
||||
#define TIME integer_resolve("time")
|
||||
#define SCORE integer_resolve("score")
|
||||
#define INTERNAL_VERSION integer_resolve("internal_version")
|
||||
#define DISPLAY_MODE integer_resolve("display_mode")
|
||||
#define MAX_RAND integer_resolve("max_rand")
|
||||
#define INTERRUPTED integer_resolve("interrupted")
|
||||
#define SOUND_ENABLED integer_resolve("sound_enabled")
|
||||
#define GRAPHICS_ENABLED integer_resolve("graphics_enabled")
|
||||
#define TIMER_ENABLED integer_resolve("timer_enabled")
|
||||
#define MULTI_PREFIX integer_resolve("multi_prefix")
|
||||
#define NOTIFY integer_resolve("notify")
|
||||
#define DEBUG integer_resolve("debug")
|
||||
|
||||
/* SYSTEM INTEGER CONSTANTS */
|
||||
|
||||
#define SOUND_SUPPORTED cinteger_resolve("sound_supported")
|
||||
#define GRAPHICS_SUPPORTED cinteger_resolve("graphics_supported")
|
||||
#define TIMER_SUPPORTED cinteger_resolve("timer_supported")
|
||||
|
||||
/* ABBREVIATIONS */
|
||||
|
||||
#define HELD player
|
||||
#define HERE get_here()
|
||||
|
||||
/* CONSTANTS */
|
||||
|
||||
#define SYSTEM_ATTRIBUTE 0
|
||||
#define USER_ATTRIBUTE 1
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define UNRESTRICT 0
|
||||
#define RESTRICT 1
|
||||
|
||||
#define SEEK_SET 0
|
||||
|
||||
#define SEEK_END 2
|
||||
|
||||
#define SCENERY 100
|
||||
#define HEAVY 99
|
||||
#define NOWHERE 0
|
||||
|
||||
#define LOG_ONLY 0
|
||||
#define PLUS_STDOUT 1
|
||||
#define PLUS_STDERR 2
|
||||
#define ONLY_STDERR 3
|
||||
#define ONLY_STDOUT 4
|
||||
|
||||
#define INT_TYPE 1
|
||||
#define STR_TYPE 2
|
||||
#define CINT_TYPE 3
|
||||
#define CSTR_TYPE 4
|
||||
#define ATT_TYPE 5
|
||||
#define OBJ_TYPE 6
|
||||
|
||||
#define CRI_NONE 0
|
||||
#define CRI_ATTRIBUTE 1
|
||||
#define CRI_USER_ATTRIBUTE 2
|
||||
#define CRI_PARENT 3
|
||||
#define CRI_SCOPE 4
|
||||
|
||||
#define BOLD 1
|
||||
#define NOTE 2
|
||||
#define INPUT 3
|
||||
#define HEADER 4
|
||||
#define SUBHEADER 5
|
||||
#define REVERSE 6
|
||||
#define PRE 7
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
105
engines/glk/jacl/csv.h
Normal file
105
engines/glk/jacl/csv.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JACL_CSV
|
||||
#define JACL_CSV
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#define CSV_MAJOR 3
|
||||
#define CSV_MINOR 0
|
||||
#define CSV_RELEASE 0
|
||||
|
||||
/* Error Codes */
|
||||
#define CSV_SUCCESS 0
|
||||
#define CSV_EPARSE 1 /* Parse error in strict mode */
|
||||
#define CSV_ENOMEM 2 /* Out of memory while increasing buffer size */
|
||||
#define CSV_ETOOBIG 3 /* Buffer larger than SIZE_MAX needed */
|
||||
#define CSV_EINVALID 4 /* Invalid code,should never be received from csv_error*/
|
||||
|
||||
|
||||
/* parser options */
|
||||
#define CSV_STRICT 1 /* enable strict mode */
|
||||
#define CSV_REPALL_NL 2 /* report all unquoted carriage returns and linefeeds */
|
||||
#define CSV_STRICT_FINI 4 /* causes csv_fini to return CSV_EPARSE if last
|
||||
field is quoted and doesn't containg ending
|
||||
quote */
|
||||
#define CSV_APPEND_NULL 8 /* Ensure that all fields are null-ternimated */
|
||||
|
||||
|
||||
/* Character values */
|
||||
#define CSV_TAB 0x09
|
||||
#define CSV_SPACE 0x20
|
||||
#define CSV_CR 0x0d
|
||||
#define CSV_LF 0x0a
|
||||
#define CSV_COMMA 0x2c
|
||||
#define CSV_QUOTE 0x22
|
||||
|
||||
struct csv_parser {
|
||||
int pstate; /* Parser state */
|
||||
int quoted; /* Is the current field a quoted field? */
|
||||
size_t spaces; /* Number of continious spaces after quote or in a non-quoted field */
|
||||
unsigned char *entry_buf; /* Entry buffer */
|
||||
size_t entry_pos; /* Current position in entry_buf (and current size of entry) */
|
||||
size_t entry_size; /* Size of entry buffer */
|
||||
int status; /* Operation status */
|
||||
unsigned char options;
|
||||
unsigned char quote_char;
|
||||
unsigned char delim_char;
|
||||
int (*is_space)(unsigned char);
|
||||
int (*is_term)(unsigned char);
|
||||
size_t blk_size;
|
||||
void *(*malloc_func)(size_t);
|
||||
void *(*realloc_func)(void *, size_t);
|
||||
void (*free_func)(void *);
|
||||
};
|
||||
|
||||
/* Function Prototypes */
|
||||
int csv_init(struct csv_parser *p, unsigned char options);
|
||||
int csv_fini(struct csv_parser *p, void (*cb1)(void *, size_t, void *), void (*cb2)(int, void *), void *data);
|
||||
void csv_free(struct csv_parser *p);
|
||||
int csv_error(struct csv_parser *p);
|
||||
const char *csv_strerror(int error);
|
||||
size_t csv_parse(struct csv_parser *p, const void *s, size_t len, void (*cb1)(void *, size_t, void *), void (*cb2)(int, void *), void *data);
|
||||
size_t csv_write(void *dest, size_t dest_size, const void *src, size_t src_size);
|
||||
int csv_fwrite(Common::WriteStream *fp, const void *src, size_t src_size);
|
||||
size_t csv_write2(void *dest, size_t dest_size, const void *src, size_t src_size, unsigned char quote);
|
||||
int csv_fwrite2(Common::WriteStream *fp, const void *src, size_t src_size, unsigned char quote);
|
||||
int csv_get_opts(struct csv_parser *p);
|
||||
int csv_set_opts(struct csv_parser *p, unsigned char options);
|
||||
void csv_set_delim(struct csv_parser *p, unsigned char c);
|
||||
void csv_set_quote(struct csv_parser *p, unsigned char c);
|
||||
unsigned char csv_get_delim(struct csv_parser *p);
|
||||
unsigned char csv_get_quote(struct csv_parser *p);
|
||||
void csv_set_space_func(struct csv_parser *p, int (*f)(unsigned char));
|
||||
void csv_set_term_func(struct csv_parser *p, int (*f)(unsigned char));
|
||||
void csv_set_realloc_func(struct csv_parser *p, void *(*)(void *, size_t));
|
||||
void csv_set_free_func(struct csv_parser *p, void (*)(void *));
|
||||
void csv_set_blk_size(struct csv_parser *p, size_t);
|
||||
size_t csv_get_buffer_size(struct csv_parser *p);
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
|
||||
#endif
|
||||
96
engines/glk/jacl/detection.cpp
Normal file
96
engines/glk/jacl/detection.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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 "glk/jacl/detection.h"
|
||||
#include "glk/jacl/detection_tables.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/md5.h"
|
||||
#include "engines/game.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
void JACLMetaEngine::getSupportedGames(PlainGameList &games) {
|
||||
for (const PlainGameDescriptor *pd = JACL_GAME_LIST; pd->gameId; ++pd)
|
||||
games.push_back(*pd);
|
||||
}
|
||||
|
||||
const GlkDetectionEntry* JACLMetaEngine::getDetectionEntries() {
|
||||
return JACL_GAMES;
|
||||
}
|
||||
|
||||
GameDescriptor JACLMetaEngine::findGame(const char *gameId) {
|
||||
for (const PlainGameDescriptor *pd = JACL_GAME_LIST; pd->gameId; ++pd) {
|
||||
if (!strcmp(gameId, pd->gameId))
|
||||
return *pd;
|
||||
}
|
||||
|
||||
return GameDescriptor::empty();
|
||||
}
|
||||
|
||||
bool JACLMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
|
||||
// Loop through the files of the folder
|
||||
for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||
// Check for a recognised filename
|
||||
if (file->isDirectory())
|
||||
continue;
|
||||
|
||||
Common::String filename = file->getName();
|
||||
if (!filename.hasSuffixIgnoreCase(".j2") && !filename.hasSuffixIgnoreCase(".jac"))
|
||||
continue;
|
||||
|
||||
Common::File gameFile;
|
||||
if (!gameFile.open(*file))
|
||||
continue;
|
||||
|
||||
gameFile.seek(0);
|
||||
Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
|
||||
uint32 filesize = gameFile.size();
|
||||
|
||||
// Scan through the JACL game list for a match
|
||||
const GlkDetectionEntry *p = JACL_GAMES;
|
||||
while (p->_md5 && p->_filesize != filesize && md5 != p->_md5)
|
||||
++p;
|
||||
|
||||
if (!p->_gameId) {
|
||||
const PlainGameDescriptor &desc = JACL_GAME_LIST[0];
|
||||
gameList.push_back(GlkDetectedGame(desc.gameId, desc.description, filename, md5, filesize));
|
||||
} else {
|
||||
// Found a match
|
||||
PlainGameDescriptor gameDesc = findGame(p->_gameId);
|
||||
gameList.push_back(GlkDetectedGame(p->_gameId, gameDesc.description, p->_extra, filename, p->_language));
|
||||
}
|
||||
}
|
||||
|
||||
return !gameList.empty();
|
||||
}
|
||||
|
||||
void JACLMetaEngine::detectClashes(Common::StringMap &map) {
|
||||
for (const PlainGameDescriptor *pd = JACL_GAME_LIST; pd->gameId; ++pd) {
|
||||
if (map.contains(pd->gameId))
|
||||
error("Duplicate game Id found - %s", pd->gameId);
|
||||
map[pd->gameId] = "";
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
64
engines/glk/jacl/detection.h
Normal file
64
engines/glk/jacl/detection.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JACL_DETECTION
|
||||
#define JACL_DETECTION
|
||||
|
||||
#include "common/fs.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "engines/game.h"
|
||||
#include "glk/detection.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
class JACLMetaEngine {
|
||||
public:
|
||||
/**
|
||||
* Get a list of supported games
|
||||
*/
|
||||
static void getSupportedGames(PlainGameList &games);
|
||||
|
||||
/**
|
||||
* Get the detection entries
|
||||
*/
|
||||
static const GlkDetectionEntry* getDetectionEntries();
|
||||
|
||||
/**
|
||||
* Returns a game description for the given game Id, if it's supported
|
||||
*/
|
||||
static GameDescriptor findGame(const char *gameId);
|
||||
|
||||
/**
|
||||
* Detect supported games
|
||||
*/
|
||||
static bool detectGames(const Common::FSList &fslist, DetectedGames &gameList);
|
||||
|
||||
/**
|
||||
* Check for game Id clashes with other sub-engines
|
||||
*/
|
||||
static void detectClashes(Common::StringMap &map);
|
||||
};
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
|
||||
#endif
|
||||
48
engines/glk/jacl/detection_tables.h
Normal file
48
engines/glk/jacl/detection_tables.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 "engines/game.h"
|
||||
#include "common/language.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
const PlainGameDescriptor JACL_GAME_LIST[] = {
|
||||
{ "bloodyguns", "The Bloody Guns" },
|
||||
{ "eldor", "The Curse of Eldor" }, // Competition 96
|
||||
{ "prisonbreak", "Prisoner Break" },
|
||||
{ "unholygrail", "The Unholy Grail" }, // Competition 97
|
||||
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
const GlkDetectionEntry JACL_GAMES[] = {
|
||||
DT_ENTRY0("bloodyguns", "7c4463e92b1c202f8be485030ef4ace5", 159505),
|
||||
DT_ENTRY1("eldor", "r3/crashing", "c1435d28e7eb577fa58c7456d4fa7009", 168119),
|
||||
DT_ENTRY0("prisonbreak", "e2e85c5e60a63575bf0cd0481f0f3958", 199403),
|
||||
DT_ENTRY1("unholygrail", "original/crashing", "2cf04cb897ba799c17cbeb407be67acb", 456730),
|
||||
DT_ENTRY1("unholygrail", "002", "7d40e485c8cf8c9d5c4958a79337d6c7", 447833),
|
||||
|
||||
DT_END_MARKER
|
||||
};
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
264
engines/glk/jacl/display.cpp
Normal file
264
engines/glk/jacl/display.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern char temp_buffer[];
|
||||
extern char function_name[];
|
||||
|
||||
extern struct object_type *object[];
|
||||
extern struct variable_type *variable[];
|
||||
|
||||
extern const char *word[];
|
||||
|
||||
extern int player;
|
||||
extern int wp;
|
||||
extern int objects;
|
||||
extern int custom_error;
|
||||
|
||||
extern int spaced;
|
||||
|
||||
int check_light(int where) {
|
||||
int index;
|
||||
|
||||
if ((object[where]->attributes & DARK) == FALSE)
|
||||
return (TRUE);
|
||||
else {
|
||||
for (index = 1; index <= objects; index++) {
|
||||
if ((object[index]->attributes & LUMINOUS)
|
||||
&& scope(index, "*present"))
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
char *sentence_output(int index, int capital) {
|
||||
if (!strcmp(object[index]->article, "name")) {
|
||||
Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, object[index]->definite);
|
||||
Common::strcat_s(temp_buffer, 1024, " ");
|
||||
Common::strcat_s(temp_buffer, 1024, object[index]->inventory);
|
||||
}
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return (temp_buffer);
|
||||
}
|
||||
|
||||
char *isnt_output(int index, bool) {
|
||||
if (object[index]->attributes & PLURAL)
|
||||
return (cstring_resolve("ARENT")->value);
|
||||
else
|
||||
return (cstring_resolve("ISNT")->value);
|
||||
}
|
||||
|
||||
char *is_output(int index, bool) {
|
||||
if (object[index]->attributes & PLURAL)
|
||||
return (cstring_resolve("ARE")->value);
|
||||
else
|
||||
return (cstring_resolve("IS")->value);
|
||||
}
|
||||
|
||||
char *sub_output(int index, int capital) {
|
||||
if (object[index]->attributes & PLURAL) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THEY_WORD")->value);
|
||||
} else {
|
||||
if (index == player) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("YOU_WORD")->value);
|
||||
} else if (object[index]->attributes & ANIMATE) {
|
||||
if (object[index]->attributes & FEMALE) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("SHE_WORD")->value);
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HE_WORD")->value);
|
||||
}
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("IT_WORD")->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return temp_buffer;
|
||||
}
|
||||
|
||||
char *obj_output(int index, int capital) {
|
||||
if (object[index]->attributes & PLURAL) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THEM_WORD")->value);
|
||||
} else {
|
||||
if (index == player) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("YOURSELF_WORD")->value);
|
||||
} else if (object[index]->attributes & ANIMATE) {
|
||||
if (object[index]->attributes & FEMALE) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HER_WORD")->value);
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("HIM_WORD")->value);
|
||||
}
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("IT_WORD")->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return temp_buffer;
|
||||
}
|
||||
|
||||
char *it_output(int index, bool) {
|
||||
if (object[index]->attributes & ANIMATE) {
|
||||
return sentence_output(index, FALSE);
|
||||
} else {
|
||||
if (object[index]->attributes & PLURAL) {
|
||||
return (cstring_resolve("THEM_WORD")->value);
|
||||
} else {
|
||||
return (cstring_resolve("IT_WORD")->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *that_output(int index, int capital) {
|
||||
if (object[index]->attributes & PLURAL) {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THOSE_WORD")->value);
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, cstring_resolve("THAT_WORD")->value);
|
||||
}
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return temp_buffer;
|
||||
}
|
||||
|
||||
char *doesnt_output(int index, bool) {
|
||||
if (object[index]->attributes & PLURAL)
|
||||
return (cstring_resolve("DONT")->value);
|
||||
else
|
||||
return (cstring_resolve("DOESNT")->value);
|
||||
}
|
||||
|
||||
char *does_output(int index, bool) {
|
||||
if (object[index]->attributes & PLURAL)
|
||||
return (cstring_resolve("DO")->value);
|
||||
else
|
||||
return (cstring_resolve("DOES")->value);
|
||||
}
|
||||
|
||||
char *list_output(int index, int capital) {
|
||||
if (!strcmp(object[index]->article, "name")) {
|
||||
Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
|
||||
} else {
|
||||
Common::strcpy_s(temp_buffer, 1024, object[index]->article);
|
||||
Common::strcat_s(temp_buffer, 1024, " ");
|
||||
Common::strcat_s(temp_buffer, 1024, object[index]->inventory);
|
||||
}
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return (temp_buffer);
|
||||
}
|
||||
|
||||
char *plain_output(int index, int capital) {
|
||||
Common::strcpy_s(temp_buffer, 1024, object[index]->inventory);
|
||||
|
||||
if (capital)
|
||||
temp_buffer[0] = toupper(temp_buffer[0]);
|
||||
|
||||
return (temp_buffer);
|
||||
}
|
||||
|
||||
char *long_output(int index) {
|
||||
if (!strcmp(object[index]->described, "function")) {
|
||||
Common::strcpy_s(function_name, 1024, "long_");
|
||||
Common::strcat_s(function_name, 1024, object[index]->label);
|
||||
if (execute(function_name) == FALSE) {
|
||||
unkfunrun(function_name);
|
||||
}
|
||||
|
||||
// THE BUFFER IS RETURNED EMPTY AS THE TEXT IS OUTPUT BY
|
||||
// WRITE STATEMENTS IN THE FUNCTION CALLED
|
||||
temp_buffer[0] = 0;
|
||||
return (temp_buffer);
|
||||
} else {
|
||||
return (object[index]->described);
|
||||
}
|
||||
}
|
||||
|
||||
void no_it() {
|
||||
write_text(cstring_resolve("NO_IT")->value);
|
||||
write_text(word[wp]);
|
||||
write_text(cstring_resolve("NO_IT_END")->value);
|
||||
custom_error = TRUE;
|
||||
}
|
||||
|
||||
void look_around() {
|
||||
/* THIS FUNCTION DISPLAYS THE DESCRIPTION OF THE CURRENT LOCATION ALONG
|
||||
* WITH ANY OBJECTS CURRENTLY IN IT */
|
||||
|
||||
if (!check_light(HERE)) {
|
||||
/* THE CURRENT LOCATION HAS 'DARK' AND NO SOURCE OF LIGHT IS
|
||||
* CURRENTLY PRESENT */
|
||||
execute("+dark_description");
|
||||
return;
|
||||
}
|
||||
|
||||
if (execute("+before_look") != FALSE)
|
||||
return;
|
||||
|
||||
execute("+title");
|
||||
|
||||
if (DISPLAY_MODE->value) {
|
||||
/* THE INTERPRETER IS IN VERBOSE MODE SO TEMPORARILY TAKE AWAYS THE
|
||||
* 'VISITED' ATTRIBUTE */
|
||||
object[HERE]->attributes &= ~1L;
|
||||
}
|
||||
|
||||
Common::strcpy_s(function_name, 81, "look_");
|
||||
Common::strcat_s(function_name, 81, object[HERE]->label);
|
||||
execute(function_name);
|
||||
|
||||
/* GIVE THE LOCATION THE ATTRIBUTES 'VISITED', 'KNOWN', AND 'MAPPED' NOW
|
||||
* THAT THE LOOK FUNCTION HAS RUN */
|
||||
object[HERE]->attributes = object[HERE]->attributes | KNOWN;
|
||||
object[HERE]->attributes = object[HERE]->attributes | VISITED;
|
||||
object[HERE]->attributes = object[HERE]->attributes | MAPPED;
|
||||
|
||||
execute("+object_descriptions");
|
||||
|
||||
Common::strcpy_s(function_name, 81, "after_look_");
|
||||
Common::strcat_s(function_name, 81, object[HERE]->label);
|
||||
execute(function_name);
|
||||
|
||||
execute("+after_look");
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
278
engines/glk/jacl/encapsulate.cpp
Normal file
278
engines/glk/jacl/encapsulate.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern struct synonym_type *synonym_table;
|
||||
extern struct filter_type *filter_table;
|
||||
|
||||
char text_buffer[1024];
|
||||
|
||||
/* THIS IS A STRING CONSTANT TO POINT TO WHENEVER A COMMA IS
|
||||
* USED IN THE PLAYER'S INPUT */
|
||||
const char *comma = "comma\0";
|
||||
const char *then = "then\0";
|
||||
const char *word[MAX_WORDS];
|
||||
int quoted[MAX_WORDS];
|
||||
int percented[MAX_WORDS];
|
||||
int wp;
|
||||
|
||||
void
|
||||
encapsulate() {
|
||||
int index,
|
||||
length;
|
||||
int position = 0;
|
||||
int new_word = TRUE;
|
||||
|
||||
length = strlen(text_buffer);
|
||||
|
||||
/* QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
|
||||
* IN THE PLAYERS COMMAND - RESET EACH WORD TO NO */
|
||||
for (index = 0; index < MAX_WORDS; index++) {
|
||||
quoted[index] = 0;
|
||||
percented[index] = 0;
|
||||
}
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
|
||||
switch (text_buffer[index]) {
|
||||
case ':':
|
||||
case '\t':
|
||||
case ' ':
|
||||
case ',':
|
||||
text_buffer[index] = 0;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
case ';':
|
||||
case '#':
|
||||
case '\r':
|
||||
case '\n':
|
||||
/* TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
|
||||
* SEMICOLON OR A HASH */
|
||||
text_buffer[index] = 0;
|
||||
index = length;
|
||||
break;
|
||||
case '"':
|
||||
index++;
|
||||
/* NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR
|
||||
* THE COMMAND 'write'*/
|
||||
quoted[position] = 1;
|
||||
|
||||
word[position] = &text_buffer[index];
|
||||
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
|
||||
/* IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
|
||||
* OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
|
||||
* WHITESPACE AS USUAL */
|
||||
for (; index < length; index++) {
|
||||
if (text_buffer[index] == '"') {
|
||||
text_buffer[index] = 0;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
|
||||
text_buffer[index] = 0;
|
||||
index = length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (new_word) {
|
||||
if (text_buffer[index] == '%' && text_buffer[index + 1] != ' ' && text_buffer[index + 1] != '\t') {
|
||||
percented[position]++;
|
||||
break;
|
||||
}
|
||||
word[position] = &text_buffer[index];
|
||||
new_word = FALSE;
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD */
|
||||
for (index = position; index < MAX_WORDS; index++)
|
||||
word[index] = nullptr;
|
||||
|
||||
wp = 0;
|
||||
}
|
||||
|
||||
// THIS VERSION OF ENCAPSULATE DOESN'T LOOK FOR CERTAIN SPECIAL CHARACTERS
|
||||
void
|
||||
command_encapsulate() {
|
||||
int index,
|
||||
length;
|
||||
int position = 0;
|
||||
int new_word = TRUE;
|
||||
|
||||
length = strlen(text_buffer);
|
||||
|
||||
// QUOTED IS USED TO STORE WHETHER EACH WORD WAS ENCLOSED IN QUOTES
|
||||
// IN THE PLAYERS COMMAND - RESET EACH WORD TO NO
|
||||
for (index = 0; index < MAX_WORDS; index++) {
|
||||
quoted[index] = 0;
|
||||
}
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
|
||||
// REDUSE EVERYTHING TO LOWER CASE EXCEPT TEXT ENCLOSED IN QUOTES
|
||||
text_buffer[index] = tolower((int) text_buffer[index]);
|
||||
|
||||
switch (text_buffer[index]) {
|
||||
case ':':
|
||||
case '\t':
|
||||
case ' ':
|
||||
text_buffer[index] = 0;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
case ',':
|
||||
text_buffer[index] = 0;
|
||||
// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
|
||||
// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEDING
|
||||
// WORD IN THE COMMAND.
|
||||
word[position] = comma;
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
case '.':
|
||||
text_buffer[index] = 0;
|
||||
// SET THIS WORD TO POINT TO A STRING CONSTANT OF 'comma' AS THE
|
||||
// COMMA ITSELF WILL BE NULLED OUT TO TERMINATE THE PRECEDING
|
||||
// WORD IN THE COMMAND
|
||||
word[position] = then;
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
case ';':
|
||||
case '\r':
|
||||
case '\n':
|
||||
// TERMINATE THE WHOLE COMMAND ON HITTING A NEWLINE CHARACTER, A
|
||||
// SEMICOLON OR A HASH
|
||||
text_buffer[index] = 0;
|
||||
index = length;
|
||||
break;
|
||||
case '"':
|
||||
index++;
|
||||
// NEED TO REMEMBER THAT THIS WORD WAS ENCLOSED IN QUOTES FOR
|
||||
// THE COMMAND 'write'
|
||||
quoted[position] = 1;
|
||||
|
||||
word[position] = &text_buffer[index];
|
||||
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
|
||||
// IF A WORD IS ENCLOSED IN QUOTES, KEEP GOING UNTIL THE END
|
||||
// OF THE LINE OR A CLOSING QUOTE IS FOUND, NOT BREAKING AT
|
||||
// WHITESPACE AS USUAL
|
||||
for (; index < length; index++) {
|
||||
if (text_buffer[index] == '"') {
|
||||
text_buffer[index] = 0;
|
||||
new_word = TRUE;
|
||||
break;
|
||||
} else if (text_buffer[index] == '\r' || text_buffer[index] == '\n') {
|
||||
text_buffer[index] = 0;
|
||||
index = length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (new_word) {
|
||||
word[position] = &text_buffer[index];
|
||||
new_word = FALSE;
|
||||
if (position < MAX_WORDS)
|
||||
position++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NULL OUT ALL THE WORD POINTERS BEYOND THE LAST WORD
|
||||
for (index = position; index < MAX_WORDS; index++) {
|
||||
word[index] = nullptr;
|
||||
}
|
||||
|
||||
wp = 0;
|
||||
}
|
||||
|
||||
void
|
||||
jacl_truncate() {
|
||||
int index,
|
||||
counter,
|
||||
match;
|
||||
int position = 0;
|
||||
|
||||
struct synonym_type *synonym;
|
||||
struct filter_type *filter = filter_table;
|
||||
|
||||
// REMOVE ALL THE DEFINED 'filter's FROM THE PLAYER'S COMMAND
|
||||
if (filter != nullptr) {
|
||||
while (word[position] != nullptr) {
|
||||
match = FALSE;
|
||||
do {
|
||||
if (!strcmp(word[position], filter->word)) {
|
||||
for (index = position; word[index + 1] != nullptr;
|
||||
index++)
|
||||
word[index] = word[index + 1];
|
||||
word[index] = nullptr;
|
||||
match = TRUE;
|
||||
}
|
||||
filter = filter->next_filter;
|
||||
} while (filter != nullptr && !match);
|
||||
filter = filter_table;
|
||||
if (!match)
|
||||
position++;
|
||||
};
|
||||
}
|
||||
|
||||
// SUBTITUTE ALL THE DEFINED 'synonym's IN THE PLAYER'S COMMAND
|
||||
if (synonym_table != nullptr) {
|
||||
for (counter = 0; word[counter] != nullptr; counter++) {
|
||||
synonym = synonym_table;
|
||||
do {
|
||||
if (!strcmp(word[counter], synonym->original)) {
|
||||
word[counter] = synonym->standard;
|
||||
break;
|
||||
}
|
||||
if (synonym->next_synonym != nullptr)
|
||||
synonym = synonym->next_synonym;
|
||||
else
|
||||
break;
|
||||
} while (TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
168
engines/glk/jacl/errors.cpp
Normal file
168
engines/glk/jacl/errors.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern struct function_type *executing_function;
|
||||
extern const char *word[];
|
||||
|
||||
extern char error_buffer[];
|
||||
|
||||
void badparrun() {
|
||||
Common::sprintf_s(error_buffer, 1024, BAD_PARENT, executing_function->name);
|
||||
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void notintrun() {
|
||||
Common::sprintf_s(error_buffer, 1024, NOT_INTEGER, executing_function->name, word[0]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void unkfunrun(const char *name) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_FUNCTION_RUN, name);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkkeyerr(int line, int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_KEYWORD_ERR, line, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void unkatterr(int line, int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_ATTRIBUTE_ERR, line,
|
||||
word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void unkvalerr(int line, int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_VALUE_ERR, line,
|
||||
word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void noproprun(int) {
|
||||
Common::sprintf_s(error_buffer, 1024, INSUFFICIENT_PARAMETERS_RUN, executing_function->name, word[0]);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void noobjerr(int line) {
|
||||
Common::sprintf_s(error_buffer, 1024, NO_OBJECT_ERR,
|
||||
line, word[0]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void noproperr(int line) {
|
||||
Common::sprintf_s(error_buffer, 1024, INSUFFICIENT_PARAMETERS_ERR,
|
||||
line, word[0]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void nongloberr(int line) {
|
||||
Common::sprintf_s(error_buffer, 1024, NON_GLOBAL_FIRST, line);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void nofnamerr(int line) {
|
||||
Common::sprintf_s(error_buffer, 1024, NO_NAME_FUNCTION, line);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void unkobjerr(int line, int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNDEFINED_ITEM_ERR, line, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void maxatterr(int line, int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024,
|
||||
MAXIMUM_ATTRIBUTES_ERR, line, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void unkobjrun(int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNDEFINED_ITEM_RUN, executing_function->name, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkattrun(int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_ATTRIBUTE_RUN, executing_function->name, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkdirrun(int wordno) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNDEFINED_DIRECTION_RUN,
|
||||
executing_function->name, word[wordno]);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void badparun() {
|
||||
Common::sprintf_s(error_buffer, 1024, BAD_PARENT, executing_function->name);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void badplrrun(int value) {
|
||||
Common::sprintf_s(error_buffer, 1024, BAD_PLAYER, executing_function->name, value);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void badptrrun(const char *name, int value) {
|
||||
Common::sprintf_s(error_buffer, 1024, BAD_POINTER, executing_function->name, name, value);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkvarrun(const char *variable) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNDEFINED_CONTAINER_RUN, executing_function->name, arg_text_of(variable));
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkstrrun(const char *variable) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNDEFINED_STRING_RUN, executing_function->name, variable);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void unkscorun(const char *scope) {
|
||||
Common::sprintf_s(error_buffer, 1024, UNKNOWN_SCOPE_RUN, executing_function->name, scope);
|
||||
log_error(error_buffer, PLUS_STDOUT);
|
||||
}
|
||||
|
||||
void totalerrs(int errors) {
|
||||
if (errors == 1)
|
||||
Common::sprintf_s(error_buffer, 1024, ERROR_DETECTED);
|
||||
else {
|
||||
Common::sprintf_s(error_buffer, 1024, ERRORS_DETECTED, errors);
|
||||
}
|
||||
|
||||
log_error(error_buffer, PLUS_STDERR);
|
||||
}
|
||||
|
||||
void outofmem() {
|
||||
log_error(OUT_OF_MEMORY, PLUS_STDERR);
|
||||
error("Terminated");
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
319
engines/glk/jacl/findroute.cpp
Normal file
319
engines/glk/jacl/findroute.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern struct object_type *object[];
|
||||
extern int objects;
|
||||
|
||||
/**************************************/
|
||||
/* Queue functions */
|
||||
/**************************************/
|
||||
|
||||
struct QueueNode {
|
||||
int val;
|
||||
int val2;
|
||||
struct QueueNode *next;
|
||||
};
|
||||
|
||||
struct Queue {
|
||||
QueueNode *head;
|
||||
QueueNode *tail;
|
||||
};
|
||||
|
||||
void qInit(Queue *q) {
|
||||
q->head = q->tail = nullptr;
|
||||
}
|
||||
|
||||
void qDelete(Queue *q) {
|
||||
QueueNode *node, *next;
|
||||
|
||||
for (node = q->head; node != nullptr; node = next) {
|
||||
next = node->next;
|
||||
free(node);
|
||||
}
|
||||
|
||||
q->head = q->tail = nullptr;
|
||||
}
|
||||
|
||||
int qIsEmpty(Queue *q) {
|
||||
return (q->head == nullptr);
|
||||
}
|
||||
|
||||
void qDebug(Queue *q) {
|
||||
debug("Queue:");
|
||||
|
||||
if (q->head == nullptr) {
|
||||
debug(" empty");
|
||||
} else {
|
||||
QueueNode *node;
|
||||
for (node = q->head; node != nullptr; node = node->next) {
|
||||
debug(" %d (%d)", node->val, node->val2);
|
||||
}
|
||||
}
|
||||
|
||||
debug("\n");
|
||||
}
|
||||
|
||||
void qAppend(Queue *q, int val, int val2) {
|
||||
QueueNode *node = (QueueNode *) malloc(sizeof(QueueNode));
|
||||
node->val = val;
|
||||
node->val2 = val2;
|
||||
node->next = nullptr;
|
||||
|
||||
if (q->head == nullptr) {
|
||||
q->head = q->tail = node;
|
||||
} else {
|
||||
q->tail->next = node;
|
||||
q->tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
void qPop(Queue *q, int *val, int *val2) {
|
||||
//assert(q->head != NULL);
|
||||
|
||||
*val = q->head->val;
|
||||
*val2 = q->head->val2;
|
||||
|
||||
if (q->head == q->tail) {
|
||||
q->head = q->tail = nullptr;
|
||||
} else {
|
||||
q->head = q->head->next;
|
||||
}
|
||||
}
|
||||
|
||||
void qTest() {
|
||||
int val, val2;
|
||||
Queue q;
|
||||
|
||||
qInit(&q);
|
||||
qDebug(&q);
|
||||
|
||||
debug("\nAdd 3, 0\n");
|
||||
qAppend(&q, 3, 0);
|
||||
qDebug(&q);
|
||||
|
||||
debug("\nAdd 4, 2\n");
|
||||
qAppend(&q, 4, 2);
|
||||
qDebug(&q);
|
||||
|
||||
debug("\nAdd 5, 1\n");
|
||||
qAppend(&q, 5, 1);
|
||||
qDebug(&q);
|
||||
|
||||
qPop(&q, &val, &val2);
|
||||
debug("\nPop %d, %d\n", val, val2);
|
||||
qDebug(&q);
|
||||
|
||||
qPop(&q, &val, &val2);
|
||||
debug("\nPop %d, %d\n", val, val2);
|
||||
qDebug(&q);
|
||||
|
||||
debug("\nAdd 6, 3\n");
|
||||
qAppend(&q, 6, 3);
|
||||
qDebug(&q);
|
||||
|
||||
debug("\nDelete all\n");
|
||||
qDelete(&q);
|
||||
qDebug(&q);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/* Set functions */
|
||||
/**************************************/
|
||||
|
||||
/* linked list for hash table */
|
||||
struct SetNode {
|
||||
int val;
|
||||
struct SetNode *next;
|
||||
};
|
||||
|
||||
#define SET_HASHSIZE 101
|
||||
|
||||
struct Set {
|
||||
SetNode *node[SET_HASHSIZE];
|
||||
};
|
||||
|
||||
void setInit(Set *set) {
|
||||
int n;
|
||||
|
||||
for (n = 0; n < SET_HASHSIZE; n++) {
|
||||
set->node[n] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setDelete(Set *set) {
|
||||
int n;
|
||||
|
||||
for (n = 0; n < SET_HASHSIZE; n++) {
|
||||
SetNode *node, *next;
|
||||
|
||||
for (node = set->node[n]; node != nullptr; node = next) {
|
||||
next = node->next;
|
||||
free(node);
|
||||
}
|
||||
|
||||
set->node[n] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setDebug(Set *set) {
|
||||
int n;
|
||||
|
||||
debug("Set:");
|
||||
|
||||
for (n = 0; n < SET_HASHSIZE; n++) {
|
||||
SetNode *node;
|
||||
|
||||
for (node = set->node[n]; node != nullptr; node = node->next) {
|
||||
debug(" %d", node->val);
|
||||
}
|
||||
}
|
||||
|
||||
debug("\n");
|
||||
}
|
||||
|
||||
int setHash(int val) {
|
||||
return abs(val) % SET_HASHSIZE;
|
||||
}
|
||||
|
||||
void setAdd(Set *set, int val) {
|
||||
SetNode *node;
|
||||
int n = setHash(val);
|
||||
|
||||
/* check if val is already in the set */
|
||||
|
||||
for (node = set->node[n]; node != nullptr; node = node->next) {
|
||||
if (node->val == val) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
node = (SetNode *) malloc(sizeof(SetNode));
|
||||
node->val = val;
|
||||
node->next = set->node[n];
|
||||
set->node[n] = node;
|
||||
}
|
||||
|
||||
/* returns 1 if the set contains val, otherwise returns 0 */
|
||||
|
||||
int setContains(Set *set, int val) {
|
||||
SetNode *node;
|
||||
int n = setHash(val);
|
||||
|
||||
for (node = set->node[n]; node != nullptr; node = node->next) {
|
||||
if (node->val == val) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setTest() {
|
||||
Set s;
|
||||
|
||||
setInit(&s);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nAdd 34\n");
|
||||
setAdd(&s, 34);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nAdd 56\n");
|
||||
setAdd(&s, 56);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nAdd 34 again\n");
|
||||
setAdd(&s, 34);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nAdd %d\n", 34 + SET_HASHSIZE);
|
||||
setAdd(&s, 34 + SET_HASHSIZE);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nAdd 78\n");
|
||||
setAdd(&s, 78);
|
||||
setDebug(&s);
|
||||
|
||||
debug("\nDelete all\n");
|
||||
setDelete(&s);
|
||||
setDebug(&s);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
|
||||
#define DIR_NONE -1
|
||||
|
||||
int find_route(int fromRoom, int toRoom, int known) {
|
||||
Set visited;
|
||||
Queue q;
|
||||
int firstTime;
|
||||
int result = DIR_NONE;
|
||||
|
||||
setInit(&visited);
|
||||
qInit(&q);
|
||||
|
||||
qAppend(&q, fromRoom, DIR_NONE);
|
||||
setAdd(&visited, fromRoom);
|
||||
firstTime = 1;
|
||||
|
||||
while (!qIsEmpty(&q)) {
|
||||
int n, dir, firstDir;
|
||||
qPop(&q, &n, &firstDir);
|
||||
|
||||
if (n == toRoom) {
|
||||
result = firstDir;
|
||||
break;
|
||||
}
|
||||
|
||||
for (dir = 0; dir < 12 ; dir++) {
|
||||
int dest = object[n]->integer[dir];
|
||||
|
||||
if (dest < 1 || dest > objects) continue;
|
||||
|
||||
if (object[dest] == nullptr) continue;
|
||||
|
||||
if (dest != NOWHERE && !setContains(&visited, dest)) {
|
||||
if (!known || (object[dest]->attributes & KNOWN)) {
|
||||
qAppend(&q, dest, (firstTime ? dir : firstDir));
|
||||
setAdd(&visited, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
firstTime = 0;
|
||||
}
|
||||
|
||||
setDelete(&visited);
|
||||
qDelete(&q);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
237
engines/glk/jacl/glk_saver.cpp
Normal file
237
engines/glk/jacl/glk_saver.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern struct object_type *object[];
|
||||
extern struct integer_type *integer_table;
|
||||
extern struct integer_type *integer[];
|
||||
extern struct function_type *function_table;
|
||||
extern struct string_type *string_table;
|
||||
|
||||
extern schanid_t sound_channel[];
|
||||
|
||||
extern char temp_buffer[];
|
||||
|
||||
extern int objects;
|
||||
extern int integers;
|
||||
extern int functions;
|
||||
extern int strings;
|
||||
extern int player;
|
||||
|
||||
extern int it;
|
||||
extern int them[];
|
||||
extern int her;
|
||||
extern int him;
|
||||
extern int parent;
|
||||
|
||||
extern int noun[];
|
||||
|
||||
bool save_game(strid_t save) {
|
||||
integer_type *current_integer = integer_table;
|
||||
function_type *current_function = function_table;
|
||||
string_type *current_string = string_table;
|
||||
int index, counter;
|
||||
|
||||
// This is written to help validate the saved game when it's loaded
|
||||
write_integer(save, objects);
|
||||
write_integer(save, integers);
|
||||
write_integer(save, functions);
|
||||
write_integer(save, strings);
|
||||
|
||||
while (current_integer != nullptr) {
|
||||
write_integer(save, current_integer->value);
|
||||
current_integer = current_integer->next_integer;
|
||||
}
|
||||
|
||||
while (current_function != nullptr) {
|
||||
write_integer(save, current_function->call_count);
|
||||
current_function = current_function->next_function;
|
||||
}
|
||||
|
||||
for (index = 1; index <= objects; index++) {
|
||||
if (object[index]->nosave)
|
||||
continue;
|
||||
|
||||
for (counter = 0; counter < 16; counter++) {
|
||||
write_integer(save, object[index]->integer[counter]);
|
||||
}
|
||||
|
||||
write_long(save, object[index]->attributes);
|
||||
write_long(save, object[index]->user_attributes);
|
||||
}
|
||||
|
||||
// Write out all the current values of the string variables
|
||||
while (current_string != nullptr) {
|
||||
for (index = 0; index < 255; index++) {
|
||||
g_vm->glk_put_char_stream(save, current_string->value[index]);
|
||||
}
|
||||
current_string = current_string->next_string;
|
||||
}
|
||||
|
||||
write_integer(save, player);
|
||||
write_integer(save, noun[3]);
|
||||
|
||||
// Save the current volume of each of the sound channels
|
||||
for (index = 0; index < 8; index++) {
|
||||
Common::sprintf_s(temp_buffer, 1024, "volume[%d]", index);
|
||||
write_integer(save, cinteger_resolve(temp_buffer)->value);
|
||||
}
|
||||
|
||||
// Save the current value of the GLK timer
|
||||
write_integer(save, cinteger_resolve("timer")->value);
|
||||
|
||||
TIME->value = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool restore_game(strid_t save, bool warn) {
|
||||
integer_type *current_integer = integer_table;
|
||||
function_type *current_function = function_table;
|
||||
string_type *current_string = string_table;
|
||||
|
||||
int index, counter;
|
||||
int file_objects, file_integers, file_functions, file_strings;
|
||||
|
||||
// Read properties to validate the savegame is for this game
|
||||
file_objects = read_integer(save);
|
||||
file_integers = read_integer(save);
|
||||
file_functions = read_integer(save);
|
||||
file_strings = read_integer(save);
|
||||
|
||||
if (file_objects != objects
|
||||
|| file_integers != integers
|
||||
|| file_functions != functions
|
||||
|| file_strings != strings) {
|
||||
if (warn == FALSE) {
|
||||
log_error(cstring_resolve("BAD_SAVED_GAME")->value, PLUS_STDOUT);
|
||||
}
|
||||
g_vm->glk_stream_close(save, nullptr);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
while (current_integer != nullptr) {
|
||||
current_integer->value = read_integer(save);
|
||||
current_integer = current_integer->next_integer;
|
||||
}
|
||||
|
||||
while (current_function != nullptr) {
|
||||
current_function->call_count = read_integer(save);
|
||||
current_function = current_function->next_function;
|
||||
}
|
||||
|
||||
for (index = 1; index <= objects; index++) {
|
||||
if (object[index]->nosave)
|
||||
continue;
|
||||
|
||||
for (counter = 0; counter < 16; counter++) {
|
||||
object[index]->integer[counter] = read_integer(save);
|
||||
}
|
||||
|
||||
object[index]->attributes = read_integer(save);
|
||||
object[index]->user_attributes = read_integer(save);
|
||||
}
|
||||
|
||||
while (current_string != nullptr) {
|
||||
for (index = 0; index < 255; index++) {
|
||||
current_string->value[index] = g_vm->glk_get_char_stream(save);
|
||||
}
|
||||
current_string = current_string->next_string;
|
||||
}
|
||||
|
||||
player = read_integer(save);
|
||||
noun[3] = read_integer(save);
|
||||
|
||||
// Restore the current volume of each of the sound channels
|
||||
for (index = 0; index < 8; index++) {
|
||||
Common::sprintf_s(temp_buffer, 1024, "volume[%d]", index);
|
||||
counter = read_integer(save);
|
||||
cinteger_resolve(temp_buffer)->value = counter;
|
||||
|
||||
if (SOUND_SUPPORTED->value) {
|
||||
// Set the GLK volume
|
||||
g_vm->glk_schannel_set_volume(sound_channel[index], (glui32) counter);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the current value of the GLK timer
|
||||
counter = read_integer(save);
|
||||
cinteger_resolve("timer")->value = counter;
|
||||
|
||||
// Set the GLK timer
|
||||
g_vm->glk_request_timer_events((glui32) counter);
|
||||
|
||||
TIME->value = FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_integer(strid_t stream, int x) {
|
||||
unsigned char c;
|
||||
|
||||
c = (unsigned char)(x) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 8) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 16) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 24) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
}
|
||||
|
||||
int read_integer(strid_t stream) {
|
||||
int a, b, c, d;
|
||||
a = (int) g_vm->glk_get_char_stream(stream);
|
||||
b = (int) g_vm->glk_get_char_stream(stream);
|
||||
c = (int) g_vm->glk_get_char_stream(stream);
|
||||
d = (int) g_vm->glk_get_char_stream(stream);
|
||||
return a | (b << 8) | (c << 16) | (d << 24);
|
||||
}
|
||||
|
||||
void write_long(strid_t stream, long x) {
|
||||
unsigned char c;
|
||||
|
||||
c = (unsigned char)(x) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 8) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 16) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
c = (unsigned char)(x >> 24) & 0xFF;
|
||||
g_vm->glk_put_char_stream(stream, c);
|
||||
}
|
||||
|
||||
long read_long(strid_t stream) {
|
||||
long a, b, c, d;
|
||||
a = (long) g_vm->glk_get_char_stream(stream);
|
||||
b = (long) g_vm->glk_get_char_stream(stream);
|
||||
c = (long) g_vm->glk_get_char_stream(stream);
|
||||
d = (long) g_vm->glk_get_char_stream(stream);
|
||||
return a | (b << 8) | (c << 16) | (d << 24);
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
3454
engines/glk/jacl/interpreter.cpp
Normal file
3454
engines/glk/jacl/interpreter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
83
engines/glk/jacl/jacl.cpp
Normal file
83
engines/glk/jacl/jacl.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "common/config-manager.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
JACL *g_vm;
|
||||
extern strid_t game_stream;
|
||||
extern void glk_main();
|
||||
|
||||
JACL::JACL(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
|
||||
_saveSlot(-1) {
|
||||
g_vm = this;
|
||||
}
|
||||
|
||||
void JACL::runGame() {
|
||||
// Check for savegame
|
||||
_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
|
||||
|
||||
// Open up the game file as a stream, and play the game
|
||||
game_stream = _streams->openStream(&_gameFile);
|
||||
glk_main();
|
||||
}
|
||||
|
||||
bool JACL::initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void JACL::deinitialize() {
|
||||
}
|
||||
|
||||
Common::Error JACL::readSaveData(Common::SeekableReadStream *rs) {
|
||||
strid_t data_stream = _streams->openStream(rs);
|
||||
bool success = restore_game(data_stream);
|
||||
_streams->deleteStream(data_stream);
|
||||
|
||||
return success ? Common::kNoError : Common::kReadingFailed;
|
||||
}
|
||||
|
||||
Common::Error JACL::writeGameData(Common::WriteStream *ws) {
|
||||
strid_t data_stream = _streams->openStream(ws);
|
||||
bool success = save_game(data_stream);
|
||||
_streams->deleteStream(data_stream);
|
||||
|
||||
return success ? Common::kNoError : Common::kWritingFailed;
|
||||
}
|
||||
|
||||
bool JACL::loadLauncherSavegame() {
|
||||
int saveSlot = _saveSlot;
|
||||
_saveSlot = -1;
|
||||
|
||||
if (loadGameState(saveSlot).getCode() == Common::kNoError)
|
||||
return true;
|
||||
|
||||
write_text(cstring_resolve("CANT_RESTORE")->value);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
96
engines/glk/jacl/jacl.h
Normal file
96
engines/glk/jacl/jacl.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Based on the JACL interpreter version 3.0.0 */
|
||||
|
||||
#ifndef JACL_JACL
|
||||
#define JACL_JACL
|
||||
|
||||
#include "glk/glk_api.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#define GLK
|
||||
|
||||
/**
|
||||
* JACL game interpreter
|
||||
*/
|
||||
class JACL : public GlkAPI {
|
||||
private:
|
||||
int _saveSlot;
|
||||
private:
|
||||
/**
|
||||
* Engine initialization
|
||||
*/
|
||||
bool initialize();
|
||||
|
||||
/**
|
||||
* Engine cleanup
|
||||
*/
|
||||
void deinitialize();
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
JACL(OSystem *syst, const GlkGameDescription &gameDesc);
|
||||
|
||||
/**
|
||||
* Run the game
|
||||
*/
|
||||
void runGame() override;
|
||||
|
||||
/**
|
||||
* Returns the running interpreter type
|
||||
*/
|
||||
InterpreterType getInterpreterType() const override {
|
||||
return INTERPRETER_JACL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Savegames aren't supported for JACL games
|
||||
*/
|
||||
Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||
|
||||
/**
|
||||
* Savegames aren't supported for JACL games
|
||||
*/
|
||||
Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||
|
||||
/**
|
||||
* Returns true if a savegame is being loaded directly from the ScummVM launcher
|
||||
*/
|
||||
bool loadingSavegame() const {
|
||||
return _saveSlot != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual loading of the savegame from a luancher
|
||||
*/
|
||||
bool loadLauncherSavegame();
|
||||
};
|
||||
|
||||
extern JACL *g_vm;
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
|
||||
#endif
|
||||
1553
engines/glk/jacl/jacl_main.cpp
Normal file
1553
engines/glk/jacl/jacl_main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
236
engines/glk/jacl/jpp.cpp
Normal file
236
engines/glk/jacl/jpp.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/* jpp.c --- The JACL Preprocessor
|
||||
(C) 2001 Andreas Matthias
|
||||
|
||||
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 1, 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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
#include "glk/jacl/version.h"
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern char text_buffer[];
|
||||
extern char temp_buffer[];
|
||||
extern const char *word[];
|
||||
extern short int quoted[];
|
||||
extern short int punctuated[];
|
||||
extern int wp;
|
||||
|
||||
extern char user_id[];
|
||||
extern char prefix[];
|
||||
extern char game_path[];
|
||||
extern char game_file[];
|
||||
extern char processed_file[];
|
||||
|
||||
extern short int encrypted;
|
||||
|
||||
extern char include_directory[];
|
||||
extern char temp_directory[];
|
||||
|
||||
extern char error_buffer[];
|
||||
|
||||
int lines_written;
|
||||
|
||||
Common::WriteStream *outputFile = nullptr;
|
||||
Common::SeekableReadStream *inputFile = nullptr;
|
||||
|
||||
char *stripped_line;
|
||||
|
||||
/* INDICATES THAT THE CURRENT '.j2' FILE BEING WORKED
|
||||
* WITH BEING PREPARED FOR RELEASE (DON'T INCLUDE DEBUG LIBARIES) */
|
||||
short int release = FALSE;
|
||||
|
||||
/* INDICATES THAT THE CURRENT '.j2' FILE BEING WORKED
|
||||
* SHOULD BE ENCRYPTED */
|
||||
short int do_encrypt = TRUE;
|
||||
|
||||
/* INDICATES THAT THE CURRENT '.processed' FILE BRING WRITTEN SHOULD NOW
|
||||
* HAVE EACH LINE ENCRYPTED AS THE FIRST NONE COMMENT LINE HAS BEEN HIT */
|
||||
short int encrypting = FALSE;
|
||||
|
||||
int jpp() {
|
||||
// TODO: Find out if this is actually used
|
||||
#ifdef UNUSED
|
||||
int game_version;
|
||||
|
||||
lines_written = 0;
|
||||
|
||||
/* CHECK IF GAME FILE IS ALREADY A PROCESSED FILE BY LOOKING FOR THE
|
||||
* STRING "#encrypted" OR "#processed" WITHIN THE FIRST FIVE LINES OF
|
||||
* THE GAME FILE IF SO, RETURN THE GAME FILE AS THE PROCESSED FILE */
|
||||
inputFile = File::open(game_file);
|
||||
|
||||
if (inputFile) {
|
||||
int index = 0;
|
||||
char *result = NULL;
|
||||
|
||||
if (inputFile->read(text_buffer, 1024) != 1024) {
|
||||
Common::sprintf_s(error_buffer, 1024, CANT_OPEN_SOURCE, game_file);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
while (inputFile->pos() < inputFile->size() && index < 10) {
|
||||
if (strstr(text_buffer, "#processed")) {
|
||||
/* THE GAME FILE IS ALREADY A PROCESSED FILE, JUST USE IT
|
||||
* DIRECTLY */
|
||||
if (sscanf(text_buffer, "#processed:%d", &game_version)) {
|
||||
if (INTERPRETER_VERSION < game_version) {
|
||||
Common::sprintf_s(error_buffer, 1024, OLD_INTERPRETER, game_version);
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
Common::strcpy_s(processed_file, 256, game_file);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
if (inputFile->read(text_buffer, 1024) != 1024)
|
||||
break;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
delete inputFile;
|
||||
} else {
|
||||
Common::sprintf_s(error_buffer, 1024, NOT_FOUND);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* SAVE A TEMPORARY FILENAME INTO PROCESSED_FILE */
|
||||
Common::sprintf_s(processed_file, "%s%s.j2", temp_directory, prefix);
|
||||
|
||||
/* ATTEMPT TO OPEN THE PROCESSED FILE IN THE TEMP DIRECTORY */
|
||||
if ((outputFile = fopen(processed_file, "w")) == NULL) {
|
||||
/* NO LUCK, TRY OPEN THE PROCESSED FILE IN THE CURRENT DIRECTORY */
|
||||
Common::sprintf_s(processed_file, "%s.j2", prefix);
|
||||
if ((outputFile = fopen(processed_file, "w")) == NULL) {
|
||||
/* NO LUCK, CAN'T CONTINUE */
|
||||
Common::sprintf_s(error_buffer, 1024, CANT_OPEN_PROCESSED, processed_file);
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (process_file(game_file, (const char *) NULL) == FALSE) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
fclose(outputFile);
|
||||
#else
|
||||
error("TODO");
|
||||
#endif
|
||||
|
||||
/* ALL OKAY, RETURN TRUE */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
int process_file(const char *sourceFile1, char *sourceFile2) {
|
||||
char temp_buffer1[1025];
|
||||
char temp_buffer2[1025];
|
||||
Common::File *srcFile = nullptr;
|
||||
char *includeFile = nullptr;
|
||||
|
||||
/* THIS FUNCTION WILL CREATE A PROCESSED FILE THAT HAS HAD ALL
|
||||
* LEADING AND TRAILING WHITE SPACE REMOVED AND ALL INCLUDED
|
||||
* FILES INSERTED */
|
||||
srcFile = File::openForReading(sourceFile1);
|
||||
|
||||
if (!srcFile) {
|
||||
if (sourceFile2 != nullptr) {
|
||||
srcFile = File::openForReading(sourceFile2);
|
||||
if (!srcFile) {
|
||||
Common::sprintf_s(error_buffer, 1024, CANT_OPEN_OR, sourceFile1, sourceFile2);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
} else {
|
||||
Common::sprintf_s(error_buffer, 1024, CANT_OPEN_SOURCE, sourceFile1);
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
*text_buffer = 0;
|
||||
|
||||
if (srcFile->read(text_buffer, 1024) != 1024) {
|
||||
Common::sprintf_s(error_buffer, 1024, READ_ERROR);
|
||||
delete srcFile;
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
while (srcFile->pos() < srcFile->size() && *text_buffer != 0) {
|
||||
if (!strncmp(text_buffer, "#include", 8) ||
|
||||
(!strncmp(text_buffer, "#debug", 6) & !release)) {
|
||||
includeFile = strrchr(text_buffer, '"');
|
||||
|
||||
if (includeFile != nullptr)
|
||||
*includeFile = 0;
|
||||
|
||||
includeFile = strchr(text_buffer, '"');
|
||||
|
||||
if (includeFile != nullptr) {
|
||||
Common::strcpy_s(temp_buffer1, game_path);
|
||||
Common::strcat_s(temp_buffer1, includeFile + 1);
|
||||
Common::strcpy_s(temp_buffer2, include_directory);
|
||||
Common::strcat_s(temp_buffer2, includeFile + 1);
|
||||
if (process_file(temp_buffer1, temp_buffer2) == FALSE) {
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
Common::sprintf_s(error_buffer, 1024, BAD_INCLUDE);
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
/* STRIP WHITESPACE FROM LINE BEFORE WRITING TO OUTPUTFILE. */
|
||||
stripped_line = stripwhite(text_buffer);
|
||||
|
||||
if (!encrypting && *stripped_line != '#' && *stripped_line != '\0' && do_encrypt & release) {
|
||||
/* START ENCRYPTING FROM THE FIRST NON-COMMENT LINE IN
|
||||
* THE SOURCE FILE */
|
||||
outputFile->writeString("#encrypted\n");
|
||||
encrypting = TRUE;
|
||||
}
|
||||
|
||||
/* ENCRYPT PROCESSED FILE IF REQUIRED */
|
||||
if (encrypting) {
|
||||
jacl_encrypt(stripped_line);
|
||||
}
|
||||
|
||||
outputFile->writeString(stripped_line);
|
||||
|
||||
lines_written++;
|
||||
if (lines_written == 1) {
|
||||
Common::sprintf_s(temp_buffer, 1024, "#processed:%d\n", INTERPRETER_VERSION);
|
||||
outputFile->writeString(temp_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
*text_buffer = 0;
|
||||
|
||||
if (srcFile->read(text_buffer, 1024) != 1024)
|
||||
// EOF HAS BEEN REACHED
|
||||
break;
|
||||
}
|
||||
|
||||
delete srcFile;
|
||||
|
||||
/* ALL OKAY, RETURN TRUE */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
570
engines/glk/jacl/language.h
Normal file
570
engines/glk/jacl/language.h
Normal file
@@ -0,0 +1,570 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
/* THIS FILE CONTAINS ALL THE TEXT OUTPUT INTERNALLY BY THE INTERPRETER.
|
||||
THE STRINGS FOR ANY GIVEN LANGUAGE ARE DIVIDED INTO TWO SECTIONS, ONE
|
||||
THAT CONTAINS THE TEXT OUTPUT DURING REGULAR PLAY AND ONE THAT CONTAINS
|
||||
THE TEXT OUTPUT DURING ERROR CONDITIONS (POSSIBLY BEFORE ANY GIVEN GAME
|
||||
HAS FINISHED LOADING.
|
||||
|
||||
TO TRANSLATE A GAME TO LANGUAGE THAT IS NOT CURRENTLY SUPPORTED YOU
|
||||
NEED TO TRANSLATE english.library AND verbs.library INTO YOUR CHOSEN
|
||||
LANGUAGE.
|
||||
|
||||
THE NATIVE_LANGUAGE CONSTANT BELOW INDICATES WHAT SHOULD BE THE DEFAULT
|
||||
LANGUAGE OF THE INTERPRETER WHEN IT IS COMPILED. THE 'GAME MESSAGES'
|
||||
BLOCK CONTAINS THE SAME STRINGS AS THE FILE english.library (AND OTHER
|
||||
LANGUAGES) AND THESE ARE THE VALUES USED BY THE INTERPRETER IF THOSE
|
||||
CONSTANTS ARE NO DEFINED BY ANY GIVEN GAME.
|
||||
|
||||
THE 'SYSTEM MESSAGES' BLOCK CONTAINS ERROR MESSAGES AND OTHER SYSTEM-
|
||||
LEVEL MESSAGES THAT ARE MOST COMMONLY SEEN DURING THE DEVELOPMENT OF A
|
||||
GAME. THESE MESSAGES CANNOT BE OVERRIDDEN BY ANY SPECIFIC GAME. */
|
||||
|
||||
|
||||
#define ENGLISH 1
|
||||
#define GERMAN 2
|
||||
#define FRENCH 3
|
||||
|
||||
#define NATIVE_LANGUAGE ENGLISH
|
||||
|
||||
#if NATIVE_LANGUAGE==ENGLISH
|
||||
/* GAME MESSAGES */
|
||||
#define COMMENT_IGNORED "No transcript running, comment ignored.^"
|
||||
#define COMMENT_RECORDED "Comment recorded.^"
|
||||
#define YES_WORD "yes"
|
||||
#define NO_WORD "no"
|
||||
#define YES_OR_NO "^Please enter ~yes~ or ~no~: "
|
||||
#define INVALID_SELECTION "Invalid selection.^"
|
||||
#define RESTARTING "^Restarting...^"
|
||||
#define RETURN_GAME "^Returning to game.^"
|
||||
#define SCRIPTING_ON "Scripting on.^"
|
||||
#define SCRIPTING_OFF "Scripting off.^"
|
||||
#define SCRIPTING_ALREADY_OFF "Scripting already off.^"
|
||||
#define SCRIPTING_ALREADY_ON "Scripting already on.^"
|
||||
#define CANT_WRITE_SCRIPT "Unable to write to script file.^"
|
||||
#define ERROR_READING_WALKTHRU "Error reading walkthru file.^"
|
||||
#define BAD_OOPS "You must follow the ~oops~ command with the word you wish to use instead.^"
|
||||
#define CANT_CORRECT "I can't correct the last command using ~oops~, sorry.^"
|
||||
#define SURE_QUIT "Are you sure you want to quit?^"
|
||||
#define SURE_RESTART "Are you sure you want to restart?^"
|
||||
#define NOT_CLEVER "It wasn't so clever as to be worth repeating.^"
|
||||
#define NO_MOVES "But you haven't done anything yet!^"
|
||||
#define TYPE_NUMBER "^Type a number between %d and %d: "
|
||||
#define BY "By ~"
|
||||
#define REFERRING_TO "~, are you referring to:^"
|
||||
#define WALKTHRU_WORD "walkthru"
|
||||
#define INFO_WORD "info"
|
||||
#define RESTART_WORD "restart"
|
||||
#define AGAIN_WORD "again"
|
||||
#define SCRIPT_WORD "script"
|
||||
#define UNSCRIPT_WORD "unscript"
|
||||
#define QUIT_WORD "quit"
|
||||
#define UNDO_WORD "undo"
|
||||
#define OOPS_WORD "oops"
|
||||
#define FROM_WORD "from"
|
||||
#define EXCEPT_WORD "except"
|
||||
#define FOR_WORD "for"
|
||||
#define BUT_WORD "but"
|
||||
#define AND_WORD "and"
|
||||
#define THEN_WORD "then"
|
||||
#define OF_WORD "of"
|
||||
#define SHE_WORD "she"
|
||||
#define HE_WORD "he"
|
||||
#define THAT_WORD "that"
|
||||
#define THEM_WORD "them"
|
||||
#define THOSE_WORD "those"
|
||||
#define THEY_WORD "they"
|
||||
#define IT_WORD "it"
|
||||
#define ITSELF_WORD "itself"
|
||||
#define HIM_WORD "him"
|
||||
#define HIMSELF_WORD "himself"
|
||||
#define HER_WORD "her"
|
||||
#define HERSELF_WORD "herself"
|
||||
#define THEMSELVES_WORD "themselves"
|
||||
#define YOU_WORD "you"
|
||||
#define YOURSELF_WORD "yourself"
|
||||
#define ONES_WORD "ones"
|
||||
#define NO_MULTI_VERB "You can't refer to multiple objects directly after the word ~%s~.^"
|
||||
#define NO_MULTI_START "You can't refer to multiple objects at the start of a command.^"
|
||||
#define PERSON_CONCEALING "%s doesn't seem to be carrying any such thing.^"
|
||||
#define PERSON_POSSESSIVE "%s isn't about to let you take anything of theirs.^"
|
||||
#define CONTAINER_CLOSED "%s is closed.^"
|
||||
#define CONTAINER_CLOSED_FEM "%s is closed.^"
|
||||
#define FROM_NON_CONTAINER "The word ~%s~ must be followed by a container.^"
|
||||
#define DOUBLE_EXCEPT "You can only use the word ~%s~ once per object reference.^"
|
||||
#define NONE_HELD "You are not holding anything like that.^"
|
||||
#define NO_OBJECTS "I don't see what you are referring to.^"
|
||||
#define NO_FILENAME "Save and restore commands must be followed by a filename.^"
|
||||
#define MOVE_UNDONE "Previous move undone.^^"
|
||||
#define NO_UNDO "Nothing to undo.^"
|
||||
#define CANT_SAVE "Unable to save game state to file.^"
|
||||
#define CANT_RESTORE "Unable to restore game state from file.^"
|
||||
#define GAME_SAVED "Game saved.^"
|
||||
#define INCOMPLETE_SENTENCE "The sentence you typed was incomplete.^"
|
||||
#define UNKNOWN_OBJECT "You can't see any such thing as ~"
|
||||
#define UNKNOWN_OBJECT_END "~.^"
|
||||
#define CANT_USE_WORD "You can't use the word ~"
|
||||
#define IN_CONTEXT "~ in that context.^"
|
||||
#define DONT_SEE "You don't see "
|
||||
#define HERE_WORD " here.^"
|
||||
#define BAD_SAVED_GAME "Attempt to restore incompatible saved-game file."
|
||||
#define ARENT "aren't"
|
||||
#define ISNT "isn't"
|
||||
#define ARE "are"
|
||||
#define IS "is"
|
||||
#define DONT "don't"
|
||||
#define DOESNT "doesn't"
|
||||
#define DO "do"
|
||||
#define DOES "does"
|
||||
#define SCORE_UP "^[YOUR SCORE JUST WENT UP BY "
|
||||
#define POINT " POINT]^"
|
||||
#define POINTS " POINTS]^"
|
||||
#define STARTING "Starting."
|
||||
#define NO_IT "You must have referred to an appropriate noun previously to use the word ~"
|
||||
#define NO_IT_END "~.^"
|
||||
#define BACK_REFERENCE "You must have referred to a noun previously in the same sentence to use the word ~"
|
||||
#define BACK_REFERENCE_END "~.^"
|
||||
#define WHEN_YOU_SAY "When you say ~"
|
||||
#define MUST_SPECIFY "~, you must specify whether you mean "
|
||||
#define OR_WORD " or "
|
||||
|
||||
/* SYSTEM MESSAGES */
|
||||
#define READ_ERROR "Error reading game file."
|
||||
#define OLD_INTERPRETER "Interpreter version is older than game file (v%d), can't continue."
|
||||
#define BAD_CURSOR "You can only use the ~cursor~ command in the status window.^"
|
||||
#define INCOMPLETE_GRAMMAR "Incomplete grammar statement."
|
||||
#define GAME_MODIFIED "Game file modified, reloading.\n"
|
||||
#define NOT_INTEGER "In function \"%s\", \"%s\" command requires integer parameter."
|
||||
#define NO_NAME_FUNCTION "In line %d, a function must have at least one name."
|
||||
#define MAXIMUM_ATTRIBUTES_ERR "In line %d, unable to create attribute \"%s\", maximum number of attributes already defined."
|
||||
#define BAD_PLAYER "In function \"%s\", attempt to use object pointer \"player\" while it does not point to an object (%d)."
|
||||
#define BAD_PARENT "In function \"%s\", attempt to use the variable 'here' while the variable 'player' does not have a legal parent."
|
||||
#define BAD_POINTER "In function \"%s\", attempt to use object pointer \"%s\" that does not point to an object (%d)."
|
||||
#define ILLEGAL_LABEL "In line %d, reserved word \"%s\" used as label."
|
||||
#define USED_LABEL_INT "In line %d, \"%s\" is already used as a variable label."
|
||||
#define USED_LABEL_CINT "In line %d, \"%s\" is already used as an integer constant label."
|
||||
#define USED_LABEL_STR "In line %d, \"%s\" is already used as a string label."
|
||||
#define USED_LABEL_CSTR "In line %d, \"%s\" is already used as a string constant label."
|
||||
#define USED_LABEL_ATT "In line %d, \"%s\" is already used as an attribute label."
|
||||
#define USED_LABEL_OBJ "In line %d, \"%s\" is already used as an object or location label."
|
||||
#define NO_OBJECT_ERR "In line %d, property \"%s\" defined before first object or location."
|
||||
#define BAD_INCLUDE "'#include' directive must be followed by file name enclosed in double quotes."
|
||||
#define BAD_PARAMETER "Unknown or inappropriate type of container '%s' associated with parameter '%s'."
|
||||
#define BAD_VALUE "Value '%s' cannot be stored in container '%s'."
|
||||
#define NO_MEDIA "WebJACL: Media file \"%s\" not found, external media support disabled.\n"
|
||||
#define MEDIA_REGISTERED "WebJACL: Registered %d media.\n"
|
||||
#define CLEANING_UP "WebJACL: Cleaning up...\n"
|
||||
#define NO_GAME "No game file specified, can't continue."
|
||||
#define NO_PORT "WebJACL: No port number specified (-p <number>), using default port %d.\n"
|
||||
#define WEBJACL_CONFIGURED "WebJACL server configured on %s:%d\n"
|
||||
#define NOT_FOUND "Unable to open game file, can't continue."
|
||||
#define CANT_OPEN "Unable to open processed file \"%s\", can't continue."
|
||||
#define CANT_RUN "A JACL game must contain at least one object (to represent the player), and at least one location (for the player to start in).^"
|
||||
#define NO_PLAYER "The object pointer 'player' does not point to an object.^"
|
||||
#define SELF_REFERENCE "In function \"%s\", reference to object \"%s\" whose parent is itself."
|
||||
#define EXECUTING "Executing function \"%s\".\n"
|
||||
#define NO_WHILE "In function \"%s\", 'endwhile' command without matching 'while' command."
|
||||
#define NO_ITERATE "In function \"%s\", 'enditerate' command without matching 'iterate' command."
|
||||
#define NO_UPDATE "In function \"%s\", 'endupdate' command without matching 'update' command."
|
||||
#define NO_REPEAT "In function \"%s\", 'until' command without matching 'repeat' command."
|
||||
#define NO_LOOP "In function \"%s\", 'endloop' command without matching 'loop' command."
|
||||
#define UNDEFINED_FUNCTION "In function \"%s\", attempt to execute undefined function \"%s\"."
|
||||
#define DIVIDE_BY_ZERO "In function \"%s\", division by zero error."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define UNKNOWN_COMMAND "In function \"%s\", unknown command \"%s\"."
|
||||
#define STACK_OVERFLOW "Stack overflow."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define OUT_OF_RANGE "In function \"%s\", element \"%s\" out of range (%d)."
|
||||
#define GLOBAL_SELF "Reference to 'self' from global function \"%s\"."
|
||||
#define NON_GLOBAL_FIRST "In line %d, non-global function before object or location."
|
||||
#define MAXIMUM_EXCEEDED "Maximum number of objects exceeded, can't continue."
|
||||
#define ERROR_DETECTED "1 error detected."
|
||||
#define ERRORS_DETECTED "%d errors detected."
|
||||
#define UNKNOWN_FUNCTION_RUN "Attempt to execute unknown function \"%s\"."
|
||||
#define UNKNOWN_KEYWORD_ERR "In line %d, unknown keyword \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_ERR "In line %d, unknown attribute \"%s\"."
|
||||
#define UNKNOWN_VALUE_ERR "In line %d, unable to resolve value \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_RUN "In function \"%s\", reference to unknown attribute \"%s\"."
|
||||
#define INSUFFICIENT_PARAMETERS_RUN "In function \"%s\", \"%s\" command with insufficient parameters."
|
||||
#define INSUFFICIENT_PARAMETERS_ERR "In line %d, \"%s\" keyword with insufficient parameters."
|
||||
#define UNDEFINED_ITEM_ERR "In line %d, reference to undefined item \"%s\"."
|
||||
#define UNDEFINED_ITEM_RUN "In function \"%s\", reference to undefined object \"%s\"."
|
||||
#define UNDEFINED_DIRECTION_RUN "In function \"%s\", reference to undefined direction \"%s\"."
|
||||
#define UNKNOWN_SCOPE_RUN "In function \"%s\", reference to unknown scope \"%s\"."
|
||||
#define UNDEFINED_STRING_RUN "In function \"%s\", reference to undefined string \"%s\"."
|
||||
#define UNDEFINED_CONTAINER_RUN "In function \"%s\", reference to undefined container \"%s\"."
|
||||
#define OUT_OF_MEMORY "Out of memory, can't continue."
|
||||
#define CANT_OPEN_PROCESSED "Unable to open output file \"%s\" for writing, can't continue."
|
||||
#define CANT_OPEN_OR "Unable to open source file \"%s\" or \"%s\", can't continue."
|
||||
#define CANT_OPEN_SOURCE "Unable to open source file \"%s\", can't continue."
|
||||
#endif
|
||||
|
||||
#if NATIVE_LANGUAGE==FRENCH
|
||||
/* GAME MESSAGES */
|
||||
#define COMMENT_IGNORED "Pas de transcription en cours, commentaire ignoré.^"
|
||||
#define COMMENT_RECORDED "Commentaire enregistré.^"
|
||||
#define YES_WORD "oui"
|
||||
#define NO_WORD "no"
|
||||
#define YES_OR_NO "^Merci d'entrer ~oui~ ou ~non~: "
|
||||
#define INVALID_SELECTION "Sélection invalide.^"
|
||||
#define RESTARTING "^En train de recommencer...^"
|
||||
#define RETURN_GAME "^Retour au jeu.^"
|
||||
#define SCRIPTING_ON "Début de transcription.^"
|
||||
#define SCRIPTING_OFF "Fin de transcription.^"
|
||||
#define SCRIPTING_ALREADY_OFF "Transcription déjà terminée.^"
|
||||
#define SCRIPTING_ALREADY_ON "Transcription déjà en cours.^"
|
||||
#define CANT_WRITE_SCRIPT "Impossible d'écrire le fichier de transcription.^"
|
||||
#define ERROR_READING_WALKTHRU "Erreur lors de la lecture du fichier de solution.^"
|
||||
#define BAD_OOPS "Vous devez faire suivre la commande ~oops~ par le mot que vous souhaitez remplacer.^"
|
||||
#define CANT_CORRECT "Désolé, je ne peux corriger la dernière commande en utilisant ~oops~.^"
|
||||
#define SURE_QUIT "Êtes-vous certain de vouloir quitter ?^"
|
||||
#define SURE_RESTART "Êtes-vous certain de vouloir recommencer ?^"
|
||||
#define NOT_CLEVER "Ce n'était pas si intelligent au point de vouloir répéter cela.^"
|
||||
#define NO_MOVES "Mais vous n'avez rien fait pour le moment !^"
|
||||
#define TYPE_NUMBER "^Entrez un nombre entre %d et %d: "
|
||||
#define BY "By ~"
|
||||
#define REFERRING_TO "Faites-vous référence à :^"
|
||||
#define WALKTHRU_WORD "solution"
|
||||
#define INFO_WORD "info"
|
||||
#define RESTART_WORD "recommencer"
|
||||
#define AGAIN_WORD "encore"
|
||||
#define SCRIPT_WORD "script"
|
||||
#define UNSCRIPT_WORD "unscript"
|
||||
#define QUIT_WORD "quitter"
|
||||
#define UNDO_WORD "annuler"
|
||||
#define OOPS_WORD "oops"
|
||||
#define FROM_WORD "depuis"
|
||||
#define EXCEPT_WORD "excepté"
|
||||
#define FOR_WORD "pour"
|
||||
#define BUT_WORD "mais"
|
||||
#define AND_WORD "et"
|
||||
#define THEN_WORD "puis"
|
||||
#define OF_WORD "de"
|
||||
#define SHE_WORD "elle"
|
||||
#define HE_WORD "il"
|
||||
#define THAT_WORD "ce"
|
||||
#define THEM_WORD "ces"
|
||||
#define THOSE_WORD "ceux"
|
||||
#define THEY_WORD "ils"
|
||||
#define IT_WORD "il"
|
||||
#define ITSELF_WORD "lui-même"
|
||||
#define HIM_WORD "him"
|
||||
#define HIMSELF_WORD "lui-même"
|
||||
#define HER_WORD "her"
|
||||
#define HERSELF_WORD "elle-même"
|
||||
#define THEMSELVES_WORD "eux-même"
|
||||
#define YOU_WORD "you"
|
||||
#define YOURSELF_WORD "yourself"
|
||||
#define ONES_WORD "ceux"
|
||||
#define NO_MULTI_VERB "Vous ne pouvez vous référer à de multiples objets après le mot \"%s\".^"
|
||||
#define NO_MULTI_START "Vous ne pouvez vous référer à de multiples objets au début d'une commande.^"
|
||||
#define PERSON_CONCEALING "%s ne semble par porter cela.^"
|
||||
#define PERSON_POSSESSIVE "%s ne vous laissera pas lui prendre ses affaires.^"
|
||||
#define CONTAINER_CLOSED "%s est fermé.^"
|
||||
#define CONTAINER_CLOSED_FEM "%s est fermé.^"
|
||||
#define FROM_NON_CONTAINER "Le mot \"%s\" doit être suivi par un contenant.^"
|
||||
#define DOUBLE_EXCEPT "Vous ne pouvez utiliser le mot \"%s\" qu'une fois par référence d'objet.^"
|
||||
#define NONE_HELD "Vous ne portez rien de cela.^"
|
||||
#define NO_OBJECTS "Je ne comprends pas ce à quoi vous vous réferez.^"
|
||||
#define NO_FILENAME "Les commandes de sauvegarde et lecture doivent être suivies par un nom de fichier.^"
|
||||
#define MOVE_UNDONE "Le tour précédent a été annulé.^^"
|
||||
#define NO_UNDO "Il n'y a rien à annuler.^"
|
||||
#define CANT_SAVE "Impossible de sauvegarder l'état du jeu sur fichier.^"
|
||||
#define CANT_RESTORE "Impossible de récupérer l'état du jeu depuis le fichier.^"
|
||||
#define GAME_SAVED "Jeu sauvegardé.^"
|
||||
#define INCOMPLETE_SENTENCE "La phrase que vous avez tapée n'est pas complète.^"
|
||||
#define UNKNOWN_OBJECT "Vous ne pouvez voir ~"
|
||||
#define UNKNOWN_OBJECT_END "~.^"
|
||||
#define CANT_USE_WORD "Vous ne pouvez utiliser le mot ~"
|
||||
#define IN_CONTEXT "~ dans ce contexte.^"
|
||||
#define DONT_SEE "Vous ne voyez pas "
|
||||
#define HERE_WORD " ici.^"
|
||||
#define BAD_SAVED_GAME "Ficher de sauvegarde incompatible."
|
||||
#define ARENT "ne sont pas"
|
||||
#define ISNT "n'est pas"
|
||||
#define ARE "sont"
|
||||
#define IS "est"
|
||||
#define DONT "ne font pas"
|
||||
#define DOESNT "ne fait pas"
|
||||
#define DO "font"
|
||||
#define DOES "fait"
|
||||
#define SCORE_UP "^[VOTRE SCORE VIENT D'AUGMENTER DE "
|
||||
#define POINT " POINT]^"
|
||||
#define POINTS " POINTS]^"
|
||||
#define STARTING "Démarrage."
|
||||
#define NO_IT "Vous devez préalablement avoir fait référence à un nom reconnu pour pouvoir utiliser le mot ~"
|
||||
#define NO_IT_END "~.^"
|
||||
#define BACK_REFERENCE "Vous devez préalablement avoir fait référence à un nom reconnu dans la même phrase pour pouvoir utiliser le mot ~"
|
||||
#define BACK_REFERENCE_END "~.^"
|
||||
#define WHEN_YOU_SAY "When you say ~"
|
||||
#define MUST_SPECIFY "~, vous devez spécifier si vous voulez dire "
|
||||
#define OR_WORD " ou "
|
||||
|
||||
/* SYSTEM MESSAGES */
|
||||
#define READ_ERROR "Erreur de lecture du fichier de jeu."
|
||||
#define OLD_INTERPRETER "La version de l'interpréteur est plus ancienne que le fichier de jeu (v%d), impossible de continuer."
|
||||
#define BAD_CURSOR "You can only use the ~cursor~ command in the status window.^"
|
||||
#define INCOMPLETE_GRAMMAR "Incomplete grammar statement."
|
||||
#define GAME_MODIFIED "Game file modified, reloading.\n"
|
||||
#define NOT_INTEGER "In function \"%s\", \"%s\" command requires integer parameter."
|
||||
#define NO_NAME_FUNCTION "In line %d, a function must have at least one name."
|
||||
#define MAXIMUM_ATTRIBUTES_ERR "In line %d, unable to create attribute \"%s\", maximum number of attributes already defined."
|
||||
#define BAD_PLAYER "In function \"%s\", attempt to use object pointer \"player\" while it does not point to an object (%d)."
|
||||
#define BAD_PARENT "In function \"%s\", attempt to use the variable 'here' while the variable 'player' does not have a legal parent."
|
||||
#define BAD_POINTER "In function \"%s\", attempt to use object pointer \"%s\" that does not point to an object (%d)."
|
||||
#define ILLEGAL_LABEL "In line %d, reserved word \"%s\" used as label."
|
||||
#define USED_LABEL_INT "In line %d, \"%s\" is already used as a variable label."
|
||||
#define USED_LABEL_CINT "In line %d, \"%s\" is already used as an integer constant label."
|
||||
#define USED_LABEL_STR "In line %d, \"%s\" is already used as a string label."
|
||||
#define USED_LABEL_CSTR "In line %d, \"%s\" is already used as a string constant label."
|
||||
#define USED_LABEL_ATT "In line %d, \"%s\" is already used as an attribute label."
|
||||
#define USED_LABEL_OBJ "In line %d, \"%s\" is already used as an object or location label."
|
||||
#define NO_OBJECT_ERR "In line %d, property \"%s\" defined before first object or location."
|
||||
#define BAD_INCLUDE "'#include' directive must be followed by file name enclosed in double quotes."
|
||||
#define BAD_PARAMETER "Unknown or inappropriate type of container '%s' associated with parameter '%s'."
|
||||
#define BAD_VALUE "Value '%s' cannot be stored in container '%s'."
|
||||
#define NO_MEDIA "WebJACL: Media file \"%s\" not found, external media support disabled.\n"
|
||||
#define MEDIA_REGISTERED "WebJACL: Registered %d media.\n"
|
||||
#define CLEANING_UP "WebJACL: Cleaning up...\n"
|
||||
#define NO_GAME "No game file specified, can't continue."
|
||||
#define NO_PORT "WebJACL: No port number specified (-p <number>), using default port %d.\n"
|
||||
#define WEBJACL_CONFIGURED "WebJACL server configured on %s:%d\n"
|
||||
#define NOT_FOUND "Unable to open game file, can't continue."
|
||||
#define CANT_OPEN "Unable to open processed file \"%s\", can't continue."
|
||||
#define CANT_RUN "A JACL game must contain at least one object (to represent the player), and at least one location (for the player to start in).^"
|
||||
#define NO_PLAYER "The object pointer 'player' does not point to an object.^"
|
||||
#define SELF_REFERENCE "In function \"%s\", reference to object \"%s\" whose parent is itself."
|
||||
#define EXECUTING "Executing function \"%s\".\n"
|
||||
#define NO_WHILE "In function \"%s\", 'endwhile' command without matching 'while' command."
|
||||
#define NO_ITERATE "In function \"%s\", 'enditerate' command without matching 'iterate' command."
|
||||
#define NO_UPDATE "In function \"%s\", 'endupdate' command without matching 'update' command."
|
||||
#define NO_REPEAT "In function \"%s\", 'until' command without matching 'repeat' command."
|
||||
#define NO_LOOP "In function \"%s\", 'endloop' command without matching 'loop' command."
|
||||
#define UNDEFINED_FUNCTION "In function \"%s\", attempt to execute undefined function \"%s\"."
|
||||
#define DIVIDE_BY_ZERO "In function \"%s\", division by zero error."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define UNKNOWN_COMMAND "In function \"%s\", unknown command \"%s\"."
|
||||
#define STACK_OVERFLOW "Stack overflow."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define OUT_OF_RANGE "In function \"%s\", element \"%s\" out of range (%d)."
|
||||
#define GLOBAL_SELF "Reference to 'self' from global function \"%s\"."
|
||||
#define NON_GLOBAL_FIRST "In line %d, non-global function before object or location."
|
||||
#define MAXIMUM_EXCEEDED "Maximum number of objects exceeded, can't continue."
|
||||
#define ERROR_DETECTED "1 error detected."
|
||||
#define ERRORS_DETECTED "%d errors detected."
|
||||
#define UNKNOWN_FUNCTION_RUN "Attempt to execute unknown function \"%s\"."
|
||||
#define UNKNOWN_KEYWORD_ERR "In line %d, unknown keyword \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_ERR "In line %d, unknown attribute \"%s\"."
|
||||
#define UNKNOWN_VALUE_ERR "In line %d, unable to resolve value \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_RUN "In function \"%s\", reference to unknown attribute \"%s\"."
|
||||
#define INSUFFICIENT_PARAMETERS_RUN "In function \"%s\", \"%s\" command with insufficient parameters."
|
||||
#define INSUFFICIENT_PARAMETERS_ERR "In line %d, \"%s\" keyword with insufficient parameters."
|
||||
#define UNDEFINED_ITEM_ERR "In line %d, reference to undefined item \"%s\"."
|
||||
#define UNDEFINED_ITEM_RUN "In function \"%s\", reference to undefined object \"%s\"."
|
||||
#define UNDEFINED_DIRECTION_RUN "In function \"%s\", reference to undefined direction \"%s\"."
|
||||
#define UNKNOWN_SCOPE_RUN "In function \"%s\", reference to unknown scope \"%s\"."
|
||||
#define UNDEFINED_STRING_RUN "In function \"%s\", reference to undefined string \"%s\"."
|
||||
#define UNDEFINED_CONTAINER_RUN "In function \"%s\", reference to undefined container \"%s\"."
|
||||
#define OUT_OF_MEMORY "Out of memory, can't continue."
|
||||
#define CANT_OPEN_PROCESSED "Unable to open output file \"%s\" for writing, can't continue."
|
||||
#define CANT_OPEN_OR "Unable to open source file \"%s\" or \"%s\", can't continue."
|
||||
#define CANT_OPEN_SOURCE "Unable to open source file \"%s\", can't continue."
|
||||
#endif
|
||||
|
||||
#if NATIVE_LANGUAGE==GERMAN
|
||||
/* GAME MESSAGES */
|
||||
#define COMMENT_IGNORED "No transcript running, comment ignored.^"
|
||||
#define COMMENT_RECORDED "Comment recorded.^"
|
||||
#define YES_WORD "yes"
|
||||
#define NO_WORD "no"
|
||||
#define YES_OR_NO "^Please enter ~yes~ or ~no~: "
|
||||
#define YES_WORD "yes"
|
||||
#define NO_WORD "no"
|
||||
#define INVALID_SELECTION "Invalid selection.^"
|
||||
#define RESTARTING "^Restarting...^"
|
||||
#define RETURN_GAME "^Returning to game.^"
|
||||
#define SCRIPTING_ON "Scripting on.^"
|
||||
#define SCRIPTING_OFF "Scripting off.^"
|
||||
#define SCRIPTING_ALREADY_OFF "Scripting already off.^"
|
||||
#define SCRIPTING_ALREADY_ON "Scripting already on.^"
|
||||
#define CANT_WRITE_SCRIPT "Unable to write to script file.^"
|
||||
#define ERROR_READING_WALKTHRU "Error reading walkthru file.^"
|
||||
#define BAD_OOPS "You must follow the ~oops~ command with the word you wish to use instead.^"
|
||||
#define CANT_CORRECT "I can't correct the last command using ~oops~, sorry.^"
|
||||
#define SURE_QUIT "Are you sure you want to quit?^"
|
||||
#define SURE_RESTART "Are you sure you want to restart?^"
|
||||
#define NOT_CLEVER "It wasn't so clever as to be worth repeating.^"
|
||||
#define NO_MOVES "But you haven't done anything yet!^"
|
||||
#define TYPE_NUMBER "^Type a number between %d and %d: "
|
||||
#define BY "By ~"
|
||||
#define REFERRING_TO "~, are you referring to:^"
|
||||
#define WALKTHRU_WORD "walkthru"
|
||||
#define INFO_WORD "info"
|
||||
#define RESTART_WORD "restart"
|
||||
#define AGAIN_WORD "again"
|
||||
#define SCRIPT_WORD "script"
|
||||
#define UNSCRIPT_WORD "unscript"
|
||||
#define QUIT_WORD "quit"
|
||||
#define UNDO_WORD "undo"
|
||||
#define OOPS_WORD "oops"
|
||||
#define FROM_WORD "from"
|
||||
#define EXCEPT_WORD "except"
|
||||
#define FOR_WORD "for"
|
||||
#define BUT_WORD "but"
|
||||
#define AND_WORD "and"
|
||||
#define THEN_WORD "then"
|
||||
#define OF_WORD "of"
|
||||
#define SHE_WORD "she"
|
||||
#define HE_WORD "he"
|
||||
#define THAT_WORD "that"
|
||||
#define THEM_WORD "them"
|
||||
#define THOSE_WORD "those"
|
||||
#define THEY_WORD "they"
|
||||
#define IT_WORD "it"
|
||||
#define ITSELF_WORD "itself"
|
||||
#define HIM_WORD "him"
|
||||
#define HIMSELF_WORD "himself"
|
||||
#define HER_WORD "her"
|
||||
#define HERSELF_WORD "herself"
|
||||
#define THEMSELVES_WORD "themselves"
|
||||
#define YOU_WORD "you"
|
||||
#define YOURSELF_WORD "yourself"
|
||||
#define ONES_WORD "ones"
|
||||
#define NO_MULTI_VERB "You can't refer to multiple objects directly after the word ~%s~.^"
|
||||
#define NO_MULTI_START "You can't refer to multiple objects at the start of a command.^"
|
||||
#define PERSON_CONCEALING "%s doesn't seem to be carrying any such thing.^"
|
||||
#define PERSON_POSSESSIVE "%s isn't about to let you take anything of theirs.^"
|
||||
#define CONTAINER_CLOSED "%s is closed.^"
|
||||
#define CONTAINER_CLOSED_FEM "%s is closed.^"
|
||||
#define FROM_NON_CONTAINER "The word ~%s~ must be followed by a container.^"
|
||||
#define DOUBLE_EXCEPT "You can only use the word ~%s~ once per object reference.^"
|
||||
#define NONE_HELD "You are not holding anything like that.^"
|
||||
#define NO_OBJECTS "I don't see what you are referring to.^"
|
||||
#define NO_FILENAME "Save and restore commands must be followed by a filename.^"
|
||||
#define MOVE_UNDONE "Previous move undone.^^"
|
||||
#define NO_UNDO "Nothing to undo.^"
|
||||
#define CANT_SAVE "Unable to save game state to file.^"
|
||||
#define CANT_RESTORE "Unable to restore game state from file.^"
|
||||
#define GAME_SAVED "Game saved.^"
|
||||
#define INCOMPLETE_SENTENCE "The sentence you typed was incomplete.^"
|
||||
#define UNKNOWN_OBJECT "You can't see any such thing as ~"
|
||||
#define UNKNOWN_OBJECT_END "~.^"
|
||||
#define CANT_USE_WORD "You can't use the word ~"
|
||||
#define IN_CONTEXT "~ in that context.^"
|
||||
#define DONT_SEE "You don't see "
|
||||
#define HERE_WORD " here.^"
|
||||
#define BAD_SAVED_GAME "Attempt to restore incompatible saved-game file."
|
||||
#define ARENT "aren't"
|
||||
#define ISNT "isn't"
|
||||
#define ARE "are"
|
||||
#define IS "is"
|
||||
#define DONT "don't"
|
||||
#define DOESNT "doesn't"
|
||||
#define DO "do"
|
||||
#define DOES "does"
|
||||
#define SCORE_UP "^[YOUR SCORE JUST WENT UP BY "
|
||||
#define POINT " POINT]^"
|
||||
#define POINTS " POINTS]^"
|
||||
#define STARTING "Starting."
|
||||
#define NO_IT "You must have referred to an appropriate noun previously to use the word ~"
|
||||
#define NO_IT_END "~.^"
|
||||
#define BACK_REFERENCE "You must have referred to a noun previously in the same sentence to use the word ~"
|
||||
#define BACK_REFERENCE_END "~.^"
|
||||
#define WHEN_YOU_SAY "When you say ~"
|
||||
#define MUST_SPECIFY "~, you must specify whether you mean "
|
||||
#define OR_WORD " or "
|
||||
|
||||
/* SYSTEM MESSAGES */
|
||||
#define READ_ERROR "Error reading game file."
|
||||
#define OLD_INTERPRETER "Interpreter version is older than game file (v%d), can't continue."
|
||||
#define BAD_CURSOR "You can only use the ~cursor~ command in the status window.^"
|
||||
#define INCOMPLETE_GRAMMAR "Incomplete grammar statement."
|
||||
#define GAME_MODIFIED "Game file modified, reloading.\n"
|
||||
#define NOT_INTEGER "In function \"%s\", \"%s\" command requires integer parameter."
|
||||
#define NO_NAME_FUNCTION "In line %d, a function must have at least one name."
|
||||
#define MAXIMUM_ATTRIBUTES_ERR "In line %d, unable to create attribute \"%s\", maximum number of attributes already defined."
|
||||
#define BAD_PLAYER "In function \"%s\", attempt to use object pointer \"player\" while it does not point to an object (%d)."
|
||||
#define BAD_PARENT "In function \"%s\", attempt to use the variable 'here' while the variable 'player' does not have a legal parent."
|
||||
#define BAD_POINTER "In function \"%s\", attempt to use object pointer \"%s\" that does not point to an object (%d)."
|
||||
#define ILLEGAL_LABEL "In line %d, reserved word \"%s\" used as label."
|
||||
#define USED_LABEL_INT "In line %d, \"%s\" is already used as a variable label."
|
||||
#define USED_LABEL_CINT "In line %d, \"%s\" is already used as an integer constant label."
|
||||
#define USED_LABEL_STR "In line %d, \"%s\" is already used as a string label."
|
||||
#define USED_LABEL_CSTR "In line %d, \"%s\" is already used as a string constant label."
|
||||
#define USED_LABEL_ATT "In line %d, \"%s\" is already used as an attribute label."
|
||||
#define USED_LABEL_OBJ "In line %d, \"%s\" is already used as an object or location label."
|
||||
#define NO_OBJECT_ERR "In line %d, property \"%s\" defined before first object or location."
|
||||
#define BAD_INCLUDE "'#include' directive must be followed by file name enclosed in double quotes."
|
||||
#define BAD_PARAMETER "Unknown or inappropriate type of container '%s' associated with parameter '%s'."
|
||||
#define BAD_VALUE "Value '%s' cannot be stored in container '%s'."
|
||||
#define NO_MEDIA "WebJACL: Media file \"%s\" not found, external media support disabled.\n"
|
||||
#define MEDIA_REGISTERED "WebJACL: Registered %d media.\n"
|
||||
#define CLEANING_UP "WebJACL: Cleaning up...\n"
|
||||
#define NO_GAME "No game file specified, can't continue."
|
||||
#define NO_PORT "WebJACL: No port number specified (-p <number>), using default port %d.\n"
|
||||
#define WEBJACL_CONFIGURED "WebJACL server configured on %s:%d\n"
|
||||
#define NOT_FOUND "Unable to open game file, can't continue."
|
||||
#define CANT_OPEN "Unable to open processed file \"%s\", can't continue."
|
||||
#define CANT_RUN "A JACL game must contain at least one object (to represent the player), and at least one location (for the player to start in).^"
|
||||
#define NO_PLAYER "The object pointer 'player' does not point to an object.^"
|
||||
#define SELF_REFERENCE "In function \"%s\", reference to object \"%s\" whose parent is itself."
|
||||
#define EXECUTING "Executing function \"%s\".\n"
|
||||
#define NO_WHILE "In function \"%s\", 'endwhile' command without matching 'while' command."
|
||||
#define NO_ITERATE "In function \"%s\", 'enditerate' command without matching 'iterate' command."
|
||||
#define NO_UPDATE "In function \"%s\", 'endupdate' command without matching 'update' command."
|
||||
#define NO_REPEAT "In function \"%s\", 'until' command without matching 'repeat' command."
|
||||
#define NO_LOOP "In function \"%s\", 'endloop' command without matching 'loop' command."
|
||||
#define UNDEFINED_FUNCTION "In function \"%s\", attempt to execute undefined function \"%s\"."
|
||||
#define DIVIDE_BY_ZERO "In function \"%s\", division by zero error."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define UNKNOWN_COMMAND "In function \"%s\", unknown command \"%s\"."
|
||||
#define STACK_OVERFLOW "Stack overflow."
|
||||
#define ILLEGAL_OPERATOR "In function \"%s\", illegal operator \"%s\"."
|
||||
#define OUT_OF_RANGE "In function \"%s\", element \"%s\" out of range (%d)."
|
||||
#define GLOBAL_SELF "Reference to 'self' from global function \"%s\"."
|
||||
#define NON_GLOBAL_FIRST "In line %d, non-global function before object or location."
|
||||
#define MAXIMUM_EXCEEDED "Maximum number of objects exceeded, can't continue."
|
||||
#define ERROR_DETECTED "1 error detected."
|
||||
#define ERRORS_DETECTED "%d errors detected."
|
||||
#define UNKNOWN_FUNCTION_RUN "Attempt to execute unknown function \"%s\"."
|
||||
#define UNKNOWN_KEYWORD_ERR "In line %d, unknown keyword \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_ERR "In line %d, unknown attribute \"%s\"."
|
||||
#define UNKNOWN_VALUE_ERR "In line %d, unable to resolve value \"%s\"."
|
||||
#define UNKNOWN_ATTRIBUTE_RUN "In function \"%s\", reference to unknown attribute \"%s\"."
|
||||
#define INSUFFICIENT_PARAMETERS_RUN "In function \"%s\", \"%s\" command with insufficient parameters."
|
||||
#define INSUFFICIENT_PARAMETERS_ERR "In line %d, \"%s\" keyword with insufficient parameters."
|
||||
#define UNDEFINED_ITEM_ERR "In line %d, reference to undefined item \"%s\"."
|
||||
#define UNDEFINED_ITEM_RUN "In function \"%s\", reference to undefined object \"%s\"."
|
||||
#define UNDEFINED_DIRECTION_RUN "In function \"%s\", reference to undefined direction \"%s\"."
|
||||
#define UNKNOWN_SCOPE_RUN "In function \"%s\", reference to unknown scope \"%s\"."
|
||||
#define UNDEFINED_STRING_RUN "In function \"%s\", reference to undefined string \"%s\"."
|
||||
#define UNDEFINED_CONTAINER_RUN "In function \"%s\", reference to undefined container \"%s\"."
|
||||
#define OUT_OF_MEMORY "Out of memory, can't continue."
|
||||
#define CANT_OPEN_PROCESSED "Unable to open output file \"%s\" for writing, can't continue."
|
||||
#define CANT_OPEN_OR "Unable to open source file \"%s\" or \"%s\", can't continue."
|
||||
#define CANT_OPEN_SOURCE "Unable to open source file \"%s\", can't continue."
|
||||
#endif
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
533
engines/glk/jacl/libcsv.cpp
Normal file
533
engines/glk/jacl/libcsv.cpp
Normal file
@@ -0,0 +1,533 @@
|
||||
/* 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 "glk/jacl/csv.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#define VERSION "3.0.0"
|
||||
|
||||
//#define MAX_INT ((size_t)-1)
|
||||
|
||||
#define ROW_NOT_BEGUN 0
|
||||
#define FIELD_NOT_BEGUN 1
|
||||
#define FIELD_BEGUN 2
|
||||
#define FIELD_MIGHT_HAVE_ENDED 3
|
||||
|
||||
#define MAX_INT 0x7fff
|
||||
|
||||
/*
|
||||
Explanation of states
|
||||
ROW_NOT_BEGUN There have not been any fields encountered for this row
|
||||
FIELD_NOT_BEGUN There have been fields but we are currently not in one
|
||||
FIELD_BEGUN We are in a field
|
||||
FIELD_MIGHT_HAVE_ENDED
|
||||
We encountered a double quote inside a quoted field, the
|
||||
field is either ended or the quote is literal
|
||||
*/
|
||||
|
||||
#define MEM_BLK_SIZE 128
|
||||
|
||||
#define SUBMIT_FIELD(p) \
|
||||
do { \
|
||||
if (!quoted) \
|
||||
entry_pos -= spaces; \
|
||||
if (p->options & CSV_APPEND_NULL) \
|
||||
((p)->entry_buf[entry_pos+1]) = '\0'; \
|
||||
if (cb1) \
|
||||
cb1(p->entry_buf, entry_pos, data); \
|
||||
pstate = FIELD_NOT_BEGUN; \
|
||||
entry_pos = quoted = spaces = 0; \
|
||||
} while (0)
|
||||
|
||||
#define SUBMIT_ROW(p, c) \
|
||||
do { \
|
||||
if (cb2) \
|
||||
cb2(c, data); \
|
||||
pstate = ROW_NOT_BEGUN; \
|
||||
entry_pos = quoted = spaces = 0; \
|
||||
} while (0)
|
||||
|
||||
#define SUBMIT_CHAR(p, c) ((p)->entry_buf[entry_pos++] = (c))
|
||||
|
||||
static const char *csv_errors[] = {"success",
|
||||
"error parsing data while strict checking enabled",
|
||||
"memory exhausted while increasing buffer size",
|
||||
"data size too large",
|
||||
"invalid status code"
|
||||
};
|
||||
|
||||
int csv_error(struct csv_parser *p) {
|
||||
/* Return the current status of the parser */
|
||||
return p->status;
|
||||
}
|
||||
|
||||
const char *csv_strerror(int status) {
|
||||
/* Return a textual description of status */
|
||||
if (status >= CSV_EINVALID || status < 0)
|
||||
return csv_errors[CSV_EINVALID];
|
||||
else
|
||||
return csv_errors[status];
|
||||
}
|
||||
|
||||
int csv_get_opts(struct csv_parser *p) {
|
||||
/* Return the currently set options of parser */
|
||||
if (p == nullptr)
|
||||
return -1;
|
||||
|
||||
return p->options;
|
||||
}
|
||||
|
||||
int csv_set_opts(struct csv_parser *p, unsigned char options) {
|
||||
/* Set the options */
|
||||
if (p == nullptr)
|
||||
return -1;
|
||||
|
||||
p->options = options;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csv_init(struct csv_parser *p, unsigned char options) {
|
||||
/* Initialize a csv_parser object returns 0 on success, -1 on error */
|
||||
if (p == nullptr)
|
||||
return -1;
|
||||
|
||||
p->entry_buf = nullptr;
|
||||
p->pstate = ROW_NOT_BEGUN;
|
||||
p->quoted = 0;
|
||||
p->spaces = 0;
|
||||
p->entry_pos = 0;
|
||||
p->entry_size = 0;
|
||||
p->status = 0;
|
||||
p->options = options;
|
||||
p->quote_char = CSV_QUOTE;
|
||||
p->delim_char = CSV_COMMA;
|
||||
p->is_space = nullptr;
|
||||
p->is_term = nullptr;
|
||||
p->blk_size = MEM_BLK_SIZE;
|
||||
p->malloc_func = nullptr;
|
||||
p->realloc_func = realloc;
|
||||
p->free_func = free;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void csv_free(struct csv_parser *p) {
|
||||
/* Free the entry_buffer of csv_parser object */
|
||||
if (p == nullptr)
|
||||
return;
|
||||
|
||||
if (p->entry_buf)
|
||||
p->free_func(p->entry_buf);
|
||||
|
||||
p->entry_buf = nullptr;
|
||||
p->entry_size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int csv_fini(struct csv_parser *p, void (*cb1)(void *, size_t, void *), void (*cb2)(int c, void *), void *data) {
|
||||
/* Finalize parsing. Needed, for example, when file does not end in a newline */
|
||||
int quoted = p->quoted;
|
||||
int pstate = p->pstate;
|
||||
size_t spaces = p->spaces;
|
||||
size_t entry_pos = p->entry_pos;
|
||||
|
||||
if (p == nullptr)
|
||||
return -1;
|
||||
|
||||
|
||||
if (p->pstate == FIELD_BEGUN && p->quoted && p->options & CSV_STRICT && p->options & CSV_STRICT_FINI) {
|
||||
/* Current field is quoted, no end-quote was seen, and CSV_STRICT_FINI is set */
|
||||
p->status = CSV_EPARSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (p->pstate) {
|
||||
case FIELD_MIGHT_HAVE_ENDED:
|
||||
p->entry_pos -= p->spaces + 1; /* get rid of spaces and original quote */
|
||||
/* Fall-through */
|
||||
case FIELD_NOT_BEGUN:
|
||||
case FIELD_BEGUN:
|
||||
quoted = p->quoted, pstate = p->pstate;
|
||||
spaces = p->spaces, entry_pos = p->entry_pos;
|
||||
SUBMIT_FIELD(p);
|
||||
SUBMIT_ROW(p, -1);
|
||||
case ROW_NOT_BEGUN: /* Already ended properly */
|
||||
;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset parser */
|
||||
p->spaces = p->quoted = p->entry_pos = p->status = 0;
|
||||
p->pstate = ROW_NOT_BEGUN;
|
||||
(void)pstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void csv_set_delim(struct csv_parser *p, unsigned char c) {
|
||||
/* Set the delimiter */
|
||||
if (p) p->delim_char = c;
|
||||
}
|
||||
|
||||
void csv_set_quote(struct csv_parser *p, unsigned char c) {
|
||||
/* Set the quote character */
|
||||
if (p) p->quote_char = c;
|
||||
}
|
||||
|
||||
unsigned char csv_get_delim(struct csv_parser *p) {
|
||||
/* Get the delimiter */
|
||||
return p->delim_char;
|
||||
}
|
||||
|
||||
unsigned char csv_get_quote(struct csv_parser *p) {
|
||||
/* Get the quote character */
|
||||
return p->quote_char;
|
||||
}
|
||||
|
||||
void csv_set_space_func(struct csv_parser *p, int (*f)(unsigned char)) {
|
||||
/* Set the space function */
|
||||
if (p) p->is_space = f;
|
||||
}
|
||||
|
||||
void csv_set_term_func(struct csv_parser *p, int (*f)(unsigned char)) {
|
||||
/* Set the term function */
|
||||
if (p) p->is_term = f;
|
||||
}
|
||||
|
||||
void csv_set_realloc_func(struct csv_parser *p, void *(*f)(void *, size_t)) {
|
||||
/* Set the realloc function used to increase buffer size */
|
||||
if (p && f) p->realloc_func = f;
|
||||
}
|
||||
|
||||
void csv_set_free_func(struct csv_parser *p, void (*f)(void *)) {
|
||||
/* Set the free function used to free the buffer */
|
||||
if (p && f) p->free_func = f;
|
||||
}
|
||||
|
||||
void csv_set_blk_size(struct csv_parser *p, size_t size) {
|
||||
/* Set the block size used to increment buffer size */
|
||||
if (p) p->blk_size = size;
|
||||
}
|
||||
|
||||
size_t csv_get_buffer_size(struct csv_parser *p) {
|
||||
/* Get the size of the entry buffer */
|
||||
if (p)
|
||||
return p->entry_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csv_increase_buffer(struct csv_parser *p) {
|
||||
/* Increase the size of the entry buffer. Attempt to increase size by
|
||||
* p->blk_size, if this is larger than MAX_INT try to increase current
|
||||
* buffer size to MAX_INT. If allocation fails, try to allocate halve
|
||||
* the size and try again until successful or increment size is zero.
|
||||
*/
|
||||
|
||||
size_t to_add = p->blk_size;
|
||||
void *vp;
|
||||
|
||||
if (p->entry_size >= MAX_INT - to_add)
|
||||
to_add = MAX_INT - p->entry_size;
|
||||
|
||||
if (!to_add) {
|
||||
p->status = CSV_ETOOBIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((vp = p->realloc_func(p->entry_buf, p->entry_size + to_add)) == nullptr) {
|
||||
to_add /= 2;
|
||||
if (!to_add) {
|
||||
p->status = CSV_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update entry buffer pointer and entry_size if successful */
|
||||
p->entry_buf = (unsigned char *)vp;
|
||||
p->entry_size += to_add;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t csv_parse(struct csv_parser *p, const void *s, size_t len, void (*cb1)(void *, size_t, void *),
|
||||
void (*cb2)(int c, void *), void *data) {
|
||||
unsigned const char *us = (unsigned const char *)s; /* Access input data as array of unsigned char */
|
||||
unsigned char c; /* The character we are currently processing */
|
||||
size_t pos = 0; /* The number of characters we have processed in this call */
|
||||
|
||||
/* Store key fields into local variables for performance */
|
||||
unsigned char delim = p->delim_char;
|
||||
unsigned char quote = p->quote_char;
|
||||
int (*is_space)(unsigned char) = p->is_space;
|
||||
int (*is_term)(unsigned char) = p->is_term;
|
||||
int quoted = p->quoted;
|
||||
int pstate = p->pstate;
|
||||
size_t spaces = p->spaces;
|
||||
size_t entry_pos = p->entry_pos;
|
||||
|
||||
|
||||
if (!p->entry_buf && pos < len) {
|
||||
/* Buffer hasn't been allocated yet and len > 0 */
|
||||
if (csv_increase_buffer(p) != 0) {
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
while (pos < len) {
|
||||
/* Check memory usage, increase buffer if necessary */
|
||||
if (entry_pos == ((p->options & CSV_APPEND_NULL) ? p->entry_size - 1 : p->entry_size)) {
|
||||
if (csv_increase_buffer(p) != 0) {
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
c = us[pos++];
|
||||
|
||||
switch (pstate) {
|
||||
case ROW_NOT_BEGUN:
|
||||
case FIELD_NOT_BEGUN:
|
||||
if (is_space ? is_space(c) : c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
|
||||
continue;
|
||||
} else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
|
||||
if (pstate == FIELD_NOT_BEGUN) {
|
||||
SUBMIT_FIELD(p);
|
||||
SUBMIT_ROW(p, (unsigned char)c);
|
||||
} else { /* ROW_NOT_BEGUN */
|
||||
/* Don't submit empty rows by default */
|
||||
if (p->options & CSV_REPALL_NL) {
|
||||
SUBMIT_ROW(p, (unsigned char)c);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else if (c == delim) { /* Comma */
|
||||
SUBMIT_FIELD(p);
|
||||
break;
|
||||
} else if (c == quote) { /* Quote */
|
||||
pstate = FIELD_BEGUN;
|
||||
quoted = 1;
|
||||
} else { /* Anything else */
|
||||
pstate = FIELD_BEGUN;
|
||||
quoted = 0;
|
||||
SUBMIT_CHAR(p, c);
|
||||
}
|
||||
break;
|
||||
case FIELD_BEGUN:
|
||||
if (c == quote) { /* Quote */
|
||||
if (quoted) {
|
||||
SUBMIT_CHAR(p, c);
|
||||
pstate = FIELD_MIGHT_HAVE_ENDED;
|
||||
} else {
|
||||
/* STRICT ERROR - double quote inside non-quoted field */
|
||||
if (p->options & CSV_STRICT) {
|
||||
p->status = CSV_EPARSE;
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos - 1;
|
||||
}
|
||||
SUBMIT_CHAR(p, c);
|
||||
spaces = 0;
|
||||
}
|
||||
} else if (c == delim) { /* Comma */
|
||||
if (quoted) {
|
||||
SUBMIT_CHAR(p, c);
|
||||
} else {
|
||||
SUBMIT_FIELD(p);
|
||||
}
|
||||
} else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
|
||||
if (!quoted) {
|
||||
SUBMIT_FIELD(p);
|
||||
SUBMIT_ROW(p, (unsigned char)c);
|
||||
} else {
|
||||
SUBMIT_CHAR(p, c);
|
||||
}
|
||||
} else if (!quoted && (is_space ? is_space(c) : c == CSV_SPACE || c == CSV_TAB)) { /* Tab or space for non-quoted field */
|
||||
SUBMIT_CHAR(p, c);
|
||||
spaces++;
|
||||
} else { /* Anything else */
|
||||
SUBMIT_CHAR(p, c);
|
||||
spaces = 0;
|
||||
}
|
||||
break;
|
||||
case FIELD_MIGHT_HAVE_ENDED:
|
||||
/* This only happens when a quote character is encountered in a quoted field */
|
||||
if (c == delim) { /* Comma */
|
||||
entry_pos -= spaces + 1; /* get rid of spaces and original quote */
|
||||
SUBMIT_FIELD(p);
|
||||
} else if (is_term ? is_term(c) : c == CSV_CR || c == CSV_LF) { /* Carriage Return or Line Feed */
|
||||
entry_pos -= spaces + 1; /* get rid of spaces and original quote */
|
||||
SUBMIT_FIELD(p);
|
||||
SUBMIT_ROW(p, (unsigned char)c);
|
||||
} else if (is_space ? is_space(c) : c == CSV_SPACE || c == CSV_TAB) { /* Space or Tab */
|
||||
SUBMIT_CHAR(p, c);
|
||||
spaces++;
|
||||
} else if (c == quote) { /* Quote */
|
||||
if (spaces) {
|
||||
/* STRICT ERROR - unescaped double quote */
|
||||
if (p->options & CSV_STRICT) {
|
||||
p->status = CSV_EPARSE;
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos - 1;
|
||||
}
|
||||
spaces = 0;
|
||||
SUBMIT_CHAR(p, c);
|
||||
} else {
|
||||
/* Two quotes in a row */
|
||||
pstate = FIELD_BEGUN;
|
||||
}
|
||||
} else { /* Anything else */
|
||||
/* STRICT ERROR - unescaped double quote */
|
||||
if (p->options & CSV_STRICT) {
|
||||
p->status = CSV_EPARSE;
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos - 1;
|
||||
}
|
||||
pstate = FIELD_BEGUN;
|
||||
spaces = 0;
|
||||
SUBMIT_CHAR(p, c);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->quoted = quoted, p->pstate = pstate, p->spaces = spaces, p->entry_pos = entry_pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t csv_write(void *dest, size_t dest_size, const void *src, size_t src_size) {
|
||||
unsigned char *cdest = (unsigned char *)dest;
|
||||
const unsigned char *csrc = (const unsigned char *)src;
|
||||
size_t chars = 0;
|
||||
|
||||
if (src == nullptr)
|
||||
return 0;
|
||||
|
||||
if (cdest == nullptr)
|
||||
dest_size = 0;
|
||||
|
||||
if (dest_size > 0)
|
||||
*cdest++ = '"';
|
||||
chars++;
|
||||
|
||||
while (src_size) {
|
||||
if (*csrc == '"') {
|
||||
if (dest_size > chars)
|
||||
*cdest++ = '"';
|
||||
if (chars < MAX_INT) chars++;
|
||||
}
|
||||
if (dest_size > chars)
|
||||
*cdest++ = *csrc;
|
||||
if (chars < MAX_INT) chars++;
|
||||
src_size--;
|
||||
csrc++;
|
||||
}
|
||||
|
||||
if (dest_size > chars)
|
||||
*cdest = '"';
|
||||
if (chars < MAX_INT) chars++;
|
||||
|
||||
return chars;
|
||||
}
|
||||
|
||||
int csv_fwrite(Common::WriteStream *fp, const void *src, size_t src_size) {
|
||||
const unsigned char *csrc = (const unsigned char *)src;
|
||||
|
||||
if (fp == nullptr || src == nullptr)
|
||||
return 0;
|
||||
|
||||
fp->writeByte('"');
|
||||
|
||||
while (src_size) {
|
||||
if (*csrc == '"') {
|
||||
fp->writeByte('"');
|
||||
}
|
||||
fp->writeByte(*csrc);
|
||||
src_size--;
|
||||
csrc++;
|
||||
}
|
||||
|
||||
fp->writeByte('"');
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t csv_write2(void *dest, size_t dest_size, const void *src, size_t src_size, unsigned char quote) {
|
||||
unsigned char *cdest = (unsigned char *)dest;
|
||||
const unsigned char *csrc = (const unsigned char *)src;
|
||||
size_t chars = 0;
|
||||
|
||||
if (src == nullptr)
|
||||
return 0;
|
||||
|
||||
if (dest == nullptr)
|
||||
dest_size = 0;
|
||||
|
||||
if (dest_size > 0)
|
||||
*cdest++ = quote;
|
||||
chars++;
|
||||
|
||||
while (src_size) {
|
||||
if (*csrc == quote) {
|
||||
if (dest_size > chars)
|
||||
*cdest++ = quote;
|
||||
if (chars < MAX_INT) chars++;
|
||||
}
|
||||
if (dest_size > chars)
|
||||
*cdest++ = *csrc;
|
||||
if (chars < MAX_INT) chars++;
|
||||
src_size--;
|
||||
csrc++;
|
||||
}
|
||||
|
||||
if (dest_size > chars)
|
||||
*cdest = quote;
|
||||
if (chars < MAX_INT) chars++;
|
||||
|
||||
return chars;
|
||||
}
|
||||
|
||||
int csv_fwrite2(Common::WriteStream *fp, const void *src, size_t src_size, unsigned char quote) {
|
||||
const unsigned char *csrc = (const unsigned char *)src;
|
||||
|
||||
if (fp == nullptr || src == nullptr)
|
||||
return 0;
|
||||
|
||||
fp->writeByte(quote);
|
||||
|
||||
while (src_size) {
|
||||
if (*csrc == quote) {
|
||||
fp->writeByte(quote);
|
||||
}
|
||||
fp->writeByte(*csrc);
|
||||
src_size--;
|
||||
csrc++;
|
||||
}
|
||||
|
||||
fp->writeByte(quote);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
1674
engines/glk/jacl/loader.cpp
Normal file
1674
engines/glk/jacl/loader.cpp
Normal file
File diff suppressed because it is too large
Load Diff
51
engines/glk/jacl/logging.cpp
Normal file
51
engines/glk/jacl/logging.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
#include "glk/jacl/language.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern char user_id[];
|
||||
extern char prefix[];
|
||||
|
||||
void log_error(const char *message, int console) {
|
||||
/* LOG A MESSAGE TO THE CONSOLE */
|
||||
|
||||
char consoleMessage[256];
|
||||
event_t event;
|
||||
|
||||
// BUILD A STRING SUITABLE FOR DISPLAY ON THE CONSOLE.
|
||||
Common::sprintf_s(consoleMessage, "ERROR: %s^", message);
|
||||
|
||||
g_vm->glk_set_style(style_Alert);
|
||||
write_text(consoleMessage);
|
||||
g_vm->glk_set_style(style_Normal);
|
||||
|
||||
// FLUSH THE GLK WINDOW SO THE ERROR GETS DISPLAYED IMMEDIATELY.
|
||||
g_vm->glk_select_poll(&event);
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
1917
engines/glk/jacl/parser.cpp
Normal file
1917
engines/glk/jacl/parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
200
engines/glk/jacl/prototypes.h
Normal file
200
engines/glk/jacl/prototypes.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#ifdef GLK
|
||||
extern strid_t open_glk_file(uint usage, uint mode, char *filename);
|
||||
extern glui32 glk_get_bin_line_stream(strid_t file_stream, char *buffer, glui32 max_length);
|
||||
extern glui32 parse_utf8(unsigned char *buf, glui32 buflen, glui32 *out, glui32 outlen);
|
||||
extern void convert_to_utf8(glui32 *text, int len);
|
||||
#else
|
||||
extern void update_parameters();
|
||||
#endif
|
||||
|
||||
extern int bearing(double x1, double y1, double x2, double y2);
|
||||
extern int distance(double x1, double y1, double x2, double y2);
|
||||
extern int strcondition();
|
||||
extern int and_strcondition();
|
||||
extern int logic_test(int first);
|
||||
extern int str_test(int first);
|
||||
extern int first_available(int list_number);
|
||||
extern int validate(const char *string);
|
||||
extern int noun_resolve(struct word_type *scope_word, int finding_from, int noun_number);
|
||||
extern int get_from_object(struct word_type *scope_word, int noun_number);
|
||||
extern int is_direct_child_of_from(int child);
|
||||
extern int is_child_of_from(int child);
|
||||
extern int verify_from_object(int from_object);
|
||||
extern int find_parent(int index);
|
||||
extern int scope(int index, const char *expected, int restricted = 0);
|
||||
extern int object_element_resolve(const char *textstring);
|
||||
extern int execute(const char *funcname);
|
||||
extern int object_resolve(const char *object_string);
|
||||
extern int random_number();
|
||||
extern void log_error(const char *message, int console);
|
||||
extern int parent_of(int parent_, int child, int restricted);
|
||||
extern int grand_of(int child, int objs_only);
|
||||
extern int check_light(int where);
|
||||
extern int find_route(int fromRoom, int toRoom, int known);
|
||||
extern int exit_function(int return_code);
|
||||
extern int count_resolve(const char *textstring);
|
||||
extern void jacl_set_window(winid_t new_window);
|
||||
extern void create_cstring(const char *name, const char *value);
|
||||
extern void create_string(const char *name, const char *value);
|
||||
extern void create_integer(const char *name, int value);
|
||||
extern void create_cinteger(const char *name, int value);
|
||||
extern void scripting();
|
||||
extern void undoing();
|
||||
extern void walking_thru();
|
||||
#ifndef GLK
|
||||
extern void create_paths(char *full_path);
|
||||
#endif
|
||||
extern int get_key();
|
||||
extern char get_character(const char *message);
|
||||
extern int get_yes_or_no();
|
||||
extern void get_string(char *string_buffer);
|
||||
extern int get_number(int insist, int low, int high);
|
||||
extern int save_interaction();
|
||||
extern int restore_interaction();
|
||||
extern void jacl_encrypt(char *string);
|
||||
extern void jacl_decrypt(char *string);
|
||||
//extern void log_message(const char *message, int console);
|
||||
extern void set_them(int noun_number);
|
||||
extern void preparse();
|
||||
extern void inspect(int object_num);
|
||||
extern void add_all(struct word_type *scope_word, int noun_number);
|
||||
extern void add_to_list(int noun_number, int resolved_object);
|
||||
extern void call_functions(const char *base_name);
|
||||
extern int build_object_list(struct word_type *scope_word, int noun_number);
|
||||
extern long value_of(const char *value, int run_time = 0);
|
||||
extern long attribute_resolve(const char *attribute);
|
||||
extern long user_attribute_resolve(const char *name);
|
||||
extern struct word_type *exact_match(struct word_type *pointer);
|
||||
extern struct word_type *object_match(struct word_type *iterator, int noun_number);
|
||||
extern struct integer_type *integer_resolve(const char *name);
|
||||
extern struct integer_type *integer_resolve_indexed(const char *name, int index);
|
||||
extern struct function_type *function_resolve(const char *name);
|
||||
extern struct string_type *string_resolve(const char *name);
|
||||
extern struct string_type *string_resolve_indexed(const char *name, int index);
|
||||
extern struct string_type *cstring_resolve(const char *name);
|
||||
extern struct string_type *cstring_resolve_indexed(const char *name, int index);
|
||||
extern struct cinteger_type *cinteger_resolve(const char *name);
|
||||
extern struct cinteger_type *cinteger_resolve_indexed(const char *name, int index);
|
||||
extern int array_length_resolve(const char *textstring);
|
||||
extern int legal_label_check(const char *word, int line, int type);
|
||||
extern char *object_names(int object_index, char *names_buffer);
|
||||
extern const char *arg_text_of(const char *string);
|
||||
extern const char *arg_text_of_word(int wordnumber);
|
||||
extern const char *var_text_of_word(int wordnumber);
|
||||
extern const char *text_of(const char *string);
|
||||
extern const char *text_of_word(int wordnumber);
|
||||
extern const char *expand_function(const char *name);
|
||||
extern int *container_resolve(const char *container_name);
|
||||
extern int condition();
|
||||
extern int and_condition();
|
||||
extern void free_from(struct word_type *x);
|
||||
extern void eachturn();
|
||||
extern int jacl_whitespace(char character);
|
||||
extern int get_here();
|
||||
extern char *stripwhite(char *string);
|
||||
extern void command_encapsulate();
|
||||
extern void encapsulate();
|
||||
extern void jacl_truncate();
|
||||
extern void parser();
|
||||
extern void diagnose();
|
||||
extern void look_around();
|
||||
extern char *macro_resolve(const char *textstring);
|
||||
extern char *plain_output(int index, int capital);
|
||||
extern char *sub_output(int index, int capital);
|
||||
extern char *obj_output(int index, int capital);
|
||||
extern char *that_output(int index, int capital);
|
||||
extern char *sentence_output(int index, int capital);
|
||||
extern char *isnt_output(int index, bool unused = false);
|
||||
extern char *is_output(int index, bool unused = false);
|
||||
extern char *it_output(int index, bool unused = false);
|
||||
extern char *doesnt_output(int index, bool unused = false);
|
||||
extern char *does_output(int index, bool unused = false);
|
||||
extern char *list_output(int index, int capital);
|
||||
extern char *long_output(int index);
|
||||
extern void terminate(int code);
|
||||
extern void set_arguments(const char *function_call);
|
||||
extern void pop_stack();
|
||||
extern void push_stack(int32 file_pointer);
|
||||
extern void pop_proxy();
|
||||
extern void push_proxy();
|
||||
extern void write_text(const char *string_buffer);
|
||||
extern void status_line();
|
||||
extern void newline();
|
||||
extern bool save_game(strid_t save);
|
||||
extern bool restore_game(strid_t save, bool warn = false);
|
||||
extern void write_integer(strid_t stream, int x);
|
||||
extern int read_integer(strid_t stream);
|
||||
extern void write_long(strid_t stream, long x);
|
||||
extern long read_long(strid_t stream);
|
||||
extern void save_game_state();
|
||||
extern void restore_game_state();
|
||||
extern void add_cstring(const char *name, const char *value);
|
||||
extern void clear_cstring(const char *name);
|
||||
extern void add_cinteger(const char *name, int value);
|
||||
extern void clear_cinteger(const char *name);
|
||||
extern void restart_game();
|
||||
extern void read_gamefile();
|
||||
extern void new_position(double x1, double y1, double bearing, double velocity);
|
||||
extern void build_grammar_table(struct word_type *pointer);
|
||||
extern void unkvalerr(int line, int wordno);
|
||||
extern void totalerrs(int errors);
|
||||
extern void unkatterr(int line, int wordno);
|
||||
extern void unkfunrun(const char *name);
|
||||
extern void nofnamerr(int line);
|
||||
extern void nongloberr(int line);
|
||||
extern void unkkeyerr(int line, int wordno);
|
||||
extern void maxatterr(int line, int wordno);
|
||||
extern void unkattrun(int wordno);
|
||||
extern void badptrrun(const char *name, int value);
|
||||
extern void badplrrun(int value);
|
||||
extern void badparrun();
|
||||
extern void notintrun();
|
||||
extern void noproprun(int unused = 0);
|
||||
extern void noproperr(int line);
|
||||
extern void noobjerr(int line);
|
||||
extern void unkobjerr(int line, int wordno);
|
||||
extern void unkobjrun(int wordno);
|
||||
extern void unkdirrun(int wordno);
|
||||
extern void unkscorun(const char *scope);
|
||||
extern void unkstrrun(const char *variable);
|
||||
extern void unkvarrun(const char *variable);
|
||||
extern void outofmem();
|
||||
extern void set_defaults();
|
||||
extern void no_it();
|
||||
extern void more(const char *message);
|
||||
extern int jpp();
|
||||
extern int process_file(const char *sourceFile1, char *sourceFile2);
|
||||
extern char *strip_return(char *string);
|
||||
extern const char *object_generator(const char *text, int state);
|
||||
extern const char *verb_generator(const char *text, int state);
|
||||
extern void add_word(const char *word);
|
||||
extern void create_language_constants();
|
||||
extern int select_next();
|
||||
extern void jacl_sleep(unsigned int mseconds);
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
1319
engines/glk/jacl/resolvers.cpp
Normal file
1319
engines/glk/jacl/resolvers.cpp
Normal file
File diff suppressed because it is too large
Load Diff
223
engines/glk/jacl/types.h
Normal file
223
engines/glk/jacl/types.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/* 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 "glk/jacl/constants.h"
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
#define DIR_SEPARATOR '/'
|
||||
#define DATA_DIR "data/"
|
||||
#define TEMP_DIR "temp/"
|
||||
#define INCLUDE_DIR "include/"
|
||||
|
||||
// THIS STRUCTURE CONTAINS ALL THE INFORMATION THAT NEEDS TO BE
|
||||
// SAVED IN ORDER TO CALL parse() RECURSIVELY
|
||||
struct proxy_type {
|
||||
int object_pointers[4]; // NOUN1 -> NOUN4
|
||||
int integer[MAX_WORDS]; // THE COMANDS INTEGERS
|
||||
char text[MAX_WORDS][256]; // THE COMANDS STRINGS
|
||||
char command[MAX_WORDS][256]; // THE WHOLE COMMAND
|
||||
int object_list[4][MAX_OBJECTS]; // THE RESOLVED OBJECTS
|
||||
int list_size[4]; // THE SIZE OF THE ABOVE LISTS
|
||||
int max_size[4]; // THE LAST USED INDEX OF THE ABOVE LISTS
|
||||
int start_of_this_command; // PREPARSE STATE
|
||||
int start_of_last_command; // PREPARSE STATE
|
||||
int integercount; // THE NUMBER OF INTEGERS SAVED
|
||||
int textcount; // THE NUMBER OF STRINGS SAVED
|
||||
int commandcount; // THE NUMBER OF WORDS IN COMMAND
|
||||
int last_exact; // WORD POINTER FOR MATCH
|
||||
int after_from; // WORD POINTER FOR FROM WORD
|
||||
};
|
||||
|
||||
struct stack_type {
|
||||
Common::SeekableReadStream *infile;
|
||||
Common::WriteStream *outfile;
|
||||
int arguments[MAX_WORDS];
|
||||
char str_arguments[MAX_WORDS][256];
|
||||
char text_buffer[1024];
|
||||
char called_name[1024];
|
||||
char _override[84];
|
||||
char scope_criterion[24];
|
||||
char default_function[84];
|
||||
const char *word[MAX_WORDS];
|
||||
int quoted[MAX_WORDS];
|
||||
int wp;
|
||||
int argcount;
|
||||
int *loop_integer;
|
||||
int *select_integer;
|
||||
int criterion_value;
|
||||
int criterion_type;
|
||||
int criterion_negate;
|
||||
int current_level;
|
||||
int execution_level;
|
||||
#ifdef GLK
|
||||
int top_of_loop;
|
||||
int top_of_select;
|
||||
int top_of_while;
|
||||
int top_of_iterate;
|
||||
int top_of_update;
|
||||
int top_of_do_loop;
|
||||
int address;
|
||||
#else
|
||||
long top_of_loop;
|
||||
long top_of_select;
|
||||
long top_of_while;
|
||||
long top_of_iterate;
|
||||
long top_of_update;
|
||||
long top_of_do_loop;
|
||||
long address;
|
||||
#endif
|
||||
struct function_type *function;
|
||||
};
|
||||
|
||||
struct object_type {
|
||||
char label[44];
|
||||
char article[12];
|
||||
char definite[12];
|
||||
struct name_type *first_name;
|
||||
struct name_type *first_plural;
|
||||
char inventory[44];
|
||||
char described[84];
|
||||
int user_attributes;
|
||||
int user_attributes_backup;
|
||||
int attributes;
|
||||
int attributes_backup;
|
||||
int integer[16];
|
||||
int integer_backup[16];
|
||||
int nosave;
|
||||
};
|
||||
|
||||
struct integer_type {
|
||||
char name[44];
|
||||
int value;
|
||||
int value_backup;
|
||||
struct integer_type *next_integer;
|
||||
};
|
||||
|
||||
struct cinteger_type {
|
||||
char name[44];
|
||||
int value;
|
||||
struct cinteger_type *next_cinteger;
|
||||
};
|
||||
|
||||
struct attribute_type {
|
||||
char name[44];
|
||||
int value;
|
||||
struct attribute_type *next_attribute;
|
||||
};
|
||||
|
||||
struct string_type {
|
||||
char name[44];
|
||||
char value[256];
|
||||
struct string_type *next_string;
|
||||
};
|
||||
|
||||
struct function_type {
|
||||
char name[84];
|
||||
#ifdef GLK
|
||||
glui32 position;
|
||||
#else
|
||||
long position;
|
||||
#endif
|
||||
|
||||
int self;
|
||||
int call_count;
|
||||
int call_count_backup;
|
||||
struct function_type *next_function;
|
||||
};
|
||||
|
||||
struct command_type {
|
||||
char word[44];
|
||||
struct command_type *next;
|
||||
};
|
||||
|
||||
#ifdef GLK
|
||||
struct window_type {
|
||||
char name[44];
|
||||
winid_t glk_window;
|
||||
glui32 glk_type;
|
||||
struct window_type *next_window;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct word_type {
|
||||
char word[44];
|
||||
struct word_type *first_child;
|
||||
struct word_type *next_sibling;
|
||||
};
|
||||
|
||||
struct synonym_type {
|
||||
char original[44];
|
||||
char standard[44];
|
||||
struct synonym_type *next_synonym;
|
||||
};
|
||||
|
||||
struct name_type {
|
||||
char name[44];
|
||||
struct name_type *next_name;
|
||||
};
|
||||
|
||||
struct filter_type {
|
||||
char word[44];
|
||||
struct filter_type *next_filter;
|
||||
};
|
||||
|
||||
#ifndef GLK
|
||||
struct parameter_type {
|
||||
char name[44];
|
||||
char container[44];
|
||||
int low;
|
||||
int high;
|
||||
struct parameter_type *next_parameter;
|
||||
};
|
||||
#endif
|
||||
|
||||
class File : public Common::File {
|
||||
public:
|
||||
static File *openForReading(const Common::String &name) {
|
||||
File *f = new File();
|
||||
if (f->open(Common::Path(name)))
|
||||
return f;
|
||||
|
||||
delete f;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Common::WriteStream *openForWriting(const Common::String &name) {
|
||||
Common::DumpFile *df = new Common::DumpFile();
|
||||
if (df->open(Common::Path(name)))
|
||||
return df;
|
||||
|
||||
delete df;
|
||||
return nullptr;
|
||||
}
|
||||
public:
|
||||
File() : Common::File() {}
|
||||
File(const Common::Path &name) {
|
||||
Common::File::open(name);
|
||||
assert(isOpen());
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
248
engines/glk/jacl/utils.cpp
Normal file
248
engines/glk/jacl/utils.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/* 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 "glk/jacl/jacl.h"
|
||||
#include "glk/jacl/language.h"
|
||||
#include "glk/jacl/types.h"
|
||||
#include "glk/jacl/prototypes.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace JACL {
|
||||
|
||||
extern char function_name[];
|
||||
|
||||
extern struct object_type *object[];
|
||||
extern struct variable_type *variable[];
|
||||
|
||||
extern int objects;
|
||||
extern int player;
|
||||
|
||||
extern char game_file[];
|
||||
extern char game_path[];
|
||||
extern char prefix[];
|
||||
extern char blorb[];
|
||||
extern char bookmark[];
|
||||
extern char walkthru[];
|
||||
extern char include_directory[];
|
||||
extern char temp_directory[];
|
||||
extern char data_directory[];
|
||||
extern char temp_buffer[];
|
||||
|
||||
void eachturn() {
|
||||
/* INCREMENT THE TOTAL NUMBER OF MOVES MADE AND CALL THE 'EACHTURN'
|
||||
* FUNCTION FOR THE CURRENT LOCATION AND THE GLOBAL 'EACHTURN'
|
||||
* FUNCTION. THESE FUNCTIONS CONTAIN ANY CODE THAT SIMULATED EVENTS
|
||||
* OCCURRING DUE TO THE PASSING OF TIME */
|
||||
TOTAL_MOVES->value++;
|
||||
execute("+eachturn");
|
||||
Common::strcpy_s(function_name, 81, "eachturn_");
|
||||
Common::strcat_s(function_name, 81, object[HERE]->label);
|
||||
execute(function_name);
|
||||
execute("+system_eachturn");
|
||||
|
||||
/* SET TIME TO FALSE SO THAT NO MORE eachturn FUNCTIONS ARE EXECUTED
|
||||
* UNTIL EITHER THE COMMAND PROMPT IS RETURNED TO (AND TIME IS SET
|
||||
* TO TRUE AGAIN, OR IT IS MANUALLY SET TO TRUE BY A VERB THAT CALLS
|
||||
* MORE THAN ONE proxy COMMAND. THIS IS BECAUSE OTHERWISE A VERB THAT
|
||||
* USES A proxy COMMAND TO TRANSLATE THE VERB IS RESULT IN TWO MOVES
|
||||
* (OR MORE) HAVING PASSED FOR THE ONE ACTION. */
|
||||
TIME->value = FALSE;
|
||||
}
|
||||
|
||||
int get_here() {
|
||||
/* THIS FUNCTION RETURNS THE VALUE OF 'here' IN A SAFE, ERROR CHECKED
|
||||
* WAY */
|
||||
if (player < 1 || player > objects) {
|
||||
badplrrun(player);
|
||||
terminate(44);
|
||||
return 0;
|
||||
} else if (object[player]->PARENT < 1 || object[player]->PARENT > objects || object[player]->PARENT == player) {
|
||||
badparrun();
|
||||
terminate(44);
|
||||
return 0;
|
||||
} else {
|
||||
return (object[player]->PARENT);
|
||||
}
|
||||
}
|
||||
|
||||
char *strip_return(char *string) {
|
||||
/* STRIP ANY TRAILING RETURN OR NEWLINE OFF THE END OF A STRING */
|
||||
int index;
|
||||
int length = strlen(string);
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
switch (string[index]) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
string[index] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
int random_number() {
|
||||
return g_vm->getRandomNumber(0x7fffffff);
|
||||
}
|
||||
|
||||
#ifndef GLK
|
||||
void create_paths(char *full_path) {
|
||||
int index;
|
||||
char *last_slash;
|
||||
|
||||
/* SAVE A COPY OF THE SUPPLIED GAMEFILE NAME */
|
||||
strcpy(game_file, full_path);
|
||||
|
||||
/* FIND THE LAST SLASH IN THE SPECIFIED GAME PATH AND REMOVE THE GAME
|
||||
* FILE SUFFIX IF ANY EXISTS */
|
||||
last_slash = (char *)nullptr;
|
||||
|
||||
/* GET A POINTER TO THE LAST SLASH IN THE FULL PATH */
|
||||
last_slash = strrchr(full_path, DIR_SEPARATOR);
|
||||
|
||||
for (index = strlen(full_path); index >= 0; index--) {
|
||||
if (full_path[index] == DIR_SEPARATOR) {
|
||||
/* NO '.' WAS FOUND BEFORE THE LAST SLASH WAS REACHED,
|
||||
* THERE IS NO FILE EXTENSION */
|
||||
break;
|
||||
} else if (full_path[index] == '.') {
|
||||
full_path[index] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* STORE THE GAME PATH AND THE GAME FILENAME PARTS SEPARATELY */
|
||||
if (last_slash == (const char *) nullptr) {
|
||||
/* GAME MUST BE IN CURRENT DIRECTORY SO THERE WILL BE NO GAME PATH */
|
||||
strcpy(prefix, full_path);
|
||||
game_path[0] = 0;
|
||||
|
||||
/* THIS ADDITION OF ./ TO THE FRONT OF THE GAMEFILE IF IT IS IN THE
|
||||
* CURRENT DIRECTORY IS REQUIRED TO KEEP Gargoyle HAPPY. */
|
||||
#ifdef __NDS__
|
||||
Common::sprintf_s(temp_buffer, "%c%s", DIR_SEPARATOR, game_file);
|
||||
#else
|
||||
Common::sprintf_s(temp_buffer, ".%c%s", DIR_SEPARATOR, game_file);
|
||||
#endif
|
||||
strcpy(game_file, temp_buffer);
|
||||
} else {
|
||||
/* STORE THE DIRECTORY THE GAME FILE IS IN WITH THE TRAILING
|
||||
* SLASH IF THERE IS ONE */
|
||||
last_slash++;
|
||||
strcpy(prefix, last_slash);
|
||||
*last_slash = '\0';
|
||||
strcpy(game_path, full_path);
|
||||
}
|
||||
|
||||
#ifdef GLK
|
||||
/* SET DEFAULT WALKTHRU FILE NAME */
|
||||
Common::sprintf_s(walkthru, "%s.walkthru", prefix);
|
||||
|
||||
/* SET DEFAULT SAVED GAME FILE NAME */
|
||||
Common::sprintf_s(bookmark, "%s.bookmark", prefix);
|
||||
|
||||
/* SET DEFAULT BLORB FILE NAME */
|
||||
Common::sprintf_s(blorb, "%s.blorb", prefix);
|
||||
#endif
|
||||
|
||||
/* SET DEFAULT FILE LOCATIONS IF NOT SET BY THE USER IN CONFIG */
|
||||
if (include_directory[0] == 0) {
|
||||
strcpy(include_directory, game_path);
|
||||
strcat(include_directory, INCLUDE_DIR);
|
||||
}
|
||||
|
||||
if (temp_directory[0] == 0) {
|
||||
strcpy(temp_directory, game_path);
|
||||
strcat(temp_directory, TEMP_DIR);
|
||||
}
|
||||
|
||||
if (data_directory[0] == 0) {
|
||||
strcpy(data_directory, game_path);
|
||||
strcat(data_directory, DATA_DIR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int jacl_whitespace(char character) {
|
||||
/* CHECK IF A CHARACTER IS CONSIDERED WHITE SPACE IN THE JACL LANGUAGE */
|
||||
switch (character) {
|
||||
case ':':
|
||||
case '\t':
|
||||
case ' ':
|
||||
return (TRUE);
|
||||
default:
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
char *stripwhite(char *string) {
|
||||
int i;
|
||||
|
||||
/* STRIP WHITESPACE FROM THE START AND END OF STRING. */
|
||||
while (jacl_whitespace(*string)) string++;
|
||||
|
||||
i = strlen(string) - 1;
|
||||
|
||||
while (i >= 0 && ((jacl_whitespace(*(string + i))) || *(string + i) == '\n' || *(string + i) == '\r')) i--;
|
||||
|
||||
#ifdef WIN32
|
||||
i++;
|
||||
*(string + i) = '\r';
|
||||
#endif
|
||||
i++;
|
||||
*(string + i) = '\n';
|
||||
i++;
|
||||
*(string + i) = '\0';
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
void jacl_encrypt(char *string) {
|
||||
int index, length;
|
||||
|
||||
length = strlen(string);
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
if (string[index] == '\n' || string[index] == '\r') {
|
||||
return;
|
||||
}
|
||||
string[index] = string[index] ^ 255;
|
||||
}
|
||||
}
|
||||
|
||||
void jacl_decrypt(char *string) {
|
||||
int index, length;
|
||||
|
||||
length = strlen(string);
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
if (string[index] == '\n' || string[index] == '\r') {
|
||||
return;
|
||||
}
|
||||
string[index] = string[index] ^ 255;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace JACL
|
||||
} // End of namespace Glk
|
||||
25
engines/glk/jacl/version.h
Normal file
25
engines/glk/jacl/version.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define J_VERSION 2
|
||||
#define J_RELEASE 9
|
||||
#define J_BUILD 0
|
||||
#define INTERPRETER_VERSION 209
|
||||
Reference in New Issue
Block a user