TWINE: merged with latest master
This commit is contained in:
parent
701c1de7dc
commit
c19e28b379
10 changed files with 113 additions and 59 deletions
|
@ -35,6 +35,7 @@
|
|||
#include "twine/scene/animations.h"
|
||||
#include "twine/audio/music.h"
|
||||
#include "twine/audio/sound.h"
|
||||
#include "twine/movies.h"
|
||||
#include "twine/scene/gamestate.h"
|
||||
#include "twine/scene/grid.h"
|
||||
#include "twine/resources/hqr.h"
|
||||
|
@ -591,17 +592,23 @@ int32 Menu::processMenu(MenuSettings *menuSettings, bool showCredits) {
|
|||
}
|
||||
if (showCredits && loopMillis - startMillis > 11650) {
|
||||
_engine->_menuOptions->showCredits();
|
||||
if (_engine->_flaMovies->playFlaMovie(FLA_DRAGON3)) {
|
||||
if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 15, 16), 3)) {
|
||||
if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 17, 18), 3)) {
|
||||
if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 19, 20), 3)) {
|
||||
if (_engine->_flaMovies->playFlaMovie(FLA_BATEAU)) {
|
||||
if (_engine->_cfgfile.Version == USA_VERSION) {
|
||||
_engine->_screens->loadImageDelay(_engine->_resources->relentLogo(), 3);
|
||||
} else {
|
||||
_engine->_screens->loadImageDelay(_engine->_resources->lbaLogo(), 3);
|
||||
}
|
||||
_engine->_screens->adelineLogo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_engine->_text->initTextBank(TextBankId::Options_and_menus);
|
||||
|
||||
// TODO the original game also performs these actions:
|
||||
// play FLA_DRAGON3 fla
|
||||
// display RESSHQR_INTROSCREEN1IMG
|
||||
// display RESSHQR_INTROSCREEN2IMG
|
||||
// display RESSHQR_INTROSCREEN3IMG
|
||||
// play FLA_BATEAU fla
|
||||
// if version == EUROPE_VERSION display RESSHQR_LBAIMG else display RESSHQR_RELLENTIMG
|
||||
// display adeline logo
|
||||
// pressing any key during these actions will abort everything and return to the menu
|
||||
startMillis = _engine->_system->getMillis();
|
||||
_engine->_screens->loadMenuImage(false);
|
||||
}
|
||||
|
@ -1148,6 +1155,7 @@ void Menu::drawInventoryItems(int32 left, int32 top) {
|
|||
for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
|
||||
drawItem(left, top, item);
|
||||
}
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
|
||||
void Menu::processInventoryMenu() {
|
||||
|
|
|
@ -353,7 +353,7 @@ void Movies::playGIFMovie(const char *flaName) {
|
|||
}
|
||||
}
|
||||
|
||||
void Movies::playFlaMovie(const char *flaName) {
|
||||
bool Movies::playFlaMovie(const char *flaName) {
|
||||
assert(_engine->isLBA1());
|
||||
_engine->_sound->stopSamples();
|
||||
|
||||
|
@ -365,7 +365,7 @@ void Movies::playFlaMovie(const char *flaName) {
|
|||
|
||||
if (_engine->_cfgfile.Movie == CONF_MOVIE_FLAGIF) {
|
||||
playGIFMovie(fileNamePath.c_str());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
_engine->_music->stopMusic();
|
||||
|
@ -377,7 +377,7 @@ void Movies::playFlaMovie(const char *flaName) {
|
|||
if (!_file.open(fileNamePath + FLA_EXT)) {
|
||||
warning("Failed to open fla movie '%s'", fileNamePath.c_str());
|
||||
playGIFMovie(fileNamePath.c_str());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32 version = _file.readUint32LE();
|
||||
|
@ -395,6 +395,7 @@ void Movies::playFlaMovie(const char *flaName) {
|
|||
|
||||
_file.skip(4 * _samplesInFla);
|
||||
|
||||
bool finished = false;
|
||||
if (version != MKTAG('V', '1', '.', '3')) {
|
||||
int32 currentFrame = 0;
|
||||
|
||||
|
@ -410,6 +411,7 @@ void Movies::playFlaMovie(const char *flaName) {
|
|||
break;
|
||||
}
|
||||
if (currentFrame == _flaHeaderData.numOfFrames) {
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
processFrame();
|
||||
|
@ -446,6 +448,7 @@ void Movies::playFlaMovie(const char *flaName) {
|
|||
}
|
||||
|
||||
_engine->_sound->stopSamples();
|
||||
return finished;
|
||||
}
|
||||
|
||||
void Movies::playSmkMovie(int index) {
|
||||
|
|
|
@ -101,8 +101,9 @@ public:
|
|||
/**
|
||||
* Play FLA movies
|
||||
* @param flaName FLA movie name
|
||||
* @return @c true if finished. @c false if aborted.
|
||||
*/
|
||||
void playFlaMovie(const char *flaName);
|
||||
bool playFlaMovie(const char *flaName);
|
||||
|
||||
void playSmkMovie(int index);
|
||||
};
|
||||
|
|
|
@ -336,6 +336,7 @@ void Redraw::processDrawListShadows(const DrawListStruct &drawCmd) {
|
|||
addRedrawArea(_engine->_interface->_clip);
|
||||
|
||||
_engine->_debugScene->drawClip(renderRect);
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
|
||||
void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw) {
|
||||
|
@ -348,7 +349,15 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
|
|||
|
||||
const IVec3 &delta = actor->pos() - _engine->_grid->_camera;
|
||||
Common::Rect renderRect;
|
||||
|
||||
if (actorIdx == OWN_ACTOR_SCENE_INDEX) {
|
||||
if (_engine->_actor->_cropBottomScreen) {
|
||||
_engine->_interface->_clip.bottom = _engine->_actor->_cropBottomScreen;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_engine->_renderer->renderIsoModel(delta.x, delta.y, delta.z, ANGLE_0, actor->_angle, ANGLE_0, _engine->_resources->_bodyData[actor->_entity], renderRect)) {
|
||||
_engine->_interface->resetClip();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -364,10 +373,6 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
|
|||
|
||||
_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
|
||||
|
||||
if (_engine->_actor->_cropBottomScreen) {
|
||||
_engine->_interface->_clip.bottom = _engine->_actor->_cropBottomScreen + 10;
|
||||
}
|
||||
|
||||
addRedrawArea(_engine->_interface->_clip);
|
||||
|
||||
if (actor->_staticFlags.bIsBackgrounded && bgRedraw) {
|
||||
|
@ -376,6 +381,7 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
|
|||
|
||||
_engine->_debugScene->drawClip(_engine->_interface->_clip);
|
||||
}
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
|
||||
void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgRedraw) {
|
||||
|
@ -399,14 +405,15 @@ void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgR
|
|||
renderRect.right = renderRect.left + spriteWidth;
|
||||
renderRect.bottom = renderRect.top + spriteHeight;
|
||||
|
||||
bool validClip;
|
||||
if (actor->_staticFlags.bUsesClipping) {
|
||||
const Common::Rect rect(_projPosScreen.x + actor->_cropLeft, _projPosScreen.y + actor->_cropTop, _projPosScreen.x + actor->_cropRight, _projPosScreen.y + actor->_cropBottom);
|
||||
_engine->_interface->setClip(rect);
|
||||
validClip = _engine->_interface->setClip(rect);
|
||||
} else {
|
||||
_engine->_interface->setClip(renderRect);
|
||||
validClip = _engine->_interface->setClip(renderRect);
|
||||
}
|
||||
|
||||
if (_engine->_interface->_clip.isValidRect()) {
|
||||
if (validClip) {
|
||||
_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
|
||||
|
||||
actor->_dynamicFlags.bIsVisible = 1;
|
||||
|
@ -434,6 +441,7 @@ void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgR
|
|||
}
|
||||
|
||||
_engine->_debugScene->drawClip(renderRect);
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,9 +469,7 @@ void Redraw::processDrawListExtras(const DrawListStruct &drawCmd) {
|
|||
_engine->_grid->drawSprite(renderRect.left, renderRect.top, spritePtr);
|
||||
}
|
||||
|
||||
_engine->_interface->setClip(renderRect);
|
||||
|
||||
if (_engine->_interface->_clip.isValidRect()) {
|
||||
if (_engine->_interface->setClip(renderRect)) {
|
||||
const int32 tmpX = (extra->pos.x + BRICK_HEIGHT) / BRICK_SIZE;
|
||||
const int32 tmpY = extra->pos.y / BRICK_HEIGHT;
|
||||
const int32 tmpZ = (extra->pos.z + BRICK_HEIGHT) / BRICK_SIZE;
|
||||
|
@ -473,6 +479,7 @@ void Redraw::processDrawListExtras(const DrawListStruct &drawCmd) {
|
|||
|
||||
// show clipping area
|
||||
//drawRectBorders(renderRect);
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,27 +487,13 @@ void Redraw::processDrawList(DrawListStruct *drawList, int32 drawListPos, bool b
|
|||
for (int32 pos = 0; pos < drawListPos; ++pos) {
|
||||
const DrawListStruct &drawCmd = drawList[pos];
|
||||
const uint32 flags = drawCmd.type;
|
||||
// Drawing actors
|
||||
if (flags < DrawListType::DrawShadows) {
|
||||
if (flags == 0) {
|
||||
processDrawListActors(drawCmd, bgRedraw);
|
||||
}
|
||||
}
|
||||
// Drawing shadows
|
||||
else if (flags == DrawListType::DrawShadows && !_engine->_actor->_cropBottomScreen) {
|
||||
if (flags == DrawListType::DrawObject3D) {
|
||||
processDrawListActors(drawCmd, bgRedraw);
|
||||
} else if (flags == DrawListType::DrawShadows && !_engine->_actor->_cropBottomScreen) {
|
||||
processDrawListShadows(drawCmd);
|
||||
}
|
||||
// Drawing unknown
|
||||
else if (flags < DrawListType::DrawActorSprites) {
|
||||
// TODO reverse this part of the code
|
||||
warning("Not yet reversed part of the rendering code: %u", flags);
|
||||
}
|
||||
// Drawing sprite actors, doors and entities
|
||||
else if (flags == DrawListType::DrawActorSprites) {
|
||||
} else if (flags == DrawListType::DrawActorSprites) {
|
||||
processDrawListActorSprites(drawCmd, bgRedraw);
|
||||
}
|
||||
// Drawing extras
|
||||
else if (flags == DrawListType::DrawExtras) {
|
||||
} else if (flags == DrawListType::DrawExtras) {
|
||||
processDrawListExtras(drawCmd);
|
||||
}
|
||||
|
||||
|
@ -575,6 +568,8 @@ void Redraw::renderOverlays() {
|
|||
_engine->_text->drawText(renderRect.left, renderRect.top, text);
|
||||
|
||||
addRedrawArea(_engine->_interface->_clip);
|
||||
|
||||
_engine->_interface->resetClip();
|
||||
break;
|
||||
}
|
||||
case OverlayType::koNumberRange: {
|
||||
|
@ -599,6 +594,7 @@ void Redraw::renderOverlays() {
|
|||
_engine->_text->drawText(renderRect.left, renderRect.top, text);
|
||||
|
||||
addRedrawArea(_engine->_interface->_clip);
|
||||
_engine->_interface->resetClip();
|
||||
break;
|
||||
}
|
||||
case OverlayType::koInventoryItem: {
|
||||
|
@ -614,6 +610,7 @@ void Redraw::renderOverlays() {
|
|||
_engine->_menu->drawRectBorders(rect);
|
||||
addRedrawArea(rect);
|
||||
_engine->_gameState->initEngineProjections();
|
||||
_engine->_interface->resetClip();
|
||||
break;
|
||||
}
|
||||
case OverlayType::koText: {
|
||||
|
@ -638,6 +635,7 @@ void Redraw::renderOverlays() {
|
|||
_engine->_text->drawText(renderRect.left, renderRect.top, text);
|
||||
|
||||
addRedrawArea(_engine->_interface->_clip);
|
||||
_engine->_interface->resetClip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -743,9 +741,10 @@ void Redraw::drawBubble(int32 actorIdx) {
|
|||
renderRect.right = spriteWidth + renderRect.left - 1;
|
||||
renderRect.bottom = spriteHeight + renderRect.top - 1;
|
||||
|
||||
_engine->_interface->setClip(renderRect);
|
||||
_engine->_grid->drawSprite(renderRect.left, renderRect.top, spritePtr);
|
||||
_engine->_interface->resetClip();
|
||||
if (_engine->_interface->setClip(renderRect)) {
|
||||
_engine->_grid->drawSprite(renderRect.left, renderRect.top, spritePtr);
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
}
|
||||
|
||||
void Redraw::zoomScreenScale() {
|
||||
|
|
|
@ -80,14 +80,23 @@ struct DrawListStruct {
|
|||
}
|
||||
};
|
||||
|
||||
#define TYPE_OBJ_SHIFT (10)
|
||||
#define TYPE_OBJ_FIRST (1 << TYPE_OBJ_SHIFT) // 1024
|
||||
#define NUM_OBJ_MASK (TYPE_OBJ_FIRST - 1)
|
||||
|
||||
class TwinEEngine;
|
||||
class Redraw {
|
||||
private:
|
||||
TwinEEngine *_engine;
|
||||
enum DrawListType {
|
||||
DrawActorSprites = 0x1000,
|
||||
DrawExtras = 0x1800,
|
||||
DrawShadows = 0xC00
|
||||
DrawObject3D = (0 << TYPE_OBJ_SHIFT),
|
||||
DrawFlagRed = (1 << TYPE_OBJ_SHIFT),
|
||||
DrawFlagYellow = (2 << TYPE_OBJ_SHIFT),
|
||||
DrawShadows = (3 << TYPE_OBJ_SHIFT),
|
||||
DrawActorSprites = (4 << TYPE_OBJ_SHIFT),
|
||||
DrawZoneDec = (5 << TYPE_OBJ_SHIFT),
|
||||
DrawExtras = (6 << TYPE_OBJ_SHIFT),
|
||||
DrawPrimitive = (7 << TYPE_OBJ_SHIFT)
|
||||
};
|
||||
|
||||
Common::Rect _currentRedrawList[300];
|
||||
|
|
|
@ -383,16 +383,46 @@ static FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
|
|||
return x < a ? a : (x > b ? b : x);
|
||||
}
|
||||
|
||||
void Renderer::computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices) {
|
||||
bool Renderer::computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices) {
|
||||
uint8 vertexParam1 = vertices[numVertices - 1].colorIndex;
|
||||
int16 currentVertexX = vertices[numVertices - 1].x;
|
||||
int16 currentVertexY = vertices[numVertices - 1].y;
|
||||
const int16 *polyTabBegin = _polyTab;
|
||||
const int16 *polyTabEnd = &_polyTab[_polyTabSize - 1];
|
||||
const int16 *polyTab2Begin = _colorProgressionBuffer;
|
||||
const int16 *polyTab2End = &_colorProgressionBuffer[_polyTabSize - 1];
|
||||
const int16 *colProgressBufStart = _colorProgressionBuffer;
|
||||
const int16 *colProgressBufEnd = &_colorProgressionBuffer[_polyTabSize - 1];
|
||||
const int screenHeight = _engine->height();
|
||||
|
||||
const Common::Rect &clip = _engine->_interface->_clip;
|
||||
if (!clip.isEmpty()) {
|
||||
int32 vleft;
|
||||
int32 vright;
|
||||
int32 vtop;
|
||||
int32 vbottom;
|
||||
|
||||
vleft = vtop = SCENE_SIZE_MAX;
|
||||
vright = vbottom = SCENE_SIZE_MIN;
|
||||
|
||||
for (int32 i = 0; i < numVertices; i++) {
|
||||
if (vertices[i].x < vleft)
|
||||
vleft = vertices[i].x;
|
||||
if (vertices[i].x > vright)
|
||||
vright = vertices[i].x;
|
||||
if (vertices[i].y < vtop)
|
||||
vtop = vertices[i].y;
|
||||
if (vertices[i].y > vbottom)
|
||||
vbottom = vertices[i].y;
|
||||
}
|
||||
// no vertices
|
||||
if (vtop > vbottom) {
|
||||
return false;
|
||||
}
|
||||
if (vright < clip.left - 1 || vleft > clip.right + 1 || vbottom < clip.top - 1 || vtop > clip.bottom + 1) {
|
||||
debug(10, "Clipped %i:%i:%i:%i, clip rect(%i:%i:%i:%i)", vleft, vtop, vright, vbottom, clip.left, clip.top, clip.right, clip.bottom);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 nVertex = 0; nVertex < numVertices; nVertex++) {
|
||||
const int16 oldVertexY = currentVertexY;
|
||||
const int16 oldVertexX = currentVertexX;
|
||||
|
@ -449,7 +479,7 @@ void Renderer::computePolygons(int16 polyRenderType, const Vertex *vertices, int
|
|||
int16 *outPtr2 = &_colorProgressionBuffer[polyTabIndex];
|
||||
|
||||
for (int16 i = 0; i < vsize + 2; i++) {
|
||||
if (outPtr2 >= polyTab2Begin && outPtr2 <= polyTab2End) {
|
||||
if (outPtr2 >= colProgressBufStart && outPtr2 <= colProgressBufEnd) {
|
||||
*outPtr2 = cvalue;
|
||||
}
|
||||
outPtr2 += direction;
|
||||
|
@ -457,6 +487,7 @@ void Renderer::computePolygons(int16 polyRenderType, const Vertex *vertices, int
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::renderPolygonsCopper(int vtop, int32 vsize, uint16 color) const {
|
||||
|
@ -954,10 +985,10 @@ void Renderer::renderPolygonsSimplified(int vtop, int32 vsize, uint16 color) con
|
|||
}
|
||||
|
||||
void Renderer::renderPolygons(const CmdRenderPolygon &polygon, Vertex *vertices, int vtop, int vbottom) {
|
||||
computePolygons(polygon.renderType, vertices, polygon.numVertices);
|
||||
|
||||
const int32 vsize = vbottom - vtop + 1;
|
||||
fillVertices(vtop, vsize, polygon.renderType, polygon.colorIndex);
|
||||
if (computePolygons(polygon.renderType, vertices, polygon.numVertices)) {
|
||||
const int32 vsize = vbottom - vtop + 1;
|
||||
fillVertices(vtop, vsize, polygon.renderType, polygon.colorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::fillVertices(int vtop, int32 vsize, uint8 renderType, uint16 color) {
|
||||
|
@ -1562,6 +1593,7 @@ void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 ang
|
|||
} else {
|
||||
renderIsoModel(0, y, 0, ANGLE_0, angle, ANGLE_0, bodyData, dummy);
|
||||
}
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
|
||||
void Renderer::renderInventoryItem(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 param) {
|
||||
|
|
|
@ -194,7 +194,7 @@ private:
|
|||
void renderPolygonsDither(int vtop, int32 vsize) const;
|
||||
void renderPolygonsMarble(int vtop, int32 vsize, uint16 color) const;
|
||||
void renderPolygonsSimplified(int vtop, int32 vsize, uint16 color) const;
|
||||
void computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices);
|
||||
bool computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices);
|
||||
|
||||
const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
|
||||
uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
* @param index \a RESS.HQR entry index (starting from 0)
|
||||
* @param paletteIndex \a RESS.HQR entry index of the palette for the given image. This is often the @c index + 1
|
||||
* @param seconds number of seconds to delay
|
||||
* @return @c true if aborted
|
||||
*/
|
||||
bool loadImageDelay(TwineImage image, int32 seconds);
|
||||
|
||||
|
|
|
@ -445,6 +445,7 @@ void GameState::processFoundItem(InventoryItems item) {
|
|||
_engine->_text->stopVox(_engine->_text->_currDialTextEntry);
|
||||
|
||||
_engine->_scene->_sceneHero->_animTimerData = tmpAnimTimer;
|
||||
_engine->_interface->resetClip();
|
||||
}
|
||||
|
||||
void GameState::processGameChoices(TextId choiceIdx) {
|
||||
|
|
|
@ -92,7 +92,7 @@ struct ConfigFile {
|
|||
bool Debug = false;
|
||||
/** Type of music file to be used */
|
||||
MidiFileType MidiType = MIDIFILE_NONE;
|
||||
/** *Game version */
|
||||
/** Game version */
|
||||
int32 Version = EUROPE_VERSION;
|
||||
/** If you want to use the LBA CD or not */
|
||||
int32 UseCD = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue