2003-08-15 18:00:22 +00:00
|
|
|
// Residual - Virtual machine to run LucasArts' 3D adventure games
|
2004-02-24 22:43:32 +00:00
|
|
|
// Copyright (C) 2003-2004 The ScummVM-Residual Team (www.scummvm.org)
|
2003-08-15 18:00:22 +00:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library 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
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
2003-08-24 17:56:03 +00:00
|
|
|
#include "stdafx.h"
|
2003-08-15 19:41:26 +00:00
|
|
|
#include "scene.h"
|
|
|
|
#include "textsplit.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "bitmap.h"
|
|
|
|
#include "colormap.h"
|
|
|
|
#include "vector3d.h"
|
2003-08-15 18:00:22 +00:00
|
|
|
#include <SDL.h>
|
|
|
|
#include <cmath>
|
2003-08-30 17:58:33 +00:00
|
|
|
#include "screen.h"
|
2004-01-23 11:10:59 +00:00
|
|
|
#include "driver_gl.h"
|
2003-08-15 18:00:22 +00:00
|
|
|
|
|
|
|
Scene::Scene(const char *name, const char *buf, int len) :
|
2004-02-24 22:43:32 +00:00
|
|
|
name_(name) {
|
|
|
|
TextSplitter ts(buf, len);
|
|
|
|
char tempBuf[256];
|
|
|
|
|
|
|
|
ts.expectString("section: colormaps");
|
|
|
|
ts.scanString(" numcolormaps %d", 1, &numCmaps_);
|
|
|
|
cmaps_ = new ResPtr<CMap>[numCmaps_];
|
|
|
|
char cmap_name[256];
|
|
|
|
for (int i = 0; i < numCmaps_; i++) {
|
|
|
|
ts.scanString(" colormap %256s", 1, cmap_name);
|
|
|
|
cmaps_[i] = ResourceLoader::instance()->loadColormap(cmap_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
ts.expectString("section: setups");
|
|
|
|
ts.scanString(" numsetups %d", 1, &numSetups_);
|
|
|
|
setups_ = new Setup[numSetups_];
|
|
|
|
for (int i = 0; i < numSetups_; i++)
|
|
|
|
setups_[i].load(ts);
|
|
|
|
currSetup_ = setups_;
|
|
|
|
|
|
|
|
numSectors_ = -1;
|
|
|
|
numLights_ = -1;
|
|
|
|
lights_ = NULL;
|
|
|
|
sectors_ = NULL;
|
|
|
|
// Lights are optional
|
|
|
|
if (ts.eof())
|
|
|
|
return;
|
|
|
|
|
|
|
|
ts.expectString("section: lights");
|
|
|
|
ts.scanString(" numlights %d", 1, &numLights_);
|
|
|
|
lights_ = new Light[numLights_];
|
|
|
|
for (int i = 0; i < numLights_; i++)
|
|
|
|
lights_[i].load(ts);
|
|
|
|
|
|
|
|
// Calculate the number of sectors
|
|
|
|
ts.expectString("section: sectors");
|
|
|
|
if (ts.eof()) // Sectors are optional, but section: doesn't seem to be
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Sector NAMES can be null, but ts doesn't seem flexible enough to allow this
|
|
|
|
if (strlen(ts.currentLine()) > strlen(" sector"))
|
|
|
|
ts.scanString(" sector %256s", 1, tempBuf);
|
|
|
|
else {
|
|
|
|
ts.nextLine();
|
|
|
|
strcpy(tempBuf, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
ts.scanString(" id %d", 1, &numSectors_);
|
2004-03-23 11:22:22 +00:00
|
|
|
numSectors_++;
|
2004-02-24 22:43:32 +00:00
|
|
|
sectors_ = new Sector[numSectors_];
|
|
|
|
// FIXME: This would be nicer if we could rewind the textsplitter
|
|
|
|
// stream
|
|
|
|
sectors_[0].load0(ts, tempBuf, numSectors_);
|
|
|
|
for (int i = 1; i < numSectors_; i++)
|
|
|
|
sectors_[i].load(ts);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Scene::~Scene() {
|
2004-02-24 22:43:32 +00:00
|
|
|
delete [] cmaps_;
|
|
|
|
delete [] setups_;
|
|
|
|
if (lights_)
|
|
|
|
delete [] lights_;
|
|
|
|
if (sectors_)
|
2004-03-22 11:23:37 +00:00
|
|
|
delete [] sectors_;
|
|
|
|
for (StateList::iterator i = states_.begin();
|
|
|
|
i != states_.end(); i++)
|
|
|
|
delete (*i);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::Setup::load(TextSplitter &ts) {
|
2004-02-24 22:43:32 +00:00
|
|
|
char buf[256];
|
2003-08-17 00:12:02 +00:00
|
|
|
|
2004-02-24 22:43:32 +00:00
|
|
|
ts.scanString(" setup %256s", 1, buf);
|
|
|
|
name_ = buf;
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2004-02-24 22:43:32 +00:00
|
|
|
ts.scanString(" background %256s", 1, buf);
|
|
|
|
bkgnd_bm_ = ResourceLoader::instance()->loadBitmap(buf);
|
2003-08-18 13:59:33 +00:00
|
|
|
|
2004-02-24 22:43:32 +00:00
|
|
|
// ZBuffer is optional
|
|
|
|
if (!ts.checkString("zbuffer")) {
|
|
|
|
bkgnd_zbm_ = NULL;
|
|
|
|
} else {
|
|
|
|
ts.scanString(" zbuffer %256s", 1, buf);
|
|
|
|
bkgnd_zbm_ = ResourceLoader::instance()->loadBitmap(buf);
|
|
|
|
}
|
2003-08-15 18:00:22 +00:00
|
|
|
|
2004-02-24 22:43:32 +00:00
|
|
|
ts.scanString(" position %f %f %f", 3, &pos_.x(), &pos_.y(), &pos_.z());
|
|
|
|
ts.scanString(" interest %f %f %f", 3, &interest_.x(), &interest_.y(),
|
2003-08-15 18:00:22 +00:00
|
|
|
&interest_.z());
|
2004-02-24 22:43:32 +00:00
|
|
|
ts.scanString(" roll %f", 1, &roll_);
|
|
|
|
ts.scanString(" fov %f", 1, &fov_);
|
|
|
|
ts.scanString(" nclip %f", 1, &nclip_);
|
|
|
|
ts.scanString(" fclip %f", 1, &fclip_);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::Light::load(TextSplitter &ts) {
|
2004-02-24 22:43:32 +00:00
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
// Light names can be null, but ts doesn't seem flexible enough to allow this
|
|
|
|
if (strlen(ts.currentLine()) > strlen(" light"))
|
|
|
|
ts.scanString(" light %256s", 1, buf);
|
|
|
|
else {
|
|
|
|
ts.nextLine();
|
|
|
|
strcpy(buf, "");
|
|
|
|
}
|
|
|
|
name_ = buf;
|
|
|
|
|
|
|
|
ts.scanString(" type %256s", 1, buf);
|
|
|
|
type_ = buf;
|
|
|
|
|
|
|
|
ts.scanString(" position %f %f %f", 3, &pos_.x(), &pos_.y(), &pos_.z());
|
|
|
|
ts.scanString(" direction %f %f %f", 3, &dir_.x(), &dir_.y(), &dir_.z());
|
|
|
|
ts.scanString(" intensity %f", 1, &intensity_);
|
|
|
|
ts.scanString(" umbraangle %f", 1, &umbraangle_);
|
|
|
|
ts.scanString(" penumbraangle %f", 1, &penumbraangle_);
|
|
|
|
ts.scanString(" color %d %d %d", 3, &color_.red(), &color_.green(), &color_.blue());
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::Setup::setupCamera() const {
|
2004-03-26 04:42:27 +00:00
|
|
|
// Ignore nclip_ and fclip_ for now. This fixes:
|
|
|
|
// (a) Nothing was being displayed in the Land of the Living
|
|
|
|
// diner because lr.set set nclip to 0.
|
|
|
|
// (b) The zbuffers for setups with different nclip or
|
|
|
|
// fclip values. If it turns out that the clipping planes
|
|
|
|
// are important at some point, we'll need to modify the
|
|
|
|
// zbuffer transformation in bitmap.cpp to take nclip_ and
|
|
|
|
// fclip_ into account.
|
|
|
|
g_driver->setupCamera(fov_, 0.01f, 3276.8f, roll_);
|
2004-02-24 22:43:32 +00:00
|
|
|
g_driver->positionCamera(pos_, interest_);
|
2003-08-15 18:00:22 +00:00
|
|
|
}
|
2003-08-30 17:58:33 +00:00
|
|
|
|
2004-02-24 22:43:32 +00:00
|
|
|
void Scene::setSetup(int num) {
|
2003-08-30 17:58:33 +00:00
|
|
|
currSetup_ = setups_ + num;
|
2003-09-21 09:51:59 +00:00
|
|
|
|
2004-03-24 12:20:46 +00:00
|
|
|
if (! SCREENBLOCKS_GLOBAL)
|
2003-09-21 09:51:59 +00:00
|
|
|
return;
|
2003-08-30 17:58:33 +00:00
|
|
|
if(currSetup_->bkgnd_zbm_)
|
|
|
|
screenBlocksInit( currSetup_->bkgnd_zbm_->getData() );
|
|
|
|
else
|
|
|
|
screenBlocksInitEmpty();
|
|
|
|
}
|
2004-03-22 11:23:37 +00:00
|
|
|
|
|
|
|
void Scene::drawBitmaps(ObjectState::Position stage) {
|
|
|
|
for (StateList::iterator i = states_.begin(); i != states_.end();
|
|
|
|
i++) {
|
|
|
|
if ((*i)->pos() == stage && currSetup_ == setups_ + (*i)->setupID())
|
|
|
|
(*i)->draw();
|
|
|
|
}
|
|
|
|
}
|
2004-03-23 10:38:02 +00:00
|
|
|
|
2004-03-25 09:33:17 +00:00
|
|
|
Sector *Scene::findPointSector(Vector3d p, int flags) {
|
|
|
|
for (int i = 0; i < numSectors_; i++) {
|
|
|
|
Sector *sector = sectors_ + i;
|
|
|
|
if ((sector->type() & flags) && sector->visible() &&
|
|
|
|
sector->isPointInSector(p))
|
|
|
|
return sector;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-03-23 10:38:02 +00:00
|
|
|
ObjectState *Scene::findState(const char *filename) {
|
|
|
|
for (StateList::iterator i = states_.begin(); i != states_.end();
|
|
|
|
i++) {
|
|
|
|
if (strcmp((*i)->bitmapFilename(), filename) == 0)
|
|
|
|
return *i;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|