Initial commit
This commit is contained in:
217
engines/cryomni3d/wam_parser.cpp
Normal file
217
engines/cryomni3d/wam_parser.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "cryomni3d/wam_parser.h"
|
||||
#include "cryomni3d/omni3d.h"
|
||||
|
||||
namespace CryOmni3D {
|
||||
|
||||
void WAMParser::loadStream(Common::ReadStream &stream) {
|
||||
char str[16];
|
||||
|
||||
_places.clear();
|
||||
|
||||
// These are unused and unknown values
|
||||
(void) stream.readByte();
|
||||
(void) stream.readByte();
|
||||
(void) stream.read(str, 16);
|
||||
(void) stream.readUint32LE();
|
||||
|
||||
uint nPlaces = stream.readByte();
|
||||
//debug("nPlaces = %u", nPlaces);
|
||||
for (uint i = 0; i < nPlaces; i++) {
|
||||
Place place;
|
||||
uint nWarps = stream.readByte();
|
||||
//debug("nWarps = %u", nWarps);
|
||||
for (uint k = 0; k < 8; k++) {
|
||||
stream.read(str, 16);
|
||||
//debug("Warp: %.16s", str);
|
||||
if (nWarps > 0) {
|
||||
place.warps.push_back(str);
|
||||
nWarps--;
|
||||
}
|
||||
}
|
||||
place.placeId = stream.readUint32LE();
|
||||
// Normally placeId should be unique but it's not always the case
|
||||
// In original game the last place is considered but we try to be efficient and stop at the first place in findPlaceById
|
||||
// Let's be a little less efficient at startup by removing duplicates
|
||||
Place *oldPlace = findPlaceById_(place.placeId);
|
||||
if (oldPlace) {
|
||||
debug("Found duplicate place %u at %u, removing it", place.placeId,
|
||||
(uint)(oldPlace - _places.begin()));
|
||||
_places.erase(oldPlace);
|
||||
}
|
||||
//debug("nPlaceId = %u", place.placeId);
|
||||
(void) stream.readUint32LE();
|
||||
uint nTransitions = stream.readByte();
|
||||
//debug("nTransitions = %u", nTransitions);
|
||||
uint nZones = stream.readByte();
|
||||
//debug("nZones = %u", nZones);
|
||||
for (uint j = 0; j < nTransitions; j++) {
|
||||
Transition trans;
|
||||
(void) stream.readUint32LE();
|
||||
uint nAnimations = stream.readByte();
|
||||
for (uint k = 0; k < 8; k++) {
|
||||
stream.read(str, 16);
|
||||
if (nAnimations > 0) {
|
||||
trans.animations.push_back(str);
|
||||
nAnimations--;
|
||||
}
|
||||
}
|
||||
(void) stream.readUint32LE();
|
||||
trans.dstId = stream.readUint32LE();
|
||||
// Unused byte
|
||||
(void) stream.readByte();
|
||||
trans.srcAlpha = stream.readDoubleLE();
|
||||
trans.srcBeta = stream.readDoubleLE();
|
||||
trans.dstAlpha = stream.readDoubleLE();
|
||||
trans.dstBeta = stream.readDoubleLE();
|
||||
place.transitions.push_back(trans);
|
||||
}
|
||||
for (uint j = 0; j < nZones; j++) {
|
||||
Zone zone;
|
||||
zone.zoneId = stream.readSint32LE();
|
||||
zone.rct.left = stream.readSint32LE();
|
||||
zone.rct.top = stream.readSint32LE();
|
||||
zone.rct.setWidth(stream.readSint32LE());
|
||||
zone.rct.setHeight(stream.readSint32LE());
|
||||
zone.action = stream.readSint32LE();
|
||||
place.zones.push_back(zone);
|
||||
}
|
||||
_places.push_back(place);
|
||||
}
|
||||
}
|
||||
|
||||
const Place *WAMParser::findPlaceById(uint placeId) const {
|
||||
for (Common::Array<Place>::const_iterator it = _places.begin(); it != _places.end(); it++) {
|
||||
if (it->placeId == placeId) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Place *WAMParser::findPlaceById_(uint placeId) {
|
||||
for (Common::Array<Place>::iterator it = _places.begin(); it != _places.end(); it++) {
|
||||
if (it->placeId == placeId) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Place::setupWarpConstraints(Omni3DManager &omni3d) const {
|
||||
int16 iAlphaMin = -32768, iAlphaMax = 32767;
|
||||
bool alphaConstraint = false;
|
||||
|
||||
omni3d.clearConstraints();
|
||||
for (Common::Array<Zone>::const_iterator it = zones.begin(); it != zones.end(); it++) {
|
||||
if (it->action == 100000) {
|
||||
int16 aMin = it->rct.left;
|
||||
if (aMin < 0) {
|
||||
aMin += 2048;
|
||||
}
|
||||
int16 aMax = aMin + it->rct.width();
|
||||
if (aMax > 2048) {
|
||||
aMax -= 2048;
|
||||
}
|
||||
// debug("x1=%d x2=%d", aMin, aMax);
|
||||
if (aMax < aMin) {
|
||||
int16 tmp = aMax;
|
||||
aMax = aMin;
|
||||
aMin = tmp;
|
||||
}
|
||||
if (alphaConstraint) {
|
||||
if (aMin < iAlphaMax && aMax > iAlphaMax) {
|
||||
iAlphaMax = aMax;
|
||||
}
|
||||
if (aMin < iAlphaMin && aMax > iAlphaMin) {
|
||||
iAlphaMin = aMin;
|
||||
}
|
||||
} else {
|
||||
iAlphaMin = aMin;
|
||||
iAlphaMax = aMax;
|
||||
alphaConstraint = true;
|
||||
}
|
||||
} else if (it->action == 200000) {
|
||||
double betaMin = ((int)it->rct.bottom - (768 / 2)) / 768. * M_PI;
|
||||
omni3d.setBetaMinConstraint(betaMin);
|
||||
} else if (it->action == 300000) {
|
||||
double betaMax = ((int)it->rct.top - (768 / 2)) / 768. * M_PI;
|
||||
omni3d.setBetaMaxConstraint(betaMax);
|
||||
}
|
||||
}
|
||||
if (alphaConstraint) {
|
||||
double alphaMin = (1 - iAlphaMin / 2048.) * M_PI * 2.;
|
||||
alphaMin += 75. / 180. * M_PI_2;
|
||||
if (alphaMin < 0.) {
|
||||
alphaMin += M_PI * 2.;
|
||||
} else if (alphaMin > M_PI * 2.) {
|
||||
alphaMin -= M_PI * 2.;
|
||||
}
|
||||
double alphaMax = (1 - iAlphaMax / 2048.) * M_PI * 2.;
|
||||
alphaMax -= 75. / 180. * M_PI_2;
|
||||
if (alphaMax < 0.) {
|
||||
alphaMax += M_PI * 2.;
|
||||
} else if (alphaMax > M_PI * 2.) {
|
||||
alphaMax -= M_PI * 2.;
|
||||
}
|
||||
omni3d.setAlphaConstraints(alphaMin, alphaMax);
|
||||
}
|
||||
}
|
||||
|
||||
uint Place::hitTest(const Common::Point &point) const {
|
||||
for (Common::Array<Zone>::const_iterator it = zones.begin(); it != zones.end(); it++) {
|
||||
if (it->action) {
|
||||
if (it->rct.contains(point)) {
|
||||
return it->action;
|
||||
}
|
||||
if (it->rct.left < 0) {
|
||||
Common::Rect rct = it->rct;
|
||||
rct.translate(2048, 0);
|
||||
if (rct.contains(point)) {
|
||||
return it->action;
|
||||
}
|
||||
} else if (it->rct.right > 2048) {
|
||||
Common::Rect rct = it->rct;
|
||||
rct.translate(-2048, 0);
|
||||
if (rct.contains(point)) {
|
||||
return it->action;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Transition *Place::findTransition(uint nextPlaceId) const {
|
||||
for (Common::Array<Transition>::const_iterator it = transitions.begin(); it != transitions.end();
|
||||
it++) {
|
||||
if (it->dstId == nextPlaceId) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // End of namespace CryOmni3D
|
||||
Reference in New Issue
Block a user