1620 lines
47 KiB
C++
1620 lines
47 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
|
|
|
|
#include "watchmaker/define.h"
|
|
#include "watchmaker/extraLS.h"
|
|
#include "watchmaker/game.h"
|
|
#include "watchmaker/globvar.h"
|
|
#include "watchmaker/init/nl_parse.h"
|
|
#include "watchmaker/ll/ll_system.h"
|
|
#include "watchmaker/types.h"
|
|
|
|
namespace Watchmaker {
|
|
|
|
char *TextBucket, cr = 0; //da rimpiazzare con la areatext allocata da fab
|
|
static char *CurText;
|
|
int SentenceNum = 1, SysSentNum = 1, TooltipSentNum = 1, ObjNameNum = 1, ExtraLSNum = 1;
|
|
int DlgItemNum = 1;
|
|
|
|
uint16 Credits_numRoles = 0;
|
|
uint16 Credits_numNames = 0;
|
|
|
|
#define DEFAULT_DEFINE_INPUT "src/define.h"
|
|
|
|
#define MAXFLAGS 360
|
|
#define MAXTOKENLEN 30
|
|
|
|
#define ANIM_MARKER 'a'
|
|
#define CREDIT_MARKER 'c'
|
|
#define DLG_MARKER 'd'
|
|
#define DIARY_MARKER 'e'
|
|
#define ATFDO_MARKER 'f'
|
|
#define ACT_MARKER 'h'
|
|
#define INV_MARKER 'i'
|
|
#define PDALOG_MARKER 'l'
|
|
#define MENU_MARKER 'm'
|
|
#define MUSIC_MARKER 'n'
|
|
#define OBJ_MARKER 'o'
|
|
#define ROOM_MARKER 'r'
|
|
#define DESC_MARKER 's'
|
|
#define ENV_MARKER 'v'
|
|
#define SOUND_MARKER 'w'
|
|
|
|
#define TOKEN_NOT_FOUND 0xffff
|
|
|
|
typedef struct {
|
|
char token[MAXTOKENLEN];
|
|
unsigned int value;
|
|
} TOKEN; // 32 bytes
|
|
|
|
int SaveTextTable(const char *name);
|
|
|
|
#define AddSound2Room(inx,val) \
|
|
{ \
|
|
\
|
|
unsigned short j=0,err=0,*tab=_init.Room[inx].sounds.rawArray(); \
|
|
while(*tab!=0) \
|
|
{ \
|
|
\
|
|
tab++; \
|
|
if(j++>=MAX_SOUNDS_IN_ROOM) \
|
|
err=1; \
|
|
} \
|
|
if(err) \
|
|
_parser->ParseError("Too many Sounds in room %s max is %d",_init.Room[inx].name,MAX_SOUNDS_IN_ROOM); \
|
|
else \
|
|
*tab=val; \
|
|
}
|
|
|
|
#define AddAnim2Room(room,inx) \
|
|
{ \
|
|
\
|
|
room->anims[animcnt++]=inx; \
|
|
if(animcnt>=MAX_ANIMS_IN_ROOM) \
|
|
return _parser->ParseError("Too many Anims in room %s max is %d",s,MAX_ANIMS_IN_ROOM); \
|
|
}
|
|
|
|
#define AddAct2Room(room,inx) \
|
|
{ \
|
|
\
|
|
room->actions[actcnt++]=inx; \
|
|
if(actcnt>=MAX_ACTIONS_IN_ROOM) \
|
|
return _parser->ParseError("Too many Acts in room %s max is %d",s,MAX_ACTIONS_IN_ROOM); \
|
|
}
|
|
|
|
#define AddObject2Room(room,inx) \
|
|
{ \
|
|
\
|
|
room->objects[objcnt++]=inx; \
|
|
if(objcnt>=MAX_OBJS_IN_ROOM) \
|
|
return _parser->ParseError("Too many Objects in room %s max is %d",s,MAX_OBJS_IN_ROOM); \
|
|
}
|
|
|
|
TOKEN *FlagToken = NULL;
|
|
TOKEN *RoomToken = NULL;
|
|
TOKEN *ObjToken = NULL;
|
|
TOKEN *AnimToken = NULL;
|
|
TOKEN *InvToken = NULL;
|
|
TOKEN *WaveToken = NULL;
|
|
TOKEN *DoToken = NULL;
|
|
TOKEN *DlgToken = NULL;
|
|
TOKEN *ActToken = NULL;
|
|
TOKEN *MenuToken = NULL;
|
|
TOKEN *DiaryToken = NULL;
|
|
TOKEN *EnvToken = NULL;
|
|
TOKEN *PDALogToken = NULL;
|
|
TOKEN *MusicToken = NULL;
|
|
|
|
const char *ShortName[] = {
|
|
"???",
|
|
"DAR",
|
|
"VIC",
|
|
"CUO",
|
|
"DOM",
|
|
"GIA",
|
|
"CUS",
|
|
"SER",
|
|
"SUP",
|
|
"MOG",
|
|
"MOG",
|
|
"CAC",
|
|
"VEC",
|
|
"CHI",
|
|
"TRA",
|
|
"ORO",
|
|
"KRE",
|
|
"DUK",
|
|
"COR",
|
|
"VAL",
|
|
"NOT",
|
|
"MOO",
|
|
"DAR",
|
|
"CAC",
|
|
"MOO",
|
|
"BOT",
|
|
"***"
|
|
};
|
|
char csn = 0;
|
|
|
|
|
|
/* -----------------16/03/98 18.14-------------------
|
|
* FreeDefineTable
|
|
* --------------------------------------------------*/
|
|
void FreeDefineTable(void) {
|
|
free(FlagToken);
|
|
free(RoomToken);
|
|
free(ObjToken);
|
|
free(AnimToken);
|
|
free(InvToken);
|
|
free(WaveToken);
|
|
free(DoToken);
|
|
free(ActToken);
|
|
free(MenuToken);
|
|
free(DlgToken);
|
|
free(DiaryToken);
|
|
free(EnvToken);
|
|
free(PDALogToken);
|
|
free(MusicToken);
|
|
|
|
FlagToken = RoomToken = DiaryToken = ObjToken = ActToken = MenuToken = PDALogToken = MusicToken = NULL;
|
|
AnimToken = InvToken = WaveToken = DoToken = DlgToken = EnvToken = NULL;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.14-------------------
|
|
* BuildDefineTable
|
|
* --------------------------------------------------*/
|
|
int BuildDefineTable(const char *name) {
|
|
auto parser = NLParser::open(DEFAULT_DEFINE_INPUT);
|
|
if (!parser) {
|
|
parser = NLParser::open(name);
|
|
if (!parser) {
|
|
error("Error Opening File NL %s", name);
|
|
}
|
|
}
|
|
parser->IfParseErrorDo(FreeDefineTable);
|
|
|
|
char str[MAXTOKENLEN];
|
|
int res, done = FALSE;
|
|
TOKEN *token = NULL;
|
|
int cur_dlg, cur_flag, cur_room, cur_obj, cur_anim, cur_inv, cur_wave, cur_do, cur_act, cur_menu, cur_diary, cur_env, cur_pdalog, cur_music;
|
|
|
|
CurText = TextBucket = t3dCalloc<char>(TEXT_BUCKET_SIZE);
|
|
if (TextBucket == nullptr)
|
|
return parser->ParseError("Error Allocating TextBucket");
|
|
|
|
FlagToken = t3dCalloc<TOKEN>(MAXFLAGS);
|
|
RoomToken = t3dCalloc<TOKEN>(MAX_ROOMS);
|
|
ObjToken = t3dCalloc<TOKEN>(MAX_OBJS);
|
|
AnimToken = t3dCalloc<TOKEN>(MAX_ANIMS);
|
|
InvToken = t3dCalloc<TOKEN>(MAX_ICONS);
|
|
WaveToken = t3dCalloc<TOKEN>(MAX_SOUNDS);
|
|
DoToken = t3dCalloc<TOKEN>(MAX_ATF_DO);
|
|
ActToken = t3dCalloc<TOKEN>(MAX_ACTIONS);
|
|
MenuToken = t3dCalloc<TOKEN>(MAX_DLG_MENUS);
|
|
DiaryToken = t3dCalloc<TOKEN>(MAX_DIARIES);
|
|
DlgToken = t3dCalloc<TOKEN>(MAX_DIALOGS);
|
|
EnvToken = t3dCalloc<TOKEN>(MAX_ENVIRONMENTS);
|
|
PDALogToken = t3dCalloc<TOKEN>(MAX_PDALOGS);
|
|
MusicToken = t3dCalloc<TOKEN>(MAX_MUSICS);
|
|
|
|
if (!DlgToken || !MenuToken || !ActToken || !RoomToken || !ObjToken || !AnimToken || !InvToken || !DiaryToken || !WaveToken || !DoToken || !EnvToken || !PDALogToken || !MusicToken)
|
|
return parser->ParseError("Error Allocating Define Tables");
|
|
|
|
cur_dlg = cur_act = cur_menu = cur_flag = cur_room = cur_obj = cur_anim = cur_inv = cur_wave = cur_do = cur_diary = cur_env = cur_pdalog = cur_music = 0;
|
|
|
|
while (!done) {
|
|
res = parser->ReadArgument(str);
|
|
warning("Cur res: %d Cur str: '%s'", res, str);
|
|
if (res == EOF_PARSED)break;
|
|
if (scumm_stricmp("#define", str))
|
|
return parser->ParseError("Match %s instead of %s", str, "#define");
|
|
|
|
if (parser->ReadArgument(str) < 0)
|
|
return parser->ParseError("Error reading a string in file %s at line %d", name, parser->getCurLine());
|
|
warning("Argument: '%s'", str);
|
|
switch (str[0]) {
|
|
case ROOM_MARKER:
|
|
token = &RoomToken[cur_room++];
|
|
if (cur_room >= MAX_ROOMS)return parser->ParseError("Too many Rooms defined (MAX is %d)", MAX_ROOMS);
|
|
break;
|
|
case OBJ_MARKER:
|
|
token = &ObjToken[cur_obj++];
|
|
if (cur_obj >= MAX_OBJS)return parser->ParseError("Too many Objects defined (MAX is %d)", MAX_OBJS);
|
|
break;
|
|
case INV_MARKER:
|
|
token = &InvToken[cur_inv++];
|
|
if (cur_inv >= MAX_ICONS)return parser->ParseError("Too many Icons defined (MAX is %d)", MAX_ICONS);
|
|
break;
|
|
case ANIM_MARKER:
|
|
token = &AnimToken[cur_anim++];
|
|
if (cur_anim >= MAX_ANIMS)return parser->ParseError("Too many Anims defined (MAX is %d)", MAX_ANIMS);
|
|
break;
|
|
case SOUND_MARKER:
|
|
token = &WaveToken[cur_wave++];
|
|
if (cur_wave >= MAX_SOUNDS)return parser->ParseError("Too many Samples defined (MAX is %d)", MAX_SOUNDS);
|
|
break;
|
|
case ATFDO_MARKER:
|
|
token = &DoToken[cur_do++];
|
|
if (cur_do >= MAX_ATF_DO)return parser->ParseError("Too many AtfDo defined (MAX is %d)", MAX_ATF_DO);
|
|
break;
|
|
case ACT_MARKER:
|
|
token = &ActToken[cur_act++];
|
|
if (cur_act >= MAX_ACTIONS)return parser->ParseError("Too many Action defined (MAX is %d)", MAX_ACTIONS);
|
|
break;
|
|
case MENU_MARKER:
|
|
token = &MenuToken[cur_menu++];
|
|
if (cur_menu >= MAX_DLG_MENUS)return parser->ParseError("Too many Menus defined (MAX is %d)", MAX_DLG_MENUS);
|
|
break;
|
|
case DIARY_MARKER:
|
|
token = &DiaryToken[cur_diary++];
|
|
if (cur_diary >= MAX_DIARIES)return parser->ParseError("Too many Diaries defined (MAX is %d)", MAX_DIARIES);
|
|
break;
|
|
case DLG_MARKER:
|
|
token = &DlgToken[cur_dlg++];
|
|
if (cur_dlg >= MAX_DIALOGS)return parser->ParseError("Too many Dialogs defined (MAX is %d) ", MAX_DIALOGS);
|
|
break;
|
|
case ENV_MARKER:
|
|
token = &EnvToken[cur_env++];
|
|
if (cur_env >= MAX_ENVIRONMENTS)return parser->ParseError("Too many Environments defined (MAX is %d) ", MAX_ENVIRONMENTS);
|
|
break;
|
|
case PDALOG_MARKER:
|
|
token = &PDALogToken[cur_pdalog++];
|
|
if (cur_pdalog >= MAX_PDALOGS)return parser->ParseError("Too many PDALogs defined (MAX is %d) ", MAX_PDALOGS);
|
|
break;
|
|
case MUSIC_MARKER:
|
|
token = &MusicToken[cur_music++];
|
|
if (cur_music >= MAX_MUSICS)return parser->ParseError("Too many Musics defined (MAX is %d) ", MAX_MUSICS);
|
|
break;
|
|
|
|
default:
|
|
if (cur_flag >= MAXFLAGS) { //ne legge solo un po'
|
|
parser->ReadNumber();
|
|
token = NULL;
|
|
break;
|
|
}
|
|
token = &FlagToken[cur_flag++];
|
|
break;
|
|
}
|
|
if (token) {
|
|
strcpy(token->token, str);
|
|
token->value = parser->ReadNumber();
|
|
}
|
|
}
|
|
parser.reset();
|
|
return 1;
|
|
}
|
|
|
|
/*PELS: end DEFINE ***********************************/
|
|
|
|
#undef Match
|
|
#define Match(t) {if((_parser->ReadArgument(str)<0) || scumm_stricmp(str,t))return _parser->ParseError("Syntax Error! can't match '%s' but found '%s'",t,str);}
|
|
|
|
static const char *InitFile[] = {
|
|
"Init.nl",
|
|
"InitLev1.nl",
|
|
"InitLev2.nl",
|
|
"InitLev3.nl",
|
|
"InitLev4.nl",
|
|
"InitAnim.nl",
|
|
"InitAnim1.nl",
|
|
"InitAnim2.nl",
|
|
"InitAnim3.nl",
|
|
"InitAnim4.nl",
|
|
"InitAnimRtv.nl",
|
|
"InitBkg.nl",
|
|
"InitText.nl",
|
|
"InitIcon.nl",
|
|
"InitDlg.nl",
|
|
"InitRtv1.nl",
|
|
"InitRtv2.nl",
|
|
"InitRtv3.nl",
|
|
"InitRtv4.nl",
|
|
"InitSound.nl",
|
|
"InitT2D.nl",
|
|
"InitDiary.nl",
|
|
"Credits.nl",
|
|
NULL
|
|
};
|
|
|
|
class StructureInitializer {
|
|
Common::SharedPtr<NLParser> _parser;
|
|
Common::String _filename;
|
|
Init &_init;
|
|
public:
|
|
StructureInitializer(Common::SharedPtr<NLParser> &parser, const Common::String &filename, Init &init) : _parser(parser), _filename(filename), _init(init) {
|
|
}
|
|
static Common::SharedPtr<StructureInitializer> open(Common::String &path, Init &init) {
|
|
// TODO: Hook up the table-freeing
|
|
auto parser = NLParser::open(path);
|
|
if (!parser) {
|
|
return nullptr;
|
|
}
|
|
warning("Casting away constness");
|
|
if (parser->SearchArgument((char *)path.c_str(), "NL.", NULL) < 0)
|
|
parser->ParseError("%s is not a NL file", path.c_str());
|
|
return Common::SharedPtr<StructureInitializer>(new StructureInitializer(parser, path, init));
|
|
}
|
|
|
|
int parseLoop() {
|
|
int res = 1;
|
|
while (true) {
|
|
char str[J_MAXSTRLEN];
|
|
if (_parser->ReadArgument(str) < 0) {
|
|
if (!scumm_stricmp(str, "end."))break;
|
|
else if ((toupper(str[0]) == 'E') && (toupper(str[1]) == 'N') &&
|
|
(toupper(str[2]) == 'D') && (toupper(str[3]) == '.'))
|
|
break;
|
|
else
|
|
return _parser->ParseError("Error Reading File %s -%s-", _filename.c_str(), str);
|
|
}
|
|
if (!scumm_stricmp(str, "end."))break;
|
|
if ((toupper(str[0]) == 'E') && (toupper(str[1]) == 'N') &&
|
|
(toupper(str[2]) == 'D') && (toupper(str[3]) == '.'))
|
|
break;
|
|
|
|
res = 0;
|
|
switch (str[0]) {
|
|
case OBJ_MARKER:
|
|
res = ParseObject(str);
|
|
break;
|
|
case ROOM_MARKER:
|
|
res = ParseRoom(str);
|
|
break;
|
|
case ANIM_MARKER:
|
|
res = ParseAnim(str);
|
|
break;
|
|
case INV_MARKER:
|
|
res = ParseInv(str);
|
|
break;
|
|
case SOUND_MARKER:
|
|
res = ParseSound(str);
|
|
break;
|
|
case DLG_MARKER:
|
|
res = ParseDialog(str);
|
|
break;
|
|
case DIARY_MARKER:
|
|
res = ParseDiary(str);
|
|
break;
|
|
case MENU_MARKER:
|
|
res = ParseMenu(str);
|
|
break;
|
|
case PDALOG_MARKER:
|
|
res = ParsePDALog(str);
|
|
break;
|
|
case MUSIC_MARKER:
|
|
res = ParseMusic(str);
|
|
break;
|
|
case CREDIT_MARKER:
|
|
res = ParseCredits(str);
|
|
break;
|
|
}
|
|
if (!res)
|
|
error("Some parse error occurred");
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.13-------------------
|
|
* GetTokenValue
|
|
* --------------------------------------------------*/
|
|
unsigned int GetTokenValue(TOKEN *where, char *what) {
|
|
if (!scumm_stricmp("none", what))return 0;
|
|
while (where->token[0] != 0) {
|
|
if (!strcmp(where->token, what))
|
|
return where->value;
|
|
where++;
|
|
}
|
|
_parser->ParseError("Can't find token %s", what);
|
|
return TOKEN_NOT_FOUND;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.13-------------------
|
|
* GetTokenValueDefault
|
|
* --------------------------------------------------*/
|
|
unsigned short GetTokenValueDefault(TOKEN *where, char *what) {
|
|
if (!scumm_stricmp("none", what))return 0;
|
|
while (where->token[0] != 0) {
|
|
if (!strcmp(where->token, what))
|
|
return where->value;
|
|
where++;
|
|
}
|
|
return TOKEN_NOT_FOUND;
|
|
}
|
|
|
|
/* -----------------16/03/98 17.48-------------------
|
|
* ReadSentence
|
|
* --------------------------------------------------*/
|
|
int ReadSentence(void) {
|
|
int a;
|
|
if ((a = _parser->ReadArgument(CurText)) < 0)
|
|
_parser->ParseError("Error Reading a string in ReadSentence");
|
|
Sentence[SentenceNum++] = CurText;
|
|
switch (SentenceNum - 1) {
|
|
case 2:
|
|
case 3:
|
|
case 6:
|
|
case 8:
|
|
case 10:
|
|
case 12:
|
|
case 13:
|
|
case 15:
|
|
csn = ocVECCHIO;
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
case 7:
|
|
case 9:
|
|
case 11:
|
|
csn = ocCHIRURGO;
|
|
break;
|
|
case 14:
|
|
csn = ocTRADUTTORE;
|
|
break;
|
|
case 1:
|
|
csn = ocOROLOGIAIO;
|
|
break;
|
|
}
|
|
debug("%s s%04d %s\n", ShortName[(uint)csn], SentenceNum - 1, CurText);
|
|
CurText += a;
|
|
return (SentenceNum - 1);
|
|
}
|
|
|
|
/* -----------------16/03/98 17.48-------------------
|
|
* ReadSysSent
|
|
* --------------------------------------------------*/
|
|
int ReadSysSent(void) {
|
|
int a;
|
|
if ((a = _parser->ReadArgument(CurText)) < 0)
|
|
_parser->ParseError("Error Reading a string in ReadSysSent");
|
|
SysSent[SysSentNum++] = CurText;
|
|
csn = ocNOTRANS;
|
|
debug("%s y%04d %s\n", ShortName[(uint)csn], SysSentNum - 1, CurText);
|
|
CurText += a;
|
|
return (SysSentNum - 1);
|
|
}
|
|
|
|
/* -----------------19/01/99 10.34-------------------
|
|
* ReadTooltipSent
|
|
* --------------------------------------------------*/
|
|
int ReadTooltipSent(void) {
|
|
int a;
|
|
if ((a = _parser->ReadArgument(CurText)) < 0)
|
|
_parser->ParseError("Error Reading a string in ReadTooltipSent");
|
|
TooltipSent[TooltipSentNum++] = CurText;
|
|
csn = ocNOTRANS;
|
|
debug("%s t%04d %s\n", ShortName[(uint)csn], TooltipSentNum - 1, CurText);
|
|
CurText += a;
|
|
return (TooltipSentNum - 1);
|
|
}
|
|
|
|
|
|
/* -----------------21/03/01 09.40-------------------
|
|
* ReadExtraLS
|
|
* --------------------------------------------------*/
|
|
int ReadExtraLS(void) {
|
|
int a;
|
|
if ((a = _parser->ReadArgument(CurText)) < 0)
|
|
_parser->ParseError("Error Reading a string in ReadExtraLS");
|
|
ExtraLS[ExtraLSNum++] = CurText;
|
|
csn = ocNOTRANS;
|
|
debug("%s e%04d %s\n", ShortName[(uint)csn], ExtraLSNum - 1, CurText);
|
|
CurText += a;
|
|
return (ExtraLSNum - 1);
|
|
}
|
|
|
|
/* -----------------16/03/98 17.47-------------------
|
|
* ReadObjName
|
|
* --------------------------------------------------*/
|
|
int ReadObjName(void) {
|
|
int a;
|
|
if ((a = _parser->ReadArgument(CurText)) < 0)
|
|
_parser->ParseError("Error Reading a string in ReadObjName");
|
|
ObjName[ObjNameNum++] = CurText;
|
|
csn = ocNOTRANS;
|
|
debug("%s n%04d %s\n", ShortName[(uint)csn], ObjNameNum - 1, CurText);
|
|
CurText += a;
|
|
return (ObjNameNum - 1);
|
|
}
|
|
|
|
/* -----------------16/03/98 17.47-------------------
|
|
* ReadIndex
|
|
* --------------------------------------------------*/
|
|
int ReadIndex() {
|
|
char str[J_MAXSTRLEN];
|
|
int inx;
|
|
if (_parser->ReadArgument(str) <= 0)
|
|
_parser->ParseError("Error Reading a string in ReadIndex");
|
|
if ((inx = GetTokenValueDefault(WaveToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(ObjToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(DoToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(RoomToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(AnimToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(InvToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(MenuToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(DiaryToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(DlgToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(FlagToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(EnvToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(PDALogToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
if ((inx = GetTokenValueDefault(MusicToken, str)) != TOKEN_NOT_FOUND)
|
|
return inx;
|
|
|
|
return atoi(str);
|
|
}
|
|
|
|
/* -----------------16/03/98 17.47-------------------
|
|
* ReadFlags
|
|
* --------------------------------------------------*/
|
|
int ReadFlags() {
|
|
int val = 0;
|
|
char str[J_MAXSTRLEN];
|
|
while (_parser->ReadArgumentEOL(str) > 0) {
|
|
val |= GetTokenValue(FlagToken, str);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
float ReadFloat(void) {
|
|
char str[J_MAXSTRLEN];
|
|
if (_parser->ReadArgument(str) < 0)
|
|
return 0;
|
|
return (float)atof(str);
|
|
}
|
|
|
|
|
|
/* -----------------16/03/98 17.47-------------------
|
|
* AssignSound
|
|
* --------------------------------------------------*/
|
|
void AssignSound(int val) {
|
|
int inx;
|
|
char str[J_MAXSTRLEN];
|
|
while (_parser->ReadArgumentEOL(str) > 0) {
|
|
if ((inx = GetTokenValue(RoomToken, str)) != TOKEN_NOT_FOUND)
|
|
AddSound2Room(inx, val);
|
|
}
|
|
}
|
|
|
|
|
|
int ParseInv(char *s);
|
|
int ParseRoom(char *s);
|
|
int ParseAnim(char *s);
|
|
int ParseObject(char *s);
|
|
int ParseSound(char *s);
|
|
int ParseItem(int d);
|
|
int ParseDialog(char *s);
|
|
int ParseDiary(char *s);
|
|
int ParseMenu(char *s);
|
|
int ParsePDALog(char *s);
|
|
int ParseMusic(char *s);
|
|
int ParseCredits(char *s);
|
|
};
|
|
|
|
int InitStructures(WGame &game) {
|
|
const char **filelist = InitFile;
|
|
|
|
if (!BuildDefineTable(game.workDirs._define.c_str()))
|
|
return 0;
|
|
|
|
SaveTextTable("SentUK.txt");
|
|
|
|
for (; *filelist != NULL; filelist++) {
|
|
Common::String path = game.workDirs._initDir + *filelist;
|
|
auto initializer = StructureInitializer::open(path, game.init);
|
|
if (!initializer)
|
|
error("Error Opening File NL %s", path.c_str());
|
|
|
|
initializer->parseLoop();
|
|
|
|
initializer.reset();
|
|
}
|
|
|
|
FreeDefineTable();
|
|
if ((CurText - TextBucket) > TEXT_BUCKET_SIZE)
|
|
error("TextBucket OverFlow in %s by %ld", *filelist, (CurText - TextBucket));
|
|
|
|
{
|
|
debug("\n// ROOMS DESCRIPTIONS\n");
|
|
for (int i = 0; i < MAX_ROOMS; i++)
|
|
debug("*** d%04d %s\n", i, game.init.Room[i].desc);
|
|
}
|
|
|
|
// tapullo perchè mancava il nome della porta in inittext
|
|
game.init.Obj[o2MBp2ME].name = game.init.Obj[o2MFp2MB].name;
|
|
game.init.Obj[0] = SObject();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/* -----------------24/08/00 9.31--------------------
|
|
* LoadExternalText
|
|
* --------------------------------------------------*/
|
|
int LoadExternalText(Init *init, char *et) {
|
|
char line[1000];
|
|
int len, num;
|
|
|
|
if (!et) return false;
|
|
if (et[0] == '\0') return true;
|
|
|
|
auto stream = openFile(et);
|
|
if (!stream)
|
|
return false;
|
|
|
|
CurText = TextBucket;
|
|
memset(TextBucket, 0, TEXT_BUCKET_SIZE);
|
|
SentenceNum = SysSentNum = TooltipSentNum = ObjNameNum = ExtraLSNum = 1;
|
|
|
|
while (stream->readLine(line, 1000) != nullptr) {
|
|
if ((line[0] == '/') && (line[1] == '/')) continue;
|
|
|
|
if ((len = strlen(line)) > 260)
|
|
error("ExternalText: line too long! curlen %d (MAX 250)\n%s", len - 10, line);
|
|
|
|
if (len < 2) continue;
|
|
|
|
if (sscanf(&line[5], "%d", &num) < 1)
|
|
error("ExternalText: sentence number not found in line:\n%s", line);
|
|
|
|
switch (line[4]) {
|
|
case 's':
|
|
Sentence[num] = CurText;
|
|
SentenceNum ++;
|
|
break;
|
|
case 'y':
|
|
SysSent[num] = CurText;
|
|
SysSentNum ++;
|
|
break;
|
|
case 't':
|
|
TooltipSent[num] = CurText;
|
|
TooltipSentNum ++;
|
|
break;
|
|
case 'e':
|
|
ExtraLS[num] = CurText;
|
|
ExtraLSNum ++;
|
|
break;
|
|
case 'n':
|
|
ObjName[num] = CurText;
|
|
ObjNameNum ++;
|
|
break;
|
|
case 'd':
|
|
break;
|
|
default:
|
|
error("ExternalText: unknown paramenters in line:\n%s", line);
|
|
}
|
|
|
|
if ((len - 10 - 1) > 0) {
|
|
memcpy(CurText, &line[10], len - 10 - 1);
|
|
|
|
switch (line[4]) {
|
|
case 'd':
|
|
strcpy(init->Room[num].desc, CurText);
|
|
break;
|
|
}
|
|
|
|
CurText += (len - 10);
|
|
} else {
|
|
switch (line[4]) {
|
|
case 'd':
|
|
strcpy(init->Room[num].desc, "");
|
|
break;
|
|
}
|
|
|
|
CurText ++;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* -----------------16/03/98 17.46-------------------
|
|
* ParseObject
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseObject(char *s) {
|
|
int inx = GetTokenValue(ObjToken, s);
|
|
int done = FALSE, arg, a, len;
|
|
struct SObject *obj;
|
|
char str[J_MAXSTRLEN];
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Object %s doesn't exist!", s);
|
|
obj = &_init.Obj[inx];
|
|
obj->room = cr;
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}",
|
|
"name:", "examine:", "examined:", "examinev:", "action:", "actiond:", "actionv:",
|
|
"anim:", "animd:", "animv:", "goroom:", "godlg:", "ninv:", "flags:", "pos:", "meshlink:",
|
|
"text:", "log:", "sys:", "tooltip:", "anim2:", "anim2d:", "anim2v:", "log2:", "extrals:",
|
|
NULL)) < 0)return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
debug("\n// %s\n", s);
|
|
obj->name = ReadObjName();
|
|
break;
|
|
case 2:
|
|
csn = ocBOTH;
|
|
obj->examine[DARRELL] = ReadSentence();
|
|
obj->examine[VICTORIA] = obj->examine[DARRELL];
|
|
break;
|
|
case 3:
|
|
csn = ocDARRELL;
|
|
obj->examine[DARRELL] = ReadSentence();
|
|
break;
|
|
case 4:
|
|
csn = ocVICTORIA;
|
|
obj->examine[VICTORIA] = ReadSentence();
|
|
break;
|
|
case 5:
|
|
csn = ocBOTH;
|
|
obj->action[DARRELL] = ReadSentence();
|
|
obj->action[VICTORIA] = obj->action[DARRELL];
|
|
break;
|
|
case 6:
|
|
csn = ocDARRELL;
|
|
obj->action[DARRELL] = ReadSentence();
|
|
break;
|
|
case 7:
|
|
csn = ocVICTORIA;
|
|
obj->action[VICTORIA] = ReadSentence();
|
|
break;
|
|
case 8:
|
|
_parser->ReadArgument(str);
|
|
obj->anim[DARRELL] = GetTokenValue(AnimToken, str);
|
|
obj->anim[VICTORIA] = obj->anim[DARRELL];
|
|
break;
|
|
case 9:
|
|
_parser->ReadArgument(str);
|
|
obj->anim[DARRELL] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 10:
|
|
_parser->ReadArgument(str);
|
|
obj->anim[VICTORIA] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 11:
|
|
_parser->ReadArgument(str);
|
|
obj->goroom = (uint8)GetTokenValue(RoomToken, str);
|
|
break;
|
|
case 12:
|
|
_parser->ReadArgument(str);
|
|
obj->goroom = (uint8)GetTokenValue(DlgToken, str);
|
|
break;
|
|
case 13:
|
|
_parser->ReadArgument(str);
|
|
obj->ninv = (uint8)GetTokenValue(InvToken, str);
|
|
break;
|
|
case 14:
|
|
obj->flags = ReadFlags();
|
|
break;
|
|
case 15:
|
|
obj->pos = _parser->ReadNumber();
|
|
break;
|
|
case 16:
|
|
for (a = 0; a < MAX_OBJ_MESHLINKS; a++) if (obj->meshLinkIsEmpty(a)) break;
|
|
if (a < MAX_OBJ_MESHLINKS)
|
|
if ((len = _parser->ReadArgument(str)) < 0 || len > MAX_MESHLINK_SIZE)return _parser->ParseError("Error reading meshlink %s in %s", str, s);
|
|
else obj->setMeshLink(a, str);
|
|
else _parser->ParseError("Too many Meshlink in Obj %s %d max is %d", s, a, MAX_OBJ_MESHLINKS);
|
|
break;
|
|
case 17:
|
|
for (a = 0; a < MAX_OBJ_USER_SENTS; a++) if (!obj->text[a]) break;
|
|
csn = ocBOTH;
|
|
if (a < MAX_OBJ_USER_SENTS) obj->text[a] = ReadSentence();
|
|
else _parser->ParseError("Too many UserText in Obj %s %d max is %d", s, a, MAX_OBJ_USER_SENTS);
|
|
break;
|
|
case 18:
|
|
_parser->ReadArgument(str);
|
|
debug("\n// %s\n", str);
|
|
break;
|
|
case 19:
|
|
ReadSysSent();
|
|
break;
|
|
case 20:
|
|
ReadTooltipSent();
|
|
break;
|
|
case 21:
|
|
_parser->ReadArgument(str);
|
|
obj->anim2[DARRELL] = GetTokenValue(AnimToken, str);
|
|
obj->anim2[VICTORIA] = obj->anim2[DARRELL];
|
|
break;
|
|
case 22:
|
|
_parser->ReadArgument(str);
|
|
obj->anim2[DARRELL] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 23:
|
|
_parser->ReadArgument(str);
|
|
obj->anim2[VICTORIA] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 24:
|
|
_parser->ReadArgument(str);
|
|
debug("// %s\n", str);
|
|
break;
|
|
case 25:
|
|
ReadExtraLS();
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------16/03/98 17.50-------------------
|
|
* ParseRoom
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseRoom(char *s) {
|
|
int inx = GetTokenValue(RoomToken, s);
|
|
int a, done = FALSE, res = TRUE, objcnt = 0, animcnt = 0, actcnt = 0;
|
|
char str[J_MAXSTRLEN];
|
|
struct SRoom *room;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Room %s doesn't exist!", s);
|
|
room = &_init.Room[inx];
|
|
|
|
a = _parser->ReadArgument(str);
|
|
if (a < 0 || (size_t)a > sizeof(room->name))return _parser->ParseError("Error reading basename in room %s", s);
|
|
strcpy((char *)room->name, str);
|
|
|
|
cr = inx;
|
|
Match("{");
|
|
while (!done) {
|
|
if (_parser->ReadArgument(str) < 0)
|
|
return _parser->ParseError("Error Reading room %s at line %d", s, _parser->getCurLine());
|
|
if (!scumm_stricmp(str, "}"))break;
|
|
switch (str[0]) {
|
|
case OBJ_MARKER:
|
|
inx = GetTokenValue(ObjToken, str);
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Can't process %s", str);
|
|
AddObject2Room(room, inx);
|
|
res = ParseObject(str);
|
|
break;
|
|
case ANIM_MARKER:
|
|
inx = GetTokenValue(AnimToken, str);
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Can't process %s", str);
|
|
AddAnim2Room(room, inx);
|
|
//res=ParseAnim(str);
|
|
break;
|
|
case ACT_MARKER:
|
|
inx = GetTokenValue(ActToken, str);
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Can't process %s", str);
|
|
AddAct2Room(room, inx);
|
|
break;
|
|
case ENV_MARKER:
|
|
inx = GetTokenValue(EnvToken, str);
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Can't process %s", str);
|
|
room->env = inx;
|
|
break;
|
|
case DESC_MARKER:
|
|
Match("{");
|
|
_parser->ReadArgument(str);
|
|
strncpy(room->desc, str, 62);
|
|
Match("}");
|
|
break;
|
|
default:
|
|
return _parser->ParseError("Can't process word %s", str);
|
|
}
|
|
if (!res)
|
|
return _parser->ParseError("Error Parsing room %s", s);
|
|
}
|
|
cr = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.01-------------------
|
|
* ParseAnim
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseAnim(char *s) {
|
|
int inx = GetTokenValue(AnimToken, s);
|
|
int done = FALSE, arg, a, j, len;
|
|
struct SAnim *anim;
|
|
char str[J_MAXSTRLEN];
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Anim %s doesn't exist!", s);
|
|
anim = &_init.Anim[inx];
|
|
/* a=_parser->ReadArgument(str);
|
|
if(a<0 || a>sizeof(anim->name))return _parser->ParseError("Error reading name in anim %s",s);
|
|
strcpy(anim->name,str);
|
|
*/ a = 0;
|
|
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "flags:", "name:", "objlink:", "meshlink:", "roomname:", "portallink:", "pos:",
|
|
"camera:", "obj:", "atframe:", NULL)) < 0)return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
anim->flags = ReadFlags();
|
|
break;
|
|
case 2:
|
|
for (a = 0; a < MAX_SUBANIMS; a++) if (anim->meshLinkIsEmpty(a)) break;
|
|
if ((a < MAX_SUBANIMS) && (--a >= 0))
|
|
if ((len = _parser->ReadArgument(str)) < 0 || (long unsigned int)len > sizeof(anim->name[a])) return _parser->ParseError("Error reading animname %s in %s", str, s);
|
|
else strcpy((char*)anim->name[a].rawArray(), str);
|
|
else return _parser->ParseError("Too many subanim in Anim %s sub %d max is %d", str, a, MAX_SUBANIMS);
|
|
break;
|
|
case 3:
|
|
for (a = 0; a < MAX_SUBANIMS; a++) if (anim->meshLinkIsEmpty(a)) break;
|
|
if ((a < MAX_SUBANIMS) && (len = _parser->ReadArgument(str)))
|
|
anim->setMeshLink(a, _init.Obj[GetTokenValue(ObjToken, str)].getMeshLink(0));
|
|
else return _parser->ParseError("Too many Objlinks in Anim %s sub %d max is %d", str, a, MAX_SUBANIMS);
|
|
break;
|
|
case 4:
|
|
for (a = 0; a < MAX_SUBANIMS; a++) if (anim->meshLinkIsEmpty(a)) break;
|
|
if (a < MAX_SUBANIMS)
|
|
if ((len = _parser->ReadArgument(str)) < 0 || len > MAX_MESHLINK_SIZE) return _parser->ParseError("Error reading meshlink %s in %s", str, s);
|
|
else anim->setMeshLink(a, str);
|
|
else return _parser->ParseError("Too many Meshlinks in Anim %s sub %d max is %d", str, a, MAX_SUBANIMS);
|
|
break;
|
|
case 5:
|
|
if ((len = _parser->ReadArgument(str)) < 0 || (size_t)len > sizeof(anim->RoomName)) return _parser->ParseError("Error reading RoomName %s in %s", str, s);
|
|
else strcpy((char*)anim->RoomName.rawArray(), str);
|
|
break;
|
|
case 6:
|
|
if ((len = _parser->ReadArgument(str)) < 0 || (size_t)len > sizeof(anim->RoomName)) return _parser->ParseError("Error reading PortalLink %s in %s", str, s);
|
|
else strcpy((char*)anim->RoomName.rawArray(), str);
|
|
break;
|
|
case 7:
|
|
anim->pos = _parser->ReadNumber();
|
|
break;
|
|
case 8:
|
|
anim->cam = _parser->ReadNumber();
|
|
break;
|
|
case 9:
|
|
_parser->ReadArgument(str);
|
|
anim->obj = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case 10:
|
|
while (_parser->ReadArgumentEOL(str) > 0) {
|
|
j = 0;
|
|
while (anim->atframe[j].type != 0)
|
|
if (j++ >= MAX_ATFRAMES) return _parser->ParseError("Too many ATFrame in Anim %s max is %d", anim->name[a].rawArray(), MAX_ATFRAMES);
|
|
anim->atframe[j].nframe = atoi(str);
|
|
if ((anim->atframe[j].nframe > 1) && (anim->atframe[j].nframe < 9000))
|
|
anim->atframe[j].nframe *= 3;
|
|
anim->atframe[j].anim = _parser->ReadNumber();
|
|
_parser->ReadArgument(str);
|
|
anim->atframe[j].type = (uint8)GetTokenValue(FlagToken, str);
|
|
anim->atframe[j].index = ReadIndex();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// for(a=0;a<MAX_SUBANIMS;a++)
|
|
// DebugFile("Anim |%s| |%s| |%s|",s,anim->meshlink[a],anim->name[a]);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.06-------------------
|
|
* ParseInv
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseInv(char *s) {
|
|
int inx = GetTokenValue(InvToken, s);
|
|
int done = FALSE, arg, a, len;
|
|
char str[J_MAXSTRLEN];
|
|
struct SInvObject *inv;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Inv %s doesn't exist!", s);
|
|
inv = &_init.InvObj[inx];
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "name:", "examine:", "examined:", "examinev:", "action:", "actiond:", "actionv:",
|
|
"meshlink:", "flags:", "text:", "log:", "uwobj:", "anim:", "animd:", "animv:", "anim2:", "anim2d:", "anim2v:",
|
|
NULL)) < 0)return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
debug("\n// %s\n", s);
|
|
inv->name = ReadObjName();
|
|
break;
|
|
case 2:
|
|
csn = ocBOTH;
|
|
inv->examine[DARRELL] = ReadSentence();
|
|
inv->examine[VICTORIA] = inv->examine[DARRELL];
|
|
break;
|
|
case 3:
|
|
csn = ocDARRELL;
|
|
inv->examine[DARRELL] = ReadSentence();
|
|
break;
|
|
case 4:
|
|
csn = ocVICTORIA;
|
|
inv->examine[VICTORIA] = ReadSentence();
|
|
break;
|
|
case 5:
|
|
csn = ocBOTH;
|
|
inv->action[DARRELL] = ReadSentence();
|
|
inv->action[VICTORIA] = inv->action[DARRELL];
|
|
break;
|
|
case 6:
|
|
csn = ocDARRELL;
|
|
inv->action[DARRELL] = ReadSentence();
|
|
break;
|
|
case 7:
|
|
csn = ocVICTORIA;
|
|
inv->action[VICTORIA] = ReadSentence();
|
|
break;
|
|
case 8:
|
|
if ((len = _parser->ReadArgument(str)) < 0 || (size_t)len > sizeof(inv->meshlink)) return _parser->ParseError("Error reading meshlink %s in %s", str, s);
|
|
else strcpy((char*)inv->meshlink.rawArray(), str);
|
|
break;
|
|
case 9:
|
|
inv->flags = ReadFlags();
|
|
break;
|
|
case 10:
|
|
for (a = 0; a < MAX_ICON_USER_SENTS; a++) if (!inv->text[a]) break;
|
|
csn = ocBOTH;
|
|
if (a < MAX_ICON_USER_SENTS) inv->text[a] = ReadSentence();
|
|
else _parser->ParseError("Too many UserText in Inv %s %d max is %d", str, a, MAX_ICON_USER_SENTS);
|
|
break;
|
|
case 11:
|
|
_parser->ReadArgument(str);
|
|
debug("\n// %s\n", str);
|
|
break;
|
|
case 12:
|
|
_parser->ReadArgument(str);
|
|
inv->uwobj = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case 13:
|
|
_parser->ReadArgument(str);
|
|
inv->anim[DARRELL] = GetTokenValue(AnimToken, str);
|
|
inv->anim[VICTORIA] = inv->anim[DARRELL];
|
|
break;
|
|
case 14:
|
|
_parser->ReadArgument(str);
|
|
inv->anim[DARRELL] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 15:
|
|
_parser->ReadArgument(str);
|
|
inv->anim[VICTORIA] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 16:
|
|
_parser->ReadArgument(str);
|
|
inv->anim2[DARRELL] = GetTokenValue(AnimToken, str);
|
|
inv->anim2[VICTORIA] = inv->anim2[DARRELL];
|
|
break;
|
|
case 17:
|
|
_parser->ReadArgument(str);
|
|
inv->anim2[DARRELL] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 18:
|
|
_parser->ReadArgument(str);
|
|
inv->anim2[VICTORIA] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------16/03/98 18.11-------------------
|
|
* ParseSound
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseSound(char *s) {
|
|
int inx = GetTokenValue(WaveToken, s);
|
|
int done = FALSE, arg, len, a;
|
|
char str[J_MAXSTRLEN];
|
|
struct SSound *sound;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Sound %s doesn't exist!", s);
|
|
sound = &_init.Sound[inx];
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "name:", "flags:", "room:", "meshlink:", "cone:", "dist:", "angle:",
|
|
NULL)) < 0)return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
len = _parser->ReadArgument(str);
|
|
if (len < 0 || (size_t)len > sizeof(sound->name))return _parser->ParseError("Error reading sound 'filename' %s in %s", str, s);
|
|
strcpy(sound->name, str);
|
|
break;
|
|
case 2:
|
|
sound->flags = ReadFlags();
|
|
break;
|
|
case 3:
|
|
AssignSound(inx);
|
|
break;
|
|
case 4:
|
|
for (a = 0; a < MAX_SOUND_MESHLINKS; a++) if (sound->meshlink[a][0] == 0) break;
|
|
if (a < MAX_SOUND_MESHLINKS)
|
|
if ((len = _parser->ReadArgument(str)) < 0 || (size_t)len > sizeof(sound->meshlink[a]))return _parser->ParseError("Error reading meshlink %s in %s", str, s);
|
|
else strcpy((char*)sound->meshlink[a].rawArray(), str);
|
|
else _parser->ParseError("Too many Meshlink in Sound %s %d max is %d", s, a, MAX_SOUND_MESHLINKS);
|
|
break;
|
|
case 5:
|
|
sound->ConeInside = _parser->ReadNumber();
|
|
sound->ConeOutside = _parser->ReadNumber();
|
|
sound->ConeOutsideVolume = _parser->ReadNumber();
|
|
break;
|
|
case 6:
|
|
sound->MinDist = ReadFloat();
|
|
sound->MaxDist = ReadFloat();
|
|
break;
|
|
case 7:
|
|
sound->Angle = _parser->ReadNumber();
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------01/06/98 10.02-------------------
|
|
* ParseItem
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseItem(int d) {
|
|
char str[J_MAXSTRLEN];
|
|
int done = FALSE, arg, a, cp = ocBOTH, i1, i2;
|
|
struct SItemCommand *ic[MAX_PLAYERS];
|
|
unsigned short com, p1, p2;
|
|
|
|
_parser->ReadArgument(str);
|
|
debug("\n// %s\n", str);
|
|
a = GetTokenValue(MenuToken, str);
|
|
if (a >= MAX_DLG_MENUS)
|
|
return _parser->ParseError("Troppi Menu nel Dialogo %d MAX = %d", d, MAX_DLG_MENUS);
|
|
|
|
_init.Dialog[d].ItemIndex[a] = DlgItemNum;
|
|
DlgItemNum ++;
|
|
if (DlgItemNum >= MAX_DLG_ITEMS)
|
|
return _parser->ParseError("Troppi DlgItem nel Dialogo %d MAX = %d", d, MAX_DLG_ITEMS);
|
|
|
|
ic[0] = (struct SItemCommand *)&_init.DlgItem[DlgItemNum - 1].item[0];
|
|
ic[1] = (struct SItemCommand *)&_init.DlgItem[DlgItemNum - 1].item[1];
|
|
|
|
for (i1 = 0; i1 < MAX_IC_PER_DLG_ITEM; i1++) if (!ic[DARRELL][i1].com) break;
|
|
for (i2 = 0; i2 < MAX_IC_PER_DLG_ITEM; i2++) if (!ic[VICTORIA][i2].com) break;
|
|
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "setplayer:", "anim:", "setcamera:", "movecamerato:", "settarget:",
|
|
"setchar:", "walkchar:", "runchar:", "backchar:", "hidechar:", "unhidechar:", "changeroom:",
|
|
"expression:", "changeplayer:", "debug:", "item:", "setflags:", "clrflags:", "atframe:", "nextdlg:", "setchar2:",
|
|
"introt1:", "introt2:",
|
|
"tanim:", "tanim2:", "twalkchar:", "trunchar:", "tbackchar:", "twaitcamera:", "twait:", "tfadout:", NULL)) < 0)
|
|
return _parser->ParseError("ParseItem %d %d error %s", d, a, str);
|
|
com = arg;
|
|
p1 = 0;
|
|
p2 = 0;
|
|
switch (arg) {
|
|
case IC_NULL:
|
|
done = TRUE;
|
|
break;
|
|
case IC_SET_PLAYER:
|
|
_parser->ReadArgument(str);
|
|
cp = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case IC_TIME_ANIM2:
|
|
case IC_ANIM:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case IC_SET_CAMERA:
|
|
case IC_TIME_WAIT_CAMERA:
|
|
case IC_MOVE_CAMERA_TO:
|
|
p1 = _parser->ReadNumber();
|
|
break;
|
|
case IC_CHANGE_PLAYER:
|
|
case IC_HIDE_CHAR:
|
|
case IC_UNHIDE_CHAR:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case IC_CHANGE_ROOM:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(RoomToken, str);
|
|
break;
|
|
case IC_SET_TARGET:
|
|
case IC_SET_CHAR2:
|
|
case IC_SET_CHAR:
|
|
case IC_WALK_CHAR:
|
|
case IC_RUN_CHAR:
|
|
case IC_BACK_CHAR:
|
|
case IC_TIME_WALK_CHAR:
|
|
case IC_TIME_RUN_CHAR:
|
|
case IC_TIME_BACK_CHAR:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(ObjToken, str);
|
|
p2 = _parser->ReadNumber();
|
|
break;
|
|
case IC_TIME_ANIM:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(AnimToken, str);
|
|
csn = _init.Anim[p1].obj;
|
|
if (csn > ocBOTH) csn = oNULL;
|
|
p2 = ReadSentence();
|
|
if (strlen(Sentence[SentenceNum - 1]) < 2) {
|
|
p2 = 0;
|
|
SentenceNum--;
|
|
}
|
|
break;
|
|
case IC_TIME_FADOUT:
|
|
case IC_TIME_WAIT:
|
|
p1 = (unsigned short)(ReadFloat() * FRAME_PER_SECOND);
|
|
break;
|
|
case IC_EXPRESSION:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(ObjToken, str);
|
|
p2 = ReadFlags();
|
|
break;
|
|
case IC_DEBUG:
|
|
csn = ocNOTRANS;
|
|
p1 = ReadSentence();
|
|
break;
|
|
case IC_ITEM:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(MenuToken, str);
|
|
p2 = _parser->ReadNumber();
|
|
break;
|
|
case IC_SET_FLAGS:
|
|
case IC_CLR_FLAGS:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(DlgToken, str);
|
|
p2 = ReadFlags();
|
|
break;
|
|
case IC_NEXT_DLG:
|
|
_parser->ReadArgument(str);
|
|
p1 = GetTokenValue(DlgToken, str);
|
|
break;
|
|
case IC_ATFRAME:
|
|
_parser->ReadArgument(str);
|
|
p1 = (uint8)GetTokenValue(FlagToken, str);
|
|
p2 = ReadIndex();
|
|
break;
|
|
case IC_INTRO_TEXT1:
|
|
case IC_INTRO_TEXT2:
|
|
p1 = _parser->ReadNumber();
|
|
p2 = ReadSysSent();
|
|
if (strlen(SysSent[SysSentNum - 1]) < 2) {
|
|
p2 = 0;
|
|
SysSentNum--;
|
|
}
|
|
break;
|
|
}
|
|
if ((i1 >= MAX_IC_PER_DLG_ITEM) || (i2 >= MAX_IC_PER_DLG_ITEM))
|
|
return _parser->ParseError("Troppi ItemCommands nel Dialogo %d item %d,%d MAX = %d", d, i1, i2, MAX_IC_PER_DLG_ITEM);
|
|
if (cp == ocBOTH) {
|
|
ic[DARRELL][i1].com = ic[VICTORIA][i2].com = (uint8)com;
|
|
ic[DARRELL][i1].param1 = ic[VICTORIA][i2].param1 = p1;
|
|
ic[DARRELL][i1++].param2 = ic[VICTORIA][i2++].param2 = p2;
|
|
} else if (cp == ocVICTORIA) {
|
|
ic[VICTORIA][i2].com = (uint8)com;
|
|
ic[VICTORIA][i2].param1 = p1;
|
|
ic[VICTORIA][i2++].param2 = p2;
|
|
} else {
|
|
ic[DARRELL][i1].com = (uint8)com;
|
|
ic[DARRELL][i1].param1 = p1;
|
|
ic[DARRELL][i1++].param2 = p2;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------01/06/98 9.55--------------------
|
|
* ParseDialog
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseDialog(char *s) {
|
|
int inx = GetTokenValue(DlgToken, s);
|
|
int arg, done = FALSE, a, alt;
|
|
char str[J_MAXSTRLEN];
|
|
struct SDialog *d;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Dialog %s doesn't exist!", s);
|
|
d = &_init.Dialog[inx];
|
|
debug("\n// %s\n", s);
|
|
Match("{");
|
|
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "flags:", "item:", "alt1pos:", "alt2pos:", "alt3pos:",
|
|
"alt1cam:", "alt2cam:", "alt3cam:", "alt1an:", "alt2an:", "alt3an:", "obj:", "log:",
|
|
NULL)) < 0) return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
d->flags = ReadFlags();
|
|
break;
|
|
case 2:
|
|
if (!ParseItem(inx)) return FALSE;
|
|
break;
|
|
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
d->AltPosSco[arg - 3] = _parser->ReadNumber();
|
|
break;
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
d->AltCamSco[arg - 6] = _parser->ReadNumber();
|
|
break;
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
for (a = 0, alt = arg - 9; a < MAX_ALT_ANIMS; a++)
|
|
if (d->AltAnims[alt][a][0] == aNULL)
|
|
break;
|
|
if (a >= MAX_ALT_ANIMS)
|
|
return _parser->ParseError("Too many Alternate Anims defined in Dialog %d max is %d", inx, MAX_ALT_ANIMS);
|
|
_parser->ReadArgument(str);
|
|
d->AltAnims[alt][a][0] = GetTokenValue(AnimToken, str);
|
|
_parser->ReadArgument(str);
|
|
d->AltAnims[alt][a][1] = GetTokenValue(AnimToken, str);
|
|
break;
|
|
case 12:
|
|
_parser->ReadArgument(str);
|
|
d->obj = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case 13:
|
|
_parser->ReadArgument(str);
|
|
debug("\n// %s\n", str);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------02/06/98 16.15-------------------
|
|
* ParseDiary
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseDiary(char *s) {
|
|
int inx = GetTokenValue(DiaryToken, s);
|
|
int done = FALSE, arg, i, j;
|
|
struct SDiary *e;
|
|
char str[J_MAXSTRLEN];
|
|
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Diary %s doesn't exist!", s);
|
|
|
|
e = &_init.Diary[inx];
|
|
e->startt = _parser->ReadNumber();
|
|
e->endt = _parser->ReadNumber();
|
|
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "room:", "obj:", "rand:", "end_hideobj:", NULL)) < 0) return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
_parser->ReadArgument(str);
|
|
e->room = GetTokenValue(RoomToken, str);
|
|
break;
|
|
case 2:
|
|
_parser->ReadArgument(str);
|
|
e->obj = GetTokenValue(ObjToken, str);
|
|
break;
|
|
case 3:
|
|
i = 0;
|
|
while (e->item[i].anim[0] != aNULL)
|
|
if (i++ >= MAX_DIARY_ITEMS)
|
|
return _parser->ParseError("Too many DiaryItem in Diary %d max is %d", inx, MAX_DIARY_ITEMS);
|
|
e->item[i].rand = _parser->ReadNumber();
|
|
e->item[i].loop = _parser->ReadNumber();
|
|
e->item[i].bnd = _parser->ReadNumber();
|
|
|
|
while (_parser->ReadArgumentEOL(str) > 0) {
|
|
j = 0;
|
|
while (e->item[i].anim[j] != aNULL)
|
|
if (j++ >= MAX_ANIMS_PER_DIARY_ITEM)
|
|
return _parser->ParseError("Too many Anims per DiaryItem in Diary %d max is %d", inx, MAX_ANIMS_PER_DIARY_ITEM);
|
|
e->item[i].anim[j] = GetTokenValue(AnimToken, str);
|
|
}
|
|
break;
|
|
case 4:
|
|
_parser->ReadArgument(str);
|
|
e->end_hideobj = GetTokenValue(ObjToken, str);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------04/06/98 10.04--------------------
|
|
* ParseMenu
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseMenu(char *s) {
|
|
int inx = GetTokenValue(MenuToken, s);
|
|
char str[J_MAXSTRLEN];
|
|
struct SDlgMenu *m;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Menu %s doesn't exist!", s);
|
|
m = &_init.DlgMenu[inx];
|
|
|
|
csn = ocNOTRANS;
|
|
m->titolo = ReadSentence();
|
|
_parser->ReadArgument(str);
|
|
m->parent = (uint8)GetTokenValue(MenuToken, str);
|
|
m->on = _parser->ReadNumber();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------26/04/00 16.36-------------------
|
|
* ParsePDALog
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParsePDALog(char *s) {
|
|
int done = FALSE, arg, a;
|
|
int inx = GetTokenValue(PDALogToken, s);
|
|
char str[J_MAXSTRLEN];
|
|
struct SPDALog *l;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("PDALog %s doesn't exist!", s);
|
|
l = &_init.PDALog[inx];
|
|
|
|
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "flags:", "time:", "menu_appartenenza:", "menu_creato:", "text:", NULL)) < 0) return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
l->flags = ReadFlags();
|
|
break;
|
|
case 2:
|
|
l->time = _parser->ReadNumber();
|
|
break;
|
|
case 3:
|
|
l->menu_appartenenza = _parser->ReadNumber();
|
|
break;
|
|
case 4:
|
|
l->menu_creato = _parser->ReadNumber();
|
|
break;
|
|
case 5:
|
|
csn = ocNOTRANS;
|
|
for (a = 0; a < MAX_PDA_INFO; a++)
|
|
if (l->text[a] == 0)
|
|
break;
|
|
if (a >= MAX_PDA_INFO) return _parser->ParseError("Too many Info in PDALog item %s: cur %d (MAX %d)", s, a, MAX_PDA_INFO);
|
|
l->text[a] = ReadSentence();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------23/06/00 16.46-------------------
|
|
* ParseMusic
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseMusic(char *s) {
|
|
int done = FALSE, arg;
|
|
int inx = GetTokenValue(MusicToken, s), len;
|
|
char str[J_MAXSTRLEN];
|
|
struct SMusic *n;
|
|
if (inx == TOKEN_NOT_FOUND)return _parser->ParseError("Music %s doesn't exist!", s);
|
|
n = &_init.Music[inx];
|
|
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}", "sub0:", "sub1:", "sub2:", "sub3:", "sub4:", "sub5:", "sub6:", "sub7:", "sub8:", "sub9:", "room:",
|
|
NULL)) < 0) return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
len = _parser->ReadArgument(str);
|
|
if (len < 0 || (size_t)len > sizeof(n->name[arg - 1]))return _parser->ParseError("Error reading music 'filename' %s in %s", str, s);
|
|
strcpy(n->name[arg - 1], str);
|
|
n->vol[arg - 1] = _parser->ReadNumber();
|
|
break;
|
|
case 11:
|
|
_parser->ReadArgument(str);
|
|
_init.Room[GetTokenValue(RoomToken, str)].music = inx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* -----------------22/11/00 15.16-------------------
|
|
* ParseCredits
|
|
* --------------------------------------------------*/
|
|
int StructureInitializer::ParseCredits(char *s) {
|
|
char str[J_MAXSTRLEN];
|
|
int done, arg, len;
|
|
uint8 curflags;
|
|
|
|
curflags = 0;
|
|
done = FALSE;
|
|
Match("{");
|
|
while (!done) {
|
|
if ((arg = _parser->SearchArgument(str, "}",
|
|
"role:", "name:", "flags:",
|
|
NULL)) < 0)return _parser->ParseError("Keyword %s Unknown in %s", str, s);
|
|
switch (arg) {
|
|
case 0:
|
|
done = TRUE;
|
|
break;
|
|
case 1:
|
|
_init._creditsRoles = SerializableDynamicArray<SCreditsRole>((Credits_numRoles + 1));
|
|
|
|
len = _parser->ReadArgument(str);
|
|
if (len) {
|
|
if (len >= 48) return _parser->ParseError("Credits role string too long (max is 47)");
|
|
strcpy(_init._creditsRoles[Credits_numRoles].role, str);
|
|
} else
|
|
strcpy(_init._creditsRoles[Credits_numRoles].role, "");
|
|
_init._creditsRoles[Credits_numRoles].flags = curflags;
|
|
|
|
Credits_numRoles ++;
|
|
|
|
if (!(curflags & CF_STATIC)) curflags = CF_NULL;
|
|
break;
|
|
case 2:
|
|
_init._creditsNames = SerializableDynamicArray<SCreditsName>((Credits_numNames + 1));
|
|
|
|
len = _parser->ReadArgument(str);
|
|
if (len) {
|
|
if (len >= 64) return _parser->ParseError("Credits name string too long (max is 31)");
|
|
strcpy(_init._creditsNames[Credits_numNames].name, str);
|
|
} else
|
|
strcpy(_init._creditsNames[Credits_numNames].name, "");
|
|
_init._creditsNames[Credits_numNames].role = Credits_numRoles - 1;
|
|
_init._creditsNames[Credits_numNames].flags = curflags;
|
|
|
|
Credits_numNames ++;
|
|
|
|
if (!(curflags & CF_STATIC)) curflags = CF_NULL;
|
|
break;
|
|
case 3:
|
|
curflags = (uint8)ReadFlags();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int SaveTextTable(const char *name) {
|
|
warning("TODO: Implement SaveTextTable(%s)", name);
|
|
return 0;
|
|
}
|
|
|
|
|
|
} // End of namespace Watchmaker
|