TWINE: implemented a few lba2 opcodes

This commit is contained in:
Martin Gerhardy 2024-03-22 18:46:53 +01:00
parent b4f6042e84
commit 9c23225eaa
12 changed files with 140 additions and 27 deletions

View File

@ -46,6 +46,25 @@ Sound::~Sound() {
_engine->_system->getMixer()->stopAll();
}
void Sound::startRainSample() {
if (!_engine->_cfgfile.Sound) {
return;
}
#if 0
const int sample = SAMPLE_RAIN;
if (CubeMode == CUBE_EXTERIEUR && !TEMPETE_FINIE && !isSamplePlaying(sample)) {
//const int frequency = 0x1000;
const int offset = 300;
const int repeat = 0;
const int panning = 64;
const int volumeRain = 70;
// TODO: playSample(sample, /*frequency,*/ offset, repeat, panning, volumeRain);
}
RestartRainSample = false;
#endif
}
void Sound::setSamplePosition(int32 channelIdx, int32 x, int32 y, int32 z) {
if (channelIdx < 0 || channelIdx >= NUM_CHANNELS) {
return;

View File

@ -100,6 +100,7 @@ public:
* @param z sound generating entity z position
* @param actorIdx
*/
// HQ_MixSample
void playSample(int32 index, int32 repeat = 1, int32 x = 128, int32 y = 128, int32 z = 128, int32 actorIdx = -1);
void playSample(int32 index, int32 repeat, const IVec3 &pos, int32 actorIdx = -1) {
playSample(index, repeat, pos.x, pos.y, pos.z, actorIdx);
@ -111,6 +112,8 @@ public:
/** Resume samples */
void resumeSamples();
void startRainSample();
/** Stop samples */
void stopSamples();

View File

@ -169,20 +169,63 @@ void Redraw::sortDrawingList(DrawListStruct *list, int32 listSize) const {
}
}
void Redraw::addOverlay(OverlayType type, int16 info0, int16 x, int16 y, int16 info1, OverlayPosType posType, int16 lifeTime) { // InitIncrustDisp
void Redraw::posObjIncrust(OverlayListStruct *ptrdisp, int32 num) {
// in case we have several 3D objects rotating at the same time!
int32 x = 10;
OverlayType type = ptrdisp->type;
if (type == OverlayType::koInventory || type == OverlayType::koInventoryItem) {
for (int32 n = 0; n < ARRAYSIZE(overlayList); n++) {
OverlayListStruct *overlay = &overlayList[n];
if (n != num && overlay->info0 != -1) {
if (overlay->type == OverlayType::koInventory || overlay->type == OverlayType::koInventoryItem) {
x += 70;
}
}
}
ptrdisp->y = 10;
ptrdisp->x = (int16)x;
}
}
int32 Redraw::addOverlay(OverlayType type, int16 info0, int16 x, int16 y, int16 info1, OverlayPosType posType, int16 lifeTime) { // InitIncrustDisp
for (int32 i = 0; i < ARRAYSIZE(overlayList); i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->info0 == -1) {
overlay->type = type;
overlay->info0 = info0;
overlay->x = x;
overlay->y = y;
overlay->info1 = info1;
overlay->posType = posType;
overlay->lifeTime = _engine->timerRef + _engine->toSeconds(lifeTime);
break;
if (_engine->isLBA1()) {
if (overlay->info0 == -1) {
overlay->type = type;
overlay->info0 = info0;
overlay->x = x;
overlay->y = y;
overlay->info1 = info1;
overlay->posType = posType;
overlay->lifeTime = _engine->timerRef + _engine->toSeconds(lifeTime);
return i;
}
} else {
if (overlay->info0 == -1 || (overlay->info0 == info0 && overlay->type == type)) {
if (overlay->info0 == -1 || overlay->type != type) {
overlay->x = x;
overlay->y = y;
}
if ((OverlayType)((uint8)type) == OverlayType::koNumberRange) {
// ATTENTION: Big Trickery: counters are always displayed
// at y=20, this allows using the Y to store the
// current value of the counter (see FlagAnimWhoSpeak)
overlay->y = info0;
}
overlay->type = type;
overlay->info0 = info0;
overlay->info1 = info1;
overlay->posType = posType;
overlay->lifeTime = _engine->timerRef + _engine->toSeconds(lifeTime);
posObjIncrust(overlay, i);
return i;
}
}
}
return -1;
}
void Redraw::updateOverlayTypePosition(int16 x1, int16 y1, int16 x2, int16 y2) {
@ -771,6 +814,13 @@ void Redraw::renderOverlays() {
_engine->_interface->unsetClip();
break;
}
case OverlayType::koSysText:
case OverlayType::koFlash:
case OverlayType::koRain:
case OverlayType::koInventory:
// TODO lba2
case OverlayType::koMax:
break;
}
}
}

View File

@ -35,7 +35,12 @@ enum class OverlayType {
koNumber = 1,
koNumberRange = 2,
koInventoryItem = 3,
koText = 4
koText = 4,
koInventory = 5, // lba2
koSysText = 6, // lba2
koFlash = 7, //lba2
koRain = 8, //lba2
koMax
};
enum class OverlayPosType {
@ -154,7 +159,8 @@ public:
void setRenderText(const Common::String &text);
// InitIncrustDisp
void addOverlay(OverlayType type, int16 info0, int16 x, int16 y, int16 info1, OverlayPosType posType, int16 lifeTime);
int32 addOverlay(OverlayType type, int16 info0, int16 x, int16 y, int16 info1, OverlayPosType posType, int16 lifeTime);
void posObjIncrust(OverlayListStruct *ptrdisp, int32 num); // lba2
/**
* Add a certain region to redraw list array

View File

@ -50,6 +50,7 @@ namespace TwinE {
#define RESSHQR_BLACKPAL 9 // lba2
#define RESSHQR_ECLAIRPAL 10 // lba2
#define SAMPLE_RAIN 13
#define RESSHQR_GAMEOVERMDL 21

View File

@ -131,6 +131,7 @@ void Actor::setBehaviour(HeroBehaviourType behaviour) {
_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, AnimationTypes::kAnimInvalid, OWN_ACTOR_SCENE_INDEX);
}
// InitSprite
void Actor::initSpriteActor(int32 actorIdx) {
ActorStruct *localActor = _engine->_scene->getActor(actorIdx);
@ -236,7 +237,7 @@ void Actor::copyInterAnim(const BodyData &src, BodyData &dest) {
}
}
void Actor::initActor(int16 actorIdx) {
void Actor::startInitObj(int16 actorIdx) {
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
if (actor->_staticFlags.bIsSpriteActor) {

View File

@ -331,7 +331,7 @@ public:
* Initialize actors
* @param actorIdx actor index to init
*/
void initActor(int16 actorIdx);
void startInitObj(int16 actorIdx);
/**
* Reset actor

View File

@ -583,7 +583,7 @@ void Scene::changeScene() {
_engine->_actor->restartHeroScene();
for (int32 a = 1; a < _nbObjets; a++) {
_engine->_actor->initActor(a);
_engine->_actor->startInitObj(a);
}
_engine->_gameState->_inventoryNumKeys = 0;

View File

@ -20,10 +20,14 @@
*/
#include "twine/script/script_life_v2.h"
#include "twine/renderer/redraw.h"
#include "twine/renderer/screens.h"
#include "twine/audio/sound.h"
#include "twine/renderer/renderer.h"
#include "twine/resources/resources.h"
#include "twine/scene/movements.h"
#include "twine/script/script_move_v2.h"
#include "twine/shared.h"
#include "twine/twine.h"
namespace TwinE {
@ -266,11 +270,27 @@ int32 ScriptLifeV2::lRESTORE_HERO(TwinEEngine *engine, LifeScriptContext &ctx) {
}
int32 ScriptLifeV2::lRAIN(TwinEEngine *engine, LifeScriptContext &ctx) {
return -1;
// Pluie n/10s
const int32 num = (int)ctx.stream.readByte() / 10;
int32 n = engine->_redraw->addOverlay(OverlayType::koRain, 0, 0, 0, 0, OverlayPosType::koNormal, 1);
if (n != -1) {
engine->_redraw->overlayList[n].lifeTime = engine->timerRef + engine->toSeconds(num);
engine->_flagRain = true;
engine->_sound->startRainSample();
}
return 0;
}
int32 ScriptLifeV2::lESCALATOR(TwinEEngine *engine, LifeScriptContext &ctx) {
return -1;
uint8 num = ctx.stream.readByte();
uint8 info1 = ctx.stream.readByte();
for (int n = 0; n < engine->_scene->_sceneNumZones; n++) {
ZoneStruct &zone = engine->_scene->_sceneZones[n];
if (zone.type == ZoneType::kEscalator && zone.num == num) {
zone.infoData.generic.info1 = info1;
}
}
return 0;
}
int32 ScriptLifeV2::lSET_CAMERA(TwinEEngine *engine, LifeScriptContext &ctx) {
@ -293,7 +313,13 @@ int32 ScriptLifeV2::lSHADOW_OBJ(TwinEEngine *engine, LifeScriptContext &ctx) {
}
int32 ScriptLifeV2::lECLAIR(TwinEEngine *engine, LifeScriptContext &ctx) {
return -1;
// Eclair n/10s
const int32 num = (int)ctx.stream.readByte() / 10;
int32 n = engine->_redraw->addOverlay(OverlayType::koFlash, 0, 0, 0, 0, OverlayPosType::koNormal, 1);
if (n != -1) {
engine->_redraw->overlayList[n].lifeTime = engine->timerRef + engine->toSeconds(num);
}
return 0;
}
int32 ScriptLifeV2::lINIT_BUGGY(TwinEEngine *engine, LifeScriptContext &ctx) {
@ -325,8 +351,7 @@ int32 ScriptLifeV2::lSET_FRAME(TwinEEngine *engine, LifeScriptContext &ctx) {
int32 ScriptLifeV2::lSET_SPRITE(TwinEEngine *engine, LifeScriptContext &ctx) {
int16 num = ctx.stream.readSint16LE();
if (ctx.actor->_staticFlags.bIsSpriteActor) {
ActorStruct *actor = engine->_scene->getActor(ctx.actorIdx);
actor->_sprite = num;
ctx.actor->_sprite = num;
engine->_actor->initSpriteActor(ctx.actorIdx);
}
return 0;

View File

@ -75,8 +75,8 @@ static const ScriptMoveFunction function_map[] = {
{"WAIT_ANIM_3DS", ScriptMoveV2::mWAIT_ANIM_3DS},
{"WAIT_FRAME_3DS", ScriptMoveV2::mWAIT_FRAME_3DS},
{"WAIT_NB_DIZIEME_RND", ScriptMoveV2::mWAIT_NB_DIZIEME_RND},
{"DECALAGE", ScriptMoveV2::mDECALAGE},
{"FREQUENCE", ScriptMoveV2::mFREQUENCE},
{"DECALAGE", ScriptMoveV2::mOFFSET},
{"FREQUENCY", ScriptMoveV2::mFREQUENCY},
{"VOLUME", ScriptMoveV2::mVOLUME}
};
@ -147,7 +147,12 @@ int32 ScriptMoveV2::mWAIT_NB_SECOND_RND(TwinEEngine *engine, MoveScriptContext &
}
int32 ScriptMoveV2::mSPRITE(TwinEEngine *engine, MoveScriptContext &ctx) {
return -1;
int16 num = ctx.stream.readSint16LE();
if (ctx.actor->_staticFlags.bIsSpriteActor) {
ctx.actor->_sprite = num;
engine->_actor->initSpriteActor(ctx.actorIdx);
}
return 0;
}
int32 ScriptMoveV2::mSET_FRAME(TwinEEngine *engine, MoveScriptContext &ctx) {
@ -182,11 +187,13 @@ int32 ScriptMoveV2::mWAIT_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx)
return -1;
}
int32 ScriptMoveV2::mDECALAGE(TwinEEngine *engine, MoveScriptContext &ctx) {
// DECALAGE
int32 ScriptMoveV2::mOFFSET(TwinEEngine *engine, MoveScriptContext &ctx) {
return -1;
}
int32 ScriptMoveV2::mFREQUENCE(TwinEEngine *engine, MoveScriptContext &ctx) {
// FREQUENCE
int32 ScriptMoveV2::mFREQUENCY(TwinEEngine *engine, MoveScriptContext &ctx) {
return -1;
}

View File

@ -42,8 +42,8 @@ public:
static int32 mWAIT_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mWAIT_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mWAIT_NB_DIZIEME_RND(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mDECALAGE(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mFREQUENCE(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mOFFSET(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mFREQUENCY(TwinEEngine *engine, MoveScriptContext &ctx);
static int32 mVOLUME(TwinEEngine *engine, MoveScriptContext &ctx);
ScriptMoveV2(TwinEEngine *engine);

View File

@ -308,6 +308,7 @@ public:
int32 _stepFalling = 0;
uint32 _gameFlags;
Common::Platform _platform;
bool _flagRain;
/** Disable screen recenter */
bool _disableScreenRecenter = false;