scummvm/engines/cryo/eden.cpp

9342 lines
237 KiB
C++
Raw Normal View History

2016-09-14 23:42:19 +02:00
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
2016-08-18 13:15:54 +02:00
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/error.h"
#include "gui/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/fs.h"
#include "common/system.h"
#include "graphics/surface.h"
#include "graphics/screen.h"
#include "graphics/palette.h"
#include "common/timer.h"
//#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "cryo/defs.h"
2016-08-18 13:15:54 +02:00
#include "cryo/cryo.h"
#include "cryo/platdefs.h"
#include "cryo/cryolib.h"
2016-08-18 13:15:54 +02:00
#include "cryo/eden.h"
2016-10-22 14:15:45 +03:00
#include "cryo/sound.h"
2016-08-18 13:15:54 +02:00
namespace Cryo {
int16 _torchTick = 0;
int16 _glowIndex = 0;
int16 _torchCurIndex = 0;
2016-08-18 13:15:54 +02:00
bool _allowDoubled = true;
int _cursCenter = 11;
2016-08-18 13:15:54 +02:00
EdenGame::EdenGame(CryoEngine *vm) : _vm(vm) {
2016-09-30 07:48:27 +02:00
_adamMapMarkPos = Common::Point(-1, -1);
2016-10-09 00:01:32 +03:00
2016-10-09 01:44:52 +03:00
_scrollPos = _oldScrollPos = 0;
2016-10-09 00:01:32 +03:00
_frescoTalk = false;
2016-12-18 13:09:56 -08:00
_torchCursor = false;
2016-10-09 00:01:32 +03:00
_curBankNum = 0;
_glowH = _glowW = _glowY = _glowX = 0;
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = false;
2016-12-18 13:09:56 -08:00
_cursorSaved = false;
2016-12-18 14:13:36 -08:00
_showBlackBars = false;
_backgroundSaved = false;
2016-12-04 14:26:44 -08:00
_bankData = nullptr;
_tyranPtr = nullptr;
2016-12-04 14:26:44 -08:00
_lastAnimFrameNumb = _curAnimFrameNumb = 0;
2016-10-09 00:01:32 +03:00
_lastAnimTicks = 0;
2016-12-25 02:17:07 -08:00
_curPersoRect = nullptr;
_numAnimFrames = _maxPersoDesc = _numImgDesc = 0;
_restartAnimation = _animationActive = false;
_animationDelay = _animationIndex = _lastAnimationIndex = 0;
2016-12-25 13:45:47 -08:00
dword_30724 = dword_30728 = _mouthAnimations = _animationTable = nullptr;
2016-12-04 14:26:44 -08:00
_characterBankData = nullptr;
2016-12-25 02:17:07 -08:00
_savedUnderSubtitles = false;
2016-12-25 13:45:47 -08:00
_numTextLines = 0;
2016-10-09 01:44:52 +03:00
textoutptr = textout = nullptr;
2016-12-04 14:26:44 -08:00
_curSpecialObject = nullptr;
2016-12-04 13:15:38 -08:00
_lastDialogChoice = false;
parlemoiNormalFlag = false;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
2016-10-09 01:44:52 +03:00
dword_30B04 = 0;
2016-10-09 00:01:32 +03:00
lastPhrasesFile = 0;
dialogSkipFlags = 0;
voiceSamplesBuffer = nullptr;
needToFade = false;
2016-10-09 00:01:32 +03:00
lastMusicNum = 0;
2016-12-04 14:54:58 -08:00
_mainBankBuf = nullptr;
_musicBuf = nullptr;
2016-10-09 00:01:32 +03:00
gameLipsync = nullptr;
gamePhrases = nullptr;
gameDialogs = nullptr;
gameConditions = nullptr;
2016-12-18 14:13:36 -08:00
_placeRawBuf = nullptr;
_bankDataBuf = nullptr;
2016-12-04 14:26:44 -08:00
_gameIcons = nullptr;
2016-12-18 14:13:36 -08:00
_gameRooms = nullptr;
_glowBuffer = nullptr;
_gameFont = nullptr;
2016-10-09 00:01:32 +03:00
p_global = nullptr;
2016-12-18 14:13:36 -08:00
_mouseCenterY = _mouseCenterX = 0;
bufferAllocationErrorFl = _quitFlag2 = _quitFlag3 = false;
2016-12-18 13:09:56 -08:00
_gameStarted = false;
2016-10-09 00:01:32 +03:00
_soundAllocated = false;
2016-10-22 14:15:45 +03:00
_musicChannel = _voiceChannel = nullptr;
2016-11-17 15:40:07 -08:00
_hnmSoundChannel = nullptr;
2016-12-18 14:13:36 -08:00
_voiceSound = nullptr;
p_view2 = p_underSubtitlesView = p_subtitlesview = p_underBarsView = _mainView = _hnmView = nullptr;
2016-10-09 00:01:32 +03:00
_hnmContext = nullptr;
_doubledScreen = false;
2016-12-18 13:09:56 -08:00
_cirsorPanX = 0;
2016-10-09 00:01:32 +03:00
_inventoryScrollDelay = 0;
2016-12-18 13:09:56 -08:00
_cursorPosY = _cursorPosX = 0;
_currCursor = 0;
2016-12-19 22:32:40 -08:00
_currSpot = _curSpot2 = nullptr;
pomme_q = false;
2016-12-18 14:13:36 -08:00
_keyboardHeld = false;
2016-12-18 13:09:56 -08:00
_mouseHeld = false;
_normalCursor = false;
2016-12-18 14:13:36 -08:00
_showVideoSubtitle = false;
_specialTextMode = false;
_voiceSamplesSize = 0;
_animateTalking = false;
2016-10-09 00:01:32 +03:00
_personTalking = false;
_musicFadeFlag = 0;
2016-12-18 14:13:36 -08:00
_musicPlayingFlag = false;
_musicSamplesPtr = _musicPatternsPtr = _musSequencePtr = nullptr;
_musicEnabledFlag = false;
2016-10-09 00:01:32 +03:00
pCurrentObjectLocation = nullptr;
2016-10-09 01:44:52 +03:00
byte_31D64 = false;
_noPalette = false;
_gameLoaded = false;
2016-10-09 01:44:52 +03:00
memset(tapes, 0, sizeof(tapes));
confirmMode = 0;
cur_slider_value_ptr = nullptr;
2016-12-19 22:32:40 -08:00
_lastMenuItemIdLo = 0;
_lastTapeRoomNum = 0;
_curSliderX = cur_slider_y = 0;
2016-10-09 01:44:52 +03:00
destinationRoom = 0;
word_31E7A = 0;
2016-10-09 00:01:32 +03:00
word_378CC = 0; //TODO: set by CLComputer_Init to 0
2016-10-09 01:44:52 +03:00
word_378CE = 0;
2016-10-21 23:11:03 +03:00
word_32448 = word_3244A = word_3244C = 0;
flt_32450 = flt_32454 = 0.0; //TODO: never changed, make consts?
curs_old_tick = 0;
2016-12-19 22:32:40 -08:00
_invIconsBase = 19;
// invIconsCount = (_vm->getPlatform() == Common::kPlatformMacintosh) ? 9 : 11;
2016-12-19 13:41:00 -08:00
_invIconsCount = 11;
2016-12-19 22:32:40 -08:00
_roomIconsBase = _invIconsBase + _invIconsCount;
2016-09-30 07:48:27 +02:00
}
2016-08-18 13:15:54 +02:00
2016-09-26 23:44:42 +02:00
void EdenGame::removeConsole() {
}
2016-08-18 13:15:54 +02:00
void EdenGame::scroll() {
2016-09-27 07:53:50 +02:00
restoreFriezes();
2016-12-18 14:13:36 -08:00
_mainView->_normal._srcLeft = _scrollPos;
_mainView->_zoom._srcLeft = _scrollPos;
}
2016-09-26 23:44:42 +02:00
void EdenGame::resetScroll() {
2016-09-30 07:48:27 +02:00
_oldScrollPos = _scrollPos;
_scrollPos = 0;
2016-09-27 07:53:50 +02:00
restoreFriezes(); //TODO: inlined scroll() ?
2016-12-18 14:13:36 -08:00
_mainView->_normal._srcLeft = 0;
_mainView->_zoom._srcLeft = 0;
}
void EdenGame::scrollFrescoes() {
2016-12-18 13:09:56 -08:00
if (_cursorPosY > 16 && _cursorPosY < 176) {
if (_cursorPosX >= 0 && _cursorPosX < 32 && _scrollPos > 3)
2016-09-30 07:48:27 +02:00
_scrollPos -= 4;
2016-12-18 13:09:56 -08:00
else if (_cursorPosX > 288 && _cursorPosX < 320 && _scrollPos < p_global->_frescoeWidth)
2016-09-30 07:48:27 +02:00
_scrollPos += 4;
2016-08-18 13:15:54 +02:00
}
scroll();
}
2016-09-26 23:44:42 +02:00
// Original name: afffresques
void EdenGame::displayFrescoes() {
2016-12-11 13:44:58 -08:00
useBank(p_global->_frescoeImgBank);
noclipax(0, 0, 16);
2016-12-11 13:44:58 -08:00
useBank(p_global->_frescoeImgBank + 1);
noclipax(0, 320, 16);
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
}
void EdenGame::gametofresques() {
2016-09-30 07:48:27 +02:00
_frescoTalk = false;
rundcurs();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-09-26 23:44:42 +02:00
displayFrescoes();
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFrescoes;
}
2016-09-26 23:44:42 +02:00
// Original name: dofresques
void EdenGame::doFrescoes() {
2016-12-18 13:09:56 -08:00
_cursorSaved = false;
_torchCursor = true;
_glowX = -1;
_glowY = -1;
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag20;
p_global->_varD4 = 0;
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = 0;
p_global->_iconsIndex = 13;
p_global->_autoDialog = false;
gametofresques();
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 3;
}
2016-09-26 23:44:42 +02:00
// Original name: finfresques
void EdenGame::endFrescoes() {
2016-12-18 13:09:56 -08:00
_torchCursor = false;
_cursorSaved = true;
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
2016-09-26 23:44:42 +02:00
resetScroll();
p_global->_var100 = 0xFF;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum == 114)
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 1;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent8;
2016-09-26 23:44:42 +02:00
showEvents();
}
void EdenGame::scrollMirror() {
2016-12-18 13:09:56 -08:00
if (_cursorPosY > 16 && _cursorPosY < 165) {
if (_cursorPosX >= 0 && _cursorPosX < 16) {
2016-09-30 07:48:27 +02:00
if (_scrollPos > 3) {
if (_doubledScreen)
_scrollPos -= 2;
else
2016-09-30 07:48:27 +02:00
_scrollPos -= 1;
scroll();
}
2016-12-18 13:09:56 -08:00
} else if (_cursorPosX > 290 && _cursorPosX < 320) {
2016-09-30 07:48:27 +02:00
if (_scrollPos < 320) {
if (_doubledScreen)
_scrollPos += 2;
else
2016-09-30 07:48:27 +02:00
_scrollPos += 1;
scroll();
2016-08-18 13:15:54 +02:00
}
}
}
}
void EdenGame::scrollpano() {
2016-12-18 13:09:56 -08:00
if (_cursorPosY > 16 && _cursorPosY < 165) {
if (_cursorPosX >= 0 && _cursorPosX < 16) {
2016-09-30 07:48:27 +02:00
if (_scrollPos > 3) {
if (_doubledScreen)
_scrollPos -= 2;
else
2016-09-30 07:48:27 +02:00
_scrollPos -= 1;
}
2016-12-18 13:09:56 -08:00
} else if (_cursorPosX > 290 && _cursorPosX < 320) {
2016-09-30 07:48:27 +02:00
if (_scrollPos < 320) {
if (_doubledScreen)
_scrollPos += 2;
else
2016-09-30 07:48:27 +02:00
_scrollPos += 1;
2016-08-18 13:15:54 +02:00
}
}
}
scroll();
}
2016-10-07 23:06:10 +02:00
// Original name: affsuiveur
void EdenGame::displayFollower(Follower *follower, int16 x, int16 y) {
useBank(follower->_spriteBank);
noclipax(follower->_spriteNum, x, y + 16);
}
2016-10-24 22:02:43 +02:00
// Original name: persoinmiroir
void EdenGame::characterInMirror() {
Icon *icon1 = &_gameIcons[3];
2016-12-19 22:32:40 -08:00
Icon *icon = &_gameIcons[_roomIconsBase];
2016-10-07 23:06:10 +02:00
Follower *suiveur = followerList;
2016-09-14 23:48:01 +02:00
int16 num = 1;
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 16; i++) {
2016-12-11 13:44:58 -08:00
if (p_global->_party & (1 << i))
num++;
2016-08-18 13:15:54 +02:00
}
icon += num;
icon->sx = -1;
icon--;
icon->sx = icon1->sx;
icon->sy = icon1->sy;
icon->ex = icon1->ex;
icon->ey = 170;
2016-12-03 15:40:53 -08:00
icon->_cursorId = icon1->_cursorId;
icon->_actionId = icon1->_actionId;
icon->_objectId = icon1->_objectId;
icon--;
2016-10-07 23:06:10 +02:00
displayFollower(suiveur, suiveur->sx, suiveur->sy);
for (; suiveur->_id != -1; suiveur++) {
perso_t *perso;
for (perso = kPersons; perso != &kPersons[PER_UNKN_156]; perso++) {
2016-10-24 22:02:43 +02:00
if (perso->_id != suiveur->_id)
continue;
if (perso->_flags & PersonFlags::pf80)
continue;
if ((perso->_flags & PersonFlags::pfInParty) == 0)
continue;
2016-12-11 13:44:58 -08:00
if (perso->_roomNum != p_global->_roomNum)
2016-10-24 22:02:43 +02:00
continue;
icon->sx = suiveur->sx;
icon->sy = suiveur->sy;
icon->ex = suiveur->ex;
icon->ey = suiveur->ey;
2016-12-03 15:40:53 -08:00
icon->_cursorId = 8;
icon->_actionId = perso->_actionId;
icon--;
2016-10-07 23:06:10 +02:00
displayFollower(suiveur, suiveur->sx, suiveur->sy);
break;
2016-08-18 13:15:54 +02:00
}
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::gametomiroir(byte arg1) {
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags != DisplayFlags::dfFlag2) {
rundcurs();
2016-09-27 07:53:50 +02:00
restoreFriezes();
drawTopScreen();
showObjects();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
int16 bank = p_global->_roomBackgroundBankNum;
unsigned int resNum = bank + 326;
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
if (bank == 76 || bank == 128)
resNum = 2487; // PCIMG.HSQ
}
useBank(resNum);
noclipax(0, 0, 16);
useBank(resNum + 1);
noclipax(0, 320, 16);
2016-10-24 22:02:43 +02:00
characterInMirror();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 16;
p_global->_autoDialog = false;
p_global->_displayFlags = DisplayFlags::dfMirror;
p_global->_var102 = arg1;
}
2016-09-26 23:44:42 +02:00
void EdenGame::flipMode() {
if (_personTalking) {
endpersovox();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags == DisplayFlags::dfPerson) {
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_THOO] && p_global->_phaseNum >= 80)
2016-12-25 02:17:07 -08:00
displaySubtitles();
else {
2016-12-25 02:17:07 -08:00
getDataSync();
load_perso_cour();
addanim();
2016-12-04 14:26:44 -08:00
_restartAnimation = true;
anim_perso();
}
} else
2016-12-25 02:17:07 -08:00
displaySubtitles();
persovox();
} else {
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags != DisplayFlags::dfFrescoes && p_global->_displayFlags != DisplayFlags::dfFlag2) {
closesalle();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfFlag1)
gametomiroir(1);
else {
2016-09-26 23:44:42 +02:00
quitMirror();
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
if (byte_31D64) {
dialautoon();
parle_moi();
2016-08-18 13:15:54 +02:00
}
2016-09-26 07:57:27 +02:00
byte_31D64 = false;
2016-08-18 13:15:54 +02:00
}
}
}
}
2016-09-26 23:44:42 +02:00
// Original name: quitmiroir
void EdenGame::quitMirror() {
rundcurs();
afficher();
2016-09-26 23:44:42 +02:00
resetScroll();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
p_global->_var100 = 0xFF;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventC;
p_global->_var102 = 1;
}
void EdenGame::clictimbre() {
2016-09-26 23:44:42 +02:00
flipMode();
}
void EdenGame::clicplanval() {
2016-12-04 14:26:44 -08:00
if ((p_global->_partyOutside & PersonMask::pmDina) && p_global->_phaseNum == 371) {
2016-09-26 23:44:42 +02:00
quitMirror();
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
return;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 8 || p_global->_roomNum < 16)
return;
rundcurs();
afficher();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags == DisplayFlags::dfMirror)
2016-09-26 23:44:42 +02:00
quitMirror();
2016-12-11 13:44:58 -08:00
deplaval((p_global->_roomNum & 0xFF00) | 1); //TODO: check me
}
void EdenGame::gotolieu(Goto *go) {
2016-12-15 22:47:29 -08:00
p_global->_valleyVidNum = go->_arriveVideoNum;
p_global->_travelTime = go->_travelTime * 256;
p_global->_stepsToFindAppleFast = 0;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent2;
setChoiceYes();
2016-09-26 23:44:42 +02:00
showEvents();
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
if (p_global->_var113) {
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (!pomme_q)
close_perso();
2016-08-18 13:15:54 +02:00
}
2016-12-15 22:47:29 -08:00
if (go->_enterVideoNum) {
bars_out();
2016-12-15 22:47:29 -08:00
playHNM(go->_enterVideoNum);
needToFade = true;
}
2016-12-11 13:44:58 -08:00
initPlace(p_global->_newRoomNum);
specialoutside();
2016-12-11 13:44:58 -08:00
faire_suivre(p_global->_newRoomNum);
closesalle();
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = -1;
_adamMapMarkPos.y = -1;
2016-12-11 13:44:58 -08:00
temps_passe(p_global->_travelTime);
2016-12-15 22:47:29 -08:00
p_global->_var100 = p_global->_roomPtr->_id;
2016-12-11 13:44:58 -08:00
p_global->_roomNum = p_global->_newRoomNum;
p_global->_areaNum = p_global->_roomNum >> 8;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = MusicType::mt2;
setpersohere();
musique();
2016-12-19 13:41:00 -08:00
updateRoom1(p_global->_roomNum);
drawTopScreen();
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = -1;
_adamMapMarkPos.y = -1;
}
2016-09-14 23:48:01 +02:00
void EdenGame::deplaval(uint16 roomNum) {
2016-12-11 13:44:58 -08:00
p_global->_newLocation = roomNum & 0xFF;
p_global->_valleyVidNum = 0;
p_global->_phaseActionsCount++;
closesalle();
endpersovox();
byte c1 = roomNum & 0xFF;
if (c1 == 0)
return;
if (c1 < 0x80) {
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
setChoiceYes();
p_global->_eventType = EventType::etEvent1;
2016-09-26 23:44:42 +02:00
showEvents();
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
2016-08-18 13:15:54 +02:00
return;
if (p_global->_var113) {
2016-12-04 13:15:38 -08:00
waitEndSpeak();
2016-08-18 13:15:54 +02:00
if (!pomme_q)
close_perso();
}
specialout();
2016-12-15 22:47:29 -08:00
if (p_global->_areaPtr->_type == AreaType::atValley) {
temps_passe(32);
p_global->_stepsToFindAppleFast++;
p_global->_stepsToFindAppleNormal++;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
faire_suivre((roomNum & 0xFF00) | p_global->_newLocation);
2016-12-15 22:47:29 -08:00
p_global->_var100 = p_global->_roomPtr->_id;
2016-12-11 13:44:58 -08:00
p_global->_roomNum = roomNum;
2016-12-04 14:26:44 -08:00
p_global->_areaNum = roomNum >> 8;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
2016-08-18 13:15:54 +02:00
setpersohere();
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = MusicType::mtNormal;
2016-08-18 13:15:54 +02:00
musique();
2016-12-19 13:41:00 -08:00
updateRoom1(roomNum);
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag = 0;
2016-12-11 13:44:58 -08:00
p_global->_chrono = 0;
p_global->_var54 = 0;
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftTyrann)
2016-12-11 13:44:58 -08:00
setChrono(3000);
return;
}
if (c1 == 0xFF) {
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventE;
2016-09-26 23:44:42 +02:00
showEvents();
2016-12-19 22:32:40 -08:00
if (!kPersons[PER_MESSAGER]._roomNum && checkEloiReturn())
2016-12-11 13:44:58 -08:00
setChrono(800);
return;
}
p_global->_stepsToFindAppleFast = 0;
byte newAreaNum = c1 & 0x7F;
2016-12-11 13:44:58 -08:00
byte curAreaNum = p_global->_roomNum >> 8;
int16 newRoomNum = newAreaNum << 8;
if (curAreaNum == Areas::arTausCave && newAreaNum == Areas::arMo)
newRoomNum |= 0x16;
else if (curAreaNum == Areas::arMoorkusLair)
newRoomNum |= 4;
else
newRoomNum |= 1;
2016-12-11 13:44:58 -08:00
p_global->_newRoomNum = newRoomNum;
if (newAreaNum == Areas::arTausCave)
gotolieu(&gotos[0]);
else {
for (Goto *go = gotos + 1; go->_curAreaNum != 0xFF; go++) {
2016-12-15 22:47:29 -08:00
if (go->_curAreaNum == curAreaNum) {
gotolieu(go);
break;
2016-08-18 13:15:54 +02:00
}
2016-09-26 23:44:42 +02:00
}
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
2016-09-26 23:44:42 +02:00
// Original name: deplacement
void EdenGame::move(Direction dir) {
Room *room = p_global->_roomPtr;
2016-12-11 13:44:58 -08:00
int16 roomNum = p_global->_roomNum;
debug("move: from room %4X", roomNum);
2016-09-26 07:57:27 +02:00
char newLoc = 0;
rundcurs();
afficher();
2016-12-11 13:44:58 -08:00
p_global->_prevLocation = roomNum & 0xFF;
switch (dir) {
case kCryoNorth:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[0];
break;
case kCryoEast:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[1];
break;
case kCryoSouth:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[2];
break;
case kCryoWest:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[3];
break;
}
deplaval((roomNum & 0xFF00) | newLoc);
}
2016-09-26 23:44:42 +02:00
// Original name: deplacement2
void EdenGame::move2(Direction dir) {
Room *room = p_global->_roomPtr;
2016-12-11 13:44:58 -08:00
int16 roomNum = p_global->_roomNum;
2016-09-26 07:57:27 +02:00
char newLoc = 0;
2016-12-11 13:44:58 -08:00
p_global->_prevLocation = roomNum & 0xFF;
switch (dir) {
case kCryoNorth:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[0];
break;
case kCryoEast:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[1];
break;
case kCryoSouth:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[2];
break;
case kCryoWest:
2016-12-15 22:47:29 -08:00
newLoc = room->_exits[3];
break;
}
deplaval((roomNum & 0xFF00) | newLoc);
}
void EdenGame::dinosoufle() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0) {
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(148);
maj2();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::plaquemonk() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0) {
if (p_global->_curObjectId == Objects::obPrism) {
2016-09-26 23:44:42 +02:00
loseObject(Objects::obPrism);
2016-08-18 13:15:54 +02:00
bars_out();
2016-12-18 14:13:36 -08:00
_specialTextMode = true;
2016-09-26 23:44:42 +02:00
playHNM(89);
2016-09-30 07:48:27 +02:00
// CHECKME: Unused code
// word_2F514 |= 0x8000;
2016-08-18 13:15:54 +02:00
maj2();
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventB;
2016-09-26 23:44:42 +02:00
showEvents();
2016-08-18 13:15:54 +02:00
}
} else {
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(7);
maj2();
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent4;
2016-09-26 23:44:42 +02:00
showEvents();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::fresquesgraa() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0) {
2016-12-11 13:44:58 -08:00
p_global->_frescoeWidth = 320;
p_global->_frescoeImgBank = 113;
2016-09-26 23:44:42 +02:00
doFrescoes();
2016-12-19 13:41:00 -08:00
handleDinaDialog();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::fresqueslasc() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0) {
2016-12-11 13:44:58 -08:00
p_global->_frescoeWidth = 112;
p_global->_frescoeImgBank = 315;
2016-09-26 23:44:42 +02:00
doFrescoes();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::pushpierre() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0) {
2016-12-18 14:13:36 -08:00
_gameRooms[22]._exits[0] = 17;
_gameRooms[26]._exits[2] = 9;
2016-09-26 23:44:42 +02:00
move(kCryoNorth);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::tetemomie() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == Objects::obTooth) {
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfMummyOpened;
2016-09-26 23:44:42 +02:00
move(kCryoNorth);
2016-12-04 13:15:38 -08:00
} else if (p_global->_curObjectId == 0) {
2016-12-04 14:26:44 -08:00
if (p_global->_gameFlags & GameFlags::gfMummyOpened)
2016-09-26 23:44:42 +02:00
move(kCryoNorth);
else {
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent6;
2016-12-11 22:52:10 -08:00
handleCharacterDialog(PersonId::pidMonk);
2016-12-04 13:15:38 -08:00
p_global->_eventType = 0;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::tetesquel() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == Objects::obTooth) {
2016-12-18 14:13:36 -08:00
_gameRooms[22]._exits[0] = 16;
_gameRooms[26]._exits[2] = 13;
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId |= 0x8000;
2016-09-26 23:44:42 +02:00
loseObject(Objects::obTooth);
move(kCryoNorth);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::squelmoorkong() {
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent9;
2016-09-26 23:44:42 +02:00
showEvents();
}
void EdenGame::choisir() {
2016-12-19 22:32:40 -08:00
byte objid = _curSpot2->_objectId;
2016-09-26 07:57:27 +02:00
byte obj;
switch (objid) {
case 0:
2016-12-11 13:44:58 -08:00
obj = p_global->_giveObj1;
break;
case 1:
2016-12-11 13:44:58 -08:00
obj = p_global->_giveObj2;
break;
case 2:
2016-12-11 13:44:58 -08:00
obj = p_global->_giveObj3;
break;
2016-09-26 07:57:27 +02:00
default:
warning("Unexpected object_id in choisir()");
return;
}
objectmain(obj);
2016-12-04 14:26:44 -08:00
winObject(obj);
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 16;
p_global->_autoDialog = false;
p_global->_var60 = 0;
parle_moi();
}
2016-12-19 13:41:00 -08:00
// Original name: dinaparle
void EdenGame::handleDinaDialog() {
2016-09-14 23:48:01 +02:00
int16 num;
perso_t *perso = &kPersons[PER_DINA];
2016-12-11 13:44:58 -08:00
if (perso->_partyMask & (p_global->_party | p_global->_partyOutside)) {
if (p_global->_frescoNumber < 3)
p_global->_frescoNumber = 3;
p_global->_frescoNumber++;
if (p_global->_frescoNumber < 15) {
endpersovox();
2016-12-11 13:44:58 -08:00
if (p_global->_frescoNumber == 7 && p_global->_phaseNum == 113)
2016-12-19 22:32:40 -08:00
incPhase();
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
2016-10-07 00:45:08 +02:00
num = (perso->_id << 3) | DialogType::dtInspect; //TODO: combine
bool res = dialoscansvmas((dial_t *)getElem(gameDialogs, num));
2016-09-30 07:48:27 +02:00
_frescoTalk = false;
if (res) {
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
2016-09-30 07:48:27 +02:00
_frescoTalk = true;
persovox();
}
p_global->_varCA = 0;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
} else
2016-09-26 23:44:42 +02:00
endFrescoes();
2016-08-18 13:15:54 +02:00
}
}
2016-12-11 22:52:10 -08:00
// Original name: roiparle
void EdenGame::handleKingDialog() {
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum <= 400)
2016-12-11 22:52:10 -08:00
handleCharacterDialog(0);
}
2016-12-11 22:52:10 -08:00
// Original name: roiparle1
void EdenGame::kingDialog1() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == Objects::obSword) {
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag80;
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(76);
move2(kCryoNorth);
} else {
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 1;
2016-12-11 22:52:10 -08:00
handleKingDialog();
2016-08-18 13:15:54 +02:00
}
}
2016-12-11 22:52:10 -08:00
// Original name: roiparle2
void EdenGame::kingDialog2() {
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 2;
2016-12-11 22:52:10 -08:00
handleKingDialog();
}
2016-12-11 22:52:10 -08:00
// Original name: roiparle3
void EdenGame::kingDialog3() {
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 3;
2016-12-11 22:52:10 -08:00
handleKingDialog();
}
2016-12-19 13:41:00 -08:00
// Original name: getcouteau
void EdenGame::getKnife() {
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 80) {
2016-12-18 14:13:36 -08:00
_gameRooms[113]._video = 0;
2016-12-11 22:52:10 -08:00
getObject(Objects::obKnife);
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent7;
2016-09-26 23:44:42 +02:00
showEvents();
}
2016-12-19 13:41:00 -08:00
// Original name: getprisme
void EdenGame::getPrism() {
2016-12-11 22:52:10 -08:00
getObject(Objects::obPrism);
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent7;
2016-09-26 23:44:42 +02:00
showEvents();
}
2016-12-19 13:41:00 -08:00
// Original name: getchampb
void EdenGame::getMushroom() {
2016-12-11 22:52:10 -08:00
getObject(Objects::obShroom);
}
2016-12-19 13:41:00 -08:00
// Original name: getchampm
void EdenGame::getBadMushroom() {
2016-12-11 22:52:10 -08:00
getObject(Objects::obBadShroom);
}
2016-12-19 13:41:00 -08:00
// Original name: getor
void EdenGame::getGold() {
2016-12-11 22:52:10 -08:00
getObject(Objects::obGold);
}
2016-12-19 13:41:00 -08:00
// Original name: getnido
void EdenGame::getFullNest() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
2016-12-15 22:47:29 -08:00
p_global->_roomPtr->_bank = 282; //TODO: fix me
2016-12-11 13:44:58 -08:00
p_global->_roomPtr--;
2016-12-15 22:47:29 -08:00
p_global->_roomPtr->_bank = 281; //TODO: fix me
p_global->_roomPtr->_id = 3;
2016-12-11 22:52:10 -08:00
getObject(Objects::obFullNest);
}
2016-12-19 13:41:00 -08:00
// Original name: getnidv
void EdenGame::getNest() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
2016-12-15 22:47:29 -08:00
p_global->_roomPtr->_bank = 282; //TODO: fix me
2016-12-11 13:44:58 -08:00
p_global->_roomPtr--;
2016-12-15 22:47:29 -08:00
p_global->_roomPtr->_bank = 281; //TODO: fix me
p_global->_roomPtr->_id = 3;
2016-12-11 22:52:10 -08:00
getObject(Objects::obNest);
}
2016-12-19 13:41:00 -08:00
// Original name: getcorne
void EdenGame::getHorn() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
2016-12-11 22:52:10 -08:00
getObject(Objects::obHorn);
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent7;
2016-09-26 23:44:42 +02:00
showEvents();
bigphase1();
setpersohere();
2016-12-19 13:41:00 -08:00
p_global->_roomPtr = getRoom(p_global->_roomNum);
}
2016-12-19 13:41:00 -08:00
// Original name: getsoleil
void EdenGame::getSunStone() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
2016-12-18 14:13:36 -08:00
_gameRooms[238]._video = 0;
_gameRooms[238]._flags = RoomFlags::rf80;
2016-12-11 22:52:10 -08:00
getObject(Objects::obSunStone);
}
2016-12-19 13:41:00 -08:00
// Original name: getoueuf
void EdenGame::getEgg() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
2016-12-15 22:47:29 -08:00
p_global->_roomPtr->_flags = 0;
p_global->_roomPtr->_video = 0;
2016-12-11 22:52:10 -08:00
getObject(Objects::obEgg);
}
2016-12-19 13:41:00 -08:00
// Original name: getplaque
void EdenGame::getTablet() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0 && p_global->_curObjectId < Objects::obTablet1)
return;
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = 0;
2016-12-11 22:52:10 -08:00
getObject(Objects::obTablet2);
2016-12-04 13:15:38 -08:00
putObject();
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 6; i++)
2016-12-04 14:26:44 -08:00
_objects[Objects::obTablet1 - 1 + i]._count = 0;
p_global->_curObjectFlags = 0;
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos = 0;
p_global->_curObjectCursor = 9;
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId |= 0x8000;
showObjects();
2016-12-18 14:13:36 -08:00
_gameRooms[131]._video = 0;
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(149);
p_global->_varF1 = RoomFlags::rf04;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags = DrawFlags::drDrawFlag20;
2016-12-18 13:09:56 -08:00
_normalCursor = true;
maj2();
}
void EdenGame::voirlac() {
perso_t *perso = &kPersons[PER_MORKUS];
Room *room = p_global->_roomPtr;
Area *area = p_global->_areaPtr;
2016-12-04 13:15:38 -08:00
int16 vid = p_global->_curObjectId == Objects::obApple ? 81 : 54;
2016-10-07 00:45:08 +02:00
for (++perso; perso->_roomNum != 0xFFFF; perso++) {
2016-12-11 13:44:58 -08:00
if (perso->_roomNum != p_global->_roomNum)
continue;
vid++;
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != Objects::obApple)
continue; //TODO: pc breaks here
2016-10-07 00:45:08 +02:00
if ((perso->_flags & PersonFlags::pfTypeMask) != PersonFlags::pftMosasaurus)
continue;
2016-10-07 00:45:08 +02:00
if (!(perso->_flags & PersonFlags::pf80))
2016-08-18 13:15:54 +02:00
return;
2016-10-07 00:45:08 +02:00
perso->_flags &= ~PersonFlags::pf80; //TODO: useless? see above
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag8;
p_global->_curAreaFlags |= AreaFlags::afFlag8;
2016-12-15 22:47:29 -08:00
room->_id = 3;
}
2016-12-11 13:44:58 -08:00
debug("sea monster: room = %X, d0 = %X\n", p_global->_roomNum, p_global->_roomImgBank);
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(vid);
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum); //TODO: getting memory trashed here?
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == Objects::obApple)
2016-09-26 23:44:42 +02:00
loseObject(Objects::obApple);
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventF;
2016-09-26 23:44:42 +02:00
showEvents();
}
void EdenGame::gotohall() {
2016-12-11 13:44:58 -08:00
p_global->_prevLocation = p_global->_roomNum & 0xFF;
deplaval((p_global->_roomNum & 0xFF00) | 6);
}
void EdenGame::demitourlabi() {
2016-12-11 13:44:58 -08:00
p_global->_prevLocation = p_global->_roomNum & 0xFF;
p_global->_var100 = 0xFF;
2016-12-19 13:41:00 -08:00
uint16 target = (p_global->_roomNum & 0xFF00) | p_global->_roomPtr->_exits[2];
faire_suivre(target);
2016-12-11 13:44:58 -08:00
p_global->_roomNum = target;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
}
void EdenGame::gotonido() {
2016-12-11 13:44:58 -08:00
p_global->_roomPtr++;
2016-12-04 13:15:38 -08:00
p_global->_eventType = 0;
2016-12-15 22:47:29 -08:00
p_global->_roomImgBank = p_global->_roomPtr->_bank;
p_global->_roomVidNum = p_global->_roomPtr->_video;
p_global->_curRoomFlags = p_global->_roomPtr->_flags;
p_global->_varF1 = p_global->_roomPtr->_flags;
animpiece();
p_global->_var100 = 0;
maj2();
}
void EdenGame::gotoval() {
2016-12-11 13:44:58 -08:00
uint16 target = p_global->_roomNum;
char obj;
rundcurs();
afficher();
2016-09-30 07:48:27 +02:00
_scrollPos = 0;
2016-12-19 22:32:40 -08:00
obj = _curSpot2->_objectId - 14; //TODO
2016-12-11 13:44:58 -08:00
p_global->_prevLocation = target & 0xFF;
deplaval((target & 0xFF00) | obj); //TODO careful!
}
void EdenGame::visiter() {
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(144);
p_global->_varF1 = RoomFlags::rf04;
maj2();
}
void EdenGame::final() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId != 0)
return;
bars_out();
2016-12-18 14:13:36 -08:00
*(int16 *)(_gameRooms + 0x6DC) = 319; //TODO
2016-12-11 13:44:58 -08:00
p_global->_roomImgBank = 319;
2016-09-26 23:44:42 +02:00
playHNM(97);
maj2();
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent12;
2016-09-26 23:44:42 +02:00
showEvents();
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 54;
}
2016-09-27 07:53:50 +02:00
// Original name: goto_nord
void EdenGame::moveNorth() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0)
2016-09-26 23:44:42 +02:00
move(kCryoNorth);
}
2016-09-27 07:53:50 +02:00
// Original name: goto_est
void EdenGame::moveEast() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0)
2016-09-26 23:44:42 +02:00
move(kCryoEast);
}
2016-09-27 07:53:50 +02:00
// Original name: goto_sud
void EdenGame::moveSouth() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0)
2016-09-26 23:44:42 +02:00
move(kCryoSouth);
}
2016-09-27 07:53:50 +02:00
// Original name: goto_ouest
void EdenGame::moveWest() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == 0)
2016-09-26 23:44:42 +02:00
move(kCryoWest);
}
void EdenGame::afficher() {
if (!p_global->_var102 && !p_global->_var103) {
2016-12-18 14:13:36 -08:00
if (_paletteUpdateRequired) {
_paletteUpdateRequired = false;
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
2016-08-18 13:15:54 +02:00
}
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
} else {
if (p_global->_var102)
effet3();
else
effet2();
p_global->_var103 = 0;
p_global->_var102 = 0;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::afficher128() {
2016-12-11 13:44:58 -08:00
if (p_global->_updatePaletteFlag == 16) {
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 129);
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
2016-12-11 13:44:58 -08:00
p_global->_updatePaletteFlag = 0;
} else {
ClearScreen();
fadetoblack128(1);
2016-12-18 14:13:36 -08:00
if (_showBlackBars)
drawBlackBars();
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
fadefromblack128(1);
2016-08-18 13:15:54 +02:00
}
}
2016-09-27 07:53:50 +02:00
// Original name: sauvefrises
void EdenGame::saveFriezes() {
saveTopFrieze(0);
saveBottomFrieze();
}
2016-09-27 07:53:50 +02:00
// Original name: sauvefriseshaut
void EdenGame::saveTopFrieze(int16 x) { // Save top bar
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect = Common::Rect(x, 0, x + 320 - 1, 15);
_underTopBarBackupRect = Common::Rect(0, 0, 320 - 1, 15);
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, p_underBarsView, &_underTopBarScreenRect, &_underTopBarBackupRect);
}
2016-09-27 07:53:50 +02:00
// Original name: sauvefrisesbas
void EdenGame::saveBottomFrieze() { // Save bottom bar
2016-09-30 07:48:27 +02:00
_underBottomBarScreenRect.left = 0;
_underBottomBarScreenRect.right = 320 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, p_underBarsView, &_underBottomBarScreenRect, &_underBottomBarBackupRect);
}
2016-09-27 07:53:50 +02:00
// Original name: restaurefrises
void EdenGame::restoreFriezes() {
restoreTopFrieze();
restoreBottomFrieze();
}
2016-09-27 07:53:50 +02:00
// Original name: restaurefriseshaut
void EdenGame::restoreTopFrieze() {
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.left = _scrollPos;
_underTopBarScreenRect.right = _scrollPos + 320 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underTopBarBackupRect, &_underTopBarScreenRect);
}
2016-09-27 07:53:50 +02:00
// Original name: restaurefrisesbas
void EdenGame::restoreBottomFrieze() {
2016-09-30 07:48:27 +02:00
_underBottomBarScreenRect.left = _scrollPos;
_underBottomBarScreenRect.right = _scrollPos + 320 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underBottomBarBackupRect, &_underBottomBarScreenRect);
}
2016-12-25 02:17:07 -08:00
void EdenGame::useMainBank() {
2016-12-04 14:54:58 -08:00
_bankData = _mainBankBuf;
}
2016-12-25 02:17:07 -08:00
void EdenGame::useCharacterBank() {
_bankData = _characterBankData;
}
2016-10-07 23:06:10 +02:00
// Original name: use_bank
void EdenGame::useBank(int16 bank) {
if (bank > 2500)
2016-10-07 23:06:10 +02:00
error("attempt to load bad bank %d", bank);
2016-12-18 14:13:36 -08:00
_bankData = _bankDataBuf;
2016-10-07 23:06:10 +02:00
if (_curBankNum != bank) {
2016-12-18 14:13:36 -08:00
loadRawFile(bank, _bankDataBuf);
verifh(_bankDataBuf);
2016-10-07 23:06:10 +02:00
_curBankNum = bank;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::sundcurs(int16 x, int16 y) {
2016-09-30 07:48:27 +02:00
byte *keep = _cursKeepBuf;
_cursKeepPos = Common::Point(x - 4, y - 4);
byte *scr = p_mainview_buf + _cursKeepPos.x + _cursKeepPos.y * 640;
for (int16 h = 48; h--;) {
for (int16 w = 48; w--;)
*keep++ = *scr++;
scr += 640 - 48;
}
2016-12-18 13:09:56 -08:00
_cursorSaved = true;
}
void EdenGame::rundcurs() {
2016-09-30 07:48:27 +02:00
byte *keep = _cursKeepBuf;
byte *scr = p_mainview_buf + _cursKeepPos.x + _cursKeepPos.y * 640;
2016-12-18 13:09:56 -08:00
if (!_cursorSaved || (_cursKeepPos == Common::Point(-1, -1))) //TODO ...
return;
for (int16 h = 48; h--;) {
for (int16 w = 48; w--;)
*scr++ = *keep++;
scr += 640 - 48;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::noclipax(int16 index, int16 x, int16 y) {
2016-12-04 14:26:44 -08:00
byte *pix = _bankData;
2016-09-14 23:48:01 +02:00
byte *scr = p_mainview_buf + x + y * 640;
byte h0, h1, mode;
int16 w, h;
if (_curBankNum != 117 && !_noPalette) {
2016-12-04 14:54:58 -08:00
if (READ_LE_UINT16(pix) > 2)
readPalette(pix + 2);
}
2016-12-04 14:54:58 -08:00
pix += READ_LE_UINT16(pix);
pix += READ_LE_UINT16(pix + index * 2);
2016-09-14 23:48:01 +02:00
// int16 height:9
// int16 pad:6;
// int16 flag:1;
h0 = *pix++;
h1 = *pix++;
w = ((h1 & 1) << 8) | h0;
h = *pix++;
mode = *pix++;
debug("- draw sprite %d at %d:%d, %dx%d", index, x, y, w, h);
if (mode != 0xFF && mode != 0xFE)
return;
if (y + h > 200)
h -= (y + h - 200);
if (h1 & 0x80) {
// compressed
for (; h-- > 0;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = w; ww > 0;) {
2016-09-14 23:48:01 +02:00
byte c = *pix++;
if (c >= 0x80) {
if (c == 0x80) {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
if (fill == 0) {
scr += 128 + 1;
ww -= 128 + 1;
} else {
2016-09-14 23:48:01 +02:00
byte run;
*scr++ = fill; //TODO: wha?
*scr++ = fill;
ww -= 128 + 1;
for (run = 127; run--;)
*scr++ = fill;
}
} else {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
byte run = 255 - c + 2;
ww -= run;
if (fill == 0)
scr += run;
else
for (; run--;)
*scr++ = fill;
}
} else {
2016-09-14 23:48:01 +02:00
byte run = c + 1;
ww -= run;
for (; run--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
if (p == 0)
scr++;
else
*scr++ = p;
}
}
2016-08-18 13:15:54 +02:00
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
} else {
// uncompressed
for (; h--;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = w; ww--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
if (p == 0)
scr++;
else
*scr++ = p;
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::noclipax_avecnoir(int16 index, int16 x, int16 y) {
2016-12-04 14:26:44 -08:00
byte *pix = _bankData;
2016-09-14 23:48:01 +02:00
byte *scr = p_mainview_buf + x + y * 640;
byte h0, h1, mode;
int16 w, h;
2016-10-07 23:06:10 +02:00
if (_curBankNum != 117) {
2016-12-04 14:54:58 -08:00
if (READ_LE_UINT16(pix) > 2)
readPalette(pix + 2);
}
2016-12-04 14:54:58 -08:00
pix += READ_LE_UINT16(pix);
pix += READ_LE_UINT16(pix + index * 2);
2016-09-14 23:48:01 +02:00
// int16 height:9
// int16 pad:6;
// int16 flag:1;
h0 = *pix++;
h1 = *pix++;
w = ((h1 & 1) << 8) | h0;
h = *pix++;
mode = *pix++;
if (mode != 0xFF && mode != 0xFE)
return;
if (y + h > 200)
h -= (y + h - 200);
if (h1 & 0x80) {
// compressed
for (; h-- > 0;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = w; ww > 0;) {
2016-09-14 23:48:01 +02:00
byte c = *pix++;
if (c >= 0x80) {
if (c == 0x80) {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
byte run;
*scr++ = fill; //TODO: wha?
*scr++ = fill;
ww -= 128 + 1;
for (run = 127; run--;)
*scr++ = fill;
} else {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
byte run = 255 - c + 2;
ww -= run;
for (; run--;)
*scr++ = fill;
}
} else {
2016-09-14 23:48:01 +02:00
byte run = c + 1;
ww -= run;
for (; run--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
*scr++ = p;
}
}
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
} else {
// uncompressed
for (; h--;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = w; ww--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
*scr++ = p;
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
}
}
2016-08-18 13:15:54 +02:00
2016-09-14 23:48:01 +02:00
void EdenGame::getglow(int16 x, int16 y, int16 w, int16 h) {
byte *scr = p_mainview_buf + x + y * 640;
2016-12-18 14:13:36 -08:00
byte *gl = _glowBuffer;
_glowX = x;
_glowY = y;
_glowW = w;
_glowH = h;
for (; h--;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = w; ww--;)
*gl++ = *scr++;
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::unglow() {
2016-12-18 14:13:36 -08:00
byte *gl = _glowBuffer;
byte *scr = p_mainview_buf + _glowX + _glowY * 640;
if (_glowX < 0 || _glowY < 0) //TODO: move it up
return;
for (; _glowH--;) {
2016-09-14 23:48:01 +02:00
int16 ww;
for (ww = _glowW; ww--;)
*scr++ = *gl++;
scr += 640 - _glowW;
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::glow(int16 index) {
// byte pixbase;
2016-12-04 14:26:44 -08:00
byte *pix = _bankData;
index += 9;
2016-12-04 14:54:58 -08:00
pix += READ_LE_UINT16(pix);
pix += READ_LE_UINT16(pix + index * 2);
2016-09-14 23:48:01 +02:00
// int16 height:9
// int16 pad:6;
// int16 flag:1;
2016-10-24 22:02:43 +02:00
byte h0 = *pix++;
byte h1 = *pix++;
int16 w = ((h1 & 1) << 8) | h0;
int16 h = *pix++;
byte mode = *pix++;
if (mode != 0xFF && mode != 0xFE)
return;
2016-12-18 13:09:56 -08:00
int16 x = _cursorPosX + _scrollPos - 38;
int16 y = _cursorPosY - 28;
2016-12-11 13:44:58 -08:00
int16 ex = p_global->_frescoeWidth + 320;
if (x + w <= 0 || x >= ex || y + h <= 0 || y >= 176)
return;
int16 dx;
if (x < 0) {
dx = -x;
x = 0;
} else if (x + w > ex)
dx = x + w - ex;
else
dx = 0;
int16 dy;
if (y < 16) {
dy = 16 - y;
y = 16;
} else if (y + h > 175)
dy = y + h - 175;
else
dy = 0;
int16 pstride = dx;
int16 sstride = 640 - (w - dx);
if (y == 16)
pix += w * dy;
if (x == 0)
pix += dx;
byte *scr = p_mainview_buf + x + y * 640;
w -= dx;
h -= dy;
getglow(x, y, w, h);
for (; h--;) {
for (int16 ww = w; ww--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
if (p == 0)
scr++;
else
*scr++ += p << 4;
2016-08-18 13:15:54 +02:00
}
pix += pstride;
scr += sstride;
}
}
void EdenGame::readPalette(byte *ptr) {
bool doit = true;
2016-12-25 13:45:47 -08:00
color3_t pal_entry;
while (doit) {
2016-09-14 23:48:01 +02:00
uint16 idx = *ptr++;
if (idx != 0xFF) {
2016-09-14 23:48:01 +02:00
uint16 cnt = *ptr++;
while (cnt--) {
if (idx == 0) {
pal_entry.r = 0;
pal_entry.g = 0;
pal_entry.b = 0;
ptr += 3;
} else {
pal_entry.r = *ptr++ << 10;
pal_entry.g = *ptr++ << 10;
pal_entry.b = *ptr++ << 10;
2016-08-18 13:15:54 +02:00
}
2016-12-25 13:45:47 -08:00
CLPalette_SetRGBColor(_globalPalette, idx, &pal_entry);
idx++;
2016-08-18 13:15:54 +02:00
}
} else
doit = false;
2016-08-18 13:15:54 +02:00
}
}
// Original name: spritesurbulle
void EdenGame::spriteOnSubtitle(int16 index, int16 x, int16 y) {
2016-12-04 14:26:44 -08:00
byte *pix = _bankData;
2016-09-14 23:48:01 +02:00
byte *scr = p_subtitlesview_buf + x + y * subtitles_x_width;
2016-12-04 14:54:58 -08:00
if ((_curBankNum != 117) && (READ_LE_UINT16(pix) > 2))
readPalette(pix + 2);
2016-12-04 14:54:58 -08:00
pix += READ_LE_UINT16(pix);
pix += READ_LE_UINT16(pix + index * 2);
2016-09-14 23:48:01 +02:00
// int16 height:9
// int16 pad:6;
// int16 flag:1;
byte h0 = *pix++;
byte h1 = *pix++;
int16 w = ((h1 & 1) << 8) | h0;
int16 h = *pix++;
byte mode = *pix++;
if (mode != 0xFF && mode != 0xFE)
return;
if (h1 & 0x80) {
// compressed
for (; h-- > 0;) {
for (int16 ww = w; ww > 0;) {
2016-09-14 23:48:01 +02:00
byte c = *pix++;
if (c >= 0x80) {
if (c == 0x80) {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
if (fill == 0) {
scr += 128 + 1;
ww -= 128 + 1;
} else {
2016-09-14 23:48:01 +02:00
byte run;
2016-08-18 13:15:54 +02:00
*scr++ = fill; //TODO: wha?
*scr++ = fill;
ww -= 128 + 1;
for (run = 127; run--;)
*scr++ = fill;
}
} else {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
byte run = 255 - c + 2;
2016-08-18 13:15:54 +02:00
ww -= run;
if (fill == 0)
scr += run;
else {
for (; run--;)
*scr++ = fill;
}
}
} else {
2016-09-14 23:48:01 +02:00
byte run = c + 1;
ww -= run;
for (; run--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
if (p == 0)
scr++;
else
2016-08-18 13:15:54 +02:00
*scr++ = p;
}
}
}
scr += subtitles_x_width - w;
}
} else {
// uncompressed
for (; h--;) {
for (int16 ww = w; ww--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
if (p == 0)
scr++;
else
2016-08-18 13:15:54 +02:00
*scr++ = p;
}
scr += subtitles_x_width - w;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::bars_out() {
2016-12-18 14:13:36 -08:00
if (_showBlackBars)
return;
afficher();
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.left = _scrollPos;
_underTopBarScreenRect.right = _scrollPos + 320 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, p_underBarsView, &_underTopBarScreenRect, &_underTopBarBackupRect);
2016-09-30 07:48:27 +02:00
_underBottomBarScreenRect.left = _underTopBarScreenRect.left;
_underBottomBarScreenRect.right = _underTopBarScreenRect.right;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, p_underBarsView, &_underBottomBarScreenRect, &_underBottomBarBackupRect);
int16 r19 = 14; // TODO - init in decl?
int16 r20 = 176;
int16 r25 = 14;
int16 r24 = 21;
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.left = 0;
_underTopBarScreenRect.right = 320 - 1;
_underTopBarBackupRect.left = _scrollPos;
_underTopBarBackupRect.right = _scrollPos + 320 - 1;
unsigned int *scr40, *scr41, *scr42;
while (r24 > 0) {
if (r25 > 0) {
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.top = 16 - r25;
_underTopBarScreenRect.bottom = 16 - 1;
_underTopBarBackupRect.top = 0;
_underTopBarBackupRect.bottom = r25 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underTopBarScreenRect, &_underTopBarBackupRect);
scr40 = ((unsigned int *)p_mainview_buf) + r19 * 640 / 4;
scr41 = scr40 + 640 / 4;
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 320; i += 4) {
*scr40++ = 0;
*scr41++ = 0;
}
}
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.top = 16;
_underTopBarScreenRect.bottom = r24 + 16 - 1;
_underTopBarBackupRect.top = 200 - r24;
_underTopBarBackupRect.bottom = 200 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underTopBarScreenRect, &_underTopBarBackupRect);
scr40 = ((unsigned int *)p_mainview_buf) + r20 * 640 / 4;
scr41 = scr40 + 640 / 4;
scr42 = scr41 + 640 / 4;
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 320; i += 4) {
*scr40++ = 0;
*scr41++ = 0;
*scr42++ = 0;
2016-08-18 13:15:54 +02:00
}
r19 -= 2;
r20 += 3;
r25 -= 2;
r24 -= 3;
afficher();
2016-08-18 13:15:54 +02:00
}
scr40 = (unsigned int *)p_mainview_buf;
scr41 = scr40 + 640 / 4;
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 320; i += 4) {
*scr40++ = 0;
*scr41++ = 0;
}
scr40 = ((unsigned int *)p_mainview_buf) + r20 * 640 / 4;
scr41 = scr40 + 640 / 4;
scr42 = scr41 + 640 / 4;
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 320; i += 4) {
*scr40++ = 0;
*scr41++ = 0;
*scr42++ = 0;
}
afficher();
2016-09-30 07:48:27 +02:00
initRects();
2016-12-18 14:13:36 -08:00
_showBlackBars = true;
}
// Original name: bars_in
void EdenGame::showBars() {
2016-12-18 14:13:36 -08:00
if (!_showBlackBars)
return;
drawBlackBars();
int16 r29 = 2;
int16 r28 = 2;
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.left = 0;
_underTopBarScreenRect.right = 320 - 1;
_underTopBarBackupRect.left = _scrollPos;
_underTopBarBackupRect.right = _scrollPos + 320 - 1;
while (r28 < 24) {
if (r29 <= 16) {
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.top = 16 - r29;
_underTopBarScreenRect.bottom = 16 - 1;
_underTopBarBackupRect.top = 0;
_underTopBarBackupRect.bottom = r29 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underTopBarScreenRect, &_underTopBarBackupRect);
2016-08-18 13:15:54 +02:00
}
2016-09-30 07:48:27 +02:00
_underTopBarScreenRect.top = 16;
_underTopBarScreenRect.bottom = 16 + r28;
_underTopBarBackupRect.top = 200 - 1 - r28;
_underTopBarBackupRect.bottom = 200 - 1;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underBarsView, _mainView, &_underTopBarScreenRect, &_underTopBarBackupRect);
r29 += 2;
r28 += 3;
afficher();
2016-08-18 13:15:54 +02:00
}
2016-09-30 07:48:27 +02:00
initRects();
2016-12-18 14:13:36 -08:00
_showBlackBars = false;
}
2016-08-18 13:15:54 +02:00
void EdenGame::sauvefondbouche() {
2016-12-25 13:45:47 -08:00
rect_src.left = _curPersoRect->left;
rect_src.top = _curPersoRect->top;
rect_src.right = _curPersoRect->right;
rect_src.bottom = _curPersoRect->bottom;
rect_dst.left = _curPersoRect->left + 320;
rect_dst.top = _curPersoRect->top;
rect_dst.right = _curPersoRect->right + 320;
rect_dst.bottom = _curPersoRect->bottom;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, _mainView, &rect_src, &rect_dst);
_backgroundSaved = true;
}
2016-08-18 13:15:54 +02:00
void EdenGame::restaurefondbouche() {
2016-12-25 13:45:47 -08:00
rect_src.left = _curPersoRect->left;
rect_src.top = _curPersoRect->top;
rect_src.right = _curPersoRect->right;
rect_src.bottom = _curPersoRect->bottom;
rect_dst.left = _curPersoRect->left + 320;
rect_dst.top = _curPersoRect->top;
rect_dst.right = _curPersoRect->right + 320;
rect_dst.bottom = _curPersoRect->bottom;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, _mainView, &rect_dst, &rect_src);
}
2016-08-18 13:15:54 +02:00
// Original name : blackbars
void EdenGame::drawBlackBars() {
2016-09-14 23:48:01 +02:00
byte *scr = p_mainview_buf;
for (int16 y = 0; y < 16; y++) {
for (int16 x = 0; x < 640; x++)
*scr++ = 0;
}
scr += 640 * (200 - 16 - 24);
for (int16 y = 0; y < 24; y++) {
for (int16 x = 0; x < 640; x++)
*scr++ = 0;
}
}
2016-08-18 13:15:54 +02:00
void EdenGame::drawTopScreen() { // Draw top bar (location / party / map)
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawTopScreen;
2016-10-07 23:06:10 +02:00
useBank(314);
noclipax(36, 83, 0);
2016-12-15 22:47:29 -08:00
noclipax(p_global->_areaPtr->_num - 1, 0, 0);
noclipax(23, 145, 0);
for (perso_t *perso = &kPersons[PER_DINA]; perso != &kPersons[PER_UNKN_156]; perso++) {
2016-10-07 00:45:08 +02:00
if ((perso->_flags & PersonFlags::pfInParty) && !(perso->_flags & PersonFlags::pf80))
noclipax(perso->_targetLoc + 18, perso->_lastLoc + 120, 0);
}
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = -1;
_adamMapMarkPos.y = -1;
2016-09-29 00:32:49 +02:00
displayValleyMap();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
}
2016-08-18 13:15:54 +02:00
2016-09-29 00:32:49 +02:00
// Original name: affplanval
void EdenGame::displayValleyMap() { // Draw mini-map
2016-12-15 22:47:29 -08:00
if (p_global->_areaPtr->_type == AreaType::atValley) {
noclipax(p_global->_areaPtr->_num + 9, 266, 1);
for (perso_t *perso = &kPersons[PER_UNKN_18C]; perso->_roomNum != 0xFFFF; perso++) {
2016-12-04 14:26:44 -08:00
if (((perso->_roomNum >> 8) == p_global->_areaNum)
2016-10-07 00:45:08 +02:00
&& !(perso->_flags & PersonFlags::pf80) && (perso->_flags & PersonFlags::pf20))
displayMapMark(33, perso->_roomNum & 0xFF);
}
2016-12-15 22:47:29 -08:00
if (p_global->_areaPtr->_citadelLevel)
displayMapMark(34, p_global->_areaPtr->_citadelRoomPtr->_location);
2016-09-27 07:53:50 +02:00
saveTopFrieze(0);
2016-12-11 13:44:58 -08:00
int16 loc = p_global->_roomNum & 0xFF;
if (loc >= 16)
2016-09-29 00:32:49 +02:00
displayAdamMapMark(loc);
2016-09-27 07:53:50 +02:00
restoreTopFrieze();
} else {
2016-09-27 07:53:50 +02:00
saveTopFrieze(0);
restoreTopFrieze();
}
}
2016-08-18 13:15:54 +02:00
2016-09-29 00:32:49 +02:00
// Original name: affrepere
void EdenGame::displayMapMark(int16 index, int16 location) {
noclipax(index, 269 + location % 16 * 4, 2 + (location - 16) / 16 * 3);
}
2016-08-18 13:15:54 +02:00
2016-09-29 00:32:49 +02:00
// Original name: affrepereadam
void EdenGame::displayAdamMapMark(int16 location) {
2016-09-14 23:48:01 +02:00
int16 x = 269;
int16 y = 2;
2016-09-29 00:32:49 +02:00
restoreAdamMapMark();
if (location > 15 && location < 76) {
x += (location & 15) * 4;
y += ((location - 16) >> 4) * 3;
2016-09-29 00:32:49 +02:00
saveAdamMapMark(x, y);
byte *pix = p_underBarsView->_bufferPtr;
int16 w = p_underBarsView->_width;
pix += x + w * y;
pix[1] = 0xC3;
pix[2] = 0xC3;
pix += w;
pix[0] = 0xC3;
pix[1] = 0xC3;
pix[2] = 0xC3;
pix[3] = 0xC3;
pix += w;
pix[1] = 0xC3;
pix[2] = 0xC3;
}
}
2016-08-18 13:15:54 +02:00
2016-09-29 00:32:49 +02:00
// Original name: rest_repadam
void EdenGame::restoreAdamMapMark() {
2016-09-30 07:48:27 +02:00
if (_adamMapMarkPos.x == -1 && _adamMapMarkPos.y == -1)
return;
2016-09-29 00:32:49 +02:00
2016-09-30 07:48:27 +02:00
int16 x = _adamMapMarkPos.x;
int16 y = _adamMapMarkPos.y;
byte *pix = p_underBarsView->_bufferPtr;
int16 w = p_underBarsView->_width;
pix += x + w * y;
2016-09-30 07:48:27 +02:00
pix[1] = _oldPix[0];
pix[2] = _oldPix[1];
pix += w;
2016-09-30 07:48:27 +02:00
pix[0] = _oldPix[2];
pix[1] = _oldPix[3];
pix[2] = _oldPix[4];
pix[3] = _oldPix[5];
pix += w;
2016-09-30 07:48:27 +02:00
pix[1] = _oldPix[6];
pix[2] = _oldPix[7];
}
2016-09-29 00:32:49 +02:00
// Original name: save_repadam
void EdenGame::saveAdamMapMark(int16 x, int16 y) {
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = x;
_adamMapMarkPos.y = y;
byte *pix = p_underBarsView->_bufferPtr;
int16 w = p_underBarsView->_width;
pix += x + w * y;
2016-09-30 07:48:27 +02:00
_oldPix[0] = pix[1];
_oldPix[1] = pix[2];
pix += w;
2016-09-30 07:48:27 +02:00
_oldPix[2] = pix[0];
_oldPix[3] = pix[1];
_oldPix[4] = pix[2];
_oldPix[5] = pix[3];
pix += w;
2016-09-30 07:48:27 +02:00
_oldPix[6] = pix[1];
_oldPix[7] = pix[2];
}
2016-09-29 00:32:49 +02:00
bool EdenGame::istrice(int16 roomNum) {
char loc = roomNum & 0xFF;
2016-09-14 23:48:01 +02:00
int16 area = roomNum & 0xFF00;
2016-09-29 00:32:49 +02:00
for (perso_t *perso = &kPersons[PER_UNKN_18C]; perso != &kPersons[PER_UNKN_372]; perso++) {
2016-10-07 00:45:08 +02:00
if ((perso->_flags & PersonFlags::pf80) || (perso->_flags & PersonFlags::pfTypeMask) != PersonFlags::pftTriceraptor)
continue;
2016-10-07 00:45:08 +02:00
if (perso->_roomNum == (area | (loc - 16)))
2016-09-29 00:32:49 +02:00
return true;
2016-10-07 00:45:08 +02:00
if (perso->_roomNum == (area | (loc + 16)))
2016-09-29 00:32:49 +02:00
return true;
2016-10-07 00:45:08 +02:00
if (perso->_roomNum == (area | (loc - 1)))
2016-09-29 00:32:49 +02:00
return true;
2016-10-07 00:45:08 +02:00
if (perso->_roomNum == (area | (loc + 1)))
2016-09-29 00:32:49 +02:00
return true;
}
2016-09-29 00:32:49 +02:00
return false;
}
bool EdenGame::istyran(int16 roomNum) {
char loc = roomNum & 0xFF;
2016-09-14 23:48:01 +02:00
int16 area = roomNum & 0xFF00;
// TODO: orig bug: this ptr is not initialized when first called from getsalle
// PC version scans kPersons[] directly and is not affected
if (!_tyranPtr)
return false;
for (; _tyranPtr->_roomNum != 0xFFFF; _tyranPtr++) {
if (_tyranPtr->_flags & PersonFlags::pf80)
continue;
if (_tyranPtr->_roomNum == (area | (loc - 16)))
return true;
if (_tyranPtr->_roomNum == (area | (loc + 16)))
return true;
if (_tyranPtr->_roomNum == (area | (loc - 1)))
return true;
if (_tyranPtr->_roomNum == (area | (loc + 1)))
return true;
}
return false;
}
void EdenGame::istyranval(Area *area) {
2016-12-15 22:47:29 -08:00
byte areaNum = area->_num;
2016-12-04 14:26:44 -08:00
area->_flags &= ~AreaFlags::HasTyrann;
for (perso_t *perso = &kPersons[PER_UNKN_372]; perso->_roomNum != 0xFFFF; perso++) {
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pf80)
continue;
2016-10-07 00:45:08 +02:00
if ((perso->_roomNum >> 8) == areaNum) {
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::HasTyrann;
break;
2016-08-18 13:15:54 +02:00
}
}
}
2016-09-29 00:32:49 +02:00
char EdenGame::getDirection(perso_t *perso) {
char dir = -1;
2016-10-07 00:45:08 +02:00
byte trgLoc = perso->_targetLoc;
byte curLoc = perso->_roomNum & 0xFF; //TODO name
if (curLoc != trgLoc) {
curLoc &= 0xF;
trgLoc &= 0xF;
if (curLoc != trgLoc) {
dir = 2;
if (curLoc > trgLoc)
dir = 5;
}
2016-10-07 00:45:08 +02:00
trgLoc = perso->_targetLoc;
curLoc = perso->_roomNum & 0xFF;
curLoc &= 0xF0;
trgLoc &= 0xF0;
if (curLoc != trgLoc) {
if (curLoc > trgLoc)
dir++;
dir++;
2016-08-18 13:15:54 +02:00
}
}
return dir;
}
2016-09-29 00:32:49 +02:00
// Original name: caselibre
bool EdenGame::canMoveThere(char loc, perso_t *perso) {
Room *room = p_global->_citaAreaFirstRoom;
2016-10-07 00:45:08 +02:00
if (loc <= 0x10 || loc > 76 || (loc & 0xF) >= 12 || loc == perso->_lastLoc)
2016-09-29 00:32:49 +02:00
return false;
2016-10-07 00:45:08 +02:00
int16 roomNum = (perso->_roomNum & ~0xFF) | loc; //TODO: danger! signed
2016-12-11 13:44:58 -08:00
if (roomNum == p_global->_roomNum)
2016-09-29 00:32:49 +02:00
return false;
2016-12-15 22:47:29 -08:00
for (; room->_id != 0xFF; room++) {
if (room->_location != loc)
continue;
2016-12-15 22:47:29 -08:00
if (!(room->_flags & RoomFlags::rf01))
2016-09-29 00:32:49 +02:00
return false;
2016-10-07 00:45:08 +02:00
for (perso = &kPersons[PER_UNKN_18C]; perso->_roomNum != 0xFFFF; perso++) {
if (perso->_flags & PersonFlags::pf80)
continue;
2016-10-07 00:45:08 +02:00
if (perso->_roomNum == roomNum)
break;
2016-08-18 13:15:54 +02:00
}
2016-10-07 00:45:08 +02:00
if (perso->_roomNum != 0xFFFF)
2016-09-29 00:32:49 +02:00
return false;
return true;
}
2016-09-29 00:32:49 +02:00
return false;
}
2016-09-29 00:32:49 +02:00
// Original name: melange1
void EdenGame::scramble1(uint8 elem[4]) {
if (_vm->_rnd->getRandomNumber(1) & 1)
2016-09-29 00:32:49 +02:00
SWAP(elem[1], elem[2]);
}
2016-09-29 00:32:49 +02:00
// Original name melange2
void EdenGame::scramble2(uint8 elem[4]) {
if (_vm->_rnd->getRandomNumber(1) & 1)
2016-09-29 00:32:49 +02:00
SWAP(elem[0], elem[1]);
if (_vm->_rnd->getRandomNumber(1) & 1)
2016-09-29 00:32:49 +02:00
SWAP(elem[2], elem[3]);
}
2016-09-29 00:32:49 +02:00
void EdenGame::melangedir() {
scramble1(tab_2CB1E[0]);
scramble1(tab_2CB1E[1]);
scramble1(tab_2CB1E[2]);
scramble2(tab_2CB1E[3]);
scramble2(tab_2CB1E[4]);
scramble1(tab_2CB1E[5]);
scramble2(tab_2CB1E[6]);
scramble2(tab_2CB1E[7]);
}
bool EdenGame::naitredino(char persoType) {
2016-10-07 00:45:08 +02:00
for (perso_t *perso = &kPersons[PER_MORKUS]; (++perso)->_roomNum != 0xFFFF;) {
char areaNum = perso->_roomNum >> 8;
2016-12-18 13:09:56 -08:00
if (areaNum != p_global->_citadelAreaNum)
continue;
2016-10-07 00:45:08 +02:00
if ((perso->_flags & PersonFlags::pf80) && (perso->_flags & PersonFlags::pfTypeMask) == persoType) {
perso->_flags &= ~PersonFlags::pf80;
2016-09-29 00:32:49 +02:00
return true;
}
}
2016-09-29 00:32:49 +02:00
return false;
}
// Original name: newcita
void EdenGame::newCitadel(char area, int16 level, Room *room) {
Citadel *cita = _citadelList;
while (cita->_id < level)
cita++;
2016-12-15 22:47:29 -08:00
uint16 index = ((room->_flags & 0xC0) >> 6); //TODO: this is very wrong
if (area == 4 || area == 6)
index++;
room->_bank = cita->_bank[index];
room->_video = cita->_video[index];
2016-12-15 22:47:29 -08:00
room->_flags |= RoomFlags::rf02;
}
2016-09-14 23:48:01 +02:00
void EdenGame::citaevol(int16 level) {
Room *room = p_global->_curAreaPtr->_citadelRoomPtr;
perso_t *perso = &kPersons[PER_UNKN_372];
2016-12-15 22:47:29 -08:00
byte loc = room->_location;
2016-12-18 13:09:56 -08:00
if (level >= 80 && !istrice((p_global->_citadelAreaNum << 8) | loc)) {
2016-12-15 22:47:29 -08:00
room->_level = 79;
return;
}
if (level > 160)
level = 160;
2016-12-15 22:47:29 -08:00
if (room->_level < 64 && level >= 64 && naitredino(PersonFlags::pftTriceraptor)) {
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr->_flags |= AreaFlags::HasTriceraptors;
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnTriceraptorsIn);
}
2016-12-15 22:47:29 -08:00
if (room->_level < 40 && level >= 40 && naitredino(PersonFlags::pftVelociraptor)) {
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr->_flags |= AreaFlags::HasVelociraptors;
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnVelociraptorsIn);
}
2016-12-15 22:47:29 -08:00
room->_level = level;
2016-12-18 13:09:56 -08:00
newCitadel(p_global->_citadelAreaNum, level, room);
2016-12-15 22:47:29 -08:00
byte speed = kDinoSpeedForCitaLevel[room->_level >> 4];
2016-10-07 00:45:08 +02:00
for (; perso->_roomNum != 0xFFFF; perso++) {
if (perso->_flags & PersonFlags::pf80)
continue;
2016-12-18 13:09:56 -08:00
if ((perso->_roomNum >> 8) == p_global->_citadelAreaNum && perso->_targetLoc == loc)
2016-10-07 00:45:08 +02:00
perso->_speed = speed;
}
}
2016-12-15 22:47:29 -08:00
// Original name: citacapoute
void EdenGame::destroyCitadelRoom(int16 roomNum) {
perso_t *perso = &kPersons[PER_UNKN_18C];
Room *room = p_global->_curAreaPtr->_citadelRoomPtr;
2016-12-15 22:47:29 -08:00
room->_flags |= RoomFlags::rf01;
room->_flags &= ~RoomFlags::rfHasCitadel;
room->_bank = 193;
room->_video = 0;
room->_level = 0;
p_global->_curAreaPtr->_citadelLevel = 0;
p_global->_curAreaPtr->_citadelRoomPtr = 0;
roomNum = (roomNum & ~0xFF) | room->_location;
2016-10-07 00:45:08 +02:00
for (; perso->_roomNum != 0xFFFF; perso++) {
if (perso->_roomNum == roomNum) {
perso->_flags &= ~PersonFlags::pf80;
2016-12-11 13:44:58 -08:00
removeInfo((roomNum >> 8) + ValleyNews::vnTyrannIn);
break;
}
}
}
2016-12-15 22:47:29 -08:00
// Original name: buildcita
void EdenGame::buildCitadel() {
Area *area = p_global->_areaPtr;
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr = p_global->_areaPtr;
2016-12-15 22:47:29 -08:00
if (area->_citadelRoomPtr)
destroyCitadelRoom(p_global->_roomNum);
p_global->_var6A = p_global->_var69;
p_global->_narratorSequence = p_global->_var69 | 0x80;
2016-12-15 22:47:29 -08:00
area->_citadelRoomPtr = p_global->_roomPtr;
p_global->_roomPtr->_flags &= ~RoomFlags::rf01;
p_global->_roomPtr->_flags |= RoomFlags::rfHasCitadel;
p_global->_roomPtr->_level = 32;
newCitadel(p_global->_areaNum, 32, p_global->_roomPtr);
2016-12-04 14:26:44 -08:00
area->_flags &= ~AreaFlags::TyrannSighted;
if (!(area->_flags & AreaFlags::afFlag8000)) {
if (p_global->_phaseNum == 304 || p_global->_phaseNum != 384) //TODO: wha
2016-12-19 22:32:40 -08:00
handleEloiReturn();
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag8000;
}
2016-12-11 13:44:58 -08:00
p_global->_roomCharacterPtr->_flags |= PersonFlags::pf80;
2016-12-18 13:09:56 -08:00
p_global->_citadelAreaNum = p_global->_areaNum;
naitredino(1);
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnCitadelLost);
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannLost);
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum == 193 && p_global->_areaNum == Areas::arUluru)
bigphase1();
}
void EdenGame::citatombe(char level) {
if (level)
2016-12-18 13:09:56 -08:00
newCitadel(p_global->_citadelAreaNum, level, p_global->_curAreaPtr->_citadelRoomPtr);
else {
2016-12-18 13:09:56 -08:00
destroyCitadelRoom(p_global->_citadelAreaNum << 8);
addInfo(p_global->_citadelAreaNum + ValleyNews::vnCitadelLost);
}
}
void EdenGame::constcita() {
2016-12-18 13:09:56 -08:00
// Room *room = p_global->_curAreaPtr->_citadelRoomPtr; //TODO: wrong? chk below
// byte id = room->_location;
2016-12-15 22:47:29 -08:00
if (!p_global->_curAreaPtr->_citadelLevel || !p_global->_curAreaPtr->_citadelRoomPtr)
return;
2016-09-29 00:32:49 +02:00
Room *room = p_global->_curAreaPtr->_citadelRoomPtr; //TODO: copied here by me
2016-12-15 22:47:29 -08:00
byte loc = room->_location;
_tyranPtr = &kPersons[PER_UNKN_372];
2016-12-18 13:09:56 -08:00
if (istyran((p_global->_citadelAreaNum << 8) | loc)) {
2016-12-11 13:44:58 -08:00
if (!(p_global->_curAreaPtr->_flags & AreaFlags::TyrannSighted)) {
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnTyrannIn);
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr->_flags |= AreaFlags::TyrannSighted;
}
2016-12-15 22:47:29 -08:00
byte level = room->_level - 1;
if (level < 32)
level = 32;
2016-12-15 22:47:29 -08:00
room->_level = level;
citatombe(level);
} else {
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr->_flags &= ~AreaFlags::TyrannSighted;
2016-12-15 22:47:29 -08:00
citaevol(room->_level + 1);
}
}
2016-12-18 13:09:56 -08:00
// Original name: depladino
void EdenGame::moveDino(perso_t *perso) {
2016-10-08 21:21:21 +02:00
int dir = getDirection(perso);
if (dir != -1) {
melangedir();
uint8 *dirs = tab_2CB1E[dir];
2016-10-07 00:45:08 +02:00
byte loc = perso->_roomNum & 0xFF;
uint8 dir2 = *dirs++;
if (dir2 & 0x80)
dir2 = -(dir2 & ~0x80);
dir2 += loc;
2016-09-29 00:32:49 +02:00
if (canMoveThere(dir2, perso))
goto ok;
dir2 = *dirs++;
if (dir2 & 0x80)
dir2 = -(dir2 & ~0x80);
dir2 += loc;
2016-09-29 00:32:49 +02:00
if (canMoveThere(dir2, perso))
goto ok;
dir2 = *dirs++;
if (dir2 & 0x80)
dir2 = -(dir2 & ~0x80);
dir2 += loc;
2016-09-29 00:32:49 +02:00
if (canMoveThere(dir2, perso))
goto ok;
dir2 = *dirs++;
if (dir2 & 0x80)
dir2 = -(dir2 & ~0x80);
dir2 += loc;
2016-09-29 00:32:49 +02:00
if (canMoveThere(dir2, perso))
goto ok;
2016-10-07 00:45:08 +02:00
dir2 = perso->_lastLoc;
perso->_lastLoc = 0;
2016-09-29 00:32:49 +02:00
if (!canMoveThere(dir2, perso))
return;
ok:
;
2016-10-07 00:45:08 +02:00
perso->_lastLoc = perso->_roomNum & 0xFF;
perso->_roomNum &= ~0xFF;
perso->_roomNum |= dir2 & 0xFF;
if (perso->_targetLoc - 16 == (perso->_roomNum & 0xFF))
perso->_targetLoc = 0;
if (perso->_targetLoc + 16 == (perso->_roomNum & 0xFF))
perso->_targetLoc = 0;
if (perso->_targetLoc - 1 == (perso->_roomNum & 0xFF))
perso->_targetLoc = 0;
if (perso->_targetLoc + 1 == (perso->_roomNum & 0xFF))
perso->_targetLoc = 0;
} else
2016-10-07 00:45:08 +02:00
perso->_targetLoc = 0;
}
2016-12-18 13:09:56 -08:00
// Original name: deplaalldino
void EdenGame::moveAllDino() {
for (perso_t *perso = &kPersons[PER_UNKN_18C]; perso->_roomNum != 0xFFFF; perso++) {
if (((perso->_roomNum >> 8) & 0xFF) != p_global->_citadelAreaNum)
continue;
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pf80)
continue;
2016-10-07 00:45:08 +02:00
if (!perso->_targetLoc)
continue;
2016-10-07 00:45:08 +02:00
if (--perso->_steps)
continue;
2016-10-07 00:45:08 +02:00
perso->_steps = 1;
2016-12-11 13:44:58 -08:00
if (perso->_roomNum == p_global->_roomNum)
continue;
2016-10-07 00:45:08 +02:00
perso->_steps = perso->_speed;
2016-12-18 13:09:56 -08:00
moveDino(perso);
}
}
// Original name: newvallee
void EdenGame::newValley() {
static int16 roomNumList[] = { 2075, 2080, 2119, -1};
perso_t *perso = &kPersons[PER_UNKN_372];
int16 *ptr = roomNumList;
int16 roomNum = *ptr++;
while (roomNum != -1) {
2016-10-07 00:45:08 +02:00
perso->_roomNum = roomNum;
perso->_flags &= ~PersonFlags::pf80;
perso->_flags &= ~PersonFlags::pf20; //TODO: combine?
perso++;
roomNum = *ptr++;
}
2016-10-07 00:45:08 +02:00
perso->_roomNum = 0xFFFF;
2016-12-04 14:26:44 -08:00
kAreasTable[7]._flags |= AreaFlags::HasTyrann;
2016-12-11 13:44:58 -08:00
p_global->_worldHasTyran = 32;
}
char EdenGame::whereiscita() {
char res = -1;
for (Room *room = p_global->_citaAreaFirstRoom; room->_id != 0xFF; room++) {
2016-12-15 22:47:29 -08:00
if (!(room->_flags & RoomFlags::rfHasCitadel))
continue;
2016-12-15 22:47:29 -08:00
res = room->_location;
break;
}
return res;
}
2016-09-29 00:32:49 +02:00
bool EdenGame::iscita(int16 loc) {
loc &= 0xFF;
for (Room *room = p_global->_citaAreaFirstRoom; room->_id != 0xFF; room++) {
2016-12-15 22:47:29 -08:00
if (!(room->_flags & RoomFlags::rfHasCitadel))
continue;
2016-12-15 22:47:29 -08:00
if (room->_location == loc + 16)
2016-09-29 00:32:49 +02:00
return true;
2016-12-15 22:47:29 -08:00
if (room->_location == loc - 16)
2016-09-29 00:32:49 +02:00
return true;
2016-12-15 22:47:29 -08:00
if (room->_location == loc - 1)
2016-09-29 00:32:49 +02:00
return true;
2016-12-15 22:47:29 -08:00
if (room->_location == loc + 1)
2016-09-29 00:32:49 +02:00
return true;
}
2016-09-29 00:32:49 +02:00
return false;
}
void EdenGame::lieuvava(Area *area) {
2016-12-15 22:47:29 -08:00
if (area->_type == AreaType::atValley) {
istyranval(area);
2016-12-15 22:47:29 -08:00
area->_citadelLevel = 0;
if (area->_citadelRoomPtr)
area->_citadelLevel = p_global->_citaAreaFirstRoom->_level; //TODO: no search?
byte mask = ~(1 << (area->_num - Areas::arChamaar));
2016-12-11 13:44:58 -08:00
p_global->_worldTyranSighted &= mask;
p_global->_var4E &= mask;
2016-12-11 13:44:58 -08:00
p_global->_worldGaveGold &= mask;
p_global->_worldHasVelociraptors &= mask;
p_global->_worldHasTriceraptors &= mask;
p_global->_worldHasTyran &= mask;
p_global->_var53 &= mask;
mask = ~mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::TyrannSighted)
2016-12-11 13:44:58 -08:00
p_global->_worldTyranSighted |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::afFlag4)
p_global->_var4E |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::HasTriceraptors)
2016-12-11 13:44:58 -08:00
p_global->_worldHasTriceraptors |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::afGaveGold)
2016-12-11 13:44:58 -08:00
p_global->_worldGaveGold |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::HasVelociraptors)
2016-12-11 13:44:58 -08:00
p_global->_worldHasVelociraptors |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::HasTyrann)
2016-12-11 13:44:58 -08:00
p_global->_worldHasTyran |= mask;
2016-12-04 14:26:44 -08:00
if (area->_flags & AreaFlags::afFlag20)
p_global->_var53 |= mask;
2016-12-04 14:26:44 -08:00
if (area == p_global->_areaPtr) {
p_global->_curAreaFlags = area->_flags;
2016-12-15 22:47:29 -08:00
p_global->_curCitadelLevel = area->_citadelLevel;
}
}
p_global->_var4D &= p_global->_worldTyranSighted;
}
void EdenGame::vivredino() {
for (perso_t *perso = &kPersons[PER_UNKN_18C]; perso->_roomNum != 0xFFFF; perso++) {
2016-12-18 13:09:56 -08:00
if (((perso->_roomNum >> 8) & 0xFF) != p_global->_citadelAreaNum)
continue;
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pf80)
continue;
2016-10-07 00:45:08 +02:00
switch (perso->_flags & PersonFlags::pfTypeMask) {
case PersonFlags::pftTyrann:
2016-10-07 00:45:08 +02:00
if (iscita(perso->_roomNum))
perso->_targetLoc = 0;
else if (!perso->_targetLoc) {
2016-09-29 00:32:49 +02:00
char cita = whereiscita();
if (cita != -1) {
2016-10-07 00:45:08 +02:00
perso->_targetLoc = cita;
perso->_speed = 2;
perso->_steps = 1;
}
}
break;
case PersonFlags::pftTriceraptor:
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pfInParty) {
if (iscita(perso->_roomNum))
perso->_targetLoc = 0;
else if (!perso->_targetLoc) {
2016-09-29 00:32:49 +02:00
char cita = whereiscita();
if (cita != -1) {
2016-10-07 00:45:08 +02:00
perso->_targetLoc = cita;
perso->_speed = 3;
perso->_steps = 1;
}
}
}
break;
case PersonFlags::pftVelociraptor:
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pf10) {
2016-12-11 13:44:58 -08:00
if (perso->_roomNum == p_global->_roomNum) {
perso_t *perso2 = &kPersons[PER_UNKN_372];
bool found = false;
2016-10-07 00:45:08 +02:00
for (; perso2->_roomNum != 0xFFFF; perso2++) {
if ((perso->_roomNum & ~0xFF) == (perso2->_roomNum & ~0xFF)) {
if (perso2->_flags & PersonFlags::pf80)
continue;
2016-10-07 00:45:08 +02:00
perso->_targetLoc = perso2->_roomNum & 0xFF;
perso->_steps = 1;
found = true;
break;
}
}
if (found)
continue;
} else {
_tyranPtr = &kPersons[PER_UNKN_372];
2016-10-07 00:45:08 +02:00
if (istyran(perso->_roomNum)) {
2016-12-18 13:09:56 -08:00
if (p_global->_phaseNum < 481 && (perso->_powers & (1 << (p_global->_citadelAreaNum - 3)))) {
_tyranPtr->_flags |= PersonFlags::pf80;
_tyranPtr->_roomNum = 0;
2016-10-07 00:45:08 +02:00
perso->_flags &= ~PersonFlags::pf10;
perso->_flags |= PersonFlags::pfInParty;
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnTyrannLost);
removeInfo(p_global->_citadelAreaNum + ValleyNews::vnTyrannIn);
if (naitredino(PersonFlags::pftTriceraptor))
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnTriceraptorsIn);
constcita();
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr->_flags &= ~AreaFlags::TyrannSighted;
} else {
2016-10-07 00:45:08 +02:00
perso->_flags &= ~PersonFlags::pf10;
perso->_flags &= ~PersonFlags::pfInParty;
2016-12-18 13:09:56 -08:00
addInfo(p_global->_citadelAreaNum + ValleyNews::vnVelociraptorsLost);
}
continue;
}
}
}
2016-10-07 00:45:08 +02:00
if (!perso->_targetLoc) {
2016-09-14 23:48:01 +02:00
int16 loc;
2016-10-07 00:45:08 +02:00
perso->_lastLoc = 0;
do {
loc = (_vm->_rnd->getRandomNumber(63) & 63) + 16;
if ((loc & 0xF) >= 12)
loc &= ~4; //TODO: ??? same as -= 4
2016-09-29 00:32:49 +02:00
} while (!canMoveThere(loc, perso));
2016-10-07 00:45:08 +02:00
perso->_targetLoc = loc;
perso->_steps = 1;
}
break;
}
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::vivreval(int16 areaNum) {
2016-12-18 13:09:56 -08:00
p_global->_citadelAreaNum = areaNum;
2016-12-11 13:44:58 -08:00
p_global->_curAreaPtr = &kAreasTable[areaNum - 1];
2016-12-18 14:13:36 -08:00
p_global->_citaAreaFirstRoom = &_gameRooms[p_global->_curAreaPtr->_firstRoomIdx];
2016-12-18 13:09:56 -08:00
moveAllDino();
constcita();
vivredino();
2016-12-18 13:09:56 -08:00
newMushroom();
newnido();
newnidv();
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 226)
newor();
2016-12-11 13:44:58 -08:00
lieuvava(p_global->_curAreaPtr);
}
void EdenGame::chaquejour() {
vivreval(3);
vivreval(4);
vivreval(5);
vivreval(6);
vivreval(7);
vivreval(8);
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawTopScreen;
}
2016-09-14 23:48:01 +02:00
void EdenGame::temps_passe(int16 t) {
2016-12-04 14:26:44 -08:00
int16 days = p_global->_gameDays;
int16 lo = p_global->_gameHours + t;
if (lo > 255) {
days++;
lo &= 0xFF;
}
2016-12-04 14:26:44 -08:00
p_global->_gameHours = lo;
t = ((t >> 8) & 0xFF) + days;
2016-12-04 14:26:44 -08:00
t -= p_global->_gameDays;
if (t) {
2016-12-04 14:26:44 -08:00
p_global->_gameDays += t;
while (t--)
chaquejour();
}
}
void EdenGame::heurepasse() {
temps_passe(5);
}
void EdenGame::anim_perso() {
2016-12-04 14:26:44 -08:00
if (_curBankNum != p_global->_characterImageBank)
loadCharacter(p_global->_characterPtr);
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
2016-12-04 14:26:44 -08:00
if (_restartAnimation) {
_lastAnimTicks = _vm->_timerTicks;
_restartAnimation = false;
}
2016-12-04 14:26:44 -08:00
_curAnimFrameNumb = (_vm->_timerTicks - _lastAnimTicks) >> 2; // TODO: check me!!!
if (_curAnimFrameNumb > _numAnimFrames) // TODO: bug?
_animateTalking = false;
2016-12-04 14:26:44 -08:00
if (p_global->_curCharacterAnimPtr && !p_global->_animationFlags && _curAnimFrameNumb != _lastAnimFrameNumb) {
_lastAnimFrameNumb = _curAnimFrameNumb;
if (*p_global->_curCharacterAnimPtr == 0xFF)
getanimrnd();
2016-12-25 02:17:07 -08:00
useCharacterBank();
_numImgDesc = 0;
2016-12-04 14:26:44 -08:00
perso_spr(p_global->_curCharacterAnimPtr);
2016-12-25 02:17:07 -08:00
p_global->_curCharacterAnimPtr += _numImgDesc + 1;
2016-12-04 14:26:44 -08:00
_mouthAnimations = _imageDesc + 200;
removeMouthSprite();
if (*_mouthAnimations)
displayImage();
_animationDelay--;
if (!_animationDelay) { //TODO: combine
p_global->_animationFlags = 1;
_animationDelay = 8;
}
}
2016-12-04 14:26:44 -08:00
_animationDelay--;
if (!_animationDelay) { //TODO: combine
getanimrnd();
//TODO: no reload?
}
if (_animateTalking) {
2016-12-25 13:45:47 -08:00
if (!_animationTable) {
_animationTable = gameLipsync + 7262; //TODO: fix me
2016-12-18 14:13:36 -08:00
if (!_backgroundSaved)
sauvefondbouche();
}
if (!_personTalking)
2016-12-04 14:26:44 -08:00
_curAnimFrameNumb = _numAnimFrames - 1;
2016-12-25 13:45:47 -08:00
_animationIndex = _animationTable[_curAnimFrameNumb];
2016-12-25 02:17:07 -08:00
if (_animationIndex == 0xFF)
_animateTalking = false;
2016-12-25 02:17:07 -08:00
else if (_animationIndex != _lastAnimationIndex) {
useCharacterBank();
restaurefondbouche();
// debug("perso spr %d", animationIndex);
2016-12-25 02:17:07 -08:00
perso_spr(p_global->_persoSpritePtr2 + _animationIndex * 2); //TODO: int16s?
2016-12-04 14:26:44 -08:00
_mouthAnimations = _imageDesc + 200;
if (*_mouthAnimations)
displayImage();
2016-12-25 02:17:07 -08:00
_lastAnimationIndex = _animationIndex;
}
}
2016-12-25 02:17:07 -08:00
displaySubtitles();
}
void EdenGame::getanimrnd() {
2016-12-04 14:26:44 -08:00
_animationDelay = 8;
int16 rnd = _vm->_rnd->getRandomNumber(65535) & (byte)~0x18; //TODO
2016-12-11 13:44:58 -08:00
dword_30724 = p_global->_persoSpritePtr + 16; //TODO
p_global->_curCharacterAnimPtr = p_global->_persoSpritePtr + ((dword_30724[1] << 8) + dword_30724[0]);
2016-12-04 14:26:44 -08:00
p_global->_animationFlags = 1;
if (rnd >= 8)
return;
2016-12-04 14:26:44 -08:00
p_global->_animationFlags = 0;
if (rnd <= 0)
return;
for (rnd *= 8; rnd > 0; rnd--) {
2016-12-04 14:26:44 -08:00
while (*p_global->_curCharacterAnimPtr)
p_global->_curCharacterAnimPtr++;
p_global->_curCharacterAnimPtr++;
}
}
void EdenGame::addanim() {
2016-12-25 02:17:07 -08:00
_lastAnimationIndex = 0xFF;
_lastAnimTicks = 0;
2016-12-04 14:26:44 -08:00
p_global->_animationFlags = 0xC0;
2016-12-11 13:44:58 -08:00
p_global->_curCharacterAnimPtr = p_global->_persoSpritePtr;
getanimrnd();
2016-12-25 02:17:07 -08:00
_animationActive = true;
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_ROI])
return;
2016-12-11 13:44:58 -08:00
perso_spr(p_global->_persoSpritePtr + READ_LE_UINT16(p_global->_persoSpritePtr)); //TODO: GetElem(0)
2016-12-04 14:26:44 -08:00
_mouthAnimations = _imageDesc + 200;
if (p_global->_characterPtr->_id != PersonId::pidCabukaOfCantura && p_global->_characterPtr->_targetLoc != 7) //TODO: targetLoc is minisprite idx
removeMouthSprite();
if (*_mouthAnimations)
displayImage();
}
2016-12-04 14:26:44 -08:00
// Original name: virespritebouche
void EdenGame::removeMouthSprite() {
byte *src = _mouthAnimations + 2;
2016-09-14 23:48:01 +02:00
byte *dst = src;
2016-12-04 14:26:44 -08:00
char cnt = _mouthAnimations[0];
while (cnt--) {
2016-09-14 23:48:01 +02:00
byte a = *src++;
byte b = *src++;
byte c = *src++;
dst[0] = a;
dst[1] = b;
dst[2] = c;
if (dword_30728[0] != 0xFF) {
if ((a < dword_30728[0] || a > dword_30728[1])
&& (a < dword_30728[2] || a > dword_30728[3]))
dst += 3;
else
2016-12-04 14:26:44 -08:00
_mouthAnimations[0]--;
} else
dst += 3;
}
}
void EdenGame::anim_perfin() {
2016-12-04 14:26:44 -08:00
p_global->_animationFlags &= ~0x80;
_animationDelay = 0;
2016-12-25 02:17:07 -08:00
_animationActive = false;
}
2016-09-14 23:48:01 +02:00
void EdenGame::perso_spr(byte *spr) {
2016-12-04 14:26:44 -08:00
byte *img = _imageDesc + 200 + 2;
2016-09-14 23:48:01 +02:00
int16 count = 0;
byte c;
while ((c = *spr++)) {
2016-09-14 23:48:01 +02:00
byte *src;
2016-10-08 21:21:21 +02:00
int16 index = 0;
byte cc = 0;
if (c == 1) {
cc = index;
c = *spr++;
}
2016-12-25 02:17:07 -08:00
_numImgDesc++;
index = (cc << 8) | c;
index -= 2;
// debug("anim sprite %d", index);
2016-12-25 02:17:07 -08:00
if (index > _maxPersoDesc)
index = _maxPersoDesc;
index *= 2; //TODO: src = GetElem(ff_C2, index)
src = p_global->_varC2;
2016-12-04 14:54:58 -08:00
src += READ_LE_UINT16(src + index);
while ((c = *src++)) {
*img++ = c;
*img++ = *src++;
*img++ = *src++;
count++;
}
}
2016-12-04 14:26:44 -08:00
_imageDesc[200] = count & 0xFF;
_imageDesc[201] = count >> 8;
}
2016-12-04 14:26:44 -08:00
// Original name: af_image
void EdenGame::displayImage() {
2016-12-04 14:54:58 -08:00
byte *img = _imageDesc + 200;
2016-12-04 14:54:58 -08:00
int16 count = READ_LE_UINT16(img);
if (!count)
return;
2016-12-04 14:54:58 -08:00
byte *img_start = img;
byte *curimg = _imageDesc;
img += 2;
count *= 3;
while (count--)
*curimg++ = *img++;
img = img_start;
2016-12-04 14:54:58 -08:00
count = READ_LE_UINT16(img);
img += 2;
/////// draw it
while (count--) {
2016-09-14 23:48:01 +02:00
uint16 index = *img++;
2016-12-04 14:26:44 -08:00
uint16 x = *img++ + _gameIcons[0].sx;
uint16 y = *img++ + _gameIcons[0].sy;
byte *pix = _bankData;
2016-09-14 23:48:01 +02:00
byte *scr = p_mainview_buf + x + y * 640;
index--;
2016-12-04 14:54:58 -08:00
if (READ_LE_UINT16(pix) > 2)
readPalette(pix + 2);
2016-12-04 14:54:58 -08:00
pix += READ_LE_UINT16(pix);
pix += READ_LE_UINT16(pix + index * 2);
2016-09-14 23:48:01 +02:00
// int16 height:9
// int16 pad:6;
// int16 flag:1;
2016-12-04 14:54:58 -08:00
byte h0 = *pix++;
byte h1 = *pix++;
int16 w = ((h1 & 1) << 8) | h0;
int16 h = *pix++;
byte mode = *pix++;
2016-08-18 13:15:54 +02:00
if (mode != 0xFF && mode != 0xFE)
continue; //TODO: enclosing block?
2016-08-18 13:15:54 +02:00
if (h1 & 0x80) {
// compressed
for (; h-- > 0;) {
for (int16 ww = w; ww > 0;) {
2016-09-14 23:48:01 +02:00
byte c = *pix++;
2016-08-18 13:15:54 +02:00
if (c >= 0x80) {
if (c == 0x80) {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
2016-08-18 13:15:54 +02:00
if (fill == 0) {
scr += 128 + 1;
ww -= 128 + 1;
} else {
2016-09-14 23:48:01 +02:00
byte run;
2016-08-18 13:15:54 +02:00
*scr++ = fill; //TODO: wha?
*scr++ = fill;
ww -= 128 + 1;
for (run = 127; run--;)
*scr++ = fill;
}
} else {
2016-09-14 23:48:01 +02:00
byte fill = *pix++;
byte run = 255 - c + 2;
2016-08-18 13:15:54 +02:00
ww -= run;
if (fill == 0)
scr += run;
else {
2016-08-18 13:15:54 +02:00
for (; run--;)
*scr++ = fill;
}
2016-08-18 13:15:54 +02:00
}
} else {
2016-09-14 23:48:01 +02:00
byte run = c + 1;
2016-08-18 13:15:54 +02:00
ww -= run;
for (; run--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
2016-08-18 13:15:54 +02:00
if (p == 0)
scr++;
else
*scr++ = p;
}
}
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
} else {
// uncompressed
for (; h--;) {
for (int16 ww = w; ww--;) {
2016-09-14 23:48:01 +02:00
byte p = *pix++;
2016-08-18 13:15:54 +02:00
if (p == 0)
scr++;
else
*scr++ = p;
}
scr += 640 - w;
2016-08-18 13:15:54 +02:00
}
}
}
}
void EdenGame::af_perso1() {
2016-12-11 13:44:58 -08:00
perso_spr(p_global->_persoSpritePtr + READ_LE_UINT16(p_global->_persoSpritePtr));
2016-12-04 14:26:44 -08:00
displayImage();
}
void EdenGame::af_perso() {
load_perso_cour();
af_perso1();
}
void EdenGame::ef_perso() {
2016-12-04 14:26:44 -08:00
p_global->_animationFlags &= 0x3F;
}
2016-12-04 14:26:44 -08:00
// Original name: load_perso
void EdenGame::loadCharacter(perso_t *perso) {
_characterBankData = nullptr;
2016-10-07 00:45:08 +02:00
if (!perso->_spriteBank)
return;
2016-12-04 14:26:44 -08:00
if (perso->_spriteBank != p_global->_characterImageBank) {
2016-12-25 02:17:07 -08:00
_curPersoRect = &perso_rects[perso->_id]; //TODO: array of int16?
2016-10-07 00:45:08 +02:00
dword_30728 = tab_persxx[perso->_id];
ef_perso();
2016-12-04 14:26:44 -08:00
p_global->_characterImageBank = perso->_spriteBank;
useBank(p_global->_characterImageBank);
_characterBankData = _bankData;
byte *ptr = _bankData;
2016-12-04 14:54:58 -08:00
ptr += READ_LE_UINT16(ptr);
byte *baseptr = ptr;
2016-12-04 14:54:58 -08:00
ptr += READ_LE_UINT16(ptr) - 2;
ptr = baseptr + READ_LE_UINT16(ptr) + 4;
_gameIcons[0].sx = READ_LE_UINT16(ptr);
_gameIcons[0].sy = READ_LE_UINT16(ptr + 2);
_gameIcons[0].ex = READ_LE_UINT16(ptr + 4);
_gameIcons[0].ey = READ_LE_UINT16(ptr + 6);
ptr += 8;
p_global->_varC2 = ptr + 2;
2016-12-25 02:17:07 -08:00
_maxPersoDesc = READ_LE_UINT16(ptr) / 2;
2016-12-04 14:54:58 -08:00
ptr += READ_LE_UINT16(ptr);
baseptr = ptr;
2016-12-04 14:54:58 -08:00
ptr += READ_LE_UINT16(ptr) - 2;
2016-12-11 13:44:58 -08:00
p_global->_persoSpritePtr = baseptr;
p_global->_persoSpritePtr2 = baseptr + READ_LE_UINT16(ptr);
debug("load perso: b6 len is %ld", p_global->_persoSpritePtr2 - p_global->_persoSpritePtr);
} else {
2016-12-04 14:26:44 -08:00
useBank(p_global->_characterImageBank);
_characterBankData = _bankData;
}
}
void EdenGame::load_perso_cour() {
2016-12-04 14:26:44 -08:00
loadCharacter(p_global->_characterPtr);
}
void EdenGame::fin_perso() {
2016-12-04 14:26:44 -08:00
p_global->_animationFlags &= 0x3F;
p_global->_curCharacterAnimPtr = nullptr;
p_global->_varCA = 0;
2016-12-04 14:26:44 -08:00
p_global->_characterImageBank = -1;
anim_perfin();
}
void EdenGame::no_perso() {
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags == DisplayFlags::dfPerson) {
2016-12-11 13:44:58 -08:00
p_global->_displayFlags = p_global->_oldDisplayFlags;
fin_perso();
}
endpersovox();
}
void EdenGame::close_perso() {
endpersovox();
2016-12-04 14:26:44 -08:00
if (p_global->_displayFlags == DisplayFlags::dfPerson && p_global->_characterPtr->_id != PersonId::pidNarrator && p_global->_eventType != EventType::etEventE) {
rundcurs();
2016-12-25 02:17:07 -08:00
_savedUnderSubtitles = true;
restorePhylacteryBackground();
2016-08-18 13:15:54 +02:00
afficher();
p_global->_var103 = 16;
2016-08-18 13:15:54 +02:00
}
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr->_id == PersonId::pidNarrator)
p_global->_var103 = 69;
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews &= 1;
p_global->_varCA = 0;
p_global->_varF6 = 0;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags == DisplayFlags::dfPerson) {
2016-12-11 13:44:58 -08:00
p_global->_displayFlags = p_global->_oldDisplayFlags;
2016-12-04 14:26:44 -08:00
p_global->_animationFlags &= 0x3F;
p_global->_curCharacterAnimPtr = nullptr;
anim_perfin();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfMirror) {
gametomiroir(1);
2016-09-30 07:48:27 +02:00
_scrollPos = _oldScrollPos;
scroll();
2016-08-18 13:15:54 +02:00
return;
}
2016-12-11 13:44:58 -08:00
if (p_global->_numGiveObjs) {
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & DisplayFlags::dfFlag2))
showObjects();
2016-12-11 13:44:58 -08:00
p_global->_numGiveObjs = 0;
2016-08-18 13:15:54 +02:00
}
if (p_global->_varF2 & 1) {
p_global->_var102 = 6;
p_global->_varF2 &= ~1;
}
2016-12-11 13:44:58 -08:00
char oldLoc = p_global->_newLocation;
p_global->_newLocation = 0;
if (!(p_global->_narratorSequence & 0x80))
p_global->_var100 = 0xFF;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
2016-12-11 13:44:58 -08:00
p_global->_newLocation = oldLoc;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_chrono)
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag = 1;
}
2016-10-07 23:06:10 +02:00
// Original name: af_fondsuiveur
void EdenGame::displayBackgroundFollower() {
2016-12-04 14:26:44 -08:00
char id = p_global->_characterPtr->_id;
2016-10-07 23:06:10 +02:00
for (Follower *follower = followerList; follower->_id != -1; follower++) {
if (follower->_id == id) {
int bank = 326;
2016-10-07 23:06:10 +02:00
if (follower->sx >= 320)
bank = 327;
2016-12-11 13:44:58 -08:00
useBank(bank + p_global->_roomBackgroundBankNum);
noclipax_avecnoir(0, 0, 16);
break;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::af_fondperso1() {
2016-09-14 23:48:01 +02:00
byte bank;
char *ptab;
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_MESSAGER]) {
_gameIcons[0].sx = 0;
2016-12-25 13:45:47 -08:00
perso_rects[PER_MESSAGER].left = 2;
2016-12-04 14:26:44 -08:00
bank = p_global->_characterBackgroundBankIdx;
2016-12-04 13:15:38 -08:00
if (p_global->_eventType == EventType::etEventE) {
p_global->_var103 = 1;
goto no_suiveur;
}
2016-12-04 14:26:44 -08:00
_gameIcons[0].sx = 60;
2016-12-25 13:45:47 -08:00
perso_rects[PER_MESSAGER].left = 62;
}
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_THOO]) {
bank = 37;
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId == Objects::obShell)
goto no_suiveur;
}
2016-12-04 14:26:44 -08:00
ptab = kPersoRoomBankTable + p_global->_characterPtr->_roomBankId;
bank = *ptab++;
2016-12-11 13:44:58 -08:00
if (!(p_global->_characterPtr->_partyMask & p_global->_party)) {
while ((bank = *ptab++) != 0xFF) {
2016-12-11 13:44:58 -08:00
if (bank == (p_global->_roomNum & 0xFF)) { //TODO: signed vs unsigned - chg r31 to uns?
bank = *ptab;
break;
}
ptab++;
2016-08-18 13:15:54 +02:00
}
if (bank != 0xFF)
goto no_suiveur;
2016-12-04 14:26:44 -08:00
ptab = kPersoRoomBankTable + p_global->_characterPtr->_roomBankId;
bank = *ptab++;
2016-08-18 13:15:54 +02:00
}
2016-10-07 23:06:10 +02:00
displayBackgroundFollower();
no_suiveur:
;
if (!bank)
return;
2016-10-07 23:06:10 +02:00
useBank(bank);
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_UNKN_156])
noclipax_avecnoir(0, 0, 16);
else
noclipax(0, 0, 16);
}
void EdenGame::af_fondperso() {
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr->_spriteBank) {
2016-12-18 14:13:36 -08:00
_backgroundSaved = false;
af_fondperso1();
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 14:26:44 -08:00
// Original name: setpersoicon
void EdenGame::setCharacterIcon() {
2016-12-04 13:15:38 -08:00
if (p_global->_iconsIndex == 4)
return;
2016-11-29 14:03:36 -08:00
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_MESSAGER] && p_global->_eventType == EventType::etEventE) {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 123;
return;
2016-08-18 13:15:54 +02:00
}
Icon *icon = _gameIcons;
2016-12-19 22:32:40 -08:00
Icon *icon2 = &_gameIcons[_roomIconsBase];
2016-11-29 14:03:36 -08:00
*icon2++ = *icon++; //TODO: is this ok?
*icon2++ = *icon++;
icon2->sx = -1;
}
2016-08-18 13:15:54 +02:00
2016-12-04 14:26:44 -08:00
// Original name: show_perso
void EdenGame::showCharacter() {
perso_t *perso = p_global->_characterPtr;
2016-10-07 00:45:08 +02:00
if (perso->_spriteBank) {
closesalle();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags != DisplayFlags::dfPerson) {
if (p_global->_displayFlags & DisplayFlags::dfMirror)
2016-09-26 23:44:42 +02:00
resetScroll();
2016-12-11 13:44:58 -08:00
p_global->_oldDisplayFlags = p_global->_displayFlags;
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfPerson;
2016-12-04 14:26:44 -08:00
loadCharacter(perso);
setCharacterIcon();
af_fondperso();
2016-12-04 13:15:38 -08:00
if (perso == &kPersons[PER_THOO] && p_global->_curObjectId == Objects::obShell) {
2016-12-25 02:17:07 -08:00
displaySubtitles();
update_cursor();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
afficher();
rundcurs();
return;
}
2016-08-18 13:15:54 +02:00
}
load_perso_cour();
addanim();
2016-12-04 14:26:44 -08:00
if (!p_global->_curCharacterAnimPtr) {
af_perso();
2016-12-25 02:17:07 -08:00
displaySubtitles();
}
2016-12-04 14:26:44 -08:00
_restartAnimation = true;
anim_perso();
if (perso != &kPersons[PER_UNKN_156])
update_cursor();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
if (perso != &kPersons[PER_UNKN_156])
rundcurs();
afficher();
} else {
2016-10-07 23:06:10 +02:00
displayPlace();
2016-12-25 02:17:07 -08:00
displaySubtitles();
2016-08-18 13:15:54 +02:00
}
}
2016-12-25 02:17:07 -08:00
// Original name: showpersopanel
void EdenGame::displayCharacterPanel() {
2016-12-04 14:26:44 -08:00
perso_t *perso = p_global->_characterPtr;
load_perso_cour();
addanim();
2016-12-04 14:26:44 -08:00
if (!p_global->_curCharacterAnimPtr) {
af_perso();
2016-12-25 02:17:07 -08:00
displaySubtitles();
}
2016-12-04 14:26:44 -08:00
_restartAnimation = true;
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawFlag8)
return;
anim_perso();
if (perso != &kPersons[PER_UNKN_156])
update_cursor();
afficher();
if (perso != &kPersons[PER_UNKN_156])
rundcurs();
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawFlag8;
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 112;
}
2016-12-25 02:17:07 -08:00
void EdenGame::getDataSync() {
2016-12-11 13:44:58 -08:00
int16 num = p_global->_textNum;
if (p_global->_textBankIndex != 1)
num += 565;
2016-12-11 13:44:58 -08:00
if (p_global->_textBankIndex == 3)
num += 707;
if (num == 144)
num = 142;
_animateTalking = ReadDataSync(num - 1);
if (_animateTalking)
2016-12-04 14:26:44 -08:00
_numAnimFrames = ReadNombreFrames();
else
2016-12-04 14:26:44 -08:00
_numAnimFrames = 0;
2016-12-11 13:44:58 -08:00
if (p_global->_textNum == 144)
2016-12-04 14:26:44 -08:00
_numAnimFrames = 48;
2016-12-25 13:45:47 -08:00
_animationTable = 0;
}
2016-09-14 23:48:01 +02:00
int16 EdenGame::ReadNombreFrames() {
int16 num = 0;
2016-12-25 13:45:47 -08:00
_animationTable = gameLipsync + 7260 + 2; //TODO: fix me
while (*_animationTable++ != 0xFF)
num++;
return num;
}
2016-12-04 13:15:38 -08:00
void EdenGame::waitEndSpeak() {
for (;;) {
2016-12-25 02:17:07 -08:00
if (_animationActive)
anim_perso();
musicspy();
afficher();
CLKeyboard_Read();
testPommeQ();
if (pomme_q) {
close_perso();
2016-12-19 22:32:40 -08:00
edenShudown();
break;
2016-08-18 13:15:54 +02:00
}
2016-12-18 13:09:56 -08:00
if (!_mouseHeld)
if (CLMouse_IsDown())
break;
2016-12-18 13:09:56 -08:00
if (_mouseHeld)
if (!CLMouse_IsDown())
2016-12-18 13:09:56 -08:00
_mouseHeld = false;
2016-08-18 13:15:54 +02:00
}
2016-12-18 13:09:56 -08:00
_mouseHeld = true;
}
void EdenGame::my_bulle() {
2016-12-11 13:44:58 -08:00
if (!p_global->_textNum)
2016-11-29 14:03:36 -08:00
return;
2016-09-14 23:48:01 +02:00
byte *icons = phraseIconsBuffer;
2016-10-08 21:26:22 +02:00
byte *linesp = phraseCoordsBuffer;
2016-12-11 13:44:58 -08:00
byte *sentencePtr = _sentenceBuffer;
p_global->_numGiveObjs = 0;
p_global->_giveObj1 = 0;
p_global->_giveObj2 = 0;
p_global->_giveObj3 = 0;
p_global->_textWidthLimit = subtitles_x_width;
2016-12-25 13:45:47 -08:00
byte *textPtr = gettxtad(p_global->_textNum);
_numTextLines = 0;
2016-11-29 14:03:36 -08:00
int16 words_on_line = 0;
int16 word_width = 0;
int16 line_width = 0;
byte c;
2016-12-25 13:45:47 -08:00
while ((c = *textPtr++) != 0xFF) {
if (c == 0x11 || c == 0x13) {
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum <= 272 || p_global->_phaseNum == 386) {
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews = c & 0xF;
p_global->_var4D = p_global->_worldTyranSighted;
2016-08-18 13:15:54 +02:00
}
} else if (c >= 0x80 && c < 0x90)
SysBeep(1);
else if (c >= 0x90 && c < 0xA0) {
2016-12-25 13:45:47 -08:00
while (*textPtr++ != 0xFF) ;
textPtr--;
} else if (c >= 0xA0 && c < 0xC0)
2016-12-11 13:44:58 -08:00
p_global->_textToken1 = c & 0xF;
else if (c >= 0xC0 && c < 0xD0)
2016-12-11 13:44:58 -08:00
p_global->_textToken2 = c & 0xF;
else if (c >= 0xD0 && c < 0xE0) {
2016-12-25 13:45:47 -08:00
byte c1 = *textPtr++;
if (c == 0xD2)
#ifdef FAKE_DOS_VERSION
2016-12-11 13:44:58 -08:00
p_global->_textWidthLimit = c1 + 160;
#else
2016-12-11 13:44:58 -08:00
p_global->_textWidthLimit = c1 + subtitles_x_center; //TODO: signed? 160 in pc ver
#endif
else {
2016-12-25 13:45:47 -08:00
byte c2 = *textPtr++;
2016-12-11 13:44:58 -08:00
switch (p_global->_numGiveObjs) {
case 0:
2016-12-11 13:44:58 -08:00
p_global->_giveObj1 = c2;
break;
case 1:
2016-12-11 13:44:58 -08:00
p_global->_giveObj2 = c2;
2016-08-18 13:15:54 +02:00
break;
case 2:
2016-12-11 13:44:58 -08:00
p_global->_giveObj3 = c2;
break;
}
2016-12-11 13:44:58 -08:00
p_global->_numGiveObjs++;
2016-12-25 13:45:47 -08:00
*icons++ = *textPtr++;
*icons++ = *textPtr++;
*icons++ = c2;
}
} else if (c >= 0xE0 && c < 0xFF)
SysBeep(1);
else if (c != '\r') {
2016-09-14 23:48:01 +02:00
byte width;
int16 overrun;
2016-12-11 13:44:58 -08:00
*sentencePtr++ = c;
2016-12-18 14:13:36 -08:00
width = _gameFont[c];
#ifdef FAKE_DOS_VERSION
if (c == ' ')
width = space_width;
#endif
word_width += width;
line_width += width;
2016-12-11 13:44:58 -08:00
overrun = line_width - p_global->_textWidthLimit;
if (overrun > 0) {
2016-12-25 13:45:47 -08:00
_numTextLines++;
if (c != ' ') {
2016-10-08 21:26:22 +02:00
*linesp++ = words_on_line;
*linesp++ = word_width + space_width - overrun;
line_width = word_width;
} else {
2016-10-08 21:26:22 +02:00
*linesp++ = words_on_line + 1;
*linesp++ = space_width - overrun; //TODO: checkme
line_width = 0;
}
word_width = 0;
words_on_line = 0;
} else {
if (c == ' ') {
words_on_line++;
word_width = 0;
}
2016-08-18 13:15:54 +02:00
}
}
}
2016-12-25 13:45:47 -08:00
_numTextLines++;
2016-10-08 21:26:22 +02:00
*linesp++ = words_on_line + 1;
*linesp++ = word_width;
2016-12-11 13:44:58 -08:00
*sentencePtr = c;
if (p_global->_textBankIndex == 2 && p_global->_textNum == 101 && p_global->_prefLanguage == 1)
2016-12-04 14:26:44 -08:00
patchPhrase();
my_pr_bulle();
2016-12-11 13:44:58 -08:00
if (!p_global->_numGiveObjs)
return;
2016-12-25 02:17:07 -08:00
useMainBank();
2016-12-25 13:45:47 -08:00
if (_numTextLines < 3)
_numTextLines = 3;
icons = phraseIconsBuffer;
2016-12-11 13:44:58 -08:00
for (byte i = 0; i < p_global->_numGiveObjs; i++) {
2016-09-14 23:48:01 +02:00
byte x = *icons++;
byte y = *icons++;
byte s = *icons++;
spriteOnSubtitle(52, x + subtitles_x_center, y - 1);
spriteOnSubtitle(s + 9, x + subtitles_x_center + 1, y);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::my_pr_bulle() {
CLBlitter_FillView(p_subtitlesview, 0);
2016-12-11 13:44:58 -08:00
if (p_global->_prefLanguage == 0)
return;
2016-11-29 14:03:36 -08:00
byte *coo = phraseCoordsBuffer;
bool done = false;
textout = p_subtitlesview_buf;
2016-12-25 13:45:47 -08:00
byte *textPtr = _sentenceBuffer;
int16 lines = 1;
while (!done) {
2016-09-14 23:48:01 +02:00
int16 num_words = *coo++; // num words on line
int16 pad_size = *coo++; // amount of extra spacing
byte *cur_out = textout;
int16 extraSpacing = num_words > 1 ? pad_size / (num_words - 1) + 1 : 0;
2016-12-25 13:45:47 -08:00
if (lines == _numTextLines)
extraSpacing = 0;
2016-12-25 13:45:47 -08:00
byte c = *textPtr++;
while (!done & (num_words > 0)) { //TODO: bug - missed & ?
if (c < 0x80 && c != '\r') {
if (c == ' ') {
num_words--;
if (pad_size >= extraSpacing) {
textout += extraSpacing + space_width;
pad_size -= extraSpacing;
} else {
textout += pad_size + space_width;
pad_size = 0;
}
} else {
2016-12-18 14:13:36 -08:00
int16 char_width = _gameFont[c];
2016-12-04 14:26:44 -08:00
if (!(p_global->_drawFlags & DrawFlags::drDrawMenu)) {
textout += subtitles_x_width;
2016-12-18 14:13:36 -08:00
if (!_specialTextMode)
charsurbulle(c, 195, char_width);
textout++;
2016-12-18 14:13:36 -08:00
if (!_specialTextMode)
charsurbulle(c, 195, char_width);
textout -= subtitles_x_width + 1;
}
2016-12-18 14:13:36 -08:00
if (_specialTextMode)
charsurbulle(c, 250, char_width);
else
charsurbulle(c, 230, char_width);
textout += char_width;
}
} else
error("my_pr_bulle: Unexpected format");
2016-12-25 13:45:47 -08:00
c = *textPtr++;
if (c == 0xFF)
done = true;
2016-08-18 13:15:54 +02:00
}
textout = cur_out + subtitles_x_width * FONT_HEIGHT;
lines++;
2016-12-25 13:45:47 -08:00
textPtr--;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::charsurbulle(byte c, byte color, int16 width) {
2016-12-18 14:13:36 -08:00
byte *glyph = _gameFont + 256 + c * FONT_HEIGHT;
textoutptr = textout;
for (int16 h = 0; h < FONT_HEIGHT; h++) {
2016-09-14 23:48:01 +02:00
byte bits = *glyph++;
int16 mask = 0x80;
for (int16 w = 0; w < width; w++) {
if (bits & mask)
*textoutptr = color;
textoutptr++;
mask >>= 1;
}
textoutptr += subtitles_x_width - width;
}
}
2016-12-25 02:17:07 -08:00
// Original name: af_subtitle
void EdenGame::displaySubtitles() {
byte *src = p_subtitlesview_buf;
byte *dst = p_mainview_buf;
int16 y;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfFlag2) {
y = 174;
2016-12-25 13:45:47 -08:00
if ((p_global->_drawFlags & DrawFlags::drDrawMenu) && _numTextLines == 1)
y = 167;
2016-12-25 13:45:47 -08:00
dst += 640 * (y - _numTextLines * FONT_HEIGHT) + subtitles_x_scr_margin;
} else {
y = 174;
2016-12-25 13:45:47 -08:00
dst += 640 * (y - _numTextLines * FONT_HEIGHT) + _scrollPos + subtitles_x_scr_margin;
}
2016-12-25 02:17:07 -08:00
if (_animationActive && !_personTalking)
return;
2016-12-25 02:17:07 -08:00
savePhylacteryBackground(y);
2016-12-25 13:45:47 -08:00
for (int16 h = 0; h < _numTextLines * FONT_HEIGHT + 1; h++) {
for (int16 w = 0; w < subtitles_x_width; w++) {
2016-09-14 23:48:01 +02:00
byte c = *src++;
if (c)
*dst = c;
dst++;
2016-08-18 13:15:54 +02:00
}
dst += 640 - subtitles_x_width;
2016-08-18 13:15:54 +02:00
}
}
2016-12-25 02:17:07 -08:00
// Original name: sauvefondbulle
void EdenGame::savePhylacteryBackground(int16 y) {
2016-12-25 13:45:47 -08:00
_underSubtitlesScreenRect.top = y - _numTextLines * FONT_HEIGHT;
2016-09-30 07:48:27 +02:00
_underSubtitlesScreenRect.left = _scrollPos + subtitles_x_scr_margin;
_underSubtitlesScreenRect.right = _scrollPos + subtitles_x_scr_margin + subtitles_x_width - 1;
_underSubtitlesScreenRect.bottom = y;
_underSubtitlesBackupRect.top = 0;
2016-12-25 13:45:47 -08:00
_underSubtitlesBackupRect.bottom = _numTextLines * FONT_HEIGHT;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, p_underSubtitlesView, &_underSubtitlesScreenRect, &_underSubtitlesBackupRect);
2016-12-25 02:17:07 -08:00
_savedUnderSubtitles = true;
}
2016-12-25 02:17:07 -08:00
// Original name: restaurefondbulle
void EdenGame::restorePhylacteryBackground() {
if (!_savedUnderSubtitles)
return;
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(p_underSubtitlesView, _mainView, &_underSubtitlesBackupRect, &_underSubtitlesScreenRect);
2016-12-25 02:17:07 -08:00
_savedUnderSubtitles = false;
}
void EdenGame::af_subtitlehnm() {
2016-09-14 23:48:01 +02:00
byte *src = p_subtitlesview_buf;
2016-12-25 13:45:47 -08:00
byte *dst = _hnmViewBuf + subtitles_x_scr_margin + (158 - _numTextLines * FONT_HEIGHT) * 320;
for (int16 y = 0; y < _numTextLines * FONT_HEIGHT; y++) {
for (int16 x = 0; x < subtitles_x_width; x++) {
char c = *src++;
if (c)
*dst = c;
dst++;
}
dst += 320 - subtitles_x_width;
}
}
2016-12-04 14:26:44 -08:00
void EdenGame::patchPhrase() {
2016-12-11 13:44:58 -08:00
_sentenceBuffer[36] = 'c';
}
void EdenGame::vavapers() {
2016-12-04 14:26:44 -08:00
perso_t *perso = p_global->_characterPtr;
2016-12-11 13:44:58 -08:00
p_global->_curPersoFlags = perso->_flags;
p_global->_curPersoItems = perso->_items;
2016-12-04 14:26:44 -08:00
p_global->_curCharacterPowers = perso->_powers;
}
void EdenGame::citadelle() {
p_global->_var69++;
p_global->_varF6++;
parlemoiNormalFlag = true;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = true;
}
void EdenGame::choixzone() {
2016-12-11 13:44:58 -08:00
if (p_global->_giveObj3)
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 6;
else
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 10;
p_global->_autoDialog = false;
putObject();
}
void EdenGame::showevents1() {
p_global->_var113 = 0;
perso_ici(3);
}
2016-09-26 23:44:42 +02:00
void EdenGame::showEvents() {
2016-12-04 13:15:38 -08:00
if (p_global->_eventType && p_global->_displayFlags != DisplayFlags::dfPerson)
showevents1();
}
void EdenGame::parle_mfin() {
2016-12-04 14:26:44 -08:00
perso_t *perso = p_global->_characterPtr;
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId) {
char curobj = p_global->_curObjectId;
if (p_global->_dialogType == DialogType::dtHint)
2016-08-18 13:15:54 +02:00
return;
2016-12-18 13:09:56 -08:00
object_t *obj = getObjectPtr(p_global->_curObjectId);
2016-12-04 13:15:38 -08:00
if (p_global->_dialogType == DialogType::dtDinoItem)
2016-12-11 13:44:58 -08:00
perso = p_global->_roomCharacterPtr;
2016-12-04 13:15:38 -08:00
if (isAnswerYes()) {
loseObject(p_global->_curObjectId);
2016-10-07 00:45:08 +02:00
perso->_powers |= obj->_powerMask;
2016-08-18 13:15:54 +02:00
}
2016-10-07 00:45:08 +02:00
perso->_items |= obj->_itemMask;
2016-12-11 22:52:10 -08:00
specialObjects(perso, curobj);
return;
}
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
2016-12-11 13:44:58 -08:00
nextInfo();
2016-12-04 13:15:38 -08:00
if (!p_global->_lastInfo)
_closeCharacterDialog = true;
else {
p_global->_nextDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
}
}
void EdenGame::parlemoi_normal() {
dial_t *dial;
if (!p_global->_nextDialogPtr) {
2016-12-04 14:26:44 -08:00
perso_t *perso = p_global->_characterPtr;
if (perso) {
2016-12-04 13:15:38 -08:00
int16 num = (perso->_id << 3) | p_global->_dialogType;
2016-10-07 00:45:08 +02:00
dial = (dial_t *)getElem(gameDialogs, num);
} else {
close_perso();
return;
2016-08-18 13:15:54 +02:00
}
} else {
2016-12-04 13:15:38 -08:00
if (_closeCharacterDialog) {
close_perso();
return;
2016-08-18 13:15:54 +02:00
}
dial = p_global->_nextDialogPtr;
2016-08-18 13:15:54 +02:00
}
char ok = dial_scan(dial);
p_global->_nextDialogPtr = p_global->_dialogPtr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
if (!ok)
close_perso();
else
parle_mfin();
}
void EdenGame::parle_moi() {
2016-09-14 23:48:01 +02:00
byte r28;
char ok;
dial_t *dial;
endpersovox();
r28 = p_global->_varF6;
p_global->_varF6 = 0;
if (!r28) {
2016-12-04 13:15:38 -08:00
setChoiceNo();
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawInventory)
showObjects();
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawTopScreen)
drawTopScreen();
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId) {
if (p_global->_dialogType == DialogType::dtTalk) {
p_global->_dialogType = DialogType::dtItem;
p_global->_nextDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
2016-08-18 13:15:54 +02:00
}
parlemoi_normal();
return;
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
if (p_global->_dialogType == DialogType::dtItem) {
p_global->_dialogType = DialogType::dtTalk;
if (!_closeCharacterDialog)
p_global->_nextDialogPtr = nullptr;
2016-08-18 13:15:54 +02:00
}
if (parlemoiNormalFlag) {
parlemoi_normal();
2016-08-18 13:15:54 +02:00
return;
}
2016-12-11 13:44:58 -08:00
if (!p_global->_lastDialogPtr) {
2016-09-14 23:48:01 +02:00
int16 num = 160;
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 400)
num++;
2016-10-07 00:45:08 +02:00
dial = (dial_t *)getElem(gameDialogs, num);
2016-08-18 13:15:54 +02:00
} else
2016-12-11 13:44:58 -08:00
dial = p_global->_lastDialogPtr;
ok = dial_scan(dial);
2016-12-11 13:44:58 -08:00
p_global->_lastDialogPtr = p_global->_dialogPtr;
parlemoiNormalFlag = false;
if (!ok) {
parlemoiNormalFlag = true;
if (p_global->_var60) {
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr == &kPersons[PER_MESSAGER]) {
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
2016-12-11 13:44:58 -08:00
if (p_global->_eloiHaveNews)
parlemoi_normal();
else
close_perso();
} else
close_perso();
} else
parlemoi_normal();
} else
parle_mfin();
} else
close_perso();
}
void EdenGame::init_perso_ptr(perso_t *perso) {
p_global->_metPersonsMask1 |= perso->_partyMask;
p_global->_metPersonsMask2 |= perso->_partyMask;
p_global->_nextDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
dialogSkipFlags = DialogFlags::dfSpoken;
p_global->_var60 = 0;
2016-12-11 13:44:58 -08:00
p_global->_textToken1 = 0;
}
void EdenGame::perso1(perso_t *perso) {
p_global->_phaseActionsCount++;
if (perso == &kPersons[PER_THOO])
p_global->_phaseActionsCount--;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
init_perso_ptr(perso);
parle_moi();
}
void EdenGame::perso_normal(perso_t *perso) {
2016-12-11 13:44:58 -08:00
p_global->_lastDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
parlemoiNormalFlag = false;
perso1(perso);
}
2016-12-11 22:52:10 -08:00
// Original name: persoparle
void EdenGame::handleCharacterDialog(int16 pers) {
perso_t *perso = &kPersons[pers];
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
uint16 idx = perso->_id * 8 | p_global->_dialogType;
dialoscansvmas((dial_t *)getElem(gameDialogs, idx));
2016-10-07 23:06:10 +02:00
displayPlace();
2016-12-25 02:17:07 -08:00
displaySubtitles();
persovox();
p_global->_varCA = 0;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
}
void EdenGame::roi() {
perso_normal(&kPersons[PER_ROI]);
}
void EdenGame::dina() {
perso_normal(&kPersons[PER_DINA]);
}
void EdenGame::thoo() {
perso_normal(&kPersons[PER_THOO]);
}
void EdenGame::monk() {
perso_normal(&kPersons[PER_MONK]);
}
void EdenGame::bourreau() {
perso_normal(&kPersons[PER_BOURREAU]);
}
void EdenGame::messager() {
perso_normal(&kPersons[PER_MESSAGER]);
}
void EdenGame::mango() {
perso_normal(&kPersons[PER_MANGO]);
}
void EdenGame::eve() {
perso_normal(&kPersons[PER_EVE]);
}
void EdenGame::azia() {
perso_normal(&kPersons[PER_AZIA]);
}
void EdenGame::mammi() {
perso_t *perso;
2016-10-07 00:45:08 +02:00
for (perso = &kPersons[PER_MAMMI]; perso->_partyMask == PersonMask::pmLeader; perso++) {
2016-12-11 13:44:58 -08:00
if (perso->_roomNum == p_global->_roomNum) {
perso_normal(perso);
break;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::gardes() {
perso_normal(&kPersons[PER_GARDES]);
}
void EdenGame::bambou() {
perso_normal(&kPersons[PER_BAMBOO]);
}
void EdenGame::kabuka() {
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 0x711) perso_normal(&kPersons[PER_KABUKA]);
else bambou();
}
void EdenGame::fisher() {
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 0x902) perso_normal(&kPersons[PER_FISHER]);
else kabuka();
}
void EdenGame::dino() {
2016-12-11 13:44:58 -08:00
perso_t *perso = p_global->_roomCharacterPtr;
if (!perso)
return;
parlemoiNormalFlag = true;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags = perso->_flags;
p_global->_roomPersoItems = perso->_items;
p_global->_roomCharacterPowers = perso->_powers;
p_global->_characterPtr = perso;
init_perso_ptr(perso);
debug("beg dino talk");
parle_moi();
debug("end dino talk");
2016-12-04 14:26:44 -08:00
if (p_global->_areaNum == Areas::arWhiteArch)
return;
if (p_global->_var60)
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (pomme_q)
return;
perso = &kPersons[PER_MANGO];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmMungo)) {
perso = &kPersons[PER_DINA];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmDina)) {
perso = &kPersons[PER_EVE];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmEve)) {
perso = &kPersons[PER_GARDES];
}
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtDinoAction;
if (p_global->_curObjectId)
p_global->_dialogType = DialogType::dtDinoItem;
perso1(perso);
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftMosasaurus && !p_global->_curObjectId) {
p_global->_areaPtr->_flags |= AreaFlags::afFlag20;
lieuvava(p_global->_areaPtr);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::tyran() {
2016-12-11 13:44:58 -08:00
perso_t *perso = p_global->_roomCharacterPtr;
if (!perso)
return;
parlemoiNormalFlag = true;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags = perso->_flags;
p_global->_characterPtr = perso;
init_perso_ptr(perso);
perso = &kPersons[PER_MANGO];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmMungo)) {
perso = &kPersons[PER_DINA];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmDina)) {
perso = &kPersons[PER_EVE];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmEve)) {
perso = &kPersons[PER_GARDES];
2016-08-18 13:15:54 +02:00
}
}
}
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtDinoAction;
if (p_global->_curObjectId)
p_global->_dialogType = DialogType::dtDinoItem;
perso1(perso);
}
void EdenGame::morkus() {
perso_normal(&kPersons[PER_MORKUS]);
}
void EdenGame::comment() {
perso_t *perso = &kPersons[PER_DINA];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmDina)) {
perso = &kPersons[PER_EVE];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmEve)) {
perso = &kPersons[PER_GARDES];
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmThugg))
return;
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtHint;
perso1(perso);
}
void EdenGame::adam() {
2016-09-26 23:44:42 +02:00
resetScroll();
2016-12-04 13:15:38 -08:00
switch (p_global->_curObjectId) {
case Objects::obNone:
gotopanel();
break;
case Objects::obRoot:
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 2817
2016-12-04 14:26:44 -08:00
&& p_global->_phaseNum > 496 && p_global->_phaseNum < 512) {
bigphase1();
2016-09-26 23:44:42 +02:00
loseObject(Objects::obRoot);
p_global->_var100 = 0xFF;
2016-09-26 23:44:42 +02:00
quitMirror();
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MESSAGER);
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent3;
2016-09-26 23:44:42 +02:00
showEvents();
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (pomme_q)
return;
close_perso();
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MESSAGER);
2016-12-11 13:44:58 -08:00
p_global->_roomNum = 2818;
2016-12-04 14:26:44 -08:00
p_global->_areaNum = Areas::arWhiteArch;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
2016-12-11 13:44:58 -08:00
p_global->_valleyVidNum = 0;
p_global->_var102 = 6;
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = MusicType::mtNormal;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
} else {
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtHint;
perso1(&kPersons[PER_EVE]);
2016-08-18 13:15:54 +02:00
}
break;
case Objects::obShell:
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtHint;
perso1(&kPersons[PER_THOO]);
break;
case Objects::obFlute:
case Objects::obTrumpet:
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType) {
2016-09-26 23:44:42 +02:00
quitMirror();
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
dino();
} else
comment();
break;
case Objects::obTablet1:
case Objects::obTablet2:
case Objects::obTablet3:
case Objects::obTablet4:
case Objects::obTablet5:
case Objects::obTablet6: {
2016-12-04 14:26:44 -08:00
if ((p_global->_partyOutside & PersonMask::pmDina)
&& p_global->_curObjectId == Objects::obTablet1 && p_global->_phaseNum == 370)
2016-12-19 22:32:40 -08:00
incPhase();
2016-12-04 13:15:38 -08:00
char *objvid = &kTabletView[(p_global->_curObjectId - Objects::obTablet1) * 2];
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(*objvid++);
int16 vid = 84;
2016-10-07 00:45:08 +02:00
if (!object->_count)
vid = *objvid;
bars_out();
2016-12-18 14:13:36 -08:00
_specialTextMode = true;
2016-09-26 23:44:42 +02:00
playHNM(vid);
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
p_global->_var102 = 16;
showBars();
gametomiroir(0);
}
break;
case Objects::obApple:
case Objects::obShroom:
case Objects::obBadShroom:
case Objects::obNest:
case Objects::obFullNest:
case Objects::obDrum:
2016-12-11 13:44:58 -08:00
if (p_global->_party & PersonMask::pmThugg) {
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtHint;
perso1(&kPersons[PER_GARDES]);
2016-08-18 13:15:54 +02:00
}
break;
default:
comment();
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
2016-12-04 13:15:38 -08:00
// Original name: oui and init_oui
void EdenGame::setChoiceYes() {
_lastDialogChoice = true;
}
2016-12-04 13:15:38 -08:00
// Original name: non and init_non
void EdenGame::setChoiceNo() {
_lastDialogChoice = false;
}
2016-12-04 13:15:38 -08:00
// Original name: verif_oui
bool EdenGame::isAnswerYes() {
return _lastDialogChoice;
}
2016-12-04 13:15:38 -08:00
// Original name: SpcChampi
void EdenGame::specialMushroom(perso_t *perso) {
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr->_flags |= AreaFlags::afFlag2;
p_global->_curAreaFlags |= AreaFlags::afFlag2;
}
2016-12-04 13:15:38 -08:00
// Original name: SpcNidv
void EdenGame::specialNidv(perso_t *perso) {
if (!isAnswerYes())
return;
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags |= PersonFlags::pf10;
p_global->_gameFlags |= GameFlags::gfFlag400;
if (p_global->_characterPtr == &kPersons[PER_EVE]) {
p_global->_areaPtr->_flags |= AreaFlags::afFlag4;
p_global->_curAreaFlags |= AreaFlags::afFlag4;
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pfInParty;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags |= PersonFlags::pfInParty;
lieuvava(p_global->_areaPtr);
} else {
2016-10-07 00:45:08 +02:00
perso->_flags &= ~PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags &= ~PersonFlags::pf10;
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 14:26:44 -08:00
// Original name: SpcNido
void EdenGame::specialNido(perso_t *perso) {
if (perso == &kPersons[PER_GARDES])
2016-12-04 14:26:44 -08:00
giveObject();
}
2016-12-04 14:26:44 -08:00
// Original name: SpcPomme
void EdenGame::specialApple(perso_t *perso) {
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr->_flags |= AreaFlags::afFlag8;
p_global->_curAreaFlags |= AreaFlags::afFlag8;
p_global->_gameFlags |= GameFlags::gfFlag200;
}
2016-12-04 14:26:44 -08:00
// Original name: SpcOr
void EdenGame::specialGold(perso_t *perso) {
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
2016-12-04 14:26:44 -08:00
perso->_items = _curSpecialObject->_itemMask;
p_global->_roomPersoItems = _curSpecialObject->_itemMask;
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf10;
perso->_flags &= ~PersonFlags::pfInParty;
perso->_targetLoc = 0;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr->_flags |= AreaFlags::afGaveGold;
p_global->_curAreaFlags |= AreaFlags::afGaveGold;
if (p_global->_phaseNum == 226)
2016-12-19 22:32:40 -08:00
incPhase();
}
2016-12-04 14:26:44 -08:00
// Original name: SpcPrisme
void EdenGame::specialPrism(perso_t *perso) {
if (perso == &kPersons[PER_DINA]) {
2016-12-04 14:26:44 -08:00
if (p_global->_partyOutside & PersonMask::pmMonk)
p_global->_gameFlags |= GameFlags::gfPrismAndMonk;
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 14:26:44 -08:00
// Original name: SpcTalisman
void EdenGame::specialTalisman(perso_t *perso) {
if (perso == &kPersons[PER_DINA])
2016-12-19 22:32:40 -08:00
AddToParty(PER_DINA);
}
2016-12-04 14:26:44 -08:00
// Original name: SpcMasque
void EdenGame::specialMask(perso_t *perso) {
if (perso == &kPersons[PER_BAMBOO]) {
dialautoon();
parlemoiNormalFlag = true;
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 14:26:44 -08:00
// Original name: SpcSac
void EdenGame::specialBag(perso_t *perso) {
2016-12-11 13:44:58 -08:00
if (p_global->_textToken1 != 3)
return;
if (perso == &kPersons[PER_KABUKA] || perso == &kPersons[PER_MAMMI_3])
2016-12-04 14:26:44 -08:00
loseObject(_curSpecialObject->_id);
}
2016-12-04 14:26:44 -08:00
// Original name: SpcTrompet
void EdenGame::specialTrumpet(perso_t *perso) {
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
p_global->_var54 = 4;
2016-12-04 14:26:44 -08:00
winObject(Objects::obTrumpet);
p_global->_drawFlags |= DrawFlags::drDrawInventory;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = true;
2016-12-11 13:44:58 -08:00
tyranDies(p_global->_roomCharacterPtr);
}
2016-12-04 14:26:44 -08:00
// Original name: SpcArmes
void EdenGame::specialWeapons(perso_t *perso) {
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
2016-12-04 14:26:44 -08:00
perso->_powers = _curSpecialObject->_powerMask;
p_global->_roomCharacterPowers = _curSpecialObject->_powerMask;
giveObject();
}
2016-12-04 14:26:44 -08:00
// Original name: SpcInstru
void EdenGame::specialInstrument(perso_t *perso) {
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
if (perso == &kPersons[PER_MONK]) {
2016-12-04 14:26:44 -08:00
p_global->_partyInstruments &= ~1; //TODO: check me
if (_curSpecialObject->_id == Objects::obRing) {
p_global->_partyInstruments |= 1;
p_global->_monkGotRing++; //TODO: |= 1 ?
2016-08-18 13:15:54 +02:00
}
}
if (perso == &kPersons[PER_GARDES]) {
2016-12-04 14:26:44 -08:00
p_global->_partyInstruments &= ~2;
if (_curSpecialObject->_id == Objects::obDrum)
p_global->_partyInstruments |= 2;
2016-08-18 13:15:54 +02:00
}
2016-12-04 14:26:44 -08:00
perso->_powers = _curSpecialObject->_powerMask;
p_global->_curCharacterPowers = _curSpecialObject->_powerMask;
giveObject();
}
2016-08-18 13:15:54 +02:00
2016-12-04 14:26:44 -08:00
// Original name: SpcOeuf
void EdenGame::specialEgg(perso_t *perso) {
2016-12-04 13:15:38 -08:00
if (!isAnswerYes())
return;
2016-12-04 14:26:44 -08:00
_gameIcons[131]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 62;
dialautoon();
}
2016-12-04 14:26:44 -08:00
// Original name: TyranMeurt
void EdenGame::tyranDies(perso_t *perso) {
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf80;
perso->_roomNum = 0;
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannIn);
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterType = 0;
p_global->_roomCharacterFlags = 0;
p_global->_chronoFlag = 0;
}
2016-12-11 22:52:10 -08:00
void EdenGame::specialObjects(perso_t *perso, char objid) {
2016-12-04 22:07:17 -08:00
#pragma pack(push, 1)
2016-12-04 14:26:44 -08:00
struct SpecialObject {
int8 _characterType;
int8 _objectId;
2016-12-04 13:15:38 -08:00
void (EdenGame::*dispFct)(perso_t *perso);
};
2016-12-04 22:07:17 -08:00
#pragma pack(pop)
2016-12-04 14:26:44 -08:00
static SpecialObject kSpecialObjectActions[] = {
2016-12-04 13:15:38 -08:00
// persoType, objectId, dispFct
{ PersonFlags::pfType8, Objects::obShroom, &EdenGame::specialMushroom },
{ PersonFlags::pftTriceraptor, Objects::obNest, &EdenGame::specialNidv },
2016-12-04 14:26:44 -08:00
{ PersonFlags::pfType0, Objects::obFullNest, &EdenGame::specialNido },
{ PersonFlags::pftMosasaurus, Objects::obApple, &EdenGame::specialApple },
{ PersonFlags::pftVelociraptor, Objects::obGold, &EdenGame::specialGold },
{ PersonFlags::pfType0, Objects::obPrism, &EdenGame::specialPrism },
{ PersonFlags::pfType0, Objects::obTalisman, &EdenGame::specialTalisman },
{ PersonFlags::pfType2, Objects::obMaskOfDeath, &EdenGame::specialMask },
{ PersonFlags::pfType2, Objects::obMaskOfBonding, &EdenGame::specialMask },
{ PersonFlags::pfType2, Objects::obMaskOfBirth, &EdenGame::specialMask },
{ PersonFlags::pfType0, Objects::obBag, &EdenGame::specialBag },
{ PersonFlags::pfType2, Objects::obBag, &EdenGame::specialBag },
{ PersonFlags::pftTyrann, Objects::obTrumpet, &EdenGame::specialTrumpet },
{ PersonFlags::pftVelociraptor, Objects::obEyeInTheStorm, &EdenGame::specialWeapons },
{ PersonFlags::pftVelociraptor, Objects::obSkyHammer, &EdenGame::specialWeapons },
{ PersonFlags::pftVelociraptor, Objects::obFireInTheClouds, &EdenGame::specialWeapons },
{ PersonFlags::pftVelociraptor, Objects::obWithinAndWithout, &EdenGame::specialWeapons },
{ PersonFlags::pftVelociraptor, Objects::obEyeInTheCyclone, &EdenGame::specialWeapons },
{ PersonFlags::pftVelociraptor, Objects::obRiverThatWinds, &EdenGame::specialWeapons },
{ PersonFlags::pfType0, Objects::obTrumpet, &EdenGame::specialInstrument },
{ PersonFlags::pfType0, Objects::obDrum, &EdenGame::specialInstrument },
{ PersonFlags::pfType0, Objects::obRing, &EdenGame::specialInstrument },
{ PersonFlags::pfType0, Objects::obEgg, &EdenGame::specialEgg },
{ -1, -1, nullptr }
};
2016-12-11 22:52:10 -08:00
2016-12-04 14:26:44 -08:00
char characterType = perso->_flags & PersonFlags::pfTypeMask;
_curSpecialObject = &_objects[objid - 1];
2016-12-11 22:52:10 -08:00
for (SpecialObject *spcObj = kSpecialObjectActions; spcObj->_characterType != -1; spcObj++) {
if (spcObj->_objectId == objid && spcObj->_characterType == characterType) {
(this->*spcObj->dispFct)(perso);
break;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::dialautoon() {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 4;
p_global->_autoDialog = true;
putObject();
}
void EdenGame::dialautooff() {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 0x10;
p_global->_autoDialog = false;
}
void EdenGame::follow() {
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pfType12) {
2016-12-11 13:44:58 -08:00
debug("follow: hiding person %ld", p_global->_roomCharacterPtr - kPersons);
p_global->_roomCharacterPtr->_flags |= PersonFlags::pf80;
p_global->_roomCharacterPtr->_roomNum = 0;
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag8;
_gameIcons[123]._objectId = 18;
_gameIcons[124]._objectId = 35;
_gameIcons[125]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 56;
} else
2016-12-19 22:32:40 -08:00
AddCharacterToParty();
}
void EdenGame::dialonfollow() {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 4;
p_global->_autoDialog = true;
follow();
}
void EdenGame::abortdial() {
p_global->_varF6++;
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType != PersonFlags::pftTriceraptor || p_global->_characterPtr != &kPersons[PER_EVE])
return;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr->_flags |= AreaFlags::afFlag4;
p_global->_curAreaFlags |= AreaFlags::afFlag4;
2016-12-11 13:44:58 -08:00
p_global->_roomCharacterPtr->_flags |= PersonFlags::pfInParty;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterFlags |= PersonFlags::pfInParty;
lieuvava(p_global->_areaPtr);
}
void EdenGame::narrateur() {
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & DisplayFlags::dfFlag1))
return;
2016-12-11 13:44:58 -08:00
if (!p_global->_narratorSequence) {
if (p_global->_var6A == p_global->_var69)
goto skip;
2016-12-15 22:47:29 -08:00
buildCitadel();
}
p_global->_varF5 |= 0x80;
p_global->_varF2 &= ~1; //TODO: check me
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = &kPersons[PER_UNKN_156];
p_global->_var60 = 0;
2016-12-04 13:15:38 -08:00
p_global->_eventType = 0;
p_global->_var103 = 69;
if (dialo_even(&kPersons[PER_UNKN_156])) {
2016-12-11 13:44:58 -08:00
p_global->_narratorDialogPtr = p_global->_dialogPtr;
dialautoon();
p_global->_varF2 |= 1;
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (pomme_q)
2016-08-18 13:15:54 +02:00
return;
endpersovox();
2016-12-11 13:44:58 -08:00
while (dialoscansvmas(p_global->_narratorDialogPtr)) {
p_global->_narratorDialogPtr = p_global->_dialogPtr;
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (pomme_q)
return;
endpersovox();
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
p_global->_narratorDialogPtr = p_global->_dialogPtr;
p_global->_var102 = 0;
p_global->_var103 = 0;
close_perso();
2016-12-04 14:26:44 -08:00
lieuvava(p_global->_areaPtr);
2016-12-11 13:44:58 -08:00
if (p_global->_narratorSequence == 8)
deplaval(134);
2016-08-18 13:15:54 +02:00
}
p_global->_var103 = 0;
2016-12-11 13:44:58 -08:00
if (p_global->_narratorSequence == 10) {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MESSAGER);
AddToParty(PER_EVE);
AddToParty(PER_MONK);
AddToParty(PER_GARDES);
removeFromParty(PER_MANGO);
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews = 0;
deplaval(139);
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventD;
2016-09-26 23:44:42 +02:00
showEvents();
p_global->_varF5 &= ~0x80;
skip:
;
p_global->_varF2 &= ~1; //TODO: check me
2016-12-11 13:44:58 -08:00
if (p_global->_narratorSequence > 50 && p_global->_narratorSequence <= 80)
p_global->_endGameFlag = 50;
if (p_global->_narratorSequence == 3)
setChrono(1200);
p_global->_narratorSequence = 0;
}
void EdenGame::vrf_phrases_file() {
2016-09-14 23:48:01 +02:00
int16 num = 3;
2016-10-24 22:02:43 +02:00
if (p_global->_dialogPtr < (dial_t *)getElem(gameDialogs, 48))
num = 1;
2016-10-24 22:02:43 +02:00
else if (p_global->_dialogPtr < (dial_t *)getElem(gameDialogs, 128))
num = 2;
2016-12-11 13:44:58 -08:00
p_global->_textBankIndex = num;
if (p_global->_prefLanguage)
num += (p_global->_prefLanguage - 1) * 3;
if (num == lastPhrasesFile)
return;
lastPhrasesFile = num;
num += 404;
2016-12-07 15:04:25 -08:00
loadRawFile(num, gamePhrases);
verifh(gamePhrases);
}
2016-09-14 23:48:01 +02:00
byte *EdenGame::gettxtad(int16 id) {
vrf_phrases_file();
2016-10-07 00:45:08 +02:00
return (byte *)getElem(gamePhrases, id - 1);
}
void EdenGame::gotocarte() {
2016-12-19 22:32:40 -08:00
Goto *go = &gotos[_curSpot2->_objectId];
endpersovox();
2016-12-15 22:47:29 -08:00
byte newArea = go->_areaNum;
p_global->_newRoomNum = (go->_areaNum << 8) | 1;
2016-12-11 13:44:58 -08:00
p_global->_newLocation = 1;
p_global->_prevLocation = p_global->_roomNum & 0xFF;
char curArea = p_global->_roomNum >> 8;
2016-12-15 22:47:29 -08:00
if (curArea == go->_areaNum)
newArea = 0;
else {
2016-12-15 22:47:29 -08:00
for (; go->_curAreaNum != 0xFF; go++) {
if (go->_curAreaNum == curArea)
break;
}
2016-12-15 22:47:29 -08:00
if (go->_areaNum == 0xFF)
return;
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etGotoArea | newArea;
setChoiceYes();
showevents1();
2016-12-04 13:15:38 -08:00
waitEndSpeak();
if (pomme_q)
return;
close_perso();
2016-12-04 13:15:38 -08:00
if (isAnswerYes())
gotolieu(go);
}
void EdenGame::record() {
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId)
return;
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr >= &kPersons[PER_UNKN_18C])
return;
2016-12-04 13:15:38 -08:00
if (p_global->_eventType == EventType::etEventE || p_global->_eventType >= EventType::etGotoArea)
return;
for (tape_t *tape = tapes; tape != tapes + MAX_TAPES; tape++) {
2016-12-11 13:44:58 -08:00
if (tape->_textNum == p_global->_textNum)
return;
}
tape_t *tape = tapes;
for (int16 i = 0; i < MAX_TAPES - 1; i++) {
2016-10-07 23:06:10 +02:00
tape->_textNum = tape[+1]._textNum;
tape->_perso = tape[+1]._perso;
tape->_party = tape[+1]._party;
tape->_roomNum = tape[+1]._roomNum;
2016-12-11 13:44:58 -08:00
tape->_backgroundBankNum = tape[+1]._backgroundBankNum;
2016-10-07 23:06:10 +02:00
tape->_dialog = tape[+1]._dialog;
tape++;
}
2016-12-04 14:26:44 -08:00
perso_t *perso = p_global->_characterPtr;
if (perso == &kPersons[PER_EVE])
2016-12-04 14:26:44 -08:00
perso = p_global->_phaseNum >= 352 ? &kPersons[PER_UNKN_372]
: &kPersons[PER_UNKN_402];
2016-12-11 13:44:58 -08:00
tape->_textNum = p_global->_textNum;
2016-10-07 23:06:10 +02:00
tape->_perso = perso;
2016-12-11 13:44:58 -08:00
tape->_party = p_global->_party;
tape->_roomNum = p_global->_roomNum;
tape->_backgroundBankNum = p_global->_roomBackgroundBankNum;
2016-10-24 22:02:43 +02:00
tape->_dialog = p_global->_dialogPtr;
}
bool EdenGame::dial_scan(dial_t *dial) {
2016-12-11 13:44:58 -08:00
if (p_global->_numGiveObjs) {
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & DisplayFlags::dfFlag2))
showObjects();
2016-12-11 13:44:58 -08:00
p_global->_numGiveObjs = 0;
2016-08-18 13:15:54 +02:00
}
2016-10-24 22:02:43 +02:00
p_global->_dialogPtr = dial;
vavapers();
2016-12-11 13:44:58 -08:00
p_global->_sentenceBufferPtr = _sentenceBuffer;
byte hidx, lidx;
uint16 mask;
2016-10-24 22:02:43 +02:00
for (;; p_global->_dialogPtr++) {
for (;; p_global->_dialogPtr++) {
if (p_global->_dialogPtr->_flags == -1 && p_global->_dialogPtr->_condNumLow == -1)
return false;
2016-10-24 22:02:43 +02:00
byte flags = p_global->_dialogPtr->_flags;
2016-12-11 13:44:58 -08:00
p_global->_dialogFlags = flags;
if (!(flags & DialogFlags::dfSpoken) || (flags & DialogFlags::dfRepeatable)) {
2016-10-24 22:02:43 +02:00
hidx = (p_global->_dialogPtr->_textCondHiMask >> 6) & 3;
lidx = p_global->_dialogPtr->_condNumLow;
if (flags & 0x10)
hidx |= 4;
if (testcondition(((hidx << 8) | lidx) & 0x7FF))
break;
} else {
if (flags & dialogSkipFlags)
continue;
2016-10-24 22:02:43 +02:00
hidx = (p_global->_dialogPtr->_textCondHiMask >> 6) & 3;
lidx = p_global->_dialogPtr->_condNumLow;
if (flags & 0x10)
hidx |= 4;
if (testcondition(((hidx << 8) | lidx) & 0x7FF))
break;
}
2016-08-18 13:15:54 +02:00
}
char bidx = (p_global->_dialogPtr->_textCondHiMask >> 2) & 0xF;
if (!bidx)
goto no_perso; //TODO: rearrange
2016-12-11 13:44:58 -08:00
mask = (p_global->_party | p_global->_partyOutside) & (1 << (bidx - 1));
if (mask)
break;
}
perso_t *perso;
2016-12-11 13:44:58 -08:00
for (perso = kPersons; !(perso->_partyMask == mask && perso->_roomNum == p_global->_roomNum); perso++)
; //Find matching
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
init_perso_ptr(perso);
no_perso();
no_perso:
;
2016-10-24 22:02:43 +02:00
hidx = p_global->_dialogPtr->_textCondHiMask;
lidx = p_global->_dialogPtr->_textNumLow;
2016-12-11 13:44:58 -08:00
p_global->_textNum = ((hidx << 8) | lidx) & 0x3FF;
if (p_global->_sentenceBufferPtr != _sentenceBuffer) {
for (int16 i = 0; i < 32; i++)
SysBeep(1);
} else
my_bulle();
if (!dword_30B04) {
static void (EdenGame::*talk_subject[])() = {
2016-12-04 13:15:38 -08:00
&EdenGame::setChoiceYes,
&EdenGame::setChoiceNo,
&EdenGame::handleEloiDeparture,
&EdenGame::dialautoon,
&EdenGame::dialautooff,
&EdenGame::stay_here,
&EdenGame::follow,
&EdenGame::citadelle,
&EdenGame::dialonfollow,
&EdenGame::abortdial,
2016-12-19 22:32:40 -08:00
&EdenGame::incPhase,
&EdenGame::bigphase,
2016-12-04 14:26:44 -08:00
&EdenGame::giveObject,
&EdenGame::choixzone,
2016-12-11 22:52:10 -08:00
&EdenGame::lostObject
};
2016-10-24 22:02:43 +02:00
char pnum = p_global->_dialogPtr->_flags & 0xF;
if (pnum)
(this->*talk_subject[pnum - 1])();
p_global->_var60 = 1;
2016-10-24 22:02:43 +02:00
p_global->_dialogPtr->_flags |= DialogFlags::dfSpoken;
p_global->_dialogPtr++;
}
2016-12-04 13:15:38 -08:00
if (p_global->_dialogType != DialogType::dtInspect) {
record();
2016-12-25 02:17:07 -08:00
getDataSync();
2016-12-04 14:26:44 -08:00
showCharacter();
persovox();
}
return true;
}
bool EdenGame::dialoscansvmas(dial_t *dial) {
2016-12-04 13:15:38 -08:00
byte oldFlag = dialogSkipFlags;
dialogSkipFlags = DialogFlags::df20;
2016-12-04 13:15:38 -08:00
bool res = dial_scan(dial);
dialogSkipFlags = oldFlag;
return res;
}
bool EdenGame::dialo_even(perso_t *perso) {
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
int num = (perso->_id << 3) | DialogType::dtEvent;
dial_t *dial = (dial_t *)getElem(gameDialogs, num);
bool res = dialoscansvmas(dial);
2016-12-11 13:44:58 -08:00
p_global->_lastDialogPtr = nullptr;
parlemoiNormalFlag = false;
return res;
}
void EdenGame::stay_here() {
2016-12-11 13:44:58 -08:00
if (p_global->_characterPtr == &kPersons[PER_DINA] && p_global->_roomNum == 260)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag1000;
2016-12-19 22:32:40 -08:00
removeCharacterFromParty();
}
2016-09-14 23:48:01 +02:00
void EdenGame::mort(int16 vid) {
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(vid);
fadeToBlack(2);
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
CLBlitter_FillView(_mainView, 0);
showBars();
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 51;
p_global->_newMusicType = MusicType::mtNormal;
musique();
musicspy();
}
void EdenGame::evenchrono() {
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & DisplayFlags::dfFlag1))
return;
2016-12-11 13:44:58 -08:00
uint16 oldGameTime = p_global->_gameTime;
2016-12-18 14:13:36 -08:00
_currentTime = _vm->_timerTicks / 100;
p_global->_gameTime = _currentTime;
2016-12-11 13:44:58 -08:00
if (p_global->_gameTime <= oldGameTime)
return;
heurepasse();
2016-12-04 14:26:44 -08:00
if (!(p_global->_chronoFlag & 1))
return;
2016-12-11 13:44:58 -08:00
p_global->_chrono -= 200;
if (p_global->_chrono == 0)
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag |= 2;
if (!(p_global->_chronoFlag & 2))
return;
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag = 0;
2016-12-11 13:44:58 -08:00
p_global->_chrono = 0;
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftTyrann) {
2016-09-14 23:48:01 +02:00
int16 vid = 272;
2016-12-11 13:44:58 -08:00
if (p_global->_curRoomFlags & 0xC0) {
vid += 2;
2016-12-11 13:44:58 -08:00
if ((p_global->_curRoomFlags & 0xC0) != 0x80) {
vid += 2;
mort(vid);
2016-08-18 13:15:54 +02:00
return;
}
}
if (p_global->_areaNum == Areas::arUluru || p_global->_areaNum == Areas::arTamara)
mort(vid);
else
mort(vid + 1);
return;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 2817) {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MESSAGER);
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag40;
dialautoon();
} else
2016-12-19 22:32:40 -08:00
handleEloiReturn();
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent10;
2016-09-26 23:44:42 +02:00
showEvents();
}
2016-12-11 13:44:58 -08:00
// Original name: chronoon
void EdenGame::setChrono(int16 t) {
p_global->_chrono = t;
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag = 1;
}
2016-09-14 23:48:01 +02:00
void EdenGame::prechargephrases(int16 vid) {
perso_t *perso = &kPersons[PER_MORKUS];
if (vid == 170)
perso = &kPersons[PER_UNKN_156];
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
int num = (perso->_id << 3) | p_global->_dialogType;
dial_t *dial = (dial_t *)getElem(gameDialogs, num);
dialoscansvmas(dial);
}
void EdenGame::effet1() {
rectanglenoir32();
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
setRS1(0, 0, 16 - 1, 4 - 1);
2016-12-18 14:13:36 -08:00
int y = _mainView->_normal._dstTop;
for (int16 i = 16; i <= 96; i += 4) {
2016-12-18 14:13:36 -08:00
for (int x = _mainView->_normal._dstLeft; x < _mainView->_normal._dstLeft + 320; x += 16) {
setRD1(x, y + i, x + 16 - 1, y + i + 4 - 1);
2016-11-30 22:51:15 -08:00
CLBlitter_CopyViewRect(p_view2, _vm->ScreenView, &rect_src, &rect_dst);
setRD1(x, y + 192 - i, x + 16 - 1, y + 192 - i + 4 - 1);
2016-11-30 22:51:15 -08:00
CLBlitter_CopyViewRect(p_view2, _vm->ScreenView, &rect_src, &rect_dst);
2016-08-18 13:15:54 +02:00
}
CLBlitter_UpdateScreen();
wait(1);
2016-08-18 13:15:54 +02:00
}
} else {
setRS1(0, 0, 16 * 2 - 1, 4 * 2 - 1);
2016-12-18 14:13:36 -08:00
int y = _mainView->_zoom._dstTop;
for (int16 i = 16 * 2; i <= 96 * 2; i += 4 * 2) {
2016-12-18 14:13:36 -08:00
for (int x = _mainView->_zoom._dstLeft; x < _mainView->_zoom._dstLeft + 320 * 2; x += 16 * 2) {
setRD1(x, y + i, x + 16 * 2 - 1, y + i + 4 * 2 - 1);
2016-11-30 22:51:15 -08:00
CLBlitter_CopyViewRect(p_view2, _vm->ScreenView, &rect_src, &rect_dst);
setRD1(x, y + 192 * 2 - i, x + 16 * 2 - 1, y + 192 * 2 - i + 4 * 2 - 1);
2016-11-30 22:51:15 -08:00
CLBlitter_CopyViewRect(p_view2, _vm->ScreenView, &rect_src, &rect_dst);
2016-08-18 13:15:54 +02:00
}
wait(1);
2016-08-18 13:15:54 +02:00
}
}
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
2016-12-18 14:13:36 -08:00
_mainView->_normal._height = 2;
_mainView->_zoom._height = 4;
int16 ny = _mainView->_normal._dstTop;
int16 dy = _mainView->_zoom._dstTop;
for (int16 i = 0; i < 100; i += 2) {
2016-12-18 14:13:36 -08:00
_mainView->_normal._srcTop = 99 - i;
_mainView->_zoom._srcTop = 99 - i;
_mainView->_normal._dstTop = 99 - i + ny;
_mainView->_zoom._dstTop = (99 - i) * 2 + dy;
CLBlitter_CopyView2Screen(_mainView);
_mainView->_normal._srcTop = 100 + i;
_mainView->_zoom._srcTop = 100 + i;
_mainView->_normal._dstTop = 100 + i + ny;
_mainView->_zoom._dstTop = (100 + i) * 2 + dy;
CLBlitter_CopyView2Screen(_mainView);
CLBlitter_UpdateScreen();
wait(1);
}
2016-12-18 14:13:36 -08:00
_mainView->_normal._height = 200;
_mainView->_zoom._height = 400;
_mainView->_normal._srcTop = 0;
_mainView->_zoom._srcTop = 0;
_mainView->_normal._dstTop = ny;
_mainView->_zoom._dstTop = dy;
p_global->_varF1 = 0;
}
void EdenGame::effet2() {
static int16 pattern1[] = {0, 1, 2, 3, 7, 11, 15, 14, 13, 12, 8, 4, 5, 6, 10, 9};
static int16 pattern2[] = {0, 15, 1, 14, 2, 13, 3, 12, 7, 8, 11, 4, 5, 10, 6, 9};
static int16 pattern3[] = {0, 2, 5, 7, 8, 10, 13, 15, 1, 3, 4, 6, 9, 11, 12, 14};
static int16 pattern4[] = {0, 3, 15, 12, 1, 7, 14, 8, 2, 11, 13, 4, 5, 6, 10, 9};
static int eff2pat = 0;
if (p_global->_var103 == 69) {
effet4();
return;
2016-08-18 13:15:54 +02:00
}
switch (++eff2pat) {
case 1:
colimacon(pattern1);
break;
case 2:
colimacon(pattern2);
break;
case 3:
colimacon(pattern3);
break;
case 4:
colimacon(pattern4);
eff2pat = 0;
break;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::effet3() {
CLPalette_GetLastPalette(oldPalette);
for (uint16 i = 0; i < 6; i++) {
for (uint16 c = 0; c < 256; c++) {
newColor.r = oldPalette[c].r >> i;
newColor.g = oldPalette[c].g >> i;
newColor.b = oldPalette[c].b >> i;
CLPalette_SetRGBColor(newPalette, c, &newColor);
}
CLPalette_Send2Screen(newPalette, 0, 256);
wait(1);
}
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
for (uint16 i = 0; i < 6; i++) {
for (uint16 c = 0; c < 256; c++) {
2016-12-25 13:45:47 -08:00
newColor.r = _globalPalette[c].r >> (5 - i);
newColor.g = _globalPalette[c].g >> (5 - i);
newColor.b = _globalPalette[c].b >> (5 - i);
CLPalette_SetRGBColor(newPalette, c, &newColor);
}
CLPalette_Send2Screen(newPalette, 0, 256);
wait(1);
}
}
void EdenGame::effet4() {
2016-09-14 23:48:01 +02:00
byte *scr, *pix, *r24, *r25, *r30, c;
int16 x, y;
int16 r17, r23, r16, r18, r19, r22, r27, r31;
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
// Unused
2016-11-30 22:51:15 -08:00
// int16 w = _vm->ScreenView->_width;
// int16 h = _vm->ScreenView->_height;
int16 ww = _vm->ScreenView->_pitch;
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
2016-12-18 14:13:36 -08:00
x = _mainView->_normal._dstLeft;
y = _mainView->_normal._dstTop;
for (int16 i = 32; i > 0; i -= 2) {
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16) * ww + x;
2016-12-18 14:13:36 -08:00
pix = _mainView->_bufferPtr + 16 * 640;
r17 = 320 / i;
r23 = 320 - 320 / i * i; //TODO: 320 % i ?
r16 = 160 / i;
r18 = 160 - 160 / i * i; //TODO: 160 % i ?
for (r19 = r16; r19 > 0; r19--) {
r24 = scr;
r25 = pix;
for (r22 = r17; r22 > 0; r22--) {
c = *r25;
r25 += i;
r30 = r24;
for (r27 = i; r27 > 0; r27--) {
for (r31 = i; r31 > 0; r31--)
*r30++ = c;
r30 += ww - i;
}
r24 += i;
2016-08-18 13:15:54 +02:00
}
if (r23) {
c = *r25;
r30 = r24;
for (r27 = i; r27 > 0; r27--) {
for (r31 = r23; r31 > 0; r31--)
*r30++ = c;
r30 += ww - r23;
2016-08-18 13:15:54 +02:00
}
}
scr += i * ww;
pix += i * 640;
}
if (r18) {
r24 = scr;
r25 = pix;
for (r22 = r17; r22 > 0; r22--) {
c = *r25;
r25 += i;
r30 = r24;
for (r27 = r18; r27 > 0; r27--) {
for (r31 = i; r31 > 0; r31--)
*r30++ = c;
r30 += ww - i;
2016-08-18 13:15:54 +02:00
}
r24 += i;
}
if (r23) {
c = *r25;
r30 = r24;
for (r27 = r18; r27 > 0; r27--) {
for (r31 = r23; r31 > 0; r31--)
*r30++ = c;
r30 += ww - r23;
2016-08-18 13:15:54 +02:00
}
}
}
CLBlitter_UpdateScreen();
wait(3);
2016-08-18 13:15:54 +02:00
}
} else {
2016-12-18 14:13:36 -08:00
x = _mainView->_zoom._dstLeft;
y = _mainView->_zoom._dstTop;
for (int16 i = 32; i > 0; i -= 2) {
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16 * 2) * ww + x;
2016-12-18 14:13:36 -08:00
pix = _mainView->_bufferPtr + 16 * 640;
r17 = 320 / i;
r23 = 320 % i;
r16 = 160 / i;
r18 = 160 % i;
for (r19 = r16; r19 > 0; r19--) {
r24 = scr;
r25 = pix;
for (r22 = r17; r22 > 0; r22--) {
c = *r25;
r25 += i;
r30 = r24;
for (r27 = i * 2; r27 > 0; r27--) {
for (r31 = i * 2; r31 > 0; r31--)
*r30++ = c;
r30 += ww - i * 2;
2016-08-18 13:15:54 +02:00
}
r24 += i * 2;
}
if (r23) {
c = *r25;
r30 = r24;
for (r27 = i * 2; r27 > 0; r27--) {
for (r31 = r23 * 2; r31 > 0; r31--)
*r30++ = c;
r30 += ww - r23 * 2;
}
}
scr += i * ww * 2;
pix += i * 640;
2016-08-18 13:15:54 +02:00
}
if (r18) {
r24 = scr;
r25 = pix;
for (r22 = r17; r22 > 0; r22--) {
c = *r25;
r25 += i;
r30 = r24;
for (r27 = r18 * 2; r27 > 0; r27--) {
for (r31 = i * 2; r31 > 0; r31--)
*r30++ = c;
r30 += ww - i * 2;
}
r24 += i * 2;
}
if (r23) {
c = *r25;
r30 = r24;
for (r27 = i * 2; r27 > 0; r27--) {
for (r31 = r23 * 2; r31 > 0; r31--)
*r30++ = c;
r30 += ww - r23 * 2;
}
}
}
wait(3);
2016-08-18 13:15:54 +02:00
}
}
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
}
void EdenGame::ClearScreen() {
2016-09-14 23:48:01 +02:00
byte *scr;
int16 x, y;
// Unused
2016-11-30 22:51:15 -08:00
// int16 w = _vm->ScreenView->_width;
// int16 h = _vm->ScreenView->_height;
int16 ww = _vm->ScreenView->_pitch;
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
2016-12-18 14:13:36 -08:00
x = _mainView->_normal._dstLeft;
y = _mainView->_normal._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16) * ww + x;
for (int16 yy = 0; yy < 160; yy++) {
for (int16 xx = 0; xx < 320; xx++)
*scr++ = 0;
scr += ww - 320;
}
} else {
2016-12-18 14:13:36 -08:00
x = _mainView->_zoom._dstLeft;
y = _mainView->_zoom._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 32) * ww + x;
for (int16 yy = 0; yy < 160; yy++) {
for (int16 xx = 0; xx < 320; xx++) {
scr[0] = 0;
scr[1] = 0;
scr[ww] = 0;
scr[ww + 1] = 0;
scr += 2;
2016-08-18 13:15:54 +02:00
}
scr += (ww - 320) * 2;
2016-08-18 13:15:54 +02:00
}
}
CLBlitter_UpdateScreen();
}
2016-09-14 23:48:01 +02:00
void EdenGame::colimacon(int16 pattern[16]) {
byte *scr, *pix;
2016-09-26 07:57:27 +02:00
int16 x, y;
int16 p, r27, r25;
// Unused
2016-11-30 22:51:15 -08:00
// int16 w = _vm->ScreenView->_width;
// int16 h = _vm->ScreenView->_height;
int16 ww = _vm->ScreenView->_pitch;
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
2016-12-18 14:13:36 -08:00
x = _mainView->_normal._dstLeft;
y = _mainView->_normal._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16) * ww + x;
for (int16 i = 0; i < 16; i++) {
p = pattern[i];
r27 = p % 4 + p / 4 * ww;
for (int16 j = 0; j < 320 * 160 / 16; j++)
scr[j / (320 / 4) * ww * 4 + j % (320 / 4) * 4 + r27] = 0;
CLBlitter_UpdateScreen();
wait(1);
2016-08-18 13:15:54 +02:00
}
} else {
2016-12-18 14:13:36 -08:00
x = _mainView->_zoom._dstLeft;
y = _mainView->_zoom._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16 * 2) * ww + x;
for (int16 i = 0; i < 16; i++) {
p = pattern[i];
r27 = p % 4 * 2 + p / 4 * ww * 2;
for (int16 j = 0; j < 320 * 160 / 16; j++) {
2016-09-14 23:48:01 +02:00
byte *sc = &scr[j / (320 / 4) * ww * 4 * 2 + j % (320 / 4) * 4 * 2 + r27];
sc[0] = 0;
sc[1] = 0;
sc[ww] = 0;
sc[ww + 1] = 0;
2016-08-18 13:15:54 +02:00
}
wait(1);
2016-08-18 13:15:54 +02:00
}
}
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
2016-12-18 14:13:36 -08:00
pix = _mainView->_bufferPtr;
x = _mainView->_normal._dstLeft;
y = _mainView->_normal._dstTop;
pix += 640 * 16;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16) * ww + x;
for (int16 i = 0; i < 16; i++) {
p = pattern[i];
r25 = p % 4 + p / 4 * 640;
r27 = p % 4 + p / 4 * ww;
for (int16 j = 0; j < 320 * 160 / 16; j++)
scr[j / (320 / 4) * ww * 4 + j % (320 / 4) * 4 + r27] =
pix[j / (320 / 4) * 640 * 4 + j % (320 / 4) * 4 + r25];
CLBlitter_UpdateScreen();
wait(1);
}
} else {
2016-12-18 14:13:36 -08:00
pix = _mainView->_bufferPtr;
x = _mainView->_zoom._dstLeft;
y = _mainView->_zoom._dstTop;
pix += 640 * 16;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16 * 2) * ww + x;
for (int16 i = 0; i < 16; i++) {
p = pattern[i];
r25 = p % 4 + p / 4 * 640;
r27 = p % 4 * 2 + p / 4 * ww * 2;
for (int16 j = 0; j < 320 * 160 / 16; j++) {
2016-09-14 23:48:01 +02:00
byte c = pix[j / (320 / 4) * 640 * 4 + j % (320 / 4) * 4 + r25];
byte *sc = &scr[j / (320 / 4) * ww * 4 * 2 + j % (320 / 4) * 4 * 2 + r27];
sc[0] = c;
sc[1] = c;
sc[ww] = c;
sc[ww + 1] = c;
2016-08-18 13:15:54 +02:00
}
wait(1);
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::fadeToBlack(int delay) {
CLPalette_GetLastPalette(oldPalette);
for (int16 i = 0; i < 6; i++) {
for (int16 j = 0; j < 256; j++) {
newColor.r = oldPalette[j].r >> i;
newColor.g = oldPalette[j].g >> i;
newColor.b = oldPalette[j].b >> i;
CLPalette_SetRGBColor(newPalette, j, &newColor);
}
CLPalette_Send2Screen(newPalette, 0, 256);
wait(delay);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::fadetoblack128(int delay) {
CLPalette_GetLastPalette(oldPalette);
for (int16 i = 0; i < 6; i++) {
for (int16 j = 0; j < 129; j++) { //TODO: wha?
newColor.r = oldPalette[j].r >> i;
newColor.g = oldPalette[j].g >> i;
newColor.b = oldPalette[j].b >> i;
CLPalette_SetRGBColor(newPalette, j, &newColor);
}
CLPalette_Send2Screen(newPalette, 0, 128);
wait(delay);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::fadefromblack128(int delay) {
for (int16 i = 0; i < 6; i++) {
for (int16 j = 0; j < 129; j++) { //TODO: wha?
2016-12-25 13:45:47 -08:00
newColor.r = _globalPalette[j].r >> (5 - i);
newColor.g = _globalPalette[j].g >> (5 - i);
newColor.b = _globalPalette[j].b >> (5 - i);
CLPalette_SetRGBColor(newPalette, j, &newColor);
}
CLPalette_Send2Screen(newPalette, 0, 128);
wait(delay);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::rectanglenoir32() {
// blacken 32x32 rectangle
int *pix = (int *)p_view2_buf;
for (int16 i = 0; i < 32; i++) {
pix[0] = 0;
pix[1] = 0;
pix[2] = 0;
pix[3] = 0;
pix[4] = 0;
pix[5] = 0;
pix[6] = 0;
pix[7] = 0;
pix += 32 / 4;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::setRS1(int16 sx, int16 sy, int16 ex, int16 ey) {
rect_src.left = sx;
rect_src.top = sy;
rect_src.right = ex;
rect_src.bottom = ey;
}
2016-09-14 23:48:01 +02:00
void EdenGame::setRD1(int16 sx, int16 sy, int16 ex, int16 ey) {
rect_dst.left = sx;
rect_dst.top = sy;
rect_dst.right = ex;
rect_dst.bottom = ey;
}
void EdenGame::wait(int howlong) {
int t = TickCount();
#ifdef EDEN_DEBUG
howlong *= 10;
#endif
for (int t2 = t; t2 - t < howlong; t2 = TickCount())
g_system->delayMillis(10); // waste time
}
void EdenGame::effetpix() {
byte *scr;
uint16 r25, r18, r31, r30; //TODO: change to xx/yy
uint16 ww = _vm->ScreenView->_pitch;
r25 = ww * 80;
r18 = 640 * 80;
2016-12-18 14:13:36 -08:00
byte *pix = _mainView->_bufferPtr + 16 * 640;
2016-09-30 07:48:27 +02:00
if (!_doubledScreen) {
2016-12-18 14:13:36 -08:00
int x = _mainView->_normal._dstLeft;
int y = _mainView->_normal._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16) * ww + x;
} else {
2016-12-18 14:13:36 -08:00
int x = _mainView->_zoom._dstLeft;
int y = _mainView->_zoom._dstTop;
2016-11-30 22:51:15 -08:00
scr = _vm->ScreenView->_bufferPtr;
scr += (y + 16 * 2) * ww + x;
r25 *= 2;
}
int16 r20 = 0x4400; //TODO
int16 r27 = 1;
int16 r26 = 0;
do {
char r8 = r27 & 1;
r27 >>= 1;
if (r8)
r27 ^= r20;
if (r27 < 320 * 80) {
r31 = r27 / 320;
r30 = r27 % 320;
2016-09-30 07:48:27 +02:00
if (_doubledScreen) {
r31 *= 2;
r30 *= 2;
scr[r31 * ww + r30] = 0;
scr[r31 * ww + r30 + 1] = 0;
scr[r31 * ww + r25 + r30] = 0;
scr[r31 * ww + r25 + r30 + 1] = 0;
r31++;
scr[r31 * ww + r30] = 0;
scr[r31 * ww + r30 + 1] = 0;
scr[r31 * ww + r25 + r30] = 0;
scr[r31 * ww + r25 + r30 + 1] = 0;
if (++r26 == 960) {
wait(1);
r26 = 0;
}
} else {
scr[r31 * ww + r30] = 0;
scr[r31 * ww + r25 + r30] = 0;
if (++r26 == 960) {
CLBlitter_UpdateScreen();
wait(1);
r26 = 0;
}
2016-08-18 13:15:54 +02:00
}
}
} while (r27 != 1);
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
r20 = 0x4400;
r27 = 1;
r26 = 0;
do {
char r8 = r27 & 1;
r27 >>= 1;
if (r8)
r27 ^= r20;
if (r27 < 320 * 80) {
r31 = r27 / 320;
r30 = r27 % 320;
byte p0 = pix[r31 * 640 + r30];
byte p1 = pix[r31 * 640 + r18 + r30];
2016-09-30 07:48:27 +02:00
if (_doubledScreen) {
r31 *= 2;
r30 *= 2;
scr[r31 * ww + r30] = p0;
scr[r31 * ww + r30 + 1] = p0;
scr[r31 * ww + r25 + r30] = p1;
scr[r31 * ww + r25 + r30 + 1] = p1;
r31++;
scr[r31 * ww + r30] = p0;
scr[r31 * ww + r30 + 1] = p0;
scr[r31 * ww + r25 + r30] = p1;
scr[r31 * ww + r25 + r30 + 1] = p1;
if (++r26 == 960) {
wait(1);
r26 = 0;
}
2016-08-18 13:15:54 +02:00
} else {
scr[r31 * ww + r30] = p0;
scr[r31 * ww + r25 + r30] = p1;
if (++r26 == 960) {
CLBlitter_UpdateScreen();
wait(1);
r26 = 0;
2016-08-18 13:15:54 +02:00
}
}
}
} while (r27 != 1);
2016-11-30 22:51:15 -08:00
assert(_vm->ScreenView->_pitch == 320);
}
////// datfile.c
void EdenGame::verifh(void *ptr) {
2016-09-14 23:48:01 +02:00
byte sum = 0;
byte *head = (byte *)ptr;
for (int8 i = 0; i < 6; i++)
sum += *head++;
if (sum != 0xAB)
return;
debug("* Begin unpacking resource");
head -= 6;
2016-12-04 14:54:58 -08:00
uint16 h0 = READ_LE_UINT16(head);
head += 2;
2016-11-15 09:41:06 +01:00
/*char unused = * */head++;
2016-12-04 14:54:58 -08:00
uint16 h3 = READ_LE_UINT16(head);
head += 2;
byte *data = h0 + head + 26;
h3 -= 6;
head += h3;
for (; h3; h3--)
*data-- = *head--;
head = data + 1;
2016-09-14 23:48:01 +02:00
data = (byte *)ptr;
Expand_hsq(head, data);
}
void EdenGame::openbigfile() {
h_bigfile.open("EDEN.DAT");
char buf[16];
int count = h_bigfile.readUint16LE();
bigfile_header = new PakHeaderNode(count);
for (int j = 0; j < count; j++) {
for (int k = 0; k < 16; k++)
buf[k] = h_bigfile.readByte();
bigfile_header->_files[j]._name = Common::String(buf);
bigfile_header->_files[j]._size = h_bigfile.readUint32LE();
bigfile_header->_files[j]._offs = h_bigfile.readUint32LE();
bigfile_header->_files[j]._flag = h_bigfile.readByte();
}
_hnmContext = _vm->_video->resetInternals();
_vm->_video->setFile(_hnmContext, &h_bigfile);
}
void EdenGame::closebigfile() {
h_bigfile.close();
}
2016-12-07 15:04:25 -08:00
void EdenGame::loadRawFile(uint16 num, byte *buffer) {
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[num];
2016-12-07 15:04:25 -08:00
int32 size = file->_size;
int32 offs = file->_offs;
h_bigfile.seek(offs, SEEK_SET);
h_bigfile.read(buffer, size);
}
void EdenGame::loadIconFile(uint16 num, Icon *buffer) {
2016-12-07 15:04:25 -08:00
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[num];
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading icon - Resource %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), offs, size);
2016-12-07 15:04:25 -08:00
h_bigfile.seek(offs, SEEK_SET);
int count = size / sizeof(Icon);
2016-12-07 15:04:25 -08:00
for (int i = 0; i < count; i++) {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
buffer[i].sx = h_bigfile.readSint16BE();
buffer[i].sy = h_bigfile.readSint16BE();
buffer[i].ex = h_bigfile.readSint16BE();
buffer[i].ey = h_bigfile.readSint16BE();
buffer[i]._cursorId = h_bigfile.readUint16BE();;
buffer[i]._actionId= h_bigfile.readUint32BE();;
buffer[i]._objectId= h_bigfile.readUint32BE();;
} else {
buffer[i].sx = h_bigfile.readSint16LE();
buffer[i].sy = h_bigfile.readSint16LE();
buffer[i].ex = h_bigfile.readSint16LE();
buffer[i].ey = h_bigfile.readSint16LE();
buffer[i]._cursorId = h_bigfile.readUint16LE();;
buffer[i]._actionId= h_bigfile.readUint32LE();;
buffer[i]._objectId= h_bigfile.readUint32LE();;
}
2016-12-07 15:04:25 -08:00
}
}
void EdenGame::loadRoomFile(uint16 num, Room *buffer) {
2016-12-07 15:04:25 -08:00
if (_vm->getPlatform() == Common::kPlatformDOS) {
if ((_vm->isDemo() && num > 2204) || num > 2472)
error("Trying to read invalid game resource");
}
assert(num < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[num];
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading room - Resource %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), offs, size);
2016-11-10 15:37:48 -08:00
h_bigfile.seek(offs, SEEK_SET);
2016-12-07 15:04:25 -08:00
int count = size / sizeof(Room);
2016-12-07 15:04:25 -08:00
for (int i = 0; i < count; i++) {
2016-12-15 22:47:29 -08:00
buffer[i]._id = h_bigfile.readByte();
2016-12-07 15:04:25 -08:00
for (int j = 0; j < 4; j++)
2016-12-15 22:47:29 -08:00
buffer[i]._exits[j] = h_bigfile.readByte();
buffer[i]._flags = h_bigfile.readByte();
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
buffer[i]._bank = h_bigfile.readUint16BE();
buffer[i]._party = h_bigfile.readUint16BE();
} else {
buffer[i]._bank = h_bigfile.readUint16LE();
buffer[i]._party = h_bigfile.readUint16LE();
}
2016-12-15 22:47:29 -08:00
buffer[i]._level = h_bigfile.readByte();
buffer[i]._video = h_bigfile.readByte();
buffer[i]._location = h_bigfile.readByte();
buffer[i]._backgroundBankNum = h_bigfile.readByte();
2016-12-07 15:04:25 -08:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::shnmfl(uint16 num) {
unsigned int resNum = num - 1 + 485;
assert(resNum < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[resNum];
2016-12-07 15:04:25 -08:00
int size = file->_size;
int offs = file->_offs;
debug("* Loading movie %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), (uint)offs, size);
2016-11-10 15:37:48 -08:00
_hnmContext->_file->seek(offs, SEEK_SET);
}
2016-09-14 23:48:01 +02:00
int EdenGame::ssndfl(uint16 num) {
unsigned int resNum = num - 1 + ((_vm->getPlatform() == Common::kPlatformDOS && _vm->isDemo()) ? 656 : 661);
assert(resNum < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[resNum];
2016-12-07 15:04:25 -08:00
int32 size = file->_size;
int32 offs = file->_offs;
debug("* Loading sound %d (%s) at 0x%X, %d bytes", num, file->_name.c_str(), (uint)offs, size);
if (_soundAllocated) {
free(voiceSamplesBuffer);
voiceSamplesBuffer = nullptr;
_soundAllocated = false; //TODO: bug??? no alloc
} else {
voiceSamplesBuffer = malloc(size);
_soundAllocated = true;
}
2016-11-10 15:37:48 -08:00
h_bigfile.seek(offs, SEEK_SET);
//For PC loaded data is a VOC file, on Mac version this is a raw samples
if (_vm->getPlatform() == Common::kPlatformMacintosh)
h_bigfile.read(voiceSamplesBuffer, size);
else {
// VOC files also include extra information for lipsync
// 1. Standard VOC header
h_bigfile.read(voiceSamplesBuffer, 0x1A);
// 2. Lipsync?
unsigned char chunkType = h_bigfile.readByte();
uint32 val;
h_bigfile.read(&val, 3);
unsigned int chunkLen = LE32(val);
if (chunkType == 5) {
h_bigfile.read(gameLipsync + 7260, chunkLen);
// anim_buffer_ptr = gameLipsync + 7260 + 2;
chunkType = h_bigfile.readByte();
h_bigfile.read(&val, 3);
chunkLen = LE32(val);
}
// 3. Normal sound data
if (chunkType == 1) {
2016-11-15 09:41:06 +01:00
/*unsigned short freq = */h_bigfile.readUint16LE();
size = chunkLen - 2;
h_bigfile.read(voiceSamplesBuffer, size);
}
}
return size;
}
void EdenGame::ConvertMacToPC() {
// Convert all mac (big-endian) resources to native format
// Array of longs
int *p = (int *)gameLipsync;
for (int i = 0; i < 7240 / 4; i++)
p[i] = BE32(p[i]);
}
void EdenGame::loadpermfiles() {
switch (_vm->getPlatform()) {
case Common::kPlatformDOS:
{
// Since PC version stores hotspots and rooms info in the executable, load them from premade resource file
Common::File f;
if (f.open("led.dat")) {
const int kNumIcons = 136;
const int kNumRooms = 424;
if (f.size() != kNumIcons * sizeof(Icon) + kNumRooms * sizeof(Room))
error("Mismatching aux data");
2016-12-07 15:04:25 -08:00
for (int i = 0; i < kNumIcons; i++) {
_gameIcons[i].sx = f.readSint16LE();
_gameIcons[i].sy = f.readSint16LE();
_gameIcons[i].ex = f.readSint16LE();
_gameIcons[i].ey = f.readSint16LE();
_gameIcons[i]._cursorId = f.readUint16LE();
_gameIcons[i]._actionId = f.readUint32LE();
_gameIcons[i]._objectId = f.readUint32LE();
}
for (int i = 0; i <kNumRooms; i++) {
2016-12-18 14:13:36 -08:00
_gameRooms[i]._id = f.readByte();
2016-12-07 15:04:25 -08:00
for (int j = 0; j < 4; j++)
2016-12-18 14:13:36 -08:00
_gameRooms[i]._exits[j] = f.readByte();
_gameRooms[i]._flags = f.readByte();
_gameRooms[i]._bank = f.readUint16LE();
_gameRooms[i]._party = f.readUint16LE();
_gameRooms[i]._level = f.readByte();
_gameRooms[i]._video = f.readByte();
_gameRooms[i]._location = f.readByte();
_gameRooms[i]._backgroundBankNum = f.readByte();
2016-12-07 15:04:25 -08:00
}
f.close();
} else
error("Can not load aux data");
}
break;
case Common::kPlatformMacintosh:
2016-12-07 15:04:25 -08:00
loadIconFile(2498, _gameIcons);
2016-12-18 14:13:36 -08:00
loadRoomFile(2497, _gameRooms);
2016-12-07 15:04:25 -08:00
loadRawFile(2486, gameLipsync);
ConvertMacToPC();
break;
default:
error("Unsupported platform");
}
2016-12-07 15:04:25 -08:00
loadRawFile(0, _mainBankBuf);
2016-12-18 14:13:36 -08:00
loadRawFile(402, _gameFont);
2016-12-07 15:04:25 -08:00
loadRawFile(404, gameDialogs);
loadRawFile(403, gameConditions);
}
bool EdenGame::ReadDataSyncVOC(unsigned int num) {
unsigned int resNum = num - 1 + ((_vm->getPlatform() == Common::kPlatformDOS && _vm->isDemo()) ? 656 : 661);
unsigned char vocHeader[0x1A];
int filePos = 0;
loadpartoffile(resNum, vocHeader, filePos, sizeof(vocHeader));
filePos += sizeof(vocHeader);
unsigned char chunkType = 0;
loadpartoffile(resNum, &chunkType, sizeof(vocHeader), 1);
filePos++;
if (chunkType == 5) {
2016-12-20 23:02:31 -08:00
uint32 chunkLen = 0;
loadpartoffile(resNum, &chunkLen, filePos, 3);
filePos += 3;
chunkLen = LE32(chunkLen);
loadpartoffile(resNum, gameLipsync + 7260, filePos, chunkLen);
return true;
2016-08-18 13:15:54 +02:00
}
return false;
}
bool EdenGame::ReadDataSync(uint16 num) {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
long pos = READ_LE_UINT32(gameLipsync + num * 4);
long len = 1024;
if (pos != -1) {
loadpartoffile(1936, gameLipsync + 7260, pos, len);
return true;
}
} else
return ReadDataSyncVOC(num + 1); //TODO: remove -1 in caller
return false;
}
2016-10-08 23:31:21 +02:00
void EdenGame::loadpartoffile(uint16 num, void *buffer, int32 pos, int32 len) {
assert(num < bigfile_header->_count);
PakHeaderItem *file = &bigfile_header->_files[num];
int32 offs = READ_LE_UINT32(&file->_offs);
debug("* Loading partial resource %d (%s) at 0x%X(+0x%X), %d bytes", num, file->_name.c_str(), offs, pos, len);
2016-11-10 15:37:48 -08:00
h_bigfile.seek(offs + pos, SEEK_SET);
h_bigfile.read(buffer, len);
}
void EdenGame::Expand_hsq(void *input, void *output) {
2016-09-14 23:48:01 +02:00
byte *src = (byte *)input;
byte *dst = (byte *)output;
byte *ptr;
uint16 bit; // bit
uint16 queue = 0; // queue
uint16 len = 0;
int16 ofs;
#define GetBit \
bit = queue & 1; \
queue >>= 1; \
if (!queue) { \
queue = (src[1] << 8) | src[0]; src += 2; \
bit = queue & 1; \
queue = (queue >> 1) | 0x8000; \
2016-08-18 13:15:54 +02:00
}
for (;;) {
GetBit;
if (bit)
*dst++ = *src++;
else {
len = 0;
GetBit;
if (!bit) {
GetBit;
len = (len << 1) | bit;
GetBit;
len = (len << 1) | bit;
ofs = 0xFF00 | *src++; //TODO: -256
} else {
ofs = (src[1] << 8) | src[0];
src += 2;
len = ofs & 7;
ofs = (ofs >> 3) | 0xE000;
if (!len) {
len = *src++;
if (!len)
break;
2016-08-18 13:15:54 +02:00
}
}
ptr = dst + ofs;
len += 2;
while (len--)
*dst++ = *ptr++;
2016-08-18 13:15:54 +02:00
}
}
}
//////
2016-12-11 13:44:58 -08:00
// Original name: ajouinfo
void EdenGame::addInfo(byte info) {
byte idx = p_global->_nextInfoIdx;
2016-10-07 00:45:08 +02:00
if (kPersons[PER_MESSAGER]._roomNum)
info |= 0x80;
2016-12-11 13:44:58 -08:00
_infoList[idx] = info;
if (idx == p_global->_lastInfoIdx)
2016-12-04 13:15:38 -08:00
p_global->_lastInfo = info;
idx++;
2016-11-13 22:59:45 -08:00
if (idx == 16)
idx = 0;
2016-12-11 13:44:58 -08:00
p_global->_nextInfoIdx = idx;
}
2016-12-11 13:44:58 -08:00
void EdenGame::unlockInfo() {
2016-11-13 22:59:45 -08:00
for (byte idx = 0; idx < 16; idx++) {
2016-12-11 13:44:58 -08:00
if (_infoList[idx] != 0xFF)
_infoList[idx] &= ~0x80;
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
p_global->_lastInfo &= ~0x80;
}
2016-12-11 13:44:58 -08:00
void EdenGame::nextInfo() {
do {
2016-12-11 13:44:58 -08:00
byte idx = p_global->_lastInfoIdx;
_infoList[idx] = 0;
idx++;
2016-11-13 22:59:45 -08:00
if (idx == 16)
idx = 0;
2016-12-11 13:44:58 -08:00
p_global->_lastInfoIdx = idx;
p_global->_lastInfo = _infoList[idx];
2016-12-04 13:15:38 -08:00
} while (p_global->_lastInfo == 0xFF);
}
2016-12-11 13:44:58 -08:00
// Original name: delinfo
void EdenGame::removeInfo(byte info) {
2016-11-13 22:59:45 -08:00
for (byte idx = 0; idx < 16; idx++) {
2016-12-11 13:44:58 -08:00
if ((_infoList[idx] & ~0x80) == info) {
_infoList[idx] = 0xFF;
if (idx == p_global->_lastInfoIdx)
nextInfo();
break;
2016-08-18 13:15:54 +02:00
}
}
}
2016-12-11 13:44:58 -08:00
void EdenGame::updateInfoList() {
2016-10-24 22:02:43 +02:00
for (int idx = 0; idx < 16; idx++)
2016-12-11 13:44:58 -08:00
_infoList[idx] = 0;
}
void EdenGame::init_globals() {
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId |= 0x8000;
2016-12-04 14:26:44 -08:00
p_global->_areaNum = Areas::arMo;
p_global->_areaVisitCount = 1;
2016-12-11 13:44:58 -08:00
p_global->_menuItemIdLo = 0;
p_global->_menuItemIdHi = 0;
p_global->_randomNumber = 0;
p_global->_gameTime = 0;
2016-12-04 14:26:44 -08:00
p_global->_gameDays = 0;
2016-12-11 13:44:58 -08:00
p_global->_chrono = 0;
p_global->_eloiDepartureDay = 0;
p_global->_roomNum = 259;
p_global->_newRoomNum = 0;
2016-12-04 14:26:44 -08:00
p_global->_phaseNum = 0;
p_global->_metPersonsMask1 = 0;
2016-12-11 13:44:58 -08:00
p_global->_party = 0;
2016-12-04 14:26:44 -08:00
p_global->_partyOutside = 0;
p_global->_metPersonsMask2 = 0;
p_global->_phaseActionsCount = 0;
2016-12-04 14:26:44 -08:00
p_global->_curAreaFlags = 0;
2016-12-11 13:44:58 -08:00
p_global->_curItemsMask = 0;
p_global->_curPowersMask = 0;
p_global->_curPersoItems = 0;
2016-12-04 14:26:44 -08:00
p_global->_curCharacterPowers = 0;
p_global->_wonItemsMask = 0;
p_global->_wonPowersMask = 0;
p_global->_stepsToFindAppleFast = 0;
p_global->_stepsToFindAppleNormal = 0;
2016-12-04 14:26:44 -08:00
p_global->_roomPersoItems = 0;
p_global->_roomCharacterPowers = 0;
p_global->_gameFlags = GameFlags::gfNone;
p_global->_morkusSpyVideoNum1 = 89;
p_global->_morkusSpyVideoNum2 = 88;
p_global->_morkusSpyVideoNum3 = 83;
p_global->_morkusSpyVideoNum4 = 94;
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = MusicType::mtDontChange;
p_global->_var43 = 0;
p_global->_videoSubtitleIndex = 0;
2016-12-04 14:26:44 -08:00
p_global->_partyInstruments = 0;
p_global->_monkGotRing = 0;
p_global->_chronoFlag = 0;
2016-12-11 13:44:58 -08:00
p_global->_curRoomFlags = 0;
p_global->_endGameFlag = 0;
2016-12-04 13:15:38 -08:00
p_global->_lastInfo = 0;
p_global->_autoDialog = false;
2016-12-11 13:44:58 -08:00
p_global->_worldTyranSighted = 0;
p_global->_var4D = 0;
p_global->_var4E = 0;
2016-12-11 13:44:58 -08:00
p_global->_worldGaveGold = 0;
p_global->_worldHasTriceraptors = 0;
p_global->_worldHasVelociraptors = 0;
p_global->_worldHasTyran = 0;
p_global->_var53 = 0;
p_global->_var54 = 0;
p_global->_var55 = 0;
2016-12-04 14:26:44 -08:00
p_global->_gameHours = 0;
2016-12-11 13:44:58 -08:00
p_global->_textToken1 = 0;
p_global->_textToken2 = 0;
p_global->_eloiHaveNews = 0;
p_global->_dialogFlags = 0;
p_global->_curAreaType = 0;
p_global->_curCitadelLevel = 0;
p_global->_newLocation = 0;
p_global->_prevLocation = 0;
p_global->_curPersoFlags = 0;
p_global->_var60 = 0;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
p_global->_var62 = 0;
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = 0;
p_global->_curObjectFlags = 0;
p_global->_var65 = 1;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterType = 0;
p_global->_roomCharacterFlags = 0;
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 0;
p_global->_var69 = 0;
p_global->_var6A = 0;
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 0;
p_global->_var6C = 0;
p_global->_var6D = 0;
p_global->_labyrinthDirections = 0;
p_global->_labyrinthRoom = 0;
2016-12-04 14:26:44 -08:00
p_global->_curCharacterAnimPtr = nullptr;
p_global->_characterImageBank = 0;
2016-12-11 13:44:58 -08:00
p_global->_roomImgBank = 0;
2016-12-04 14:26:44 -08:00
p_global->_characterBackgroundBankIdx = 55;
p_global->_varD4 = 0;
2016-12-11 13:44:58 -08:00
p_global->_frescoeWidth = 0;
p_global->_frescoeImgBank = 0;
p_global->_varDA = 0;
p_global->_varDC = 0;
2016-12-11 13:44:58 -08:00
p_global->_roomBaseX = 0;
p_global->_varE0 = 0;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
p_global->_varE4 = 0;
2016-12-11 13:44:58 -08:00
p_global->_currMusicNum = 0;
p_global->_textNum = 0;
p_global->_travelTime = 0;
p_global->_varEC = 0;
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
2016-12-11 13:44:58 -08:00
p_global->_oldDisplayFlags = 1;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags = 0;
p_global->_varF1 = 0;
p_global->_varF2 = 0;
p_global->_menuFlags = 0;
p_global->_varF5 = 0;
p_global->_varF6 = 0;
p_global->_varF7 = 0;
p_global->_varF8 = 0;
p_global->_varF9 = 0;
p_global->_varFA = 0;
2016-12-04 14:26:44 -08:00
p_global->_animationFlags = 0;
2016-12-11 13:44:58 -08:00
p_global->_giveObj1 = 0;
p_global->_giveObj2 = 0;
p_global->_giveObj3 = 0;
p_global->_var100 = 0;
2016-12-11 13:44:58 -08:00
p_global->_roomVidNum = 0;
p_global->_var102 = 0;
p_global->_var103 = 0;
2016-12-11 13:44:58 -08:00
p_global->_roomBackgroundBankNum = 0;
p_global->_valleyVidNum = 0;
p_global->_updatePaletteFlag = 0;
p_global->_inventoryScrollPos = 0;
p_global->_objCount = 0;
p_global->_textBankIndex = 69;
2016-12-18 13:09:56 -08:00
p_global->_citadelAreaNum = 0;
p_global->_var113 = 0;
2016-12-11 13:44:58 -08:00
p_global->_lastPlaceNum = 0;
2016-10-24 22:02:43 +02:00
p_global->_dialogPtr = nullptr;
2016-12-11 13:44:58 -08:00
p_global->_tapePtr = tapes;
p_global->_nextDialogPtr = nullptr;
2016-12-11 13:44:58 -08:00
p_global->_narratorDialogPtr = nullptr;
p_global->_lastDialogPtr = nullptr;
p_global->_nextRoomIcon = nullptr;
p_global->_sentenceBufferPtr = nullptr;
p_global->_roomPtr = nullptr;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr = nullptr;
2016-12-11 13:44:58 -08:00
p_global->_lastAreaPtr = nullptr;
p_global->_curAreaPtr = nullptr;
p_global->_citaAreaFirstRoom = 0;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = nullptr;
2016-12-11 13:44:58 -08:00
p_global->_roomCharacterPtr = 0;
p_global->_lastInfoIdx = 0;
p_global->_nextInfoIdx = 0;
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 16;
2016-12-11 13:44:58 -08:00
p_global->_persoSpritePtr = nullptr;
p_global->_numGiveObjs = 0;
2016-09-30 07:48:27 +02:00
initRects();
2016-09-30 07:48:27 +02:00
_underSubtitlesScreenRect.top = 0;
_underSubtitlesScreenRect.left = subtitles_x_scr_margin;
_underSubtitlesScreenRect.right = subtitles_x_scr_margin + subtitles_x_width - 1;
_underSubtitlesScreenRect.bottom = 176 - 1;
2016-09-30 07:48:27 +02:00
_underSubtitlesBackupRect.top = 0;
_underSubtitlesBackupRect.left = subtitles_x_scr_margin;
_underSubtitlesBackupRect.right = subtitles_x_scr_margin + subtitles_x_width - 1;
_underSubtitlesBackupRect.bottom = 60 - 1;
}
2016-09-30 07:48:27 +02:00
void EdenGame::initRects() {
_underTopBarScreenRect = Common::Rect(0, 0, 320 - 1, 16 - 1);
_underTopBarBackupRect = Common::Rect(0, 0, 320 - 1, 16 - 1);
_underBottomBarScreenRect = Common::Rect(0, 176, 320 - 1, 200 - 1); //TODO: original bug? this cause crash in copyrect (this, underBottomBarBackupRect)
_underBottomBarBackupRect = Common::Rect(0, 16, 320 - 1, 40 - 1);
}
void EdenGame::closesalle() {
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfPanable) {
p_global->_displayFlags &= ~DisplayFlags::dfPanable;
2016-09-26 23:44:42 +02:00
resetScroll();
}
}
2016-10-07 23:06:10 +02:00
// Original name afsalle1
void EdenGame::displaySingleRoom(Room *room) {
2016-12-18 14:13:36 -08:00
byte *ptr = (byte *)getElem(_placeRawBuf, room->_id - 1);
ptr++;
for (;;) {
2016-10-07 23:06:10 +02:00
byte b0 = *ptr++;
byte b1 = *ptr++;
int16 index = (b1 << 8) | b0;
if (index == -1)
2016-08-18 13:15:54 +02:00
break;
if (index > 0) {
2016-10-07 23:06:10 +02:00
int16 x = *ptr++ | (((b1 & 0x2) >> 1) << 8); //TODO: check me
int16 y = *ptr++;
ptr++;
index &= 0x1FF;
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & 0x80)) {
if (index == 1 || p_global->_varF7)
noclipax_avecnoir(index - 1, x, y);
2016-08-18 13:15:54 +02:00
}
p_global->_varF7 = 0;
continue;
}
if (b1 & 0x40) {
if (b1 & 0x20) {
bool addIcon = false;
Icon *icon = p_global->_nextRoomIcon;
if (b0 < 4) {
2016-12-15 22:47:29 -08:00
if (p_global->_roomPtr->_exits[b0])
addIcon = true;
} else if (b0 > 229) {
2016-12-04 14:26:44 -08:00
if (p_global->_partyOutside & (1 << (b0 - 230)))
addIcon = true;
} else if (b0 >= 100) {
debug("add object %d", b0 - 100);
if (objecthere(b0 - 100)) {
addIcon = true;
p_global->_varF7 = 1;
}
} else
addIcon = true;
if (addIcon) {
2016-12-03 15:40:53 -08:00
icon->_actionId = b0;
icon->_objectId = b0;
icon->_cursorId = kActionCursors[b0];
2016-12-04 14:54:58 -08:00
int16 x = READ_LE_UINT16(ptr);
ptr += 2;
2016-12-04 14:54:58 -08:00
int16 y = READ_LE_UINT16(ptr);
ptr += 2;
2016-12-04 14:54:58 -08:00
int16 ex = READ_LE_UINT16(ptr);
ptr += 2;
2016-12-04 14:54:58 -08:00
int16 ey = READ_LE_UINT16(ptr);
ptr += 2;
2016-12-11 13:44:58 -08:00
x += p_global->_roomBaseX;
ex += p_global->_roomBaseX;
debug("add hotspot at %3d:%3d - %3d:%3d, action = %d", x, y, ex, ey, b0);
#ifdef EDEN_DEBUG
2016-11-13 22:59:45 -08:00
for (int iii = x; iii < ex; iii++)
p_mainview_buf[y * 640 + iii] = p_mainview_buf[ey * 640 + iii] = (iii % 2) ? 0 : 255;
for (int iii = y; iii < ey; iii++)
p_mainview_buf[iii * 640 + x] = p_mainview_buf[iii * 640 + ex] = (iii % 2) ? 0 : 255;
#endif
icon->sx = x;
icon->sy = y;
icon->ex = ex;
icon->ey = ey;
2016-12-11 13:44:58 -08:00
p_global->_nextRoomIcon = ++icon;
icon->sx = -1;
} else
ptr += 8;
2016-08-18 13:15:54 +02:00
} else
ptr += 8;
} else
ptr += 8;
2016-08-18 13:15:54 +02:00
}
}
2016-10-07 23:06:10 +02:00
// Original name: afsalle
void EdenGame::displayRoom() {
Room *room = p_global->_roomPtr;
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
2016-12-11 13:44:58 -08:00
p_global->_roomBaseX = 0;
2016-12-15 22:47:29 -08:00
p_global->_roomBackgroundBankNum = room->_backgroundBankNum;
if (room->_flags & RoomFlags::rf08) {
2016-12-04 13:15:38 -08:00
p_global->_displayFlags |= DisplayFlags::dfFlag80;
2016-12-15 22:47:29 -08:00
if (room->_flags & RoomFlags::rfPanable) {
2016-10-07 23:06:10 +02:00
// Scrollable room on 2 screens
2016-12-04 13:15:38 -08:00
p_global->_displayFlags |= DisplayFlags::dfPanable;
p_global->_varF4 = 0;
rundcurs();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-12-15 22:47:29 -08:00
useBank(room->_bank - 1);
noclipax_avecnoir(0, 0, 16);
2016-12-15 22:47:29 -08:00
useBank(room->_bank);
noclipax_avecnoir(0, 320, 16);
2016-10-07 23:06:10 +02:00
displaySingleRoom(room);
2016-12-11 13:44:58 -08:00
p_global->_roomBaseX = 320;
2016-10-07 23:06:10 +02:00
displaySingleRoom(room + 1);
} else
2016-10-07 23:06:10 +02:00
displaySingleRoom(room);
} else {
//TODO: roomImgBank is garbage here!
2016-12-11 13:44:58 -08:00
debug("drawroom: room 0x%X using bank %d", p_global->_roomNum, p_global->_roomImgBank);
useBank(p_global->_roomImgBank);
2016-10-07 23:06:10 +02:00
displaySingleRoom(room);
2016-11-30 22:51:15 -08:00
assert(_vm->ScreenView->_pitch == 320);
2016-08-18 13:15:54 +02:00
}
}
2016-10-07 23:06:10 +02:00
// Original name: aflieu
void EdenGame::displayPlace() {
no_perso();
if (!pomme_q) {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 16;
p_global->_autoDialog = false;
2016-08-18 13:15:54 +02:00
}
2016-12-19 22:32:40 -08:00
p_global->_nextRoomIcon = &_gameIcons[_roomIconsBase];
2016-10-07 23:06:10 +02:00
displayRoom();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
}
2016-10-07 23:06:10 +02:00
// Original name: loadsal
void EdenGame::loadPlace(int16 num) {
2016-12-11 13:44:58 -08:00
if (num == p_global->_lastPlaceNum)
return;
2016-12-11 13:44:58 -08:00
p_global->_lastPlaceNum = num;
2016-12-18 14:13:36 -08:00
loadRawFile(num + 419, _placeRawBuf);
}
void EdenGame::specialoutside() {
2016-12-15 22:47:29 -08:00
if (p_global->_lastAreaPtr->_type == AreaType::atValley && (p_global->_party & PersonMask::pmLeader))
perso_ici(5);
}
void EdenGame::specialout() {
2016-12-11 13:44:58 -08:00
if (p_global->_gameDays - p_global->_eloiDepartureDay > 2) {
2016-12-19 22:32:40 -08:00
if (checkEloiReturn())
handleEloiReturn();
2016-08-18 13:15:54 +02:00
}
2016-10-07 23:06:10 +02:00
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 32 && p_global->_phaseNum < 48) {
2016-12-11 13:44:58 -08:00
if (p_global->_newLocation == 9 || p_global->_newLocation == 4 || p_global->_newLocation == 24) {
2016-10-07 00:45:08 +02:00
kPersons[PER_MESSAGER]._roomNum = 263;
2016-08-18 13:15:54 +02:00
return;
}
2016-10-07 23:06:10 +02:00
}
2016-12-11 13:44:58 -08:00
if ((p_global->_phaseNum == 434) && (p_global->_newLocation == 5)) {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_BOURREAU);
2016-10-07 23:06:10 +02:00
kPersons[PER_BOURREAU]._roomNum = 264;
return;
}
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum < 400) {
2016-12-11 13:44:58 -08:00
if ((p_global->_gameFlags & GameFlags::gfFlag4000) && p_global->_prevLocation == 1
&& (p_global->_party & PersonMask::pmEloi) && p_global->_curAreaType == AreaType::atValley)
handleEloiDeparture();
2016-10-07 23:06:10 +02:00
}
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum == 386) {
2016-12-11 13:44:58 -08:00
if (p_global->_prevLocation == 1
&& (p_global->_party & PersonMask::pmEloi) && p_global->_areaNum == Areas::arCantura)
handleEloiDeparture();
2016-10-07 23:06:10 +02:00
}
}
void EdenGame::specialin() {
2016-12-11 13:44:58 -08:00
if (!(p_global->_party & PersonMask::pmEloi) && (p_global->_partyOutside & PersonMask::pmEloi) && (p_global->_roomNum & 0xFF) == 1) {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MESSAGER);
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews = 1;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 288)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag100 | GameFlags::gfFlag2000;
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 3075 && p_global->_phaseNum == 546) {
2016-12-19 22:32:40 -08:00
incPhase();
2016-12-11 13:44:58 -08:00
if (p_global->_curItemsMask & 0x2000) { // Morkus' tablet
bars_out();
2016-09-26 23:44:42 +02:00
playHNM(92);
2016-12-18 14:13:36 -08:00
_gameRooms[129]._exits[0] = 0;
_gameRooms[129]._exits[2] = 1;
2016-12-11 13:44:58 -08:00
p_global->_roomNum = 3074;
2016-10-07 00:45:08 +02:00
kPersons[PER_MANGO]._roomNum = 3074;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEvent5;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
return;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 53;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 1793 && p_global->_phaseNum == 336)
handleEloiDeparture();
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 259 && p_global->_phaseNum == 129)
p_global->_narratorSequence = 12;
if (p_global->_roomNum >= 289 && p_global->_roomNum < 359)
p_global->_labyrinthDirections = kLabyrinthPath[(p_global->_roomNum & 0xFF) - 33];
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 305 && p_global->_prevLocation == 103)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags &= ~GameFlags::gfFlag2000;
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 304 && p_global->_prevLocation == 105)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags &= ~GameFlags::gfFlag2000;
if (p_global->_phaseNum < 226) {
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 842)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag2;
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 1072)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag4;
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 1329)
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag8000;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::animpiece() {
Room *room = p_global->_roomPtr;
if (p_global->_roomVidNum && p_global->_var100 != 0xFF) {
2016-12-15 22:47:29 -08:00
if (p_global->_valleyVidNum || !room->_level || (room->_flags & RoomFlags::rfHasCitadel)
|| room->_level == p_global->_var100) {
bars_out();
2016-12-11 13:44:58 -08:00
p_global->_updatePaletteFlag = 16;
if (!(p_global->_narratorSequence & 0x80)) //TODO: bug? !() @ 100DC
p_global->_var102 = 0;
if (!needToFade)
2016-12-15 22:47:29 -08:00
needToFade = room->_flags & RoomFlags::rf02;
2016-12-11 13:44:58 -08:00
playHNM(p_global->_roomVidNum);
2016-08-18 13:15:54 +02:00
return;
}
2016-08-18 13:15:54 +02:00
}
p_global->_varF1 &= ~RoomFlags::rf04;
}
void EdenGame::getdino(Room *room) {
assert(tab_2CEF0[4] == 0x25);
2016-12-15 22:47:29 -08:00
room->_flags &= ~0xC;
2016-11-13 22:59:45 -08:00
for (perso_t *perso = &kPersons[PER_UNKN_18C]; perso->_roomNum != 0xFFFF; perso++) {
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pf80)
continue;
2016-12-11 13:44:58 -08:00
if (perso->_roomNum != p_global->_roomNum)
continue;
2016-11-13 22:59:45 -08:00
byte persoType = perso->_flags & PersonFlags::pfTypeMask;
if (persoType == PersonFlags::pftVelociraptor)
2016-12-18 13:09:56 -08:00
removeInfo(p_global->_citadelAreaNum + ValleyNews::vnVelociraptorsIn);
if (persoType == PersonFlags::pftTriceraptor)
2016-12-18 13:09:56 -08:00
removeInfo(p_global->_citadelAreaNum + ValleyNews::vnTriceraptorsIn);
2016-10-07 00:45:08 +02:00
perso->_flags |= PersonFlags::pf20;
2016-11-13 22:59:45 -08:00
int16 *tab = tab_2CF70;
2016-12-04 14:26:44 -08:00
if (p_global->_areaNum != Areas::arUluru && p_global->_areaNum != Areas::arTamara)
tab = tab_2CEF0;
2016-12-15 22:47:29 -08:00
byte r27 = (room->_flags & 0xC0) >> 2; //TODO: check me (like pc)
2016-10-07 00:45:08 +02:00
persoType = perso->_flags & PersonFlags::pfTypeMask;
if (persoType == PersonFlags::pftTyrann)
persoType = 13;
r27 |= (persoType & 7) << 1; //TODO: check me 13 & 7 = ???
tab += r27;
2016-12-11 13:44:58 -08:00
p_global->_roomVidNum = *tab++;
2016-11-13 22:59:45 -08:00
int16 bank = *tab;
if (bank & 0x8000) {
bank &= ~0x8000;
2016-12-15 22:47:29 -08:00
room->_flags |= RoomFlags::rf08;
}
2016-12-15 22:47:29 -08:00
room->_flags |= RoomFlags::rf04 | RoomFlags::rf02;
2016-12-11 13:44:58 -08:00
p_global->_roomImgBank = bank;
break;
2016-08-18 13:15:54 +02:00
}
}
2016-12-19 13:41:00 -08:00
// Original name: getsalle
Room *EdenGame::getRoom(int16 loc) { //TODO: byte?
2016-12-15 22:47:29 -08:00
debug("get room for %X, starting from %d, looking for %X", loc, p_global->_areaPtr->_firstRoomIdx, p_global->_partyOutside);
2016-12-18 14:13:36 -08:00
Room *room = &_gameRooms[p_global->_areaPtr->_firstRoomIdx];
loc &= 0xFF;
for (;; room++) {
2016-12-15 22:47:29 -08:00
for (; room->_location != loc; room++) {
if (room->_id == 0xFF)
return 0;
2016-08-18 13:15:54 +02:00
}
2016-12-15 22:47:29 -08:00
if (p_global->_partyOutside == room->_party || room->_party == 0xFFFF)
break;
2016-08-18 13:15:54 +02:00
}
2016-12-15 22:47:29 -08:00
debug("found room: party = %X, bank = %X", room->_party, room->_bank);
p_global->_roomImgBank = room->_bank;
p_global->_labyrinthRoom = 0;
2016-12-11 13:44:58 -08:00
if (p_global->_roomImgBank > 104 && p_global->_roomImgBank <= 112)
p_global->_labyrinthRoom = p_global->_roomImgBank - 103;
2016-12-11 13:44:58 -08:00
if (p_global->_valleyVidNum)
p_global->_roomVidNum = p_global->_valleyVidNum;
else
2016-12-15 22:47:29 -08:00
p_global->_roomVidNum = room->_video;
if ((room->_flags & 0xC0) == RoomFlags::rf40 || (room->_flags & RoomFlags::rf01))
getdino(room);
2016-12-15 22:47:29 -08:00
if (room->_flags & RoomFlags::rfHasCitadel) {
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnCitadelLost);
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannIn);
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannLost);
removeInfo(p_global->_areaNum + ValleyNews::vnVelociraptorsLost);
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (istyran(p_global->_roomNum))
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag10;
else
2016-12-04 14:26:44 -08:00
p_global->_gameFlags &= ~GameFlags::gfFlag10;
return room;
}
2016-08-18 13:15:54 +02:00
2016-10-07 23:06:10 +02:00
// Original name: initlieu
void EdenGame::initPlace(int16 roomNum) {
2016-12-04 14:26:44 -08:00
p_global->_gameFlags |= GameFlags::gfFlag4000;
_gameIcons[18]._cursorId |= 0x8000;
2016-12-11 13:44:58 -08:00
p_global->_lastAreaPtr = p_global->_areaPtr;
2016-12-04 14:26:44 -08:00
p_global->_areaPtr = &kAreasTable[((roomNum >> 8) & 0xFF) - 1];
Area *area = p_global->_areaPtr;
2016-12-15 22:47:29 -08:00
area->_visitCount++;
p_global->_areaVisitCount = area->_visitCount;
2016-12-04 14:26:44 -08:00
p_global->_curAreaFlags = area->_flags;
2016-12-15 22:47:29 -08:00
p_global->_curAreaType = area->_type;
p_global->_curCitadelLevel = area->_citadelLevel;
2016-12-11 13:44:58 -08:00
if (p_global->_curAreaType == AreaType::atValley)
2016-12-04 14:26:44 -08:00
_gameIcons[18]._cursorId &= ~0x8000;
2016-12-15 22:47:29 -08:00
loadPlace(area->_placeNum);
}
void EdenGame::maj2() {
2016-10-07 23:06:10 +02:00
displayPlace();
2016-11-30 22:51:15 -08:00
assert(_vm->ScreenView->_pitch == 320);
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 273 && p_global->_prevLocation == 18)
p_global->_var102 = 1;
2016-12-04 13:15:38 -08:00
if (p_global->_eventType == EventType::etEventC) {
drawTopScreen();
showObjects();
}
FRDevents();
2016-11-30 22:51:15 -08:00
assert(_vm->ScreenView->_pitch == 320);
2016-11-13 22:59:45 -08:00
bool r30 = false;
2016-12-11 13:44:58 -08:00
if (p_global->_curAreaType == AreaType::atValley && !(p_global->_displayFlags & DisplayFlags::dfPanable))
2016-11-13 22:59:45 -08:00
r30 = true;
//TODO: ^^ inlined func?
if (p_global->_var102 || p_global->_var103)
afficher();
else if (p_global->_varF1 == (RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01)) {
drawBlackBars();
effet1();
} else if (p_global->_varF1 && !(p_global->_varF1 & RoomFlags::rf04) && !r30) {
2016-12-04 13:15:38 -08:00
if (!(p_global->_displayFlags & DisplayFlags::dfPanable))
drawBlackBars();
2016-12-11 13:44:58 -08:00
else if (p_global->_valleyVidNum)
drawBlackBars();
effet1();
} else if (r30 && !(p_global->_varF1 & RoomFlags::rf04))
effetpix();
else
afficher128();
musique();
2016-12-04 13:15:38 -08:00
if (p_global->_eventType != EventType::etEventC) {
drawTopScreen();
showObjects();
}
showBars();
2016-09-26 23:44:42 +02:00
showEvents();
p_global->_labyrinthDirections = 0;
specialin();
}
2016-12-19 13:41:00 -08:00
// Original name: majsalle1
void EdenGame::updateRoom1(int16 roomNum) {
Room *room = getRoom(roomNum & 0xFF);
2016-12-11 13:44:58 -08:00
p_global->_roomPtr = room;
debug("DrawRoom: room 0x%X, arg = 0x%X", p_global->_roomNum, roomNum);
2016-12-15 22:47:29 -08:00
p_global->_curRoomFlags = room->_flags;
p_global->_varF1 = room->_flags;
animpiece();
p_global->_var100 = 0;
maj2();
}
2016-12-19 13:41:00 -08:00
// Original name: maj_salle
void EdenGame::updateRoom(uint16 roomNum) {
setpersohere();
2016-12-19 13:41:00 -08:00
updateRoom1(roomNum);
}
// Original name: initbuf
void EdenGame::allocateBuffers() {
#define ALLOC(ptr, size, typ) if (!((ptr) = (typ*)malloc(size))) bufferAllocationErrorFl = true;
2016-12-18 14:13:36 -08:00
ALLOC(_gameRooms, 0x4000, Room);
ALLOC(_gameIcons, 0x4000, Icon);
2016-12-18 14:13:36 -08:00
ALLOC(_bankDataBuf, 0x10000, byte);
ALLOC(p_global, sizeof(*p_global), global_t);
2016-12-18 14:13:36 -08:00
ALLOC(_placeRawBuf, 2048, byte);
2016-09-14 23:48:01 +02:00
ALLOC(gameConditions, 0x4800, byte);
ALLOC(gameDialogs, 0x2800, byte);
ALLOC(gamePhrases, 0x10000, byte);
2016-12-04 14:54:58 -08:00
ALLOC(_mainBankBuf, 0x9400, byte);
2016-12-18 14:13:36 -08:00
ALLOC(_glowBuffer, 0x2800, byte);
ALLOC(_gameFont, 0x900, byte);
2016-09-14 23:48:01 +02:00
ALLOC(gameLipsync, 0x205C, byte);
2016-12-04 14:54:58 -08:00
ALLOC(_musicBuf, 0x140000, byte);
#undef ALLOC
}
void EdenGame::freebuf() {
delete(bigfile_header);
bigfile_header = nullptr;
2016-12-18 14:13:36 -08:00
free(_gameRooms);
2016-12-04 14:26:44 -08:00
free(_gameIcons);
2016-12-18 14:13:36 -08:00
free(_bankDataBuf);
free(p_global);
2016-12-18 14:13:36 -08:00
free(_placeRawBuf);
free(gameConditions);
free(gameDialogs);
free(gamePhrases);
2016-12-04 14:54:58 -08:00
free(_mainBankBuf);
2016-12-18 14:13:36 -08:00
free(_glowBuffer);
free(_gameFont);
free(gameLipsync);
2016-12-04 14:54:58 -08:00
free(_musicBuf);
}
2016-12-19 13:41:00 -08:00
void EdenGame::openWindow() {
2016-11-30 22:51:15 -08:00
p_underBarsView = new View(_vm, 320, 40);
p_underBarsView->_normal._width = 320;
2016-11-30 22:51:15 -08:00
p_view2 = new View(_vm, 32, 32);
p_view2_buf = p_view2->_bufferPtr;
2016-11-30 22:51:15 -08:00
p_subtitlesview = new View(_vm, subtitles_x_width, 60);
p_subtitlesview_buf = p_subtitlesview->_bufferPtr;
2016-11-30 22:51:15 -08:00
p_underSubtitlesView = new View(_vm, subtitles_x_width, 60);
p_underSubtitlesView_buf = p_underSubtitlesView->_bufferPtr;
2016-12-18 14:13:36 -08:00
_mainView = new View(_vm, 640, 200);
_mainView->_normal._width = 320;
CLBlitter_FillView(_mainView, 0xFFFFFFFF);
_mainView->setSrcZoomValues(0, 0);
_mainView->setDisplayZoomValues(640, 400);
_mainView->centerIn(_vm->ScreenView);
p_mainview_buf = _mainView->_bufferPtr;
_mouseCenterX = _mainView->_normal._dstLeft + _mainView->_normal._width / 2;
_mouseCenterY = _mainView->_normal._dstTop + _mainView->_normal._height / 2;
CLMouse_SetPosition(_mouseCenterX, _mouseCenterY);
CLMouse_Hide();
2016-12-18 13:09:56 -08:00
_cursorPosX = 320 / 2;
_cursorPosY = 200 / 2;
}
void EdenGame::EmergencyExit() {
SysBeep(1);
}
void EdenGame::run() {
2016-12-19 13:41:00 -08:00
_invIconsCount = (_vm->getPlatform() == Common::kPlatformMacintosh) ? 9 : 11;
2016-12-19 22:32:40 -08:00
_roomIconsBase = _invIconsBase + _invIconsCount;
word_378CE = 0;
CRYOLib_ManagersInit();
_vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0 , 0);
_vm->_video->setForceZero2Black(true);
_vm->_video->setupTimer(12.5);
2016-12-18 14:13:36 -08:00
_voiceSound = CLSoundRaw_New(0, 11025 * 65536.0, 8, 0);
_hnmSoundChannel = _vm->_video->getSoundChannel();
CLSound_SetWantsDesigned(1); // CHECKME: Used?
_musicChannel = new CSoundChannel(_vm->_mixer, 11025, false);
_voiceChannel = new CSoundChannel(_vm->_mixer, 11025, false);
2016-10-22 14:15:45 +03:00
allocateBuffers();
openbigfile();
2016-12-19 13:41:00 -08:00
openWindow();
loadpermfiles();
if (!bufferAllocationErrorFl) {
LostEdenMac_InitPrefs();
if (_vm->getPlatform() == Common::kPlatformMacintosh)
initCubeMac();
else
initCubePC();
2016-12-18 14:13:36 -08:00
_mainView->_doubled = _doubledScreen;
while (!_quitFlag2) {
init_globals();
2016-12-18 14:13:36 -08:00
_quitFlag3 = false;
2016-12-18 13:09:56 -08:00
_normalCursor = true;
_torchCursor = false;
2016-09-30 07:48:27 +02:00
_cursKeepPos = Common::Point(-1, -1);
if (!_gameLoaded)
intro();
edmain();
startmusique(1);
drawBlackBars();
afficher();
fadeToBlack(3);
ClearScreen();
2016-09-26 23:44:42 +02:00
playHNM(95);
2016-12-11 13:44:58 -08:00
if (p_global->_endGameFlag == 50) {
loadrestart();
_gameLoaded = false;
2016-08-18 13:15:54 +02:00
}
fademusica0(2);
2016-10-22 14:15:45 +03:00
_musicChannel->stop();
2016-12-18 14:13:36 -08:00
_musicPlayingFlag = false;
_musicEnabledFlag = false;
2016-08-18 13:15:54 +02:00
}
// LostEdenMac_SavePrefs();
2016-08-18 13:15:54 +02:00
}
2016-10-22 14:15:45 +03:00
delete _voiceChannel;
delete _musicChannel;
fadeToBlack(4);
closebigfile();
freebuf();
CRYOLib_ManagersDone();
}
2016-08-18 13:15:54 +02:00
void EdenGame::edmain() {
//TODO
entergame();
2016-12-18 14:13:36 -08:00
while (!bufferAllocationErrorFl && !_quitFlag3 && p_global->_endGameFlag != 50) {
2016-12-18 13:09:56 -08:00
if (!_gameStarted) {
// if in demo mode, reset game after a while
2016-12-18 14:13:36 -08:00
_demoCurrentTicks = _vm->_timerTicks;
if (_demoCurrentTicks - _demoStartTicks > 3000) {
rundcurs();
afficher();
fademusica0(2);
fadeToBlack(3);
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
CLBlitter_FillView(_mainView, 0);
2016-10-22 14:15:45 +03:00
_musicChannel->stop();
2016-12-18 14:13:36 -08:00
_musicPlayingFlag = false;
_musicEnabledFlag = false;
intro();
entergame();
}
}
rundcurs();
musicspy();
FRDevents();
narrateur();
evenchrono();
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawInventory)
showObjects();
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawTopScreen)
drawTopScreen();
2016-12-04 13:15:38 -08:00
if ((p_global->_displayFlags & DisplayFlags::dfPanable) && (p_global->_displayFlags != DisplayFlags::dfPerson))
scrollpano();
2016-12-04 13:15:38 -08:00
if ((p_global->_displayFlags & DisplayFlags::dfMirror) && (p_global->_displayFlags != DisplayFlags::dfPerson))
scrollMirror();
2016-12-04 13:15:38 -08:00
if ((p_global->_displayFlags & DisplayFlags::dfFrescoes) && (p_global->_displayFlags != DisplayFlags::dfPerson))
scrollFrescoes();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfFlag2)
noclicpanel();
2016-12-25 02:17:07 -08:00
if (_animationActive)
anim_perso();
update_cursor();
afficher();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::intro() {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
// Play intro videos in HQ
2016-11-17 15:40:07 -08:00
CLSoundChannel_Stop(_hnmSoundChannel);
_vm->_video->closeSound();
_vm->_video->setupSound(5, 0x2000, 16, 22050 * 65536.0, 0);
_hnmSoundChannel = _vm->_video->getSoundChannel();
2016-09-26 23:44:42 +02:00
playHNM(2012);
playHNM(171);
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
_specialTextMode = false;
2016-09-26 23:44:42 +02:00
playHNM(2001);
2016-11-17 15:40:07 -08:00
CLSoundChannel_Stop(_hnmSoundChannel);
_vm->_video->closeSound();
_vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0, 0);
_hnmSoundChannel = _vm->_video->getSoundChannel();
} else {
playHNM(98); // Cryo logo
playHNM(171); // Virgin logo
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
_specialTextMode = false;
playHNM(170); // Intro video
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::entergame() {
char flag = 0;
2016-12-18 14:13:36 -08:00
_currentTime = _vm->_timerTicks / 100;
p_global->_gameTime = _currentTime;
_demoStartTicks = _vm->_timerTicks;
2016-12-18 13:09:56 -08:00
_gameStarted = false;
if (!_gameLoaded) {
2016-12-11 13:44:58 -08:00
p_global->_roomNum = 279;
2016-12-04 14:26:44 -08:00
p_global->_areaNum = Areas::arMo;
p_global->_var100 = 0xFF;
2016-12-11 13:44:58 -08:00
initPlace(p_global->_roomNum);
p_global->_currMusicNum = 0;
startmusique(1);
} else {
2016-12-04 13:15:38 -08:00
flag = p_global->_autoDialog; //TODO
initafterload();
2016-12-11 13:44:58 -08:00
lastMusicNum = p_global->_currMusicNum; //TODO: ???
p_global->_currMusicNum = 0;
startmusique(lastMusicNum);
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos = 0;
2016-12-18 13:09:56 -08:00
_gameStarted = true;
}
showObjects();
drawTopScreen();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-12-18 14:13:36 -08:00
_showBlackBars = true;
p_global->_var102 = 1;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
if (flag) {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 4;
p_global->_autoDialog = true;
parle_moi();
2016-08-18 13:15:54 +02:00
}
}
2016-10-08 21:21:21 +02:00
void EdenGame::signon(const char *s) {
}
void EdenGame::testPommeQ() {
if (!CLKeyboard_HasCmdDown())
return;
char key = CLKeyboard_GetLastASCII();
if (key == 'Q' || key == 'q') {
if (!pomme_q)
pomme_q = true;
}
}
void EdenGame::FRDevents() {
CLKeyboard_Read();
if (_allowDoubled) {
if (CLKeyboard_IsScanCodeDown(0x30)) { //TODO: const
2016-12-18 14:13:36 -08:00
if (!_keyboardHeld) {
2016-09-30 07:48:27 +02:00
_doubledScreen = !_doubledScreen;
2016-12-18 14:13:36 -08:00
_mainView->_doubled = _doubledScreen;
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
_keyboardHeld = true;
}
} else
2016-12-18 14:13:36 -08:00
_keyboardHeld = false;
}
2016-12-19 13:41:00 -08:00
int16 mouseY;
int16 mouseX;
2016-09-30 07:48:27 +02:00
CLMouse_GetPosition(&mouseX, &mouseY);
2016-12-18 14:13:36 -08:00
mouseX -= _mouseCenterX;
mouseY -= _mouseCenterY;
CLMouse_SetPosition(_mouseCenterX , _mouseCenterY);
2016-12-18 13:09:56 -08:00
_cursorPosX += mouseX;
_cursorPosX = CLIP<int16>(_cursorPosX, 4, 292);
2016-12-18 13:09:56 -08:00
_cursorPosY += mouseY;
int16 maxY = p_global->_displayFlags == DisplayFlags::dfFlag2 ? 190 : 170;
_cursorPosY = CLIP<int16>(_cursorPosY, 4, maxY);
2016-12-18 13:09:56 -08:00
_cirsorPanX = _cursorPosX;
2016-12-18 13:09:56 -08:00
if (_cursorPosY >= 10 && _cursorPosY <= 164 && !(p_global->_displayFlags & DisplayFlags::dfFrescoes))
_cirsorPanX += _scrollPos;
if (_normalCursor) {
_currCursor = 0;
2016-12-18 13:09:56 -08:00
_currSpot = scan_icon_list(_cirsorPanX + _cursCenter, _cursorPosY + _cursCenter, p_global->_iconsIndex);
if (_currSpot)
_currCursor = _currSpot->_cursorId;
}
if (_cursCenter == 0 && _currCursor != 53) {
_cursCenter = 11;
2016-12-18 13:09:56 -08:00
_cursorPosX -= 11;
}
if (_cursCenter == 11 && _currCursor == 53) {
_cursCenter = 0;
2016-12-18 13:09:56 -08:00
_cursorPosX += 11;
}
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfPanable) {
2016-12-19 13:41:00 -08:00
//TODO: _currSpot may be zero (due to scan_icon_list failure) if cursor slips between hot areas.
//fix me here or above?
2016-12-18 13:09:56 -08:00
if (_currSpot) { // ok, plug it here
2016-12-19 22:32:40 -08:00
_curSpot2 = _currSpot;
displayAdamMapMark(_curSpot2->_actionId - 14);
}
2016-08-18 13:15:54 +02:00
}
2016-12-18 13:09:56 -08:00
if (p_global->_displayFlags == DisplayFlags::dfFlag2 && _currSpot)
2016-12-19 22:32:40 -08:00
_curSpot2 = _currSpot;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfFrescoes) {
2016-09-30 07:48:27 +02:00
if (_frescoTalk)
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
2016-12-18 13:09:56 -08:00
if (_currCursor == 9 && !_torchCursor) {
rundcurs();
2016-12-18 13:09:56 -08:00
_torchCursor = true;
_glowX = -1;
2016-08-18 13:15:54 +02:00
}
2016-12-18 13:09:56 -08:00
if (_currCursor != 9 && _torchCursor) {
unglow();
2016-12-18 13:09:56 -08:00
_torchCursor = false;
_cursorSaved = false;
}
}
if (CLMouse_IsDown()) {
2016-12-18 13:09:56 -08:00
if (!_mouseHeld) {
_mouseHeld = true;
_gameStarted = true;
mouse();
}
} else
2016-12-18 13:09:56 -08:00
_mouseHeld = false;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags != DisplayFlags::dfFlag2) {
2016-09-30 07:48:27 +02:00
if (--_inventoryScrollDelay <= 0) {
2016-12-19 13:41:00 -08:00
if (p_global->_objCount > _invIconsCount && _cursorPosY > 164) {
if (_cursorPosX > 284 && p_global->_inventoryScrollPos + _invIconsCount < p_global->_objCount) {
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos++;
2016-09-30 07:48:27 +02:00
_inventoryScrollDelay = 20;
showObjects();
}
2016-12-18 13:09:56 -08:00
if (_cursorPosX < 30 && p_global->_inventoryScrollPos != 0) {
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos--;
2016-09-30 07:48:27 +02:00
_inventoryScrollDelay = 20;
showObjects();
}
2016-08-18 13:15:54 +02:00
}
}
}
2016-09-30 07:48:27 +02:00
if (_inventoryScrollDelay < 0)
_inventoryScrollDelay = 0;
if (!pomme_q) {
testPommeQ();
if (pomme_q) {
2016-12-19 22:32:40 -08:00
edenShudown();
return; //TODO: useless
2016-08-18 13:15:54 +02:00
}
}
}
2016-08-18 13:15:54 +02:00
Icon *EdenGame::scan_icon_list(int16 x, int16 y, int16 index) {
for (Icon *icon = &_gameIcons[index]; icon->sx >= 0; icon++) {
2016-12-03 15:40:53 -08:00
if (icon->_cursorId & 0x8000)
continue;
#if 0
// MAC version use this check. Same check is present in PC version, but never used
// Because of x >= clause two adjacent rooms has 1-pixel wide dead zone between them
// On valley view screens if cursor slips in this zone a crash in FRDevents occurs
// due to lack of proper checks
if (x < icon->ff_0 || x >= icon->ff_4
|| y < icon->ff_2 || y >= icon->ff_6)
#else
// PC version has this check inlined in FRDevents
// Should we keep it or fix edge coordinates in afroom() instead?
if (x < icon->sx || x > icon->ex
|| y < icon->sy || y > icon->ey)
#endif
continue;
return icon;
2016-08-18 13:15:54 +02:00
}
return nullptr;
}
void EdenGame::update_cursor() {
if (++_torchTick > 3)
_torchTick = 0;
if (!_torchTick) {
_torchCurIndex++;
_glowIndex++;
}
if (_torchCurIndex > 8)
_torchCurIndex = 0;
if (_glowIndex > 4)
_glowIndex = 0;
2016-10-24 22:02:43 +02:00
2016-12-18 13:09:56 -08:00
if (!_torchCursor) {
2016-12-25 02:17:07 -08:00
useMainBank();
2016-12-18 13:09:56 -08:00
sundcurs(_cursorPosX + _scrollPos, _cursorPosY);
if (_currCursor != 53 && _currCursor < 10) { //TODO: cond
if (_vm->getPlatform() == Common::kPlatformMacintosh)
2016-12-25 13:45:47 -08:00
engineMac();
else
2016-12-25 13:45:47 -08:00
enginePC();
} else
2016-12-18 13:09:56 -08:00
noclipax(_currCursor, _cursorPosX + _scrollPos, _cursorPosY);
_glowX = 1;
} else {
2016-10-07 23:06:10 +02:00
useBank(117);
2016-12-18 13:09:56 -08:00
if (_cursorPosX > 294)
_cursorPosX = 294;
unglow();
glow(_glowIndex);
2016-12-18 13:09:56 -08:00
noclipax(_torchCurIndex, _cursorPosX + _scrollPos, _cursorPosY);
2016-09-30 07:48:27 +02:00
if (_frescoTalk)
2016-12-25 02:17:07 -08:00
displaySubtitles();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::mouse() {
static void (EdenGame::*mouse_actions[])() = {
2016-09-27 07:53:50 +02:00
&EdenGame::moveNorth,
&EdenGame::moveEast,
&EdenGame::moveSouth,
&EdenGame::moveWest,
&EdenGame::plaquemonk,
&EdenGame::fresquesgraa,
&EdenGame::pushpierre,
&EdenGame::tetesquel,
&EdenGame::tetemomie,
2016-09-27 07:53:50 +02:00
&EdenGame::moveNorth,
2016-12-11 22:52:10 -08:00
&EdenGame::kingDialog1,
&EdenGame::kingDialog2,
&EdenGame::kingDialog3,
&EdenGame::gotohall,
&EdenGame::demitourlabi,
&EdenGame::squelmoorkong,
&EdenGame::gotonido,
&EdenGame::voirlac,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::final,
2016-09-27 07:53:50 +02:00
&EdenGame::moveNorth,
&EdenGame::moveSouth,
&EdenGame::visiter,
&EdenGame::dinosoufle,
&EdenGame::fresqueslasc,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
&EdenGame::gotoval,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
2016-12-19 13:41:00 -08:00
&EdenGame::getPrism,
&EdenGame::ret,
&EdenGame::ret,
2016-12-19 13:41:00 -08:00
&EdenGame::getEgg,
&EdenGame::ret,
&EdenGame::ret,
2016-12-19 13:41:00 -08:00
&EdenGame::getMushroom,
&EdenGame::getBadMushroom,
&EdenGame::getKnife,
&EdenGame::getNest,
&EdenGame::getFullNest,
&EdenGame::getGold,
nullptr,
&EdenGame::ret,
2016-12-19 13:41:00 -08:00
&EdenGame::getSunStone,
&EdenGame::getHorn,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
&EdenGame::ret,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
2016-12-19 13:41:00 -08:00
&EdenGame::getTablet,
&EdenGame::clicplanval,
2016-09-26 23:44:42 +02:00
&EdenGame::endFrescoes,
&EdenGame::choisir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::roi,
&EdenGame::dina,
&EdenGame::thoo,
&EdenGame::monk,
&EdenGame::bourreau,
&EdenGame::messager,
&EdenGame::mango,
&EdenGame::eve,
&EdenGame::azia,
&EdenGame::mammi,
&EdenGame::gardes,
&EdenGame::fisher,
&EdenGame::dino,
&EdenGame::tyran,
&EdenGame::morkus,
&EdenGame::ret,
&EdenGame::parle_moi,
&EdenGame::adam,
2016-12-11 22:52:10 -08:00
&EdenGame::takeObject,
2016-12-04 13:15:38 -08:00
&EdenGame::putObject,
&EdenGame::clictimbre,
2016-12-19 13:41:00 -08:00
&EdenGame::handleDinaDialog,
&EdenGame::close_perso,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
&EdenGame::generique,
2016-12-19 22:32:40 -08:00
&EdenGame::choseSubtitleOption,
&EdenGame::edenQuit,
&EdenGame::restart,
&EdenGame::cancel2,
&EdenGame::testvoice,
2016-12-19 22:32:40 -08:00
&EdenGame::changeVolume,
&EdenGame::load,
&EdenGame::save,
&EdenGame::cliccurstape,
&EdenGame::playtape,
&EdenGame::stoptape,
&EdenGame::rewindtape,
&EdenGame::forwardtape,
&EdenGame::confirmyes,
&EdenGame::confirmno,
&EdenGame::gotocarte
};
2016-12-18 13:09:56 -08:00
if (!(_currSpot = scan_icon_list(_cirsorPanX + _cursCenter,
_cursorPosY + _cursCenter, p_global->_iconsIndex)))
return;
2016-12-19 22:32:40 -08:00
_curSpot2 = _currSpot;
2016-12-18 13:09:56 -08:00
debug("invoking mouse action %d", _currSpot->_actionId);
if (mouse_actions[_currSpot->_actionId])
(this->*mouse_actions[_currSpot->_actionId])();
}
////// film.c
2016-09-27 07:53:50 +02:00
// Original name: showfilm
void EdenGame::showMovie(char arg1) {
_vm->_video->readHeader(_hnmContext);
if (_vm->_video->_curVideoNum == 92) {
// _hnmContext->_header._unusedFlag2 = 0; CHECKME: Useless?
2016-11-17 15:40:07 -08:00
CLSoundChannel_SetVolumeLeft(_hnmSoundChannel, 0);
CLSoundChannel_SetVolumeRight(_hnmSoundChannel, 0);
}
if (_vm->_video->getVersion(_hnmContext) != 4)
return;
bool playing = true;
_vm->_video->allocMemory(_hnmContext);
2016-12-18 14:13:36 -08:00
_hnmView = new View(_vm, _hnmContext->_header._width, _hnmContext->_header._height);
_hnmView->setSrcZoomValues(0, 0);
_hnmView->setDisplayZoomValues(_hnmContext->_header._width * 2, _hnmContext->_header._height * 2);
_hnmView->centerIn(_vm->ScreenView);
_hnmViewBuf = _hnmView->_bufferPtr;
if (arg1) {
2016-12-18 14:13:36 -08:00
_hnmView->_normal._height = 160;
_hnmView->_zoom._height = 320; //TODO: width??
_hnmView->_normal._dstTop = _mainView->_normal._dstTop + 16;
_hnmView->_zoom._dstTop = _mainView->_zoom._dstTop + 32;
}
2016-12-18 14:13:36 -08:00
_vm->_video->setFinalBuffer(_hnmContext, _hnmView->_bufferPtr);
_hnmView->_doubled = _doubledScreen;
do {
2016-12-18 14:13:36 -08:00
_hnmFrameNum = _vm->_video->getFrameNum(_hnmContext);
_vm->_video->waitLoop(_hnmContext);
playing = _vm->_video->nextElement(_hnmContext);
2016-12-18 14:13:36 -08:00
if (_specialTextMode)
2016-09-26 23:44:42 +02:00
displayHNMSubtitles();
else
musicspy();
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_hnmView);
2016-11-30 22:51:15 -08:00
assert(_vm->ScreenView->_pitch == 320);
CLKeyboard_Read();
if (_allowDoubled) {
if (CLKeyboard_IsScanCodeDown(0x30)) { //TODO: const
2016-12-18 14:13:36 -08:00
if (!_keyboardHeld) {
2016-09-30 07:48:27 +02:00
_doubledScreen = !_doubledScreen;
2016-12-18 14:13:36 -08:00
_hnmView->_doubled = _doubledScreen; //TODO: but mainview ?
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
_keyboardHeld = true;
2016-08-18 13:15:54 +02:00
}
} else
2016-12-18 14:13:36 -08:00
_keyboardHeld = false;
2016-08-18 13:15:54 +02:00
}
if (arg1) {
if (CLMouse_IsDown()) {
2016-12-18 13:09:56 -08:00
if (!_mouseHeld) {
_mouseHeld = true;
2016-12-18 14:13:36 -08:00
_videoCanceledFlag = true;
}
} else
2016-12-18 13:09:56 -08:00
_mouseHeld = false;
2016-08-18 13:15:54 +02:00
}
2016-12-18 14:13:36 -08:00
} while (playing && !_videoCanceledFlag);
delete _hnmView;
_vm->_video->deallocMemory(_hnmContext);
}
2016-09-26 23:44:42 +02:00
void EdenGame::playHNM(int16 num) {
2016-09-26 07:57:27 +02:00
perso_t *perso = nullptr;
int16 oldDialogType = -1;
_vm->_video->_curVideoNum = num;
if (num != 2001 && num != 2012 && num != 98 && num != 171) {
2016-12-11 13:44:58 -08:00
byte oldMusicType = p_global->_newMusicType;
p_global->_newMusicType = MusicType::mtEvent;
musique();
musicspy();
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = oldMusicType;
2016-08-18 13:15:54 +02:00
}
p_global->_videoSubtitleIndex = 1;
2016-12-18 14:13:36 -08:00
if (_specialTextMode) {
2016-12-04 14:26:44 -08:00
perso = p_global->_characterPtr;
2016-12-04 13:15:38 -08:00
oldDialogType = p_global->_dialogType;
prechargephrases(num);
fademusica0(1);
2016-10-22 14:15:45 +03:00
_musicChannel->stop();
}
2016-12-18 14:13:36 -08:00
_showVideoSubtitle = false;
_videoCanceledFlag = false;
shnmfl(num);
_vm->_video->reset(_hnmContext);
_vm->_video->flushPreloadBuffer(_hnmContext);
if (needToFade) {
fadeToBlack(4);
ClearScreen();
needToFade = false;
}
if (num == 2012 || num == 98 || num == 171)
2016-09-27 07:53:50 +02:00
showMovie(0);
else
2016-09-27 07:53:50 +02:00
showMovie(1);
2016-09-30 07:48:27 +02:00
_cursKeepPos = Common::Point(-1, -1);
2016-12-18 14:13:36 -08:00
_mainView->_doubled = _doubledScreen;
if (_specialTextMode) {
_musicFadeFlag = 3;
musicspy();
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = oldDialogType;
2016-12-18 14:13:36 -08:00
_specialTextMode = false;
2016-08-18 13:15:54 +02:00
}
2016-12-18 14:13:36 -08:00
if (_videoCanceledFlag)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
if (_vm->_video->_curVideoNum == 167)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
if (_vm->_video->_curVideoNum == 104)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
if (_vm->_video->_curVideoNum == 102)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
if (_vm->_video->_curVideoNum == 77)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
if (_vm->_video->_curVideoNum == 149)
p_global->_varF1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
}
2016-09-26 23:44:42 +02:00
// Original name bullehnm
void EdenGame::displayHNMSubtitles() {
2016-12-01 22:59:55 -08:00
uint16 *frames;
perso_t *perso;
switch (_vm->_video->_curVideoNum) {
case 170:
frames = kFramesVid170;
perso = &kPersons[PER_UNKN_156];
break;
case 83:
frames = kFramesVid83;
perso = &kPersons[PER_MORKUS];
break;
case 88:
frames = kFramesVid88;
perso = &kPersons[PER_MORKUS];
break;
case 89:
frames = kFramesVid89;
perso = &kPersons[PER_MORKUS];
break;
case 94:
frames = kFramesVid94;
perso = &kPersons[PER_MORKUS];
break;
default:
return;
2016-08-18 13:15:54 +02:00
}
2016-12-01 22:59:55 -08:00
uint16 *frames_start = frames;
uint16 frame;
while ((frame = *frames++) != 0xFFFF) {
2016-12-18 14:13:36 -08:00
if ((frame & ~0x8000) == _hnmFrameNum)
break;
2016-08-18 13:15:54 +02:00
}
2016-12-01 22:59:55 -08:00
if (frame == 0xFFFF) {
2016-12-18 14:13:36 -08:00
if (_showVideoSubtitle)
af_subtitlehnm();
return;
2016-08-18 13:15:54 +02:00
}
if (frame & 0x8000)
2016-12-18 14:13:36 -08:00
_showVideoSubtitle = false;
else {
p_global->_videoSubtitleIndex = (frames - frames_start) / 2 + 1;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = perso;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
int16 num = (perso->_id << 3) | p_global->_dialogType;
2016-10-07 00:45:08 +02:00
dialoscansvmas((dial_t *)getElem(gameDialogs, num));
2016-12-18 14:13:36 -08:00
_showVideoSubtitle = true;
}
2016-12-18 14:13:36 -08:00
if (_showVideoSubtitle)
af_subtitlehnm();
}
////// sound.c
void EdenGame::musique() {
2016-12-11 13:44:58 -08:00
if (p_global->_newMusicType == MusicType::mtDontChange)
return;
dial_t *dial = (dial_t *)getElem(gameDialogs, 128);
for (;;dial++) {
2016-10-07 00:45:08 +02:00
if (dial->_flags == -1 && dial->_condNumLow == -1)
2016-08-18 13:15:54 +02:00
return;
byte flag = dial->_flags;
byte hidx = (dial->_textCondHiMask & 0xC0) >> 6;
byte lidx = dial->_condNumLow; //TODO: fixme - unsigned = signed
if (flag & 0x10)
hidx |= 4;
if (testcondition(((hidx << 8) | lidx) & 0x7FF))
2016-08-18 13:15:54 +02:00
break;
}
byte mus = dial->_textNumLow;
2016-12-11 13:44:58 -08:00
p_global->_newMusicType = MusicType::mtDontChange;
if (mus != 0 && mus != 2 && mus < 50)
startmusique(mus);
}
2016-09-14 23:48:01 +02:00
void EdenGame::startmusique(byte num) {
2016-12-11 13:44:58 -08:00
if (num == p_global->_currMusicNum)
return;
2016-12-18 14:13:36 -08:00
if (_musicPlayingFlag) {
fademusica0(1);
2016-10-22 14:15:45 +03:00
_musicChannel->stop();
}
loadmusicfile(num);
2016-12-11 13:44:58 -08:00
p_global->_currMusicNum = num;
2016-12-04 14:54:58 -08:00
_musSequencePtr = _musicBuf + 32; //TODO: rewrite it properly
int16 seq_size = READ_LE_UINT16(_musicBuf + 30);
2016-12-18 14:13:36 -08:00
_musicPatternsPtr = _musicBuf + 30 + seq_size;
2016-12-04 14:54:58 -08:00
int16 pat_size = READ_LE_UINT16(_musicBuf + 27);
2016-12-18 14:13:36 -08:00
_musicSamplesPtr = _musicBuf + 32 + 4 + pat_size;
int16 freq = READ_LE_UINT16(_musicSamplesPtr - 2);
2016-10-22 14:15:45 +03:00
delete _musicChannel;
_musicChannel = new CSoundChannel(_vm->_mixer, freq == 166 ? 11025 : 22050, false);
2016-12-18 14:13:36 -08:00
_musicEnabledFlag = true;
2016-10-22 14:15:45 +03:00
2016-12-18 14:13:36 -08:00
_musicSequencePos = 0;
_musicLeftVol = p_global->_prefMusicVol[0];
_musicRightVol = p_global->_prefMusicVol[1];
_musicChannel->setVolume(_musicLeftVol, _musicRightVol);
}
void EdenGame::musicspy() {
2016-12-18 14:13:36 -08:00
if (!_musicEnabledFlag)
return;
2016-12-18 14:13:36 -08:00
_musicLeftVol = p_global->_prefMusicVol[0];
_musicRightVol = p_global->_prefMusicVol[1];
if (_musicFadeFlag & 3)
fademusicup();
2016-10-22 14:15:45 +03:00
if (_personTalking && !_voiceChannel->numQueued())
_musicFadeFlag = 3;
2016-10-22 14:15:45 +03:00
if (_musicChannel->numQueued() < 3) {
2016-12-18 14:13:36 -08:00
byte patnum = _musSequencePtr[(int)_musicSequencePos];
if (patnum == 0xFF) {
// rewind
2016-12-18 14:13:36 -08:00
_musicSequencePos = 0;
patnum = _musSequencePtr[(int)_musicSequencePos];
2016-08-18 13:15:54 +02:00
}
2016-12-18 14:13:36 -08:00
_musicSequencePos++;
byte *patptr = _musicPatternsPtr + patnum * 6;
int ofs = patptr[0] + (patptr[1] << 8) + (patptr[2] << 16);
int len = patptr[3] + (patptr[4] << 8) + (patptr[5] << 16);
2016-12-18 14:13:36 -08:00
_musicChannel->queueBuffer(_musicSamplesPtr + ofs, len);
_musicPlayingFlag = true;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
int EdenGame::loadmusicfile(int16 num) {
PakHeaderItem *file = &bigfile_header->_files[num + 435];
2016-12-07 15:04:25 -08:00
int32 size = file->_size;
int32 offs = file->_offs;
2016-11-10 15:37:48 -08:00
h_bigfile.seek(offs, SEEK_SET);
2016-10-08 23:31:21 +02:00
int32 numread = size;
if (numread > 0x140000) //TODO: const
numread = 0x140000;
2016-12-04 14:54:58 -08:00
h_bigfile.read(_musicBuf, numread);
return size;
}
void EdenGame::persovox() {
2016-12-11 13:44:58 -08:00
int16 num = p_global->_textNum;
if (p_global->_textBankIndex != 1)
num += 565;
2016-12-11 13:44:58 -08:00
if (p_global->_textBankIndex == 3)
num += 707;
2016-12-18 14:13:36 -08:00
_voiceSamplesSize = ssndfl(num);
2016-12-11 13:44:58 -08:00
int16 volumeLeft = p_global->_prefSoundVolume[0];
int16 volumeRight = p_global->_prefSoundVolume[1];
2016-10-22 14:15:45 +03:00
int16 stepLeft = _musicChannel->_volumeLeft < volumeLeft ? stepLeft = 1 : -1;
int16 stepRight = _musicChannel->_volumeRight < volumeRight ? stepRight = 1 : -1;
do {
if (volumeLeft != _musicChannel->_volumeLeft)
2016-10-22 14:15:45 +03:00
_musicChannel->setVolumeLeft(_musicChannel->_volumeLeft + stepLeft);
if (volumeRight != _musicChannel->_volumeRight)
2016-10-22 14:15:45 +03:00
_musicChannel->setVolumeRight(_musicChannel->_volumeRight + stepRight);
} while (_musicChannel->_volumeLeft != volumeLeft || _musicChannel->_volumeRight != volumeRight);
2016-12-11 13:44:58 -08:00
volumeLeft = p_global->_prefVoiceVol[0];
volumeRight = p_global->_prefVoiceVol[1];
2016-10-22 14:15:45 +03:00
_voiceChannel->setVolume(volumeLeft, volumeRight);
2016-12-18 14:13:36 -08:00
_voiceChannel->queueBuffer((byte*)voiceSamplesBuffer, _voiceSamplesSize, true);
_personTalking = true;
_musicFadeFlag = 0;
2016-12-04 14:26:44 -08:00
_lastAnimTicks = _vm->_timerTicks;
}
void EdenGame::endpersovox() {
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
if (_personTalking) {
2016-10-22 14:15:45 +03:00
_voiceChannel->stop();
_personTalking = false;
_musicFadeFlag = 3;
2016-08-18 13:15:54 +02:00
}
if (_soundAllocated) {
free(voiceSamplesBuffer);
voiceSamplesBuffer = nullptr;
_soundAllocated = false;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::fademusicup() {
if (_musicFadeFlag & 2) {
int16 vol = _musicChannel->_volumeLeft;
2016-12-18 14:13:36 -08:00
if (vol < _musicLeftVol) {
vol += 8;
2016-12-18 14:13:36 -08:00
if (vol > _musicLeftVol)
vol = _musicLeftVol;
2016-08-18 13:15:54 +02:00
} else {
vol -= 8;
2016-12-18 14:13:36 -08:00
if (vol < _musicLeftVol)
vol = _musicLeftVol;
}
2016-10-22 14:15:45 +03:00
_musicChannel->setVolumeLeft(vol);
2016-12-18 14:13:36 -08:00
if (vol == _musicLeftVol)
_musicFadeFlag &= ~2;
}
if (_musicFadeFlag & 1) {
int16 vol = _musicChannel->_volumeRight;
2016-12-18 14:13:36 -08:00
if (vol < _musicRightVol) {
vol += 8;
2016-12-18 14:13:36 -08:00
if (vol > _musicRightVol)
vol = _musicRightVol;
2016-08-18 13:15:54 +02:00
} else {
vol -= 8;
2016-12-18 14:13:36 -08:00
if (vol < _musicRightVol)
vol = _musicRightVol;
2016-08-18 13:15:54 +02:00
}
2016-10-22 14:15:45 +03:00
_musicChannel->setVolumeRight(vol);
2016-12-18 14:13:36 -08:00
if (vol == _musicRightVol)
_musicFadeFlag &= ~1;
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::fademusica0(int16 delay) {
int16 volume;
2016-10-22 14:15:45 +03:00
while ((volume = _musicChannel->getVolume()) > 2) {
volume -= 2;
if (volume < 2)
volume = 2;
2016-10-22 14:15:45 +03:00
_musicChannel->setVolume(volume, volume);
wait(delay);
2016-08-18 13:15:54 +02:00
}
}
//// obj.c
2016-12-18 13:09:56 -08:00
// Original name: getobjaddr
object_t *EdenGame::getObjectPtr(int16 id) {
int i;
for (i = 0; i < MAX_OBJECTS; i++) {
2016-12-04 14:26:44 -08:00
if (_objects[i]._id == id)
break;
}
2016-12-18 13:09:56 -08:00
return &_objects[i];
}
2016-12-18 13:09:56 -08:00
void EdenGame::countObjects() {
2016-09-14 23:48:01 +02:00
int16 index = 0;
byte total = 0;
for (int i = 0; i < MAX_OBJECTS; i++) {
2016-12-04 14:26:44 -08:00
int16 count = _objects[i]._count;
2016-08-18 13:15:54 +02:00
#ifdef EDEN_DEBUG
count = 1;
goto show_all_objects; //DEBUG
2016-08-18 13:15:54 +02:00
#endif
if (count == 0)
continue;
2016-12-04 14:26:44 -08:00
if (_objects[i]._flags & ObjectFlags::ofInHands)
count--;
show_all_objects:
;
if (count) {
total += count;
while (count--)
2016-12-04 14:26:44 -08:00
own_objects[index++] = _objects[i]._id;
2016-08-18 13:15:54 +02:00
}
}
2016-12-11 13:44:58 -08:00
p_global->_objCount = total;
}
2016-08-18 13:15:54 +02:00
void EdenGame::showObjects() {
2016-12-19 22:32:40 -08:00
Icon *icon = &_gameIcons[_invIconsBase];
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~(DrawFlags::drDrawInventory | DrawFlags::drDrawFlag2);
2016-12-18 13:09:56 -08:00
countObjects();
2016-12-11 13:44:58 -08:00
int16 total = p_global->_objCount;
2016-12-19 13:41:00 -08:00
for (int16 i = _invIconsCount; i--; icon++) {
if (total) {
2016-12-03 15:40:53 -08:00
icon->_cursorId &= ~0x8000;
total--;
} else
2016-12-03 15:40:53 -08:00
icon->_cursorId |= 0x8000;
}
2016-12-25 02:17:07 -08:00
useMainBank();
noclipax(55, 0, 176);
2016-12-19 22:32:40 -08:00
icon = &_gameIcons[_invIconsBase];
2016-12-11 13:44:58 -08:00
total = p_global->_objCount;
int16 index = p_global->_inventoryScrollPos;
2016-12-19 13:41:00 -08:00
for (int16 i = _invIconsCount; total-- && i--; icon++) {
char obj = own_objects[index++];
2016-12-03 15:40:53 -08:00
icon->_objectId = obj;
noclipax(obj + 9, icon->sx, 178);
}
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
2016-12-04 13:15:38 -08:00
if ((p_global->_displayFlags & DisplayFlags::dfMirror) || (p_global->_displayFlags & DisplayFlags::dfPanable)) {
2016-09-27 07:53:50 +02:00
saveBottomFrieze();
scroll();
2016-08-18 13:15:54 +02:00
}
}
2016-12-04 14:26:44 -08:00
void EdenGame::winObject(int16 id) {
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-10-07 00:45:08 +02:00
object->_flags |= ObjectFlags::ofFlag1;
object->_count++;
2016-12-11 13:44:58 -08:00
p_global->_curItemsMask |= object->_itemMask;
p_global->_wonItemsMask |= object->_itemMask;
p_global->_curPowersMask |= object->_powerMask;
p_global->_wonPowersMask |= object->_powerMask;
}
2016-09-26 23:44:42 +02:00
void EdenGame::loseObject(int16 id) {
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-10-07 00:45:08 +02:00
if (object->_count > 0)
object->_count--;
if (!object->_count) {
object->_flags &= ~ObjectFlags::ofFlag1;
2016-12-11 13:44:58 -08:00
p_global->_curItemsMask &= ~object->_itemMask;
p_global->_curPowersMask &= ~object->_powerMask;
}
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = 0;
p_global->_curObjectFlags = 0;
p_global->_curObjectCursor = 9;
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId |= 0x8000;
2016-10-07 00:45:08 +02:00
object->_flags &= ~ObjectFlags::ofInHands;
2016-12-18 13:09:56 -08:00
_normalCursor = true;
_currCursor = 0;
2016-12-18 13:09:56 -08:00
_torchCursor = false;
}
2016-12-11 22:52:10 -08:00
void EdenGame::lostObject() {
parlemoiNormalFlag = true;
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId)
loseObject(p_global->_curObjectId);
}
bool EdenGame::objecthere(int16 id) {
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-12-01 22:59:55 -08:00
for (pCurrentObjectLocation = &kObjectLocations[object->_locations]; *pCurrentObjectLocation != 0xFFFF; pCurrentObjectLocation++) {
2016-12-11 13:44:58 -08:00
if (*pCurrentObjectLocation == p_global->_roomNum)
return true;
2016-08-18 13:15:54 +02:00
}
return false;
}
2016-08-18 13:15:54 +02:00
2016-09-14 23:48:01 +02:00
void EdenGame::objectmain(int16 id) {
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId &= ~0x8000;
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = object->_id;
p_global->_curObjectCursor = p_global->_curObjectId + 9;
2016-10-07 00:45:08 +02:00
object->_flags |= ObjectFlags::ofInHands;
p_global->_curObjectFlags = object->_flags;
2016-12-04 13:15:38 -08:00
_currCursor = p_global->_curObjectId + 9;
2016-12-18 13:09:56 -08:00
_normalCursor = false;
}
2016-12-11 22:52:10 -08:00
void EdenGame::getObject(int16 id) {
Room *room = p_global->_roomPtr;
2016-12-04 13:15:38 -08:00
if (p_global->_curObjectId)
return;
if (!objecthere(id))
return;
*pCurrentObjectLocation |= 0x8000;
objectmain(id);
2016-12-04 14:26:44 -08:00
winObject(id);
showObjects();
2016-12-15 22:47:29 -08:00
p_global->_roomImgBank = room->_bank;
p_global->_roomVidNum = room->_video;
2016-10-07 23:06:10 +02:00
displayPlace();
}
2016-12-04 13:15:38 -08:00
void EdenGame::putObject() {
if (!p_global->_curObjectId)
return;
2016-12-04 14:26:44 -08:00
_gameIcons[16]._cursorId |= 0x8000;
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(p_global->_curObjectId);
p_global->_curObjectCursor = 9;
2016-12-04 13:15:38 -08:00
p_global->_curObjectId = 0;
p_global->_curObjectFlags = 0;
2016-10-07 00:45:08 +02:00
object->_flags &= ~ObjectFlags::ofInHands;
p_global->_nextDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
p_global->_dialogType = DialogType::dtTalk;
showObjects();
2016-12-18 13:09:56 -08:00
_normalCursor = true;
}
2016-12-11 22:52:10 -08:00
void EdenGame::newObject(int16 id, int16 arg2) {
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-12-01 22:59:55 -08:00
uint16 e, *t = &kObjectLocations[object->_locations];
while ((e = *t) != 0xFFFF) {
e &= ~0x8000;
if ((e >> 8) == arg2)
*t = e;
t++;
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
2016-09-14 23:48:01 +02:00
void EdenGame::giveobjectal(int16 id) {
if (id == Objects::obKnife)
kObjectLocations[2] = 0;
if (id == Objects::obApple)
p_global->_stepsToFindAppleNormal = 0;
2016-12-04 14:26:44 -08:00
if (id >= Objects::obEyeInTheStorm && id < (Objects::obRiverThatWinds + 1) && p_global->_roomCharacterType == PersonFlags::pftVelociraptor) {
//TODO: fix that cond above
2016-12-18 13:09:56 -08:00
object_t *object = getObjectPtr(id);
2016-12-11 13:44:58 -08:00
p_global->_roomCharacterPtr->_powers &= ~object->_powerMask;
2016-08-18 13:15:54 +02:00
}
2016-12-04 14:26:44 -08:00
winObject(id);
}
2016-08-18 13:15:54 +02:00
2016-12-04 14:26:44 -08:00
void EdenGame::giveObject() {
2016-12-11 13:44:58 -08:00
byte id = p_global->_giveObj1;
if (id) {
2016-12-11 13:44:58 -08:00
p_global->_giveObj1 = 0;
giveobjectal(id);
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
id = p_global->_giveObj2;
if (id) {
2016-12-11 13:44:58 -08:00
p_global->_giveObj2 = 0;
giveobjectal(id);
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
id = p_global->_giveObj3;
if (id) {
2016-12-11 13:44:58 -08:00
p_global->_giveObj3 = 0;
giveobjectal(id);
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
2016-12-11 22:52:10 -08:00
void EdenGame::takeObject() {
2016-12-19 22:32:40 -08:00
objectmain(_curSpot2->_objectId);
p_global->_nextDialogPtr = nullptr;
2016-12-04 13:15:38 -08:00
_closeCharacterDialog = false;
p_global->_dialogType = DialogType::dtTalk;
2016-12-11 13:44:58 -08:00
if (p_global->_inventoryScrollPos)
p_global->_inventoryScrollPos--;
showObjects();
}
////
2016-12-18 13:09:56 -08:00
// Original name: newchampi
void EdenGame::newMushroom() {
2016-12-04 14:26:44 -08:00
if (_objects[Objects::obShroom - 1]._count == 0) {
2016-12-18 13:09:56 -08:00
newObject(Objects::obShroom, p_global->_citadelAreaNum);
newObject(Objects::obBadShroom, p_global->_citadelAreaNum);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::newnidv() {
Room *room = p_global->_citaAreaFirstRoom;
2016-12-04 14:26:44 -08:00
if (_objects[Objects::obNest - 1]._count)
return;
2016-12-18 13:09:56 -08:00
object_t *obj = getObjectPtr(Objects::obNest);
2016-12-01 22:59:55 -08:00
for (uint16 *ptr = kObjectLocations + obj->_locations; *ptr != 0xFFFF; ptr++) {
2016-12-18 13:09:56 -08:00
if ((*ptr & ~0x8000) >> 8 != p_global->_citadelAreaNum)
continue;
*ptr &= ~0x8000;
2016-12-15 22:47:29 -08:00
for (; room->_id != 0xFF; room++) {
if (room->_location == (*ptr & 0xFF)) {
room->_bank = 279;
room->_id = 9;
room++;
2016-12-15 22:47:29 -08:00
room->_bank = 280;
return;
}
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::newnido() {
Room *room = p_global->_citaAreaFirstRoom;
2016-12-04 14:26:44 -08:00
if (_objects[Objects::obFullNest - 1]._count)
return;
2016-12-04 14:26:44 -08:00
if (_objects[Objects::obNest - 1]._count)
return;
2016-12-18 13:09:56 -08:00
object_t *obj = getObjectPtr(Objects::obFullNest);
2016-12-01 22:59:55 -08:00
for (uint16 *ptr = kObjectLocations + obj->_locations; *ptr != 0xFFFF; ptr++) {
2016-12-18 13:09:56 -08:00
if ((*ptr & ~0x8000) >> 8 != p_global->_citadelAreaNum)
continue;
*ptr &= ~0x8000;
2016-12-15 22:47:29 -08:00
for (; room->_id != 0xFF; room++) {
if (room->_location == (*ptr & 0xFF)) {
room->_bank = 277;
room->_id = 9;
room++;
2016-12-15 22:47:29 -08:00
room->_bank = 278;
return;
2016-08-18 13:15:54 +02:00
}
}
}
}
void EdenGame::newor() {
2016-12-04 14:26:44 -08:00
if (_objects[Objects::obGold - 1]._count == 0) {
2016-12-18 13:09:56 -08:00
newObject(Objects::obGold, p_global->_citadelAreaNum);
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
void EdenGame::gotopanel() {
if (pomme_q)
2016-12-04 13:15:38 -08:00
byte_31D64 = p_global->_autoDialog; //TODO: check me
_noPalette = false;
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 85;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = nullptr;
p_global->_drawFlags |= DrawFlags::drDrawMenu;
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag2;
p_global->_menuFlags = 0;
2016-12-19 22:32:40 -08:00
displayPanel();
fadeToBlack(3);
2016-12-19 22:32:40 -08:00
displayTopPanel();
2016-12-18 14:13:36 -08:00
CLBlitter_CopyView2Screen(_mainView);
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
2016-12-18 13:09:56 -08:00
_cursorPosX = 320 / 2;
_cursorPosY = 200 / 2;
2016-12-18 14:13:36 -08:00
CLMouse_SetPosition(_mouseCenterX, _mouseCenterY);
}
void EdenGame::noclicpanel() {
if (p_global->_menuFlags & MenuFlags::mfFlag4) {
depcurstape();
return;
}
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawFlag8)
return;
if (p_global->_menuFlags & MenuFlags::mfFlag1) {
changervol();
return;
}
byte num;
2016-12-19 22:32:40 -08:00
if (_curSpot2 >= &_gameIcons[119]) {
debug("noclic: objid = %p, glob3,2 = %2X %2X", (void *)_curSpot2, p_global->_menuItemIdHi, p_global->_menuItemIdLo);
if (_curSpot2->_objectId == (uint16)((p_global->_menuItemIdLo + p_global->_menuItemIdHi) << 8)) //TODO: check me
return;
} else {
2016-12-19 22:32:40 -08:00
int idx = _curSpot2 - &_gameIcons[105];
if (idx == 0) {
2016-12-11 13:44:58 -08:00
p_global->_menuItemIdLo = 1;
num = 1;
goto skip;
}
num = idx & 0x7F + 1;
if (num >= 5)
num = 1;
if (num == p_global->_var43)
return;
p_global->_var43 = 0;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
num = p_global->_menuItemIdLo;
2016-12-19 22:32:40 -08:00
p_global->_menuItemIdLo = _curSpot2->_objectId & 0xFF;
skip:
;
2016-12-19 22:32:40 -08:00
p_global->_menuItemIdHi = (_curSpot2->_objectId & 0xFF00) >> 8;
2016-12-11 13:44:58 -08:00
debug("noclic: new glob3,2 = %2X %2X", p_global->_menuItemIdHi, p_global->_menuItemIdLo);
2016-12-19 22:32:40 -08:00
displayResult();
num &= 0xF0;
if (num != 0x30)
2016-12-11 13:44:58 -08:00
num = p_global->_menuItemIdLo & 0xF0;
if (num == 0x30)
2016-12-19 22:32:40 -08:00
displayCursors();
}
void EdenGame::generique() {
drawBlackBars();
afficher();
fadeToBlack(3);
ClearScreen();
2016-12-11 13:44:58 -08:00
int oldmusic = p_global->_currMusicNum;
2016-09-26 23:44:42 +02:00
playHNM(95);
2016-12-19 22:32:40 -08:00
displayPanel();
displayTopPanel();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
startmusique(oldmusic);
}
void EdenGame::cancel2() {
drawTopScreen();
showObjects();
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 16;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawMenu;
gametomiroir(1);
}
void EdenGame::testvoice() {
2016-12-11 13:44:58 -08:00
p_global->_frescoNumber = 0;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = kPersons;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
int16 num = (kPersons[PER_ROI]._id << 3) | p_global->_dialogType;
dialoscansvmas((dial_t *)getElem(gameDialogs, num));
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
displaySubtitles();
persovox();
2016-12-04 13:15:38 -08:00
waitEndSpeak();
endpersovox();
p_global->_varCA = 0;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
}
void EdenGame::load() {
char name[132];
_gameLoaded = false;
2016-12-11 13:44:58 -08:00
byte oldMusic = p_global->_currMusicNum; //TODO: from ush to byte?!
fademusica0(1);
desktopcolors();
FlushEvents(-1, 0);
// if(OpenDialog(0, 0)) //TODO: write me
{
// TODO
strcpy(name, "edsave1.000");
loadgame(name);
2016-08-18 13:15:54 +02:00
}
CLMouse_Hide();
2016-09-26 07:57:27 +02:00
CLBlitter_FillScreenView(0xFFFFFFFF);
fadeToBlack(3);
CLBlitter_FillScreenView(0);
if (!_gameLoaded) {
_musicFadeFlag = 3;
musicspy();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
return;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if ((oldMusic & 0xFF) != p_global->_currMusicNum) { //TODO: r30 is uns char/bug???
oldMusic = p_global->_currMusicNum;
p_global->_currMusicNum = 0;
startmusique(oldMusic);
} else {
_musicFadeFlag = 3;
musicspy();
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
bool talk = p_global->_autoDialog; //TODO check me
initafterload();
fadeToBlack(3);
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
CLBlitter_FillView(_mainView, 0);
drawTopScreen();
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos = 0;
showObjects();
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
if (talk) {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 4;
p_global->_autoDialog = true;
parle_moi();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::initafterload() {
2016-12-04 14:26:44 -08:00
p_global->_characterImageBank = 0;
2016-12-11 13:44:58 -08:00
p_global->_lastPlaceNum = 0;
2016-12-15 22:47:29 -08:00
loadPlace(p_global->_areaPtr->_placeNum);
2016-12-04 14:26:44 -08:00
_gameIcons[18]._cursorId |= 0x8000;
2016-12-11 13:44:58 -08:00
if (p_global->_curAreaType == AreaType::atValley)
2016-12-04 14:26:44 -08:00
_gameIcons[18]._cursorId &= ~0x8000;
kPersoRoomBankTable[30] = 27;
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 352)
kPersoRoomBankTable[30] = 26;
_animateTalking = false;
2016-12-25 02:17:07 -08:00
_animationActive = false;
p_global->_var100 = 0;
2016-12-04 13:15:38 -08:00
p_global->_eventType = EventType::etEventC;
2016-12-11 13:44:58 -08:00
p_global->_valleyVidNum = 0;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawMenu;
2016-12-18 14:13:36 -08:00
_currentTime = _vm->_timerTicks / 100;
p_global->_gameTime = _currentTime;
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftTyrann)
2016-12-11 13:44:58 -08:00
setChrono(3000);
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = -1;
_adamMapMarkPos.y = -1;
}
void EdenGame::save() {
char name[260];
fademusica0(1);
desktopcolors();
FlushEvents(-1, 0);
//SaveDialog(byte_37150, byte_37196->ff_A);
//TODO
strcpy(name, "edsave1.000");
savegame(name);
CLMouse_Hide();
CLBlitter_FillScreenView(0xFFFFFFFF);
fadeToBlack(3);
CLBlitter_FillScreenView(0);
_musicFadeFlag = 3;
musicspy();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
}
void EdenGame::desktopcolors() {
fadeToBlack(3);
2016-09-26 07:57:27 +02:00
CLBlitter_FillScreenView(0xFFFFFFFF);
CLPalette_BeSystem();
CLMouse_Show();
}
void EdenGame::panelrestart() {
_gameLoaded = false;
2016-12-11 13:44:58 -08:00
byte curmus = p_global->_currMusicNum;
byte curlng = p_global->_prefLanguage;
loadrestart();
2016-12-11 13:44:58 -08:00
p_global->_prefLanguage = curlng;
if (!_gameLoaded) //TODO always?
return;
2016-12-04 14:26:44 -08:00
p_global->_characterImageBank = 0;
2016-12-11 13:44:58 -08:00
p_global->_lastPlaceNum = 0;
2016-12-15 22:47:29 -08:00
loadPlace(p_global->_areaPtr->_placeNum);
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
2016-12-04 14:26:44 -08:00
_gameIcons[18]._cursorId |= 0x8000;
2016-12-11 13:44:58 -08:00
if (p_global->_curAreaType == AreaType::atValley)
2016-12-04 14:26:44 -08:00
_gameIcons[18]._cursorId &= ~0x8000;
kPersoRoomBankTable[30] = 27;
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum >= 352)
kPersoRoomBankTable[30] = 26;
_animateTalking = false;
2016-12-25 02:17:07 -08:00
_animationActive = false;
p_global->_var100 = 0;
2016-12-04 13:15:38 -08:00
p_global->_eventType = 0;
2016-12-11 13:44:58 -08:00
p_global->_valleyVidNum = 0;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawMenu;
2016-12-11 13:44:58 -08:00
p_global->_inventoryScrollPos = 0;
2016-09-30 07:48:27 +02:00
_adamMapMarkPos.x = -1;
_adamMapMarkPos.y = -1;
2016-12-11 13:44:58 -08:00
if (curmus != p_global->_currMusicNum) {
curmus = p_global->_currMusicNum;
p_global->_currMusicNum = 0;
startmusique(curmus);
}
fadeToBlack(3);
CLBlitter_FillScreenView(0);
2016-12-18 14:13:36 -08:00
CLBlitter_FillView(_mainView, 0);
drawTopScreen();
showObjects();
2016-09-27 07:53:50 +02:00
saveFriezes();
2016-12-18 14:13:36 -08:00
_showBlackBars = true;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
}
void EdenGame::reallyquit() {
2016-12-18 14:13:36 -08:00
_quitFlag3 = true;
_quitFlag2 = true;
}
void EdenGame::confirmer(char mode, char yesId) {
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 119;
2016-12-04 14:26:44 -08:00
_gameIcons[119]._objectId = yesId;
confirmMode = mode;
2016-10-07 23:06:10 +02:00
useBank(65);
noclipax(12, 117, 74);
2016-12-18 13:09:56 -08:00
_cursorPosX = 156;
if (pomme_q)
2016-12-18 13:09:56 -08:00
_cursorPosX = 136;
_cursorPosY = 88;
}
void EdenGame::confirmyes() {
2016-12-19 22:32:40 -08:00
displayPanel();
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 85;
switch (confirmMode) {
case 1:
panelrestart();
break;
case 2:
reallyquit();
break;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::confirmno() {
2016-12-19 22:32:40 -08:00
displayPanel();
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 85;
pomme_q = false;
}
void EdenGame::restart() {
2016-12-19 22:32:40 -08:00
confirmer(1, _curSpot2->_objectId);
}
2016-12-19 22:32:40 -08:00
void EdenGame::edenQuit() {
confirmer(2, _curSpot2->_objectId);
}
2016-12-19 22:32:40 -08:00
// Original name: choixsubtitle
void EdenGame::choseSubtitleOption() {
byte lang = _curSpot2->_objectId & 0xF;
2016-12-11 13:44:58 -08:00
if (lang == p_global->_prefLanguage)
return;
if (lang > 5)
return;
2016-12-11 13:44:58 -08:00
p_global->_prefLanguage = lang;
langbuftopanel();
2016-12-19 22:32:40 -08:00
displayLanguage();
}
2016-12-19 22:32:40 -08:00
// Original name: reglervol
void EdenGame::changeVolume() {
byte *valptr = &p_global->_prefMusicVol[_curSpot2->_objectId & 7];
2016-12-18 13:09:56 -08:00
_cursorPosY = 104 - ((*valptr >> 2) & 0x3F); // TODO: check me
cur_slider_value_ptr = valptr;
p_global->_menuFlags |= MenuFlags::mfFlag1;
2016-12-19 22:32:40 -08:00
if (_curSpot2->_objectId & 8)
p_global->_menuFlags |= MenuFlags::mfFlag2;
2016-12-19 22:32:40 -08:00
_curSliderX = _curSpot2->sx;
2016-12-18 13:09:56 -08:00
cur_slider_y = _cursorPosY;
}
void EdenGame::changervol() {
2016-12-18 13:09:56 -08:00
if (_mouseHeld) {
2016-12-19 22:32:40 -08:00
restrictCursorArea(_curSliderX - 1, _curSliderX + 3, 40, 110);
2016-12-18 13:09:56 -08:00
int16 delta = cur_slider_y - _cursorPosY;
if (delta == 0)
return;
newvol(cur_slider_value_ptr, delta);
if (p_global->_menuFlags & MenuFlags::mfFlag2)
newvol(cur_slider_value_ptr + 1, delta);
cursbuftopanel();
2016-12-19 22:32:40 -08:00
displayCursors();
2016-12-18 13:09:56 -08:00
cur_slider_y = _cursorPosY;
} else
p_global->_menuFlags &= ~(MenuFlags::mfFlag1 | MenuFlags::mfFlag2);
}
2016-09-14 23:48:01 +02:00
void EdenGame::newvol(byte *volptr, int16 delta) {
int16 vol = *volptr / 4;
vol += delta;
if (vol < 0)
vol = 0;
if (vol > 63)
vol = 63;
*volptr = vol * 4;
2016-12-11 13:44:58 -08:00
_musicChannel->setVolume(p_global->_prefMusicVol[0], p_global->_prefMusicVol[1]);
}
void EdenGame::playtape() {
2016-12-11 13:44:58 -08:00
if (p_global->_menuItemIdHi & 8)
p_global->_tapePtr++;
for (;; p_global->_tapePtr++) {
if (p_global->_tapePtr == &tapes[MAX_TAPES]) {
p_global->_tapePtr--;
stoptape();
return;
2016-08-18 13:15:54 +02:00
}
2016-12-11 13:44:58 -08:00
if (p_global->_tapePtr->_textNum)
2016-08-18 13:15:54 +02:00
break;
}
p_global->_menuFlags |= MenuFlags::mfFlag8;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawMenu;
2016-12-11 13:44:58 -08:00
uint16 oldRoomNum = p_global->_roomNum;
uint16 oldParty = p_global->_party;
byte oldBack = p_global->_roomBackgroundBankNum;
2016-12-04 14:26:44 -08:00
perso_t *oldPerso = p_global->_characterPtr;
2016-12-11 13:44:58 -08:00
p_global->_party = p_global->_tapePtr->_party;
p_global->_roomNum = p_global->_tapePtr->_roomNum;
p_global->_roomBackgroundBankNum = p_global->_tapePtr->_backgroundBankNum;
p_global->_dialogPtr = p_global->_tapePtr->_dialog;
p_global->_characterPtr = p_global->_tapePtr->_perso;
endpersovox();
affcurstape();
2016-12-04 14:26:44 -08:00
if (p_global->_characterPtr != oldPerso
2016-12-19 22:32:40 -08:00
|| p_global->_roomNum != _lastTapeRoomNum) {
_lastTapeRoomNum = p_global->_roomNum;
2016-12-04 14:26:44 -08:00
p_global->_curCharacterAnimPtr = nullptr;
p_global->_varCA = 0;
2016-12-04 14:26:44 -08:00
p_global->_characterImageBank = -1;
anim_perfin();
load_perso_cour();
2016-08-18 13:15:54 +02:00
}
af_fondperso();
2016-12-11 13:44:58 -08:00
p_global->_textNum = p_global->_tapePtr->_textNum;
my_bulle();
2016-12-25 02:17:07 -08:00
getDataSync();
displayCharacterPanel();
persovox();
2016-12-11 13:44:58 -08:00
p_global->_roomBackgroundBankNum = oldBack;
p_global->_party = oldParty;
p_global->_roomNum = oldRoomNum;
}
void EdenGame::rewindtape() {
2016-12-11 13:44:58 -08:00
if (p_global->_tapePtr > tapes) {
p_global->_tapePtr--;
p_global->_menuFlags &= ~MenuFlags::mfFlag8;
affcurstape();
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
void EdenGame::depcurstape() {
2016-12-18 13:09:56 -08:00
if (_mouseHeld) {
2016-12-19 22:32:40 -08:00
restrictCursorArea(95, 217, 179, 183);
2016-12-18 13:09:56 -08:00
int idx = (_cursorPosX - 97);
2016-10-24 22:02:43 +02:00
if (idx < 0)
idx = 0;
idx /= 8;
2016-10-24 22:02:43 +02:00
tape_t *tape = tapes + idx;
if (tape >= tapes + 16)
tape = tapes + 16 - 1;
2016-12-11 13:44:58 -08:00
if (tape != p_global->_tapePtr) {
p_global->_tapePtr = tape;
affcurstape();
p_global->_menuFlags &= ~MenuFlags::mfFlag8;
}
} else
p_global->_menuFlags &= ~MenuFlags::mfFlag4;
}
2016-08-18 13:15:54 +02:00
void EdenGame::affcurstape() {
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawFlag8)
_noPalette = true;
2016-10-07 23:06:10 +02:00
useBank(65);
noclipax(2, 0, 176);
2016-12-11 13:44:58 -08:00
int x = (p_global->_tapePtr - tapes) * 8 + 97;
2016-12-04 14:26:44 -08:00
_gameIcons[112].sx = x - 3;
_gameIcons[112].ex = x + 3;
noclipax(5, x, 179);
_noPalette = false;
}
2016-08-18 13:15:54 +02:00
void EdenGame::forwardtape() {
2016-12-11 13:44:58 -08:00
if (p_global->_tapePtr < tapes + 16) {
p_global->_tapePtr++;
p_global->_menuFlags &= ~MenuFlags::mfFlag8;
affcurstape();
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::stoptape() {
2016-12-04 14:26:44 -08:00
if (!(p_global->_drawFlags & DrawFlags::drDrawFlag8))
2016-08-18 13:15:54 +02:00
return;
p_global->_menuFlags &= ~MenuFlags::mfFlag8;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags &= ~DrawFlags::drDrawFlag8;
p_global->_menuFlags |= MenuFlags::mfFlag10;
2016-12-04 13:15:38 -08:00
p_global->_iconsIndex = 85;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = nullptr;
2016-12-19 22:32:40 -08:00
_lastTapeRoomNum = 0;
endpersovox();
fin_perso();
2016-12-19 22:32:40 -08:00
displayPanel();
displayTopPanel();
2016-12-18 14:13:36 -08:00
_paletteUpdateRequired = true;
}
2016-08-18 13:15:54 +02:00
void EdenGame::cliccurstape() {
p_global->_menuFlags |= MenuFlags::mfFlag4;
}
void EdenGame::paneltobuf() {
setRS1(0, 16, 320 - 1, 169 - 1);
setRD1(320, 16, 640 - 1, 169 - 1);
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, _mainView, &rect_src, &rect_dst);
}
void EdenGame::cursbuftopanel() {
setRS1(434, 40, 525 - 1, 111 - 1);
setRD1(114, 40, 205 - 1, 111 - 1);
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, _mainView, &rect_src, &rect_dst);
}
void EdenGame::langbuftopanel() {
setRS1(328, 42, 407 - 1, 97 - 1);
setRD1(8, 42, 87 - 1, 97 - 1);
2016-12-18 14:13:36 -08:00
CLBlitter_CopyViewRect(_mainView, _mainView, &rect_src, &rect_dst);
}
2016-12-19 22:32:40 -08:00
// Original name: affpanel
void EdenGame::displayPanel() {
2016-10-07 23:06:10 +02:00
useBank(65);
noclipax(0, 0, 16);
paneltobuf();
2016-12-19 22:32:40 -08:00
displayLanguage();
displayCursors();
affcurstape();
}
2016-12-19 22:32:40 -08:00
// Original name: afflangue
void EdenGame::displayLanguage() {
2016-10-07 23:06:10 +02:00
useBank(65);
2016-12-11 13:44:58 -08:00
if (p_global->_prefLanguage < 0 //TODO: never happens
|| p_global->_prefLanguage > 5)
return;
2016-12-11 13:44:58 -08:00
noclipax(6, 8, p_global->_prefLanguage * 9 + 43); //TODO: * FONT_HEIGHT
noclipax(7, 77, p_global->_prefLanguage * 9 + 44);
}
2016-12-19 22:32:40 -08:00
// Original name: affcursvol
void EdenGame::displayVolCursor(int16 x, int16 vol1, int16 vol2) {
2016-09-14 23:48:01 +02:00
int16 slider = 3;
2016-12-19 22:32:40 -08:00
if (_lastMenuItemIdLo && (_lastMenuItemIdLo & 9) != 1) //TODO check me
slider = 4;
noclipax(slider, x, 104 - vol1);
slider = 3;
2016-12-19 22:32:40 -08:00
if ((_lastMenuItemIdLo & 9) != 0)
slider = 4;
noclipax(slider, x + 12, 104 - vol2);
}
2016-12-19 22:32:40 -08:00
// Original name: affcurseurs
void EdenGame::displayCursors() {
2016-10-07 23:06:10 +02:00
useBank(65);
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawFlag8)
return;
2016-12-19 22:32:40 -08:00
selectCursor(48);
displayVolCursor(114, p_global->_prefMusicVol[0] / 4, p_global->_prefMusicVol[1] / 4);
selectCursor(50);
displayVolCursor(147, p_global->_prefVoiceVol[0] / 4, p_global->_prefVoiceVol[1] / 4);
selectCursor(52);
displayVolCursor(179, p_global->_prefSoundVolume[0] / 4, p_global->_prefSoundVolume[1] / 4);
}
2016-12-19 22:32:40 -08:00
// Original name: curseurselect
void EdenGame::selectCursor(int itemId) {
_lastMenuItemIdLo = p_global->_menuItemIdLo;
if ((_lastMenuItemIdLo & ~9) != itemId)
_lastMenuItemIdLo = 0;
}
2016-12-19 22:32:40 -08:00
// Original name: afftoppano
void EdenGame::displayTopPanel() {
noclipax(1, 0, 0);
}
2016-12-19 22:32:40 -08:00
// Original name: affresult
void EdenGame::displayResult() {
2016-12-25 02:17:07 -08:00
restorePhylacteryBackground();
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = &kPersons[19];
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtInspect;
int16 num = (kPersons[PER_UNKN_156]._id << 3) | p_global->_dialogType;
2016-10-07 00:45:08 +02:00
if (dialoscansvmas((dial_t *)getElem(gameDialogs, num)))
2016-12-25 02:17:07 -08:00
displaySubtitles();
p_global->_varCA = 0;
2016-12-04 13:15:38 -08:00
p_global->_dialogType = DialogType::dtTalk;
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = nullptr;
}
2016-12-19 22:32:40 -08:00
// Original name: limitezonecurs
void EdenGame::restrictCursorArea(int16 xmin, int16 xmax, int16 ymin, int16 ymax) {
2016-12-18 13:09:56 -08:00
_cursorPosX = CLIP(_cursorPosX, xmin, xmax);
_cursorPosY = CLIP(_cursorPosY, ymin, ymax);
}
2016-12-19 22:32:40 -08:00
// Original name: PommeQ
void EdenGame::edenShudown() {
Icon *icon = &_gameIcons[85];
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfFrescoes) {
2016-12-18 13:09:56 -08:00
_torchCursor = false;
_cursorSaved = true;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfPerson)
close_perso();
2016-12-04 13:15:38 -08:00
p_global->_displayFlags = DisplayFlags::dfFlag1;
2016-09-26 23:44:42 +02:00
resetScroll();
p_global->_var100 = 0xFF;
2016-12-19 13:41:00 -08:00
updateRoom(p_global->_roomNum);
2016-08-18 13:15:54 +02:00
}
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfPerson)
close_perso();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfPanable)
2016-09-26 23:44:42 +02:00
resetScroll();
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags & DisplayFlags::dfMirror)
2016-09-26 23:44:42 +02:00
resetScroll();
2016-12-04 14:26:44 -08:00
if (p_global->_drawFlags & DrawFlags::drDrawFlag8)
stoptape();
if (_personTalking)
endpersovox();
p_global->_var103 = 0;
p_global->_var102 = 0;
2016-12-04 13:15:38 -08:00
putObject();
_currCursor = 53;
2016-12-04 13:15:38 -08:00
if (p_global->_displayFlags != DisplayFlags::dfFlag2)
gotopanel();
2016-12-19 22:32:40 -08:00
_curSpot2 = icon + 7; //TODO
edenQuit();
}
void EdenGame::habitants(perso_t *perso) {
2016-10-07 00:45:08 +02:00
char persType = perso->_flags & PersonFlags::pfTypeMask; //TODO rename
if (persType && persType != PersonFlags::pfType2) {
2016-12-11 13:44:58 -08:00
p_global->_roomCharacterPtr = perso;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterType = persType;
p_global->_roomCharacterFlags = perso->_flags;
p_global->_roomPersoItems = perso->_items;
p_global->_roomCharacterPowers = perso->_powers;
p_global->_partyOutside |= perso->_partyMask;
if (p_global->_roomCharacterType == PersonFlags::pftTriceraptor)
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnTriceraptorsIn);
2016-12-04 14:26:44 -08:00
else if (p_global->_roomCharacterType == PersonFlags::pftVelociraptor)
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnVelociraptorsIn);
2016-10-07 00:45:08 +02:00
} else if (!(perso->_flags & PersonFlags::pfInParty))
2016-12-04 14:26:44 -08:00
p_global->_partyOutside |= perso->_partyMask;
}
void EdenGame::suiveurs(perso_t *perso) {
2016-10-07 00:45:08 +02:00
char persType = perso->_flags & PersonFlags::pfTypeMask;
if (persType == 0 || persType == PersonFlags::pfType2) {
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pfInParty)
2016-12-11 13:44:58 -08:00
p_global->_party |= perso->_partyMask;
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::evenements(perso_t *perso) {
if (p_global->_var113)
return;
2016-10-24 22:02:43 +02:00
if (perso >= &kPersons[PER_UNKN_18C])
return;
2016-10-24 22:02:43 +02:00
if (!dialo_even(perso))
return;
2016-10-24 22:02:43 +02:00
p_global->_var113++;
2016-12-11 13:44:58 -08:00
p_global->_oldDisplayFlags = 1;
2016-12-04 14:26:44 -08:00
perso = p_global->_characterPtr;
init_perso_ptr(perso);
2016-10-07 00:45:08 +02:00
if (!(perso->_partyMask & PersonMask::pmLeader))
p_global->_var60 = 1;
2016-12-04 13:15:38 -08:00
p_global->_eventType = 0;
}
void EdenGame::followme(perso_t *perso) {
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pfTypeMask)
return;
2016-10-07 00:45:08 +02:00
if (perso->_flags & PersonFlags::pfInParty)
perso->_roomNum = destinationRoom;
}
void EdenGame::rangermammi(perso_t *perso, Room *room) {
Room *found_room = nullptr;
2016-10-07 00:45:08 +02:00
if (!(perso->_partyMask & PersonMask::pmLeader))
return;
2016-12-15 22:47:29 -08:00
for (; room->_id != 0xFF; room++) {
if (room->_flags & RoomFlags::rfHasCitadel) {
found_room = room;
break;
2016-08-18 13:15:54 +02:00
}
2016-12-15 22:47:29 -08:00
if (room->_party != 0xFFFF && (room->_party & PersonMask::pmLeader))
found_room = room; //TODO: no brk?
2016-08-18 13:15:54 +02:00
}
2016-09-26 07:57:27 +02:00
if (!found_room)
return;
2016-10-07 00:45:08 +02:00
perso->_roomNum &= ~0xFF;
2016-12-15 22:47:29 -08:00
perso->_roomNum |= found_room->_location;
2016-10-07 00:45:08 +02:00
perso->_flags &= ~PersonFlags::pfInParty;
2016-12-11 13:44:58 -08:00
p_global->_party &= ~perso->_partyMask;
}
2016-09-14 23:48:01 +02:00
void EdenGame::perso_ici(int16 action) {
perso_t *perso = &kPersons[PER_UNKN_156];
2016-08-18 13:15:54 +02:00
// room_t *room = p_global->last_area_ptr->room_ptr; //TODO: compiler opt bug? causes access to zero ptr??? last_area_ptr == 0
switch (action) {
case 0:
suiveurs(perso);
break;
case 1:
habitants(perso);
break;
case 3:
evenements(perso);
break;
case 4:
followme(perso);
break;
case 5:
2016-12-15 22:47:29 -08:00
rangermammi(perso, p_global->_lastAreaPtr->_citadelRoomPtr);
break;
}
perso = kPersons;
do {
2016-12-11 13:44:58 -08:00
if (perso->_roomNum == p_global->_roomNum && !(perso->_flags & PersonFlags::pf80)) {
switch (action) {
case 0:
suiveurs(perso);
break;
case 1:
habitants(perso);
break;
case 3:
evenements(perso);
break;
case 4:
followme(perso);
break;
case 5:
2016-12-15 22:47:29 -08:00
rangermammi(perso, p_global->_lastAreaPtr->_citadelRoomPtr);
break;
2016-08-18 13:15:54 +02:00
}
}
perso++;
2016-10-07 00:45:08 +02:00
} while (perso->_roomNum != 0xFFFF);
}
void EdenGame::setpersohere() {
2016-12-04 14:26:44 -08:00
debug("setpersohere, perso is %ld", p_global->_characterPtr - kPersons);
p_global->_partyOutside = 0;
2016-12-11 13:44:58 -08:00
p_global->_party = 0;
p_global->_roomCharacterPtr = 0;
2016-12-04 14:26:44 -08:00
p_global->_roomCharacterType = 0;
p_global->_roomCharacterFlags = 0;
perso_ici(1);
perso_ici(0);
2016-12-11 13:44:58 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftTyrann) removeInfo(p_global->_areaNum + ValleyNews::vnTyrannIn);
if (p_global->_roomCharacterType == PersonFlags::pftTriceraptor) removeInfo(p_global->_areaNum + ValleyNews::vnTriceraptorsIn);
2016-12-04 14:26:44 -08:00
if (p_global->_roomCharacterType == PersonFlags::pftVelociraptor) {
2016-12-11 13:44:58 -08:00
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannIn);
removeInfo(p_global->_areaNum + ValleyNews::vnTyrannLost);
removeInfo(p_global->_areaNum + ValleyNews::vnVelociraptorsLost);
2016-08-18 13:15:54 +02:00
}
}
2016-09-14 23:48:01 +02:00
void EdenGame::faire_suivre(int16 roomNum) {
destinationRoom = roomNum;
perso_ici(4);
}
2016-12-19 22:32:40 -08:00
// Original name: suis_moi5
void EdenGame::AddCharacterToParty() {
2016-12-04 14:26:44 -08:00
debug("adding person %ld to party", p_global->_characterPtr - kPersons);
p_global->_characterPtr->_flags |= PersonFlags::pfInParty;
2016-12-11 13:44:58 -08:00
p_global->_characterPtr->_roomNum = p_global->_roomNum;
p_global->_party |= p_global->_characterPtr->_partyMask;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawTopScreen;
}
2016-12-19 22:32:40 -08:00
// Original name: suis_moi
void EdenGame::AddToParty(int16 index) {
2016-12-04 14:26:44 -08:00
perso_t *old_perso = p_global->_characterPtr;
p_global->_characterPtr = &kPersons[index];
2016-12-19 22:32:40 -08:00
AddCharacterToParty();
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = old_perso;
}
2016-12-19 22:32:40 -08:00
// Original name: reste_ici5
void EdenGame::removeCharacterFromParty() {
2016-12-04 14:26:44 -08:00
debug("removing person %ld from party", p_global->_characterPtr - kPersons);
p_global->_characterPtr->_flags &= ~PersonFlags::pfInParty;
p_global->_partyOutside |= p_global->_characterPtr->_partyMask;
2016-12-11 13:44:58 -08:00
p_global->_party &= ~p_global->_characterPtr->_partyMask;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawTopScreen;
}
2016-12-19 22:32:40 -08:00
// Original name: reste_ici
void EdenGame::removeFromParty(int16 index) {
2016-12-04 14:26:44 -08:00
perso_t *old_perso = p_global->_characterPtr;
p_global->_characterPtr = &kPersons[index];
2016-12-19 22:32:40 -08:00
removeCharacterFromParty();
2016-12-04 14:26:44 -08:00
p_global->_characterPtr = old_perso;
}
// Original name: eloipart
void EdenGame::handleEloiDeparture() {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MESSAGER);
2016-12-04 14:26:44 -08:00
p_global->_gameFlags &= ~GameFlags::gfFlag4000;
2016-10-07 00:45:08 +02:00
kPersons[PER_MESSAGER]._roomNum = 0;
2016-12-04 14:26:44 -08:00
p_global->_partyOutside &= ~kPersons[PER_MESSAGER]._partyMask;
2016-12-11 13:44:58 -08:00
if (p_global->_roomNum == 2817)
setChrono(3000);
p_global->_eloiDepartureDay = p_global->_gameDays;
p_global->_eloiHaveNews = 0;
unlockInfo();
}
2016-12-19 22:32:40 -08:00
// Original name: eloirevientq
bool EdenGame::checkEloiReturn() {
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum < 304)
2016-10-07 23:06:10 +02:00
return true;
2016-12-04 14:26:44 -08:00
if ((p_global->_phaseNum <= 353) || (p_global->_phaseNum == 370) || (p_global->_phaseNum == 384))
2016-10-07 23:06:10 +02:00
return false;
2016-12-04 14:26:44 -08:00
if (p_global->_areaNum != Areas::arShandovra)
2016-10-07 23:06:10 +02:00
return true;
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum < 480)
2016-10-07 23:06:10 +02:00
return false;
return true;
}
2016-12-19 22:32:40 -08:00
// Original name: eloirevient
void EdenGame::handleEloiReturn() {
2016-12-15 22:47:29 -08:00
if (p_global->_areaPtr->_type == AreaType::atValley && !kPersons[PER_MESSAGER]._roomNum)
2016-12-11 13:44:58 -08:00
kPersons[PER_MESSAGER]._roomNum = (p_global->_roomNum & 0xFF00) + 1;
}
2016-08-18 13:15:54 +02:00
//// phase.c
2016-12-19 22:32:40 -08:00
void EdenGame::incPhase() {
static phase_t phases[] = {
{ 65, &EdenGame::dialautoon },
{ 113, &EdenGame::phase113 },
{ 129, &EdenGame::dialautoon },
{ 130, &EdenGame::phase130 },
{ 161, &EdenGame::phase161 },
{ 211, &EdenGame::dialautoon },
{ 226, &EdenGame::phase226 },
{ 257, &EdenGame::phase257 },
{ 353, &EdenGame::phase353 },
{ 369, &EdenGame::phase369 },
{ 371, &EdenGame::phase371 },
{ 385, &EdenGame::phase385 },
{ 386, &EdenGame::dialonfollow },
{ 418, &EdenGame::phase418 },
{ 433, &EdenGame::phase433 },
{ 434, &EdenGame::phase434 },
{ 449, &EdenGame::dialautoon },
{ 497, &EdenGame::dialautoon },
{ 513, &EdenGame::phase513 },
{ 514, &EdenGame::phase514 },
{ 529, &EdenGame::phase529 },
{ 545, &EdenGame::phase545 },
{ 561, &EdenGame::phase561 },
{ -1, nullptr }
};
2016-08-18 13:15:54 +02:00
2016-12-04 14:26:44 -08:00
p_global->_phaseNum++;
2016-12-11 13:44:58 -08:00
debug("!!! next phase - %4X , room %4X", p_global->_phaseNum, p_global->_roomNum);
p_global->_phaseActionsCount = 0;
for (phase_t *phase = phases; phase->_id != -1; phase++) {
2016-12-04 14:26:44 -08:00
if (p_global->_phaseNum == phase->_id) {
(this->*phase->disp)();
break;
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::phase113() {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_DINA);
2016-10-07 00:45:08 +02:00
kPersons[PER_DINA]._roomNum = 274;
}
void EdenGame::phase130() {
dialautoon();
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MONK);
}
void EdenGame::phase161() {
Area *area = p_global->_areaPtr;
2016-12-19 22:32:40 -08:00
AddToParty(PER_MAMMI);
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI]._flags |= PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
}
void EdenGame::phase226() {
2016-12-11 22:52:10 -08:00
newObject(16, 3);
newObject(16, 4);
newObject(16, 5);
}
void EdenGame::phase257() {
2016-12-04 14:26:44 -08:00
_gameIcons[127]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 58;
dialautooff();
}
void EdenGame::phase353() {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_DINA);
2016-10-07 00:45:08 +02:00
kPersons[PER_DINA]._roomNum = 0;
kTabletView[1] = 88;
}
void EdenGame::phase369() {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MESSAGER);
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 2;
2016-12-18 14:13:36 -08:00
_gameRooms[334]._exits[0] = 134;
_gameRooms[335]._exits[0] = 134;
}
void EdenGame::phase371() {
2016-12-19 22:32:40 -08:00
handleEloiReturn();
2016-12-04 14:26:44 -08:00
_gameIcons[128]._cursorId &= ~0x8000;
_gameIcons[129]._cursorId &= ~0x8000;
_gameIcons[127]._cursorId |= 0x8000;
p_global->_characterBackgroundBankIdx = 59;
2016-12-18 14:13:36 -08:00
_gameRooms[334]._exits[0] = 0xFF;
_gameRooms[335]._exits[0] = 0xFF;
2016-12-04 14:26:44 -08:00
_gameIcons[123]._objectId = 9;
_gameIcons[124]._objectId = 26;
_gameIcons[125]._objectId = 42;
_gameIcons[126]._objectId = 56;
}
void EdenGame::phase385() {
dialautooff();
2016-12-19 22:32:40 -08:00
handleEloiReturn();
2016-12-11 13:44:58 -08:00
p_global->_nextInfoIdx = 0;
p_global->_lastInfoIdx = 0;
updateInfoList();
2016-12-04 13:15:38 -08:00
p_global->_lastInfo = 0;
}
void EdenGame::phase418() {
2016-09-26 23:44:42 +02:00
loseObject(Objects::obHorn);
dialautoon();
2016-12-19 22:32:40 -08:00
AddToParty(PER_BOURREAU);
}
void EdenGame::phase433() {
dialautoon();
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_4]._flags &= ~PersonFlags::pf80;
kPersons[PER_BOURREAU]._flags &= ~PersonFlags::pf80;
setpersohere();
2016-12-04 14:26:44 -08:00
p_global->_chronoFlag = 0;
2016-12-11 13:44:58 -08:00
p_global->_chrono = 0;
}
void EdenGame::phase434() {
2016-12-11 13:44:58 -08:00
p_global->_roomNum = 275;
2016-12-18 14:13:36 -08:00
_gameRooms[16]._bank = 44;
_gameRooms[18]._bank = 44;
2016-12-04 14:26:44 -08:00
_gameIcons[132]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 61;
2016-12-18 14:13:36 -08:00
_gameRooms[118]._exits[2] = 0xFF;
abortdial();
2016-12-18 14:13:36 -08:00
_gameRooms[7]._bank = 322;
2016-12-19 22:32:40 -08:00
removeFromParty(PER_EVE);
removeFromParty(PER_MONK);
removeFromParty(PER_MESSAGER);
removeFromParty(PER_GARDES);
removeFromParty(PER_BOURREAU);
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawTopScreen;
}
void EdenGame::phase513() {
2016-12-11 13:44:58 -08:00
p_global->_lastDialogPtr = nullptr;
parlemoiNormalFlag = false;
dialautoon();
}
void EdenGame::phase514() {
2016-12-18 14:13:36 -08:00
_gameRooms[123]._exits[2] = 1;
}
void EdenGame::phase529() {
2016-12-04 14:26:44 -08:00
_gameIcons[133]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 63;
}
void EdenGame::phase545() {
}
void EdenGame::phase561() {
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 10;
}
void EdenGame::bigphase1() {
static void (EdenGame::*bigphases[])() = {
&EdenGame::phase16,
&EdenGame::phase32,
&EdenGame::phase48,
&EdenGame::phase64,
&EdenGame::phase80,
&EdenGame::phase96,
&EdenGame::phase112,
&EdenGame::phase128,
&EdenGame::phase144,
&EdenGame::phase160,
&EdenGame::phase176,
&EdenGame::phase192,
&EdenGame::phase208,
&EdenGame::phase224,
&EdenGame::phase240,
&EdenGame::phase256,
&EdenGame::phase272,
&EdenGame::phase288,
&EdenGame::phase304,
&EdenGame::phase320,
&EdenGame::phase336,
&EdenGame::phase352,
&EdenGame::phase368,
&EdenGame::phase384,
&EdenGame::phase400,
&EdenGame::phase416,
&EdenGame::phase432,
&EdenGame::phase448,
&EdenGame::phase464,
&EdenGame::phase480,
&EdenGame::phase496,
&EdenGame::phase512,
&EdenGame::phase528,
&EdenGame::phase544,
&EdenGame::phase560
};
2016-12-04 14:26:44 -08:00
int16 phase = (p_global->_phaseNum & ~3) + 0x10; //TODO: check me
debug("!!! big phase - %4X", phase);
p_global->_phaseActionsCount = 0;
2016-12-04 14:26:44 -08:00
p_global->_phaseNum = phase;
if (phase > 560)
return;
phase >>= 4;
(this->*bigphases[phase - 1])();
}
void EdenGame::bigphase() {
2016-10-24 22:02:43 +02:00
if (!(p_global->_dialogPtr->_flags & DialogFlags::dfSpoken))
bigphase1();
}
void EdenGame::phase16() {
dialautoon();
}
void EdenGame::phase32() {
word_31E7A &= ~0x8000;
}
void EdenGame::phase48() {
2016-12-18 14:13:36 -08:00
_gameRooms[8]._exits[1] = 22;
dialautoon();
}
void EdenGame::phase64() {
2016-12-19 22:32:40 -08:00
AddToParty(PER_DINA);
2016-10-07 00:45:08 +02:00
kPersons[PER_MESSAGER]._roomNum = 259;
}
void EdenGame::phase80() {
2016-10-07 00:45:08 +02:00
kPersons[PER_THOO]._roomNum = 0;
}
void EdenGame::phase96() {
}
void EdenGame::phase112() {
2016-12-04 14:26:44 -08:00
giveObject();
}
void EdenGame::phase128() {
2016-12-19 22:32:40 -08:00
AddToParty(PER_DINA);
2016-12-04 14:26:44 -08:00
giveObject();
}
void EdenGame::phase144() {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MESSAGER);
2016-12-18 14:13:36 -08:00
_gameRooms[113]._video = 0;
_gameRooms[113]._bank = 317;
}
void EdenGame::phase160() {
}
void EdenGame::phase176() {
dialonfollow();
}
void EdenGame::phase192() {
Area *area = p_global->_areaPtr;
2016-12-19 22:32:40 -08:00
AddToParty(PER_MAMMI_1);
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_1]._flags |= PersonFlags::pf10;
dialautoon();
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
}
void EdenGame::phase208() {
2016-12-19 22:32:40 -08:00
handleEloiReturn();
}
void EdenGame::phase224() {
2016-12-04 14:26:44 -08:00
_gameIcons[126]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 57;
dialautooff();
}
void EdenGame::phase240() {
Area *area = p_global->_areaPtr;
2016-12-19 22:32:40 -08:00
AddToParty(PER_MAMMI_2);
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_2]._flags |= PersonFlags::pf10;
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
}
void EdenGame::phase256() {
dialautoon();
}
void EdenGame::phase272() {
dialautoon();
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews = 0;
}
void EdenGame::phase288() {
2016-12-04 13:15:38 -08:00
setChoiceYes();
2016-10-07 00:45:08 +02:00
kPersons[PER_MANGO]._roomNum = 0;
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MANGO);
AddToParty(PER_MESSAGER);
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 8;
}
void EdenGame::phase304() {
Area *area = p_global->_areaPtr;
2016-12-19 22:32:40 -08:00
AddToParty(PER_EVE);
AddToParty(PER_MAMMI_5);
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_5]._flags |= PersonFlags::pf10;
dialautoon();
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
}
void EdenGame::phase320() {
dialonfollow();
}
void EdenGame::phase336() {
2016-12-18 14:13:36 -08:00
_gameRooms[288]._exits[0] = 135;
_gameRooms[289]._exits[0] = 135;
2016-12-04 13:15:38 -08:00
loseObject(p_global->_curObjectId);
dialautoon();
}
void EdenGame::phase352() {
kPersoRoomBankTable[30] = 26;
2016-10-07 00:45:08 +02:00
kPersons[PER_EVE]._spriteBank = 9;
kPersons[PER_EVE]._targetLoc = 8;
2016-10-07 23:06:10 +02:00
followerList[13]._spriteNum = 2;
dialautoon();
2016-12-18 14:13:36 -08:00
_gameRooms[288]._exits[0] = 0xFF;
_gameRooms[289]._exits[0] = 0xFF;
_gameRooms[288]._flags &= ~RoomFlags::rf02;
_gameRooms[289]._flags &= ~RoomFlags::rf02;
}
void EdenGame::phase368() {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_EVE);
dialautoon();
2016-10-07 00:45:08 +02:00
kPersons[PER_MESSAGER]._roomNum = 1811;
kPersons[PER_DINA]._roomNum = 1607;
}
void EdenGame::phase384() {
Area *area = p_global->_areaPtr;
2016-12-19 22:32:40 -08:00
AddToParty(PER_EVE);
removeFromParty(PER_DINA);
dialautoon();
2016-12-04 14:26:44 -08:00
area->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
handleEloiDeparture();
}
void EdenGame::phase400() {
dialonfollow();
2016-10-07 00:45:08 +02:00
kPersons[PER_ROI]._roomNum = 0;
kPersons[PER_MONK]._roomNum = 259;
2016-12-11 13:44:58 -08:00
p_global->_eloiHaveNews = 0;
kObjectLocations[20] = 259;
}
void EdenGame::phase416() {
2016-12-19 22:32:40 -08:00
AddToParty(PER_MONK);
2016-12-04 14:26:44 -08:00
_gameIcons[130]._cursorId &= ~0x8000;
p_global->_characterBackgroundBankIdx = 60;
2016-12-18 14:13:36 -08:00
_gameRooms[0]._exits[0] = 138;
}
void EdenGame::phase432() {
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 3;
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_4]._flags |= PersonFlags::pf80;
kPersons[PER_BOURREAU]._flags |= PersonFlags::pf80;
kPersons[PER_MESSAGER]._roomNum = 257;
2016-12-18 14:13:36 -08:00
_gameRooms[0]._exits[0] = 0xFF;
2016-12-04 14:26:44 -08:00
p_global->_drawFlags |= DrawFlags::drDrawTopScreen;
}
void EdenGame::phase448() {
dialautoon();
handleEloiDeparture();
}
void EdenGame::phase464() {
2016-12-04 14:26:44 -08:00
p_global->_areaPtr->_flags |= AreaFlags::afFlag1;
p_global->_curAreaFlags |= AreaFlags::afFlag1;
2016-10-07 00:45:08 +02:00
kPersons[PER_MAMMI_6]._flags |= PersonFlags::pf10;
2016-12-19 22:32:40 -08:00
AddToParty(PER_AZIA);
2016-12-18 13:09:56 -08:00
p_global->_citadelAreaNum = p_global->_areaNum;
naitredino(8);
}
void EdenGame::phase480() {
2016-12-04 14:26:44 -08:00
giveObject();
newValley();
2016-12-19 22:32:40 -08:00
handleEloiReturn();
kTabletView[1] = 94;
}
void EdenGame::phase496() {
dialautoon();
2016-12-11 13:44:58 -08:00
p_global->_lastDialogPtr = nullptr;
parlemoiNormalFlag = false;
}
void EdenGame::phase512() {
2016-12-19 22:32:40 -08:00
removeFromParty(PER_MONK);
removeFromParty(PER_EVE);
removeFromParty(PER_AZIA);
removeFromParty(PER_GARDES);
}
void EdenGame::phase528() {
2016-12-11 13:44:58 -08:00
p_global->_narratorSequence = 11;
2016-12-19 22:32:40 -08:00
AddToParty(PER_MONK);
AddToParty(PER_MESSAGER);
AddToParty(PER_EVE);
AddToParty(PER_AZIA);
AddToParty(PER_GARDES);
}
void EdenGame::phase544() {
handleEloiDeparture();
dialautoon();
2016-12-19 22:32:40 -08:00
removeFromParty(PER_AZIA);
removeFromParty(PER_GARDES);
}
void EdenGame::phase560() {
2016-10-07 00:45:08 +02:00
kPersons[PER_MESSAGER]._roomNum = 3073;
2016-12-18 14:13:36 -08:00
_gameRooms[127]._exits[1] = 0;
}
2016-08-18 13:15:54 +02:00
//// saveload.c
void EdenGame::savegame(char *name) {
2016-08-18 13:15:54 +02:00
// filespec_t fs;
2016-12-05 22:44:24 -08:00
// Common::File handle;
2016-10-08 23:31:21 +02:00
int32 size;
2016-08-18 13:15:54 +02:00
// CLFile_MakeStruct(0, 0, name, &fs);
// CLFile_Create(&fs);
// CLFile_SetFinderInfos(&fs, 'EDNS', 'LEDN');
// CLFile_Open(&fs, 3, handle);
Common::OutSaveFile *handle = g_system->getSavefileManager()->openForSaving(name);
if (!handle)
return;
2016-08-18 13:15:54 +02:00
#define CLFile_Write(h, ptr, size) \
2016-10-08 23:31:21 +02:00
debug("writing 0x%X bytes", *size); \
h->write(ptr, *size);
vavaoffsetout();
size = (char *)(&p_global->_saveEnd) - (char *)(p_global);
CLFile_Write(handle, p_global, &size);
2016-12-04 14:26:44 -08:00
size = (char *)(&_gameIcons[134]) - (char *)(&_gameIcons[123]);
CLFile_Write(handle, &_gameIcons[123], &size);
lieuoffsetout();
size = (char *)(&kAreasTable[12]) - (char *)(&kAreasTable[0]);
CLFile_Write(handle, &kAreasTable[0], &size);
2016-12-18 14:13:36 -08:00
size = (char *)(&_gameRooms[423]) - (char *)(&_gameRooms[0]);
CLFile_Write(handle, &_gameRooms[0], &size);
2016-12-04 14:26:44 -08:00
size = (char *)(&_objects[42]) - (char *)(&_objects[0]);
CLFile_Write(handle, &_objects[0], &size);
size = (char *)(&kObjectLocations[45]) - (char *)(&kObjectLocations[0]);
CLFile_Write(handle, &kObjectLocations[0], &size);
2016-10-07 23:06:10 +02:00
size = (char *)(&followerList[14]) - (char *)(&followerList[13]);
CLFile_Write(handle, &followerList[13], &size);
size = (char *)(&kPersons[PER_UNKN_3DE]) - (char *)(&kPersons[PER_ROI]);
CLFile_Write(handle, &kPersons[PER_ROI], &size);
bandeoffsetout();
size = (char *)(&tapes[16]) - (char *)(&tapes[0]);
CLFile_Write(handle, &tapes[0], &size);
size = (char *)(&kTabletView[6]) - (char *)(&kTabletView[0]);
CLFile_Write(handle, &kTabletView[0], &size);
size = (char *)(&gameDialogs[10240]) - (char *)(&gameDialogs[0]); //TODO: const size 10240
CLFile_Write(handle, &gameDialogs[0], &size);
delete handle;
2016-08-18 13:15:54 +02:00
#undef CLFile_Write
// CLFile_Close(handle);
vavaoffsetin();
lieuoffsetin();
bandeoffsetin();
debug("* Game saved to %s", name);
}
void EdenGame::loadrestart() {
assert(0); //TODO: this won't work atm - all snapshots are BE
2016-10-08 23:31:21 +02:00
int32 offs = 0;
int32 size;
size = (char *)(&p_global->_saveEnd) - (char *)(p_global);
loadpartoffile(2495, p_global, offs, size);
offs += size;
vavaoffsetin();
2016-12-04 14:26:44 -08:00
size = (char *)(&_gameIcons[134]) - (char *)(&_gameIcons[123]);
loadpartoffile(2495, &_gameIcons[123], offs, size);
offs += size;
size = (char *)(&kAreasTable[12]) - (char *)(&kAreasTable[0]);
loadpartoffile(2495, &kAreasTable[0], offs, size);
offs += size;
lieuoffsetin();
2016-12-18 14:13:36 -08:00
size = (char *)(&_gameRooms[423]) - (char *)(&_gameRooms[0]);
loadpartoffile(2495, &_gameRooms[0], offs, size);
offs += size;
2016-12-04 14:26:44 -08:00
size = (char *)(&_objects[42]) - (char *)(&_objects[0]);
loadpartoffile(2495, &_objects[0], offs, size);
offs += size;
size = (char *)(&kObjectLocations[45]) - (char *)(&kObjectLocations[0]);
loadpartoffile(2495, &kObjectLocations[0], offs, size);
offs += size;
2016-10-07 23:06:10 +02:00
size = (char *)(&followerList[14]) - (char *)(&followerList[13]);
loadpartoffile(2495, &followerList[13], offs, size);
offs += size;
size = (char *)(&kPersons[PER_UNKN_3DE]) - (char *)(&kPersons[PER_ROI]);
loadpartoffile(2495, &kPersons[PER_ROI], offs, size);
offs += size;
size = (char *)(&tapes[16]) - (char *)(&tapes[0]);
loadpartoffile(2495, &tapes[0], offs, size);
offs += size;
bandeoffsetin();
size = (char *)(&kTabletView[6]) - (char *)(&kTabletView[0]);
loadpartoffile(2495, &kTabletView[0], offs, size);
offs += size;
size = (char *)(&gameDialogs[10240]) - (char *)(&gameDialogs[0]); //TODO: const size 10240
loadpartoffile(2495, &gameDialogs[0], offs, size);
_gameLoaded = true;
}
void EdenGame::loadgame(char *name) {
2016-08-18 13:15:54 +02:00
// filespec_t fs;
2016-12-05 22:44:24 -08:00
// Common::File handle;
2016-08-18 13:15:54 +02:00
// CLFile_MakeStruct(0, 0, name, &fs);
// CLFile_Open(&fs, 3, handle);
Common::InSaveFile *handle = g_system->getSavefileManager()->openForLoading(name);
if (!handle)
return;
2016-08-18 13:15:54 +02:00
#define CLFile_Read(h, ptr, size) \
h->read(ptr, *size);
int32 size = (char *)(&p_global->_saveEnd) - (char *)(p_global);
CLFile_Read(handle, p_global, &size);
vavaoffsetin();
2016-12-04 14:26:44 -08:00
size = (char *)(&_gameIcons[134]) - (char *)(&_gameIcons[123]);
CLFile_Read(handle, &_gameIcons[123], &size);
size = (char *)(&kAreasTable[12]) - (char *)(&kAreasTable[0]);
CLFile_Read(handle, &kAreasTable[0], &size);
lieuoffsetin();
2016-12-18 14:13:36 -08:00
size = (char *)(&_gameRooms[423]) - (char *)(&_gameRooms[0]);
CLFile_Read(handle, &_gameRooms[0], &size);
2016-12-04 14:26:44 -08:00
size = (char *)(&_objects[42]) - (char *)(&_objects[0]);
CLFile_Read(handle, &_objects[0], &size);
size = (char *)(&kObjectLocations[45]) - (char *)(&kObjectLocations[0]);
CLFile_Read(handle, &kObjectLocations[0], &size);
2016-10-07 23:06:10 +02:00
size = (char *)(&followerList[14]) - (char *)(&followerList[13]);
CLFile_Read(handle, &followerList[13], &size);
size = (char *)(&kPersons[55]) - (char *)(&kPersons[0]);
CLFile_Read(handle, &kPersons[0], &size);
size = (char *)(&tapes[16]) - (char *)(&tapes[0]);
CLFile_Read(handle, &tapes[0], &size);
bandeoffsetin();
size = (char *)(&kTabletView[6]) - (char *)(&kTabletView[0]);
CLFile_Read(handle, &kTabletView[0], &size);
size = (char *)(&gameDialogs[10240]) - (char *)(&gameDialogs[0]); //TODO: const size 10240
CLFile_Read(handle, &gameDialogs[0], &size);
delete handle;
2016-08-18 13:15:54 +02:00
#undef CLFile_Read
// CLFile_Close(handle);
_gameLoaded = true;
debug("* Game loaded from %s", name);
}
2016-08-18 13:15:54 +02:00
#define NULLPTR (void*)0xFFFFFF
#define OFSOUT(val, base, typ) if (val) (val) = (typ*)((char*)(val) - (size_t)(base)); else (val) = (typ*)NULLPTR;
#define OFSIN(val, base, typ) if ((void*)(val) != NULLPTR) (val) = (typ*)((char*)(val) + (size_t)(base)); else (val) = 0;
void EdenGame::vavaoffsetout() {
2016-10-24 22:02:43 +02:00
OFSOUT(p_global->_dialogPtr, gameDialogs, dial_t);
OFSOUT(p_global->_nextDialogPtr, gameDialogs, dial_t);
2016-12-11 13:44:58 -08:00
OFSOUT(p_global->_narratorDialogPtr, gameDialogs, dial_t);
OFSOUT(p_global->_lastDialogPtr, gameDialogs, dial_t);
OFSOUT(p_global->_tapePtr, tapes, tape_t);
OFSOUT(p_global->_nextRoomIcon, _gameIcons, Icon);
2016-12-18 14:13:36 -08:00
OFSOUT(p_global->_roomPtr, _gameRooms, Room);
OFSOUT(p_global->_citaAreaFirstRoom, _gameRooms, Room);
OFSOUT(p_global->_areaPtr, kAreasTable, Area);
OFSOUT(p_global->_lastAreaPtr, kAreasTable, Area);
OFSOUT(p_global->_curAreaPtr, kAreasTable, Area);
2016-12-04 14:26:44 -08:00
OFSOUT(p_global->_characterPtr, kPersons, perso_t);
2016-12-11 13:44:58 -08:00
OFSOUT(p_global->_roomCharacterPtr, kPersons, perso_t);
}
void EdenGame::vavaoffsetin() {
2016-10-24 22:02:43 +02:00
OFSIN(p_global->_dialogPtr, gameDialogs, dial_t);
OFSIN(p_global->_nextDialogPtr, gameDialogs, dial_t);
2016-12-11 13:44:58 -08:00
OFSIN(p_global->_narratorDialogPtr, gameDialogs, dial_t);
OFSIN(p_global->_lastDialogPtr, gameDialogs, dial_t);
OFSIN(p_global->_tapePtr, tapes, tape_t);
OFSIN(p_global->_nextRoomIcon, _gameIcons, Icon);
2016-12-18 14:13:36 -08:00
OFSIN(p_global->_roomPtr, _gameRooms, Room);
OFSIN(p_global->_citaAreaFirstRoom, _gameRooms, Room);
OFSIN(p_global->_areaPtr, kAreasTable, Area);
OFSIN(p_global->_lastAreaPtr, kAreasTable, Area);
OFSIN(p_global->_curAreaPtr, kAreasTable, Area);
2016-12-04 14:26:44 -08:00
OFSIN(p_global->_characterPtr, kPersons, perso_t);
2016-12-11 13:44:58 -08:00
OFSIN(p_global->_roomCharacterPtr, kPersons, perso_t);
}
void EdenGame::lieuoffsetout() {
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 12; i++)
2016-12-18 14:13:36 -08:00
OFSOUT(kAreasTable[i]._citadelRoomPtr, _gameRooms, Room);
}
void EdenGame::lieuoffsetin() {
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 12; i++)
2016-12-18 14:13:36 -08:00
OFSIN(kAreasTable[i]._citadelRoomPtr, _gameRooms, Room);
}
void EdenGame::bandeoffsetout() {
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 16; i++) {
2016-10-07 23:06:10 +02:00
OFSOUT(tapes[i]._perso, kPersons, perso_t);
OFSOUT(tapes[i]._dialog, gameDialogs, dial_t);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::bandeoffsetin() {
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 16; i++) {
2016-10-07 23:06:10 +02:00
OFSIN(tapes[i]._perso, kPersons, perso_t);
OFSIN(tapes[i]._dialog, gameDialogs, dial_t);
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
//// cond.c
2016-09-14 23:48:01 +02:00
byte *code_ptr;
2016-08-18 13:15:54 +02:00
2016-09-14 23:48:01 +02:00
char EdenGame::testcondition(int16 index) {
char end = 0;
2016-09-14 23:48:01 +02:00
byte op;
uint16 value, value2;
uint16 stack[32], *sp = stack, *sp2;
assert(index > 0);
2016-10-07 00:45:08 +02:00
code_ptr = (byte *)getElem(gameConditions, (index - 1));
do {
value = cher_valeur();
for (;;) {
op = *code_ptr++;
if (op == 0xFF) {
end = 1;
break;
2016-08-18 13:15:54 +02:00
}
if ((op & 0x80) == 0) {
value2 = cher_valeur();
2016-08-18 13:15:54 +02:00
value = operation(op, value, value2);
} else {
assert(sp < stack + 32);
*sp++ = value;
*sp++ = op;
break;
}
2016-08-18 13:15:54 +02:00
}
} while (!end);
if (sp != stack) {
*sp++ = value;
sp2 = stack;
value = *sp2++;
do {
op = *sp2++;
value2 = *sp2++;
value = operation(op, value, value2);
} while (sp2 != sp);
}
2016-08-18 13:15:54 +02:00
// if (value)
debug("cond %d(-1) returns %s", index, value ? "TRUE" : "false");
2016-08-18 13:15:54 +02:00
// if (index == 402) debug("(glob_61.b == %X) & (glob_12.w == %X) & (glob_4C.b == %X) & (glob_4E.b == %X)", p_global->eventType, p_global->phaseNum, p_global->worldTyrannSighted, p_global->ff_4E);
return value != 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_add(uint16 v1, uint16 v2) {
return v1 + v2;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_sub(uint16 v1, uint16 v2) {
return v1 - v2;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_and(uint16 v1, uint16 v2) {
return v1 & v2;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_or(uint16 v1, uint16 v2) {
return v1 | v2;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_egal(uint16 v1, uint16 v2) {
return v1 == v2 ? -1 : 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_petit(uint16 v1, uint16 v2) {
return v1 < v2 ? -1 : 0; //TODO: all comparisons are unsigned!
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_grand(uint16 v1, uint16 v2) {
return v1 > v2 ? -1 : 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_diff(uint16 v1, uint16 v2) {
return v1 != v2 ? -1 : 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_petega(uint16 v1, uint16 v2) {
return v1 <= v2 ? -1 : 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_graega(uint16 v1, uint16 v2) {
return v1 >= v2 ? -1 : 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::opera_faux(uint16 v1, uint16 v2) {
return 0;
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::operation(byte op, uint16 v1, uint16 v2) {
static uint16(EdenGame::*operations[16])(uint16, uint16) = {
&EdenGame::opera_egal,
&EdenGame::opera_petit,
&EdenGame::opera_grand,
&EdenGame::opera_diff,
&EdenGame::opera_petega,
&EdenGame::opera_graega,
&EdenGame::opera_add,
&EdenGame::opera_sub,
&EdenGame::opera_and,
&EdenGame::opera_or,
&EdenGame::opera_faux,
&EdenGame::opera_faux,
&EdenGame::opera_faux,
&EdenGame::opera_faux,
&EdenGame::opera_faux,
&EdenGame::opera_faux
};
return (this->*operations[(op & 0x1F) >> 1])(v1, v2);
}
2016-09-14 23:48:01 +02:00
uint16 EdenGame::cher_valeur() {
uint16 val;
byte typ = *code_ptr++;
if (typ < 0x80) {
2016-09-14 23:48:01 +02:00
byte ofs = *code_ptr++;
if (typ == 1)
2016-09-14 23:48:01 +02:00
val = *(byte *)(ofs + (byte *)p_global);
else
2016-09-14 23:48:01 +02:00
val = *(uint16 *)(ofs + (byte *)p_global);
} else if (typ == 0x80)
val = *code_ptr++;
else {
2016-12-04 14:54:58 -08:00
val = READ_LE_UINT16(code_ptr);
code_ptr += 2;
}
return val;
}
void EdenGame::ret() {
}
2016-08-18 13:15:54 +02:00
//// cube.c
void EdenGame::make_tabcos() {
2016-10-08 21:26:22 +02:00
for (int i = 0; i < 361; i++) {
tabcos[i * 2] = (int)(cos(3.1416 * i / 180.0) * 255.0);
tabcos[i * 2 + 1] = (int)(sin(3.1416 * i / 180.0) * 255.0);
2016-08-18 13:15:54 +02:00
}
}
void EdenGame::make_matrice_fix() {
int16 r30 = word_3244C;
int16 r28 = word_3244A;
int16 r29 = word_32448;
dword_32424 = (tabcos[r29 * 2] * tabcos[r28 * 2]) >> 8;
dword_32430 = (tabcos[r29 * 2 + 1] * tabcos[r28 * 2]) >> 8;
dword_3243C = -tabcos[r28 * 2 + 1];
dword_32428 = ((-tabcos[r29 * 2 + 1] * tabcos[r30 * 2]) >> 8)
+ ((tabcos[r30 * 2 + 1] * ((tabcos[r29 * 2] * tabcos[r28 * 2 + 1]) >> 8)) >> 8);
dword_32434 = ((tabcos[r29 * 2] * tabcos[r30 * 2]) >> 8)
+ ((tabcos[r30 * 2 + 1] * ((tabcos[r29 * 2 + 1] * tabcos[r28 * 2 + 1]) >> 8)) >> 8);
dword_32440 = (tabcos[r28 * 2] * tabcos[r30 * 2 + 1]) >> 8;
dword_3242C = ((tabcos[r29 * 2 + 1] * tabcos[r30 * 2 + 1]) >> 8)
+ ((tabcos[r30 * 2] * ((tabcos[r29 * 2] * tabcos[r28 * 2 + 1]) >> 8)) >> 8);
dword_32438 = ((-tabcos[r29 * 2] * tabcos[r30 * 2 + 1]) >> 8)
+ ((tabcos[r30 * 2] * ((tabcos[r29 * 2 + 1] * tabcos[r28 * 2 + 1]) >> 8)) >> 8);
dword_32444 = (tabcos[r28 * 2] * tabcos[r30 * 2]) >> 8;
}
2016-10-08 21:21:21 +02:00
void EdenGame::projection_fix(cube_t *cubep, int n) {
2016-10-08 21:26:22 +02:00
for (int i = 0; i < n; i++) {
int r28 = cubep->vertices[i * 4];
int r27 = cubep->vertices[i * 4 + 1];
int r26 = cubep->vertices[i * 4 + 2];
int r25 = dword_32424 * r28 + dword_32428 * r27 + dword_3242C * r26 + (int)(flt_32454 * 256.0f);
int r24 = dword_32430 * r28 + dword_32434 * r27 + dword_32438 * r26 + (int)(flt_32450 * 256.0f);
int r29 = dword_3243C * r28 + dword_32440 * r27 + dword_32444 * r26 + (int)(flt_2DF7C * 256.0f);
r29 >>= 8;
if (r29 == -256)
r29++;
2016-12-18 13:09:56 -08:00
cubep->projection[i * 4 ] = r25 / (r29 + 256) + _cursorPosX + 14 + _scrollPos;
cubep->projection[i * 4 + 1] = r24 / (r29 + 256) + _cursorPosY + 14;
2016-10-08 21:21:21 +02:00
cubep->projection[i * 4 + 2] = r29;
2016-08-18 13:15:54 +02:00
// assert(cube->projection[i * 4] < 640);
// assert(cube->projection[i * 4 + 1] < 200);
}
}
// Original name init_cube
void EdenGame::initCubeMac() {
NEWcharge_map(2493, cube_texture);
NEWcharge_objet_mob(&cube, 2494, cube_texture);
make_tabcos();
}
2016-12-25 13:45:47 -08:00
void EdenGame::engineMac() {
Eden_dep_and_rot();
make_matrice_fix();
projection_fix(&cube, cube_faces);
affiche_objet(&cube);
}
2016-10-08 21:21:21 +02:00
void EdenGame::affiche_objet(cube_t *cubep) {
for (int i = 0; i < cubep->num; i++)
affiche_polygone_mapping(cubep, cubep->faces[i]);
}
2016-09-14 23:48:01 +02:00
void EdenGame::NEWcharge_map(int file_id, byte *buffer) {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
loadpartoffile(file_id, buffer, 32, 256 * 3);
2016-10-24 22:02:43 +02:00
for (int i = 0; i < 256; i++) {
color3_t color;
color.r = buffer[i * 3] << 8;
color.g = buffer[i * 3 + 1] << 8;
color.b = buffer[i * 3 + 2] << 8;
2016-12-25 13:45:47 -08:00
CLPalette_SetRGBColor(_globalPalette, i, &color);
}
2016-12-25 13:45:47 -08:00
CLPalette_Send2Screen(_globalPalette, 0, 256);
loadpartoffile(file_id, buffer, 32 + 256 * 3, 0x4000);
} else {
#if 0
// Fake Mac cursor on PC
Common::File f;
if (f.open("curs.raw")) {
f.seek(32);
f.read(buffer, 256 * 3);
for (i = 0; i < 256; i++) {
color3_t color;
color.r = buffer[i * 3] << 8;
color.g = buffer[i * 3 + 1] << 8;
color.b = buffer[i * 3 + 2] << 8;
CLPalette_SetRGBColor(global_palette, i, &color);
}
CLPalette_Send2Screen(global_palette, 0, 256);
f.read(buffer, 0x4000);
f.close();
}
else
error("can not load cursor texture");
#endif
}
}
2016-10-08 21:21:21 +02:00
void EdenGame::NEWcharge_objet_mob(cube_t *cubep, int file_id, byte *texptr) {
char *tmp1 = (char *)malloc(454);
if (_vm->getPlatform() == Common::kPlatformMacintosh)
loadpartoffile(file_id, tmp1, 0, 454);
else {
#if 0
// Fake Mac cursor on PC
Common::File f;
if (f.open("curseden.mob")) {
f.read(tmp1, 454);
f.close();
}
else
::error("can not load cursor model");
#endif
}
char *next = tmp1;
char error;
cube_faces = next_val(&next, &error);
int16 *vertices = (int16 *)malloc(cube_faces * 4 * sizeof(*vertices));
int16 *projection = (int16 *)malloc(cube_faces * 4 * sizeof(*projection));
2016-10-08 21:26:22 +02:00
for (int i = 0; i < cube_faces; i++) {
vertices[i * 4] = next_val(&next, &error);
vertices[i * 4 + 1] = next_val(&next, &error);
vertices[i * 4 + 2] = next_val(&next, &error);
}
2016-10-08 21:26:22 +02:00
int count2 = next_val(&next, &error);
cubeface_t **tmp4 = (cubeface_t **)malloc(count2 * sizeof(*tmp4));
2016-10-08 21:26:22 +02:00
for (int i = 0; i < count2; i++) {
char textured;
tmp4[i] = (cubeface_t *)malloc(sizeof(cubeface_t));
tmp4[i]->tri = 3;
textured = next_val(&next, &error);
tmp4[i]->ff_5 = next_val(&next, &error);
2016-09-14 23:48:01 +02:00
tmp4[i]->indices = (uint16 *)malloc(3 * sizeof(*tmp4[i]->indices));
tmp4[i]->uv = (int16 *)malloc(3 * 2 * sizeof(*tmp4[i]->uv));
2016-10-08 21:26:22 +02:00
for (int j = 0; j < 3; j++) {
tmp4[i]->indices[j] = next_val(&next, &error);
2016-08-18 13:15:54 +02:00
if (textured) {
tmp4[i]->uv[j * 2] = next_val(&next, &error);
tmp4[i]->uv[j * 2 + 1] = next_val(&next, &error);
2016-08-18 13:15:54 +02:00
}
}
if (textured) {
tmp4[i]->ff_4 = 3;
tmp4[i]->texptr = texptr;
} else
tmp4[i]->ff_4 = 0;
2016-08-18 13:15:54 +02:00
}
free(tmp1);
2016-10-08 21:21:21 +02:00
cubep->num = count2;
cubep->faces = tmp4;
cubep->projection = projection;
cubep->vertices = vertices;
}
int EdenGame::next_val(char **ptr, char *error) {
char c = 0;
char *p = *ptr;
int val = strtol(p, 0, 10);
while ((*p >= '0' && *p <= '9' && *p != 0) || *p == '-')
p++;
while ((*p == 13 || *p == 10 || *p == ',' || *p == ' ') && *p)
c = *p++;
*error = c == 10;
*ptr = p;
return val;
}
2016-09-14 23:48:01 +02:00
void EdenGame::selectmap(int16 num) {
static const char mapMode[12] = { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 2, 0 };
// Cube faces to texture coords mapping
// each entry is num_polys(6) * num_faces_per_poly(2) * vertex_per_face(3) * uv(2)
static const int16 cube_texcoords[3][6 * 2 * 3 * 2] = {
{
32, 32, 0, 32, 0, 0,
32, 32, 0, 0, 32, 0,
0, 32, 0, 0, 32, 0,
0, 32, 32, 0, 32, 32,
32, 32, 0, 32, 0, 0,
32, 32, 0, 0, 32, 0,
32, 0, 32, 32, 0, 32,
32, 0, 0, 32, 0, 0,
0, 0, 32, 0, 32, 32,
0, 0, 32, 32, 0, 32,
0, 32, 0, 0, 32, 0,
0, 32, 32, 0, 32, 32
}, {
32, 32, 0, 32, 0, 0,
32, 32, 0, 0, 32, 0,
32, 0, 32, 32, 0, 32,
32, 0, 0, 32, 0, 0,
32, 0, 32, 32, 0, 32,
32, 0, 0, 32, 0, 0,
0, 32, 0, 0, 32, 0,
0, 32, 32, 0, 32, 32,
32, 0, 32, 32, 0, 32,
32, 0, 0, 32, 0, 0,
32, 0, 32, 32, 0, 32,
32, 0, 0, 32, 0, 0
}, {
30, 30, 2, 30, 2, 2,
30, 30, 2, 2, 30, 2,
2, 30, 2, 2, 30, 2,
2, 30, 30, 2, 30, 30,
30, 30, 2, 30, 2, 2,
30, 30, 2, 2, 30, 2,
30, 2, 30, 30, 2, 30,
30, 2, 2, 30, 2, 2,
2, 2, 30, 2, 30, 30,
2, 2, 30, 30, 2, 30,
2, 30, 2, 2, 30, 2,
2, 30, 30, 2, 30, 30
}
};
curs_cur_map = num;
int16 k = 0;
int mode = mapMode[num];
int16 x = (num & 7) * 32;
int16 y = (num & 0x18) * 4;
for (int i = 0; i < 6 * 2; i++) {
for (int j = 0; j < 3; j++) {
cube.faces[i]->uv[j * 2 ] = x + cube_texcoords[mode][k++];
cube.faces[i]->uv[j * 2 + 1] = y + cube_texcoords[mode][k++];
2016-08-18 13:15:54 +02:00
}
}
}
void EdenGame::Eden_dep_and_rot() {
int16 curs = _currCursor;
2016-12-18 13:09:56 -08:00
if (_normalCursor && (p_global->_drawFlags & DrawFlags::drDrawFlag20))
curs = 10;
selectmap(curs);
curs_new_tick = TickCount();
if (curs_new_tick - curs_old_tick < 1)
return;
curs_old_tick = curs_new_tick;
switch (_currCursor) {
case 0:
word_3244C = (word_3244C + 2) % 360;
word_3244A = (word_3244A + 2) % 360;
restoreZDEP();
break;
case 1:
word_3244C = 0;
word_3244A -= 2;
if (word_3244A < 0)
word_3244A += 360;
restoreZDEP();
break;
case 2:
word_3244C = (word_3244C + 2) % 360;
word_3244A = 0;
restoreZDEP();
break;
case 3:
word_3244C -= 2;
if (word_3244C < 0)
word_3244C += 360;
word_3244A = 0;
restoreZDEP();
break;
case 4:
word_3244C = 0;
word_3244A = (word_3244A + 2) % 360;
restoreZDEP();
break;
case 5:
word_3244C = 0;
word_3244A = 0;
flt_2DF7C += flt_2DF84;
if ((flt_2DF7C < -3600.0 + flt_2DF80) || flt_2DF7C > flt_2DF80)
flt_2DF84 = -flt_2DF84;
break;
case 6:
word_3244C = 0;
word_3244A = 0;
flt_2DF7C = flt_2DF80;
break;
case 7:
word_3244C -= 2;
if (word_3244C < 0)
word_3244C += 360;
word_3244A = 0;
restoreZDEP();
break;
case 8:
word_3244C = 0;
word_3244A = 0;
flt_2DF7C = flt_2DF80;
break;
case 9:
word_3244C = 0;
word_3244A = 0;
flt_2DF7C = flt_2DF80;
break;
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
void EdenGame::restoreZDEP() {
flt_2DF84 = 200.0;
if (flt_2DF7C < flt_2DF80)
flt_2DF7C += flt_2DF84;
if (flt_2DF7C > flt_2DF80)
flt_2DF7C -= flt_2DF84;
}
2016-08-18 13:15:54 +02:00
2016-10-08 21:21:21 +02:00
void EdenGame::affiche_polygone_mapping(cube_t *cubep, cubeface_t *face) {
2016-09-14 23:48:01 +02:00
uint16 *indices = face->indices;
int idx = indices[0] * 4;
int16 v46 = cubep->projection[idx];
int16 v48 = cubep->projection[idx + 1];
2016-08-18 13:15:54 +02:00
idx = indices[1] * 4;
int16 v4A = cubep->projection[idx];
int16 v4C = cubep->projection[idx + 1];
idx = indices[2] * 4;
int16 v4E = cubep->projection[idx];
int16 v50 = cubep->projection[idx + 1];
if ((v4C - v48) * (v4E - v46) - (v50 - v48) * (v4A - v46) > 0)
return;
2016-08-18 13:15:54 +02:00
int16 *uv = face->uv;
int16 ymin = 200; // min y
int16 ymax = 0; // max y
idx = indices[0] * 4;
int16 r20 = cubep->projection[idx];
int16 r30 = cubep->projection[idx + 1];
int16 r19 = *uv++;
int16 r18 = *uv++;
indices++;
for (int r17 = 0; r17 < face->tri - 1; r17++, indices++) {
idx = indices[0] * 4;
int16 r26 = cubep->projection[idx];
int16 r31 = cubep->projection[idx + 1];
uint16 r25 = *uv++; //TODO: unsigned
int16 r24 = *uv++; //TODO: unsigned
2016-08-18 13:15:54 +02:00
if (r30 < ymin)
ymin = r30;
if (r30 > ymax)
ymax = r30;
if (r31 < ymin)
ymin = r31;
if (r31 > ymax)
ymax = r31;
trace_ligne_mapping(r20, r30, r26, r31, r19, r18, r25, r24, _lines);
r20 = r26;
r30 = r31;
r19 = r25;
r18 = r24;
}
idx = face->indices[0] * 4;
int16 r26 = cubep->projection[idx];
int16 r31 = cubep->projection[idx + 1];
uv = face->uv;
uint16 r25 = *uv++; //TODO: this is unsigned
int16 r24 = *uv; //TODO: this is signed
if (r30 < ymin)
ymin = r30;
if (r30 > ymax)
ymax = r30;
if (r31 < ymin)
ymin = r31;
if (r31 > ymax)
ymax = r31;
trace_ligne_mapping(r20, r30, r26, r31, r19, r18, r25, r24, _lines);
2016-12-18 14:13:36 -08:00
affiche_ligne_mapping(ymin, ymax, _mainView->_bufferPtr, face->texptr);
}
2016-10-08 21:21:21 +02:00
void EdenGame::trace_ligne_mapping(int16 r3, int16 r4, int16 r5, int16 r6, int16 r7, int16 r8, int16 r9, int16 r10, int16 *linesp) {
int16 r26 = r6 - r4;
if (r26 <= 0) {
if (r26 == 0) {
2016-10-08 21:21:21 +02:00
linesp += r4 * 8;
if (r5 - r3 > 0) {
2016-10-08 21:21:21 +02:00
linesp[0] = r3;
linesp[1] = r5;
linesp[4] = r7;
linesp[5] = r9;
linesp[6] = r8;
linesp[7] = r10;
} else {
2016-10-08 21:21:21 +02:00
linesp[0] = r5;
linesp[1] = r3;
linesp[4] = r9;
linesp[5] = r7;
linesp[6] = r10;
linesp[7] = r8;
2016-08-18 13:15:54 +02:00
}
return;
}
int16 t = r3;
r3 = r5;
r5 = t;
t = r7;
r7 = r9;
r9 = t;
t = r8;
r8 = r10;
r10 = t;
2016-10-08 21:21:21 +02:00
linesp += r6 * 8;
r26 = -r26;
} else
2016-10-08 21:21:21 +02:00
linesp += r4 * 8 + 1; //TODO wha???
2016-08-18 13:15:54 +02:00
int r30 = r3 << 16;
int r29 = r7 << 16;
int r28 = r8 << 16;
2016-08-18 13:15:54 +02:00
int r25 = ((r5 - r3) << 16) / r26;
int r24 = ((r9 - r7) << 16) / r26;
int r23 = ((r10 - r8) << 16) / r26;
2016-08-18 13:15:54 +02:00
for (int i = 0; i < r26; i++) {
2016-10-08 21:21:21 +02:00
linesp[0] = r30 >> 16;
linesp[4] = r29 >> 16;
linesp[6] = r28 >> 16;
2016-08-18 13:15:54 +02:00
r30 += r25;
r29 += r24;
r28 += r23;
2016-10-08 21:21:21 +02:00
linesp += 8;
2016-08-18 13:15:54 +02:00
}
}
2016-08-18 13:15:54 +02:00
2016-09-14 23:48:01 +02:00
void EdenGame::affiche_ligne_mapping(int16 r3, int16 r4, byte *target, byte *texture) {
int16 height = r4 - r3;
2016-12-18 14:13:36 -08:00
byte *trg_line = _mainView->_bufferPtr + r3 * 640; //TODO: target??
int16 *line = &_lines[r3 * 8];
// debug("curs: beg draw %d - %d", r3, r4);
for (int r22 = height; r22; r22--, line += 8, trg_line += 640) {
int16 r29 = line[0];
int16 r28 = line[1];
int16 len = r28 - r29;
if (len < 0)
break;
if (len == 0)
continue;
// debug("curs: lin draw %d", r4 - height);
uint16 r31 = line[4] << 8;
uint16 r30 = line[6] << 8;
int16 r21 = line[5] - line[4];
int16 r20 = line[7] - line[6];
2016-08-18 13:15:54 +02:00
int16 r26 = (r21 << 8) / len;
int16 r25 = (r20 << 8) / len;
byte *trg = trg_line + r29;
2016-08-18 13:15:54 +02:00
#if 1
while (r29++ < r28) {
*trg++ = texture[(r30 & 0xFF00) | (r31 >> 8)];
r31 += r26;
r30 += r25;
2016-08-18 13:15:54 +02:00
}
#endif
2016-08-18 13:15:54 +02:00
}
}
// PC cursor
cubeCursor pc_cursors[9] = {
{ { 0, 0, 0, 0, 0, 0 }, 3, 2 },
{ { 1, 1, 0, 1, 1, 0 }, 2, -2 },
{ { 2, 2, 2, 2, 2, 2 }, 1, 2 },
{ { 3, 3, 3, 3, 3, 3 }, 1, -2 },
{ { 4, 4, 4, 4, 4, 4 }, 2, 2 },
{ { 5, 5, 5, 5, 5, 5 }, 4, 0 },
{ { 6, 6, 6, 6, 6, 6 }, 1, 2 },
{ { 7, 7, 7, 7, 7, 7 }, 1, -2 },
// { { 0, 8, 0, 0, 8, 8 }, 2, 2 },
{ { 0, 8, 0, 0, 8, 8 }, 2, 2 }
};
XYZ pc_cube[6][3] = {
{ { -15, -15, -15 }, { -15, 15, -15 }, { 15, 15, -15 } },
{ { -15, -15, 15 }, { -15, 15, 15 }, { -15, 15, -15 } },
{ { -15, -15, 15 }, { -15, -15, -15 }, { 15, -15, -15 } },
{ { 15, -15, 15 }, { 15, 15, 15 }, { -15, 15, 15 } },
{ { 15, -15, -15 }, { 15, 15, -15 }, { 15, 15, 15 } },
{ { 15, 15, 15 }, { 15, 15, -15 }, { -15, 15, -15 } }
};
signed short cosine[] = {
// = cos(n) << 7; n += 10;
128, 126, 120, 111, 98, 82, 64, 44, 22, 0, -22, -44, -64, -82, -98, -111, -120, -126,
-128, -126, -120, -111, -98, -82, -64, -44, -22, 0, 22, 44, 64, 82, 98, 111, 120, 126,
128, 126, 120, 111, 98, 82, 64, 44, 22, 0
};
2016-12-25 13:45:47 -08:00
void EdenGame::makeTables() {
for (int i = -15; i < 15; i++) {
int v = (i * 11) / 15 + 11;
tab1[i + 15] = v;
tab2[i + 15] = v * 22;
}
for (int i = 0; i < 36; i++) {
for (int j = -35; j < 36; j++)
tab3[i][j + 35] = (cosine[i] * j) >> 7;
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::getSinCosTables(unsigned short angle, signed char **cos_table, signed char **sin_table) {
angle /= 2;
*cos_table = tab3[angle] + 35;
angle += 9;
if (angle >= 36)
angle -= 36;
*sin_table = tab3[angle] + 35;
}
2016-12-25 13:45:47 -08:00
void EdenGame::rotatePoint(XYZ *point, XYZ *rpoint) {
// see http://www.cprogramming.com/tutorial/3d/rotation.html
XYZ xrot;
xrot.x = point->x;
2016-12-25 13:45:47 -08:00
xrot.y = _cosX[point->y] + _sinX[point->z];
xrot.z = _sinX[-point->y] + _cosX[point->z];
2016-12-25 13:45:47 -08:00
rpoint->x = _cosY[xrot.x] + _sinY[-xrot.z];
rpoint->y = xrot.y;
2016-12-25 13:45:47 -08:00
rpoint->z = _sinY[xrot.x] + _cosY[xrot.z];
2016-12-25 13:45:47 -08:00
rpoint->z += _zoomZ;
}
2016-12-25 13:45:47 -08:00
void EdenGame::mapPoint(XYZ *point, short *x, short *y) {
*y = ((12800 / point->z) * point->y) >> 7;
*x = ((12800 / point->z) * point->x) >> 7;
}
2016-12-25 13:45:47 -08:00
short EdenGame::calcFaceArea(XYZ *face) {
XYZ rpoint;
short x[3], y[3];
for (int i = 0; i < 3; i++) {
2016-12-25 13:45:47 -08:00
rotatePoint(&face[i], &rpoint);
mapPoint(&rpoint, &x[i], &y[i]);
}
short area = (y[1] - y[0]) * (x[2] - x[0]) - (y[2] - y[0]) * (x[1] - x[0]);
return area;
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintPixel(XYZ *point, unsigned char pixel) {
short x, y;
2016-12-25 13:45:47 -08:00
mapPoint(point, &x, &y);
_cursorCenter[y * 40 + x] = pixel;
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace0(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->x = x;
point->y = y;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[0][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace1(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->y = y;
point->z = -x;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[1][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace2(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->x = x;
point->z = -y;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[2][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace3(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->x = -x;
point->y = -y;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[3][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace4(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->y = y;
point->z = x;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[4][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFace5(XYZ *point) {
XYZ rpoint;
for (int y = -15; y < 15; y++) {
for (int x = -15; x < 15; x++) {
point->x = x;
point->z = y;
2016-12-25 13:45:47 -08:00
rotatePoint(point, &rpoint);
paintPixel(&rpoint, _face[5][tab1[x + 15] + tab2[y + 15]]);
}
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::paintFaces() {
XYZ point;
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 1)) {
point.z = -15;
2016-12-25 13:45:47 -08:00
paintFace0(&point);
}
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 2)) {
point.x = -15;
2016-12-25 13:45:47 -08:00
paintFace1(&point);
}
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 4)) {
point.y = -15;
2016-12-25 13:45:47 -08:00
paintFace2(&point);
}
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 8)) {
point.z = 15;
2016-12-25 13:45:47 -08:00
paintFace3(&point);
}
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 16)) {
point.x = 15;
2016-12-25 13:45:47 -08:00
paintFace4(&point);
}
2016-12-25 13:45:47 -08:00
if (!(_faceSkip & 32)) {
point.y = 15;
2016-12-25 13:45:47 -08:00
paintFace5(&point);
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::renderCube() {
for (int i = 0; i < sizeof(_cursor); i++)
_cursor[i] = 0;
_cursorCenter = &_cursor[40 * 20 + 20];
2016-12-25 13:45:47 -08:00
getSinCosTables(_angleX, &_cosX, &_sinX);
getSinCosTables(_angleY, &_cosY, &_sinY);
getSinCosTables(_angleZ, &_cosZ, &_sinZ);
for (int i = 0; i < 6; i++) {
2016-12-25 13:45:47 -08:00
int area = calcFaceArea(pc_cube[i]);
if (area <= 0) {
_face[i] = _newface[i]; // set new texture for invisible area,
2016-12-25 13:45:47 -08:00
_faceSkip |= 1 << i; // but don't draw it just yet
} else
2016-12-25 13:45:47 -08:00
_faceSkip &= ~(1 << i);
}
2016-12-25 13:45:47 -08:00
paintFaces();
const int xshift = -5; // TODO: temporary fix to decrease left margin
2016-12-25 13:45:47 -08:00
unsigned char *cur = _cursor;
2016-12-18 14:13:36 -08:00
unsigned char *scr = _mainView->_bufferPtr + _cursorPosX + _scrollPos + xshift + _cursorPosY * _mainView->_pitch;
for (int y = 0; y < 40; y++) {
for (int x = 0; x < 40; x++) {
2016-12-18 14:13:36 -08:00
if (x + _cursorPosX + _scrollPos + xshift < _mainView->_pitch && y + _cursorPosY < _mainView->_height)
if (*cur)
*scr = *cur;
scr++;
cur++;
}
2016-12-18 14:13:36 -08:00
scr += _mainView->_pitch - 40;
}
}
2016-12-18 14:13:36 -08:00
void EdenGame::incAngleX(int step) {
2016-12-25 13:45:47 -08:00
_angleX += step;
if (_angleX == 70 + 2)
_angleX = 0;
if (_angleX == 0 - 2)
_angleX = 70;
}
2016-12-18 14:13:36 -08:00
void EdenGame::decAngleX() {
2016-12-25 13:45:47 -08:00
if (_angleX != 0)
_angleX -= (_angleX > 4) ? 4 : 2;
}
2016-12-18 14:13:36 -08:00
void EdenGame::incAngleY(int step) {
2016-12-25 13:45:47 -08:00
_angleY += step;
if (_angleY == 70 + 2)
_angleY = 0;
if (_angleY == 0 - 2)
_angleY = 70;
}
2016-12-18 14:13:36 -08:00
void EdenGame::decAngleY() {
2016-12-25 13:45:47 -08:00
if (_angleY != 0)
_angleY -= (_angleY > 4) ? 4 : 2;
}
2016-12-18 14:13:36 -08:00
void EdenGame::incZoom() {
2016-12-25 13:45:47 -08:00
if (_zoomZ == 170)
_zoomZStep = 40;
if (_zoomZ == 570)
_zoomZStep = -40;
_zoomZ += _zoomZStep;
}
2016-12-18 14:13:36 -08:00
void EdenGame::decZoom() {
2016-12-25 13:45:47 -08:00
if (_zoomZ != 170) {
if (_zoomZ < 170)
_zoomZ = 170;
else
2016-12-25 13:45:47 -08:00
_zoomZ -= 40;
}
}
void EdenGame::initCubePC() {
2016-12-25 13:45:47 -08:00
_zoomZ = 170;
_zoomZStep = 40;
_angleX = _angleY = _angleZ = 0;
_pcCursor = &pc_cursors[0];
curs_cur_map = -1;
2016-12-25 13:45:47 -08:00
makeTables();
}
2016-12-25 13:45:47 -08:00
void EdenGame::selectPCMap(int16 num) {
if (num != curs_cur_map) {
2016-12-25 13:45:47 -08:00
_pcCursor = &pc_cursors[num];
2016-12-04 14:54:58 -08:00
unsigned char *bank = _mainBankBuf + READ_LE_UINT16(_mainBankBuf);
for (int i = 0; i < 6; i++) {
2016-12-25 13:45:47 -08:00
_newface[i] = 4 + (unsigned char*)getElem(bank, _pcCursor->_sides[i]);
if (curs_cur_map == -1)
_face[i] = _newface[i];
}
curs_cur_map = num;
}
}
2016-12-25 13:45:47 -08:00
void EdenGame::enginePC() {
int16 curs = _currCursor;
2016-12-18 13:09:56 -08:00
if (_normalCursor && (p_global->_drawFlags & DrawFlags::drDrawFlag20))
curs = 9;
2016-12-25 13:45:47 -08:00
selectPCMap(curs);
curs_new_tick = TickCount();
if (curs_new_tick - curs_old_tick < 1)
return;
curs_old_tick = curs_new_tick;
2016-12-25 13:45:47 -08:00
int step = _pcCursor->speed;
switch (_pcCursor->kind) {
case 0:
break;
case 1: // rot up-down
2016-12-18 14:13:36 -08:00
decAngleY();
decZoom();
incAngleX(step);
break;
case 2: // rot left-right
2016-12-18 14:13:36 -08:00
decAngleX();
decZoom();
incAngleY(step);
break;
case 3: // rotate random
2016-12-18 14:13:36 -08:00
decZoom();
incAngleX(step);
incAngleY(step);
break;
case 4: // zoom in-out
_face[0] = _newface[0];
2016-12-18 14:13:36 -08:00
decAngleY();
decAngleX();
incZoom();
break;
}
2016-12-25 13:45:47 -08:00
renderCube();
}
2016-08-18 13:15:54 +02:00
////// macgame.c
//void MyDlgHook() { }
//void PrepareReply() { }
2016-09-14 23:48:01 +02:00
int16 EdenGame::OpenDialog(void *arg1, void *arg2) {
//TODO
return 0;
}
2016-08-18 13:15:54 +02:00
//void SaveDialog() { }
//void LostEdenMac_SavePrefs() { }
//void LostEdenMac_LoadPrefs() { }
void EdenGame::LostEdenMac_InitPrefs() {
2016-12-11 13:44:58 -08:00
p_global->_prefLanguage = 1;
2016-09-30 07:48:27 +02:00
_doubledScreen = false; // TODO: set to true
2016-12-11 13:44:58 -08:00
p_global->_prefMusicVol[0] = 192;
p_global->_prefMusicVol[1] = 192;
p_global->_prefVoiceVol[0] = 255;
p_global->_prefVoiceVol[1] = 255;
p_global->_prefSoundVolume[0] = 32;
p_global->_prefSoundVolume[1] = 32;
}
2016-08-18 13:15:54 +02:00
//void MacGame_DoAbout() { }
//void MacGame_DoAdjustMenus() { }
//void LostEdenMac_DoPreferences() { }
//void MacGame_DoSave() { }
//void MacGame_DoMenuCommand() { }
//void MacGame_DoOpen() { }
//void MacGame_DoSaveAs() { }
} // namespace Cryo