/*
===========================================================================
ARX FATALIS GPL Source Code
Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
Arx Fatalis Source Code 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.
Arx Fatalis Source Code 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 Arx Fatalis Source Code. If not, see
.
In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "eerieapp.h"
#include "Hermesmain.h"
#include "ARX_LocHash.h"
#include "ARX_Loc.h"
#include "Arx_Config.h"
#include
#include
#include "Arx_menu2.h"
#include "EerieTexture.h"
#define _CRTDBG_MAP_ALLOC
#include
extern long GERMAN_VERSION;
extern long FRENCH_VERSION;
extern long CHINESE_VERSION;
extern long FINAL_COMMERCIAL_GAME;
extern PROJECT Project;
extern bool bForceInPack;
extern long FINAL_COMMERCIAL_DEMO;
using namespace std;
extern CMenuConfig * pMenuConfig;
#define MAX_LINE_SIZE 8096
CLocalisationHash * pHashLocalisation = NULL;
//-----------------------------------------------------------------------------
bool isSection(_TCHAR * _lpszUText)
{
ULONG i = 0;
unsigned long ulTextSize = _tcslen(_lpszUText);
bool bFirst = false;
bool bLast = false;
while (i < ulTextSize)
{
if (_lpszUText[i] == _T('['))
{
if (bFirst)
return false;
else
bFirst = true;
}
else if (_lpszUText[i] == _T(']'))
{
if (bFirst)
if (bLast)
return false;
else
bLast = true;
else
return false;
}
else if (_istalnum(_lpszUText[i]))
{
if (!bFirst)
return false;
else if (bFirst && bLast)
return false;
}
i++;
}
if (bFirst && bLast) return true;
return false;
}
//-----------------------------------------------------------------------------
bool isKey(const _TCHAR * _lpszUText)
{
unsigned long i = 0;
unsigned long ulTextSize = _tcslen(_lpszUText);
bool bSpace = false;
bool bAlpha = false;
while (i < ulTextSize)
{
if (_lpszUText[i] == _T('='))
{
if (bSpace)
return false;
else
bSpace = true;
}
else if (_istalnum(_lpszUText[i]))
{
if (!bAlpha)
bAlpha = true;
}
i++;
}
if (bSpace && bAlpha) return true;
return false;
}
//-----------------------------------------------------------------------------
bool isNotEmpty(_TCHAR * _lpszUText)
{
ULONG i = 0;
unsigned long ulTextSize = _tcslen(_lpszUText);
while (i < ulTextSize)
{
if (_istalnum(_lpszUText[i]))
{
return true;
}
i++;
}
return false;
}
//-----------------------------------------------------------------------------
_TCHAR * CleanSection(const _TCHAR * _lpszUText)
{
_TCHAR * lpszUText = (_TCHAR *) malloc((_tcslen(_lpszUText) + 2) * sizeof(_TCHAR));
ZeroMemory(lpszUText, (_tcslen(_lpszUText) + 2)*sizeof(_TCHAR));
unsigned long ulPos = 0;
bool bFirst = false;
bool bLast = false;
for (unsigned long ul = 0; ul < _tcslen(_lpszUText); ul++)
{
if (_lpszUText[ul] == _T('['))
{
bFirst = true;
}
else if (_lpszUText[ul] == _T(']'))
{
bLast = true;
}
if (bFirst)
{
lpszUText[ulPos] = _lpszUText[ul];
ulPos ++;
if (bLast)
{
break;
}
}
}
return lpszUText;
}
//-----------------------------------------------------------------------------
_TCHAR * CleanKey(const _TCHAR * _lpszUText)
{
_TCHAR * lpszUText = (_TCHAR *) malloc((_tcslen(_lpszUText) + 2) * sizeof(_TCHAR));
ZeroMemory(lpszUText, (_tcslen(_lpszUText) + 2)*sizeof(_TCHAR));
unsigned long ulPos = 0;
unsigned long ulTextSize = _tcslen(_lpszUText);
bool bAlpha = false;
bool bEqual = false;
for (unsigned long ul = 0; ul < ulTextSize; ul++)
{
if (_lpszUText[ul] == _T('='))
{
bEqual = true;
}
else if (bEqual && (_istalnum(_lpszUText[ul]) ||
((_lpszUText[ul] != _T(' ')) &&
(_lpszUText[ul] != _T('"')))
))
{
bAlpha = true;
}
else if ((_lpszUText[ul] == _T('\"')) && (!bAlpha))
{
continue;
}
if (bEqual && bAlpha)
{
lpszUText[ulPos] = _lpszUText[ul];
ulPos ++;
}
}
while (ulPos--)
{
if (_istalnum(lpszUText[ulPos]))
{
break;
}
else if (lpszUText[ulPos] == _T('"'))
{
lpszUText[ulPos] = 0;
}
}
return lpszUText;
}
//-----------------------------------------------------------------------------
void ParseFile(_TCHAR * _lpszUTextFile, const unsigned long _ulFileSize)
{
_TCHAR * pULine;
//-------------------------------------------------------------------------
// on skip l'entete unicode
_TCHAR * pFile = _lpszUTextFile;
pFile ++;
unsigned long ulFileSize = _ulFileSize - 1;
//-------------------------------------------------------------------------
//clean up comments
for (unsigned long i = 0; i < (ulFileSize - 1); i++)
{
if ((pFile[i] == _T('/')) && (pFile[i+1] == _T('/')))
{
unsigned long j = i;
while ((j < (ulFileSize - 1)) && (pFile[j] != _T('\r')) && (pFile[j+1] != _T('\n')))
{
pFile[j] = _T(' ');
j++;
}
i = j;
}
}
//-------------------------------------------------------------------------
// get all lines into list
list<_TCHAR *> lUText;
pULine = _tcstok(pFile, _T("\r\n"));
long t = 0;
while (pULine != NULL)
{
if (isNotEmpty(pULine))
{
t++;
lUText.insert(lUText.end(), (pULine)); //_tcsdup
}
pULine = _tcstok(NULL, _T("\r\n"));
}
list<_TCHAR *>::iterator it;
//-------------------------------------------------------------------------
// look up for sections and associated keys
it = lUText.begin();
t = 0;
while (it != lUText.end())
{
if (isSection(*it))
{
CLocalisation * pLoc = new CLocalisation();
_TCHAR * lpszUT = CleanSection(*it);
pLoc->SetSection(lpszUT);
free(lpszUT);
it++;
t++;
while ((it != lUText.end()) && (!isSection(*it)))
{
if (isKey(*it))
{
_TCHAR * lpszUTk = CleanKey(*it);
pLoc->AddKey(lpszUTk);
free(lpszUTk);
it++;
t++;
}
else
{
break;
}
}
pHashLocalisation->AddElement(pLoc);
continue;
}
it++;
t++;
}
}
//-----------------------------------------------------------------------------
char LocalisationLanguage = -1;
//-----------------------------------------------------------------------------
void ARX_Localisation_Init(char * _lpszExtension)
{
if (_lpszExtension == NULL)
return;
// nettoyage
if (pHashLocalisation)
{
ARX_Localisation_Close();
}
char tx[256];
ZeroMemory(tx, 256);
sprintf(tx, "%slocalisation\\utext_%s.ini", Project.workingdir, Project.localisationpath);
long LocalisationSize = 0;
_TCHAR * Localisation = NULL;
if (GERMAN_VERSION)
{
bool bOldForceInPack = bForceInPack;
bForceInPack = true;
Localisation = (_TCHAR *)PAK_FileLoadMallocZero(tx, &LocalisationSize);
bForceInPack = bOldForceInPack;
}
else
{
Localisation = (_TCHAR *)PAK_FileLoadMallocZero(tx, &LocalisationSize);
}
if (Localisation == NULL)
{
if (GERMAN_VERSION || FRENCH_VERSION)
{
delete pMenuConfig;
pMenuConfig = NULL;
exit(0);
}
ZeroMemory(tx, 256);
strcpy(Project.localisationpath, "english");
sprintf(tx, "%slocalisation\\utext_%s.ini", Project.workingdir, Project.localisationpath);
Localisation = (_TCHAR *)PAK_FileLoadMallocZero(tx, &LocalisationSize);
}
if (Localisation && LocalisationSize)
{
pHashLocalisation = new CLocalisationHash(1 << 13);
LocalisationSize = _tcslen(Localisation);
ParseFile(Localisation, LocalisationSize);
free((void *)Localisation);
Localisation = NULL;
LocalisationSize = 0;
}
//CD Check
if (FINAL_COMMERCIAL_DEMO && (!bForceInPack))
{
_TCHAR szMenuText[256];
PAK_UNICODE_GetPrivateProfileString(_T("system_menus_main_cdnotfound"), _T("string"), _T(""), szMenuText, 256, NULL);
if (!szMenuText[0]) //warez
{
bForceInPack = true;
ARX_Localisation_Init();
bForceInPack = false;
}
}
if (FINAL_COMMERCIAL_GAME)
{
_TCHAR szMenuText[256] = {0};
PAK_UNICODE_GetPrivateProfileString(_T("unicode"), _T("string"), _T(""), szMenuText, 256, NULL);
if (szMenuText[0]) //warez
{
if (!_tcsicmp(_T("chinese"), szMenuText))
{
CHINESE_VERSION = 1;
}
}
}
}
//-----------------------------------------------------------------------------
void ARX_Localisation_Close()
{
LocalisationLanguage = -1;
delete pHashLocalisation;
pHashLocalisation = NULL;
}
//-----------------------------------------------------------------------------
long HERMES_UNICODE_GetProfileString(_TCHAR * sectionname,
_TCHAR * t_keyname,
_TCHAR * defaultstring,
_TCHAR * destination,
unsigned long maxsize,
_TCHAR * datastream,
long lastspeech)
{
ZeroMemory(destination, maxsize * sizeof(_TCHAR));
if (pHashLocalisation)
{
_TCHAR * t = pHashLocalisation->GetPtrWithString(sectionname);
if (t)
{
_tcsncpy(destination, t, min(maxsize, _tcslen(t)));
}
else
{
_tcsncpy(destination, defaultstring, min(maxsize, _tcslen(defaultstring)));
}
}
else
{
_tcsncpy(destination, defaultstring, min(maxsize, _tcslen(defaultstring)));
}
return 0;
}
//-----------------------------------------------------------------------------
long HERMES_UNICODE_GetProfileSectionKeyCount(const _TCHAR * sectionname)
{
if (pHashLocalisation)
return pHashLocalisation->GetKeyCount(sectionname);
return 0;
}
static long ltNum = 0;
//-----------------------------------------------------------------------------
DWORD PAK_UNICODE_GetPrivateProfileString(_TCHAR * _lpszSection,
_TCHAR * _lpszKey,
_TCHAR * _lpszDefault,
_TCHAR * _lpszBuffer,
unsigned long _lBufferSize,
char * _lpszFileName)
{
ltNum ++;
ZeroMemory(_lpszBuffer, _lBufferSize * sizeof(_TCHAR));
if (_lpszSection[0] == _T('\0'))
{
_tcsncpy(_lpszBuffer, _lpszDefault, min(_lBufferSize, _tcslen(_lpszDefault)));
_stprintf(_lpszBuffer, _T("%s: NOT FOUND"), _lpszSection);
return 0;
}
_TCHAR szSection[256] = _T("");
_stprintf(szSection, _T("[%s]"), _lpszSection);
HERMES_UNICODE_GetProfileString(
szSection,
_lpszKey,
_lpszDefault,
_lpszBuffer,
_lBufferSize,
NULL,
-1); //lastspeechflag
return 1;
}
#include
using namespace std;
extern PakManager * pPakManager;
vector mlist;
//-----------------------------------------------------------------------------
void ParseCurFile(EVE_TFILE * _e)
{
if (!_e) return;
if (stricmp((char *)_e->name, "utext") > 0)
{
char * t = strdup((char *)_e->name);
for (UINT i = 0 ; i < strlen(t) ; i++)
{
t[i] = ARX_CLEAN_WARN_CAST_CHAR(tolower(t[i]));
}
mlist.insert(mlist.end(), t);
//free (t);
}
ParseCurFile(_e->fnext);
}
//-----------------------------------------------------------------------------
void ParseCurRep(EVE_REPERTOIRE * _er)
{
if (!_er) return;
ParseCurFile(_er->fichiers);
ParseCurRep(_er->fils);
ParseCurRep(_er->brothernext);
}
extern HBITMAP ARX_CONFIG_hBitmap;