mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
38bead0c37
Most of them were due to setting -1 to unsigned values Else it was bogus unintialized values
219 lines
6.2 KiB
C++
219 lines
6.2 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
|
|
#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
|