Initial commit
This commit is contained in:
1098
engines/tetraedge/te/micropather.cpp
Normal file
1098
engines/tetraedge/te/micropather.cpp
Normal file
File diff suppressed because it is too large
Load Diff
473
engines/tetraedge/te/micropather.h
Normal file
473
engines/tetraedge/te/micropather.h
Normal file
@@ -0,0 +1,473 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This is a lightly modified version of MicroPather, from
|
||||
github.com/leethomason/MicroPather. Modifications were made to fit with
|
||||
ScummVM coding style and APIs.
|
||||
|
||||
The original copyright message is:
|
||||
|
||||
-------
|
||||
|
||||
Copyright (c) 2000-2013 Lee Thomason (www.grinninglizard.com)
|
||||
Micropather
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TETRAEDGE_TE_MICROPATHER
|
||||
#define TETRAEDGE_TE_MICROPATHER
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/util.h"
|
||||
#include "common/types.h"
|
||||
#include "math/utils.h"
|
||||
|
||||
|
||||
/** @mainpage MicroPather
|
||||
|
||||
MicroPather is a path finder and A* solver (astar or a-star) written in platform independent
|
||||
C++ that can be easily integrated into existing code. MicroPather focuses on being a path
|
||||
finding engine for video games but is a generic A* solver. MicroPather is open source, with
|
||||
a license suitable for open source or commercial use.
|
||||
*/
|
||||
|
||||
namespace Tetraedge
|
||||
{
|
||||
|
||||
namespace micropather
|
||||
{
|
||||
|
||||
typedef uintptr MP_UPTR;
|
||||
|
||||
/**
|
||||
Used to pass the cost of states from the cliet application to MicroPather. This
|
||||
structure is copied in a vector.
|
||||
|
||||
@sa AdjacentCost
|
||||
*/
|
||||
struct StateCost
|
||||
{
|
||||
void* state; ///< The state as a void*
|
||||
float cost; ///< The cost to the state. Use FLT_MAX for infinite cost.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A pure abstract class used to define a set of callbacks.
|
||||
The client application inherits from
|
||||
this class, and the methods will be called when MicroPather::Solve() is invoked.
|
||||
|
||||
The notion of a "state" is very important. It must have the following properties:
|
||||
- Unique
|
||||
- Unchanging (unless MicroPather::Reset() is called)
|
||||
|
||||
If the client application represents states as objects, then the state is usually
|
||||
just the object cast to a void*. If the client application sees states as numerical
|
||||
values, (x,y) for example, then state is an encoding of these values. MicroPather
|
||||
never interprets or modifies the value of state.
|
||||
*/
|
||||
class Graph
|
||||
{
|
||||
public:
|
||||
virtual ~Graph() {}
|
||||
|
||||
/**
|
||||
Return the least possible cost between 2 states. For example, if your pathfinding
|
||||
is based on distance, this is simply the straight distance between 2 points on the
|
||||
map. If you pathfinding is based on minimum time, it is the minimal travel time
|
||||
between 2 points given the best possible terrain.
|
||||
*/
|
||||
virtual float LeastCostEstimate( void* stateStart, void* stateEnd ) = 0;
|
||||
|
||||
/**
|
||||
Return the exact cost from the given state to all its neighboring states. This
|
||||
may be called multiple times, or cached by the solver. It *must* return the same
|
||||
exact values for every call to MicroPather::Solve(). It should generally be a simple,
|
||||
fast function with no callbacks into the pather.
|
||||
*/
|
||||
virtual void AdjacentCost( void* state, Common::Array< micropather::StateCost > *adjacent ) = 0;
|
||||
|
||||
/**
|
||||
This function is only used in DEBUG mode - it dumps output to stdout. Since void*
|
||||
aren't really human readable, normally you print out some concise info (like "(1,2)")
|
||||
without an ending newline.
|
||||
*/
|
||||
virtual void PrintStateInfo( void* state ) = 0;
|
||||
};
|
||||
|
||||
|
||||
class PathNode;
|
||||
|
||||
struct NodeCost
|
||||
{
|
||||
PathNode* node;
|
||||
float cost;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Every state (void*) is represented by a PathNode in MicroPather. There
|
||||
can only be one PathNode for a given state.
|
||||
*/
|
||||
class PathNode
|
||||
{
|
||||
public:
|
||||
void Init( unsigned _frame,
|
||||
void* _state,
|
||||
float _costFromStart,
|
||||
float _estToGoal,
|
||||
PathNode* _parent );
|
||||
|
||||
void Clear();
|
||||
void InitSentinel() {
|
||||
Clear();
|
||||
Init( 0, 0, FLT_MAX, FLT_MAX, 0 );
|
||||
prev = next = this;
|
||||
}
|
||||
|
||||
void *state; // the client state
|
||||
float costFromStart; // exact
|
||||
float estToGoal; // estimated
|
||||
float totalCost; // could be a function, but save some math.
|
||||
PathNode* parent; // the parent is used to reconstruct the path
|
||||
unsigned frame; // unique id for this path, so the solver can distinguish
|
||||
// correct from stale values
|
||||
|
||||
int numAdjacent; // -1 is unknown & needs to be queried
|
||||
int cacheIndex; // position in cache
|
||||
|
||||
PathNode *child[2]; // Binary search in the hash table. [left, right]
|
||||
PathNode *next, *prev; // used by open queue
|
||||
|
||||
bool inOpen;
|
||||
bool inClosed;
|
||||
|
||||
void Unlink() {
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
next = prev = 0;
|
||||
}
|
||||
void AddBefore( PathNode* addThis ) {
|
||||
addThis->next = this;
|
||||
addThis->prev = prev;
|
||||
prev->next = addThis;
|
||||
prev = addThis;
|
||||
}
|
||||
#ifdef TETRAEDGE_MICROPATHER_DEBUG
|
||||
void CheckList()
|
||||
{
|
||||
MPASSERT( totalCost == FLT_MAX );
|
||||
for( PathNode* it = next; it != this; it=it->next ) {
|
||||
MPASSERT( it->prev == this || it->totalCost >= it->prev->totalCost );
|
||||
MPASSERT( it->totalCost <= it->next->totalCost );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CalcTotalCost() {
|
||||
if ( costFromStart < FLT_MAX && estToGoal < FLT_MAX )
|
||||
totalCost = costFromStart + estToGoal;
|
||||
else
|
||||
totalCost = FLT_MAX;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void operator=( const PathNode& );
|
||||
};
|
||||
|
||||
|
||||
/* Memory manager for the PathNodes. */
|
||||
class PathNodePool
|
||||
{
|
||||
public:
|
||||
PathNodePool( unsigned allocate, unsigned typicalAdjacent );
|
||||
~PathNodePool();
|
||||
|
||||
// Free all the memory except the first block. Resets all memory.
|
||||
void Clear();
|
||||
|
||||
// Essentially:
|
||||
// pNode = Find();
|
||||
// if ( !pNode )
|
||||
// pNode = New();
|
||||
//
|
||||
// Get the PathNode associated with this state. If the PathNode already
|
||||
// exists (allocated and is on the current frame), it will be returned.
|
||||
// Else a new PathNode is allocated and returned. The returned object
|
||||
// is always fully initialized.
|
||||
//
|
||||
// NOTE: if the pathNode exists (and is current) all the initialization
|
||||
// parameters are ignored.
|
||||
PathNode* GetPathNode( unsigned frame,
|
||||
void* _state,
|
||||
float _costFromStart,
|
||||
float _estToGoal,
|
||||
PathNode* _parent );
|
||||
|
||||
// Get a pathnode that is already in the pool.
|
||||
PathNode* FetchPathNode( void* state );
|
||||
|
||||
// Store stuff in cache
|
||||
bool PushCache( const NodeCost* nodes, int nNodes, int* start );
|
||||
|
||||
// Get neighbors from the cache
|
||||
// Note - always access this with an offset. Can get re-allocated.
|
||||
void GetCache( int start, int nNodes, NodeCost* nodes );
|
||||
|
||||
// Return all the allocated states. Useful for visuallizing what
|
||||
// the pather is doing.
|
||||
void AllStates( unsigned frame, Common::Array< void* >* stateVec );
|
||||
|
||||
private:
|
||||
struct Block
|
||||
{
|
||||
Block* nextBlock;
|
||||
PathNode pathNode[1];
|
||||
};
|
||||
|
||||
unsigned Hash( void* voidval );
|
||||
unsigned HashSize() const { return 1<<hashShift; }
|
||||
unsigned HashMask() const { return ((1<<hashShift)-1); }
|
||||
void AddPathNode( unsigned key, PathNode* p );
|
||||
Block* NewBlock();
|
||||
PathNode* Alloc();
|
||||
|
||||
PathNode** hashTable;
|
||||
Block* firstBlock;
|
||||
Block* blocks;
|
||||
|
||||
NodeCost* cache;
|
||||
int cacheCap;
|
||||
int cacheSize;
|
||||
|
||||
PathNode freeMemSentinel;
|
||||
unsigned allocate; // how big a block of pathnodes to allocate at once
|
||||
unsigned nAllocated; // number of pathnodes allocated (from Alloc())
|
||||
unsigned nAvailable; // number available for allocation
|
||||
|
||||
unsigned hashShift;
|
||||
unsigned totalCollide;
|
||||
};
|
||||
|
||||
|
||||
/* Used to cache results of paths. Much, much faster
|
||||
to return an existing solution than to calculate
|
||||
a new one. A post on this is here:
|
||||
https://web.archive.org/web/20170714084918/http://grinninglizard.com/altera/programming/a-path-caching-2/
|
||||
*/
|
||||
class PathCache
|
||||
{
|
||||
public:
|
||||
struct Item {
|
||||
// The key:
|
||||
void* start;
|
||||
void* end;
|
||||
|
||||
bool KeyEqual( const Item& item ) const { return start == item.start && end == item.end; }
|
||||
bool Empty() const { return start == 0 && end == 0; }
|
||||
|
||||
// Data:
|
||||
void* next;
|
||||
float cost; // from 'start' to 'next'. FLT_MAX if unsolveable.
|
||||
|
||||
unsigned Hash() const {
|
||||
const unsigned char *p = (const unsigned char *)(&start);
|
||||
uint h = 2166136261U;
|
||||
|
||||
for( unsigned i=0; i<sizeof(void*)*2; ++i, ++p ) {
|
||||
h ^= *p;
|
||||
h *= 16777619;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
PathCache( int itemsToAllocate );
|
||||
~PathCache();
|
||||
|
||||
void Reset();
|
||||
void Add( const Common::Array< void* >& path, const Common::Array< float >& cost );
|
||||
void AddNoSolution( void* end, void* states[], int count );
|
||||
int Solve( void* startState, void* endState, Common::Array< void* >* path, float* totalCost );
|
||||
|
||||
int AllocatedBytes() const { return allocated * sizeof(Item); }
|
||||
int UsedBytes() const { return nItems * sizeof(Item); }
|
||||
|
||||
int hit;
|
||||
int miss;
|
||||
|
||||
private:
|
||||
void AddItem( const Item& item );
|
||||
const Item* Find( void* start, void* end );
|
||||
|
||||
Item* mem;
|
||||
int allocated;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
struct CacheData {
|
||||
CacheData() { reset(); }
|
||||
|
||||
int nBytesAllocated;
|
||||
int nBytesUsed;
|
||||
float memoryFraction;
|
||||
|
||||
int hit;
|
||||
int miss;
|
||||
float hitFraction;
|
||||
|
||||
void reset() {
|
||||
nBytesAllocated = 0;
|
||||
nBytesUsed = 0;
|
||||
memoryFraction = 0;
|
||||
|
||||
hit = 0;
|
||||
miss = 0;
|
||||
hitFraction = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Create a MicroPather object to solve for a best path. Detailed usage notes are
|
||||
on the main page.
|
||||
*/
|
||||
class MicroPather
|
||||
{
|
||||
friend class micropather::PathNode;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
SOLVED,
|
||||
NO_SOLUTION,
|
||||
START_END_SAME,
|
||||
|
||||
// internal
|
||||
NOT_CACHED
|
||||
};
|
||||
|
||||
/**
|
||||
Construct the pather, passing a pointer to the object that implements
|
||||
the Graph callbacks.
|
||||
|
||||
@param graph The "map" that implements the Graph callbacks.
|
||||
@param allocate How many states should be internally allocated at a time. This
|
||||
can be hard to get correct. The higher the value, the more memory
|
||||
MicroPather will use.
|
||||
- If you have a small map (a few thousand states?) it may make sense
|
||||
to pass in the maximum value. This will cache everything, and MicroPather
|
||||
will only need one main memory allocation. For a chess board, allocate
|
||||
would be set to 8x8 (64)
|
||||
- If your map is large, something like 1/4 the number of possible
|
||||
states is good.
|
||||
- If your state space is huge, use a multiple (5-10x) of the normal
|
||||
path. "Occasionally" call Reset() to free unused memory.
|
||||
@param typicalAdjacent Used to determine cache size. The typical number of adjacent states
|
||||
to a given state. (On a chessboard, 8.) Higher values use a little
|
||||
more memory.
|
||||
@param cache Turn on path caching. Uses more memory (yet again) but at a huge speed
|
||||
advantage if you may call the pather with the same path or sub-path, which
|
||||
is common for pathing over maps in games.
|
||||
*/
|
||||
MicroPather( Graph* graph, unsigned allocate = 250, unsigned typicalAdjacent=6, bool cache=true );
|
||||
~MicroPather();
|
||||
|
||||
/**
|
||||
Solve for the path from start to end.
|
||||
|
||||
@param startState Input, the starting state for the path.
|
||||
@param endState Input, the ending state for the path.
|
||||
@param path Output, a vector of states that define the path. Empty if not found.
|
||||
@param totalCost Output, the cost of the path, if found.
|
||||
@return Success or failure, expressed as SOLVED, NO_SOLUTION, or START_END_SAME.
|
||||
*/
|
||||
int Solve( void* startState, void* endState, Common::Array< void* >* path, float* totalCost );
|
||||
|
||||
/**
|
||||
Find all the states within a given cost from startState.
|
||||
|
||||
@param startState Input, the starting state for the path.
|
||||
@param near All the states within 'maxCost' of 'startState', and cost to that state.
|
||||
@param maxCost Input, the maximum cost that will be returned. (Higher values return
|
||||
larger 'near' sets and take more time to compute.)
|
||||
@return Success or failure, expressed as SOLVED or NO_SOLUTION.
|
||||
*/
|
||||
int SolveForNearStates( void* startState, Common::Array< StateCost >* near, float maxCost );
|
||||
|
||||
/** Should be called whenever the cost between states or the connection between states changes.
|
||||
Also frees overhead memory used by MicroPather, and calling will free excess memory.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
// Debugging function to return all states that were used by the last "solve"
|
||||
void StatesInPool( Common::Array< void* >* stateVec );
|
||||
void GetCacheData( CacheData* data );
|
||||
|
||||
private:
|
||||
MicroPather( const MicroPather& ); // undefined and unsupported
|
||||
void operator=( const MicroPather ); // undefined and unsupported
|
||||
|
||||
void GoalReached( PathNode* node, void* start, void* end, Common::Array< void* > *path );
|
||||
|
||||
void GetNodeNeighbors( PathNode* node, Common::Array< NodeCost >* neighborNode );
|
||||
|
||||
#ifdef TETRAEDGE_MICROPATHER_DEBUG
|
||||
void DumpStats();
|
||||
#endif
|
||||
|
||||
PathNodePool pathNodePool;
|
||||
Common::Array< StateCost > stateCostVec; // local to Solve, but put here to reduce memory allocation
|
||||
Common::Array< NodeCost > nodeCostVec; // local to Solve, but put here to reduce memory allocation
|
||||
Common::Array< float > costVec;
|
||||
|
||||
Graph* graph;
|
||||
unsigned frame; // incremented with every solve, used to determine if cached data needs to be refreshed
|
||||
PathCache* pathCache;
|
||||
};
|
||||
|
||||
} // namespace micropather
|
||||
|
||||
} // namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_MICROPATHER
|
||||
|
||||
376
engines/tetraedge/te/te_3d_object2.cpp
Normal file
376
engines/tetraedge/te/te_3d_object2.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* 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 "tetraedge/te/te_3d_object2.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
Te3DObject2::Te3DObject2() : _childListChanged(false), _parent(nullptr), _scale(1.0f, 1.0f, 1.0f), _color(255, 255, 255, 255), _visible(true), _colorInheritance(true) {
|
||||
_onWorldVisibleChangedParentCallback.reset(
|
||||
new TeCallback0Param<Te3DObject2>(this, &Te3DObject2::onWorldVisibleChangedSlot));
|
||||
_onWorldColorChangedParentCallback.reset(
|
||||
new TeCallback0Param<Te3DObject2>(this, &Te3DObject2::onParentWorldColorChanged));
|
||||
_onWorldTransformationMatrixChangedParentCallback.reset(
|
||||
new TeCallback0Param<Te3DObject2>(this, &Te3DObject2::onParentWorldTransformationMatrixChanged));
|
||||
}
|
||||
|
||||
Te3DObject2::~Te3DObject2() {
|
||||
for (auto *child : _children) {
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
// clear list in case parent->removeChild triggers a signal which ends up referencing it.
|
||||
_children.clear();
|
||||
if (parent()) {
|
||||
parent()->removeChild(this);
|
||||
}
|
||||
setParent(nullptr);
|
||||
}
|
||||
|
||||
void Te3DObject2::addChild(Te3DObject2 *newChild) {
|
||||
assert(newChild != this && newChild != _parent);
|
||||
for (auto *c : _children) {
|
||||
if (c == newChild)
|
||||
error("Trying to re-add child %s to object %s", newChild->name().c_str(), _name.c_str());
|
||||
}
|
||||
|
||||
_children.push_back(newChild);
|
||||
newChild->setParent(this);
|
||||
_childListChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::addChildBefore(Te3DObject2 *newChild, const Te3DObject2 *ref) {
|
||||
assert(newChild != this && newChild != _parent);
|
||||
for (auto *c : _children) {
|
||||
if (c == newChild)
|
||||
error("Trying to re-add child %s to object %s", newChild->name().c_str(), _name.c_str());
|
||||
}
|
||||
|
||||
Common::Array<Te3DObject2 *>::iterator iter;
|
||||
for (iter = _children.begin(); iter != _children.end(); iter++) {
|
||||
if (*iter == ref) {
|
||||
_children.insert(iter, newChild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iter == _children.end())
|
||||
_children.push_back(newChild);
|
||||
|
||||
newChild->setParent(this);
|
||||
_childListChangedSignal.call();
|
||||
}
|
||||
|
||||
Te3DObject2 *Te3DObject2::child(int offset) {
|
||||
return _children[offset];
|
||||
}
|
||||
|
||||
int Te3DObject2::childIndex(Te3DObject2 *c) const {
|
||||
for (uint i = 0; i < _children.size(); i++) {
|
||||
if (_children[i] == c)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DObject2::deserialize(Common::ReadStream &stream, Te3DObject2 &dest, bool includesName /* = true */) {
|
||||
if (includesName) {
|
||||
Common::String str = deserializeString(stream);
|
||||
dest.setName(str);
|
||||
}
|
||||
|
||||
TeVector3f32 vect;
|
||||
TeVector3f32::deserialize(stream, vect);
|
||||
dest.setPosition(vect);
|
||||
|
||||
TeQuaternion quat;
|
||||
TeQuaternion::deserialize(stream, quat);
|
||||
dest.setRotation(quat);
|
||||
|
||||
TeVector3f32::deserialize(stream, vect);
|
||||
dest.setScale(vect);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DObject2::serialize(Common::WriteStream &stream, Te3DObject2 &src) {
|
||||
const Common::String &name = src.name();
|
||||
stream.writeUint32LE(name.size());
|
||||
stream.write(name.c_str(), name.size());
|
||||
|
||||
const TeVector3f32 pos = src.position();
|
||||
TeVector3f32::serialize(stream, pos);
|
||||
|
||||
const TeQuaternion rot = src.rotation();
|
||||
TeQuaternion::serialize(stream, rot);
|
||||
|
||||
const TeVector3f32 sca = src.scale();
|
||||
TeVector3f32::serialize(stream, sca);
|
||||
}
|
||||
|
||||
bool Te3DObject2::onParentWorldColorChanged() {
|
||||
_onParentWorldColorChangedSignal.call();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Te3DObject2::onParentWorldTransformationMatrixChanged() {
|
||||
_onParentWorldTransformationMatrixChangedSignal.call();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Te3DObject2::removeChild(Te3DObject2 *child) {
|
||||
uint i;
|
||||
for (i = 0; i < _children.size(); i++) {
|
||||
if (_children[i] == child) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < _children.size()) {
|
||||
_children[i]->setParent(nullptr);
|
||||
_children.remove_at(i);
|
||||
_childListChangedSignal.call();
|
||||
} /*else {
|
||||
// Print a warning?
|
||||
// This happens on every scene change so this is a bit too noisy.
|
||||
Common::String cname("nullptr");
|
||||
if (child)
|
||||
cname = child->name();
|
||||
debug("Request to remove child (%s) which is not a child of this (%s).", cname.c_str(), name().c_str());
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Te3DObject2::onWorldVisibleChangedSlot() {
|
||||
_onWorldVisibleChangedSlotSignal.call();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Te3DObject2::removeChildren() {
|
||||
for (auto *child : _children) {
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
_children.clear();
|
||||
_childListChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::rotate(const TeQuaternion &rot) {
|
||||
const TeQuaternion newRot = rotation() * rot;
|
||||
setRotation(newRot);
|
||||
}
|
||||
|
||||
void Te3DObject2::setColor(const TeColor &col) {
|
||||
_color = col;
|
||||
_onParentWorldColorChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::setParent(Te3DObject2 *newparent) {
|
||||
assert(newparent != this);
|
||||
if (_parent) {
|
||||
if (_onWorldVisibleChangedParentCallback)
|
||||
_parent->onWorldVisibleChanged().remove(_onWorldVisibleChangedParentCallback);
|
||||
if (_onWorldTransformationMatrixChangedParentCallback)
|
||||
_parent->onWorldTransformationMatrixChanged().remove(_onWorldTransformationMatrixChangedParentCallback);
|
||||
if (_onWorldColorChangedParentCallback)
|
||||
_parent->onWorldColorChanged().remove(_onWorldColorChangedParentCallback);
|
||||
}
|
||||
_parent = newparent;
|
||||
if (newparent) {
|
||||
if (_onWorldVisibleChangedParentCallback)
|
||||
_parent->onWorldVisibleChanged().push_back(_onWorldVisibleChangedParentCallback);
|
||||
if (_onWorldTransformationMatrixChangedParentCallback)
|
||||
_parent->onWorldTransformationMatrixChanged().push_back(_onWorldTransformationMatrixChangedParentCallback);
|
||||
if (_onWorldColorChangedParentCallback)
|
||||
_parent->onWorldColorChanged().push_back(_onWorldColorChangedParentCallback);
|
||||
|
||||
_onWorldVisibleChangedSlotSignal.call();
|
||||
_onParentWorldTransformationMatrixChangedSignal.call();
|
||||
_onParentWorldColorChangedSignal.call();
|
||||
}
|
||||
}
|
||||
|
||||
void Te3DObject2::setPosition(const TeVector3f32 &pos) {
|
||||
if (_position == pos)
|
||||
return;
|
||||
|
||||
// FIXME: remove this debugging code.
|
||||
if ((_position - pos).length() > 2.0f && name() == "Kate" && _position != TeVector3f32()) {
|
||||
debug("Large position move %s %s -> %s", name().c_str(),
|
||||
_position.dump().c_str(), pos.dump().c_str());
|
||||
}
|
||||
|
||||
_position = pos;
|
||||
_onPositionChangedSignal.call();
|
||||
_onParentWorldTransformationMatrixChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::setPositionFast(const TeVector3f32 &pos) {
|
||||
_position = pos;
|
||||
}
|
||||
|
||||
void Te3DObject2::setRotation(const TeQuaternion &rot) {
|
||||
if (_rotation == rot)
|
||||
return;
|
||||
|
||||
_rotation = rot;
|
||||
_onParentWorldTransformationMatrixChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::setScale(const TeVector3f32 &scale) {
|
||||
if (_scale == scale)
|
||||
return;
|
||||
|
||||
_scale = scale;
|
||||
_onParentWorldTransformationMatrixChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::setSize(const TeVector3f32 &size) {
|
||||
if (_size == size)
|
||||
return;
|
||||
|
||||
_size = size;
|
||||
_onSizeChangedSignal.call();
|
||||
}
|
||||
|
||||
void Te3DObject2::setVisible(bool visible) {
|
||||
if (_visible == visible)
|
||||
return;
|
||||
|
||||
_visible = visible;
|
||||
onWorldVisibleChangedSlot();
|
||||
}
|
||||
|
||||
void Te3DObject2::setZPosition(float zpos) {
|
||||
TeVector3f32 pos = position();
|
||||
pos.z() = zpos;
|
||||
setPosition(pos);
|
||||
}
|
||||
|
||||
TeMatrix4x4 Te3DObject2::transformationMatrix() {
|
||||
TeMatrix4x4 retval;
|
||||
retval.translate(position());
|
||||
retval.rotate(rotation());
|
||||
retval.scale(scale());
|
||||
return retval;
|
||||
}
|
||||
|
||||
void Te3DObject2::translate(const TeVector3f32 &vec) {
|
||||
TeVector3f32 pos = position();
|
||||
pos += vec;
|
||||
setPosition(pos);
|
||||
}
|
||||
|
||||
TeColor Te3DObject2::worldColor() {
|
||||
if (!_parent || !_colorInheritance) {
|
||||
return color();
|
||||
} else {
|
||||
const TeColor parentCol = _parent->worldColor();
|
||||
const TeColor thisCol = color();
|
||||
return parentCol * thisCol;
|
||||
}
|
||||
}
|
||||
|
||||
TeVector3f32 Te3DObject2::worldPosition() {
|
||||
if (!_parent) {
|
||||
return position();
|
||||
} else {
|
||||
return _parent->worldPosition() + position();
|
||||
}
|
||||
}
|
||||
|
||||
TeQuaternion Te3DObject2::worldRotation() {
|
||||
if (!_parent) {
|
||||
return rotation();
|
||||
} else {
|
||||
return _parent->worldRotation() * rotation();
|
||||
}
|
||||
}
|
||||
|
||||
TeVector3f32 Te3DObject2::worldScale() {
|
||||
if (!_parent) {
|
||||
return scale();
|
||||
} else {
|
||||
return _parent->worldScale() * scale();
|
||||
}
|
||||
}
|
||||
|
||||
TeMatrix4x4 Te3DObject2::worldTransformationMatrix() {
|
||||
if (!_parent) {
|
||||
return transformationMatrix();
|
||||
} else {
|
||||
return _parent->worldTransformationMatrix() * transformationMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
bool Te3DObject2::worldVisible() {
|
||||
if (!_parent) {
|
||||
return visible();
|
||||
} else {
|
||||
return _parent->worldVisible() && visible();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool Te3DObject2::loadAndCheckFourCC(Common::ReadStream &stream, const char *str) {
|
||||
char buf[5];
|
||||
buf[4] = '\0';
|
||||
stream.read(buf, 4);
|
||||
bool result = !strncmp(buf, str, 4);
|
||||
if (!result)
|
||||
debug("loadAndCheckFourCC: Look for %s, got %s", str, buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
Common::String Te3DObject2::deserializeString(Common::ReadStream &stream) {
|
||||
uint slen = stream.readUint32LE();
|
||||
if (slen > 1024 * 1024)
|
||||
error("Improbable string size %d", slen);
|
||||
|
||||
if (slen) {
|
||||
char *buf = new char[slen + 1];
|
||||
buf[slen] = '\0';
|
||||
stream.read(buf, slen);
|
||||
Common::String str(buf);
|
||||
delete[] buf;
|
||||
return str;
|
||||
}
|
||||
return Common::String();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DObject2::deserializeVectorArray(Common::ReadStream &stream, Common::Array<TeVector3f32> &dest) {
|
||||
uint32 nentries = stream.readUint32LE();
|
||||
if (nentries > 1000000)
|
||||
error("TeFreeMoveZone improbable number of vectors %d", nentries);
|
||||
dest.resize(nentries);
|
||||
for (uint i = 0; i < nentries; i++)
|
||||
TeVector3f32::deserialize(stream, dest[i]);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DObject2::deserializeUintArray(Common::ReadStream &stream, Common::Array<uint> &dest) {
|
||||
uint32 nentries = stream.readUint32LE();
|
||||
if (nentries > 1000000)
|
||||
error("TeFreeMoveZone improbable number of ints %d", nentries);
|
||||
dest.resize(nentries);
|
||||
for (uint i = 0; i < nentries; i++)
|
||||
dest[i] = stream.readUint32LE();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
182
engines/tetraedge/te/te_3d_object2.h
Normal file
182
engines/tetraedge/te/te_3d_object2.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_3D_OBJECT2_H
|
||||
#define TETRAEDGE_TE_TE_3D_OBJECT2_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_i_3d_object2.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_object.h"
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class Te3DObject2 : public TeI3DObject2, public TeObject {
|
||||
public:
|
||||
Te3DObject2();
|
||||
virtual ~Te3DObject2();
|
||||
|
||||
// note, probably should be Te*I*3DObject2 args here
|
||||
virtual void addChild(Te3DObject2 *newChild);
|
||||
virtual void addChildBefore(Te3DObject2 *newChild, const Te3DObject2 *ref);
|
||||
virtual Te3DObject2 *child(int offset);
|
||||
int childCount() {
|
||||
return _children.size();
|
||||
}
|
||||
|
||||
int childIndex(Te3DObject2 *childToFind) const;
|
||||
|
||||
const Common::Array<Te3DObject2 *> &childList() const {
|
||||
return _children;
|
||||
}
|
||||
|
||||
bool childListChanged() const {
|
||||
return _childListChanged;
|
||||
}
|
||||
|
||||
const TeColor &color() const {
|
||||
return _color;
|
||||
}
|
||||
|
||||
bool colorInheritance() const {
|
||||
return _colorInheritance;
|
||||
}
|
||||
|
||||
/* Note: Added control for includesName not in original as Syberia 2 data format uses
|
||||
the file name as the model name. */
|
||||
static void deserialize(Common::ReadStream &stream, Te3DObject2 &dest, bool includesName = true);
|
||||
static void serialize(Common::WriteStream &stream, Te3DObject2 &src);
|
||||
|
||||
virtual void draw() {}
|
||||
const Common::String &name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
virtual bool onParentWorldColorChanged();
|
||||
bool onParentWorldTransformationMatrixChanged();
|
||||
bool onWorldVisibleChangedSlot();
|
||||
TeSignal0Param &onPositionChanged() {
|
||||
return _onPositionChangedSignal;
|
||||
}
|
||||
TeSignal0Param &onSizeChanged() {
|
||||
return _onSizeChangedSignal;
|
||||
}
|
||||
TeSignal0Param &onWorldColorChanged() {
|
||||
return _onParentWorldColorChangedSignal;
|
||||
}
|
||||
TeSignal0Param &onWorldTransformationMatrixChanged() {
|
||||
return _onParentWorldTransformationMatrixChangedSignal;
|
||||
}
|
||||
TeSignal0Param &onWorldVisibleChanged() {
|
||||
return _onWorldVisibleChangedSlotSignal;
|
||||
}
|
||||
|
||||
Te3DObject2 *parent() {
|
||||
return _parent;
|
||||
}
|
||||
virtual TeVector3f32 position() {
|
||||
return _position;
|
||||
}
|
||||
virtual void removeChild(Te3DObject2 *toRemove);
|
||||
virtual void removeChildren();
|
||||
void rotate(const TeQuaternion &rot);
|
||||
const TeQuaternion &rotation() {
|
||||
return _rotation;
|
||||
}
|
||||
const TeVector3f32 &scale() const {
|
||||
return _scale;
|
||||
}
|
||||
virtual void setColor(const TeColor &col);
|
||||
virtual void setColorInheritance(bool val) {
|
||||
_colorInheritance = val;
|
||||
}
|
||||
virtual bool setName(const Common::String &newName) {
|
||||
_name = newName;
|
||||
return true;
|
||||
}
|
||||
virtual void setParent(Te3DObject2 *newparent); // note, probably should be Te*I*3DObject2 arg
|
||||
virtual void setPosition(const TeVector3f32 &pos);
|
||||
virtual void setPositionFast(const TeVector3f32 &pos);
|
||||
virtual void setRotation(const TeQuaternion &rot);
|
||||
virtual void setScale(const TeVector3f32 &newScale);
|
||||
virtual void setSize(const TeVector3f32 &newSize);
|
||||
void setVisible(bool visible);
|
||||
virtual void setZPosition(float zpos);
|
||||
virtual TeVector3f32 size() {
|
||||
return _size;
|
||||
}
|
||||
TeMatrix4x4 transformationMatrix();
|
||||
virtual void translate(const TeVector3f32 &vec);
|
||||
virtual void updateZ() {};
|
||||
virtual bool visible() const {
|
||||
return _visible;
|
||||
}
|
||||
|
||||
TeColor worldColor();
|
||||
virtual TeVector3f32 worldPosition();
|
||||
TeQuaternion worldRotation();
|
||||
TeVector3f32 worldScale();
|
||||
virtual TeMatrix4x4 worldTransformationMatrix();
|
||||
virtual bool worldVisible();
|
||||
virtual float xSize() { return _size.x(); };
|
||||
virtual float ySize() { return _size.y(); };
|
||||
virtual float zSize() { return _size.z(); };
|
||||
|
||||
static bool loadAndCheckFourCC(Common::ReadStream &stream, const char *str);
|
||||
static Common::String deserializeString(Common::ReadStream &stream);
|
||||
static void deserializeVectorArray(Common::ReadStream &stream, Common::Array<TeVector3f32> &dest);
|
||||
static void deserializeUintArray(Common::ReadStream &stream, Common::Array<uint> &dest);
|
||||
|
||||
protected:
|
||||
TeVector3f32 _size;
|
||||
TeVector3f32 _position;
|
||||
TeQuaternion _rotation;
|
||||
TeVector3f32 _scale;
|
||||
|
||||
private:
|
||||
Common::Array<Te3DObject2 *> _children;
|
||||
bool _childListChanged;
|
||||
TeColor _color;
|
||||
bool _colorInheritance;
|
||||
Common::String _name;
|
||||
Te3DObject2 *_parent;
|
||||
bool _visible;
|
||||
|
||||
TeSignal0Param _childListChangedSignal;
|
||||
TeSignal0Param _onWorldVisibleChangedSlotSignal;
|
||||
TeSignal0Param _onPositionChangedSignal;
|
||||
TeSignal0Param _onSizeChangedSignal;
|
||||
TeSignal0Param _onParentWorldColorChangedSignal;
|
||||
TeSignal0Param _onParentWorldTransformationMatrixChangedSignal;
|
||||
|
||||
TeICallback0ParamPtr _onWorldVisibleChangedParentCallback;
|
||||
TeICallback0ParamPtr _onWorldTransformationMatrixChangedParentCallback;
|
||||
TeICallback0ParamPtr _onWorldColorChangedParentCallback;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_3D_OBJECT2_H
|
||||
122
engines/tetraedge/te/te_3d_texture.cpp
Normal file
122
engines/tetraedge/te/te_3d_texture.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
#include "tetraedge/te/te_3d_texture_opengl.h"
|
||||
#include "tetraedge/te/te_3d_texture_tinygl.h"
|
||||
#include "tetraedge/te/te_resource_manager.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
Te3DTexture::Te3DTexture() : _createdTexture(false),
|
||||
_loaded(false), _width(0), _height(0), _texHeight(0), _texWidth(0),
|
||||
_topBorder(0), _leftBorder(0), _rightBorder(0), _btmBorder(0),
|
||||
_flipY(false), _alphaOnly(false) {
|
||||
}
|
||||
|
||||
Te3DTexture::~Te3DTexture() {
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeIntrusivePtr<Te3DTexture> Te3DTexture::load2(const TetraedgeFSNode &node, bool alphaOnly) {
|
||||
const Common::Path fullPath = node.getPath().append(".3dtex");
|
||||
|
||||
TeResourceManager *resMgr = g_engine->getResourceManager();
|
||||
if (!resMgr->exists(fullPath)) {
|
||||
TeIntrusivePtr<Te3DTexture> retval(makeInstance());
|
||||
if (!node.exists())
|
||||
warning("Request to load unreadable texture %s", node.toString().c_str());
|
||||
if (alphaOnly)
|
||||
retval->setLoadAlphaOnly();
|
||||
|
||||
bool result = retval->load(node);
|
||||
if (!result)
|
||||
warning("Failed loading texture %s", node.toString().c_str());
|
||||
|
||||
retval->setAccessName(fullPath);
|
||||
resMgr->addResource(retval.get());
|
||||
return retval;
|
||||
} else {
|
||||
return resMgr->getResourceByName<Te3DTexture>(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
bool Te3DTexture::load(const TetraedgeFSNode &node) {
|
||||
TeResourceManager *resmgr = g_engine->getResourceManager();
|
||||
TeIntrusivePtr<TeImage> img = resmgr->getResource<TeImage>(node);
|
||||
bool result = load(*img);
|
||||
setAccessName(node.getPath().append(".3dtex"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeVector2s32 Te3DTexture::optimisedSize(const TeVector2s32 &size) {
|
||||
//
|
||||
// Note: When we enable optimized sizes it can leave artifacts around
|
||||
// movies etc unless the render size is exactly 800x600.
|
||||
//
|
||||
// There is a workaround to clear some of the texture data in
|
||||
// Te3DTextureOpenGL::load to fix this.
|
||||
//
|
||||
|
||||
// The maths here is a bit funky but it just picks the nearest power of 2 (up)
|
||||
int xsize = size._x - 1;
|
||||
int ysize = size._y - 1;
|
||||
|
||||
xsize = (int)xsize >> 1 | xsize;
|
||||
xsize = (int)xsize >> 2 | xsize;
|
||||
xsize = (int)xsize >> 4 | xsize;
|
||||
xsize = (int)xsize >> 8 | xsize;
|
||||
int v1 = ((int)xsize >> 0x10 | xsize) + 1;
|
||||
if (v1 < 8) {
|
||||
v1 = 8;
|
||||
}
|
||||
|
||||
ysize = (int)ysize >> 1 | ysize;
|
||||
ysize = (int)ysize >> 2 | ysize;
|
||||
ysize = (int)ysize >> 4 | ysize;
|
||||
ysize = (int)ysize >> 8 | ysize;
|
||||
int v2 = ((int)ysize >> 0x10 | ysize) + 1;
|
||||
if (v2 < 8) {
|
||||
v2 = 8;
|
||||
}
|
||||
return TeVector2s32(v1, v2);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
Te3DTexture *Te3DTexture::makeInstance() {
|
||||
Graphics::RendererType r = g_engine->preferredRendererType();
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
if (r == Graphics::kRendererTypeOpenGL)
|
||||
return new Te3DTextureOpenGL();
|
||||
#endif
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
if (r == Graphics::kRendererTypeTinyGL)
|
||||
return new Te3DTextureTinyGL();
|
||||
#endif
|
||||
error("Couldn't create Te3DTexture for selected renderer");
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
92
engines/tetraedge/te/te_3d_texture.h
Normal file
92
engines/tetraedge/te/te_3d_texture.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_3D_TEXTURE_H
|
||||
#define TETRAEDGE_TE_TE_3D_TEXTURE_H
|
||||
|
||||
#include "common/path.h"
|
||||
#include "common/ptr.h"
|
||||
#include "common/str.h"
|
||||
|
||||
#include "tetraedge/te/te_image.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_resource.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class Te3DTexture : public TeResource {
|
||||
public:
|
||||
Te3DTexture();
|
||||
virtual ~Te3DTexture();
|
||||
|
||||
virtual void bind() const = 0;
|
||||
virtual void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) = 0;
|
||||
virtual void create() = 0;
|
||||
virtual void destroy() = 0;
|
||||
virtual void forceTexData(uint gltexture, uint xsize, uint ysize) = 0;
|
||||
|
||||
bool hasAlpha() const { return _hasAlpha; }
|
||||
|
||||
bool load(const TetraedgeFSNode &path);
|
||||
virtual bool load(const TeImage &img) = 0;
|
||||
// The original passes a GL enum param, but it's only ever GL_INVALID or GL_ALPHA.
|
||||
// Simplify to avoid leaking gl types.
|
||||
static TeIntrusivePtr<Te3DTexture> load2(const TetraedgeFSNode &node, bool alphaOnly);
|
||||
|
||||
static TeVector2s32 optimisedSize(const TeVector2s32 &size);
|
||||
|
||||
virtual bool unload() = 0;
|
||||
virtual void update(const TeImage &img, uint xoff, uint yoff) = 0;
|
||||
|
||||
virtual void writeTo(Graphics::Surface &surf) = 0;
|
||||
|
||||
uint width() const { return _width; }
|
||||
uint height() const { return _height; }
|
||||
void setLoadAlphaOnly() { _alphaOnly = true; }
|
||||
|
||||
static Te3DTexture *makeInstance();
|
||||
|
||||
|
||||
protected:
|
||||
uint _width;
|
||||
uint _height;
|
||||
bool _createdTexture;
|
||||
bool _loaded;
|
||||
TeMatrix4x4 _matrix;
|
||||
|
||||
bool _hasAlpha;
|
||||
bool _alphaOnly;
|
||||
|
||||
uint _texWidth;
|
||||
uint _texHeight;
|
||||
uint _leftBorder;
|
||||
uint _btmBorder;
|
||||
uint _rightBorder;
|
||||
uint _topBorder;
|
||||
bool _flipY;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_3D_TEXTURE_H
|
||||
232
engines/tetraedge/te/te_3d_texture_opengl.cpp
Normal file
232
engines/tetraedge/te/te_3d_texture_opengl.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/* 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 "graphics/opengl/system_headers.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_3d_texture_opengl.h"
|
||||
#include "tetraedge/te/te_resource_manager.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
static const uint NO_TEXTURE = 0xffffffff;
|
||||
|
||||
Te3DTextureOpenGL::Te3DTextureOpenGL() : _glTexture(NO_TEXTURE)/*, _glPixelFormat(GL_INVALID_ENUM)*/ {
|
||||
create();
|
||||
}
|
||||
|
||||
Te3DTextureOpenGL::~Te3DTextureOpenGL() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::bind() const {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
|
||||
renderer->loadMatrix(_matrix);
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
|
||||
_matrix.setToIdentity();
|
||||
const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
|
||||
_matrix.scale(texScale);
|
||||
const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
|
||||
_matrix.translate(offset);
|
||||
const TeVector3f32 borderScale(
|
||||
1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
|
||||
1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
|
||||
_matrix.scale(borderScale);
|
||||
bind();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::writeTo(Graphics::Surface &surf) {
|
||||
Graphics::Surface fullTex;
|
||||
fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat::createFormatRGBA32());
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTex.getPixels());
|
||||
surf.create(_width, _height, fullTex.format);
|
||||
surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
|
||||
fullTex.free();
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::create() {
|
||||
_flipY = false;
|
||||
_leftBorder = _btmBorder = _texWidth = _texHeight = 0;
|
||||
_rightBorder = _topBorder = _width = _height = 0;
|
||||
_hasAlpha = false;
|
||||
_loaded = false;
|
||||
if (!_createdTexture)
|
||||
glGenTextures(1, &_glTexture);
|
||||
if (_glTexture == NO_TEXTURE) {
|
||||
_createdTexture = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_createdTexture = true;
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::destroy() {
|
||||
if (_createdTexture) {
|
||||
glDeleteTextures(1, &_glTexture);
|
||||
}
|
||||
_createdTexture = false;
|
||||
_loaded = false;
|
||||
_glTexture = NO_TEXTURE;
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
|
||||
if (_glTexture != 0xffffffff)
|
||||
destroy();
|
||||
_glTexture = gltexture;
|
||||
_width = xsize;
|
||||
_height = ysize;
|
||||
_texWidth = xsize;
|
||||
_texHeight = ysize;
|
||||
}
|
||||
|
||||
bool Te3DTextureOpenGL::load(const TeImage &img) {
|
||||
setAccessName(img.getAccessName().append(".3dtex"));
|
||||
|
||||
_width = img.w;
|
||||
_height = img.h;
|
||||
_hasAlpha = img.format.aBits() > 0;
|
||||
|
||||
// TODO? set some other fields from the image here.
|
||||
// For now just set defaults as these never get used in games.
|
||||
_flipY = true; //img._flipY;
|
||||
_leftBorder = 0; //img._leftBorder;
|
||||
_btmBorder = 0; //img._btmBorder;
|
||||
_rightBorder = 0; //img._rightBorder;
|
||||
_topBorder = 0; //img._topBorder;
|
||||
|
||||
const TeVector2s32 optimizedSz = optimisedSize(img.bufSize());
|
||||
_texWidth = optimizedSz._x;
|
||||
_texHeight = optimizedSz._y;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
const void *imgdata = img.getPixels();
|
||||
if (img.format == Graphics::PixelFormat::createFormatRGBA32()) {
|
||||
Graphics::Surface surf;
|
||||
if (_alphaOnly) {
|
||||
surf.copyFrom(img);
|
||||
// Slight hack: Move R data to A channel. Our image reader
|
||||
// only reads data as RGB, so use red for alpha-only values.
|
||||
uint32 *p = (uint32 *)surf.getPixels();
|
||||
for (int y = 0; y < img.h; y++) {
|
||||
for (int x = 0; x < img.w; x++) {
|
||||
byte a, r, g, b;
|
||||
img.format.colorToARGB(p[x], a, r, g ,b);
|
||||
p[x] = img.format.ARGBToColor(r, r, r, r);
|
||||
}
|
||||
p += img.pitch / 4;
|
||||
}
|
||||
imgdata = surf.getPixels();
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
|
||||
|
||||
// FIXME: Slight hack.. sometimes artifacts appear because we draw
|
||||
// a (half?)pixel outside the original texture. Clear one more row
|
||||
// of the new texture with 0s to avoid artifacts.
|
||||
if ((int)_texHeight > img.h) {
|
||||
byte *buf = new byte[img.w * 4];
|
||||
memset(buf, 0, img.w * 4);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, img.h, img.w, 1, GL_RGBA, GL_UNSIGNED_BYTE, buf);
|
||||
delete [] buf;
|
||||
}
|
||||
// And the same for the right-hand-side
|
||||
if ((int)_texWidth > img.w) {
|
||||
byte *buf = new byte[img.h * 4];
|
||||
memset(buf, 0, img.h * 4);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, img.w, 0, 1, img.h, GL_RGBA, GL_UNSIGNED_BYTE, buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
if (_alphaOnly)
|
||||
surf.free();
|
||||
} else {
|
||||
warning("Te3DTexture::load can't send image format %s to GL.", img.format.toString().c_str());
|
||||
}
|
||||
|
||||
_matrix.setToIdentity();
|
||||
|
||||
_matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
|
||||
_matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
|
||||
_matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
|
||||
1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
|
||||
if (_flipY) {
|
||||
_matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
|
||||
_matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
|
||||
}
|
||||
_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DTextureOpenGL::unbind() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
|
||||
renderer->loadIdentityMatrix();
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
}
|
||||
|
||||
bool Te3DTextureOpenGL::unload() {
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
_loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Te3DTextureOpenGL::update(const TeImage &img, uint xoff, uint yoff) {
|
||||
if (!img.w || !img.h)
|
||||
return;
|
||||
|
||||
setAccessName(img.getAccessName().append(".3dtex"));
|
||||
glBindTexture(GL_TEXTURE_2D, _glTexture);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
const void *imgdata = img.getPixels();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
60
engines/tetraedge/te/te_3d_texture_opengl.h
Normal file
60
engines/tetraedge/te/te_3d_texture_opengl.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
|
||||
#define TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class Te3DTextureOpenGL : public Te3DTexture {
|
||||
public:
|
||||
Te3DTextureOpenGL();
|
||||
virtual ~Te3DTextureOpenGL();
|
||||
|
||||
void bind() const override;
|
||||
void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) override;
|
||||
void create() override;
|
||||
void destroy() override;
|
||||
void forceTexData(uint gltexture, uint xsize, uint ysize) override;
|
||||
|
||||
bool load(const TeImage &img) override;
|
||||
|
||||
static void unbind();
|
||||
bool unload() override;
|
||||
void update(const TeImage &img, uint xoff, uint yoff) override;
|
||||
|
||||
void writeTo(Graphics::Surface &surf) override;
|
||||
|
||||
private:
|
||||
uint _glTexture;
|
||||
//uint _glPixelFormat;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_OPENGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_3D_TEXTURE_OPENGL_H
|
||||
200
engines/tetraedge/te/te_3d_texture_tinygl.cpp
Normal file
200
engines/tetraedge/te/te_3d_texture_tinygl.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/* 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 "graphics/tinygl/tinygl.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_3d_texture_tinygl.h"
|
||||
#include "tetraedge/te/te_resource_manager.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
static const uint NO_TEXTURE = 0xffffffff;
|
||||
|
||||
Te3DTextureTinyGL::Te3DTextureTinyGL() : _glTexture(NO_TEXTURE)/*, _glPixelFormat(TGL_INVALID_ENUM)*/ {
|
||||
create();
|
||||
}
|
||||
|
||||
Te3DTextureTinyGL::~Te3DTextureTinyGL() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::bind() const {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
tglBindTexture(TGL_TEXTURE_2D, _glTexture);
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
|
||||
renderer->loadMatrix(_matrix);
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) {
|
||||
_matrix.setToIdentity();
|
||||
const TeVector3f32 texScale((float)_width / _texWidth, (float)_height / _texHeight, 1.0);
|
||||
_matrix.scale(texScale);
|
||||
const TeVector3f32 offset((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0);
|
||||
_matrix.translate(offset);
|
||||
const TeVector3f32 borderScale(
|
||||
1.0 - (float)(_rightBorder + _leftBorder) / (float)_width,
|
||||
1.0 - (float)(_topBorder + _btmBorder) / (float)_height, 1.0);
|
||||
_matrix.scale(borderScale);
|
||||
bind();
|
||||
//TODO: Come up with equivalent for TGL.
|
||||
//tglCopyTexSubImage2D(TGL_TEXTURE_2D, 0, xoffset, yoffset, x, y, _texWidth, _texHeight);
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::writeTo(Graphics::Surface &surf) {
|
||||
Graphics::Surface fullTex;
|
||||
fullTex.create(_texWidth, _texHeight, Graphics::PixelFormat::createFormatRGBA32());
|
||||
//TODO: Come up with equivalent for TGL.
|
||||
//tglGetTexImage(TGL_TEXTURE_2D, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, fullTex.getPixels());
|
||||
surf.create(_width, _height, fullTex.format);
|
||||
surf.copyRectToSurface(fullTex, 0, 0, Common::Rect(_width, _height));
|
||||
fullTex.free();
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::create() {
|
||||
_flipY = false;
|
||||
_leftBorder = _btmBorder = _texWidth = _texHeight = 0;
|
||||
_rightBorder = _topBorder = _width = _height = 0;
|
||||
_hasAlpha = false;
|
||||
_loaded = false;
|
||||
if (!_createdTexture)
|
||||
tglGenTextures(1, &_glTexture);
|
||||
if (_glTexture == NO_TEXTURE) {
|
||||
_createdTexture = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_createdTexture = true;
|
||||
tglBindTexture(TGL_TEXTURE_2D, _glTexture);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP_TO_EDGE);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::destroy() {
|
||||
if (_createdTexture) {
|
||||
tglDeleteTextures(1, &_glTexture);
|
||||
}
|
||||
_createdTexture = false;
|
||||
_loaded = false;
|
||||
_glTexture = NO_TEXTURE;
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::forceTexData(uint gltexture, uint xsize, uint ysize) {
|
||||
if (_glTexture != 0xffffffff)
|
||||
destroy();
|
||||
_glTexture = gltexture;
|
||||
_width = xsize;
|
||||
_height = ysize;
|
||||
_texWidth = xsize;
|
||||
_texHeight = ysize;
|
||||
}
|
||||
|
||||
bool Te3DTextureTinyGL::load(const TeImage &img) {
|
||||
setAccessName(img.getAccessName().append(".3dtex"));
|
||||
|
||||
_width = img.w;
|
||||
_height = img.h;
|
||||
_hasAlpha = img.format.aBits() > 0;
|
||||
|
||||
// TODO? set some other fields from the image here.
|
||||
// for now just set some good defaults.
|
||||
_flipY = true; //img._flipY;
|
||||
_leftBorder = 0; //img._leftBorder;
|
||||
_btmBorder = 0; //img._btmBorder;
|
||||
_rightBorder = 0; //img._rightBorder;
|
||||
_topBorder = 0; //img._topBorder;
|
||||
|
||||
_texWidth = _width;
|
||||
_texHeight = _height;
|
||||
|
||||
tglBindTexture(TGL_TEXTURE_2D, _glTexture);
|
||||
// Note: these are unsupported in TGL but should be the defaults?
|
||||
//tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
|
||||
//tglPixelStorei(TGL_UNPACK_LSB_FIRST, TGL_FALSE);
|
||||
//tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
|
||||
//tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
|
||||
//tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
|
||||
tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
const void *imgdata = img.getPixels();
|
||||
TGLenum destfmt = _alphaOnly ? TGL_ALPHA : TGL_RGBA;
|
||||
if (img.format == Graphics::PixelFormat::createFormatRGBA32()) {
|
||||
tglTexImage2D(TGL_TEXTURE_2D, 0, destfmt, img.w, img.h, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, imgdata);
|
||||
} else {
|
||||
warning("Te3DTexture::load can't send image format %s to GL.", img.format.toString().c_str());
|
||||
}
|
||||
|
||||
_matrix.setToIdentity();
|
||||
|
||||
_matrix.scale(TeVector3f32((float)_width / _texWidth, (float)_height / _texHeight, 1.0f));
|
||||
_matrix.translate(TeVector3f32((float)_leftBorder / _width, (float)_btmBorder / _height, 0.0f));
|
||||
_matrix.scale(TeVector3f32(1.0 - (float)(_rightBorder + _leftBorder) / _width,
|
||||
1.0 - (float)(_topBorder + _btmBorder) / _height, 1.0f));
|
||||
if (_flipY) {
|
||||
_matrix.translate(TeVector3f32(0.0f, 1.0f, 0.0f));
|
||||
_matrix.scale(TeVector3f32(1.0f, -1.0f, 1.0f));
|
||||
}
|
||||
_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Te3DTextureTinyGL::unbind() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_TEXTURE);
|
||||
renderer->loadIdentityMatrix();
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
tglBindTexture(TGL_TEXTURE_2D, 0);
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
}
|
||||
|
||||
bool Te3DTextureTinyGL::unload() {
|
||||
tglBindTexture(TGL_TEXTURE_2D, _glTexture);
|
||||
tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGB, 0, 0, 0, TGL_RGB, TGL_UNSIGNED_BYTE, NULL);
|
||||
_loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Te3DTextureTinyGL::update(const TeImage &img, uint xoff, uint yoff) {
|
||||
if (!img.w || !img.h)
|
||||
return;
|
||||
|
||||
setAccessName(img.getAccessName().append(".3dtex"));
|
||||
tglBindTexture(TGL_TEXTURE_2D, _glTexture);
|
||||
// Note: these are unsupported in TGL but should be the defaults?
|
||||
//tglPixelStorei(TGL_UNPACK_SWAP_BYTES, TGL_FALSE);
|
||||
//tglPixelStorei(TGL_UNPACK_LSB_FIRST, TGL_FALSE);
|
||||
//tglPixelStorei(TGL_UNPACK_ROW_LENGTH, 0);
|
||||
//tglPixelStorei(TGL_UNPACK_SKIP_ROWS, 0);
|
||||
//tglPixelStorei(TGL_UNPACK_SKIP_PIXELS, 0);
|
||||
tglPixelStorei(TGL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
//TODO: Come up with equivalent for TGL.
|
||||
//const void *imgdata = img.getPixels();
|
||||
//tglTexSubImage2D(TGL_TEXTURE_2D, 0, xoff, yoff, img.w, img.h, TGL_RGBA, TGL_UNSIGNED_BYTE, imgdata);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
60
engines/tetraedge/te/te_3d_texture_tinygl.h
Normal file
60
engines/tetraedge/te/te_3d_texture_tinygl.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
|
||||
#define TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class Te3DTextureTinyGL : public Te3DTexture {
|
||||
public:
|
||||
Te3DTextureTinyGL();
|
||||
virtual ~Te3DTextureTinyGL();
|
||||
|
||||
void bind() const override;
|
||||
void copyCurrentRender(uint xoffset, uint yoffset, uint x, uint y) override;
|
||||
void create() override;
|
||||
void destroy() override;
|
||||
void forceTexData(uint gltexture, uint xsize, uint ysize) override;
|
||||
|
||||
bool load(const TeImage &img) override;
|
||||
|
||||
static void unbind();
|
||||
bool unload() override;
|
||||
void update(const TeImage &img, uint xoff, uint yoff) override;
|
||||
|
||||
void writeTo(Graphics::Surface &surf) override;
|
||||
|
||||
private:
|
||||
uint _glTexture;
|
||||
//uint _glPixelFormat;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_TINYGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_3D_TEXTURE_TINYGL_H
|
||||
29
engines/tetraedge/te/te_act_zone.cpp
Normal file
29
engines/tetraedge/te/te_act_zone.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 "tetraedge/te/te_act_zone.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeActZone::TeActZone() : _flag1(false), _flag2(false) {
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
46
engines/tetraedge/te/te_act_zone.h
Normal file
46
engines/tetraedge/te/te_act_zone.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_ACT_ZONE_H
|
||||
#define TETRAEDGE_TE_TE_ACT_ZONE_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "tetraedge/te/te_vector2f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeActZone {
|
||||
public:
|
||||
TeActZone();
|
||||
|
||||
Common::String _s1;
|
||||
Common::String _s2;
|
||||
TeVector2f32 _points[4];
|
||||
bool _flag1;
|
||||
bool _flag2;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_ACT_ZONE_H
|
||||
139
engines/tetraedge/te/te_animation.cpp
Normal file
139
engines/tetraedge/te/te_animation.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* 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 "tetraedge/te/te_animation.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/*static*/
|
||||
Common::Array<TeAnimation *> *TeAnimation::_animations = nullptr;
|
||||
|
||||
/*static*/
|
||||
Common::Array<TeAnimation *> *TeAnimation::animations() {
|
||||
if (!_animations)
|
||||
_animations = new Common::Array<TeAnimation *>();
|
||||
return _animations;
|
||||
}
|
||||
|
||||
TeAnimation::TeAnimation() : _repeatCount(1), _dontRepeat(false) {
|
||||
}
|
||||
|
||||
TeAnimation::~TeAnimation() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void TeAnimation::cont() {
|
||||
if (!_runTimer.running()) {
|
||||
_runTimer.start();
|
||||
|
||||
Common::Array<TeAnimation *> *anims = animations();
|
||||
Common::Array<TeAnimation *>::iterator iter;
|
||||
for (iter = anims->begin(); iter != anims->end(); iter++) {
|
||||
if (*iter == this) {
|
||||
error("anim being resumed is already in active anims");
|
||||
}
|
||||
}
|
||||
anims->push_back(this);
|
||||
update(_runTimer.getTimeFromStart() / 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TeAnimation::removeThisFromAnimations() {
|
||||
// Find and remove this one
|
||||
Common::Array<TeAnimation *> *anims = animations();
|
||||
Common::Array<TeAnimation *>::iterator iter;
|
||||
for (iter = anims->begin(); iter != anims->end(); iter++) {
|
||||
if (*iter == this) {
|
||||
anims->erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = anims->begin(); iter != anims->end(); iter++) {
|
||||
if (*iter == this) {
|
||||
error("anim was added twice to active anims");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeAnimation::pause() {
|
||||
if (_runTimer.running()) {
|
||||
removeThisFromAnimations();
|
||||
_runTimer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
void TeAnimation::stop() {
|
||||
if (_runTimer.running()) {
|
||||
removeThisFromAnimations();
|
||||
_runTimer.stop();
|
||||
_onStopSignal.call();
|
||||
}
|
||||
}
|
||||
|
||||
void TeAnimation::reset() {
|
||||
if (_runTimer.running()) {
|
||||
removeThisFromAnimations();
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TeAnimation::seekToStart() {
|
||||
_runTimer.stop();
|
||||
_runTimer.start();
|
||||
update(_runTimer.getTimeFromStart() / 1000.0);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeAnimation::pauseAll() {
|
||||
for (auto &anim : *animations()) {
|
||||
if (anim->_runTimer.running())
|
||||
anim->pause();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeAnimation::resumeAll() {
|
||||
for (auto &anim : *animations()) {
|
||||
anim->cont();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeAnimation::cleanup() {
|
||||
delete _animations;
|
||||
_animations = nullptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeAnimation::updateAll() {
|
||||
Common::Array<TeAnimation *> &anims = *animations();
|
||||
// Note: update can cause events which cascade into animtaions
|
||||
// getting deleted, so be careful about the numbers.
|
||||
for (uint i = 0; i < anims.size(); i++) {
|
||||
if (anims[i]->_runTimer.running()) {
|
||||
double msFromStart = anims[i]->_runTimer.getTimeFromStart() / 1000.0;
|
||||
anims[i]->update(msFromStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
75
engines/tetraedge/te/te_animation.h
Normal file
75
engines/tetraedge/te/te_animation.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_ANIMATION_H
|
||||
#define TETRAEDGE_TE_TE_ANIMATION_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "tetraedge/te/te_timer.h"
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeAnimation {
|
||||
public:
|
||||
TeAnimation();
|
||||
virtual ~TeAnimation();
|
||||
|
||||
virtual void cont();
|
||||
virtual void pause();
|
||||
virtual void stop();
|
||||
virtual void reset();
|
||||
void play() {
|
||||
cont();
|
||||
}
|
||||
virtual void update(double millis) = 0;
|
||||
|
||||
void seekToStart();
|
||||
//void staticDestroy();
|
||||
|
||||
static void pauseAll();
|
||||
static void resumeAll();
|
||||
static void updateAll();
|
||||
|
||||
static void cleanup();
|
||||
|
||||
TeSignal0Param &onStop() { return _onStopSignal; }
|
||||
TeSignal0Param &onFinished() { return _onFinishedSignal; }
|
||||
|
||||
TeTimer _runTimer;
|
||||
int _repeatCount;
|
||||
|
||||
protected:
|
||||
bool _dontRepeat;
|
||||
TeSignal0Param _onStopSignal;
|
||||
TeSignal0Param _onFinishedSignal;
|
||||
|
||||
private:
|
||||
void removeThisFromAnimations();
|
||||
|
||||
static Common::Array<TeAnimation *> *animations();
|
||||
static Common::Array<TeAnimation *> *_animations;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_ANIMATION_H
|
||||
257
engines/tetraedge/te/te_bezier_curve.cpp
Normal file
257
engines/tetraedge/te/te_bezier_curve.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
/* 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/file.h"
|
||||
|
||||
#include "tetraedge/te/te_bezier_curve.h"
|
||||
#include "tetraedge/te/te_mesh.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeBezierCurve::TeBezierCurve() : _length(0.0), _rawLength(0.0), _lengthNeedsUpdate(true),
|
||||
_rawLengthNeedsUpdate(true), _numIterations(1000) {
|
||||
}
|
||||
|
||||
//int TeBezierCurve::bounds(int start);
|
||||
|
||||
void TeBezierCurve::clear() {
|
||||
_lengthNeedsUpdate = true;
|
||||
_rawLengthNeedsUpdate = true;
|
||||
_length = 0.0;
|
||||
_controlPoints.clear();
|
||||
}
|
||||
|
||||
void TeBezierCurve::draw() {
|
||||
if (!worldVisible() || _controlPoints.empty())
|
||||
return;
|
||||
|
||||
Common::SharedPtr<TeMesh> mesh1(TeMesh::makeInstance());
|
||||
Common::SharedPtr<TeMesh> mesh2(TeMesh::makeInstance());
|
||||
uint npoints = _controlPoints.size();
|
||||
|
||||
mesh1->setConf(npoints, npoints, TeMesh::MeshMode_Points, 0, 0);
|
||||
for (uint i = 0; i < npoints; i++) {
|
||||
mesh1->setVertex(i, _controlPoints[i]);
|
||||
mesh1->setIndex(i, i);
|
||||
}
|
||||
|
||||
mesh2->setConf(npoints, npoints, TeMesh::MeshMode_LineStrip, 0, 0);
|
||||
for (uint i = 0; i < npoints; i++) {
|
||||
mesh2->setVertex(i, _controlPoints[i]);
|
||||
mesh2->setNormal(i, TeVector3f32(0.0f, 1.0f, 0.0));
|
||||
mesh2->setIndex(i, i);
|
||||
}
|
||||
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
const TeColor prevColor = renderer->currentColor();
|
||||
renderer->pushMatrix();
|
||||
renderer->multiplyMatrix(worldTransformationMatrix());
|
||||
renderer->setCurrentColor(TeColor(0, 0xff, 0xff, 0xff));
|
||||
mesh2->draw();
|
||||
renderer->setCurrentColor(TeColor(0xff, 0, 0xff, 0xff));
|
||||
mesh1->draw();
|
||||
renderer->popMatrix();
|
||||
renderer->setCurrentColor(prevColor);
|
||||
}
|
||||
|
||||
float TeBezierCurve::length() {
|
||||
if (_lengthNeedsUpdate) {
|
||||
_length = 0.0;
|
||||
_lengthNeedsUpdate = false;
|
||||
_lengths.clear();
|
||||
|
||||
TeVector3f32 lastpt = _controlPoints[0];
|
||||
lastpt.y() = 0;
|
||||
for (uint i = 0; i < _numIterations; i++) {
|
||||
float amount = (float)i / _numIterations;
|
||||
TeVector3f32 pt = retrievePoint(amount);
|
||||
pt.y() = 0;
|
||||
float len = (lastpt - pt).length();
|
||||
_length += len;
|
||||
_lengths.push_back(_length);
|
||||
lastpt = pt;
|
||||
}
|
||||
}
|
||||
return _length;
|
||||
}
|
||||
|
||||
void TeBezierCurve::pseudoTangent(float offset, TeVector3f32 &v1, TeVector3f32 &v2) {
|
||||
const float step = 1.0f / _numIterations;
|
||||
if (step + offset <= 1.0f) {
|
||||
v1 = retrievePoint(offset);
|
||||
v2 = retrievePoint(offset + step);
|
||||
} else {
|
||||
v1 = retrievePoint(offset - step);
|
||||
v2 = retrievePoint(offset);
|
||||
}
|
||||
}
|
||||
|
||||
float TeBezierCurve::rawLength() {
|
||||
if (_rawLengthNeedsUpdate) {
|
||||
_rawLengthNeedsUpdate = false;
|
||||
_rawLength = 0.0;
|
||||
_rawLengths.clear();
|
||||
_rawLengths.push_back(0.0);
|
||||
for (uint i = 1; i < _controlPoints.size(); i++) {
|
||||
const TeVector3f32 diff = _controlPoints[i] - _controlPoints[i - 1];
|
||||
_rawLength += diff.length();
|
||||
_rawLengths.push_back(_rawLength);
|
||||
}
|
||||
}
|
||||
return _rawLength;
|
||||
}
|
||||
|
||||
TeVector3f32 TeBezierCurve::retrievePoint(float offset) {
|
||||
const int npoints = _controlPoints.size();
|
||||
|
||||
// Simple cases for small numbers of points.
|
||||
if (npoints == 0)
|
||||
return TeVector3f32();
|
||||
else if (npoints == 1)
|
||||
return _controlPoints[0];
|
||||
else if (npoints == 2)
|
||||
return _controlPoints[0] + (_controlPoints[1] - _controlPoints[0]) * offset;
|
||||
|
||||
// else, there are at least 3 points so need to actually interpolate.
|
||||
const float rawlen = rawLength();
|
||||
|
||||
float proportion = 0.0f;
|
||||
int startpt = 0;
|
||||
while (startpt < npoints) {
|
||||
proportion = _rawLengths[startpt] / rawlen;
|
||||
if (proportion >= offset)
|
||||
break;
|
||||
startpt++;
|
||||
}
|
||||
|
||||
float t;
|
||||
if (proportion == offset) {
|
||||
// Exactly on a point
|
||||
t = 0.0f;
|
||||
} else {
|
||||
// Proportion between two points
|
||||
float p1 = _rawLengths[startpt - 1];
|
||||
float p2 = _rawLengths[startpt];
|
||||
t = (rawlen * offset - p1) / (p2 - p1);
|
||||
startpt--;
|
||||
}
|
||||
|
||||
// Collect 4 points around the startpt (1 before, 2 after)
|
||||
TeVector3f32 points[4];
|
||||
const int maxPt = _controlPoints.size() - 1;
|
||||
for (int p = 0; p < 4; p++) {
|
||||
int ptno = CLIP(startpt + p - 1, 0, maxPt);
|
||||
points[p] = _controlPoints[ptno];
|
||||
}
|
||||
|
||||
// If we hit the end, linearly extend the last gradient.
|
||||
if (startpt <= 0)
|
||||
points[0] += (points[1] - points[2]);
|
||||
|
||||
if (startpt + 1 >= maxPt)
|
||||
points[3] += (points[2] - points[1]);
|
||||
|
||||
return hermiteInterpolate(t, points, 0.0, 0.0);
|
||||
}
|
||||
|
||||
void TeBezierCurve::setControlPoints(const Common::Array<TeVector3f32> &points) {
|
||||
_lengthNeedsUpdate = true;
|
||||
_rawLengthNeedsUpdate = true;
|
||||
_controlPoints = points;
|
||||
}
|
||||
|
||||
void TeBezierCurve::setNbIterations(uint iterations) {
|
||||
_lengthNeedsUpdate = true;
|
||||
_rawLengthNeedsUpdate = true;
|
||||
_numIterations = iterations;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeBezierCurve::serialize(Common::WriteStream &stream, const TeBezierCurve &curve) {
|
||||
error("TODO: Implement TeBezierCurve::serialize");
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeBezierCurve::deserialize(Common::ReadStream &stream, TeBezierCurve &curve) {
|
||||
Te3DObject2::deserialize(stream, curve);
|
||||
|
||||
curve._lengthNeedsUpdate = false;
|
||||
curve._length = stream.readFloatLE();
|
||||
uint32 npoints = stream.readUint32LE();
|
||||
if (npoints > 1000000)
|
||||
error("TeBezierCurve::deserialize improbable number of control ponts %d", npoints);
|
||||
|
||||
for (uint i = 0; i < npoints; i++) {
|
||||
TeVector3f32 vec;
|
||||
TeVector3f32::deserialize(stream, vec);
|
||||
curve._controlPoints.push_back(vec);
|
||||
}
|
||||
}
|
||||
|
||||
void TeBezierCurve::loadBin(TetraedgeFSNode &node) {
|
||||
Common::ScopedPtr<Common::SeekableReadStream> file(node.createReadStream());
|
||||
Common::String fname = node.getPath().baseName();
|
||||
if (fname.size() < 4)
|
||||
error("TeBezierCurve::loadBin fname %s is too short", fname.c_str());
|
||||
setName(fname.substr(0, fname.size() - 4));
|
||||
|
||||
// Load position / rotation / size
|
||||
Te3DObject2::deserialize(*file, *this, false);
|
||||
// Then it resets them?
|
||||
setPosition(TeVector3f32());
|
||||
setRotation(TeQuaternion());
|
||||
setSize(TeVector3f32(1, 1, 1));
|
||||
|
||||
_lengthNeedsUpdate = true;
|
||||
uint32 npoints = file->readUint32LE();
|
||||
if (npoints > 1000000)
|
||||
error("TeBezierCurve::loadBin improbable number of control ponts %d", npoints);
|
||||
|
||||
for (uint i = 0; i < npoints; i++) {
|
||||
TeVector3f32 vec;
|
||||
TeVector3f32::deserialize(*file, vec);
|
||||
_controlPoints.push_back(vec);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeVector3f32 TeBezierCurve::hermiteInterpolate(float t, const TeVector3f32 *points, float param_4, float param_5) {
|
||||
assert(points);
|
||||
const TeVector3f32 delta1 = ((points[1] - points[0]) * (param_5 + 1.0) * (1.0 - param_4)) / 2.0;
|
||||
const TeVector3f32 delta2a = ((points[2] - points[1]) * (1.0 - param_5) * (1.0 - param_4)) / 2.0;
|
||||
const TeVector3f32 delta2b = ((points[2] - points[1]) * (param_5 + 1.0) * (1.0 - param_4)) / 2.0;
|
||||
const TeVector3f32 delta3 = ((points[3] - points[2]) * (1.0 - param_5) * (1.0 - param_4)) / 2.0;
|
||||
|
||||
const TeVector3f32 x1 = delta1 + delta2a;
|
||||
const TeVector3f32 x2 = delta2b + delta3;
|
||||
|
||||
const float t2 = t * t;
|
||||
const float t3 = t * t * t;
|
||||
const TeVector3f32 h1a = points[1] * ((t3 + t3) - t2 * 3.0 + 1.0);
|
||||
const TeVector3f32 h1b = x1 * ((t3 - (t2 + t2)) + t);
|
||||
const TeVector3f32 h1 = (h1a + h1b) + (x2 * (t3 - t2));
|
||||
return h1 + (points[2] * (t3 * -2.0 + t2 * 3.0));
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
72
engines/tetraedge/te/te_bezier_curve.h
Normal file
72
engines/tetraedge/te/te_bezier_curve.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_BEZIER_CURVE_H
|
||||
#define TETRAEDGE_TE_TE_BEZIER_CURVE_H
|
||||
|
||||
#include "common/array.h"
|
||||
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_references_counter.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeBezierCurve : public Te3DObject2, public TeReferencesCounter {
|
||||
public:
|
||||
TeBezierCurve();
|
||||
|
||||
int bounds(int val);
|
||||
void clear();
|
||||
void draw() override;
|
||||
float length();
|
||||
|
||||
void pseudoTangent(float f, TeVector3f32 &v1, TeVector3f32 &v2);
|
||||
|
||||
float rawLength();
|
||||
|
||||
TeVector3f32 retrievePoint(float offset);
|
||||
void setControlPoints(const Common::Array<TeVector3f32> &points);
|
||||
void setNbIterations(uint iterations);
|
||||
|
||||
static TeVector3f32 hermiteInterpolate(float param_2, const TeVector3f32 *points, float param_4, float param_5);
|
||||
|
||||
static void serialize(Common::WriteStream &stream, const TeBezierCurve &curve);
|
||||
static void deserialize(Common::ReadStream &stream, TeBezierCurve &curve);
|
||||
void loadBin(TetraedgeFSNode &node);
|
||||
|
||||
const Common::Array<TeVector3f32> &controlPoints() { return _controlPoints; }
|
||||
uint numIterations() const { return _numIterations; }
|
||||
|
||||
private:
|
||||
uint _numIterations;
|
||||
float _length;
|
||||
float _rawLength;
|
||||
bool _lengthNeedsUpdate;
|
||||
bool _rawLengthNeedsUpdate;
|
||||
Common::Array<TeVector3f32> _controlPoints;
|
||||
Common::Array<float> _rawLengths;
|
||||
Common::Array<float> _lengths;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_BEZIER_CURVE_H
|
||||
413
engines/tetraedge/te/te_button_layout.cpp
Normal file
413
engines/tetraedge/te/te_button_layout.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_button_layout.h"
|
||||
#include "tetraedge/te/te_sound_manager.h"
|
||||
#include "tetraedge/te/te_input_mgr.h"
|
||||
#include "tetraedge/te/te_sprite_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeZPriorityMouseCallback : public TeCallback1Param<TeButtonLayout, const Common::Point &> {
|
||||
public:
|
||||
TeZPriorityMouseCallback(TeButtonLayout *layout, TMethod method) : TeCallback1Param<TeButtonLayout, const Common::Point &>(layout, method), _pri(0.0) {}
|
||||
virtual float &priority() override {
|
||||
_pri =_object->worldPosition().z();
|
||||
return _pri;
|
||||
}
|
||||
float _pri;
|
||||
};
|
||||
|
||||
/*static*/
|
||||
bool TeButtonLayout::_mousePositionChangedCatched = false;
|
||||
/*static*/
|
||||
TeTimer *TeButtonLayout::_doubleValidationProtectionTimer = nullptr;
|
||||
|
||||
/*static*/
|
||||
TeTimer *TeButtonLayout::getDoubleValidationProtectionTimer() {
|
||||
if (!_doubleValidationProtectionTimer) {
|
||||
_doubleValidationProtectionTimer = new TeTimer();
|
||||
}
|
||||
return _doubleValidationProtectionTimer;
|
||||
}
|
||||
|
||||
TeButtonLayout::TeButtonLayout() : _currentState(BUTTON_STATE_UP),
|
||||
_clickPassThrough(false), _validationSoundVolume(1.0),
|
||||
_ignoreMouseEvents(false), _doubleValidationProtectionEnabled(true),
|
||||
_upLayout(nullptr), _downLayout(nullptr), _rolloverLayout(nullptr),
|
||||
_disabledLayout(nullptr), _hitZoneLayout(nullptr), _ownedLayouts(false)
|
||||
{
|
||||
_onMousePositionChangedMaxPriorityCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMousePositionChangedMaxPriority, FLT_MAX));
|
||||
|
||||
_onMousePositionChangedCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMousePositionChanged));
|
||||
_onMouseLeftDownCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMouseLeftDown));
|
||||
_onMouseLeftUpMaxPriorityCallback.reset(new TeCallback1Param<TeButtonLayout, const Common::Point &>(this, &TeButtonLayout::onMouseLeftUpMaxPriority, FLT_MAX));
|
||||
_onMouseLeftUpCallback.reset(new TeZPriorityMouseCallback(this, &TeButtonLayout::onMouseLeftUp));
|
||||
|
||||
TeInputMgr *inputmgr = g_engine->getInputMgr();
|
||||
inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedCallback);
|
||||
inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedMaxPriorityCallback);
|
||||
inputmgr->_mouseLDownSignal.push_back(_onMouseLeftDownCallback);
|
||||
inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpCallback);
|
||||
inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpMaxPriorityCallback);
|
||||
|
||||
setEditionColor(TeColor(128, 128, 128, 255));
|
||||
if (!getDoubleValidationProtectionTimer()->running())
|
||||
getDoubleValidationProtectionTimer()->start();
|
||||
}
|
||||
|
||||
TeButtonLayout::~TeButtonLayout() {
|
||||
TeInputMgr *inputmgr = g_engine->getInputMgr();
|
||||
inputmgr->_mouseMoveSignal.remove(_onMousePositionChangedCallback);
|
||||
inputmgr->_mouseMoveSignal.remove(_onMousePositionChangedMaxPriorityCallback);
|
||||
inputmgr->_mouseLDownSignal.remove(_onMouseLeftDownCallback);
|
||||
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpCallback);
|
||||
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpMaxPriorityCallback);
|
||||
if (_ownedLayouts) {
|
||||
if (_upLayout)
|
||||
delete _upLayout;
|
||||
if (_downLayout)
|
||||
delete _downLayout;
|
||||
if (_rolloverLayout)
|
||||
delete _rolloverLayout;
|
||||
if (_hitZoneLayout)
|
||||
delete _hitZoneLayout;
|
||||
if (_disabledLayout)
|
||||
delete _disabledLayout;
|
||||
}
|
||||
}
|
||||
|
||||
bool TeButtonLayout::isMouseIn(const TeVector2s32 &mouseloc) {
|
||||
if (!_hitZoneLayout) {
|
||||
return TeLayout::isMouseIn(mouseloc);
|
||||
} else {
|
||||
return _hitZoneLayout->isMouseIn(mouseloc);
|
||||
}
|
||||
}
|
||||
|
||||
void TeButtonLayout::load(const Common::Path &upImg, const Common::Path &downImg, const Common::Path &overImg) {
|
||||
TeSpriteLayout *upSprite = nullptr;
|
||||
if (!upImg.empty()) {
|
||||
upSprite = new TeSpriteLayout();
|
||||
if (!upSprite->load(upImg))
|
||||
warning("Failed to load button up img %s", upImg.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
setUpLayout(upSprite);
|
||||
|
||||
TeSpriteLayout *downSprite = nullptr;
|
||||
if (!downImg.empty()) {
|
||||
downSprite = new TeSpriteLayout();
|
||||
if (!downSprite->load(downImg))
|
||||
warning("Failed to load button down img %s", downImg.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
setDownLayout(downSprite);
|
||||
|
||||
TeSpriteLayout *overSprite = nullptr;
|
||||
if (!overImg.empty()) {
|
||||
overSprite = new TeSpriteLayout();
|
||||
if (!overSprite->load(overImg))
|
||||
warning("Failed to load button over img %s", overImg.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
setRollOverLayout(overSprite);
|
||||
setHitZone(nullptr);
|
||||
setDisabledLayout(nullptr);
|
||||
_ownedLayouts = true;
|
||||
}
|
||||
|
||||
bool TeButtonLayout::onMouseLeftDown(const Common::Point &pt) {
|
||||
if (!worldVisible() || _currentState == BUTTON_STATE_DISABLED || _ignoreMouseEvents)
|
||||
return false;
|
||||
|
||||
// Note: This doesn't exactly reproduce the original behavior, it's
|
||||
// very simplified.
|
||||
bool mouseIn = isMouseIn(pt);
|
||||
|
||||
//if (mouseIn)
|
||||
// debug("mouse down on button '%s' (current state %d)", name().c_str(), _currentState);
|
||||
|
||||
enum State newState = _currentState;
|
||||
switch (_currentState) {
|
||||
case BUTTON_STATE_DOWN:
|
||||
if (!mouseIn)
|
||||
newState = BUTTON_STATE_UP;
|
||||
/*
|
||||
// TODO: should this be a click?
|
||||
if (mouseIn) {
|
||||
newState = BUTTON_STATE_UP;
|
||||
debug("mouse clicked button '%s' (from leftdown)", name().c_str());
|
||||
if (!_validationSound.empty()) {
|
||||
TeSoundManager *sndMgr = g_engine->getSoundManager();
|
||||
sndMgr->playFreeSound(_validationSound, _validationSoundVolume, "sfx");
|
||||
}
|
||||
setState(newState);
|
||||
_onMouseClickValidatedSignal.call();
|
||||
return !_clickPassThrough;
|
||||
}*/
|
||||
break;
|
||||
case BUTTON_STATE_ROLLOVER:
|
||||
case BUTTON_STATE_UP:
|
||||
if (mouseIn)
|
||||
newState = BUTTON_STATE_DOWN;
|
||||
break;
|
||||
case BUTTON_STATE_DISABLED:
|
||||
break;
|
||||
}
|
||||
setState(newState);
|
||||
return mouseIn && !_clickPassThrough;
|
||||
}
|
||||
|
||||
bool TeButtonLayout::onMouseLeftUp(const Common::Point &pt) {
|
||||
if (!worldVisible() || _currentState == BUTTON_STATE_DISABLED)
|
||||
return false;
|
||||
|
||||
// Note: This doesn't exactly reproduce the original behavior, it's
|
||||
// somewhat simplified.
|
||||
bool mouseIn = isMouseIn(pt);
|
||||
|
||||
//if (mouseIn)
|
||||
// debug("mouse up on button '%s' (current state %d)", name().c_str(), _currentState);
|
||||
|
||||
enum State newState = _currentState;
|
||||
switch (_currentState) {
|
||||
case BUTTON_STATE_DOWN:
|
||||
newState = BUTTON_STATE_UP;
|
||||
if (mouseIn) {
|
||||
debug("mouse clicked button '%s' (from leftup)", name().c_str());
|
||||
if (!_validationSound.empty()) {
|
||||
TeSoundManager *sndMgr = g_engine->getSoundManager();
|
||||
sndMgr->playFreeSound(_validationSound, _validationSoundVolume, "sfx");
|
||||
}
|
||||
setState(newState);
|
||||
bool stopProcessing = _onMouseClickValidatedSignal.call();
|
||||
return !_clickPassThrough || stopProcessing;
|
||||
}
|
||||
break;
|
||||
case BUTTON_STATE_ROLLOVER:
|
||||
case BUTTON_STATE_UP:
|
||||
case BUTTON_STATE_DISABLED:
|
||||
break;
|
||||
}
|
||||
setState(newState);
|
||||
return mouseIn && !_clickPassThrough;
|
||||
}
|
||||
|
||||
bool TeButtonLayout::onMousePositionChanged(const Common::Point &pt) {
|
||||
if (!worldVisible() || _ignoreMouseEvents)
|
||||
return false;
|
||||
|
||||
// Note: This doesn't exactly reproduce the original behavior, it's
|
||||
// very simplified.
|
||||
bool mouseIn = isMouseIn(pt);
|
||||
|
||||
enum State newState = _currentState;
|
||||
switch (_currentState) {
|
||||
case BUTTON_STATE_UP:
|
||||
if (mouseIn) {
|
||||
newState = BUTTON_STATE_ROLLOVER;
|
||||
}
|
||||
break;
|
||||
case BUTTON_STATE_DOWN:
|
||||
case BUTTON_STATE_ROLLOVER:
|
||||
if (!mouseIn) {
|
||||
newState = BUTTON_STATE_UP;
|
||||
}
|
||||
break;
|
||||
case BUTTON_STATE_DISABLED:
|
||||
break;
|
||||
}
|
||||
setState(newState);
|
||||
return false;
|
||||
}
|
||||
|
||||
void TeButtonLayout::reset() {
|
||||
_intArr.clear();
|
||||
State newState = (_currentState == BUTTON_STATE_DISABLED ? BUTTON_STATE_DISABLED : BUTTON_STATE_UP);
|
||||
setState(newState);
|
||||
}
|
||||
|
||||
void TeButtonLayout::resetTimeFromLastValidation() {
|
||||
TeTimer *timer = getDoubleValidationProtectionTimer();
|
||||
if (!timer->running()) {
|
||||
timer->start();
|
||||
}
|
||||
timer->timeElapsed();
|
||||
}
|
||||
|
||||
uint64 TeButtonLayout::timeFromLastValidation() {
|
||||
// probably not needed because we reimplemented how this works.
|
||||
error("TODO: Implement TeButtonLayout::timeFromLastValidation.");
|
||||
}
|
||||
|
||||
void TeButtonLayout::setDisabledLayout(TeLayout *disabledLayout) {
|
||||
if (_disabledLayout)
|
||||
removeChild(_disabledLayout);
|
||||
|
||||
_disabledLayout = disabledLayout;
|
||||
if (_disabledLayout) {
|
||||
_sizeChanged = true;
|
||||
addChild(_disabledLayout);
|
||||
//_disabledLayout->setColor(TeColor(0, 0, 0, 0));
|
||||
//_disabledLayout->setName(name() + "_disabledLayout");
|
||||
}
|
||||
|
||||
setState(_currentState);
|
||||
}
|
||||
|
||||
void TeButtonLayout::setHitZone(TeLayout *hitZoneLayout) {
|
||||
if (_hitZoneLayout)
|
||||
removeChild(_hitZoneLayout);
|
||||
|
||||
_hitZoneLayout = hitZoneLayout;
|
||||
if (_hitZoneLayout) {
|
||||
_sizeChanged = true;
|
||||
addChild(_hitZoneLayout);
|
||||
//_hitZoneLayout->setColor(TeColor(0, 0, 0xff, 0xff));
|
||||
//_hitZoneLayout->setName(name() + "_hitZoneLayout");
|
||||
}
|
||||
}
|
||||
|
||||
void TeButtonLayout::setDownLayout(TeLayout *downLayout) {
|
||||
if (_downLayout)
|
||||
removeChild(_downLayout);
|
||||
|
||||
if (downLayout)
|
||||
addChild(downLayout);
|
||||
_downLayout = downLayout;
|
||||
|
||||
if (sizeType() == ABSOLUTE &&
|
||||
size().x() == 1.0f && size().y() == 1.0f &&
|
||||
!_upLayout && _downLayout) {
|
||||
setSize(_downLayout->size());
|
||||
}
|
||||
|
||||
//if (_downLayout) {
|
||||
// _downLayout->setColor(TeColor(0, 0, 0, 0));
|
||||
//_downLayout->setName(name() + "_downLayout");
|
||||
//}
|
||||
|
||||
setState(_currentState);
|
||||
}
|
||||
|
||||
void TeButtonLayout::setRollOverLayout(TeLayout *rollOverLayout) {
|
||||
if (_rolloverLayout)
|
||||
removeChild(_rolloverLayout);
|
||||
|
||||
_rolloverLayout = rollOverLayout;
|
||||
if (_rolloverLayout) {
|
||||
addChild(_rolloverLayout);
|
||||
//_rolloverLayout->setName(name() + "_rolloverLayout");
|
||||
}
|
||||
|
||||
// This is not a copy paste error, or at least, not *my*
|
||||
// copy paste error.. it's what the original game does.
|
||||
//if (_disabledLayout)
|
||||
// _disabledLayout->setColor(TeColor(0, 0, 0, 0));
|
||||
|
||||
setState(_currentState);
|
||||
}
|
||||
|
||||
void TeButtonLayout::setUpLayout(TeLayout *upLayout) {
|
||||
if (_upLayout)
|
||||
removeChild(_upLayout);
|
||||
|
||||
if (upLayout)
|
||||
addChild(upLayout);
|
||||
_upLayout = upLayout;
|
||||
|
||||
if (sizeType() == ABSOLUTE &&
|
||||
size().x() == 1.0f && size().y() == 1.0f &&
|
||||
!_downLayout && _upLayout) {
|
||||
setSize(_upLayout->size());
|
||||
}
|
||||
|
||||
if (_upLayout) {
|
||||
//_upLayout->setColor(TeColor(0, 0, 0, 0));
|
||||
//_upLayout->setName(name() + "_upLayout");
|
||||
}
|
||||
|
||||
setState(_currentState);
|
||||
}
|
||||
|
||||
void TeButtonLayout::setDoubleValidationProtectionEnabled(bool enable) {
|
||||
_doubleValidationProtectionEnabled = enable;
|
||||
}
|
||||
|
||||
void TeButtonLayout::setEnable(bool enable) {
|
||||
if (enable && _currentState == BUTTON_STATE_DISABLED) {
|
||||
_currentState = BUTTON_STATE_UP;
|
||||
setState(_currentState);
|
||||
} else if (!enable && _currentState != BUTTON_STATE_DISABLED) {
|
||||
_currentState = BUTTON_STATE_DISABLED;
|
||||
setState(_currentState);
|
||||
}
|
||||
}
|
||||
|
||||
void TeButtonLayout::setPosition(const TeVector3f32 &pos) {
|
||||
TeLayout::setPosition(pos);
|
||||
|
||||
if (_currentState != BUTTON_STATE_DISABLED) {
|
||||
//int somethingCount = 0;
|
||||
if (!_intArr.empty()) {
|
||||
// probably not needed as we reimplememted how this works.
|
||||
error("TODO: Implement setPosition logic for up/down state");
|
||||
}
|
||||
// Original does something like this, but that breaks in
|
||||
// Amerzone where the button position can move during a click.
|
||||
//if (!_ignoreMouseEvents) {
|
||||
// setState(somethingCount ? BUTTON_STATE_DOWN : BUTTON_STATE_UP);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
void TeButtonLayout::setState(State newState) {
|
||||
if (_currentState != newState) {
|
||||
switch (newState) {
|
||||
case BUTTON_STATE_UP:
|
||||
_onButtonChangedToStateUpSignal.call();
|
||||
break;
|
||||
case BUTTON_STATE_DOWN:
|
||||
_onButtonChangedToStateDownSignal.call();
|
||||
break;
|
||||
case BUTTON_STATE_ROLLOVER:
|
||||
_onButtonChangedToStateRolloverSignal.call();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_currentState = newState;
|
||||
}
|
||||
|
||||
if (_upLayout)
|
||||
_upLayout->setVisible(_currentState == BUTTON_STATE_UP
|
||||
|| (_currentState == BUTTON_STATE_ROLLOVER && _rolloverLayout == nullptr)
|
||||
|| (_currentState == BUTTON_STATE_DOWN && _downLayout == nullptr)
|
||||
|| (_currentState == BUTTON_STATE_DISABLED && _disabledLayout == nullptr));
|
||||
if (_downLayout)
|
||||
_downLayout->setVisible(_currentState == BUTTON_STATE_DOWN);
|
||||
if (_disabledLayout)
|
||||
_disabledLayout->setVisible(_currentState == BUTTON_STATE_DISABLED);
|
||||
if (_rolloverLayout)
|
||||
_rolloverLayout->setVisible(_currentState == BUTTON_STATE_ROLLOVER);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
141
engines/tetraedge/te/te_button_layout.h
Normal file
141
engines/tetraedge/te/te_button_layout.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_BUTTON_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_BUTTON_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_callback.h"
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
#include "tetraedge/te/te_timer.h"
|
||||
|
||||
#include "common/path.h"
|
||||
|
||||
namespace Common {
|
||||
struct Point;
|
||||
}
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeButtonLayout : public TeLayout {
|
||||
public:
|
||||
TeButtonLayout();
|
||||
|
||||
virtual ~TeButtonLayout();
|
||||
|
||||
enum State {
|
||||
BUTTON_STATE_UP = 0,
|
||||
BUTTON_STATE_DOWN = 1,
|
||||
BUTTON_STATE_DISABLED = 2,
|
||||
BUTTON_STATE_ROLLOVER = 3
|
||||
};
|
||||
|
||||
uint64 doubleValidationProtectionTimeoutTime() { return 500; }
|
||||
uint64 frozenValidationTimeoutTime() { return 500; }
|
||||
|
||||
virtual bool isMouseIn(const TeVector2s32 &mouseloc) override;
|
||||
bool onMouseLeftDown(const Common::Point &pt);
|
||||
bool onMouseLeftDownMaxPriority(const Common::Point &pt) { return false; }
|
||||
bool onMouseLeftUp(const Common::Point &pt);
|
||||
bool onMouseLeftUpMaxPriority(const Common::Point &pt) { return false; }
|
||||
bool onMousePositionChanged(const Common::Point &pt);
|
||||
bool onMousePositionChangedMaxPriority(const Common::Point &pt) {
|
||||
_mousePositionChangedCatched = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
void resetTimeFromLastValidation();
|
||||
uint64 timeFromLastValidation();
|
||||
|
||||
void setDisabledLayout(TeLayout *disabledLayout);
|
||||
void setHitZone(TeLayout *hitZoneLayout);
|
||||
void setDownLayout(TeLayout *downLayout);
|
||||
void setRollOverLayout(TeLayout *rollOverLayout);
|
||||
void setUpLayout(TeLayout *upLayout);
|
||||
|
||||
void setDoubleValidationProtectionEnabled(bool enable);
|
||||
void setEnable(bool enable);
|
||||
virtual void setPosition(const TeVector3f32 &pos) override;
|
||||
|
||||
void setClickPassThrough(bool val) {
|
||||
_clickPassThrough = val;
|
||||
}
|
||||
void setValidationSound(const Common::Path &val) {
|
||||
_validationSound = val;
|
||||
}
|
||||
void setValidationSoundVolume(float val) {
|
||||
_validationSoundVolume = val;
|
||||
}
|
||||
|
||||
void setState(State newState);
|
||||
State state() const { return _currentState; };
|
||||
|
||||
TeSignal0Param &onMouseClickValidated() { return _onMouseClickValidatedSignal; };
|
||||
TeSignal0Param &onButtonChangedToStateUpSignal() { return _onButtonChangedToStateUpSignal; };
|
||||
TeSignal0Param &onButtonChangedToStateDownSignal() { return _onButtonChangedToStateDownSignal; };
|
||||
TeSignal0Param &onButtonChangedToStateRolloverSignal() { return _onButtonChangedToStateRolloverSignal; };
|
||||
|
||||
TeLayout *upLayout() { return _upLayout; }
|
||||
TeLayout *downLayout() { return _downLayout; }
|
||||
void setIgnoreMouseEvents(bool val) { _ignoreMouseEvents = val; }
|
||||
|
||||
// From TeSpriteButton, a direct way to load the images.
|
||||
void load(const Common::Path &upImg, const Common::Path &downImg, const Common::Path &overImg);
|
||||
|
||||
private:
|
||||
static bool _mousePositionChangedCatched;
|
||||
static TeTimer *getDoubleValidationProtectionTimer();
|
||||
static TeTimer *_doubleValidationProtectionTimer;
|
||||
|
||||
bool _doubleValidationProtectionEnabled;
|
||||
bool _ignoreMouseEvents;
|
||||
bool _ownedLayouts;
|
||||
|
||||
bool _clickPassThrough;
|
||||
State _currentState;
|
||||
Common::Path _validationSound;
|
||||
float _validationSoundVolume;
|
||||
|
||||
Common::Array<uint> _intArr;
|
||||
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMousePositionChangedMaxPriorityCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMousePositionChangedCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftDownCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftUpMaxPriorityCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftUpCallback;
|
||||
|
||||
TeLayout *_rolloverLayout;
|
||||
TeLayout *_disabledLayout;
|
||||
TeLayout *_hitZoneLayout;
|
||||
TeLayout *_upLayout;
|
||||
TeLayout *_downLayout;
|
||||
|
||||
TeSignal0Param _onMouseClickValidatedSignal;
|
||||
TeSignal0Param _onButtonChangedToStateUpSignal;
|
||||
TeSignal0Param _onButtonChangedToStateDownSignal;
|
||||
TeSignal0Param _onButtonChangedToStateRolloverSignal;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_BUTTON_LAYOUT_H
|
||||
133
engines/tetraedge/te/te_callback.h
Normal file
133
engines/tetraedge/te/te_callback.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CALLBACK_H
|
||||
#define TETRAEDGE_TE_TE_CALLBACK_H
|
||||
|
||||
//#include "common/callback.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeICallback0Param {
|
||||
public:
|
||||
virtual ~TeICallback0Param() {}
|
||||
virtual bool operator()() = 0;
|
||||
virtual bool call() = 0;
|
||||
virtual float priority() const = 0;
|
||||
virtual bool equals(const TeICallback0Param *other) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* TeCallback is similar to Common::Callback, but it takes 0 parameters,
|
||||
* supports priority, and the function returns bool.
|
||||
*/
|
||||
template<class T> class TeCallback0Param : public TeICallback0Param {
|
||||
public:
|
||||
typedef bool(T::*TMethod)();
|
||||
protected:
|
||||
T *_object;
|
||||
TMethod _method;
|
||||
float _priority;
|
||||
public:
|
||||
TeCallback0Param(T *object, TMethod method, float priority_ = 0.0f): _object(object), _method(method), _priority(priority_) {}
|
||||
virtual ~TeCallback0Param() {}
|
||||
bool operator()() override { return (_object->*_method)(); }
|
||||
bool call() override { return (_object->*_method)(); }
|
||||
|
||||
virtual float priority() const override { return _priority; }
|
||||
|
||||
bool equals(const TeICallback0Param *other) const override {
|
||||
const TeCallback0Param<T> *o = dynamic_cast<const TeCallback0Param<T> *>(other);
|
||||
return o && _object == o->_object && _method == o->_method;
|
||||
}
|
||||
//virtual void setPriority()
|
||||
};
|
||||
|
||||
template<class T> class TeICallback1Param {
|
||||
public:
|
||||
virtual ~TeICallback1Param() {}
|
||||
virtual bool operator()(T data) = 0;
|
||||
virtual bool call(T data) = 0;
|
||||
virtual float &priority() = 0;
|
||||
virtual bool equals(const TeICallback1Param *other) const = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class T, typename S> class TeCallback1Param : public TeICallback1Param<S> {
|
||||
public:
|
||||
typedef bool(T::*TMethod)(S);
|
||||
protected:
|
||||
T *_object;
|
||||
TMethod _method;
|
||||
float _priority;
|
||||
public:
|
||||
TeCallback1Param(T *object, TMethod method, float priority_ = 0.0f): _object(object), _method(method), _priority(priority_) {}
|
||||
virtual ~TeCallback1Param() {}
|
||||
bool operator()(S data) override { return (_object->*_method)(data); }
|
||||
bool call(S data) override { return (_object->*_method)(data); }
|
||||
|
||||
virtual float &priority() override { return _priority; }
|
||||
|
||||
bool equals(const TeICallback1Param<S> *other) const override {
|
||||
const TeCallback1Param<T, S> *o = dynamic_cast<const TeCallback1Param<T, S> *>(other);
|
||||
return o && _object == o->_object && _method == o->_method;
|
||||
}
|
||||
//virtual void setPriority()
|
||||
};
|
||||
|
||||
|
||||
template<class S, class T> class TeICallback2Param {
|
||||
public:
|
||||
virtual ~TeICallback2Param() {}
|
||||
virtual bool operator()(S data1, T data2) = 0;
|
||||
virtual bool call(S data1, T data2) = 0;
|
||||
virtual float &priority() = 0;
|
||||
virtual bool equals(const TeICallback2Param *other) const = 0;
|
||||
};
|
||||
|
||||
|
||||
template<class C, class S, typename T> class TeCallback2Param : public TeICallback2Param<S, T> {
|
||||
public:
|
||||
typedef bool(C::*TMethod)(S, T);
|
||||
protected:
|
||||
C *_object;
|
||||
TMethod _method;
|
||||
float _priority;
|
||||
public:
|
||||
TeCallback2Param(C *object, TMethod method, float priority_ = 0.0f): _object(object), _method(method), _priority(priority_) {}
|
||||
virtual ~TeCallback2Param() {}
|
||||
bool operator()(S data1, T data2) override { return (_object->*_method)(data1, data2); }
|
||||
bool call(S data1, T data2) override { return (_object->*_method)(data1, data2); }
|
||||
|
||||
virtual float &priority() override { return _priority; }
|
||||
|
||||
bool equals(const TeICallback2Param<S, T> *other) const override {
|
||||
const TeCallback2Param<C, S, T> *o = dynamic_cast<const TeCallback2Param<C, S, T> *>(other);
|
||||
return o && _object == o->_object && _method == o->_method;
|
||||
}
|
||||
//virtual void setPriority()
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CALLBACK_H
|
||||
300
engines/tetraedge/te/te_camera.cpp
Normal file
300
engines/tetraedge/te/te_camera.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/* 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/file.h"
|
||||
#include "math/ray.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_camera.h"
|
||||
#include "tetraedge/te/te_camera_xml_parser.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeCamera::TeCamera() : _projectionMatrixType(0), _orthogonalParamL(0.0f),
|
||||
_orthogonalParamR(1.0f), _orthogonalParamT(1.0f), _orthogonalParamB(0.0f),
|
||||
_orthNearVal(10.0f), _orthFarVal(4000.0f), _transformA(0), /*_transformB(0),*/
|
||||
_fov(40.0f), _aspectRatio(1.0f), _viewportX(0), _viewportY(0), _viewportW(0),
|
||||
_viewportH(0)
|
||||
{
|
||||
}
|
||||
|
||||
void TeCamera::apply() {
|
||||
//debug("TeCamera::apply %13s mtype %d fov %.2f persp %.2f orth(%.2f %.2f) pos %s scale %s rot %s", name().c_str(),
|
||||
// _projectionMatrixType, _fov, _somePerspectiveVal, _orthNearVal, _orthFarVal,
|
||||
// position().dump().c_str(), scale().dump().c_str(), rotation().dump().c_str());
|
||||
applyProjection();
|
||||
applyTransformations();
|
||||
}
|
||||
|
||||
void TeCamera::applyProjection() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setCurrentCamera(this);
|
||||
renderer->setViewport(_viewportX, _viewportY,
|
||||
(uint)(_viewportW * _scale.x()), (uint)(_viewportH * _scale.y()));
|
||||
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_PROJECTION);
|
||||
updateProjectionMatrix();
|
||||
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_PROJECTION);
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void TeCamera::applyTransformations() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_MODELVIEW);
|
||||
TeMatrix4x4 matrix = worldTransformationMatrix();
|
||||
matrix.inverse();
|
||||
renderer->loadMatrix(matrix);
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
}
|
||||
|
||||
void TeCamera::buildOrthoMatrix() {
|
||||
float widthNorm = FLT_MAX;
|
||||
if ((_orthogonalParamR - _orthogonalParamL) != 0.0) {
|
||||
widthNorm = 1.0 / (_orthogonalParamR - _orthogonalParamL);
|
||||
}
|
||||
float heightNorm = FLT_MAX;
|
||||
if (_orthogonalParamB - _orthogonalParamT != 0.0) {
|
||||
heightNorm = 1.0 / (_orthogonalParamB - _orthogonalParamT);
|
||||
}
|
||||
float depthNorm = FLT_MAX;
|
||||
if ((_orthFarVal - _orthNearVal) != 0.0) {
|
||||
depthNorm = 1.0 / (_orthFarVal - _orthNearVal);
|
||||
}
|
||||
|
||||
_projectionMatrix.setValue(0, 0, widthNorm * 2.0f);
|
||||
_projectionMatrix.setValue(1, 0, 0.0);
|
||||
_projectionMatrix.setValue(2, 0, 0.0);
|
||||
_projectionMatrix.setValue(3, 0, 0.0);
|
||||
|
||||
_projectionMatrix.setValue(0, 1, 0.0);
|
||||
_projectionMatrix.setValue(1, 1, heightNorm * 2.0f);
|
||||
_projectionMatrix.setValue(2, 1, 0.0);
|
||||
_projectionMatrix.setValue(3, 1, 0.0);
|
||||
|
||||
_projectionMatrix.setValue(0, 2, 0.0);
|
||||
_projectionMatrix.setValue(1, 2, 0.0);
|
||||
_projectionMatrix.setValue(2, 2, depthNorm * -2.0f);
|
||||
_projectionMatrix.setValue(3, 2, 0.0);
|
||||
|
||||
_projectionMatrix.setValue(0, 3, -((_orthogonalParamR + _orthogonalParamL) * widthNorm));
|
||||
_projectionMatrix.setValue(1, 3, -((_orthogonalParamB + _orthogonalParamT) * heightNorm));
|
||||
_projectionMatrix.setValue(2, 3, -((_orthFarVal + _orthNearVal) * depthNorm));
|
||||
_projectionMatrix.setValue(3, 3, 1.0);
|
||||
}
|
||||
|
||||
void TeCamera::buildPerspectiveMatrix() {
|
||||
_projectionMatrix = TeMatrix4x4();
|
||||
float f = tanf(_fov * 0.5);
|
||||
_projectionMatrix.setValue(0, 0, (1.0 / f) / ((float)_viewportW / _viewportH));
|
||||
_projectionMatrix.setValue(1, 1, 1.0 / f);
|
||||
_projectionMatrix.setValue(2, 2, (_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(3, 2, (_orthNearVal * _orthFarVal) / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(2, 3, -1);
|
||||
_projectionMatrix.setValue(3, 3, 0.0);
|
||||
}
|
||||
|
||||
void TeCamera::buildPerspectiveMatrix2() {
|
||||
_projectionMatrix = TeMatrix4x4();
|
||||
float f = tanf(_fov * 0.5);
|
||||
_projectionMatrix.setValue(0, 0, 1.0 / f);
|
||||
_projectionMatrix.setValue(1, 1, _aspectRatio / f);
|
||||
_projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(3, 2, 1.0);
|
||||
_projectionMatrix.setValue(2, 3, (_orthFarVal * 2) * _orthNearVal / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(3, 3, 0.0);
|
||||
}
|
||||
|
||||
void TeCamera::buildPerspectiveMatrix3() {
|
||||
_projectionMatrix = TeMatrix4x4();
|
||||
float f = tanf(_fov * 0.5);
|
||||
_projectionMatrix.setValue(0, 0, (1.0 / f) / _aspectRatio);
|
||||
_projectionMatrix.setValue(1, 1, 1.0 / f);
|
||||
_projectionMatrix.setValue(2, 2, -(_orthNearVal + _orthFarVal) / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(3, 2, 1.0);
|
||||
_projectionMatrix.setValue(2, 3, (_orthFarVal * 2) * _orthNearVal / (_orthNearVal - _orthFarVal));
|
||||
_projectionMatrix.setValue(3, 3, 0.0);
|
||||
}
|
||||
|
||||
void TeCamera::draw() {
|
||||
error("TODO: Implement TeCamera::draw");
|
||||
}
|
||||
|
||||
Math::Ray TeCamera::getRay(const TeVector2s32 &pxloc) {
|
||||
const Math::Vector3d origin = position();
|
||||
|
||||
// point offset relative to viewport
|
||||
const float xval = (pxloc._x - _viewportX) / fabs(_viewportW);
|
||||
const float yval = (_viewportH - (pxloc._y - _viewportY)) / fabs(_viewportH);
|
||||
|
||||
// normalized to -1..1
|
||||
const TeVector3f32 projectedPoint(xval * 2.0f - 1.0f, yval * 2.0f - 1.0f, 1.0f);
|
||||
|
||||
TeMatrix4x4 projInverse = _projectionMatrix;
|
||||
bool inverted = projInverse.inverse();
|
||||
if (!inverted)
|
||||
error("failed to invert camera projection");
|
||||
TeVector3f32 unprojectedPoint = projInverse * projectedPoint;
|
||||
unprojectedPoint.normalize();
|
||||
|
||||
TeQuaternion rot = _rotation;
|
||||
rot.normalize();
|
||||
TeMatrix4x4 rotMatrix = rot.toTeMatrix();
|
||||
TeVector3f32 rayDir = rotMatrix * unprojectedPoint;
|
||||
Math::Ray ray(origin, rayDir);
|
||||
return ray;
|
||||
}
|
||||
|
||||
void TeCamera::loadXml(const Common::Path &path) {
|
||||
setName(path.baseName());
|
||||
_projectionMatrixType = 3;
|
||||
TeCore *core = g_engine->getCore();
|
||||
TetraedgeFSNode cameraNode = core->findFile(path);
|
||||
if (!cameraNode.isReadable()) {
|
||||
//
|
||||
// WORKAROUND: scenes/A3_Village/34015 has Camera34010, not 34015
|
||||
//
|
||||
Common::String spath = path.toString();
|
||||
size_t pos = spath.find("34015.xml");
|
||||
if (pos != Common::String::npos) {
|
||||
spath.replace(pos + 4, 1, "0");
|
||||
}
|
||||
cameraNode = core->findFile(Common::Path(spath, '/'));
|
||||
}
|
||||
if (!cameraNode.isReadable()) {
|
||||
warning("Can't open camera data %s", cameraNode.toString().c_str());
|
||||
}
|
||||
TeCameraXmlParser parser;
|
||||
parser._cam = this;
|
||||
if (!cameraNode.loadXML(parser))
|
||||
error("TeCamera::loadXml: can't load file %s", cameraNode.toString().c_str());
|
||||
if (!parser.parse())
|
||||
error("TeCamera::loadXml: error parsing %s", cameraNode.toString().c_str());
|
||||
}
|
||||
|
||||
void TeCamera::orthogonalParams(float left, float right, float top, float bottom) {
|
||||
_orthogonalParamL = left;
|
||||
_orthogonalParamR = right;
|
||||
_orthogonalParamT = top;
|
||||
_orthogonalParamB = bottom;
|
||||
}
|
||||
|
||||
TeMatrix4x4 TeCamera::projectionMatrix() {
|
||||
switch(_projectionMatrixType) {
|
||||
case 1:
|
||||
buildPerspectiveMatrix();
|
||||
break;
|
||||
case 2:
|
||||
buildPerspectiveMatrix2();
|
||||
break;
|
||||
case 3:
|
||||
buildPerspectiveMatrix3();
|
||||
break;
|
||||
case 4:
|
||||
buildOrthoMatrix();
|
||||
break;
|
||||
}
|
||||
return _projectionMatrix;
|
||||
}
|
||||
|
||||
TeVector2f32 TeCamera::projectPoint(const TeVector3f32 &pt) {
|
||||
_rotation.normalize();
|
||||
TeMatrix4x4 worldInverse = worldTransformationMatrix();
|
||||
worldInverse.inverse();
|
||||
const TeVector3f32 projectedPt = _projectionMatrix * worldInverse * pt;
|
||||
int halfViewportW = (int)_viewportW / 2;
|
||||
int halfViewportH = (int)_viewportH / 2;
|
||||
|
||||
float projectedX = halfViewportW * (projectedPt.x() + 1.0) + _viewportX;
|
||||
float projectedY = halfViewportH * (1.0 - projectedPt.y()) + _viewportY;
|
||||
return TeVector2f32(projectedX, projectedY);
|
||||
}
|
||||
|
||||
TeVector3f32 TeCamera::projectPoint3f32(const TeVector3f32 &pt) {
|
||||
_rotation.normalize();
|
||||
TeMatrix4x4 worldInverse = worldTransformationMatrix();
|
||||
worldInverse.inverse();
|
||||
const TeVector3f32 projectedPt = _projectionMatrix * worldInverse * pt;
|
||||
int halfViewportW = (int)_viewportW / 2;
|
||||
int halfViewportH = (int)_viewportH / 2;
|
||||
|
||||
float projectedX = halfViewportW * (projectedPt.x() + 1.0) + _viewportX;
|
||||
float projectedY = halfViewportH * (1.0 - projectedPt.y()) + _viewportY;
|
||||
return TeVector3f32(projectedX, projectedY, projectedPt.z());
|
||||
}
|
||||
|
||||
void TeCamera::restore() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setCurrentColor(TeColor(255, 255, 255, 255));
|
||||
renderer->setCurrentCamera(nullptr);
|
||||
}
|
||||
|
||||
TeMatrix4x4 TeCamera::transformationMatrix() {
|
||||
if (!_transformA)
|
||||
return Te3DObject2::transformationMatrix();
|
||||
|
||||
TeMatrix4x4 retval;
|
||||
warning("TODO: Implement TeCamera::transformationMatrix");
|
||||
|
||||
retval.setToIdentity();
|
||||
return retval;
|
||||
}
|
||||
|
||||
TeVector3f32 TeCamera::transformCoord(const TeVector3f32 &pt) {
|
||||
_rotation.normalize();
|
||||
TeQuaternion rot(-_rotation.x(), -_rotation.y(), -_rotation.z(), _rotation.w());
|
||||
const TeMatrix4x4 rotMatrix = rot.toTeMatrix();
|
||||
const TeVector3f32 transPt = (_projectionMatrix * rotMatrix) * pt;
|
||||
const int halfVPWidth = abs((int)(_viewportW / 2));
|
||||
const int halfVPHeight = abs((int)(_viewportH / 2));
|
||||
TeVector3f32 retval;
|
||||
retval.x() = halfVPWidth * (transPt.x() + 1);
|
||||
retval.y() = halfVPHeight * (transPt.y() + 1);
|
||||
retval.z() = transPt.z();
|
||||
return retval;
|
||||
}
|
||||
|
||||
TeVector3f32 TeCamera::transformPoint2Dto3D(const TeVector3f32 &pt) {
|
||||
TeVector3f32 retval;
|
||||
TeVector3f32 vp_br(_viewportX + _viewportW, _viewportY + _viewportH, 0.0f);
|
||||
float x = (pt.x() - _viewportX) / (vp_br.x() - _viewportX);
|
||||
float y = (pt.y() - _viewportY) / (vp_br.y() - _viewportY);
|
||||
return TeVector3f32(x * 2 - 1.0f, -(y * 2 - 1.0f), 0.0);
|
||||
}
|
||||
|
||||
void TeCamera::updateProjectionMatrix() {
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->setMatrixMode(TeRenderer::MatrixMode::MM_GL_PROJECTION);
|
||||
renderer->loadProjectionMatrix(projectionMatrix());
|
||||
}
|
||||
|
||||
void TeCamera::viewport(int x, int y, uint w, uint h) {
|
||||
_viewportX = x;
|
||||
_viewportY = y;
|
||||
_viewportW = w;
|
||||
_viewportH = h;
|
||||
_onViewportChangedSignal.call();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
116
engines/tetraedge/te/te_camera.h
Normal file
116
engines/tetraedge/te/te_camera.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CAMERA_H
|
||||
#define TETRAEDGE_TE_TE_CAMERA_H
|
||||
|
||||
#include "common/path.h"
|
||||
#include "common/str.h"
|
||||
#include "math/ray.h"
|
||||
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_references_counter.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
#include "tetraedge/te/te_vector2f32.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeCamera : public Te3DObject2, public TeReferencesCounter {
|
||||
public:
|
||||
TeCamera();
|
||||
|
||||
void apply();
|
||||
void applyProjection();
|
||||
void applyTransformations();
|
||||
void buildOrthoMatrix();
|
||||
void buildPerspectiveMatrix();
|
||||
void buildPerspectiveMatrix2();
|
||||
void buildPerspectiveMatrix3();
|
||||
void draw() override;
|
||||
|
||||
Math::Ray getRay(const TeVector2s32 &pxloc);
|
||||
|
||||
// Syberia 2 redefines loadBin to actually load XML.
|
||||
// We just have a separate function.
|
||||
void loadXml(const Common::Path &path);
|
||||
|
||||
void orthogonalParams(float f1, float f2, float f3, float f4);
|
||||
TeMatrix4x4 projectionMatrix();
|
||||
|
||||
TeVector2f32 projectPoint(const TeVector3f32 &pt);
|
||||
TeVector3f32 projectPoint3f32(const TeVector3f32 &pt);
|
||||
|
||||
static void restore();
|
||||
TeMatrix4x4 transformationMatrix();
|
||||
TeVector3f32 transformCoord(const TeVector3f32 &pt);
|
||||
TeVector3f32 transformPoint2Dto3D(const TeVector3f32 &pt);
|
||||
|
||||
void viewport(int x, int y, uint width, uint height);
|
||||
TeVector2f32 viewportSize() const { return TeVector2f32(_viewportW, _viewportH); }
|
||||
|
||||
TeSignal0Param &onViewportChangedSignal() { return _onViewportChangedSignal; }
|
||||
|
||||
void setFov(float fov) { _fov = fov; }
|
||||
void setOrthoPlanes(float near, float far) {
|
||||
_orthFarVal = far;
|
||||
_orthNearVal = near;
|
||||
}
|
||||
void setProjMatrixType(int matrixType) { _projectionMatrixType = matrixType; }
|
||||
int projMatrixType() const { return _projectionMatrixType; }
|
||||
void setAspectRatio(float val) { _aspectRatio = val; }
|
||||
float orthoNearPlane() const { return _orthNearVal; }
|
||||
float orthoFarPlane() const { return _orthFarVal; }
|
||||
void setOrthoNear(float f) { _orthNearVal = f; }
|
||||
void setOrthoFar(float f) { _orthFarVal = f; }
|
||||
float getViewportHeight() const { return _viewportH; }
|
||||
float getViewportWidth() const { return _viewportW; }
|
||||
|
||||
private:
|
||||
void updateProjectionMatrix();
|
||||
|
||||
int _projectionMatrixType; // TODO: Should be an enum.
|
||||
float _orthNearVal;
|
||||
float _orthFarVal;
|
||||
float _fov;
|
||||
float _aspectRatio;
|
||||
|
||||
int _viewportX;
|
||||
int _viewportY;
|
||||
uint _viewportW;
|
||||
uint _viewportH;
|
||||
|
||||
int _transformA;
|
||||
|
||||
float _orthogonalParamL;
|
||||
float _orthogonalParamR;
|
||||
float _orthogonalParamT;
|
||||
float _orthogonalParamB;
|
||||
|
||||
TeMatrix4x4 _projectionMatrix;
|
||||
|
||||
TeSignal0Param _onViewportChangedSignal;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CAMERA_H
|
||||
68
engines/tetraedge/te/te_camera_xml_parser.cpp
Normal file
68
engines/tetraedge/te/te_camera_xml_parser.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 "tetraedge/te/te_camera_xml_parser.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_position(ParserNode *node) {
|
||||
_cam->setPosition(parsePoint(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_rotation(ParserNode *node) {
|
||||
float x = atof(node->values["x"].c_str());
|
||||
float y = atof(node->values["y"].c_str());
|
||||
float z = atof(node->values["z"].c_str());
|
||||
float w = atof(node->values["w"].c_str());
|
||||
_cam->setRotation(TeQuaternion(x, y, z, w));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_scale(ParserNode *node) {
|
||||
_cam->setScale(parsePoint(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_fov(ParserNode *node) {
|
||||
float fov = parseDouble(node);
|
||||
fov = atanf(1.0f / (1.333333f / tanf(fov / 2)));
|
||||
_cam->setFov(fov * 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_aspect(ParserNode *node) {
|
||||
_cam->setAspectRatio(parseDouble(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_near(ParserNode *node) {
|
||||
_cam->setOrthoNear(parseDouble(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeCameraXmlParser::parserCallback_far(ParserNode *node) {
|
||||
_cam->setOrthoFar(parseDouble(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
81
engines/tetraedge/te/te_camera_xml_parser.h
Normal file
81
engines/tetraedge/te/te_camera_xml_parser.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CAMERA_XML_PARSER_H
|
||||
#define TETRAEDGE_TE_TE_CAMERA_XML_PARSER_H
|
||||
|
||||
#include "tetraedge/te/te_xml_parser.h"
|
||||
#include "tetraedge/te/te_camera.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeCameraXmlParser : public TeXmlParser {
|
||||
public:
|
||||
// Parser
|
||||
CUSTOM_XML_PARSER(TeCameraXmlParser) {
|
||||
XML_KEY(camera)
|
||||
XML_KEY(position)
|
||||
XML_PROP(x, true)
|
||||
XML_PROP(y, true)
|
||||
XML_PROP(z, true)
|
||||
KEY_END()
|
||||
XML_KEY(rotation)
|
||||
XML_PROP(x, true)
|
||||
XML_PROP(y, true)
|
||||
XML_PROP(z, true)
|
||||
XML_PROP(w, true)
|
||||
KEY_END()
|
||||
XML_KEY(scale)
|
||||
XML_PROP(x, true)
|
||||
XML_PROP(y, true)
|
||||
XML_PROP(z, true)
|
||||
KEY_END()
|
||||
XML_KEY(fov)
|
||||
XML_PROP(value, true)
|
||||
KEY_END()
|
||||
XML_KEY(aspect)
|
||||
XML_PROP(value, true)
|
||||
KEY_END()
|
||||
XML_KEY(near)
|
||||
XML_PROP(value, true)
|
||||
KEY_END()
|
||||
XML_KEY(far)
|
||||
XML_PROP(value, true)
|
||||
KEY_END()
|
||||
KEY_END()
|
||||
} PARSER_END()
|
||||
|
||||
public:
|
||||
bool parserCallback_camera(ParserNode *node) { return true; }
|
||||
bool parserCallback_position(ParserNode *node);
|
||||
bool parserCallback_rotation(ParserNode *node);
|
||||
bool parserCallback_scale(ParserNode *node);
|
||||
bool parserCallback_fov(ParserNode *node);
|
||||
bool parserCallback_aspect(ParserNode *node);
|
||||
bool parserCallback_near(ParserNode *node);
|
||||
bool parserCallback_far(ParserNode *node);
|
||||
|
||||
TeCamera *_cam;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CAMERA_XML_PARSER_H
|
||||
258
engines/tetraedge/te/te_checkbox_layout.cpp
Normal file
258
engines/tetraedge/te/te_checkbox_layout.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_checkbox_layout.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_callback.h"
|
||||
#include "tetraedge/te/te_input_mgr.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeCheckboxLayout::TeCheckboxLayout() : _activeLayout(nullptr), _unactiveLayout(nullptr),
|
||||
_activeDisabledLayout(nullptr), _unactiveDisabledLayout(nullptr),
|
||||
_activeRollOverLayout(nullptr), _unactiveRollOverLayout(nullptr), _hitZone(nullptr),
|
||||
_clickPassThrough(false), _state(CheckboxState6)
|
||||
{
|
||||
_onMouseLeftUpCallback.reset(new TeCallback1Param<TeCheckboxLayout, const Common::Point &>(this, &TeCheckboxLayout::onMouseLeftUp));
|
||||
_onMouseLeftUpMaxPriorityCallback.reset(new TeCallback1Param<TeCheckboxLayout, const Common::Point &>(this, &TeCheckboxLayout::onMouseLeftUpMaxPriority));
|
||||
_onMouseLeftDownCallback.reset(new TeCallback1Param<TeCheckboxLayout, const Common::Point &>(this, &TeCheckboxLayout::onMouseLeftDown));
|
||||
_onMousePositionChangedCallback.reset(new TeCallback1Param<TeCheckboxLayout, const Common::Point &>(this, &TeCheckboxLayout::onMousePositionChanged));
|
||||
|
||||
TeInputMgr *inputmgr = g_engine->getInputMgr();
|
||||
inputmgr->_mouseMoveSignal.push_back(_onMousePositionChangedCallback);
|
||||
inputmgr->_mouseLDownSignal.push_back(_onMouseLeftDownCallback);
|
||||
inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpCallback);
|
||||
inputmgr->_mouseLUpSignal.push_back(_onMouseLeftUpMaxPriorityCallback);
|
||||
}
|
||||
|
||||
TeCheckboxLayout::~TeCheckboxLayout() {
|
||||
TeInputMgr *inputmgr = g_engine->getInputMgr();
|
||||
inputmgr->_mouseMoveSignal.remove(_onMousePositionChangedCallback);
|
||||
inputmgr->_mouseLDownSignal.remove(_onMouseLeftDownCallback);
|
||||
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpCallback);
|
||||
inputmgr->_mouseLUpSignal.remove(_onMouseLeftUpMaxPriorityCallback);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setActiveLayout(TeLayout *layout) {
|
||||
if (_activeLayout)
|
||||
removeChild(_activeLayout);
|
||||
_activeLayout = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setUnactiveLayout(TeLayout *layout) {
|
||||
if (_unactiveLayout)
|
||||
removeChild(_unactiveLayout);
|
||||
_unactiveLayout = layout;
|
||||
warning("TODO: Add extra code in TeCheckboxLayout::setUnactiveLayout.");
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setActiveDisabledLayout(TeLayout *layout) {
|
||||
if (_activeDisabledLayout)
|
||||
removeChild(_activeDisabledLayout);
|
||||
_activeDisabledLayout = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setUnactiveDisabledLayout(TeLayout *layout) {
|
||||
if (_unactiveDisabledLayout)
|
||||
removeChild(_unactiveDisabledLayout);
|
||||
_unactiveDisabledLayout = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setActiveRollOverLayout(TeLayout *layout) {
|
||||
if (_activeRollOverLayout)
|
||||
removeChild(_activeRollOverLayout);
|
||||
_activeRollOverLayout = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setUnactiveRollOverLayout(TeLayout *layout) {
|
||||
if (_unactiveRollOverLayout)
|
||||
removeChild(_unactiveRollOverLayout);
|
||||
_unactiveRollOverLayout = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0, 0));
|
||||
}
|
||||
setState(_state);
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setHitZone(TeLayout *layout) {
|
||||
if (_hitZone)
|
||||
removeChild(_hitZone);
|
||||
_hitZone = layout;
|
||||
if (layout) {
|
||||
addChild(layout);
|
||||
//layout->setColor(TeColor(0, 0, 0xff, 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TeCheckboxLayout::setClickPassThrough(bool val) {
|
||||
_clickPassThrough = val;
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setActivationSound(const Common::String &sound) {
|
||||
_activationSound = sound;
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setUnactivationSound(const Common::String &sound) {
|
||||
_unactivationSound = sound;
|
||||
}
|
||||
|
||||
bool TeCheckboxLayout::isMouseIn(const TeVector2s32 &pt) {
|
||||
if (_hitZone) {
|
||||
return _hitZone->isMouseIn(pt);
|
||||
} else {
|
||||
return TeLayout::isMouseIn(pt);
|
||||
}
|
||||
}
|
||||
|
||||
void TeCheckboxLayout::setState(enum State state) {
|
||||
if (_state == state)
|
||||
return;
|
||||
|
||||
_state = state;
|
||||
|
||||
if (_activeLayout)
|
||||
_activeLayout->setVisible(state == CheckboxStateActive);
|
||||
if (_unactiveLayout)
|
||||
_unactiveLayout->setVisible(state == CheckboxStateUnactive);
|
||||
if (_activeRollOverLayout)
|
||||
_activeRollOverLayout->setVisible(state == CheckboxStateActiveRollover);
|
||||
if (_unactiveRollOverLayout)
|
||||
_unactiveRollOverLayout->setVisible(state == CheckboxStateUnactiveRollover);
|
||||
if (_activeDisabledLayout)
|
||||
_activeDisabledLayout->setVisible(state == CheckboxStateActiveDisabled);
|
||||
if (_unactiveDisabledLayout)
|
||||
_unactiveDisabledLayout->setVisible(state == CheckboxStateUnactiveDisabled);
|
||||
|
||||
_onStateChangedSignal.call(state);
|
||||
}
|
||||
|
||||
bool TeCheckboxLayout::onMouseLeftUp(const Common::Point &pt) {
|
||||
if (!worldVisible())
|
||||
return false;
|
||||
|
||||
bool mouseIn = isMouseIn(pt);
|
||||
|
||||
State newState = _state;
|
||||
|
||||
switch (_state) {
|
||||
case CheckboxStateActive:
|
||||
if (mouseIn)
|
||||
newState = CheckboxStateUnactive;
|
||||
break;
|
||||
case CheckboxStateUnactive:
|
||||
if (mouseIn)
|
||||
newState = CheckboxStateActive;
|
||||
break;
|
||||
case CheckboxStateActiveRollover:
|
||||
if (mouseIn)
|
||||
newState = CheckboxStateUnactiveRollover;
|
||||
else
|
||||
newState = CheckboxStateActive;
|
||||
break;
|
||||
case CheckboxStateUnactiveRollover:
|
||||
if (mouseIn)
|
||||
newState = CheckboxStateActiveRollover;
|
||||
else
|
||||
newState = CheckboxStateUnactive;
|
||||
break;
|
||||
case CheckboxStateActiveDisabled:
|
||||
case CheckboxStateUnactiveDisabled:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setState(newState);
|
||||
return !_clickPassThrough;
|
||||
}
|
||||
|
||||
bool TeCheckboxLayout::onMouseLeftUpMaxPriority(const Common::Point &pt) {
|
||||
if (!worldVisible())
|
||||
return false;
|
||||
|
||||
//bool mouseIn = isMouseIn(pt);
|
||||
|
||||
//error("TODO: Implement TeCheckboxLayout::onMouseLeftUpMaxPriority");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TeCheckboxLayout::onMouseLeftDown(const Common::Point &pt) {
|
||||
if (!worldVisible())
|
||||
return false;
|
||||
|
||||
//bool mouseIn = isMouseIn(pt);
|
||||
|
||||
//error("TODO: Implement TeCheckboxLayout::onMouseLeftDown");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TeCheckboxLayout::onMousePositionChanged(const Common::Point &pt) {
|
||||
if (!worldVisible())
|
||||
return false;
|
||||
|
||||
State newState = _state;
|
||||
bool mouseIn = isMouseIn(pt);
|
||||
|
||||
if (!mouseIn) {
|
||||
if (_state == CheckboxStateActiveRollover)
|
||||
newState = CheckboxStateActive;
|
||||
else if (_state == CheckboxStateUnactiveRollover)
|
||||
newState = CheckboxStateUnactive;
|
||||
} else {
|
||||
if (_state == CheckboxStateActive)
|
||||
newState = CheckboxStateActiveRollover;
|
||||
else if (_state == CheckboxStateUnactive)
|
||||
newState = CheckboxStateUnactiveRollover;
|
||||
}
|
||||
|
||||
setState(newState);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
89
engines/tetraedge/te/te_checkbox_layout.h
Normal file
89
engines/tetraedge/te/te_checkbox_layout.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CHECKBOX_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_CHECKBOX_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeCheckboxLayout : public TeLayout {
|
||||
public:
|
||||
TeCheckboxLayout();
|
||||
virtual ~TeCheckboxLayout();
|
||||
|
||||
enum State {
|
||||
CheckboxStateActive,
|
||||
CheckboxStateUnactive,
|
||||
CheckboxStateActiveDisabled,
|
||||
CheckboxStateUnactiveDisabled,
|
||||
CheckboxStateActiveRollover,
|
||||
CheckboxStateUnactiveRollover,
|
||||
CheckboxState6
|
||||
};
|
||||
|
||||
void setActiveLayout(TeLayout *layout);
|
||||
void setUnactiveLayout(TeLayout *layout);
|
||||
void setActiveDisabledLayout(TeLayout *layout);
|
||||
void setUnactiveDisabledLayout(TeLayout *layout);
|
||||
void setActiveRollOverLayout(TeLayout *layout);
|
||||
void setUnactiveRollOverLayout(TeLayout *layout);
|
||||
void setHitZone(TeLayout *layout);
|
||||
void setClickPassThrough(bool val);
|
||||
void setActivationSound(const Common::String &sound);
|
||||
void setUnactivationSound(const Common::String &sound);
|
||||
bool isMouseIn(const TeVector2s32 &pt) override;
|
||||
void setState(State state);
|
||||
|
||||
TeSignal1Param<State> &onStateChangedSignal() { return _onStateChangedSignal; }
|
||||
|
||||
bool onMouseLeftUp(const Common::Point &pt);
|
||||
bool onMouseLeftUpMaxPriority(const Common::Point &pt);
|
||||
bool onMouseLeftDown(const Common::Point &pt);
|
||||
bool onMousePositionChanged(const Common::Point &pt);
|
||||
|
||||
private:
|
||||
TeLayout *_activeLayout;
|
||||
TeLayout *_unactiveLayout;
|
||||
TeLayout *_activeDisabledLayout;
|
||||
TeLayout *_unactiveDisabledLayout;
|
||||
TeLayout *_activeRollOverLayout;
|
||||
TeLayout *_unactiveRollOverLayout;
|
||||
TeLayout *_hitZone;
|
||||
|
||||
bool _clickPassThrough;
|
||||
Common::String _activationSound;
|
||||
Common::String _unactivationSound;
|
||||
State _state;
|
||||
TeSignal1Param<State> _onStateChangedSignal;
|
||||
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftUpCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftUpMaxPriorityCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMouseLeftDownCallback;
|
||||
TeICallback1ParamPtr<const Common::Point &> _onMousePositionChangedCallback;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CHECKBOX_LAYOUT_H
|
||||
65
engines/tetraedge/te/te_clip_layout.cpp
Normal file
65
engines/tetraedge/te/te_clip_layout.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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 "tetraedge/te/te_clip_layout.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/game/application.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeClipLayout::TeClipLayout() {
|
||||
}
|
||||
|
||||
void TeClipLayout::draw() {
|
||||
if (!worldVisible())
|
||||
return;
|
||||
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
bool prevScissorEnabled = renderer->scissorEnabled();
|
||||
const TeVector2f32 prevScissorPos(renderer->scissorX(), renderer->scissorY());
|
||||
const TeVector2f32 prevScissorSize(renderer->scissorWidth(), renderer->scissorHeight());
|
||||
|
||||
const TeMatrix4x4 worldTransform = worldTransformationMatrix();
|
||||
|
||||
const TeVector3f32 v1 = worldTransform * TeVector3f32(0, 0, 0);
|
||||
const TeVector3f32 v2 = worldTransform * TeVector3f32(1, 0, 0);
|
||||
const TeVector3f32 v3 = worldTransform * TeVector3f32(0, 1, 0);
|
||||
|
||||
const TeVector3f32 offset((v2 - v1).length(), (v3 - v1).length(), 1);
|
||||
const TeVector3f32 thisSize(xSize(), ySize(), 0);
|
||||
const TeVector3f32 newScissorSize = thisSize * offset;
|
||||
const TeVector3f32 transformedSize(v1.x() - newScissorSize.x() / 2, v1.y() + newScissorSize.y() / 2, 0);
|
||||
|
||||
const TeVector3f32 winSize = g_engine->getApplication()->getMainWindow().size();
|
||||
|
||||
const TeVector3f32 newScissorOff(transformedSize.x() + winSize.x() / 2, winSize.y() - (transformedSize.y() + winSize.y() / 2), 0);
|
||||
|
||||
renderer->setScissorEnabled(true);
|
||||
renderer->setScissor(newScissorOff.x(), newScissorOff.y(), newScissorSize.x(), newScissorSize.y());
|
||||
|
||||
TeLayout::draw();
|
||||
|
||||
renderer->setScissor(prevScissorPos.getX(), prevScissorPos.getY(), prevScissorSize.getX(), prevScissorSize.getY());
|
||||
renderer->setScissorEnabled(prevScissorEnabled);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
39
engines/tetraedge/te/te_clip_layout.h
Normal file
39
engines/tetraedge/te/te_clip_layout.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CLIP_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_CLIP_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
// Not used in Syberia1
|
||||
class TeClipLayout : public TeLayout {
|
||||
public:
|
||||
TeClipLayout();
|
||||
|
||||
virtual void draw() override;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CLIP_LAYOUT_H
|
||||
81
engines/tetraedge/te/te_color.cpp
Normal file
81
engines/tetraedge/te/te_color.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 "tetraedge/te/te_color.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeColor::TeColor() : _c{0, 0, 0, 0xff} {
|
||||
}
|
||||
|
||||
TeColor::TeColor(uint32 rgba) {
|
||||
_c[0] = (byte)(rgba >> 24);
|
||||
_c[1] = (byte)(rgba >> 16);
|
||||
_c[2] = (byte)(rgba >> 8);
|
||||
_c[3] = (byte)rgba;
|
||||
}
|
||||
|
||||
TeColor::TeColor(uint16 shortcol) {
|
||||
_c[0] = (byte)(shortcol >> 7) & 0xf8;
|
||||
_c[1] = (byte)(shortcol >> 2) & 0xf8;
|
||||
_c[2] = (byte)shortcol << 3;
|
||||
_c[3] = 0;
|
||||
}
|
||||
|
||||
TeColor::TeColor(byte r, byte g, byte b, byte a) : _c{r, g, b, a} {
|
||||
}
|
||||
|
||||
uint32 TeColor::getPacked() const {
|
||||
return (g() & 0xf8) << 2 | (r() & 0xf8) << 7 | (b() >> 3);
|
||||
}
|
||||
|
||||
uint32 TeColor::getPacked32() const {
|
||||
return (r() << 24) | (g() << 16) | (b() << 8) | a();
|
||||
}
|
||||
|
||||
bool TeColor::serialize(Common::WriteStream &stream) const {
|
||||
for (int i = 0; i < 4; i++)
|
||||
stream.writeByte(_c[i]);
|
||||
return true;
|
||||
}
|
||||
bool TeColor::deserialize(Common::ReadStream &stream) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
_c[i] = stream.readByte();
|
||||
return true;
|
||||
}
|
||||
|
||||
TeColor operator*(const TeColor &c1, const TeColor &c2) {
|
||||
return TeColor(
|
||||
((c2.r() * (c1.r() / 255.0)) / 255.0) * 255.0,
|
||||
((c2.g() * (c1.g() / 255.0)) / 255.0) * 255.0,
|
||||
((c2.b() * (c1.b() / 255.0)) / 255.0) * 255.0,
|
||||
((c2.a() * (c1.a() / 255.0)) / 255.0) * 255.0);
|
||||
}
|
||||
|
||||
TeColor operator*(const TeColor &c, double amount) {
|
||||
return TeColor(c.r() * amount, c.g() * amount, c.b() * amount, c.a() * amount);
|
||||
}
|
||||
|
||||
TeColor operator+(const TeColor &c1, const TeColor &c2) {
|
||||
return TeColor(c1.r() + c2.r(), c1.g() + c2.g(), c1.b() + c2.b(), c1.a() + c2.a());
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
76
engines/tetraedge/te/te_color.h
Normal file
76
engines/tetraedge/te/te_color.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_COLOR_H
|
||||
#define TETRAEDGE_TE_TE_COLOR_H
|
||||
|
||||
#include "common/types.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeColor {
|
||||
public:
|
||||
TeColor();
|
||||
TeColor(uint32 rgba);
|
||||
TeColor(uint16 shortcol);
|
||||
TeColor(byte r, byte g, byte b, byte a);
|
||||
|
||||
byte &r() { return _c[0]; };
|
||||
byte &g() { return _c[1]; };
|
||||
byte &b() { return _c[2]; };
|
||||
byte &a() { return _c[3]; };
|
||||
|
||||
const byte &r() const { return _c[0]; };
|
||||
const byte &g() const { return _c[1]; };
|
||||
const byte &b() const { return _c[2]; };
|
||||
const byte &a() const { return _c[3]; };
|
||||
|
||||
uint32 getPacked() const;
|
||||
uint32 getPacked32() const;
|
||||
|
||||
bool serialize(Common::WriteStream &stream) const;
|
||||
bool deserialize(Common::ReadStream &stream);
|
||||
|
||||
bool operator==(const TeColor &c) const {
|
||||
return (_c[0] == c._c[0] && _c[1] == c._c[1] &&
|
||||
_c[2] == c._c[2] && _c[3] == c._c[3]);
|
||||
}
|
||||
bool operator!=(const TeColor &c) {
|
||||
return !operator==(c);
|
||||
}
|
||||
|
||||
Common::String dump() const {
|
||||
return Common::String::format("TeColor(%d %d %d %d)",
|
||||
_c[0], _c[1], _c[2], _c[3]);
|
||||
}
|
||||
|
||||
private:
|
||||
byte _c[4];
|
||||
};
|
||||
|
||||
TeColor operator*(const TeColor &c1, const TeColor &c2);
|
||||
TeColor operator*(const TeColor &c1, double amount);
|
||||
TeColor operator+(const TeColor &c1, const TeColor &c2);
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_COLOR_H
|
||||
245
engines/tetraedge/te/te_core.cpp
Normal file
245
engines/tetraedge/te/te_core.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/* 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/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/language.h"
|
||||
#include "common/tokenizer.h"
|
||||
|
||||
#include "tetraedge/te/te_core.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_png.h"
|
||||
#include "tetraedge/te/te_images_sequence.h"
|
||||
#include "tetraedge/te/te_jpeg.h"
|
||||
#include "tetraedge/te/te_zlib_jpeg.h"
|
||||
#include "tetraedge/te/te_theora.h"
|
||||
#include "tetraedge/te/te_tga.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeCore::TeCore() : _loc(nullptr), _coreNotReady(true), _resourcesRoot("") {
|
||||
create();
|
||||
}
|
||||
|
||||
void TeCore::addLoc(TeILoc *loc) {
|
||||
if (_loc) {
|
||||
warning("TeCore::addLoc: There is already a loc");
|
||||
}
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
void TeCore::create() {
|
||||
const char *langCode = getLanguageCode(g_engine->getGameLanguage());
|
||||
const Common::String confLang = ConfMan.get("language");
|
||||
Common::String useLang = "en";
|
||||
if (langCode)
|
||||
useLang = langCode;
|
||||
if (!confLang.empty())
|
||||
useLang = confLang;
|
||||
language(useLang);
|
||||
_coreNotReady = false;
|
||||
_activityTrackingTimer.alarmSignal().add(this, &TeCore::onActivityTrackingAlarm);
|
||||
warning("TODO: TeCore::create: Finish implementing me.");
|
||||
|
||||
const Common::FSNode gameRoot(ConfMan.getPath("path"));
|
||||
if (!gameRoot.isDirectory())
|
||||
error("Game directory should be a directory");
|
||||
const Common::FSNode resNode = (g_engine->getGamePlatform() == Common::kPlatformMacintosh
|
||||
? gameRoot.getChild("Resources")
|
||||
: gameRoot);
|
||||
if (!resNode.isDirectory())
|
||||
error("Resources directory should exist in game");
|
||||
|
||||
_resourcesRoot = Common::FSDirectory(resNode, 5, false, false, true);
|
||||
}
|
||||
|
||||
TeICodec *TeCore::createVideoCodec(const Common::String &extn) {
|
||||
// The original engine has more formats and even checks for alpha maps,
|
||||
// but it never uses them.
|
||||
if (TePng::matchExtension(extn)) {
|
||||
// png codec needs to know extension
|
||||
return new TePng(extn);
|
||||
} else if (TeJpeg::matchExtension(extn)) {
|
||||
return new TeJpeg();
|
||||
} else if (TeZlibJpeg::matchExtension(extn)) {
|
||||
return new TeZlibJpeg();
|
||||
} else if (TeTheora::matchExtension(extn)) {
|
||||
return new TeTheora();
|
||||
} else if (TeTga::matchExtension(extn)) {
|
||||
return new TeTga();
|
||||
} else if (TeImagesSequence::matchExtension(extn)) {
|
||||
return new TeImagesSequence();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeICodec *TeCore::createVideoCodec(const TetraedgeFSNode &node, const Common::Path &origPath) {
|
||||
//
|
||||
// Need to use the original requested path (not the node path) as
|
||||
// it might include the #anim directive for animated pngs.
|
||||
//
|
||||
const Common::String filename = origPath.baseName();
|
||||
if (!filename.contains('.'))
|
||||
return nullptr;
|
||||
Common::String extn = filename.substr(filename.findLastOf('.') + 1);
|
||||
extn.toLowercase();
|
||||
TeICodec *codec = createVideoCodec(extn);
|
||||
if (!codec)
|
||||
error("TTeCore::createVideoCodec: Unrecognised format %s", filename.c_str());
|
||||
return codec;
|
||||
}
|
||||
|
||||
const Common::String &TeCore::fileFlagSystemFlag(const Common::String &name) const {
|
||||
return _fileSystemFlags.find(name)->_value;
|
||||
}
|
||||
|
||||
void TeCore::fileFlagSystemSetFlag(const Common::String &name, const Common::String &val) {
|
||||
// TODO: Impmenent this fully to check possible values
|
||||
_fileSystemFlags.setVal(name, val);
|
||||
}
|
||||
|
||||
bool TeCore::fileFlagSystemFlagsContains(const Common::String &name) const {
|
||||
error("TODO: Implement TeCore::fileFlagSystemFlagsContains");
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::Array<Common::String> TeCore::fileFlagSystemPossibleFlags() {
|
||||
error("TODO: Implement TeCore::fileFlagSystemPossibleFlags");
|
||||
return Common::Array<Common::String>();
|
||||
}
|
||||
|
||||
bool TeCore::fileFlagSystemPossibleFlagsContains(const Common::String &name) const {
|
||||
error("TODO: Implement TeCore::fileFlagSystemPossibleFlagsContains");
|
||||
return false;
|
||||
}
|
||||
|
||||
const Common::String &TeCore::language() const {
|
||||
return fileFlagSystemFlag("language");
|
||||
}
|
||||
|
||||
void TeCore::language(const Common::String &val) {
|
||||
return fileFlagSystemSetFlag("language", val);
|
||||
}
|
||||
|
||||
bool TeCore::onActivityTrackingAlarm() {
|
||||
error("TODO: Implement TeCore::onActivityTrackingAlarm");
|
||||
}
|
||||
|
||||
static bool _checkFileFlag(const Common::String &fname, const Common::HashMap<Common::String, bool, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> &activeTags) {
|
||||
Common::StringTokenizer tokenizer(fname, "-");
|
||||
while(!tokenizer.empty())
|
||||
if (activeTags.getValOrDefault(tokenizer.nextToken(), false))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void _findFileRecursively(const TetraedgeFSNode &parent,
|
||||
const Common::HashMap<Common::String, bool, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> &activeTags,
|
||||
const Common::String &fname,
|
||||
Common::Array<TetraedgeFSNode> &foundFiles,
|
||||
int maxDepth) {
|
||||
TetraedgeFSNode child = parent.getChild(Common::Path(fname, '/'));
|
||||
if (child.exists())
|
||||
foundFiles.push_back(child);
|
||||
|
||||
if (maxDepth <= 0)
|
||||
return;
|
||||
|
||||
TetraedgeFSList list;
|
||||
if (!parent.getChildren(list))
|
||||
return;
|
||||
|
||||
for (TetraedgeFSList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||
if (_checkFileFlag(it->getName(), activeTags))
|
||||
_findFileRecursively(*it, activeTags, fname, foundFiles, maxDepth - 1);
|
||||
}
|
||||
|
||||
TetraedgeFSNode TeCore::findFile(const Common::Path &path, bool quiet) const {
|
||||
Common::Array<TetraedgeFSNode> dirNodes;
|
||||
const Common::Path dir = path.getParent();
|
||||
|
||||
TetraedgeFSNode node;
|
||||
|
||||
const Common::Array<Common::Archive *> &roots = g_engine->getRootArchives();
|
||||
for (Common::Archive *const archive : roots) {
|
||||
TetraedgeFSNode archiveNode(archive);
|
||||
node = archiveNode.getChild(path);
|
||||
if (node.exists())
|
||||
return node;
|
||||
dirNodes.push_back(archiveNode.getChild(dir));
|
||||
}
|
||||
|
||||
Common::String fname = path.getLastComponent().toString();
|
||||
|
||||
// Slight HACK: Remove 'comments' used to specify animated pngs
|
||||
if (fname.contains('#'))
|
||||
fname = fname.substr(0, fname.find('#'));
|
||||
|
||||
Common::HashMap<Common::String, bool, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> activeFlags;
|
||||
|
||||
for (Common::HashMap<Common::String, Common::String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo>::const_iterator it = _fileSystemFlags.begin();
|
||||
it != _fileSystemFlags.end(); it++)
|
||||
activeFlags[it->_value] = true;
|
||||
|
||||
// This is to minimize functionality changes from the previous implementation.
|
||||
// I'm not sure if it's needed
|
||||
// TODO: Figure out what to do with this. Right now we set the flag
|
||||
// to "SD" but use assets from "HD". This seems to give the best
|
||||
// results, but is fundamentally wrong.
|
||||
activeFlags.erase("SD");
|
||||
activeFlags["HD"] = true;
|
||||
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
if (attempt == 1)
|
||||
activeFlags["en"] = true;
|
||||
for (uint dirNode = 0; dirNode < dirNodes.size(); dirNode++) {
|
||||
Common::Array<TetraedgeFSNode> foundFiles;
|
||||
_findFileRecursively(dirNodes[dirNode], activeFlags, fname, foundFiles, 5);
|
||||
if (foundFiles.empty())
|
||||
continue;
|
||||
TetraedgeFSNode best = foundFiles[0];
|
||||
int bestDepth = best.getDepth();
|
||||
for (uint i = 1; i < foundFiles.size(); i++) {
|
||||
int depth = foundFiles[i].getDepth();
|
||||
if (depth > bestDepth) {
|
||||
bestDepth = depth;
|
||||
best = foundFiles[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (attempt == 1 && !quiet)
|
||||
debug("TeCore::findFile Falled back to English for %s", path.toString().c_str());
|
||||
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find it at all..
|
||||
if (!quiet)
|
||||
debug("TeCore::findFile Searched but didn't find %s", path.toString().c_str());
|
||||
return TetraedgeFSNode(nullptr, path);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
77
engines/tetraedge/te/te_core.h
Normal file
77
engines/tetraedge/te/te_core.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CORE_H
|
||||
#define TETRAEDGE_TE_TE_CORE_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "common/path.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
#include "tetraedge/te/te_i_loc.h"
|
||||
#include "tetraedge/te/te_i_codec.h"
|
||||
#include "tetraedge/te/te_timer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeCore {
|
||||
public:
|
||||
TeCore();
|
||||
|
||||
void addLoc(TeILoc *loc);
|
||||
void create();
|
||||
TeICodec *createVideoCodec(const TetraedgeFSNode &node, const Common::Path &origPath);
|
||||
TeICodec *createVideoCodec(const Common::String &extn);
|
||||
const Common::String &fileFlagSystemFlag(const Common::String &name) const;
|
||||
bool fileFlagSystemFlagsContains(const Common::String &name) const;
|
||||
Common::Array<Common::String> fileFlagSystemPossibleFlags();
|
||||
bool fileFlagSystemPossibleFlagsContains(const Common::String &name) const;
|
||||
void fileFlagSystemSetFlag(const Common::String &name, const Common::String &val);
|
||||
|
||||
const Common::String &language() const;
|
||||
void language(const Common::String &val);
|
||||
|
||||
TeILoc *loc() { return _loc; }
|
||||
|
||||
bool onActivityTrackingAlarm();
|
||||
|
||||
// Note: this is not in the original, but it's not clear how the original
|
||||
// adds things like "PC-MacOSX" to the path, and there is not clear logic
|
||||
// to them, so here we are.
|
||||
TetraedgeFSNode findFile(const Common::Path &path, bool quiet = false) const;
|
||||
TetraedgeFSNode getFSNode(const Common::Path &path) const;
|
||||
|
||||
bool _coreNotReady;
|
||||
|
||||
private:
|
||||
TeILoc *_loc;
|
||||
|
||||
Common::HashMap<Common::String, Common::String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> _fileSystemFlags;
|
||||
Common::FSDirectory _resourcesRoot;
|
||||
|
||||
TeTimer _activityTrackingTimer;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CORE_H
|
||||
80
engines/tetraedge/te/te_curve_anim2.h
Normal file
80
engines/tetraedge/te/te_curve_anim2.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_CURVE_ANIM2_H
|
||||
#define TETRAEDGE_TE_TE_CURVE_ANIM2_H
|
||||
|
||||
#include "tetraedge/te/te_animation.h"
|
||||
#include "tetraedge/te/te_interpolation.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
template<class T> static T linearInterpolation(T &obj1, T &obj2, double amount) {
|
||||
amount = CLIP<double>(amount, 0.0, 1.0);
|
||||
return (obj1 * (1.0 - amount)) + (obj2 * amount);
|
||||
}
|
||||
|
||||
template<class T, class S>
|
||||
class TeCurveAnim2 : public TeAnimation {
|
||||
public:
|
||||
typedef void(T::*TMethod)(const S &);
|
||||
|
||||
TeCurveAnim2() : _callbackObj(nullptr), _callbackMethod(nullptr), _duration(0), _lastUpdateTime(0) {}
|
||||
virtual ~TeCurveAnim2() {}
|
||||
|
||||
void setCurve(const Common::Array<float> &curve) {
|
||||
// The original writes the curve to a stream to load it back in in
|
||||
// the interpolation.. we just skip that with a direct array copy.
|
||||
_interp.load(curve);
|
||||
}
|
||||
|
||||
void update(double millis) {
|
||||
_lastUpdateTime = millis;
|
||||
|
||||
double amount = _interp.interpole(millis, _duration);
|
||||
|
||||
const S interpVal = linearInterpolation<S>(_startVal, _endVal, amount);
|
||||
//debug("CurveAnim %.02f/%.02f (%.02f) -> %s", time, _maxTime, amount, interpVal.toString().c_str());
|
||||
(_callbackObj->*_callbackMethod)(interpVal);
|
||||
if (_lastUpdateTime >= _duration) {
|
||||
if (_repeatCount == -1) {
|
||||
seekToStart();
|
||||
} else {
|
||||
stop();
|
||||
onFinished().call();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S _startVal;
|
||||
S _endVal;
|
||||
T *_callbackObj;
|
||||
TMethod _callbackMethod;
|
||||
double _duration;
|
||||
|
||||
private:
|
||||
TeInterpolation _interp;
|
||||
double _lastUpdateTime;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_CURVE_ANIM2_H
|
||||
92
engines/tetraedge/te/te_extended_text_layout.cpp
Normal file
92
engines/tetraedge/te/te_extended_text_layout.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 "tetraedge/te/te_extended_text_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeExtendedTextLayout::TeExtendedTextLayout() {
|
||||
_textLayout.setSizeType(RELATIVE_TO_PARENT);
|
||||
_textLayout.setAnchor(TeVector3f32(0.5, 0.0, 0.0));
|
||||
_textLayout.setPosition(TeVector3f32(0.5, 0.0, 0.0));
|
||||
const TeVector3f32 usersz = userSize();
|
||||
_textLayout.setSize(TeVector3f32(1.0, 1.0, usersz.z()));
|
||||
_scrollingLayout.setContentLayout(&_textLayout);
|
||||
_scrollingLayout.setSizeType(RELATIVE_TO_PARENT);
|
||||
_scrollingLayout.setSize(TeVector3f32(1.0, 1.0, usersz.z()));
|
||||
_scrollingLayout.setDirection(TeVector3f32(0.0, 1.0, 0.0));
|
||||
_scrollingLayout.setMouseControl(false);
|
||||
_scrollingLayout.setEnclose(true);
|
||||
_scrollingLayout.setAutoScrollLoop(1);
|
||||
_scrollingLayout.setAutoScrollDelay(4000);
|
||||
_scrollingLayout.setAutoScrollAnimation1Enabled(true);
|
||||
_scrollingLayout.setAutoScrollAnimation1Delay(0);
|
||||
_scrollingLayout.setAutoScrollAnimation1Speed(0.1f);
|
||||
_scrollingLayout.setAutoScrollAnimation2Enabled(false);
|
||||
_scrollingLayout.setAutoScrollAnimation2Delay(0);
|
||||
_scrollingLayout.setAutoScrollAnimation2Speed(0.1f);
|
||||
addChild(&_scrollingLayout);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setAutoScrollDelay(int val) {
|
||||
_scrollingLayout.setAutoScrollDelay(val);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setAutoScrollSpeed(float val) {
|
||||
_scrollingLayout.setAutoScrollAnimation1Speed(val);
|
||||
_scrollingLayout.setAutoScrollAnimation2Speed(val);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setText(const Common::String &val) {
|
||||
_textLayout.setText(val);
|
||||
_scrollingLayout.resetScrollPosition();
|
||||
_scrollingLayout.playAutoScroll();
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setInterLine(float val) {
|
||||
_textLayout.setInterLine(val);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setWrapMode(TeTextBase2::WrapMode mode) {
|
||||
if (mode == TeTextBase2::WrapModeFixed) {
|
||||
_textLayout.setAnchor(TeVector3f32(0.5f, 0.0f, 0.0f));
|
||||
_textLayout.setPosition(TeVector3f32(0.5f, 0.0f, 0.0f));
|
||||
_scrollingLayout.setDirection(TeVector3f32(0.0, 1.0, 0.0));
|
||||
} else {
|
||||
_textLayout.setAnchor(TeVector3f32(0.0f, 0.5f, 0.0f));
|
||||
_textLayout.setPosition(TeVector3f32(0.0f, 0.5f, 0.0f));
|
||||
_scrollingLayout.setDirection(TeVector3f32(1.0, 0.0, 0.0));
|
||||
}
|
||||
_scrollingLayout.setContentLayout(nullptr);
|
||||
_scrollingLayout.setContentLayout(&_textLayout);
|
||||
_textLayout.setWrapMode(mode);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setTextSizeType(int type) {
|
||||
_textLayout.setTextSizeType(type);
|
||||
}
|
||||
|
||||
void TeExtendedTextLayout::setTextSizeProportionalToWidth(int val) {
|
||||
_textLayout.setTextSizeProportionalToWidth(val);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
52
engines/tetraedge/te/te_extended_text_layout.h
Normal file
52
engines/tetraedge/te/te_extended_text_layout.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_EXTENDED_TEXT_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_EXTENDED_TEXT_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_i_text_layout.h"
|
||||
#include "tetraedge/te/te_text_layout.h"
|
||||
#include "tetraedge/te/te_scrolling_layout.h"
|
||||
#include "tetraedge/te/te_clip_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeExtendedTextLayout : public TeClipLayout, public TeITextLayout {
|
||||
public:
|
||||
TeExtendedTextLayout();
|
||||
|
||||
void setAutoScrollDelay(int val);
|
||||
void setAutoScrollSpeed(float val);
|
||||
|
||||
void setText(const Common::String &val) override;
|
||||
void setInterLine(float val) override;
|
||||
void setWrapMode(TeTextBase2::WrapMode mode) override;
|
||||
void setTextSizeType(int type) override;
|
||||
void setTextSizeProportionalToWidth(int val) override;
|
||||
|
||||
private:
|
||||
TeScrollingLayout _scrollingLayout;
|
||||
TeTextLayout _textLayout;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_EXTENDED_TEXT_LAYOUT_H
|
||||
231
engines/tetraedge/te/te_font2.cpp
Normal file
231
engines/tetraedge/te/te_font2.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/* 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 "tetraedge/te/te_font2.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
bool operator==(const KernChars &l, const KernChars &r) {
|
||||
return l._c1 == r._c1 && l._c2 == r._c2;
|
||||
}
|
||||
|
||||
TeFont2::TeFont2() : _numChars(0), _hasKernData(false), _maxHeight(0) {
|
||||
}
|
||||
|
||||
TeFont2::~TeFont2() {
|
||||
}
|
||||
|
||||
bool TeFont2::load(const Common::Path &path) {
|
||||
if (_loadedPath == path)
|
||||
return true; // already open
|
||||
|
||||
TeCore *core = g_engine->getCore();
|
||||
TetraedgeFSNode node = core->findFile(path);
|
||||
return load(node);
|
||||
}
|
||||
|
||||
bool TeFont2::load(const TetraedgeFSNode &node) {
|
||||
const Common::Path path = node.getPath();
|
||||
|
||||
unload();
|
||||
setAccessName(path);
|
||||
_loadedPath = path;
|
||||
|
||||
if (!node.exists()) {
|
||||
warning("TeFont2::load: Can't read from %s", node.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::ScopedPtr<Common::SeekableReadStream> file(node.createReadStream());
|
||||
|
||||
if (!Te3DObject2::loadAndCheckFourCC(*file, "TESF")) {
|
||||
warning("TeFont2::load: Invalid magic in %s", node.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_numChars = file->readUint32LE();
|
||||
if (_numChars > 65535)
|
||||
error("TeFont2::load: improbable number of char points %d", _numChars);
|
||||
TeVector2s32::deserialize(*file, _somePt);
|
||||
TeVector3f32::deserialize(*file, _someVec);
|
||||
_hasKernData = (file->readByte() != 0);
|
||||
if (_hasKernData) {
|
||||
uint32 numKernData = file->readUint32LE();
|
||||
if (numKernData > 10000)
|
||||
error("TeFont2::load: improbable number of kerning points %d", numKernData);
|
||||
for (uint32 i = 0; i < numKernData; i++) {
|
||||
KernChars kc;
|
||||
TeVector3f32 vec;
|
||||
kc._c1 = file->readUint32LE();
|
||||
kc._c2 = file->readUint32LE();
|
||||
vec.x() = file->readFloatLE();
|
||||
vec.y() = file->readFloatLE();
|
||||
_kernData[kc] = vec;
|
||||
//debug("KernChars: '%c'-'%c' (%.2f, %.2f)", (char)kc._c1, (char)kc._c2, vec.x(), vec.y());
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < _numChars; i++) {
|
||||
GlyphData2 g;
|
||||
g._xSz = file->readFloatLE();
|
||||
g._ySz = file->readFloatLE();
|
||||
_maxHeight = MAX(_maxHeight, g._ySz);
|
||||
g._xOff = file->readFloatLE();
|
||||
g._yOff = file->readFloatLE();
|
||||
g._xAdvance = file->readFloatLE();
|
||||
// TODO: What are these other floats?
|
||||
for (uint j = 0; j < 3; j++)
|
||||
g._floats[j] = file->readFloatLE();
|
||||
g._vec.x() = file->readFloatLE();
|
||||
g._vec.y() = file->readFloatLE();
|
||||
_glyphs.push_back(g);
|
||||
uint32 charNo = file->readUint32LE();
|
||||
_uintArray.push_back(charNo);
|
||||
/*
|
||||
if (i >= 35 && i <= 127)
|
||||
debug("Char data %c: sz (%.1f %.1f) off (%.1f %.1f) xadv %.1f %.1f %.1f %.1f texloc (%.1f, %.1f) %d", (char)i,
|
||||
g._xSz, g._ySz, g._xOff, g._yOff, g._xAdvance, g._floats[0], g._floats[1], g._floats[2],
|
||||
g._vec.x(), g._vec.y(), charNo);
|
||||
*/
|
||||
}
|
||||
|
||||
if (!_texture.load(*file, "png")) {
|
||||
warning("Invalid png data in %s", node.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeFont2::unload() {
|
||||
_texture.free();
|
||||
_uintArray.clear();
|
||||
_glyphs.clear();
|
||||
_kernData.clear();
|
||||
_numChars = 0;
|
||||
}
|
||||
|
||||
int TeFont2::getFontHeight() const {
|
||||
return _maxHeight;
|
||||
}
|
||||
|
||||
int TeFont2::getMaxCharWidth() const {
|
||||
int maxWidth = 0;
|
||||
for (auto &glyph : _glyphs) {
|
||||
maxWidth = MAX(maxWidth, (int)glyph._xAdvance);
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
int TeFont2::getCharWidth(uint32 chr) const {
|
||||
if (chr >= _glyphs.size())
|
||||
return 0;
|
||||
return (int)_glyphs[chr]._xAdvance;
|
||||
}
|
||||
|
||||
void TeFont2::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
|
||||
if (chr >= _glyphs.size())
|
||||
return;
|
||||
|
||||
if (_texture.empty())
|
||||
error("Call to TeFont2::drawChar but no texture loaded");
|
||||
const GlyphData2 g = _glyphs[chr];
|
||||
|
||||
if (!g._xSz || !g._ySz)
|
||||
return;
|
||||
|
||||
Common::Rect srcRect;
|
||||
srcRect.left = (int)g._vec.x();
|
||||
srcRect.top = _texture.h - (int)g._vec.y() - g._ySz;
|
||||
srcRect.right = srcRect.left + g._xSz;
|
||||
srcRect.bottom = srcRect.top + g._ySz;
|
||||
|
||||
int dstX = x + g._xOff;
|
||||
int dstY = _maxHeight - g._yOff;
|
||||
|
||||
if (dstX + srcRect.width() > dst->w)
|
||||
srcRect.right = srcRect.left + (dst->w - dstX);
|
||||
if (dstY + srcRect.height() > dst->h)
|
||||
srcRect.bottom = srcRect.top + (dst->h - dstY);
|
||||
|
||||
debug("TeFont2::drawChar %c (%d, %d) from (%d,%d-%d,%d)", chr, x, y,
|
||||
srcRect.left, srcRect.top, srcRect.right, srcRect.bottom);
|
||||
|
||||
dst->copyRectToSurface(_texture, dstX, dstY, srcRect);
|
||||
}
|
||||
|
||||
int TeFont2::getKerningOffset(uint32 left, uint32 right) const {
|
||||
KernChars kc { left, right };
|
||||
if (_kernData.contains(kc))
|
||||
return (int)_kernData[kc].x();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeVector3f32 TeFont2::kerning(uint pxSize, uint isocode1, uint isocode2) {
|
||||
KernChars kc { isocode1, isocode2 };
|
||||
if (_kernData.contains(kc))
|
||||
return _kernData[kc];
|
||||
return TeVector3f32();
|
||||
}
|
||||
|
||||
Common::Rect TeFont2::getBBox(const Common::String &str, int fontSize) {
|
||||
Common::Rect rect;
|
||||
for (uint i = 0; i < str.size(); i++) {
|
||||
uint c = str[i];
|
||||
if (c >= _glyphs.size())
|
||||
continue;
|
||||
const GlyphData2 &g = _glyphs[c];
|
||||
rect.top = MIN(rect.top, (int16)-g._yOff);
|
||||
rect.bottom = MAX(rect.bottom, (int16)(-g._yOff + g._ySz));
|
||||
rect.right += g._xAdvance;
|
||||
if (i < str.size() - 1) {
|
||||
rect.right += kerning(fontSize, c, str[i+1]).x();
|
||||
}
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
Common::Rect TeFont2::getBoundingBox(uint32 chr) const {
|
||||
if (chr > _glyphs.size())
|
||||
return Common::Rect();
|
||||
|
||||
Common::Rect rect;
|
||||
rect.left = (int)_glyphs[chr]._xOff;
|
||||
rect.right = rect.left + _glyphs[chr]._xSz;
|
||||
rect.top = _maxHeight - _glyphs[chr]._yOff;
|
||||
rect.bottom = _maxHeight;
|
||||
return rect;
|
||||
}
|
||||
|
||||
float TeFont2::height(uint pxSize) {
|
||||
return _maxHeight;
|
||||
}
|
||||
|
||||
Graphics::Font *TeFont2::getAtSize(uint size) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
107
engines/tetraedge/te/te_font2.h
Normal file
107
engines/tetraedge/te/te_font2.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_FONT2_H
|
||||
#define TETRAEDGE_TE_TE_FONT2_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/file.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "graphics/font.h"
|
||||
|
||||
#include "tetraedge/te/te_resource.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
#include "tetraedge/te/te_i_font.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
struct KernChars {
|
||||
uint32 _c1;
|
||||
uint32 _c2;
|
||||
};
|
||||
bool operator==(const KernChars &l, const KernChars &r);
|
||||
}
|
||||
|
||||
namespace Common {
|
||||
template<> struct Hash<Tetraedge::KernChars> : public UnaryFunction<Tetraedge::KernChars, uint> {
|
||||
uint operator()(Tetraedge::KernChars val) const { return val._c1 * 7333 + val._c2; }
|
||||
};
|
||||
}
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/**
|
||||
* A pre-rendered font format with positioning data used in Amerzone
|
||||
* ('tef' format)
|
||||
*/
|
||||
class TeFont2 : public TeIFont, public Graphics::Font {
|
||||
public:
|
||||
|
||||
struct GlyphData2 {
|
||||
float _xSz;
|
||||
float _ySz;
|
||||
float _xOff; // from nominal location
|
||||
float _yOff; // top location, from baseline
|
||||
float _xAdvance;
|
||||
float _floats[3];
|
||||
TeVector3f32 _vec; // location in texture - offset from bottom left
|
||||
};
|
||||
|
||||
TeFont2();
|
||||
virtual ~TeFont2();
|
||||
|
||||
bool load(const Common::Path &path);
|
||||
bool load(const TetraedgeFSNode &node);
|
||||
void unload();
|
||||
|
||||
Graphics::Font *getAtSize(uint size) override;
|
||||
|
||||
virtual int getFontHeight() const override;
|
||||
virtual int getMaxCharWidth() const override;
|
||||
virtual int getCharWidth(uint32 chr) const override;
|
||||
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
|
||||
virtual int getKerningOffset(uint32 left, uint32 right) const override;
|
||||
virtual Common::Rect getBBox(const Common::String &str, int fontSize) override;
|
||||
virtual Common::Rect getBoundingBox(uint32 chr) const override;
|
||||
virtual TeVector3f32 kerning(uint pxSize, uint isocode1, uint isocode2) override;
|
||||
|
||||
virtual float height(uint pxSize) override;
|
||||
|
||||
private:
|
||||
Common::Path _loadedPath;
|
||||
|
||||
uint32 _numChars;
|
||||
TeVector2s32 _somePt;
|
||||
TeVector3f32 _someVec;
|
||||
bool _hasKernData;
|
||||
float _maxHeight;
|
||||
// Records a map of character pairs to kerning offsets
|
||||
Common::HashMap<KernChars, TeVector3f32> _kernData;
|
||||
Common::Array<uint32> _uintArray;
|
||||
Common::Array<GlyphData2> _glyphs;
|
||||
TeImage _texture;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_FONT2_H
|
||||
95
engines/tetraedge/te/te_font3.cpp
Normal file
95
engines/tetraedge/te/te_font3.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_font3.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fonts/ttf.h"
|
||||
#include "common/unicode-bidi.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeFont3::TeFont3() {
|
||||
}
|
||||
|
||||
TeFont3::~TeFont3() {
|
||||
unload();
|
||||
}
|
||||
|
||||
Graphics::Font *TeFont3::getAtSize(uint size) {
|
||||
if (_fonts.contains(size))
|
||||
return _fonts.getVal(size);
|
||||
|
||||
if (!_fontFile)
|
||||
load(getAccessName());
|
||||
|
||||
if (!_fontFile)
|
||||
error("TeFont3::: Couldn't open font file %s.", getAccessName().toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
_fontFile->seek(0);
|
||||
Graphics::Font *newFont = Graphics::loadTTFFont(_fontFile.get(), DisposeAfterUse::NO, size, Graphics::kTTFSizeModeCharacter, 0, 0, Graphics::kTTFRenderModeNormal);
|
||||
if (!newFont) {
|
||||
error("TeFont3::: Couldn't load font %s at size %d.", _loadedPath.toString(Common::Path::kNativeSeparator).c_str(), size);
|
||||
}
|
||||
_fonts.setVal(size, newFont);
|
||||
return newFont;
|
||||
}
|
||||
|
||||
bool TeFont3::load(const Common::Path &path) {
|
||||
if (_loadedPath == path && _fontFile)
|
||||
return true; // already open
|
||||
|
||||
TeCore *core = g_engine->getCore();
|
||||
TetraedgeFSNode node = core->findFile(path);
|
||||
return load(node);
|
||||
}
|
||||
|
||||
bool TeFont3::load(const TetraedgeFSNode &node) {
|
||||
const Common::Path fontPath = node.getPath();
|
||||
if (_loadedPath == fontPath && _fontFile)
|
||||
return true; // already open
|
||||
|
||||
setAccessName(fontPath);
|
||||
_loadedPath = fontPath;
|
||||
|
||||
if (!node.exists()) {
|
||||
warning("TeFont3::load: Can't find %s", node.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_fontFile.reset(node.createReadStream());
|
||||
if (!_fontFile) {
|
||||
warning("TeFont3::load: can't open %s", node.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeFont3::unload() {
|
||||
for (auto &entry : _fonts) {
|
||||
delete entry._value;
|
||||
}
|
||||
_fonts.clear();
|
||||
_fontFile.reset();
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
73
engines/tetraedge/te/te_font3.h
Normal file
73
engines/tetraedge/te/te_font3.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_FONT3_H
|
||||
#define TETRAEDGE_TE_TE_FONT3_H
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/str.h"
|
||||
#include "common/path.h"
|
||||
#include "common/types.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
#include "tetraedge/te/te_resource.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_image.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
#include "tetraedge/te/te_i_font.h"
|
||||
|
||||
namespace Graphics {
|
||||
class Font;
|
||||
}
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/**
|
||||
* TeFont3 is a minimal wrapper on Graphics::Font for TTF files, supporting
|
||||
* multiple sizes and matching the original TeFont api a bit closer.
|
||||
*/
|
||||
class TeFont3 : public TeIFont {
|
||||
public:
|
||||
TeFont3();
|
||||
virtual ~TeFont3();
|
||||
|
||||
bool load(const Common::Path &path);
|
||||
bool load(const TetraedgeFSNode &node);
|
||||
void unload();
|
||||
|
||||
private:
|
||||
|
||||
TeIntrusivePtr<Te3DTexture> getFontSizeData(int size) const {
|
||||
return _fontSizeData[size];
|
||||
}
|
||||
|
||||
Graphics::Font *getAtSize(uint size) override;
|
||||
Common::ScopedPtr<Common::SeekableReadStream> _fontFile;
|
||||
Common::HashMap<uint, Graphics::Font *> _fonts;
|
||||
Common::Path _loadedPath;
|
||||
Common::HashMap<uint, TeIntrusivePtr<Te3DTexture>> _fontSizeData;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_FONT3_H
|
||||
75
engines/tetraedge/te/te_frame_anim.cpp
Normal file
75
engines/tetraedge/te/te_frame_anim.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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/util.h"
|
||||
#include "math/utils.h"
|
||||
#include "tetraedge/te/te_frame_anim.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeFrameAnim::TeFrameAnim() : _nbFrames(0), _frameRate(25.0f), _reversed(false), _minFrame(0),
|
||||
_numFramesToShow(-1), _startTime(0), _endTime(FLT_MAX), _loopCount(0), _lastFrameShown(-1) {
|
||||
}
|
||||
|
||||
void TeFrameAnim::update(double millis) {
|
||||
int minFrame = MIN(_minFrame, _nbFrames);
|
||||
int maxFrame = MIN(_minFrame + _numFramesToShow, _nbFrames);
|
||||
double frameNo = _frameRate * millis / 1000.0;
|
||||
|
||||
int loopsDone;
|
||||
int framesToPlay = maxFrame - minFrame;
|
||||
if (framesToPlay <= 0 && _nbFrames > 0)
|
||||
framesToPlay = _nbFrames;
|
||||
|
||||
int frameToShow;
|
||||
if (framesToPlay == 0) {
|
||||
frameToShow = 0;
|
||||
loopsDone = -1;
|
||||
} else if (framesToPlay > 0) {
|
||||
loopsDone = (int)((int)frameNo / framesToPlay);
|
||||
if (!_reversed) {
|
||||
frameToShow = (int)frameNo % framesToPlay + minFrame;
|
||||
} else {
|
||||
frameToShow = (maxFrame - 1) - (int)frameNo % framesToPlay;
|
||||
}
|
||||
} else {
|
||||
// else, we don't know the total frames.. just keep asking for higher.
|
||||
loopsDone = -1;
|
||||
frameToShow = (int)frameNo;
|
||||
}
|
||||
|
||||
if (_loopCount == -1 || loopsDone < _loopCount) {
|
||||
if (frameToShow == _lastFrameShown)
|
||||
return;
|
||||
|
||||
_lastFrameShown = frameToShow;
|
||||
if (_frameChangedSignal.call()) {
|
||||
// got signal that we'd finished.
|
||||
if (_nbFrames == 0)
|
||||
_nbFrames = frameToShow;
|
||||
}
|
||||
} else {
|
||||
stop();
|
||||
_onFinishedSignal.call();
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
69
engines/tetraedge/te/te_frame_anim.h
Normal file
69
engines/tetraedge/te/te_frame_anim.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_FRAME_ANIM_H
|
||||
#define TETRAEDGE_TE_TE_FRAME_ANIM_H
|
||||
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
#include "tetraedge/te/te_animation.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeFrameAnim : public TeAnimation {
|
||||
public:
|
||||
TeFrameAnim();
|
||||
virtual ~TeFrameAnim() {}
|
||||
|
||||
void update(double millis) override;
|
||||
|
||||
TeSignal0Param &frameChangedSignal() { return _frameChangedSignal; };
|
||||
|
||||
void setFrameRate(float rate) { _frameRate = rate; }
|
||||
void setNbFrames(int frames) { _nbFrames = frames; }
|
||||
void setLoopCount(int count) { _loopCount = count; }
|
||||
void setReversed(bool reverse) { _reversed = reverse; }
|
||||
|
||||
void setStartTime(double start) { _startTime = start; }
|
||||
void setEndTime(double end) { _endTime = end; }
|
||||
|
||||
int lastFrameShown() const { return _lastFrameShown; }
|
||||
|
||||
private:
|
||||
float _frameRate;
|
||||
// TODO: Isn't this the same as TeAnimation::_repeatCount??
|
||||
int _loopCount;
|
||||
int _nbFrames;
|
||||
int _numFramesToShow;
|
||||
|
||||
bool _reversed;
|
||||
|
||||
int _lastFrameShown;
|
||||
int _minFrame;
|
||||
|
||||
double _startTime;
|
||||
double _endTime;
|
||||
|
||||
TeSignal0Param _frameChangedSignal;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_FRAME_ANIM_H
|
||||
1124
engines/tetraedge/te/te_free_move_zone.cpp
Normal file
1124
engines/tetraedge/te/te_free_move_zone.cpp
Normal file
File diff suppressed because it is too large
Load Diff
174
engines/tetraedge/te/te_free_move_zone.h
Normal file
174
engines/tetraedge/te/te_free_move_zone.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_FREE_MOVE_ZONE_H
|
||||
#define TETRAEDGE_TE_TE_FREE_MOVE_ZONE_H
|
||||
|
||||
#include "common/array.h"
|
||||
|
||||
#include "tetraedge/te/te_bezier_curve.h"
|
||||
#include "tetraedge/te/te_camera.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
#include "tetraedge/te/te_obp.h"
|
||||
#include "tetraedge/te/te_pick_mesh2.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_act_zone.h"
|
||||
#include "tetraedge/te/te_timer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
namespace micropather {
|
||||
class MicroPather;
|
||||
}
|
||||
|
||||
// TODO: should these structs be moved to their own headers?
|
||||
struct TeBlocker {
|
||||
Common::String _s;
|
||||
TeVector2f32 _pts[2];
|
||||
bool _enabled;
|
||||
};
|
||||
|
||||
struct TeRectBlocker {
|
||||
Common::String _s;
|
||||
TeVector2f32 _pts[4];
|
||||
bool _enabled;
|
||||
};
|
||||
|
||||
class TeFreeMoveZoneGraph;
|
||||
|
||||
class TeFreeMoveZone : public TePickMesh2 {
|
||||
public:
|
||||
struct CollidePoint {
|
||||
TeVector3f32 _point;
|
||||
float _distance;
|
||||
};
|
||||
|
||||
TeFreeMoveZone();
|
||||
~TeFreeMoveZone();
|
||||
|
||||
float bordersDistance() const;
|
||||
void buildAStar();
|
||||
void calcGridMatrix();
|
||||
void clear();
|
||||
Common::Array<TeVector3f32> collisions(const TeVector3f32 &v1, const TeVector3f32 &v2);
|
||||
TeVector3f32 correctCharacterPosition(const TeVector3f32 &pos, bool *flagout, bool f);
|
||||
|
||||
TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 &startpt, const TeVector2s32 &endpt, float param_5, bool findMeshFlag);
|
||||
TeIntrusivePtr<TeBezierCurve> curve(const TeVector3f32 &startpt, const TeVector3f32 &endpt);
|
||||
|
||||
void draw() override;
|
||||
TeVector3f32 findNearestPointOnBorder(const TeVector2f32 &pt);
|
||||
byte hasBlockerIntersection(const TeVector2s32 &pt);
|
||||
bool hasCellBorderIntersection(const TeVector2s32 &pt);
|
||||
|
||||
TeActZone *isInZone(const TeVector3f32 &pt);
|
||||
|
||||
bool loadAStar(const Common::Path &path, const TeVector2s32 &size);
|
||||
bool loadBin(const Common::Path &path, const Common::Array<TeBlocker> *blockers,
|
||||
const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
|
||||
const TeVector2f32 &gridSize);
|
||||
bool loadBin(Common::ReadStream &stream, const Common::Array<TeBlocker> *blockers,
|
||||
const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones,
|
||||
const TeVector2f32 &gridSize);
|
||||
|
||||
// loadBin() 2 versions, seem unused
|
||||
|
||||
// name(), onPositionChanged(), position(), rotate(), rotation(), scale(),
|
||||
// setName(), setPosition(), setRotation(), setScale(), setVisible(),
|
||||
// translate(), and visible() are all implemented in original, but all
|
||||
// just do the same as super.
|
||||
|
||||
bool onViewportChanged();
|
||||
void preUpdateGrid();
|
||||
TeVector2s32 projectOnAStarGrid(const TeVector3f32 &pt);
|
||||
Common::Array<TeVector3f32> removeInsignificantPoints(const Common::Array<TeVector3f32> &points);
|
||||
void setBordersDistance(float dist);
|
||||
void setCamera(TeIntrusivePtr<TeCamera> &cam, bool noRecalcProjPoints);
|
||||
void setNbTriangles(uint len);
|
||||
void setPathFindingOccluder(const TeOBP &occluder);
|
||||
void setVertex(uint offset, const TeVector3f32 &vertex);
|
||||
TeVector3f32 transformAStarGridInWorldSpace(const TeVector2s32 &gridpt);
|
||||
float transformHeightMin(float minval);
|
||||
TeVector3f32 transformVectorInWorldSpace(float param_3, float param_4);
|
||||
void updateBorders();
|
||||
void updateGrid(bool force);
|
||||
void updatePickMesh();
|
||||
void updateProjectedPoints();
|
||||
void updateTransformedVertices();
|
||||
|
||||
static float normalizeAngle(float angle);
|
||||
static void deserialize(Common::ReadStream &stream, TeFreeMoveZone &dest, const Common::Array<TeBlocker> *blockers,
|
||||
const Common::Array<TeRectBlocker> *rectblockers, const Common::Array<TeActZone> *actzones);
|
||||
static void serialize(Common::WriteStream &stream, const TeFreeMoveZone &src, bool updateFirst);
|
||||
|
||||
static TePickMesh2 *findNearestMesh(TeIntrusivePtr<TeCamera> &camera, const TeVector2s32 &frompt,
|
||||
Common::Array<TePickMesh2*> &pickMeshes, TeVector3f32 *outloc, bool lastHitFirst);
|
||||
|
||||
const Common::Array<TeVector3f32> freeMoveZoneVerticies() const { return _freeMoveZoneVerticies; }
|
||||
|
||||
static void setCollisionSlide(bool val) { _collisionSlide = val; }
|
||||
|
||||
private:
|
||||
TeVector2s32 aStarResolution() const;
|
||||
|
||||
const Common::Array<TeActZone> *_actzones;
|
||||
const Common::Array<TeBlocker> *_blockers;
|
||||
const Common::Array<TeRectBlocker> *_rectBlockers;
|
||||
|
||||
Common::Array<TeVector3f32> _freeMoveZoneVerticies;
|
||||
Common::Array<uint> _pickMesh;
|
||||
Common::Array<TeVector3f32> _transformedVerticies;
|
||||
Common::Array<uint> _borders;
|
||||
Common::Array<TeVector2f32> _projectedPoints;
|
||||
|
||||
TeVector2f32 _gridSquareSize;
|
||||
TeVector2f32 _gridTopLeft;
|
||||
TeVector2f32 _gridBottomRight;
|
||||
TeVector2f32 _loadGridSize; // At least, it seems unused?
|
||||
TeMatrix4x4 _gridMatrix;
|
||||
TeMatrix4x4 _inverseWorldTransform;
|
||||
|
||||
float _gridWorldY;
|
||||
|
||||
TeOBP _obp;
|
||||
TeIntrusivePtr<TeCamera> _camera;
|
||||
//static TeIntrusivePtr<TeCamera> _globalCamera;
|
||||
|
||||
TeFreeMoveZoneGraph *_graph;
|
||||
|
||||
bool _loadedFromBin;
|
||||
bool _gridDirty;
|
||||
bool _transformedVerticiesDirty;
|
||||
bool _bordersDirty;
|
||||
bool _pickMeshDirty;
|
||||
bool _projectedPointsDirty;
|
||||
|
||||
micropather::MicroPather *_micropather;
|
||||
TeTimer _updateTimer;
|
||||
|
||||
Common::Path _aszGridPath;
|
||||
|
||||
static bool _collisionSlide;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_FREE_MOVE_ZONE_H
|
||||
38
engines/tetraedge/te/te_frustum.cpp
Normal file
38
engines/tetraedge/te/te_frustum.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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 "tetraedge/te/te_frustum.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeFrustum::TeFrustum() {
|
||||
}
|
||||
|
||||
void TeFrustum::update(TeCamera &cam) {
|
||||
const TeMatrix4x4 camProjMatrix = cam.projectionMatrix();
|
||||
TeMatrix4x4 camWorldMatrix = cam.worldTransformationMatrix();
|
||||
camWorldMatrix.inverse();
|
||||
const TeMatrix4x4 camProjWorld = camProjMatrix * camWorldMatrix;
|
||||
setup(camProjWorld.toScummVMMatrix());
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
47
engines/tetraedge/te/te_frustum.h
Normal file
47
engines/tetraedge/te/te_frustum.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_FRUSTUM_H
|
||||
#define TETRAEDGE_TE_TE_FRUSTUM_H
|
||||
|
||||
#include "math/frustum.h"
|
||||
|
||||
#include "tetraedge/te/te_camera.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeFrustum : public Math::Frustum {
|
||||
public:
|
||||
TeFrustum();
|
||||
|
||||
// unused..
|
||||
//void computeNormal(unsigned int val);
|
||||
//bool pointIsIn(const TeVector3f32 &pt) const;
|
||||
//bool sphereIsIn(const TeVector3f32 &vec, float f) const;
|
||||
|
||||
void update(TeCamera &camera);
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_FRUSTUM_H
|
||||
29
engines/tetraedge/te/te_i_3d_object2.cpp
Normal file
29
engines/tetraedge/te/te_i_3d_object2.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 "tetraedge/te/te_i_3d_object2.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeI3DObject2::TeI3DObject2() {
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
36
engines/tetraedge/te/te_i_3d_object2.h
Normal file
36
engines/tetraedge/te/te_i_3d_object2.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_3D_OBJECT2_H
|
||||
#define TETRAEDGE_TE_TE_I_3D_OBJECT2_H
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeI3DObject2 {
|
||||
public:
|
||||
TeI3DObject2();
|
||||
|
||||
virtual ~TeI3DObject2() {}
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_3D_OBJECT2_H
|
||||
67
engines/tetraedge/te/te_i_codec.h
Normal file
67
engines/tetraedge/te/te_i_codec.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_CODEC_H
|
||||
#define TETRAEDGE_TE_TE_I_CODEC_H
|
||||
|
||||
#include "common/path.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_image.h"
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeICodec {
|
||||
public:
|
||||
TeICodec() {};
|
||||
|
||||
virtual ~TeICodec() {};
|
||||
virtual bool load(const TetraedgeFSNode &node) = 0;
|
||||
virtual uint width() = 0;
|
||||
virtual uint height() = 0;
|
||||
virtual int nbFrames() = 0;
|
||||
virtual Graphics::PixelFormat pixelFormat() = 0;
|
||||
virtual void setLeftBorderSize(uint val) = 0;
|
||||
virtual uint leftBorderSize() = 0;
|
||||
virtual void setRightBorderSize(uint val) = 0;
|
||||
virtual uint rightBorderSize() = 0;
|
||||
virtual void setBottomBorderSize(uint val) = 0;
|
||||
virtual uint bottomBorderSize() = 0;
|
||||
virtual void setTopBorderSize(uint val) = 0;
|
||||
virtual uint topBorderSize() = 0;
|
||||
virtual float frameRate() = 0;
|
||||
virtual bool update(uint i, TeImage &imgout) = 0;
|
||||
virtual bool isAtEnd() = 0;
|
||||
virtual TeSignal0Param &onVideoFinished() { return _finishedSignal; };
|
||||
virtual void setColorKeyActivated(bool val) = 0;
|
||||
virtual void setColorKey(const TeColor &col) = 0;
|
||||
virtual void setColorKeyTolerence(float val) = 0;
|
||||
|
||||
private:
|
||||
TeSignal0Param _finishedSignal;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_CODEC_H
|
||||
133
engines/tetraedge/te/te_i_font.cpp
Normal file
133
engines/tetraedge/te/te_i_font.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_font3.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fonts/ttf.h"
|
||||
#include "common/unicode-bidi.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeIFont::TeIFont() {
|
||||
_codePage = codePage();
|
||||
}
|
||||
|
||||
TeIFont::~TeIFont() {
|
||||
}
|
||||
|
||||
TeIFont::GlyphData TeIFont::glyph(uint pxSize, uint charcode) {
|
||||
Graphics::Font *font = getAtSize(pxSize);
|
||||
Common::Rect bbox = font->getBoundingBox(charcode);
|
||||
TeImage *img = new TeImage();
|
||||
Common::SharedPtr<TePalette> nullpal;
|
||||
img->createImg(bbox.width(), bbox.height(), nullpal, Graphics::PixelFormat::createFormatRGBA32());
|
||||
font->drawChar(img, charcode, 0, 0, 0xffffffff);
|
||||
GlyphData retval;
|
||||
retval._charcode = charcode;
|
||||
retval._bitmapSize = bbox;
|
||||
retval._img = img;
|
||||
return retval;
|
||||
}
|
||||
|
||||
Common::CodePage TeIFont::codePage() const {
|
||||
Common::String lang = g_engine->getCore()->language();
|
||||
if (g_engine->isUtf8Release())
|
||||
return Common::CodePage::kUtf8;
|
||||
if (lang == "ru")
|
||||
return Common::kISO8859_5;
|
||||
if (g_engine->getGamePlatform() == Common::Platform::kPlatformAndroid)
|
||||
return Common::CodePage::kUtf8;
|
||||
if (lang == "he")
|
||||
return Common::kWindows1255;
|
||||
return Common::kLatin1;
|
||||
}
|
||||
|
||||
int TeIFont::wordWrapText(const Common::String &str, int fontSize, int maxWidth, Common::Array<Common::String> &lines) {
|
||||
Graphics::Font *font = getAtSize(fontSize);
|
||||
Common::Array<Common::U32String> u32lines;
|
||||
int retval = font->wordWrapText(str.decode(_codePage), maxWidth, u32lines);
|
||||
for (auto &line: u32lines) {
|
||||
lines.push_back(line.encode(_codePage));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Common::Rect TeIFont::getBBox(const Common::String &str, int fontSize) {
|
||||
Graphics::Font *font = getAtSize(fontSize);
|
||||
return font->getBoundingBox(str.decode(_codePage));
|
||||
}
|
||||
|
||||
int TeIFont::getHeight(int fontSize) {
|
||||
Graphics::Font *font = getAtSize(fontSize);
|
||||
return font->getFontHeight();
|
||||
}
|
||||
|
||||
void TeIFont::draw(TeImage &destImage, const Common::String &str, int fontSize, int yoff, const TeColor &col, TeIFont::AlignStyle align) {
|
||||
Graphics::Font *font = getAtSize(fontSize);
|
||||
Graphics::TextAlign talign;
|
||||
switch (align) {
|
||||
case AlignLeft:
|
||||
talign = Graphics::kTextAlignLeft;
|
||||
break;
|
||||
case AlignRight:
|
||||
talign = Graphics::kTextAlignRight;
|
||||
break;
|
||||
// Note: we don't support justify.. just center. (justify is not used anyway)
|
||||
case AlignJustify:
|
||||
case AlignCenter:
|
||||
default:
|
||||
talign = Graphics::kTextAlignCenter;
|
||||
break;
|
||||
}
|
||||
const Graphics::PixelFormat &fmt = destImage.format;
|
||||
|
||||
uint32 uintcol = ((uint32)col.a() << fmt.aShift) | ((uint32)(col.r()) << fmt.rShift)
|
||||
| ((uint32)(col.g()) << fmt.gShift) | ((uint32)(col.b()) << fmt.bShift);
|
||||
Common::U32String line = str.decode(_codePage);
|
||||
if (g_engine->getCore()->language() == "he")
|
||||
line = Common::convertBiDiU32String(line).visual;
|
||||
font->drawString(&destImage, line, 0, yoff, destImage.w, uintcol, talign);
|
||||
}
|
||||
|
||||
float TeIFont::ascender(uint pxSize) {
|
||||
Graphics::Font *font = getAtSize(pxSize);
|
||||
return font->getFontAscent();
|
||||
}
|
||||
|
||||
float TeIFont::descender(uint pxSize) {
|
||||
error("TODO: Implement TeFont3::descender");
|
||||
}
|
||||
|
||||
float TeIFont::height(uint pxSize) {
|
||||
Graphics::Font *font = getAtSize(pxSize);
|
||||
return font->getFontHeight();
|
||||
}
|
||||
|
||||
TeVector3f32 TeIFont::kerning(uint pxSize, uint charcode1, uint charcode2) {
|
||||
Graphics::Font *font = getAtSize(pxSize);
|
||||
int offset = font->getKerningOffset(charcode1, charcode2);
|
||||
// note: not perfect because we have no Y, but it's ok..
|
||||
return TeVector3f32(offset, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
78
engines/tetraedge/te/te_i_font.h
Normal file
78
engines/tetraedge/te/te_i_font.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_FONT_H
|
||||
#define TETRAEDGE_TE_TE_I_FONT_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "graphics/font.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_image.h"
|
||||
#include "tetraedge/te/te_resource.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/**
|
||||
* A wrapper to provide a TeFont-like interface using ScummVM'S font class.
|
||||
*/
|
||||
class TeIFont : public TeResource {
|
||||
public:
|
||||
enum AlignStyle {
|
||||
AlignLeft,
|
||||
AlignRight,
|
||||
AlignJustify,
|
||||
AlignCenter
|
||||
};
|
||||
|
||||
struct GlyphData {
|
||||
uint32 _charcode;
|
||||
Common::Rect _bitmapSize;
|
||||
TeIntrusivePtr<TeImage> _img;
|
||||
};
|
||||
|
||||
TeIFont();
|
||||
virtual ~TeIFont();
|
||||
virtual Graphics::Font *getAtSize(uint size) = 0;
|
||||
|
||||
virtual float ascender(uint pxSize);
|
||||
virtual float descender(uint pxSize);
|
||||
virtual float height(uint pxSize);
|
||||
virtual TeVector3f32 kerning(uint pxSize, uint isocode1, uint isocode2);
|
||||
|
||||
virtual void draw(TeImage &destImage, const Common::String &str, int fontSize, int yoff, const TeColor &col, AlignStyle alignMode);
|
||||
virtual Common::Rect getBBox(const Common::String &str, int fontSize);
|
||||
virtual int getHeight(int fontSize);
|
||||
virtual int wordWrapText(const Common::String &str, int fontSize, int maxWidth, Common::Array<Common::String> &lines);
|
||||
|
||||
virtual TeIFont::GlyphData glyph(uint pxSize, uint charcode);
|
||||
|
||||
protected:
|
||||
Common::CodePage _codePage;
|
||||
|
||||
private:
|
||||
Common::CodePage codePage() const;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_FONT_H
|
||||
31
engines/tetraedge/te/te_i_layout.cpp
Normal file
31
engines/tetraedge/te/te_i_layout.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/* 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 "tetraedge/te/te_i_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeILayout::TeILayout() {
|
||||
}
|
||||
|
||||
// TODO: Add more functions here.
|
||||
|
||||
} // end namespace Tetraedge
|
||||
52
engines/tetraedge/te/te_i_layout.h
Normal file
52
engines/tetraedge/te/te_i_layout.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_I_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeILayout {
|
||||
public:
|
||||
TeILayout();
|
||||
|
||||
enum CoordinatesType {
|
||||
ABSOLUTE, // use User Position?
|
||||
RELATIVE_TO_PARENT // scale based on parent size
|
||||
};
|
||||
|
||||
enum DrawMode {
|
||||
DrawMode0
|
||||
};
|
||||
|
||||
enum RatioMode {
|
||||
RATIO_MODE_NONE = 0,
|
||||
RATIO_MODE_LETTERBOX = 1,
|
||||
RATIO_MODE_PAN_SCAN = 2
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_LAYOUT_H
|
||||
36
engines/tetraedge/te/te_i_loc.cpp
Normal file
36
engines/tetraedge/te/te_i_loc.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 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 "tetraedge/te/te_i_loc.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeILoc::TeILoc() {
|
||||
}
|
||||
|
||||
const Common::String *TeILoc::text(const Common::String &key) const {
|
||||
if (!_map.contains(key)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &_map.find(key)->_value;
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
44
engines/tetraedge/te/te_i_loc.h
Normal file
44
engines/tetraedge/te/te_i_loc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_LOC_H
|
||||
#define TETRAEDGE_TE_TE_I_LOC_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeILoc {
|
||||
public:
|
||||
TeILoc();
|
||||
virtual ~TeILoc() {};
|
||||
|
||||
virtual const Common::String *text(const Common::String &key) const;
|
||||
|
||||
protected:
|
||||
Common::StringMap _map;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_LOC_H
|
||||
31
engines/tetraedge/te/te_i_text_layout.cpp
Normal file
31
engines/tetraedge/te/te_i_text_layout.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/* 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 "tetraedge/te/te_i_text_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeITextLayout::TeITextLayout() {
|
||||
}
|
||||
|
||||
// TODO: Add more functions here.
|
||||
|
||||
} // end namespace Tetraedge
|
||||
45
engines/tetraedge/te/te_i_text_layout.h
Normal file
45
engines/tetraedge/te/te_i_text_layout.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_text_base2.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeITextLayout {
|
||||
public:
|
||||
TeITextLayout();
|
||||
virtual ~TeITextLayout() {}
|
||||
|
||||
virtual void setText(const Common::String &val) = 0;
|
||||
virtual void setInterLine(float val) = 0;
|
||||
virtual void setWrapMode(TeTextBase2::WrapMode mode) = 0;
|
||||
virtual void setTextSizeType(int type) = 0;
|
||||
virtual void setTextSizeProportionalToWidth(int val) = 0;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_I_TEXT_LAYOUT_H
|
||||
140
engines/tetraedge/te/te_image.cpp
Normal file
140
engines/tetraedge/te/te_image.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/file.h"
|
||||
#include "common/rect.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "tetraedge/te/te_image.h"
|
||||
#include "tetraedge/te/te_i_codec.h"
|
||||
#include "tetraedge/te/te_scummvm_codec.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeImage::TeImage() : ManagedSurface() {
|
||||
}
|
||||
|
||||
TeImage::TeImage(const TeImage &other) : ManagedSurface() {
|
||||
copyFrom(other);
|
||||
error("TODO: Implement TeImage::TeImage copy constructor");
|
||||
}
|
||||
|
||||
void TeImage::copy(TeImage &dest, const TeVector2s32 &vec1, const TeVector2s32 &vec2, const TeVector2s32 &vec3) const {
|
||||
error("TODO: Implement TeImage::copy");
|
||||
}
|
||||
|
||||
uint64 TeImage::countPixelsOfColor(const TeColor &col) const {
|
||||
error("TODO: Implement TeImage::countPixelsOfColor");
|
||||
}
|
||||
|
||||
/*
|
||||
void TeImage::create() {
|
||||
// Never used, but in original seems to do the same as destroy??
|
||||
destroy();
|
||||
}*/
|
||||
|
||||
void TeImage::createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
|
||||
const Graphics::PixelFormat &pxformat, uint bufxsize, uint bufysize) {
|
||||
Graphics::ManagedSurface::create(xsize, ysize, pxformat);
|
||||
if (pxformat.aBits() > 0)
|
||||
Graphics::ManagedSurface::fillRect(Common::Rect(0, 0, xsize, ysize), 0);
|
||||
}
|
||||
|
||||
void TeImage::deserialize(Common::ReadStream &stream) {
|
||||
error("TODO: Implement TeImage::deserialize");
|
||||
}
|
||||
|
||||
void TeImage::destroy() {
|
||||
Graphics::ManagedSurface::free();
|
||||
}
|
||||
|
||||
void TeImage::drawPlot(void *outbuf, int x, int y, const TeVector2s32 &bufsize, const TeColor &col) {
|
||||
error("TODO: Implement TeImage::drawPlot");
|
||||
}
|
||||
|
||||
void TeImage::fill(byte val) {
|
||||
error("TODO: Implement TeImage::fill");
|
||||
}
|
||||
|
||||
void TeImage::fill(byte r, byte g, byte b, byte a) {
|
||||
Common::Rect wholeSurf(0, 0, w, h);
|
||||
|
||||
uint32 col = ((uint32)r << format.rShift) | ((uint32)g << format.gShift) | ((uint32)b << format.bShift) | ((uint32)a << format.aShift);
|
||||
Graphics::ManagedSurface::fillRect(wholeSurf, col);
|
||||
}
|
||||
|
||||
void TeImage::getBuff(uint x, uint y, byte *pout, uint w_, uint h_) {
|
||||
error("TODO: Implement TeImage::getBuff");
|
||||
}
|
||||
|
||||
bool TeImage::isExtensionSupported(const Common::Path &path) {
|
||||
error("TODO: Implement TeImage::isExtensionSupported");
|
||||
}
|
||||
|
||||
bool TeImage::load(const TetraedgeFSNode &node) {
|
||||
TeCore *core = g_engine->getCore();
|
||||
TeICodec *codec = core->createVideoCodec(node, node.getPath());
|
||||
if (!node.exists() || !codec->load(node)) {
|
||||
warning("TeImage::load: Failed to load %s.", node.toString().c_str());
|
||||
delete codec;
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::SharedPtr<TePalette> nullpal;
|
||||
createImg(codec->width(), codec->height(), nullpal, codec->pixelFormat(), codec->width(), codec->height());
|
||||
|
||||
if (!codec->update(0, *this)) {
|
||||
error("TeImage::load: Failed to update from %s.", node.toString().c_str());
|
||||
}
|
||||
delete codec;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeImage::load(Common::SeekableReadStream &stream, const Common::String &type) {
|
||||
TeCore *core = g_engine->getCore();
|
||||
TeScummvmCodec *codec = dynamic_cast<TeScummvmCodec *>(core->createVideoCodec(type));
|
||||
if (!codec || !codec->load(stream)) {
|
||||
warning("TeImage::load: Failed to load stream");
|
||||
delete codec;
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::SharedPtr<TePalette> nullpal;
|
||||
createImg(codec->width(), codec->height(), nullpal, codec->pixelFormat(), codec->width(), codec->height());
|
||||
|
||||
if (!codec->update(0, *this)) {
|
||||
error("TeImage::load: Failed to update from stream");
|
||||
}
|
||||
delete codec;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeImage::save(const Common::Path &path, enum SaveType type) {
|
||||
error("TODO: Implement TeImage::save");
|
||||
}
|
||||
|
||||
int TeImage::serialize(Common::WriteStream &stream) {
|
||||
error("TODO: Implement TeImage::serialize");
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
85
engines/tetraedge/te/te_image.h
Normal file
85
engines/tetraedge/te/te_image.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_IMAGE_H
|
||||
#define TETRAEDGE_TE_TE_IMAGE_H
|
||||
|
||||
#include "common/fs.h"
|
||||
#include "common/ptr.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/types.h"
|
||||
#include "common/path.h"
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_palette.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
#include "tetraedge/te/te_resource.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeImage : public TeResource, public Graphics::ManagedSurface {
|
||||
public:
|
||||
TeImage();
|
||||
TeImage(const TeImage &other);
|
||||
|
||||
virtual ~TeImage() {
|
||||
destroy();
|
||||
};
|
||||
|
||||
enum SaveType {
|
||||
PNG
|
||||
};
|
||||
|
||||
void copy(TeImage &dest, const TeVector2s32 &vec1, const TeVector2s32 &vec2,
|
||||
const TeVector2s32 &vec3) const;
|
||||
uint64 countPixelsOfColor(const TeColor &col) const;
|
||||
// void create(); // never used?
|
||||
void createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &palette, const Graphics::PixelFormat &newformat) {
|
||||
createImg(xsize, ysize, palette, newformat, xsize, ysize);
|
||||
}
|
||||
void createImg(uint xsize, uint ysize, Common::SharedPtr<TePalette> &pal,
|
||||
const Graphics::PixelFormat &format, uint bufxsize, uint bufysize);
|
||||
void deserialize(Common::ReadStream &stream);
|
||||
void destroy();
|
||||
void drawPlot(int x, int y, const TeColor &col) {
|
||||
drawPlot(getPixels(), x, y, bufSize(), col);
|
||||
}
|
||||
void drawPlot(void *outbuf, int x, int y, const TeVector2s32 &bufsize, const TeColor &col);
|
||||
void fill(byte val);
|
||||
void fill(byte r, byte g, byte b, byte a);
|
||||
void getBuff(uint x, uint y, byte *pout, uint w, uint h);
|
||||
bool isExtensionSupported(const Common::Path &path);
|
||||
bool load(const TetraedgeFSNode &node);
|
||||
bool load(Common::SeekableReadStream &stream, const Common::String &type);
|
||||
bool save(const Common::Path &path, enum SaveType type);
|
||||
int serialize(Common::WriteStream &stream);
|
||||
TeVector2s32 bufSize() const {
|
||||
return TeVector2s32(pitch / format.bytesPerPixel, h);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_IMAGE_H
|
||||
169
engines/tetraedge/te/te_images_sequence.cpp
Normal file
169
engines/tetraedge/te/te_images_sequence.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
/* 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/file.h"
|
||||
#include "image/png.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "tetraedge/te/te_images_sequence.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeImagesSequence::TeImagesSequence() : _width(0), _height(0), _curFrame(0), _frameRate(0) {
|
||||
}
|
||||
|
||||
TeImagesSequence::~TeImagesSequence() {
|
||||
for (auto surf : _cachedSurfaces) {
|
||||
if (surf)
|
||||
delete surf;
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool TeImagesSequence::matchExtension(const Common::String &extn) {
|
||||
return extn == "anim" || extn == "animcached";
|
||||
}
|
||||
|
||||
static bool compareNodes(const TetraedgeFSNode &left, const TetraedgeFSNode &right) {
|
||||
return left.getPath().toString('/') < right.getPath().toString('/');
|
||||
}
|
||||
|
||||
bool TeImagesSequence::load(const TetraedgeFSNode &dir) {
|
||||
if (!dir.isDirectory()) {
|
||||
warning("TeImagesSequence::load:: not a directory %s", dir.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
TetraedgeFSList children;
|
||||
if (!dir.getChildren(children, Common::FSNode::kListFilesOnly) || children.empty()) {
|
||||
warning("TeImagesSequence::load:: couldn't get children of %s", dir.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::sort(children.begin(), children.end(), compareNodes);
|
||||
dir.maybeAddToSearchMan();
|
||||
|
||||
for (TetraedgeFSNode &child : children) {
|
||||
const Common::String fileName = child.getName();
|
||||
|
||||
if (fileName.size() <= 10 || fileName.substr(fileName.size() - 7) != "fps.png")
|
||||
continue;
|
||||
|
||||
Common::String fstart = fileName.substr(0, fileName.size() - 7);
|
||||
int frameno = 0;
|
||||
int fps = 0;
|
||||
if (sscanf(fstart.c_str(), "%d-%d", &frameno, &fps) != 2) {
|
||||
warning("TeImagesSequence::load can't match %s", fileName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *stream = child.createReadStream();
|
||||
if (!stream) {
|
||||
warning("TeImagesSequence::load can't open %s", child.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only do the deep check for the first file to get dimensions.
|
||||
// If the images are small then cache them to avoid reloading each frame each time.
|
||||
if (!_width || (_width < 100 && _height < 100)) {
|
||||
Image::PNGDecoder png;
|
||||
if (!png.loadStream(*stream)) {
|
||||
warning("Image sequence failed to load png %s", child.toString().c_str());
|
||||
delete stream;
|
||||
return false;
|
||||
}
|
||||
|
||||
_frameRate = fps;
|
||||
const Graphics::Surface *pngsurf = png.getSurface();
|
||||
assert(pngsurf);
|
||||
_width = pngsurf->w;
|
||||
_height = pngsurf->h;
|
||||
if (_width < 100 && _height < 100) {
|
||||
Graphics::ManagedSurface *surf = new Graphics::ManagedSurface();
|
||||
surf->copyFrom(*pngsurf);
|
||||
_cachedSurfaces.push_back(surf);
|
||||
} else {
|
||||
_cachedSurfaces.push_back(nullptr);
|
||||
}
|
||||
} else {
|
||||
_cachedSurfaces.push_back(nullptr);
|
||||
}
|
||||
|
||||
_files.push_back(child);
|
||||
delete stream;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TeImagesSequence::update(uint i, TeImage &imgout) {
|
||||
_curFrame = i;
|
||||
|
||||
if (i >= _files.size())
|
||||
return false;
|
||||
|
||||
if (_cachedSurfaces[i] == nullptr) {
|
||||
Common::SeekableReadStream *stream = _files[i].createReadStream();
|
||||
if (!stream)
|
||||
error("Open %s failed.. it was ok before?", _files[i].getName().c_str());
|
||||
|
||||
Image::PNGDecoder png;
|
||||
if (!png.loadStream(*stream)) {
|
||||
warning("Image sequence failed to load png %s", _files[i].getName().c_str());
|
||||
delete stream;
|
||||
return false;
|
||||
}
|
||||
|
||||
const Graphics::Surface *surf = png.getSurface();
|
||||
assert(surf);
|
||||
|
||||
imgout.setAccessName(_files[i].getPath());
|
||||
|
||||
if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
|
||||
imgout.copyFrom(*surf);
|
||||
delete stream;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
const Graphics::ManagedSurface *surf = _cachedSurfaces[i];
|
||||
if (imgout.w == surf->w && imgout.h == surf->h && imgout.format == surf->format) {
|
||||
imgout.setAccessName(_files[i].getPath());
|
||||
imgout.copyFrom(*surf);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
error("TODO: Implement TeImagesSequence::update for different sizes");
|
||||
}
|
||||
|
||||
bool TeImagesSequence::isAtEnd() {
|
||||
return _curFrame >= _files.size();
|
||||
}
|
||||
|
||||
Graphics::PixelFormat TeImagesSequence::pixelFormat() {
|
||||
return Graphics::PixelFormat::createFormatRGBA32();
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
73
engines/tetraedge/te/te_images_sequence.h
Normal file
73
engines/tetraedge/te/te_images_sequence.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
|
||||
#define TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "tetraedge/te/te_i_codec.h"
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
class ManagedSurface;
|
||||
}
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeImagesSequence : public TeICodec {
|
||||
public:
|
||||
TeImagesSequence();
|
||||
virtual ~TeImagesSequence();
|
||||
|
||||
virtual bool load(const TetraedgeFSNode &node) override;
|
||||
virtual uint width() override { return _width; }
|
||||
virtual uint height() override { return _height; }
|
||||
virtual int nbFrames() override { return _files.size(); }
|
||||
virtual void setLeftBorderSize(uint val) override { }
|
||||
virtual uint leftBorderSize() override { return 0; }
|
||||
virtual void setRightBorderSize(uint val) override { }
|
||||
virtual uint rightBorderSize() override { return 0; }
|
||||
virtual void setBottomBorderSize(uint val) override { }
|
||||
virtual uint bottomBorderSize() override { return 0; }
|
||||
virtual void setTopBorderSize(uint val) override { }
|
||||
virtual uint topBorderSize() override { return 0; }
|
||||
virtual Graphics::PixelFormat pixelFormat() override;
|
||||
virtual float frameRate() override { return _frameRate; }
|
||||
virtual bool update(uint i, TeImage &imgout) override;
|
||||
virtual bool isAtEnd() override;
|
||||
virtual void setColorKeyActivated(bool val) override { }
|
||||
virtual void setColorKey(const TeColor &col) override { }
|
||||
virtual void setColorKeyTolerence(float val) override { }
|
||||
|
||||
static bool matchExtension(const Common::String &extn);
|
||||
|
||||
private:
|
||||
float _frameRate;
|
||||
uint _width;
|
||||
uint _height;
|
||||
Common::Array<TetraedgeFSNode> _files;
|
||||
Common::Array<Graphics::ManagedSurface *> _cachedSurfaces;
|
||||
uint _curFrame;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_IMAGES_SEQUENCE_H
|
||||
73
engines/tetraedge/te/te_input_mgr.cpp
Normal file
73
engines/tetraedge/te/te_input_mgr.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/game/game.h"
|
||||
#include "tetraedge/te/te_input_mgr.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeInputMgr::TeInputMgr() {
|
||||
}
|
||||
|
||||
void TeInputMgr::handleEvent(const Common::Event &e) {
|
||||
switch (e.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
_customActionStartSignal.call(e.customType);
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
_customActionEndSignal.call(e.customType);
|
||||
break;
|
||||
case Common::EVENT_KEYDOWN:
|
||||
_keyDownSignal.call(e.kbd);
|
||||
break;
|
||||
case Common::EVENT_KEYUP:
|
||||
_keyUpSignal.call(e.kbd);
|
||||
break;
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
_mouseMoveSignal.call(e.mouse);
|
||||
_lastMousePos = e.mouse;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
_mouseLDownSignal.call(e.mouse);
|
||||
_lastMousePos = e.mouse;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
_mouseLUpSignal.call(e.mouse);
|
||||
_lastMousePos = e.mouse;
|
||||
break;
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
_mouseRDownSignal.call(e.mouse);
|
||||
_lastMousePos = e.mouse;
|
||||
break;
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
_mouseRUpSignal.call(e.mouse);
|
||||
_lastMousePos = e.mouse;
|
||||
break;
|
||||
case Common::EVENT_MAINMENU:
|
||||
g_engine->getGame()->_returnToMainMenu = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
57
engines/tetraedge/te/te_input_mgr.h
Normal file
57
engines/tetraedge/te/te_input_mgr.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_INPUT_MGR_H
|
||||
#define TETRAEDGE_TE_TE_INPUT_MGR_H
|
||||
|
||||
#include "common/events.h"
|
||||
|
||||
#include "tetraedge/te/te_signal.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeInputMgr {
|
||||
public:
|
||||
TeInputMgr();
|
||||
|
||||
void handleEvent(const Common::Event &e);
|
||||
|
||||
TeSignal1Param<const Common::KeyState &> _keyDownSignal;
|
||||
TeSignal1Param<const Common::KeyState &> _keyUpSignal;
|
||||
TeSignal1Param<const Common::Point &> _mouseMoveSignal;
|
||||
TeSignal1Param<const Common::Point &> _mouseLDownSignal;
|
||||
TeSignal1Param<const Common::Point &> _mouseLUpSignal;
|
||||
TeSignal1Param<const Common::Point &> _mouseRDownSignal;
|
||||
TeSignal1Param<const Common::Point &> _mouseRUpSignal;
|
||||
TeSignal1Param<const Common::CustomEventType &> _customActionStartSignal;
|
||||
TeSignal1Param<const Common::CustomEventType &> _customActionEndSignal;
|
||||
|
||||
const Common::Point &lastMousePos() {
|
||||
return _lastMousePos;
|
||||
}
|
||||
|
||||
private:
|
||||
Common::Point _lastMousePos;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_INPUT_MGR_H
|
||||
82
engines/tetraedge/te/te_interpolation.cpp
Normal file
82
engines/tetraedge/te/te_interpolation.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/* 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/file.h"
|
||||
|
||||
#include "tetraedge/te/te_interpolation.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeInterpolation::TeInterpolation() {
|
||||
}
|
||||
|
||||
void TeInterpolation::load(Common::ReadStream &stream) {
|
||||
uint32 len = stream.readUint32LE();
|
||||
if (len > 1000000)
|
||||
error("TeInterpolation: Unexpected interpolation length %d", len);
|
||||
_array.resize(len);
|
||||
for (uint32 i = 0; i < len && !stream.err(); i++)
|
||||
_array[i] = stream.readFloatLE();
|
||||
}
|
||||
|
||||
void TeInterpolation::load(TetraedgeFSNode &node) {
|
||||
Common::ScopedPtr<Common::SeekableReadStream> f(node.createReadStream());
|
||||
if (!f)
|
||||
error("Couldn't open %s", node.toString().c_str());
|
||||
|
||||
load(*f);
|
||||
}
|
||||
|
||||
|
||||
// Note: this function is not in the original but simplifies
|
||||
// the code for TeCurveAnim2 a lot.
|
||||
void TeInterpolation::load(const Common::Array<double> &array) {
|
||||
_array = array;
|
||||
}
|
||||
|
||||
void TeInterpolation::load(const Common::Array<float> &array) {
|
||||
_array.clear();
|
||||
for (auto f : array) {
|
||||
_array.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
double TeInterpolation::interpole(double where, double max) const {
|
||||
const uint arrayLen = _array.size();
|
||||
if (!arrayLen)
|
||||
return 0.0;
|
||||
|
||||
double elemNum = (arrayLen - 1) * where / max;
|
||||
int leftElemNum = (int)floor(elemNum);
|
||||
|
||||
if (leftElemNum >= (int)arrayLen - 1)
|
||||
return _array[arrayLen - 1];
|
||||
else if (leftElemNum < 0)
|
||||
return _array[0];
|
||||
|
||||
double left = _array[leftElemNum];
|
||||
double right = _array[leftElemNum + 1];
|
||||
|
||||
return left + (right - left) * (elemNum - leftElemNum);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
54
engines/tetraedge/te/te_interpolation.h
Normal file
54
engines/tetraedge/te/te_interpolation.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_INTERPOLATION_H
|
||||
#define TETRAEDGE_TE_TE_INTERPOLATION_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/fs.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeInterpolation {
|
||||
public:
|
||||
TeInterpolation();
|
||||
|
||||
void load(Common::ReadStream &stream);
|
||||
void load(TetraedgeFSNode &node);
|
||||
|
||||
// Note: this function is not in the original but simplifies
|
||||
// the code for TeCurveAnim2 a lot.
|
||||
void load(const Common::Array<double> &array);
|
||||
void load(const Common::Array<float> &array);
|
||||
|
||||
double interpole(double amount, double max) const;
|
||||
|
||||
private:
|
||||
Common::Array<double> _array;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_INTERPOLATION_H
|
||||
133
engines/tetraedge/te/te_intrusive_ptr.h
Normal file
133
engines/tetraedge/te/te_intrusive_ptr.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
|
||||
#define TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/**
|
||||
Like the boost intrusive pointer. To be used with an
|
||||
object inheriting from TeReferencesCounter
|
||||
*/
|
||||
template<class T> class TeIntrusivePtr {
|
||||
public:
|
||||
// NOTE: The original uses a member function for this, which is cleaner, but
|
||||
// MSVC compiles member functions for different class types (forward
|
||||
// declaration, multi-inheritance, etc) as different sizes which causes all
|
||||
// sorts of issues. Only accept a static function to avoid such problems.
|
||||
typedef void(*Tdestructor)(T *obj);
|
||||
|
||||
TeIntrusivePtr() : _p(nullptr), _deleteFn(nullptr) {}
|
||||
|
||||
TeIntrusivePtr(const TeIntrusivePtr<T> &other) : _deleteFn(nullptr) {
|
||||
_p = other._p;
|
||||
if (_p)
|
||||
_p->incrementCounter();
|
||||
}
|
||||
|
||||
TeIntrusivePtr(T *obj) : _deleteFn(nullptr) {
|
||||
_p = obj;
|
||||
if (_p)
|
||||
_p->incrementCounter();
|
||||
}
|
||||
|
||||
virtual ~TeIntrusivePtr() {
|
||||
release();
|
||||
}
|
||||
|
||||
TeIntrusivePtr<T> &operator=(T *obj) {
|
||||
if (_p != obj) {
|
||||
release();
|
||||
_p = obj;
|
||||
if (_p)
|
||||
_p->incrementCounter();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TeIntrusivePtr<T> &operator=(const TeIntrusivePtr<T> &other) {
|
||||
if (this != &other) {
|
||||
release();
|
||||
_p = other._p;
|
||||
_deleteFn = other._deleteFn;
|
||||
if (_p)
|
||||
_p->incrementCounter();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void release() {
|
||||
if (_p) {
|
||||
if (_p->decrementCounter()) {
|
||||
if (_deleteFn)
|
||||
(_deleteFn)(_p);
|
||||
else
|
||||
delete _p;
|
||||
}
|
||||
}
|
||||
_p = nullptr;
|
||||
}
|
||||
|
||||
bool operator==(const TeIntrusivePtr<T> &other) const {
|
||||
return (this == &other || _p == other._p);
|
||||
}
|
||||
|
||||
T *get() {
|
||||
return _p;
|
||||
}
|
||||
|
||||
const T *get() const {
|
||||
return _p;
|
||||
}
|
||||
|
||||
T &operator*() {
|
||||
return *_p;
|
||||
}
|
||||
|
||||
const T &operator*() const {
|
||||
return *_p;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return _p != nullptr;
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
return _p;
|
||||
}
|
||||
|
||||
const T *operator->() const {
|
||||
return _p;
|
||||
}
|
||||
|
||||
void setDeleteFn(Tdestructor destructor) {
|
||||
_deleteFn = destructor;
|
||||
}
|
||||
|
||||
private:
|
||||
T *_p;
|
||||
Tdestructor _deleteFn;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_INTRUSIVE_PTR_H
|
||||
57
engines/tetraedge/te/te_jpeg.cpp
Normal file
57
engines/tetraedge/te/te_jpeg.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 "tetraedge/te/te_jpeg.h"
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/path.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "image/jpeg.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeJpeg::TeJpeg() {
|
||||
}
|
||||
|
||||
TeJpeg::~TeJpeg() {
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool TeJpeg::matchExtension(const Common::String &extn) {
|
||||
return extn == "jpg" || extn == "jpeg";
|
||||
}
|
||||
|
||||
bool TeJpeg::load(Common::SeekableReadStream &stream) {
|
||||
Image::JPEGDecoder jpg;
|
||||
|
||||
if (_loadedSurface)
|
||||
delete _loadedSurface;
|
||||
_loadedSurface = nullptr;
|
||||
|
||||
jpg.setOutputPixelFormat(Graphics::PixelFormat::createFormatRGBA32());
|
||||
if (!jpg.loadStream(stream))
|
||||
return false;
|
||||
|
||||
_loadedSurface = jpg.getSurface()->convertTo(Graphics::PixelFormat::createFormatRGBA32());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
53
engines/tetraedge/te/te_jpeg.h
Normal file
53
engines/tetraedge/te/te_jpeg.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_JPEG_H
|
||||
#define TETRAEDGE_TE_TE_JPEG_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "tetraedge/te/te_scummvm_codec.h"
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
}
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeJpeg : public TeScummvmCodec {
|
||||
public:
|
||||
TeJpeg();
|
||||
virtual ~TeJpeg();
|
||||
|
||||
virtual bool load(Common::SeekableReadStream &stream) override;
|
||||
virtual int nbFrames() override { return 1; }
|
||||
virtual float frameRate() override { return 0.0f; }
|
||||
virtual bool isAtEnd() override { return true; }
|
||||
virtual void setColorKeyActivated(bool val) override { }
|
||||
virtual void setColorKey(const TeColor &col) override { }
|
||||
virtual void setColorKeyTolerence(float val) override { }
|
||||
|
||||
static bool matchExtension(const Common::String &extn);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_JPEG_H
|
||||
519
engines/tetraedge/te/te_layout.cpp
Normal file
519
engines/tetraedge/te/te_layout.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
/* 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/textconsole.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/game/application.h"
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_i_3d_object2.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeLayout::TeLayout() : Te3DObject2(), _autoz(true), _needZUpdate(true), _updatingZ(false),
|
||||
_needZSizeUpdate(true), _updatingZSize(false), _sizeChanged(true), _updatingSize(false),
|
||||
_positionChanged(true), _updatingPosition(false), _worldMatrixChanged(true),
|
||||
_updatingWorldMatrix(false), _drawMode(TeILayout::DrawMode0),
|
||||
_sizeType(CoordinatesType::ABSOLUTE), _userSize(1.0f, 1.0f, 1.0f),
|
||||
_anchor(0.5f, 0.5f, 0.5f), _ratio(1.0f), _safeAreaRatio(1.333333f),
|
||||
_ratioMode(RATIO_MODE_NONE), _positionType(CoordinatesType::RELATIVE_TO_PARENT)
|
||||
{
|
||||
_userPosition = _position = TeVector3f32(0.5f, 0.5f, 0.5f);
|
||||
_size = TeVector3f32(1.0f, 1.0f, 1.0f);
|
||||
_onChildSizeChangedCallback.reset(
|
||||
new TeCallback0Param<TeLayout>(this, &TeLayout::onChildSizeChanged));
|
||||
_onParentSizeChangedCallback.reset(
|
||||
new TeCallback0Param<TeLayout>(this, &TeLayout::onParentSizeChanged));
|
||||
_onParentWorldTransformationMatrixChangedCallback.reset(
|
||||
new TeCallback0Param<TeLayout>(this, &TeLayout::onParentWorldTransformationMatrixChanged));
|
||||
|
||||
updateSize();
|
||||
updateMesh();
|
||||
}
|
||||
|
||||
TeLayout::~TeLayout() {
|
||||
if (parent() && _onParentSizeChangedCallback) {
|
||||
parent()->onSizeChanged().remove(_onParentSizeChangedCallback);
|
||||
_onParentSizeChangedCallback.reset();
|
||||
parent()->onWorldTransformationMatrixChanged().remove(_onParentWorldTransformationMatrixChangedCallback);
|
||||
_onParentWorldTransformationMatrixChangedCallback.reset();
|
||||
}
|
||||
|
||||
if (_onChildSizeChangedCallback) {
|
||||
for (auto &child : childList()) {
|
||||
child->onSizeChanged().remove(_onChildSizeChangedCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::addChild(Te3DObject2 *child) {
|
||||
Te3DObject2::addChild(child);
|
||||
if (_onChildSizeChangedCallback) {
|
||||
child->onSizeChanged().push_back(_onChildSizeChangedCallback);
|
||||
}
|
||||
_needZSizeUpdate = true;
|
||||
_needZUpdate = true;
|
||||
updateZSize();
|
||||
updateZ();
|
||||
}
|
||||
|
||||
void TeLayout::addChildBefore(Te3DObject2 *child, const Te3DObject2 *ref) {
|
||||
Te3DObject2::addChildBefore(child, ref);
|
||||
if (_onChildSizeChangedCallback) {
|
||||
child->onSizeChanged().push_back(_onChildSizeChangedCallback);
|
||||
}
|
||||
_needZSizeUpdate = true;
|
||||
_needZUpdate = true;
|
||||
updateZSize();
|
||||
updateZ();
|
||||
}
|
||||
|
||||
void TeLayout::removeChild(Te3DObject2 *child) {
|
||||
if (_onChildSizeChangedCallback) {
|
||||
child->onSizeChanged().remove(_onChildSizeChangedCallback);
|
||||
}
|
||||
Te3DObject2::removeChild(child);
|
||||
_needZSizeUpdate = true;
|
||||
_needZUpdate = true;
|
||||
updateZSize();
|
||||
updateZ();
|
||||
}
|
||||
|
||||
const TeVector3f32 &TeLayout::anchor() {
|
||||
return _anchor;
|
||||
}
|
||||
|
||||
void TeLayout::disableAutoZ() {
|
||||
_autoz = false;
|
||||
}
|
||||
|
||||
void TeLayout::enableAutoZ() {
|
||||
_autoz = true;
|
||||
}
|
||||
|
||||
bool TeLayout::isAutoZEnabled() {
|
||||
return _autoz;
|
||||
}
|
||||
|
||||
void TeLayout::draw() {
|
||||
if (visible() && worldVisible()) {
|
||||
// Ensure world transform is up-to-date.
|
||||
worldTransformationMatrix();
|
||||
for (auto &child : childList()) {
|
||||
child->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const float EPSILON = 1.192093e-07f;
|
||||
|
||||
bool TeLayout::isMouseIn(const TeVector2s32 &mouseloc) {
|
||||
const TeVector3f32 transformedPos = transformMousePosition(mouseloc);
|
||||
const TeVector3f32 halfSize = size() / 2.0;
|
||||
|
||||
return ( (transformedPos.x() >= -halfSize.x() - EPSILON)
|
||||
&& (transformedPos.x() < halfSize.x() + EPSILON)
|
||||
&& (transformedPos.y() >= -halfSize.y() - EPSILON)
|
||||
&& (transformedPos.y() < halfSize.y() + EPSILON));
|
||||
}
|
||||
|
||||
TeILayout::DrawMode TeLayout::mode() {
|
||||
return _drawMode;
|
||||
}
|
||||
|
||||
bool TeLayout::onChildSizeChanged() {
|
||||
_needZSizeUpdate = true;
|
||||
_needZUpdate = true;
|
||||
|
||||
updateSize();
|
||||
if (!_updatingZSize)
|
||||
updateZSize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TeLayout::onParentSizeChanged() {
|
||||
_sizeChanged = true;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TeLayout::onParentWorldTransformationMatrixChanged() {
|
||||
_worldMatrixChanged = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::position() {
|
||||
updateZ();
|
||||
updatePosition();
|
||||
return _position;
|
||||
}
|
||||
|
||||
TeLayout::CoordinatesType TeLayout::positionType() const {
|
||||
return _positionType;
|
||||
}
|
||||
|
||||
float TeLayout::ratio() const {
|
||||
return _ratio;
|
||||
}
|
||||
|
||||
TeLayout::RatioMode TeLayout::ratioMode() const {
|
||||
return _ratioMode;
|
||||
}
|
||||
|
||||
float TeLayout::safeAreaRatio() const {
|
||||
return _safeAreaRatio;
|
||||
}
|
||||
|
||||
void TeLayout::setAnchor(const TeVector3f32 &anchor) {
|
||||
if (_anchor != anchor) {
|
||||
_anchor = anchor;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
updatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setMode(DrawMode mode) {
|
||||
_drawMode = mode;
|
||||
}
|
||||
|
||||
void TeLayout::setParent(Te3DObject2 *parent) {
|
||||
assert(parent != this);
|
||||
Te3DObject2 *oldParent = Te3DObject2::parent();
|
||||
if (oldParent) {
|
||||
if (_onParentSizeChangedCallback)
|
||||
oldParent->onSizeChanged().remove(_onParentSizeChangedCallback);
|
||||
if (_onParentWorldTransformationMatrixChangedCallback)
|
||||
oldParent->onWorldTransformationMatrixChanged().remove(_onParentWorldTransformationMatrixChangedCallback);
|
||||
}
|
||||
|
||||
//
|
||||
TeLayout &mainWindowLayout = g_engine->getApplication()->getMainWindow();
|
||||
mainWindowLayout.onSizeChanged().remove(_onMainWindowChangedCallback);
|
||||
|
||||
Te3DObject2::setParent(parent);
|
||||
if (parent) {
|
||||
if (_onParentSizeChangedCallback)
|
||||
parent->onSizeChanged().push_back(_onParentSizeChangedCallback);
|
||||
if (_onParentWorldTransformationMatrixChangedCallback)
|
||||
parent->onWorldTransformationMatrixChanged().push_back(_onParentWorldTransformationMatrixChangedCallback);
|
||||
if (_onMainWindowChangedCallback)
|
||||
mainWindowLayout.onSizeChanged().push_back(_onMainWindowChangedCallback);
|
||||
}
|
||||
_needZUpdate = true;
|
||||
_sizeChanged = true;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void TeLayout::setPosition(const TeVector3f32 &pos) {
|
||||
TeVector3f32 pos3d(pos.x(), pos.y(), _userPosition.z());
|
||||
if (_userPosition != pos3d) {
|
||||
_userPosition.x() = pos.x();
|
||||
_userPosition.y() = pos.y();
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setPositionType(CoordinatesType newtype) {
|
||||
if (_positionType != newtype) {
|
||||
_positionType = newtype;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setRatio(float val) {
|
||||
if (_ratio != val) {
|
||||
_ratio = val;
|
||||
_sizeChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setRatioMode(RatioMode mode) {
|
||||
if (_ratioMode != mode) {
|
||||
_ratioMode = mode;
|
||||
_sizeChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setRotation(const TeQuaternion &rot) {
|
||||
if (rot != _rotation) {
|
||||
Te3DObject2::setRotation(rot);
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setSafeAreaRatio(float ratio) {
|
||||
if (_safeAreaRatio != ratio) {
|
||||
_safeAreaRatio = ratio;
|
||||
_sizeChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setScale(const TeVector3f32 &scale) {
|
||||
Te3DObject2::setScale(scale);
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
|
||||
void TeLayout::setSize(const TeVector3f32 &size) {
|
||||
const TeVector3f32 size3d(size.x(), size.y(), _userSize.z());
|
||||
if (_userSize != size3d) {
|
||||
_userSize.x() = size.x();
|
||||
_userSize.y() = size.y();
|
||||
_sizeChanged = true;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setSizeType(CoordinatesType coordtype) {
|
||||
assert(coordtype == RELATIVE_TO_PARENT || coordtype == ABSOLUTE);
|
||||
if (_sizeType != coordtype) {
|
||||
_sizeType = coordtype;
|
||||
_sizeChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::setZPosition(float zpos) {
|
||||
if (_userPosition.z() != zpos) {
|
||||
_userPosition.z() = zpos;
|
||||
_positionChanged = true;
|
||||
_worldMatrixChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::size() {
|
||||
updateSize();
|
||||
updateZSize();
|
||||
return _size;
|
||||
}
|
||||
|
||||
TeLayout::CoordinatesType TeLayout::sizeType() const {
|
||||
return _sizeType;
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::transformMousePosition(const TeVector2s32 &mousepos) {
|
||||
TeVector3f32 relativeMouse(mousepos);
|
||||
|
||||
relativeMouse.x() -= g_system->getWidth() / 2;
|
||||
relativeMouse.y() -= g_system->getHeight() / 2;
|
||||
|
||||
TeMatrix4x4 transform = worldTransformationMatrix();
|
||||
transform.inverse();
|
||||
TeVector3f32 transformpos = transform * relativeMouse;
|
||||
|
||||
//debug("transformMousePosition: %d %d -> %f %f", mousepos._x, mousepos._y, transformpos.x(), transformpos.y());
|
||||
return transformpos;
|
||||
}
|
||||
|
||||
void TeLayout::updatePosition() {
|
||||
if (!_positionChanged)
|
||||
return;
|
||||
|
||||
_positionChanged = false;
|
||||
_updatingPosition = true;
|
||||
TeVector3f32 oldpos = _position;
|
||||
Te3DObject2 *parentObj = parent();
|
||||
static const TeVector3f32 midPoint(0.5f, 0.5f, 0.5f);
|
||||
if (_positionType == RELATIVE_TO_PARENT && parentObj) {
|
||||
const TeVector3f32 offsetUserPos = _userPosition - midPoint;
|
||||
const TeVector3f32 parentSize(parentObj->xSize(), parentObj->ySize(), 0.0);
|
||||
const TeVector3f32 offsetAnchor = midPoint - _anchor;
|
||||
const TeVector3f32 thisSize(xSize(), ySize(), 0.0);
|
||||
const TeVector3f32 newpos = (offsetUserPos * parentSize) + (offsetAnchor * thisSize);
|
||||
_position = newpos;
|
||||
} else if (_positionType == RELATIVE_TO_PARENT && !parentObj) {
|
||||
// Not in original, but no parent -> set midpoint.
|
||||
const TeVector3f32 offsetAnchor = midPoint - _anchor;
|
||||
const TeVector3f32 thisSize(xSize(), ySize(), 0.0);
|
||||
_position = offsetAnchor * thisSize;
|
||||
} else if (_positionType == ABSOLUTE) {
|
||||
_position = _userPosition;
|
||||
}
|
||||
_position.z() = _userPosition.z();
|
||||
_worldMatrixChanged = true;
|
||||
_updatingPosition = false;
|
||||
|
||||
if (_position != oldpos) {
|
||||
onPositionChanged().call();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::updateSize() {
|
||||
if (!_sizeChanged)
|
||||
return;
|
||||
|
||||
_sizeChanged = false;
|
||||
_updatingSize = true;
|
||||
const TeVector3f32 oldSize = _size;
|
||||
|
||||
if (_sizeType == ABSOLUTE) {
|
||||
TeVector3f32 newSize = _userSize;
|
||||
_size.x() = abs(newSize.x());
|
||||
_size.y() = abs(newSize.y());
|
||||
// don't set Z val.
|
||||
} else if (_sizeType == RELATIVE_TO_PARENT) {
|
||||
Te3DObject2 *parentObj = parent();
|
||||
if (parentObj) {
|
||||
const TeVector3f32 parentSize(parentObj->xSize(), parentObj->ySize(), 0.0);
|
||||
TeVector3f32 newSize = _userSize * parentSize;
|
||||
if (newSize.x() > 0.0f && newSize.y() > 0.0f && _ratio > 0.0f && _safeAreaRatio > 0.0f) {
|
||||
float newSizeRatio = newSize.x() / newSize.y();
|
||||
if (_ratioMode == RATIO_MODE_PAN_SCAN) {
|
||||
if (_safeAreaRatio <= newSizeRatio) {
|
||||
newSize.x() = _ratio * newSize.y();
|
||||
} else {
|
||||
newSize.x() =
|
||||
(1.0f - (_safeAreaRatio - newSizeRatio) / _safeAreaRatio) *
|
||||
_ratio * newSize.y();
|
||||
}
|
||||
} else if (_ratioMode == RATIO_MODE_LETTERBOX) {
|
||||
if (_ratio < newSizeRatio)
|
||||
newSize.x() = _ratio * newSize.y();
|
||||
else
|
||||
newSize.y() = newSize.x() / _ratio;
|
||||
}
|
||||
}
|
||||
|
||||
_size.x() = newSize.x();
|
||||
_size.y() = newSize.y();
|
||||
} else {
|
||||
_size.x() = 0.0f;
|
||||
_size.y() = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
_updatingSize = false;
|
||||
// TODO: check this, is it the right flag to set?
|
||||
_positionChanged = true;
|
||||
|
||||
updateMesh();
|
||||
|
||||
if (_size != oldSize) {
|
||||
onSizeChanged().call();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::updateWorldMatrix() {
|
||||
if (!_worldMatrixChanged)
|
||||
return;
|
||||
|
||||
_worldMatrixChanged = false;
|
||||
_updatingWorldMatrix = true;
|
||||
const TeMatrix4x4 oldMatrix = _worldMatrixCache;
|
||||
_worldMatrixCache = Te3DObject2::worldTransformationMatrix();
|
||||
_updatingWorldMatrix = false;
|
||||
if (_worldMatrixCache != oldMatrix) {
|
||||
onWorldTransformationMatrixChanged().call();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLayout::updateZ() {
|
||||
if (!_needZUpdate || !_autoz)
|
||||
return;
|
||||
|
||||
_needZUpdate = false;
|
||||
_updatingZ = true;
|
||||
|
||||
float ztotal = 0.1f;
|
||||
for (auto &child : childList()) {
|
||||
child->setZPosition(ztotal);
|
||||
ztotal += child->zSize();
|
||||
}
|
||||
_updatingZ = false;
|
||||
}
|
||||
|
||||
void TeLayout::updateZSize() {
|
||||
if (!_needZSizeUpdate)
|
||||
return;
|
||||
|
||||
_needZSizeUpdate = false;
|
||||
_updatingZSize = true;
|
||||
const TeVector3f32 oldSize = _size;
|
||||
_size.z() = 0.1f;
|
||||
|
||||
for (auto &child : childList()) {
|
||||
_size.z() += child->zSize();
|
||||
}
|
||||
|
||||
_positionChanged = true;
|
||||
_updatingZSize = false;
|
||||
if (_size != oldSize) {
|
||||
onSizeChanged().call();
|
||||
}
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::userPosition() const {
|
||||
return _userPosition;
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::userSize() {
|
||||
updateZ();
|
||||
return _userSize;
|
||||
}
|
||||
|
||||
TeVector3f32 TeLayout::worldPosition() {
|
||||
if (!parent()) {
|
||||
return position();
|
||||
} else {
|
||||
return parent()->worldPosition() + position();
|
||||
}
|
||||
}
|
||||
|
||||
TeMatrix4x4 TeLayout::worldTransformationMatrix() {
|
||||
updateZ();
|
||||
updatePosition();
|
||||
updateWorldMatrix();
|
||||
return _worldMatrixCache;
|
||||
}
|
||||
|
||||
bool TeLayout::worldVisible() {
|
||||
bool visible = Te3DObject2::visible();
|
||||
if (visible && parent()) {
|
||||
return parent()->worldVisible();
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
float TeLayout::xSize() {
|
||||
updateSize();
|
||||
return _size.x();
|
||||
}
|
||||
|
||||
float TeLayout::ySize() {
|
||||
updateSize();
|
||||
return _size.y();
|
||||
}
|
||||
|
||||
float TeLayout::zSize() {
|
||||
updateZSize();
|
||||
return _size.z();
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
133
engines/tetraedge/te/te_layout.h
Normal file
133
engines/tetraedge/te/te_layout.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_i_layout.h"
|
||||
#include "tetraedge/te/te_i_3d_object2.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_vector2s32.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLayout : public TeILayout, public Te3DObject2 {
|
||||
public:
|
||||
TeLayout();
|
||||
|
||||
virtual ~TeLayout();
|
||||
|
||||
void addChild(Te3DObject2 *child) override;
|
||||
void addChildBefore(Te3DObject2 *newchild, const Te3DObject2 *ref) override;
|
||||
const TeVector3f32 &anchor();
|
||||
void disableAutoZ();
|
||||
void enableAutoZ();
|
||||
bool isAutoZEnabled();
|
||||
|
||||
void draw() override;
|
||||
|
||||
virtual bool isMouseIn(const TeVector2s32 &mouseloc);
|
||||
|
||||
DrawMode mode();
|
||||
|
||||
bool onChildSizeChanged();
|
||||
bool onParentSizeChanged();
|
||||
bool onParentWorldTransformationMatrixChanged();
|
||||
|
||||
TeVector3f32 position() override;
|
||||
CoordinatesType positionType() const;
|
||||
float ratio() const;
|
||||
RatioMode ratioMode() const;
|
||||
void removeChild(Te3DObject2 *child) override;
|
||||
float safeAreaRatio() const;
|
||||
void setAnchor(const TeVector3f32 &anchor);
|
||||
virtual void setEditionColor(TeColor col) {};
|
||||
void setMode(DrawMode mode);
|
||||
void setParent(Te3DObject2 *parent) override;
|
||||
void setPosition(const TeVector3f32 &pos) override;
|
||||
void setPositionType(CoordinatesType newtype);
|
||||
void setRatio(float val);
|
||||
void setRatioMode(RatioMode mode);
|
||||
void setRotation(const TeQuaternion &rot) override;
|
||||
void setSafeAreaRatio(float ratio);
|
||||
void setScale(const TeVector3f32 &scale) override;
|
||||
void setSize(const TeVector3f32 &size) override;
|
||||
void setSizeType(CoordinatesType coordtype);
|
||||
void setZPosition(float zpos) override;
|
||||
|
||||
virtual TeVector3f32 size() override;
|
||||
CoordinatesType sizeType() const;
|
||||
TeVector3f32 transformMousePosition(const TeVector2s32 &mousepos);
|
||||
|
||||
virtual void updateMesh() {}; // override available for TeSpriteLayout
|
||||
void updatePosition();
|
||||
virtual void updateSize();
|
||||
void updateWorldMatrix();
|
||||
void updateZ() override;
|
||||
void updateZSize();
|
||||
|
||||
TeVector3f32 userPosition() const;
|
||||
TeVector3f32 userSize();
|
||||
TeVector3f32 worldPosition() override;
|
||||
TeMatrix4x4 worldTransformationMatrix() override;
|
||||
bool worldVisible() override;
|
||||
float xSize() override;
|
||||
float ySize() override;
|
||||
float zSize() override;
|
||||
|
||||
protected:
|
||||
bool _sizeChanged;
|
||||
|
||||
private:
|
||||
TeVector3f32 _anchor;
|
||||
CoordinatesType _positionType;
|
||||
TeVector3f32 _userPosition;
|
||||
CoordinatesType _sizeType;
|
||||
TeVector3f32 _userSize;
|
||||
TeMatrix4x4 _worldMatrixCache;
|
||||
|
||||
DrawMode _drawMode;
|
||||
bool _autoz;
|
||||
bool _positionChanged;
|
||||
bool _worldMatrixChanged;
|
||||
bool _needZSizeUpdate;
|
||||
bool _needZUpdate;
|
||||
bool _updatingZ;
|
||||
bool _updatingZSize;
|
||||
bool _updatingSize;
|
||||
bool _updatingPosition;
|
||||
bool _updatingWorldMatrix;
|
||||
float _ratio;
|
||||
RatioMode _ratioMode;
|
||||
float _safeAreaRatio;
|
||||
|
||||
TeICallback0ParamPtr _onChildSizeChangedCallback;
|
||||
TeICallback0ParamPtr _onParentSizeChangedCallback;
|
||||
TeICallback0ParamPtr _onParentWorldTransformationMatrixChangedCallback;
|
||||
TeICallback0ParamPtr _onMainWindowChangedCallback;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LAYOUT_H
|
||||
112
engines/tetraedge/te/te_light.cpp
Normal file
112
engines/tetraedge/te/te_light.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/* 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 "graphics/renderer.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_light.h"
|
||||
#include "tetraedge/te/te_light_opengl.h"
|
||||
#include "tetraedge/te/te_light_tinygl.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/*static*/
|
||||
uint32 TeLight::_globalAmbientColor = 0xffffffff;
|
||||
|
||||
TeLight::TeLight() : _colAmbient(0, 0, 0, 0xff), _colDiffuse(0, 0, 0, 0xff), _colSpecular(0xff, 0xff, 0xff, 0xff),
|
||||
_constAtten(1.0f), _linearAtten(0.0f), _quadraticAtten(0.0f), _cutoff(0.0f), _exponent(0.0f), _type(LightTypePoint),
|
||||
_displaySize(3.0f)
|
||||
{
|
||||
}
|
||||
|
||||
TeVector3f32 TeLight::directionVector() const {
|
||||
float cosx = cosf(_positionRadial.getX());
|
||||
float cosy = cosf(_positionRadial.getY());
|
||||
float sinx = sinf(_positionRadial.getX());
|
||||
float siny = sinf(_positionRadial.getY());
|
||||
return TeVector3f32(cosx * cosy, siny, sinx * cosy);
|
||||
}
|
||||
|
||||
void TeLight::transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2) {
|
||||
const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX() + M_PI);
|
||||
const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), -_positionRadial.getY());
|
||||
pt2.rotate(q2);
|
||||
pt2.rotate(q1);
|
||||
pt2 += pt1;
|
||||
}
|
||||
|
||||
void TeLight::transformSpotPoint(TeVector3f32 &pt) {
|
||||
const TeQuaternion q1 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), _positionRadial.getX());
|
||||
const TeQuaternion q2 = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 0, -1), _positionRadial.getY());
|
||||
pt.rotate(q2);
|
||||
pt.rotate(q1);
|
||||
pt += _position3d;
|
||||
}
|
||||
|
||||
Common::String TeLight::dump() const {
|
||||
const char *ltype;
|
||||
switch (_type) {
|
||||
case LightTypeSpot:
|
||||
ltype = "Spot";
|
||||
break;
|
||||
case LightTypePoint:
|
||||
ltype = "Point";
|
||||
break;
|
||||
case LightTypeDirectional:
|
||||
ltype = "Directional";
|
||||
break;
|
||||
default:
|
||||
error("Invalid light type %d", (int)_type);
|
||||
}
|
||||
|
||||
return Common::String::format("%sLight(\n\tamb:%s diff:%s spec:%s\n\tpos:%s posRad:%s atten:%.02f %.02f %.02f\n\tcutoff:%.02f exp:%.02f dispSz:%.02f\n)",
|
||||
ltype, _colAmbient.dump().c_str(), _colDiffuse.dump().c_str(),
|
||||
_colSpecular.dump().c_str(), _position3d.dump().c_str(),
|
||||
_positionRadial.dump().c_str(), _constAtten, _linearAtten,
|
||||
_quadraticAtten, _cutoff, _exponent, _displaySize);
|
||||
}
|
||||
|
||||
void TeLight::correctAttenuation() {
|
||||
if (!_constAtten && !_linearAtten && !_quadraticAtten)
|
||||
_constAtten = 1.0;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeLight *TeLight::makeInstance() {
|
||||
Graphics::RendererType r = g_engine->preferredRendererType();
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
if (r == Graphics::kRendererTypeOpenGL)
|
||||
return new TeLightOpenGL();
|
||||
#endif
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
if (r == Graphics::kRendererTypeTinyGL)
|
||||
return new TeLightTinyGL();
|
||||
#endif
|
||||
error("Couldn't create TeLight for selected renderer");
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
101
engines/tetraedge/te/te_light.h
Normal file
101
engines/tetraedge/te/te_light.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LIGHT_H
|
||||
#define TETRAEDGE_TE_TE_LIGHT_H
|
||||
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_vector2f32.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
enum TeLightType {
|
||||
LightTypePoint = 0,
|
||||
LightTypeDirectional = 1,
|
||||
LightTypeSpot = 2
|
||||
};
|
||||
|
||||
class TeCamera;
|
||||
|
||||
class TeLight {
|
||||
public:
|
||||
TeLight();
|
||||
virtual ~TeLight() {};
|
||||
|
||||
TeVector3f32 directionVector() const;
|
||||
virtual void disable(uint lightno) = 0;
|
||||
virtual void enable(uint lightno) = 0;
|
||||
|
||||
virtual void draw(TeCamera &camera) = 0;
|
||||
|
||||
void transformDirPoint(const TeVector3f32 &pt1, TeVector3f32 &pt2);
|
||||
void transformSpotPoint(TeVector3f32 &pt1);
|
||||
|
||||
virtual void update(uint lightno) = 0;
|
||||
static void setGlobalAmbient(const TeColor &col) { _globalAmbientColor = col.getPacked32(); }
|
||||
static TeColor globalAmbient() { return TeColor(_globalAmbientColor); }
|
||||
|
||||
void setSpecular(const TeColor &col) { _colSpecular = col; }
|
||||
void setDiffuse(const TeColor &col) { _colDiffuse = col; }
|
||||
void setAmbient(const TeColor &col) { _colAmbient = col; }
|
||||
|
||||
void setConstAtten(float val) { _constAtten = val; }
|
||||
void setLinearAtten(float val) { _linearAtten = val; }
|
||||
void setQuadraticAtten(float val) { _quadraticAtten = val; }
|
||||
void setCutoff(float val) { _cutoff = val; }
|
||||
void setExponent(float val) { _exponent = val; }
|
||||
void setDisplaySize(float val) { _displaySize = val; }
|
||||
void setPosition3d(const TeVector3f32 &pos) { _position3d = pos; }
|
||||
void setPositionRadial(const TeVector2f32 &pos) { _positionRadial = pos; }
|
||||
void setType(TeLightType ltype) { _type = ltype; }
|
||||
|
||||
const TeVector2f32 &positionRadial() const { return _positionRadial; }
|
||||
const TeVector3f32 &position3d() const { return _position3d; }
|
||||
|
||||
Common::String dump() const;
|
||||
void correctAttenuation();
|
||||
|
||||
static TeLight *makeInstance();
|
||||
|
||||
protected:
|
||||
TeVector3f32 _position3d;
|
||||
TeVector2f32 _positionRadial;
|
||||
|
||||
TeColor _colAmbient;
|
||||
TeColor _colDiffuse;
|
||||
TeColor _colSpecular;
|
||||
|
||||
enum TeLightType _type;
|
||||
|
||||
static uint32 _globalAmbientColor;
|
||||
|
||||
float _constAtten;
|
||||
float _linearAtten;
|
||||
float _quadraticAtten;
|
||||
float _cutoff;
|
||||
float _exponent;
|
||||
float _displaySize;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LIGHT_H
|
||||
124
engines/tetraedge/te/te_light_opengl.cpp
Normal file
124
engines/tetraedge/te/te_light_opengl.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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 "tetraedge/te/te_light_opengl.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
#include "graphics/opengl/system_headers.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
static inline uint _toGlLight(uint lightno) {
|
||||
return GL_LIGHT0 + lightno;
|
||||
}
|
||||
|
||||
TeLightOpenGL::TeLightOpenGL() {
|
||||
}
|
||||
|
||||
void TeLightOpenGL::disable(uint lightno) {
|
||||
glDisable(_toGlLight(lightno));
|
||||
}
|
||||
|
||||
void TeLightOpenGL::enable(uint lightno) {
|
||||
// Note: original casts to float and compares to 0.01, but that's the same?
|
||||
if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
|
||||
glDisable(_toGlLight(lightno));
|
||||
else
|
||||
glEnable(_toGlLight(lightno));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightOpenGL::disableAll() {
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightOpenGL::enableAll() {
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
void TeLightOpenGL::draw(TeCamera &camera) {
|
||||
error("TODO: Finish TeLightOpenGL::draw");
|
||||
}
|
||||
|
||||
void TeLightOpenGL::update(uint lightno) {
|
||||
if (lightno > GL_MAX_LIGHTS)
|
||||
error("Invalid light no %d", lightno);
|
||||
const uint glLight = _toGlLight(lightno);
|
||||
|
||||
const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
|
||||
_colAmbient.b() / 255.0f, 1.0f};
|
||||
glLightfv(glLight, GL_AMBIENT, ambient);
|
||||
|
||||
const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
|
||||
_colDiffuse.b() / 255.0f, 1.0f};
|
||||
glLightfv(glLight, GL_DIFFUSE, diff);
|
||||
|
||||
// WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
|
||||
// the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
|
||||
// values (4, 0, 0) which means it gets enabled and everything is dark.
|
||||
|
||||
if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
|
||||
glDisable(glLight);
|
||||
|
||||
const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
|
||||
_colSpecular.b() / 255.0f, 1.0f};
|
||||
glLightfv(glLight, GL_SPECULAR, spec);
|
||||
|
||||
if (_type == LightTypeSpot || _type == LightTypePoint) {
|
||||
const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
|
||||
glLightfv(glLight, GL_POSITION, pos);
|
||||
glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
|
||||
glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
|
||||
glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
|
||||
}
|
||||
|
||||
if (_type == LightTypeDirectional) {
|
||||
const TeVector3f32 dirv = directionVector();
|
||||
const float dir[4] = {dirv.x(), dirv.y(), dirv.z(), 0.0f};
|
||||
glLightfv(glLight, GL_POSITION, dir);
|
||||
}
|
||||
|
||||
if (_type == LightTypeSpot) {
|
||||
const TeVector3f32 dirv = directionVector();
|
||||
const float dir[4] = {dirv.x(), dirv.y(), dirv.z(), 0.0f};
|
||||
glLightfv(glLight, GL_SPOT_DIRECTION, dir);
|
||||
glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0f) / M_PI);
|
||||
// Exponent doesn't get set in Syberia 2
|
||||
if (g_engine->gameType() == TetraedgeEngine::kSyberia)
|
||||
glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
|
||||
} else {
|
||||
glLightf(glLight, GL_SPOT_CUTOFF, 180.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightOpenGL::updateGlobal() {
|
||||
const TeColor globalAmbient(_globalAmbientColor);
|
||||
const float col[4] = {globalAmbient.r() / 255.0f,
|
||||
globalAmbient.g() / 255.0f, globalAmbient.b() / 255.0f, 1.0f};
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
56
engines/tetraedge/te/te_light_opengl.h
Normal file
56
engines/tetraedge/te/te_light_opengl.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LIGHT_OPENGL_H
|
||||
#define TETRAEDGE_TE_TE_LIGHT_OPENGL_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
|
||||
#include "tetraedge/te/te_light.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeCamera;
|
||||
|
||||
class TeLightOpenGL : public TeLight {
|
||||
public:
|
||||
TeLightOpenGL();
|
||||
|
||||
void disable(uint lightno) override;
|
||||
void enable(uint lightno) override;
|
||||
|
||||
void draw(TeCamera &camera) override;
|
||||
|
||||
void update(uint lightno) override;
|
||||
static void updateGlobal();
|
||||
|
||||
static void disableAll();
|
||||
static void enableAll();
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_OPENGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LIGHT_OPENGL_H
|
||||
123
engines/tetraedge/te/te_light_tinygl.cpp
Normal file
123
engines/tetraedge/te/te_light_tinygl.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/* 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 "graphics/tinygl/tinygl.h"
|
||||
|
||||
#include "tetraedge/te/te_light_tinygl.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
static inline uint _toGlLight(uint lightno) {
|
||||
return TGL_LIGHT0 + lightno;
|
||||
}
|
||||
|
||||
TeLightTinyGL::TeLightTinyGL() {
|
||||
}
|
||||
|
||||
void TeLightTinyGL::disable(uint lightno) {
|
||||
tglDisable(_toGlLight(lightno));
|
||||
}
|
||||
|
||||
void TeLightTinyGL::enable(uint lightno) {
|
||||
if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
|
||||
tglDisable(_toGlLight(lightno));
|
||||
else
|
||||
tglEnable(_toGlLight(lightno));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightTinyGL::disableAll() {
|
||||
tglDisable(TGL_LIGHTING);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightTinyGL::enableAll() {
|
||||
tglEnable(TGL_LIGHTING);
|
||||
}
|
||||
|
||||
void TeLightTinyGL::draw(TeCamera &camera) {
|
||||
error("TODO: Finish TeLight::draw");
|
||||
}
|
||||
|
||||
void TeLightTinyGL::update(uint lightno) {
|
||||
if (lightno > TGL_MAX_LIGHTS)
|
||||
error("Invalid light no %d", lightno);
|
||||
const uint glLight = _toGlLight(lightno);
|
||||
|
||||
const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
|
||||
_colAmbient.b() / 255.0f, 1.0f};
|
||||
tglLightfv(glLight, TGL_AMBIENT, ambient);
|
||||
|
||||
const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
|
||||
_colDiffuse.b() / 255.0f, 1.0f};
|
||||
tglLightfv(glLight, TGL_DIFFUSE, diff);
|
||||
|
||||
// WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
|
||||
// the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
|
||||
// values (4, 0, 0) which means it gets enabled and everything is dark.
|
||||
|
||||
if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
|
||||
tglDisable(glLight);
|
||||
|
||||
const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
|
||||
_colSpecular.b() / 255.0f, 1.0f};
|
||||
tglLightfv(glLight, TGL_SPECULAR, spec);
|
||||
|
||||
if (_type == LightTypeSpot || _type == LightTypePoint) {
|
||||
const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
|
||||
tglLightfv(glLight, TGL_POSITION, pos);
|
||||
tglLightf(glLight, TGL_CONSTANT_ATTENUATION, _constAtten);
|
||||
tglLightf(glLight, TGL_LINEAR_ATTENUATION, _linearAtten);
|
||||
tglLightf(glLight, TGL_QUADRATIC_ATTENUATION, _quadraticAtten);
|
||||
}
|
||||
|
||||
if (_type == LightTypeDirectional) {
|
||||
const TeVector3f32 dirv = directionVector();
|
||||
const float dir[4] = {dirv.x(), dirv.y(), dirv.z(), 0.0f};
|
||||
tglLightfv(glLight, TGL_POSITION, dir);
|
||||
}
|
||||
|
||||
if (_type == LightTypeSpot) {
|
||||
const TeVector3f32 dirv = directionVector();
|
||||
const float dir[4] = {dirv.x(), dirv.y(), dirv.z(), 0.0f};
|
||||
tglLightfv(glLight, TGL_SPOT_DIRECTION, dir);
|
||||
tglLightf(glLight, TGL_SPOT_CUTOFF, (_cutoff * 180.0f) / M_PI);
|
||||
// Exponent doesn't get set in Syberia 2
|
||||
if (g_engine->gameType() == TetraedgeEngine::kSyberia)
|
||||
tglLightf(glLight, TGL_SPOT_EXPONENT, _exponent);
|
||||
} else {
|
||||
tglLightf(glLight, TGL_SPOT_CUTOFF, 180.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLightTinyGL::updateGlobal() {
|
||||
const TeColor globalAmbient(_globalAmbientColor);
|
||||
const float col[4] = {globalAmbient.r() / 255.0f,
|
||||
globalAmbient.g() / 255.0f, globalAmbient.b() / 255.0f, 1.0f};
|
||||
tglLightModelfv(TGL_LIGHT_MODEL_AMBIENT, col);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
54
engines/tetraedge/te/te_light_tinygl.h
Normal file
54
engines/tetraedge/te/te_light_tinygl.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LIGHT_TINYGL_H
|
||||
#define TETRAEDGE_TE_TE_LIGHT_TINYGL_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
|
||||
#include "tetraedge/te/te_light.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLightTinyGL : public TeLight {
|
||||
public:
|
||||
TeLightTinyGL();
|
||||
|
||||
void disable(uint lightno) override;
|
||||
void enable(uint lightno) override;
|
||||
|
||||
void draw(TeCamera &camera) override;
|
||||
|
||||
void update(uint lightno) override;
|
||||
static void updateGlobal();
|
||||
|
||||
static void disableAll();
|
||||
static void enableAll();
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_TINYGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LIGHT_TINYGL_H
|
||||
29
engines/tetraedge/te/te_list_layout.cpp
Normal file
29
engines/tetraedge/te/te_list_layout.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 "tetraedge/te/te_list_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeListLayout::TeListLayout() {
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
50
engines/tetraedge/te/te_list_layout.h
Normal file
50
engines/tetraedge/te/te_list_layout.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LIST_LAYOUT_H
|
||||
#define TETRAEDGE_TE_TE_LIST_LAYOUT_H
|
||||
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeListLayout : public TeLayout {
|
||||
public:
|
||||
TeListLayout();
|
||||
|
||||
void setMinimumMargin(const TeVector3f32 &val) { _minimumMargin = val; }
|
||||
void setMaximumMargin(const TeVector3f32 &val) { _maximumMargin = val; }
|
||||
void setDirection(const TeVector3f32 &val) { _direction = val; }
|
||||
|
||||
const TeVector3f32 &minimumMargin() { return _minimumMargin; }
|
||||
const TeVector3f32 &maximumMargin() { return _maximumMargin; }
|
||||
const TeVector3f32 &direction() { return _direction; }
|
||||
|
||||
private:
|
||||
TeVector3f32 _minimumMargin;
|
||||
TeVector3f32 _maximumMargin;
|
||||
TeVector3f32 _direction;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LIST_LAYOUT_H
|
||||
252
engines/tetraedge/te/te_lua_context.cpp
Normal file
252
engines/tetraedge/te/te_lua_context.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/* 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/debug.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/lua/lua.h"
|
||||
#include "common/lua/lualib.h"
|
||||
#include "common/lua/lauxlib.h"
|
||||
|
||||
#include "tetraedge/te/te_lua_context.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
//#define TETRAEDGE_LUA_DEBUG 1
|
||||
|
||||
//static lua_State *globalState = nullptr;
|
||||
|
||||
static int luaPanicFunction(lua_State *state) {
|
||||
const char *msg = lua_tolstring(state, -1, nullptr);
|
||||
warning("Lua: %s", msg);
|
||||
lua_settop(state, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
static void luaDebugHook(lua_State *L, lua_Debug *ar) {
|
||||
if (!lua_getinfo(L, "Sn", ar))
|
||||
return;
|
||||
debug("LUA: %s %d", ar->source, ar->currentline);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TeLuaContext::TeLuaContext() : _luaState(nullptr) {
|
||||
_luaState = lua_open();
|
||||
luaL_openlibs(_luaState);
|
||||
lua_atpanic(_luaState, luaPanicFunction);
|
||||
}
|
||||
|
||||
TeLuaContext::~TeLuaContext() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void TeLuaContext::addBindings(void(*fn)(lua_State *)) {
|
||||
fn(_luaState);
|
||||
}
|
||||
|
||||
void TeLuaContext::create() {
|
||||
_luaState = lua_open();
|
||||
luaL_openlibs(_luaState);
|
||||
lua_atpanic(_luaState, luaPanicFunction);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
lua_sethook(_luaState, luaDebugHook, LUA_MASKCALL | LUA_MASKLINE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TeLuaContext::destroy() {
|
||||
if (_luaState)
|
||||
lua_close(_luaState);
|
||||
_luaState = nullptr;
|
||||
}
|
||||
|
||||
TeVariant TeLuaContext::global(const Common::String &name) {
|
||||
lua_getglobal(_luaState, name.c_str());
|
||||
TeVariant retval;
|
||||
int type = lua_type(_luaState, -1);
|
||||
if (type == LUA_TBOOLEAN) {
|
||||
int result = lua_toboolean(_luaState, -1);
|
||||
lua_settop(_luaState, -2);
|
||||
return TeVariant(result > 0);
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
double result = lua_tonumber(_luaState, -1);
|
||||
lua_settop(_luaState, -2);
|
||||
return TeVariant(result);
|
||||
} else if (type == LUA_TSTRING) {
|
||||
const char *str = lua_tolstring(_luaState, -1, nullptr);
|
||||
lua_settop(_luaState, -2);
|
||||
return TeVariant(str);
|
||||
}
|
||||
if (type != LUA_TNIL)
|
||||
warning("TeLuaContext::global: Unexpected type %d for global %s", type, name.c_str());
|
||||
else
|
||||
debug("TeLuaContext::global: Request for nil global %s", name.c_str());
|
||||
return TeVariant();
|
||||
}
|
||||
|
||||
void TeLuaContext::setGlobal(const Common::String &name, int val) {
|
||||
lua_pushinteger(_luaState, val);
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
}
|
||||
|
||||
void TeLuaContext::setGlobal(const Common::String &name, bool val) {
|
||||
lua_pushboolean(_luaState, val);
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
}
|
||||
|
||||
void TeLuaContext::setGlobal(const Common::String &name, const Common::String &val) {
|
||||
lua_pushstring(_luaState, val.c_str());
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
}
|
||||
|
||||
void TeLuaContext::removeGlobal(const Common::String &name) {
|
||||
lua_pushnil(_luaState);
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
}
|
||||
|
||||
void TeLuaContext::registerCFunction(const Common::String &name, int(*fn)(lua_State *)) {
|
||||
lua_pushcclosure(_luaState, fn, 0);
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
}
|
||||
|
||||
void TeLuaContext::setInRegistry(const Common::String &name, TeLuaGUI *gui) {
|
||||
lua_pushstring(_luaState, name.c_str());
|
||||
lua_pushlightuserdata(_luaState, gui);
|
||||
lua_settable(_luaState, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
// Types for save file. Aligned with the Lua types at type of
|
||||
// writing, but don't save them just in case they could change.
|
||||
enum TeLuaSaveVarType {
|
||||
None = 0,
|
||||
Boolean = 1,
|
||||
Number = 3,
|
||||
String = 4
|
||||
};
|
||||
|
||||
//#define TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
|
||||
Common::Error TeLuaContext::syncState(Common::Serializer &s) {
|
||||
// Save/Load globals. The format of saving is:
|
||||
// [type][name][val] [type][name][val]...
|
||||
// Vals can be string, number (uint32), or boolean (byte)
|
||||
// The type of "None" (0) is the end of the list (and has no name/val).
|
||||
if (s.isSaving()) {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: --- Saving globals: ---");
|
||||
#endif
|
||||
lua_pushvalue(_luaState, LUA_GLOBALSINDEX);
|
||||
lua_pushnil(_luaState);
|
||||
int nextresult = lua_next(_luaState, -2);
|
||||
while (true) {
|
||||
if (nextresult == 0) {
|
||||
TeLuaSaveVarType stype = None;
|
||||
s.syncAsUint32LE(stype);
|
||||
lua_settop(_luaState, -2);
|
||||
break;
|
||||
}
|
||||
uint vtype = lua_type(_luaState, -1);
|
||||
Common::String name = lua_tolstring(_luaState, -2, nullptr);
|
||||
if (vtype == LUA_TBOOLEAN) {
|
||||
TeLuaSaveVarType stype = Boolean;
|
||||
s.syncAsUint32LE(stype);
|
||||
s.syncString(name);
|
||||
bool val = lua_toboolean(_luaState, -1);
|
||||
s.syncAsByte(val);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: bool %s = %s", name.c_str(), val ? "true" : "false");
|
||||
#endif
|
||||
} else if (vtype == LUA_TNUMBER) {
|
||||
TeLuaSaveVarType stype = Number;
|
||||
s.syncAsUint32LE(stype);
|
||||
s.syncString(name);
|
||||
double val = lua_tonumber(_luaState, -1);
|
||||
s.syncAsDoubleLE(val);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: num %s = %f", name.c_str(), val);
|
||||
#endif
|
||||
} else if (vtype == LUA_TSTRING) {
|
||||
TeLuaSaveVarType stype = String;
|
||||
s.syncAsUint32LE(stype);
|
||||
s.syncString(name);
|
||||
Common::String val = lua_tostring(_luaState, -1);
|
||||
s.syncString(val);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: str %s = '%s'", name.c_str(), val.c_str());
|
||||
#endif
|
||||
}
|
||||
lua_settop(_luaState, -2);
|
||||
nextresult = lua_next(_luaState, -2);
|
||||
}
|
||||
} else {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: --- Loading globals: --- ");
|
||||
#endif
|
||||
// loading
|
||||
TeLuaSaveVarType vtype = None;
|
||||
s.syncAsUint32LE(vtype);
|
||||
while (vtype != None) {
|
||||
Common::String name;
|
||||
s.syncString(name);
|
||||
switch (vtype) {
|
||||
case Boolean: {
|
||||
byte b = 0;
|
||||
s.syncAsByte(b);
|
||||
lua_pushboolean(_luaState, b);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: bool %s = %s", name.c_str(), b ? "true" : "false");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case Number: {
|
||||
float d = 0;
|
||||
s.syncAsDoubleLE(d);
|
||||
lua_pushnumber(_luaState, d);
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: num %s = %f", name.c_str(), d);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case String: {
|
||||
Common::String str;
|
||||
s.syncString(str);
|
||||
lua_pushstring(_luaState, str.c_str());
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: str %s = '%s'", name.c_str(), str.c_str());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error("Unexpected lua type on load %d", (int)vtype);
|
||||
}
|
||||
lua_setglobal(_luaState, name.c_str());
|
||||
s.syncAsUint32LE(vtype);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG_SAVELOAD
|
||||
debug("TeLuaContext::syncState: -------- end --------");
|
||||
#endif
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
82
engines/tetraedge/te/te_lua_context.h
Normal file
82
engines/tetraedge/te/te_lua_context.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LUA_CONTEXT_H
|
||||
#define TETRAEDGE_TE_TE_LUA_CONTEXT_H
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/str.h"
|
||||
#include "common/serializer.h"
|
||||
|
||||
#include "tetraedge/te/te_variant.h"
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLuaGUI;
|
||||
|
||||
/*
|
||||
* The lua state holder. In the original Te engine this is split into an
|
||||
* interface and Impl class, but it just ends up being a 1-line wrapper in
|
||||
* each function so there's very little point.
|
||||
*/
|
||||
class TeLuaContext {
|
||||
public:
|
||||
TeLuaContext();
|
||||
~TeLuaContext();
|
||||
|
||||
void addBindings(void(*fn)(lua_State *));
|
||||
void create();
|
||||
void destroy();
|
||||
TeVariant global(const Common::String &name);
|
||||
void global(const Common::String &name, bool &outVal);
|
||||
void global(const Common::String &name, Common::String &outVal);
|
||||
void global(const Common::String &name, int &outVal);
|
||||
void global(const Common::String &name, float &outVal);
|
||||
bool isCreated() {
|
||||
return _luaState != nullptr;
|
||||
}
|
||||
|
||||
//void load(TiXmlNode *node);
|
||||
//void save(TiXmlNode *node);
|
||||
|
||||
lua_State *luaState() { return _luaState; }
|
||||
|
||||
void registerCFunction(const Common::String &name, int(*fn)(lua_State *));
|
||||
|
||||
void removeGlobal(const Common::String &name);
|
||||
|
||||
void setGlobal(const Common::String &name, int val);
|
||||
void setGlobal(const Common::String &name, bool val);
|
||||
void setGlobal(const Common::String &name, const Common::String &val);
|
||||
|
||||
void setInRegistry(const Common::String &name, TeLuaGUI *gui);
|
||||
|
||||
Common::Error syncState(Common::Serializer &s);
|
||||
|
||||
private:
|
||||
lua_State *_luaState;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LUA_CONTEXT_H
|
||||
302
engines/tetraedge/te/te_lua_gui.cpp
Normal file
302
engines/tetraedge/te/te_lua_gui.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/* 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/file.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "tetraedge/te/te_lua_gui.h"
|
||||
#include "tetraedge/te/te_lua_gui_lua_callbacks.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeLuaGUI::TeLuaGUI() : _loaded(false) {
|
||||
}
|
||||
|
||||
TeButtonLayout *TeLuaGUI::buttonLayout(const Common::String &name) {
|
||||
StringMap<TeButtonLayout *>::iterator iter = _buttonLayouts.find(name);
|
||||
if (iter != _buttonLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeCheckboxLayout *TeLuaGUI::checkboxLayout(const Common::String &name) {
|
||||
StringMap<TeCheckboxLayout *>::iterator iter = _checkboxLayouts.find(name);
|
||||
if (iter != _checkboxLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeClipLayout *TeLuaGUI::clipLayout(const Common::String &name) {
|
||||
StringMap<TeClipLayout *>::iterator iter = _clipLayouts.find(name);
|
||||
if (iter != _clipLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeCurveAnim2<Te3DObject2, TeColor> *TeLuaGUI::colorLinearAnimation(const Common::String &name) {
|
||||
StringMap<TeCurveAnim2<Te3DObject2, TeColor> *>::iterator iter = _colorLinearAnimations.find(name);
|
||||
if (iter != _colorLinearAnimations.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeExtendedTextLayout *TeLuaGUI::extendedTextLayout(const Common::String &name) {
|
||||
StringMap<TeExtendedTextLayout *>::iterator iter = _extendedTextLayouts.find(name);
|
||||
if (iter != _extendedTextLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeLayout *TeLuaGUI::layout(const Common::String &name) {
|
||||
StringMap<TeLayout *>::iterator iter = _layouts.find(name);
|
||||
if (iter != _layouts.end())
|
||||
return iter->_value;
|
||||
|
||||
TeLayout *layout;
|
||||
layout = buttonLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = spriteLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = dynamic_cast<TeLayout *>(textLayout(name));
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = checkboxLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = listLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = scrollingLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = clipLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
layout = extendedTextLayout(name);
|
||||
if (layout)
|
||||
return layout;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *TeLuaGUI::layoutAnchorLinearAnimation(const Common::String &name) {
|
||||
return _layoutAnchorLinearAnimations.getVal(name);
|
||||
}
|
||||
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *TeLuaGUI::layoutPositionLinearAnimation(const Common::String &name) {
|
||||
return _layoutPositionLinearAnimations.getVal(name);
|
||||
}
|
||||
|
||||
TeListLayout *TeLuaGUI::listLayout(const Common::String &name) {
|
||||
StringMap<TeListLayout *>::iterator iter = _listLayouts.find(name);
|
||||
if (iter != _listLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeCurveAnim2<TeI3DObject2, TeQuaternion> *TeLuaGUI::rotationLinearAnimation(const Common::String &name) {
|
||||
error("TODO: Implement TeLuaGUI::rotationLinearAnimation.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeScrollingLayout *TeLuaGUI::scrollingLayout(const Common::String &name) {
|
||||
StringMap<TeScrollingLayout *>::iterator iter = _scrollingLayouts.find(name);
|
||||
if (iter != _scrollingLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeSpriteLayout *TeLuaGUI::spriteLayout(const Common::String &name) {
|
||||
StringMap<TeSpriteLayout *>::iterator iter = _spriteLayouts.find(name);
|
||||
if (iter != _spriteLayouts.end())
|
||||
return iter->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeITextLayout *TeLuaGUI::textLayout(const Common::String &name) {
|
||||
StringMap<TeTextLayout *>::iterator iter = _textLayouts.find(name);
|
||||
if (iter != _textLayouts.end())
|
||||
return iter->_value;
|
||||
StringMap<TeExtendedTextLayout *>::iterator iter2 = _extendedTextLayouts.find(name);
|
||||
if (iter2 != _extendedTextLayouts.end())
|
||||
return iter2->_value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TeButtonLayout *TeLuaGUI::buttonLayoutChecked(const Common::String &name) {
|
||||
TeButtonLayout *l = buttonLayout(name);
|
||||
if (!l) {
|
||||
error("No button '%s' in gui data '%s'", name.c_str(),
|
||||
_scriptPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
TeLayout *TeLuaGUI::layoutChecked(const Common::String &name) {
|
||||
TeLayout *l = layout(name);
|
||||
if (!l) {
|
||||
error("No layout '%s' in gui data '%s'", name.c_str(),
|
||||
_scriptPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
TeSpriteLayout *TeLuaGUI::spriteLayoutChecked(const Common::String &name) {
|
||||
TeSpriteLayout *l = spriteLayout(name);
|
||||
if (!l) {
|
||||
error("No sprite layout '%s' in gui data '%s'", name.c_str(),
|
||||
_scriptPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
bool TeLuaGUI::load(const Common::Path &subPath) {
|
||||
TeCore *core = g_engine->getCore();
|
||||
return load(core->findFile(subPath));
|
||||
}
|
||||
|
||||
bool TeLuaGUI::load(const TetraedgeFSNode &node) {
|
||||
unload();
|
||||
_scriptPath = node.getPath();
|
||||
// Not the same as original, we abstract the search logic a bit.
|
||||
_luaContext.setGlobal("Pixel", 0);
|
||||
_luaContext.setGlobal("Percent", 1);
|
||||
_luaContext.setGlobal("None", 0);
|
||||
_luaContext.setGlobal("LetterBox", 1);
|
||||
_luaContext.setGlobal("PanScan", 2);
|
||||
_luaContext.setGlobal("MultiLine", 0);
|
||||
_luaContext.setGlobal("SingleLine", 1);
|
||||
_luaContext.setGlobal("Fixed", 0);
|
||||
_luaContext.setGlobal("Proportional", 1);
|
||||
_luaContext.registerCFunction("TeLayout", layoutBindings);
|
||||
_luaContext.registerCFunction("TeListLayout", listLayoutBindings);
|
||||
_luaContext.registerCFunction("TeSpriteLayout", spriteLayoutBindings);
|
||||
_luaContext.registerCFunction("TeButtonLayout", buttonLayoutBindings);
|
||||
_luaContext.registerCFunction("TeCheckboxLayout", checkboxLayoutBindings);
|
||||
_luaContext.registerCFunction("TeLayoutPositionLinearAnimation", layoutPositionLinearAnimationBindings);
|
||||
_luaContext.registerCFunction("TeLayoutAnchorLinearAnimation", layoutAnchorLinearAnimationBindings);
|
||||
_luaContext.registerCFunction("TeTextLayout", textLayoutBindings);
|
||||
_luaContext.registerCFunction("TeClipLayout", clipLayoutBindings);
|
||||
_luaContext.registerCFunction("TeColorLinearAnimation", colorLinearAnimationBindings);
|
||||
_luaContext.registerCFunction("TeRotationLinearAnimation", rotationLinearAnimationBindings);
|
||||
_luaContext.registerCFunction("TeScrollingLayout", scrollingLayoutBindings);
|
||||
_luaContext.registerCFunction("TeExtendedTextLayout", extendedTextLayoutBindings);
|
||||
// TODO: We replaced the video layout from Amerzone with a sprite layout. Probably
|
||||
// works ok?
|
||||
_luaContext.registerCFunction("TeVideoLayout", spriteLayoutBindings);
|
||||
_luaContext.setInRegistry("__TeLuaGUIThis", this);
|
||||
_luaScript.attachToContext(&_luaContext);
|
||||
_luaScript.load(node);
|
||||
_luaScript.execute();
|
||||
_luaScript.unload();
|
||||
_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeLuaGUI::unload() {
|
||||
for (auto &iter : _layouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_layouts.clear();
|
||||
|
||||
for (auto &iter : _buttonLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_buttonLayouts.clear();
|
||||
|
||||
for (auto &iter : _checkboxLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_checkboxLayouts.clear();
|
||||
|
||||
for (auto &iter : _listLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_listLayouts.clear();
|
||||
|
||||
for (auto &iter : _spriteLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_spriteLayouts.clear();
|
||||
|
||||
for (auto &iter : _textLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_textLayouts.clear();
|
||||
|
||||
for (auto &iter : _scrollingLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_scrollingLayouts.clear();
|
||||
|
||||
for (auto &iter : _clipLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_clipLayouts.clear();
|
||||
|
||||
for (auto &iter : _extendedTextLayouts) {
|
||||
iter._value->setVisible(false);
|
||||
iter._value->deleteLater();
|
||||
}
|
||||
_extendedTextLayouts.clear();
|
||||
|
||||
for (auto &iter : _layoutAnchorLinearAnimations) {
|
||||
iter._value->stop();
|
||||
delete iter._value;
|
||||
}
|
||||
_layoutAnchorLinearAnimations.clear();
|
||||
|
||||
for (auto &iter : _layoutPositionLinearAnimations) {
|
||||
iter._value->stop();
|
||||
delete iter._value;
|
||||
}
|
||||
_layoutPositionLinearAnimations.clear();
|
||||
|
||||
for (auto &iter : _colorLinearAnimations) {
|
||||
iter._value->stop();
|
||||
delete iter._value;
|
||||
}
|
||||
_colorLinearAnimations.clear();
|
||||
_loaded = false;
|
||||
}
|
||||
|
||||
TeVariant TeLuaGUI::value(const Common::String &globalName) {
|
||||
return _luaContext.global(globalName);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
129
engines/tetraedge/te/te_lua_gui.h
Normal file
129
engines/tetraedge/te/te_lua_gui.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LUA_GUI_H
|
||||
#define TETRAEDGE_TE_TE_LUA_GUI_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "tetraedge/te/te_button_layout.h"
|
||||
#include "tetraedge/te/te_checkbox_layout.h"
|
||||
#include "tetraedge/te/te_clip_layout.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_curve_anim2.h"
|
||||
#include "tetraedge/te/te_extended_text_layout.h"
|
||||
#include "tetraedge/te/te_i_3d_object2.h"
|
||||
#include "tetraedge/te/te_i_layout.h"
|
||||
#include "tetraedge/te/te_i_text_layout.h"
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_list_layout.h"
|
||||
#include "tetraedge/te/te_lua_context.h"
|
||||
#include "tetraedge/te/te_lua_script.h"
|
||||
#include "tetraedge/te/te_object.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
#include "tetraedge/te/te_scrolling_layout.h"
|
||||
#include "tetraedge/te/te_sprite_layout.h"
|
||||
#include "tetraedge/te/te_text_layout.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_variant.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLuaGUI : public TeObject {
|
||||
public:
|
||||
TeLuaGUI();
|
||||
virtual ~TeLuaGUI() {
|
||||
unload();
|
||||
};
|
||||
|
||||
virtual void enter() {};
|
||||
virtual void leave() {};
|
||||
|
||||
TeLayout *layout(const Common::String &name);
|
||||
TeButtonLayout *buttonLayout(const Common::String &name);
|
||||
TeCheckboxLayout *checkboxLayout(const Common::String &name);
|
||||
TeClipLayout *clipLayout(const Common::String &name);
|
||||
TeCurveAnim2<Te3DObject2, TeColor> *colorLinearAnimation(const Common::String &name);
|
||||
TeExtendedTextLayout *extendedTextLayout(const Common::String &name);
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *layoutAnchorLinearAnimation(const Common::String &name);
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *layoutPositionLinearAnimation(const Common::String &name);
|
||||
TeListLayout *listLayout(const Common::String &name);
|
||||
TeCurveAnim2<TeI3DObject2, TeQuaternion> *rotationLinearAnimation(const Common::String &name);
|
||||
TeScrollingLayout *scrollingLayout(const Common::String &name);
|
||||
TeSpriteLayout *spriteLayout(const Common::String &name);
|
||||
TeITextLayout *textLayout(const Common::String &name);
|
||||
|
||||
// Same as the above functions, but call error() if the result is null.
|
||||
TeLayout *layoutChecked(const Common::String &name);
|
||||
TeButtonLayout *buttonLayoutChecked(const Common::String &name);
|
||||
TeSpriteLayout *spriteLayoutChecked(const Common::String &name);
|
||||
|
||||
bool load(const Common::Path &subPath);
|
||||
bool load(const TetraedgeFSNode &node);
|
||||
void unload();
|
||||
|
||||
TeVariant value(const Common::String &key);
|
||||
|
||||
template <typename T> using StringMap = Common::HashMap<Common::String, T>;
|
||||
|
||||
StringMap<TeLayout *> &layouts() { return _layouts; }
|
||||
StringMap<TeButtonLayout *> &buttonLayouts() { return _buttonLayouts; }
|
||||
StringMap<TeCheckboxLayout *> &checkboxLayouts() { return _checkboxLayouts; }
|
||||
StringMap<TeListLayout *> &listLayouts() { return _listLayouts; }
|
||||
StringMap<TeSpriteLayout *> &spriteLayouts() { return _spriteLayouts; }
|
||||
StringMap<TeTextLayout *> &textLayouts() { return _textLayouts; }
|
||||
StringMap<TeScrollingLayout *> &scrollingLayouts() { return _scrollingLayouts; }
|
||||
StringMap<TeClipLayout *> &clipLayouts() { return _clipLayouts; }
|
||||
StringMap<TeExtendedTextLayout *> &extendedTextLayouts() { return _extendedTextLayouts; }
|
||||
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &layoutAnchorLinearAnimations() { return _layoutAnchorLinearAnimations; }
|
||||
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &layoutPositionLinearAnimations() { return _layoutPositionLinearAnimations; }
|
||||
StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &colorLinearAnimations() { return _colorLinearAnimations; }
|
||||
|
||||
bool loaded() const { return _loaded; }
|
||||
const Common::Path &scriptPath() const { return _scriptPath; }
|
||||
|
||||
protected:
|
||||
bool _loaded;
|
||||
|
||||
private:
|
||||
Common::Path _scriptPath;
|
||||
|
||||
TeLuaContext _luaContext;
|
||||
TeLuaScript _luaScript;
|
||||
|
||||
StringMap<TeLayout *> _layouts;
|
||||
StringMap<TeButtonLayout *> _buttonLayouts;
|
||||
StringMap<TeCheckboxLayout *> _checkboxLayouts;
|
||||
StringMap<TeListLayout *> _listLayouts;
|
||||
StringMap<TeSpriteLayout *> _spriteLayouts;
|
||||
StringMap<TeTextLayout *> _textLayouts;
|
||||
StringMap<TeScrollingLayout *> _scrollingLayouts;
|
||||
StringMap<TeClipLayout *> _clipLayouts;
|
||||
StringMap<TeExtendedTextLayout *> _extendedTextLayouts;
|
||||
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> _layoutAnchorLinearAnimations;
|
||||
StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> _layoutPositionLinearAnimations;
|
||||
StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> _colorLinearAnimations;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LUA_GUI_H
|
||||
964
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
Normal file
964
engines/tetraedge/te/te_lua_gui_lua_callbacks.cpp
Normal file
@@ -0,0 +1,964 @@
|
||||
/* 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/lua/lua.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "tetraedge/te/te_lua_gui_lua_callbacks.h"
|
||||
#include "tetraedge/te/te_layout.h"
|
||||
#include "tetraedge/te/te_lua_gui.h"
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_object.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
template <typename T> static T TeLuaTo(lua_State *L, int index) {
|
||||
void *ptr = lua_touserdata(L, index);
|
||||
if (!ptr)
|
||||
return nullptr;
|
||||
T obj = reinterpret_cast<T>(ptr);
|
||||
return dynamic_cast<T>(obj);
|
||||
}
|
||||
|
||||
static Common::String TeLuaToTeString(lua_State *L, int index) {
|
||||
if (!lua_isstring(L, index)) {
|
||||
warning("TeLuaToTeString:: not a string");
|
||||
return "";
|
||||
} else {
|
||||
return lua_tolstring(L, index, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static long TeLuaToS32(lua_State *L, int index) {
|
||||
if (!lua_isnumber(L, index)) {
|
||||
warning("TeLuaToS32:: not a number");
|
||||
return 0;
|
||||
} else {
|
||||
return lua_tointeger(L, index);
|
||||
}
|
||||
}
|
||||
|
||||
static long TeLuaToU32(lua_State *L, int index) {
|
||||
if (!lua_isnumber(L, index)) {
|
||||
warning("TeLuaToU32:: not a number");
|
||||
return 0;
|
||||
} else {
|
||||
return lua_tointeger(L, index);
|
||||
}
|
||||
}
|
||||
|
||||
static float TeLuaToF32(lua_State *L, int index) {
|
||||
if (!lua_isnumber(L, index)) {
|
||||
warning("TeLuaToF32:: not a number");
|
||||
return 0.0f;
|
||||
} else {
|
||||
return lua_tonumber(L, index);
|
||||
}
|
||||
}
|
||||
|
||||
static bool TeLuaToBool(lua_State *L, int index) {
|
||||
if (lua_type(L, index) != LUA_TBOOLEAN) {
|
||||
warning("TeLuaToBool:: not a bool");
|
||||
return false;
|
||||
} else {
|
||||
return lua_toboolean(L, index);
|
||||
}
|
||||
}
|
||||
|
||||
static TeColor TeLuaToTeColor(lua_State *L, int index) {
|
||||
TeColor retval(255, 255, 255, 255);
|
||||
if (lua_type(L, index) != LUA_TTABLE) {
|
||||
warning("TeLuaToTeColor:: not a table");
|
||||
return retval;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, 1);
|
||||
index--;
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.r() = TeLuaToU32(L, -1);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_gettable(L, index);
|
||||
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.g() = TeLuaToU32(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
lua_pushinteger(L, 3);
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.b() = TeLuaToU32(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
lua_pushinteger(L, 4);
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.a() = TeLuaToU32(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static TeVector3f32 TeLuaToTeVector3f32(lua_State *L, int index, TeVector3f32 defaultVal) {
|
||||
TeVector3f32 retval = defaultVal;
|
||||
if (lua_type(L, index) != LUA_TTABLE) {
|
||||
warning("TeLuaToTeVector3f32:: not a table");
|
||||
} else {
|
||||
lua_pushinteger(L, 1);
|
||||
index--;
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.x() = TeLuaToF32(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.y() = TeLuaToF32(L, -1);
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
lua_pushinteger(L, 3);
|
||||
lua_gettable(L, index);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
retval.z() = TeLuaToF32(L, -1);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static Common::Array<float> TeLuaToFloatArray(lua_State *L, int index) {
|
||||
Common::Array<float> result;
|
||||
int type = lua_type(L, index);
|
||||
if (type == LUA_TTABLE) {
|
||||
lua_pushnil(L);
|
||||
while (true) {
|
||||
int next = lua_next(L, index - 1);
|
||||
if (next == 0)
|
||||
break;
|
||||
result.push_back(TeLuaToF32(L, -1));
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
} else {
|
||||
warning("TeLuaToF32TeArray:: the lua value is not a table");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static bool loadCommonLayoutItems(lua_State *L, const char *s, TeLayout *layout) {
|
||||
if (!strcmp(s, "name")) {
|
||||
layout->setName(TeLuaToTeString(L, -1));
|
||||
} else if (!strcmp(s, "sizeType")) {
|
||||
layout->setSizeType(static_cast<TeILayout::CoordinatesType>(TeLuaToS32(L, -1)));
|
||||
} else if (!strcmp(s, "size")) {
|
||||
TeVector3f32 lastSize = layout->userSize();
|
||||
TeVector3f32 size = TeLuaToTeVector3f32(L, -1, lastSize);
|
||||
layout->setSize(size);
|
||||
} else if (!strcmp(s, "ratio")) {
|
||||
layout->setRatio(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "ratioMode")) {
|
||||
layout->setRatioMode(static_cast<TeILayout::RatioMode>(TeLuaToS32(L, -1)));
|
||||
} else if (!strcmp(s, "safeAreaRatio")) {
|
||||
layout->setSafeAreaRatio(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "anchor")) {
|
||||
TeVector3f32 lastAnchor = layout->anchor();
|
||||
TeVector3f32 anchor = TeLuaToTeVector3f32(L, -1, lastAnchor);
|
||||
layout->setAnchor(anchor);
|
||||
} else if (!strcmp(s, "positionType")) {
|
||||
layout->setPositionType(static_cast<TeILayout::CoordinatesType>(TeLuaToS32(L, -1)));
|
||||
} else if (!strcmp(s, "position")) {
|
||||
TeVector3f32 lastPos = layout->userPosition();
|
||||
TeVector3f32 pos = TeLuaToTeVector3f32(L, -1, lastPos);
|
||||
layout->setPosition(pos);
|
||||
} else if (!strcmp(s, "visible")) {
|
||||
layout->setVisible(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "color")) {
|
||||
layout->setColor(TeLuaToTeColor(L, -1));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Fix this widescreen flag
|
||||
static bool _g_bWidescreen = false;
|
||||
|
||||
int layoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("layoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeLayout *layout = new TeLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(obj);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeLayout *> &layouts = gui->layouts();
|
||||
if (!layouts.contains(layout->name())) {
|
||||
layouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int listLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("listLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeListLayout *layout = new TeListLayout();
|
||||
lua_pushnil(L);
|
||||
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "direction")) {
|
||||
const TeVector3f32 lastDirection = layout->direction();
|
||||
const TeVector3f32 direction = TeLuaToTeVector3f32(L, -1, lastDirection);
|
||||
layout->setDirection(direction);
|
||||
} else if (!strcmp(s, "minimumMargin")) {
|
||||
const TeVector3f32 lastMinimumMargin = layout->minimumMargin();
|
||||
const TeVector3f32 minimumMargin = TeLuaToTeVector3f32(L, -1, lastMinimumMargin);
|
||||
layout->setMinimumMargin(minimumMargin);
|
||||
} else if (!strcmp(s, "maximumMargin")) {
|
||||
const TeVector3f32 lastMaximumMargin = layout->maximumMargin();
|
||||
const TeVector3f32 maximumMargin = TeLuaToTeVector3f32(L, -1, lastMaximumMargin);
|
||||
layout->setMaximumMargin(maximumMargin);
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(obj);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeListLayout *> &layouts = gui->listLayouts();
|
||||
if (!layouts.contains(layout->name())) {
|
||||
layouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("listLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int spriteLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("spriteLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
lua_settop(L, -2);
|
||||
TeSpriteLayout *layout = new TeSpriteLayout();
|
||||
lua_pushnil(L);
|
||||
|
||||
bool playNow = layout->_tiledSurfacePtr->_frameAnim._runTimer.running();
|
||||
int startingFrame = 0;
|
||||
int endingFrame = -1;
|
||||
Common::Path imgFullPath;
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, 0);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "image")) {
|
||||
Common::String imgPath = TeLuaToTeString(L, -1);
|
||||
// Slight hack.. fix double-slash that appears in some script files
|
||||
uint32 loc = imgPath.find("//");
|
||||
if (loc != Common::String::npos) {
|
||||
imgPath.replace(loc, 2, "/");
|
||||
}
|
||||
if (imgPath.substr(0, 2) == "./") {
|
||||
imgPath = imgPath.substr(0, 2);
|
||||
// NOTE: This is bad.. the scriptPath is a system-local path so the
|
||||
// separator may not be '/', we can't just make a Path from it like
|
||||
// this. Fortunately it seems this is never actually used? No sprites
|
||||
// use './' in their data.
|
||||
warning("Taking non-portable code path to load image in spriteLayoutBindings");
|
||||
imgFullPath = Common::Path(gui->scriptPath()).getParent().join(imgPath);
|
||||
} else {
|
||||
imgFullPath = imgPath;
|
||||
}
|
||||
} else if (!strcmp(s, "leftCropping")) {
|
||||
layout->_tiledSurfacePtr->setLeftCropping(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "rightCropping")) {
|
||||
layout->_tiledSurfacePtr->setRightCropping(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "topCropping")) {
|
||||
layout->_tiledSurfacePtr->setTopCropping(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "bottomCropping")) {
|
||||
layout->_tiledSurfacePtr->setBottomCropping(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "loopCount")) {
|
||||
layout->_tiledSurfacePtr->_frameAnim.setLoopCount(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "play")) {
|
||||
playNow = TeLuaToBool(L, -1);
|
||||
} else if (!strcmp(s, "reversed")) {
|
||||
layout->_tiledSurfacePtr->_frameAnim.setReversed(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "startingFrame")) {
|
||||
startingFrame = TeLuaToU32(L, -1);
|
||||
} else if (!strcmp(s, "endingFrame")) {
|
||||
endingFrame = TeLuaToU32(L, -1);
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (!imgFullPath.empty())
|
||||
layout->load(imgFullPath);
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(object);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
|
||||
// WORKAROUND: ValStreet scene 11070 has a misnamed animation in the script.
|
||||
// All references to it in script refer to it with the "ab".
|
||||
// This scene is broken in the original game too.
|
||||
if (layout->name() == "11070-1")
|
||||
layout->setName("ab11070-1");
|
||||
|
||||
TeICodec *codec = layout->_tiledSurfacePtr->codec();
|
||||
if (codec) {
|
||||
float frameRate = codec->frameRate();
|
||||
layout->_tiledSurfacePtr->_frameAnim.setStartTime((startingFrame / frameRate) * 1000.0 * 1000.0);
|
||||
if (endingFrame == -1) {
|
||||
layout->_tiledSurfacePtr->_frameAnim.setEndTime(FLT_MAX);
|
||||
} else {
|
||||
layout->_tiledSurfacePtr->_frameAnim.setEndTime((endingFrame / frameRate) * 1000.0 * 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Slight divergence from original.. start playing only after setting
|
||||
// start/end values above as it makes more sense that way.
|
||||
if (playNow) {
|
||||
layout->play();
|
||||
} else {
|
||||
layout->stop();
|
||||
}
|
||||
|
||||
if (!gui->spriteLayout(layout->name())) {
|
||||
TeLuaGUI::StringMap<TeSpriteLayout *> &spriteLayouts = gui->spriteLayouts();
|
||||
spriteLayouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int buttonLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("buttonLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeButtonLayout *layout = new TeButtonLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "upLayout")) {
|
||||
layout->setUpLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "downLayout")) {
|
||||
layout->setDownLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "disabledLayout")) {
|
||||
layout->setDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "rollOverLayout")) {
|
||||
layout->setRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "hitZone")) {
|
||||
layout->setHitZone(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "enable")) {
|
||||
layout->setEnable(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "clickPassThrough")) {
|
||||
layout->setClickPassThrough(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "validationSound")) {
|
||||
layout->setValidationSound(Common::Path(TeLuaToTeString(L, -1)));
|
||||
} else if (!strcmp(s, "validationSoundVolume")) {
|
||||
layout->setValidationSoundVolume(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(object);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = gui->buttonLayouts();
|
||||
if (!blayouts.contains(layout->name())) {
|
||||
blayouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("buttonLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int checkboxLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("checkboxLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeCheckboxLayout *layout = new TeCheckboxLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "activeLayout")) {
|
||||
layout->setActiveLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "unactiveLayout")) {
|
||||
layout->setUnactiveLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "activeDisabledLayout")) {
|
||||
layout->setActiveDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "unactiveDisabledLayout")) {
|
||||
layout->setUnactiveDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "activeRollOverLayout")) {
|
||||
layout->setActiveRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "unactiveRollOverLayout")) {
|
||||
layout->setUnactiveRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "hitZone")) {
|
||||
layout->setHitZone(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "clickPassThrough")) {
|
||||
layout->setClickPassThrough(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "activationSound")) {
|
||||
layout->setActivationSound(TeLuaToTeString(L, -1));
|
||||
} else if (!strcmp(s, "unactivationSound")) {
|
||||
layout->setUnactivationSound(TeLuaToTeString(L, -1));
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.checkboxLayoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(object);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeCheckboxLayout *> &blayouts = gui->checkboxLayouts();
|
||||
if (!blayouts.contains(layout->name())) {
|
||||
blayouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("checkboxLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int layoutPositionLinearAnimationBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("layoutPositionLinearAnimationBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
|
||||
lua_pushnil(L);
|
||||
Common::String name;
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (!strcmp(s, "name")) {
|
||||
name = TeLuaToTeString(L, -1);
|
||||
} else if (!strcmp(s, "duration")) {
|
||||
anim->_duration = TeLuaToF32(L, -1);
|
||||
} else if (!strcmp(s, "startValue")) {
|
||||
static const TeVector3f32 defaultStart(0.0f, 0.0f, 0.0f);
|
||||
anim->_startVal = TeLuaToTeVector3f32(L, -1, defaultStart);
|
||||
} else if (!strcmp(s, "endValue")) {
|
||||
static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
|
||||
anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
|
||||
} else if (!strcmp(s, "layout") || !strcmp(s, "pausable")) {
|
||||
// skip.
|
||||
// TODO: What should we do with "pausable" attribute?
|
||||
} else if (!strcmp(s, "curve")) {
|
||||
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
||||
anim->setCurve(curve);
|
||||
} else {
|
||||
error("[TeLuaGUI.layoutPositionLinearAnimationBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
name = Common::String::format("%p", (void *)anim);
|
||||
}
|
||||
anim->_callbackMethod = &TeLayout::setPosition;
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutPositionLinearAnimations();
|
||||
if (!anims.contains(name)) {
|
||||
anims.setVal(name, anim);
|
||||
lua_pushlightuserdata(L, (void *)(anim));
|
||||
return true;
|
||||
} else {
|
||||
warning("layoutPositionLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
||||
delete anim;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int layoutAnchorLinearAnimationBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("layoutAnchorLinearAnimationBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
|
||||
lua_pushnil(L);
|
||||
Common::String name;
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (!strcmp(s, "name")) {
|
||||
name = TeLuaToTeString(L, -1);
|
||||
} else if (!strcmp(s, "duration")) {
|
||||
anim->_duration = TeLuaToF32(L, -1);
|
||||
} else if (!strcmp(s, "startValue")) {
|
||||
static const TeVector3f32 defaultStart(0.0f, 0.0f, 0.0f);
|
||||
anim->_startVal = TeLuaToTeVector3f32(L, -1, defaultStart);
|
||||
} else if (!strcmp(s, "endValue")) {
|
||||
static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
|
||||
anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
|
||||
} else if (!strcmp(s, "layout")) {
|
||||
// skip.
|
||||
} else if (!strcmp(s, "curve")) {
|
||||
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
||||
anim->setCurve(curve);
|
||||
} else {
|
||||
error("[TeLuaGUI.layoutAnchorLinearAnimationBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
name = Common::String::format("%p", (void *)anim);
|
||||
}
|
||||
anim->_callbackMethod = &TeLayout::setAnchor;
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutAnchorLinearAnimations();
|
||||
if (!anims.contains(name)) {
|
||||
anims.setVal(name, anim);
|
||||
lua_pushlightuserdata(L, (void *)(anim));
|
||||
return true;
|
||||
} else {
|
||||
warning("layoutAnchorLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
||||
delete anim;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int textLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("textLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeTextLayout *layout = new TeTextLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "text")) {
|
||||
layout->setText(TeLuaToTeString(L, -1));
|
||||
} else if (!strcmp(s, "interLine") || !strcmp(s, "interline")) {
|
||||
layout->setInterLine(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "wrapMode")) {
|
||||
layout->setWrapMode(static_cast<TeTextBase2::WrapMode>(TeLuaToS32(L, -1)));
|
||||
} else if (!strcmp(s, "textSizeType")) {
|
||||
layout->setTextSizeType(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "textSizeProportionalToWidth")) {
|
||||
layout->setTextSizeProportionalToWidth(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(obj);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeTextLayout *> &layouts = gui->textLayouts();
|
||||
if (!layouts.contains(layout->name())) {
|
||||
layouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("textLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int clipLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("clipLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
error("TODO: Implement clipLayoutBindings.");
|
||||
}
|
||||
|
||||
int colorLinearAnimationBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("colorLinearAnimationBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeCurveAnim2<Te3DObject2, TeColor> *anim = new TeCurveAnim2<Te3DObject2, TeColor>();
|
||||
lua_pushnil(L);
|
||||
Common::String name;
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (!strcmp(s, "name")) {
|
||||
name = TeLuaToTeString(L, -1);
|
||||
} else if (!strcmp(s, "duration")) {
|
||||
anim->_duration = TeLuaToF32(L, -1);
|
||||
} else if (!strcmp(s, "startValue")) {
|
||||
anim->_startVal = TeLuaToTeColor(L, -1);
|
||||
} else if (!strcmp(s, "endValue")) {
|
||||
anim->_endVal = TeLuaToTeColor(L, -1);
|
||||
} else if (!strcmp(s, "layout")) {
|
||||
} else if (!strcmp(s, "curve")) {
|
||||
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
||||
anim->setCurve(curve);
|
||||
} else {
|
||||
error("[TeLuaGUI.colorLinearAnimationBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
name = Common::String::format("%p", (void *)anim);
|
||||
}
|
||||
anim->_callbackMethod = &Te3DObject2::setColor;
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &anims = gui->colorLinearAnimations();
|
||||
if (!anims.contains(name)) {
|
||||
anims.setVal(name, anim);
|
||||
lua_pushlightuserdata(L, (void *)(anim));
|
||||
return true;
|
||||
} else {
|
||||
warning("colorLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
||||
delete anim;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int rotationLinearAnimationBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("rotationLinearAnimationBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
error("TODO: Implement rotationLinearAnimationBindings.");
|
||||
}
|
||||
|
||||
int scrollingLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("scrollingLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeScrollingLayout *layout = new TeScrollingLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "inertiaAnimationDuration")) {
|
||||
layout->setInertiaAnimationDuration(TeLuaToU32(L, -1));
|
||||
} else if (!strcmp(s, "inertiaAnimationCurve")) {
|
||||
layout->setInertiaAnimationCurve(TeLuaToFloatArray(L, -1));
|
||||
} else if (!strcmp(s, "direction")) {
|
||||
TeVector3f32 newdir = TeLuaToTeVector3f32(L, -1, layout->direction());
|
||||
layout->setDirection(newdir);
|
||||
} else if (!strcmp(s, "contentLayout")) {
|
||||
layout->setContentLayout(TeLuaTo<TeLayout*>(L, -1));
|
||||
} else if (!strcmp(s, "enclose")) {
|
||||
layout->setEnclose(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "mouseControl")) {
|
||||
layout->setMouseControl(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollLoop")) {
|
||||
layout->setAutoScrollLoop(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollDelay")) {
|
||||
layout->setAutoScrollDelay(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation1Enabled")) {
|
||||
layout->setAutoScrollAnimation1Enabled(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation1Delay")) {
|
||||
layout->setAutoScrollAnimation1Delay(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation1Speed")) {
|
||||
layout->setAutoScrollAnimation1Speed(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation1Curve")) {
|
||||
layout->setAutoScrollAnimation1Curve(TeLuaToFloatArray(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation2Enabled")) {
|
||||
layout->setAutoScrollAnimation2Enabled(TeLuaToBool(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation2Delay")) {
|
||||
layout->setAutoScrollAnimation2Delay(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation2Speed")) {
|
||||
layout->setAutoScrollAnimation2Speed(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollAnimation2Curve")) {
|
||||
layout->setAutoScrollAnimation2Curve(TeLuaToFloatArray(L, -1));
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.scrollingLayoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(obj);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeScrollingLayout *> &layouts = gui->scrollingLayouts();
|
||||
if (!layouts.contains(layout->name())) {
|
||||
layouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("scrollingLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int extendedTextLayoutBindings(lua_State *L) {
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
warning("extendedTextLayoutBindings:: the lua value is not a table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TeExtendedTextLayout *layout = new TeExtendedTextLayout();
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
int type = lua_type(L, -2);
|
||||
if (type == LUA_TSTRING) {
|
||||
const char *s = lua_tolstring(L, -2, nullptr);
|
||||
if (loadCommonLayoutItems(L, s, layout)) {
|
||||
// do nothing.
|
||||
} else if (!strcmp(s, "text")) {
|
||||
layout->setText(TeLuaToTeString(L, -1));
|
||||
} else if (!strcmp(s, "interLine") || !strcmp(s, "interline")) {
|
||||
layout->setInterLine(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "wrapMode")) {
|
||||
layout->setWrapMode(static_cast<TeTextBase2::WrapMode>(TeLuaToS32(L, -1)));
|
||||
} else if (!strcmp(s, "autoScrollDelay")) {
|
||||
layout->setAutoScrollDelay(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "autoScrollSpeed")) {
|
||||
layout->setAutoScrollSpeed(TeLuaToF32(L, -1));
|
||||
} else if (!strcmp(s, "textSizeType")) {
|
||||
layout->setTextSizeType(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "textSizeProportionalToWidth")) {
|
||||
layout->setTextSizeProportionalToWidth(TeLuaToS32(L, -1));
|
||||
} else if (!strcmp(s, "consoleNoStretch")) {
|
||||
warning("TODO: Handle _g_bWidescreen");
|
||||
if (_g_bWidescreen) {
|
||||
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
||||
}
|
||||
} else {
|
||||
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
|
||||
}
|
||||
} else if (type == LUA_TNUMBER) {
|
||||
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
||||
layout->addChild(obj);
|
||||
}
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
|
||||
if (layout->name().empty()) {
|
||||
layout->setName(Common::String::format("%p", (void *)layout));
|
||||
}
|
||||
lua_pushstring(L, "__TeLuaGUIThis");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
|
||||
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
||||
TeLuaGUI::StringMap<TeExtendedTextLayout *> &layouts = gui->extendedTextLayouts();
|
||||
if (!layouts.contains(layout->name())) {
|
||||
layouts.setVal(layout->name(), layout);
|
||||
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
||||
return true;
|
||||
} else {
|
||||
warning("extendedTextLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
||||
delete layout;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
46
engines/tetraedge/te/te_lua_gui_lua_callbacks.h
Normal file
46
engines/tetraedge/te/te_lua_gui_lua_callbacks.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LUA_GUI_LUA_CALLBACKS_H
|
||||
#define TETRAEDGE_TE_TE_LUA_GUI_LUA_CALLBACKS_H
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
int layoutBindings(lua_State *state);
|
||||
int listLayoutBindings(lua_State *state);
|
||||
int spriteLayoutBindings(lua_State *state);
|
||||
int buttonLayoutBindings(lua_State *state);
|
||||
int checkboxLayoutBindings(lua_State *state);
|
||||
int layoutPositionLinearAnimationBindings(lua_State *state);
|
||||
int layoutAnchorLinearAnimationBindings(lua_State *state);
|
||||
int textLayoutBindings(lua_State *state);
|
||||
int clipLayoutBindings(lua_State *state);
|
||||
int colorLinearAnimationBindings(lua_State *state);
|
||||
int rotationLinearAnimationBindings(lua_State *state);
|
||||
int scrollingLayoutBindings(lua_State *state);
|
||||
int extendedTextLayoutBindings(lua_State *state);
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LUA_GUI_LUA_CALLBACKS_H
|
||||
95
engines/tetraedge/te/te_lua_script.cpp
Normal file
95
engines/tetraedge/te/te_lua_script.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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/debug.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/file.h"
|
||||
#include "tetraedge/te/te_lua_script.h"
|
||||
#include "tetraedge/te/te_lua_thread.h"
|
||||
#include "tetraedge/te/te_lua_context.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeLuaScript::TeLuaScript() : _started(false), _luaContext(nullptr) {
|
||||
}
|
||||
|
||||
void TeLuaScript::attachToContext(TeLuaContext *context) {
|
||||
_luaContext = context;
|
||||
}
|
||||
|
||||
void TeLuaScript::execute() {
|
||||
if (_luaContext) {
|
||||
//debug("TeLuaScript::execute %s", _scriptNode.toString().c_str());
|
||||
lua_State *state = _luaContext->luaState();
|
||||
if (state) {
|
||||
TeLuaThread *thread = TeLuaThread::create(_luaContext);
|
||||
thread->executeFile(_scriptNode);
|
||||
thread->release();
|
||||
_started = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaScript::execute(const Common::String &fname) {
|
||||
if (_luaContext) {
|
||||
//debug("TeLuaScript::execute %s %s", _scriptNode.toString().c_str(), fname.c_str());
|
||||
TeLuaThread *thread = TeLuaThread::create(_luaContext);
|
||||
thread->execute(fname);
|
||||
thread->release();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1) {
|
||||
if (_luaContext) {
|
||||
//debug("TeLuaScript::execute %s %s(%s)", _scriptNode.toString().c_str(), fname.c_str(), p1.toString().c_str());
|
||||
TeLuaThread *thread = TeLuaThread::create(_luaContext);
|
||||
thread->execute(fname, p1);
|
||||
thread->release();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2) {
|
||||
if (_luaContext) {
|
||||
TeLuaThread *thread = TeLuaThread::create(_luaContext);
|
||||
thread->execute(fname, p1, p2);
|
||||
thread->release();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaScript::execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3) {
|
||||
if (_luaContext) {
|
||||
TeLuaThread *thread = TeLuaThread::create(_luaContext);
|
||||
thread->execute(fname, p1, p2, p3);
|
||||
thread->release();
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaScript::load(const TetraedgeFSNode &node) {
|
||||
_started = false;
|
||||
_scriptNode = node;
|
||||
}
|
||||
|
||||
void TeLuaScript::unload() {
|
||||
_scriptNode = TetraedgeFSNode();
|
||||
_started = false;
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
58
engines/tetraedge/te/te_lua_script.h
Normal file
58
engines/tetraedge/te/te_lua_script.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LUA_SCRIPT_H
|
||||
#define TETRAEDGE_TE_TE_LUA_SCRIPT_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/path.h"
|
||||
#include "tetraedge/te/te_variant.h"
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLuaContext;
|
||||
|
||||
class TeLuaScript {
|
||||
public:
|
||||
TeLuaScript();
|
||||
|
||||
void attachToContext(TeLuaContext *context);
|
||||
|
||||
void execute();
|
||||
void execute(const Common::String &fname);
|
||||
void execute(const Common::String &fname, const TeVariant &p1);
|
||||
void execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2);
|
||||
void execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
|
||||
|
||||
void load(const TetraedgeFSNode &node);
|
||||
void unload();
|
||||
|
||||
private:
|
||||
TeLuaContext *_luaContext;
|
||||
|
||||
TetraedgeFSNode _scriptNode;
|
||||
bool _started;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LUA_SCRIPT_H
|
||||
406
engines/tetraedge/te/te_lua_thread.cpp
Normal file
406
engines/tetraedge/te/te_lua_thread.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_lua_thread.h"
|
||||
#include "tetraedge/te/te_lua_context.h"
|
||||
#include "tetraedge/te/te_variant.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/str.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/lua/lua.h"
|
||||
#include "common/lua/lauxlib.h"
|
||||
#include "common/lua/lualib.h"
|
||||
|
||||
//#define TETRAEDGE_LUA_DEBUG 1
|
||||
//#define TETRAEDGE_RESTORE_EXPERIMENTAL 1
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
/*static*/
|
||||
Common::Array<TeLuaThread *> *TeLuaThread::_threadList = nullptr;
|
||||
|
||||
TeLuaThread::TeLuaThread(TeLuaContext *context) : _resumeCount(0), _lastResumeResult(0), _released(false) {
|
||||
_luaThread = lua_newthread(context->luaState());
|
||||
_bottomRef = luaL_ref(context->luaState(), LUA_REGISTRYINDEX);
|
||||
threadList()->push_back(this);
|
||||
}
|
||||
|
||||
TeLuaThread::~TeLuaThread() {
|
||||
luaL_unref(_luaThread, LUA_REGISTRYINDEX, _bottomRef);
|
||||
uint i;
|
||||
Common::Array<TeLuaThread *> *threads = threadList();
|
||||
for (i = 0; i < threads->size(); i++)
|
||||
if ((*threads)[i] == this)
|
||||
break;
|
||||
if (i < threads->size())
|
||||
threads->remove_at(i);
|
||||
}
|
||||
|
||||
/*static*/ TeLuaThread *TeLuaThread::create(TeLuaContext *context) {
|
||||
return new TeLuaThread(context);
|
||||
}
|
||||
|
||||
void TeLuaThread::_resume(int nargs) {
|
||||
_resumeCount++;
|
||||
_lastResumeResult = lua_resume(_luaThread, nargs);
|
||||
if (_lastResumeResult > 1) {
|
||||
const char *msg = lua_tolstring(_luaThread, -1, nullptr);
|
||||
warning("TeLuaThread::_resume: %s", msg);
|
||||
}
|
||||
if (_lastResumeResult != 1 && _released) {
|
||||
//debug("TeLuaThread:: deleting this?");
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::execute(const Common::String &fname) {
|
||||
if (!_luaThread)
|
||||
return;
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
if (fname != "Update" && fname != "UpdateHelp")
|
||||
debug("TeLuaThread::execute: %s()", fname.c_str());
|
||||
#endif
|
||||
|
||||
lua_getglobal(_luaThread, fname.c_str());
|
||||
if (lua_type(_luaThread, -1) == LUA_TFUNCTION) {
|
||||
_resume(0);
|
||||
} else {
|
||||
if (!fname.contains("Update"))
|
||||
debug("[TeLuaThread::Execute0] Function: \"%s\" does not exist", fname.c_str());
|
||||
lua_settop(_luaThread, -2);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1) {
|
||||
if (!_luaThread)
|
||||
return;
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::execute: %s(%s)", fname.c_str(), p1.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
lua_getglobal(_luaThread, fname.c_str());
|
||||
if (lua_type(_luaThread, -1) == LUA_TFUNCTION) {
|
||||
pushValue(p1);
|
||||
_resume(1);
|
||||
} else {
|
||||
// Don't report Update (as original) or some other functions which are not
|
||||
// implemented in both games
|
||||
if (!fname.contains("Update") && !fname.equals("OnCellCharacterAnimationPlayerFinished")
|
||||
&& !fname.equals("OnCharacterAnimationFinished") && !fname.equals("OnCellDialogFinished")
|
||||
&& !fname.equals("OnCellFreeSoundFinished"))
|
||||
debug("[TeLuaThread::Execute1] Function: \"%s\" does not exist", fname.c_str());
|
||||
lua_settop(_luaThread, -2);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2) {
|
||||
if (!_luaThread)
|
||||
return;
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::execute: %s(%s, %s)", fname.c_str(), p1.dumpStr().c_str(),
|
||||
p2.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
lua_getglobal(_luaThread, fname.c_str());
|
||||
if (lua_type(_luaThread, -1) == LUA_TFUNCTION) {
|
||||
pushValue(p1);
|
||||
pushValue(p2);
|
||||
_resume(2);
|
||||
} else {
|
||||
if (!fname.contains("Update"))
|
||||
debug("[TeLuaThread::Execute2] Function: \"%s\" does not exist.", fname.c_str());
|
||||
lua_settop(_luaThread, -2);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::execute(const Common::String &fname, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3) {
|
||||
if (!_luaThread)
|
||||
return;
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::execute: %s(%s, %s, %s)", fname.c_str(), p1.dumpStr().c_str(),
|
||||
p2.dumpStr().c_str(), p3.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
|
||||
lua_getglobal(_luaThread, fname.c_str());
|
||||
if (lua_type(_luaThread, -1) == LUA_TFUNCTION) {
|
||||
pushValue(p1);
|
||||
pushValue(p2);
|
||||
pushValue(p3);
|
||||
_resume(3);
|
||||
} else {
|
||||
if (!fname.contains("Update"))
|
||||
debug("[TeLuaThread::Execute3] Function: \"%s\" does not exist.", fname.c_str());
|
||||
lua_settop(_luaThread, -4);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::applyScriptWorkarounds(char *buf, const Common::String &fileNameIn) {
|
||||
char *fixline;
|
||||
|
||||
Common::String fileName(fileNameIn);
|
||||
|
||||
if (fileName.hasSuffix(".data")) {
|
||||
fileName = fileName.substr(0, fileName.size() - 5) + ".lua";
|
||||
}
|
||||
|
||||
//
|
||||
// WORKAROUND: Some script files have rogue ";" lines in them with nothing
|
||||
// else, and ScummVM common lua version doesn't like them. Clean those up.
|
||||
//
|
||||
fixline = strstr(buf, "\n\t;");
|
||||
if (fixline)
|
||||
fixline[2] = '\t';
|
||||
|
||||
//
|
||||
// Restore Syberia 1 scenes by patching up the scripts
|
||||
//
|
||||
if (g_engine->gameType() == TetraedgeEngine::kSyberia && ConfMan.getBool("restore_scenes")) {
|
||||
if (fileName.contains("Logic11070.lua")) {
|
||||
// Allow Kate to enter scene 11100
|
||||
fixline = strstr(buf, "\"11110\"");
|
||||
if (fixline) // 11110 -> 11100
|
||||
fixline[4] = '0';
|
||||
fixline = strstr(buf, "\"11110\"");
|
||||
if (fixline)
|
||||
fixline[4] = '0';
|
||||
} else if (fileName.contains("Logic11110.lua")) {
|
||||
// Allow Kate to enter scene 11100
|
||||
fixline = strstr(buf, "\"11070\"");
|
||||
if (fixline) // 11070 -> 11100
|
||||
memcpy(fixline + 3, "10 ", 2);
|
||||
fixline = strstr(buf, "\"11070\"");
|
||||
if (fixline)
|
||||
memcpy(fixline + 3, "10 ", 2);
|
||||
#ifdef TETRAEDGE_RESTORE_EXPERIMENTAL
|
||||
// The 11170 scene is not usable yet - it seems
|
||||
// to not have any free move zone data?
|
||||
} else if (fileName.contains("Logic11160.lua")) {
|
||||
fixline = strstr(buf, "\"11180\"");
|
||||
if (fixline) // 11180 -> 11170
|
||||
fixline[4] = '7';
|
||||
fixline = strstr(buf, "\"11180\"");
|
||||
if (fixline)
|
||||
fixline[4] = '7';
|
||||
} else if (fileName.contains("Logic11180.lua")) {
|
||||
fixline = strstr(buf, "\"11160\"");
|
||||
if (fixline) // 11160 -> 11170
|
||||
fixline[4] = '7';
|
||||
fixline = strstr(buf, "\"11160\"");
|
||||
if (fixline)
|
||||
fixline[4] = '7';
|
||||
#endif
|
||||
} else if (fileName.contains("Logic11100.lua")) {
|
||||
fixline = strstr(buf, " , 55 ,70, ");
|
||||
if (fixline) // 70 -> 65 to fix speech marker location
|
||||
memcpy(fixline + 7, "65 ", 2);
|
||||
} else if (fileName.contains("Int11100.lua") || fileName.contains("Int11170.lua")) {
|
||||
fixline = strstr(buf, "ratio = 16/9,");
|
||||
if (fixline) // 16/9 -> 4/3
|
||||
memcpy(fixline + 8, "4/3 ", 4);
|
||||
fixline = strstr(buf, "ratioMode = PanScan,");
|
||||
if (fixline)
|
||||
memcpy(fixline + 9, "=LetterBox", 10);
|
||||
} else if (fileName.contains("For11100.lua") || fileName.contains("For11170.lua")) {
|
||||
fixline = strstr(buf, "size = {1.0");
|
||||
if (fixline) // 1.0 -> 1.5
|
||||
fixline[10] = '5';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// WORKAROUND: Syberia 2 constantly re-seeds the random number generator.
|
||||
// This fails on ScummVM Lua because os.time() returns a large Number and
|
||||
// math.randomseed() clamps the number to an int, so it always seeds on the
|
||||
// same value. It's also kind of pointless, so just patch it out.
|
||||
//
|
||||
static const char RESEED_PATTERN[] = "math.randomseed( os.time() )";
|
||||
fixline = strstr(buf, RESEED_PATTERN);
|
||||
while (fixline != nullptr) {
|
||||
for (int i = 0; i < ARRAYSIZE(RESEED_PATTERN); i++) {
|
||||
fixline[i] = ' ';
|
||||
}
|
||||
fixline = strstr(fixline, RESEED_PATTERN);
|
||||
}
|
||||
|
||||
//
|
||||
// WORKAROUND: Syberia 2 A1_Cabaret/11420/Logic11420.lua has a typo on a
|
||||
// variable name that causes the game to lock up
|
||||
//
|
||||
fixline = strstr(buf, "OBJECT_10050_Inventory_obj_coeurmec_Taketoun ");
|
||||
if (fixline) {
|
||||
// Taketoun -> Taken
|
||||
memcpy(fixline + 40, "n ", 4);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::executeFile(const TetraedgeFSNode &node) {
|
||||
Common::ScopedPtr<Common::SeekableReadStream> scriptFile(node.createReadStream());
|
||||
if (!scriptFile) {
|
||||
warning("TeLuaThread::executeFile: File %s can't be opened", node.getName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::executeFile: %s", node.getName().c_str());
|
||||
#endif
|
||||
|
||||
int64 fileLen = scriptFile->size();
|
||||
char *buf = new char[fileLen + 1];
|
||||
scriptFile->read(buf, fileLen);
|
||||
buf[fileLen] = 0;
|
||||
scriptFile.reset();
|
||||
|
||||
applyScriptWorkarounds(buf, node.getPath().baseName());
|
||||
|
||||
_lastResumeResult = luaL_loadbuffer(_luaThread, buf, fileLen, node.toString().c_str());
|
||||
if (_lastResumeResult) {
|
||||
const char *msg = lua_tostring(_luaThread, -1);
|
||||
warning("TeLuaThread::executeFile: %s", msg);
|
||||
}
|
||||
delete [] buf;
|
||||
|
||||
_resume(0);
|
||||
}
|
||||
|
||||
void TeLuaThread::pushValue(const TeVariant &val) {
|
||||
TeVariant::VariantType valType = val.type();
|
||||
switch(valType) {
|
||||
case TeVariant::TypeBoolean:
|
||||
lua_pushboolean(_luaThread, val.toBoolean());
|
||||
break;
|
||||
case TeVariant::TypeInt32:
|
||||
lua_pushinteger(_luaThread, val.toSigned32());
|
||||
break;
|
||||
case TeVariant::TypeUInt32:
|
||||
lua_pushinteger(_luaThread, val.toUnsigned32());
|
||||
break;
|
||||
case TeVariant::TypeInt64:
|
||||
lua_pushinteger(_luaThread, val.toSigned64());
|
||||
break;
|
||||
case TeVariant::TypeUInt64:
|
||||
lua_pushinteger(_luaThread, val.toUnsigned64());
|
||||
break;
|
||||
case TeVariant::TypeFloat32:
|
||||
lua_pushnumber(_luaThread, val.toFloat32());
|
||||
break;
|
||||
case TeVariant::TypeFloat64:
|
||||
lua_pushnumber(_luaThread, val.toFloat64());
|
||||
break;
|
||||
case TeVariant::TypeString:
|
||||
lua_pushstring(_luaThread, val.toString().c_str());
|
||||
break;
|
||||
default:
|
||||
warning("TeLuaThread::pushValue: Unknown type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::release() {
|
||||
_released = true;
|
||||
if (_lastResumeResult != 1) {
|
||||
//debug("TeLuaThread:: deleting this?");
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::resume() {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::resume");
|
||||
#endif
|
||||
|
||||
if (_luaThread)
|
||||
_resume(0);
|
||||
}
|
||||
|
||||
void TeLuaThread::resume(const TeVariant &p1) {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::resume(%s)", p1.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
if (_luaThread) {
|
||||
pushValue(p1);
|
||||
_resume(1);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::resume(const TeVariant &p1, const TeVariant &p2) {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::resume(%s, %s)", p1.dumpStr().c_str(), p2.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
if (_luaThread) {
|
||||
pushValue(p1);
|
||||
pushValue(p2);
|
||||
_resume(2);
|
||||
}
|
||||
}
|
||||
|
||||
void TeLuaThread::resume(const TeVariant &p1, const TeVariant &p2, const TeVariant &p3) {
|
||||
#ifdef TETRAEDGE_LUA_DEBUG
|
||||
debug("TeLuaThread::resume(%s, %s, %s)", p1.dumpStr().c_str(), p2.dumpStr().c_str(),
|
||||
p3.dumpStr().c_str());
|
||||
#endif
|
||||
|
||||
if (_luaThread) {
|
||||
pushValue(p1);
|
||||
pushValue(p2);
|
||||
pushValue(p3);
|
||||
_resume(3);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeLuaThread *TeLuaThread::threadFromState(lua_State *state) {
|
||||
Common::Array<TeLuaThread *> *threads = threadList();
|
||||
for (auto &thread : *threads) {
|
||||
if (thread->_luaThread == state)
|
||||
return thread;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
Common::Array<TeLuaThread *> *TeLuaThread::threadList() {
|
||||
if (!_threadList)
|
||||
_threadList = new Common::Array<TeLuaThread *>();
|
||||
return _threadList;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeLuaThread::cleanup() {
|
||||
delete _threadList;
|
||||
_threadList = nullptr;
|
||||
}
|
||||
|
||||
int TeLuaThread::yield() {
|
||||
return lua_yield(_luaThread, 0);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
82
engines/tetraedge/te/te_lua_thread.h
Normal file
82
engines/tetraedge/te/te_lua_thread.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_LUA_THREAD_H
|
||||
#define TETRAEDGE_TE_TE_LUA_THREAD_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "common/fs.h"
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeLuaContext;
|
||||
class TeVariant;
|
||||
|
||||
class TeLuaThread {
|
||||
public:
|
||||
TeLuaThread(TeLuaContext *context);
|
||||
|
||||
~TeLuaThread();
|
||||
|
||||
static TeLuaThread *create(TeLuaContext *context);
|
||||
|
||||
void execute(const Common::String &str);
|
||||
void execute(const Common::String &str, const TeVariant &p1);
|
||||
void execute(const Common::String &str, const TeVariant &p1, const TeVariant &p2);
|
||||
void execute(const Common::String &str, const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
|
||||
|
||||
void executeFile(const TetraedgeFSNode &node);
|
||||
void pushValue(const TeVariant &val);
|
||||
|
||||
void release();
|
||||
|
||||
void resume();
|
||||
void resume(const TeVariant &p1);
|
||||
void resume(const TeVariant &p1, const TeVariant &p2);
|
||||
void resume(const TeVariant &p1, const TeVariant &p2, const TeVariant &p3);
|
||||
|
||||
static TeLuaThread *threadFromState(lua_State *state);
|
||||
int yield();
|
||||
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
void _resume(int nargs);
|
||||
|
||||
void applyScriptWorkarounds(char *buf, const Common::String &fileName);
|
||||
|
||||
lua_State *_luaThread;
|
||||
uint64 _resumeCount;
|
||||
int _bottomRef;
|
||||
int _lastResumeResult;
|
||||
bool _released;
|
||||
|
||||
static Common::Array<TeLuaThread *> *threadList();
|
||||
static Common::Array<TeLuaThread *> *_threadList;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_LUA_THREAD_H
|
||||
64
engines/tetraedge/te/te_marker.cpp
Normal file
64
engines/tetraedge/te/te_marker.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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 "tetraedge/te/te_marker.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMarker::TeMarker() : _visible(true), _isActive(false), _zLoc(0) {
|
||||
}
|
||||
|
||||
void TeMarker::active(bool val) {
|
||||
_isActive = val;
|
||||
_button.setVisible(_visible && val);
|
||||
}
|
||||
|
||||
void TeMarker::update(TeCamera &camera) {
|
||||
_button.setVisible(true);
|
||||
if (!_visible)
|
||||
return;
|
||||
const TeVector3f32 transformLoc = camera.projectPoint3f32(_loc);
|
||||
const TeVector3f32 btnSize = _button.size();
|
||||
_button.setPositionType(TeILayout::ABSOLUTE);
|
||||
float vpWidth = camera.getViewportWidth();
|
||||
float vpHeight = camera.getViewportHeight();
|
||||
if (transformLoc.z() < 1.0f) {
|
||||
// Behind the camera, move off-screen.
|
||||
_button.setPosition(TeVector3f32(-btnSize.x() - vpWidth / 2, -btnSize.y() - vpHeight / 2, _zLoc));
|
||||
} else {
|
||||
TeVector3f32 buttonMiddle(transformLoc.x() - btnSize.x() / 2 - vpWidth / 2, transformLoc.y() - btnSize.y() / 2 - vpHeight / 2, _zLoc);
|
||||
// Note: device rotation is taken account of here in original, skip that.
|
||||
// Original also uses scales 480 and 320, but that makes it too small
|
||||
// in HD.
|
||||
//TeVector3f32 newScale(480.0f / vpWidth, 320.0f / vpHeight, 1.0);
|
||||
//_button.setScale(newScale);
|
||||
_button.setPosition(TeVector3f32(buttonMiddle.x(), buttonMiddle.y(), buttonMiddle.z()));
|
||||
/*debug("Updated button pos to %s (transformed %s middle %s)", _button.position().dump().c_str(), transformLoc.dump().c_str(), buttonMiddle.dump().c_str());*/
|
||||
}
|
||||
}
|
||||
|
||||
void TeMarker::visible(bool vis) {
|
||||
_visible = vis;
|
||||
bool buttonVis = (vis && _isActive);
|
||||
_button.setVisible(buttonVis);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
57
engines/tetraedge/te/te_marker.h
Normal file
57
engines/tetraedge/te/te_marker.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MARKER_H
|
||||
#define TETRAEDGE_TE_TE_MARKER_H
|
||||
|
||||
#include "tetraedge/te/te_camera.h"
|
||||
#include "tetraedge/te/te_button_layout.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
// Note: Only used in Amerzone
|
||||
class TeMarker : public TeObject {
|
||||
public:
|
||||
TeMarker();
|
||||
|
||||
void active(bool val);
|
||||
void update(TeCamera &camera);
|
||||
void visible(bool val);
|
||||
|
||||
TeButtonLayout &button() { return _button; }
|
||||
TeVector3f32 &loc() { return _loc; }
|
||||
|
||||
void setZLoc(float f) { _zLoc = f; }
|
||||
|
||||
private:
|
||||
bool _visible;
|
||||
bool _isActive;
|
||||
float _zLoc;
|
||||
TeVector3f32 _loc;
|
||||
// Note: this is a TeSpriteButton in the original, updated
|
||||
// to use the newer ButtonLayout
|
||||
TeButtonLayout _button;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MARKER_H
|
||||
143
engines/tetraedge/te/te_material.cpp
Normal file
143
engines/tetraedge/te/te_material.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/* 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/textconsole.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
|
||||
#include "tetraedge/te/te_core.h"
|
||||
#include "tetraedge/te/te_light.h"
|
||||
#include "tetraedge/te/te_material.h"
|
||||
#include "tetraedge/te/te_model.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMaterial::TeMaterial() {
|
||||
defaultValues();
|
||||
_mode = MaterialMode1;
|
||||
}
|
||||
|
||||
TeMaterial::TeMaterial(TeIntrusivePtr<Te3DTexture> texture, Mode mode) {
|
||||
defaultValues();
|
||||
_texture = texture;
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
void TeMaterial::defaultValues() {
|
||||
_ambientColor = TeColor(0, 0, 0, 255);
|
||||
_diffuseColor = TeColor(255, 255, 255, 255);
|
||||
_specularColor = TeColor(0, 0, 0, 255);
|
||||
_emissionColor = TeColor(0, 0, 0, 255);
|
||||
_shininess = 0.0;
|
||||
_enableLights = false;
|
||||
_isShadowTexture = false;
|
||||
}
|
||||
|
||||
Common::String TeMaterial::dump() const {
|
||||
return Common::String::format
|
||||
("amb:%s dif:%s spe:%s emi:%s mode:%d tex:%s shin:%.02f lights:%s",
|
||||
_ambientColor.dump().c_str(),
|
||||
_diffuseColor.dump().c_str(),
|
||||
_specularColor.dump().c_str(),
|
||||
_emissionColor.dump().c_str(),
|
||||
(int)_mode,
|
||||
_texture ? _texture->getAccessName().toString('/').c_str() : "None",
|
||||
_shininess, _enableLights ? "on" : "off");
|
||||
}
|
||||
|
||||
bool TeMaterial::operator==(const TeMaterial &other) const {
|
||||
return (_texture == other._texture) && (_ambientColor == other._ambientColor)
|
||||
&& (_diffuseColor == other._diffuseColor) && (_specularColor == other._specularColor)
|
||||
&& (_emissionColor == other._emissionColor) && (_enableLights == other._enableLights)
|
||||
&& (_shininess == other._shininess) && (_mode == other._mode);
|
||||
}
|
||||
|
||||
TeMaterial &TeMaterial::operator=(const TeMaterial &other) {
|
||||
if (&other == this)
|
||||
return *this;
|
||||
|
||||
_texture = other._texture;
|
||||
_ambientColor = other._ambientColor;
|
||||
_diffuseColor = other._diffuseColor;
|
||||
_specularColor = other._specularColor;
|
||||
_emissionColor = other._emissionColor;
|
||||
_enableLights = other._enableLights;
|
||||
_shininess = other._shininess;
|
||||
_mode = other._mode;
|
||||
_isShadowTexture = other._isShadowTexture;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void TeMaterial::deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &texPath) {
|
||||
const Common::String nameStr = Te3DObject2::deserializeString(stream);
|
||||
|
||||
TeModel::loadAlign(stream);
|
||||
material._mode = static_cast<TeMaterial::Mode>(stream.readUint32LE());
|
||||
|
||||
if (nameStr.size()) {
|
||||
TeCore *core = g_engine->getCore();
|
||||
TetraedgeFSNode matPath = core->findFile(Common::Path(texPath).join(nameStr));
|
||||
material._texture = Te3DTexture::load2(matPath, false);
|
||||
if (!material._texture)
|
||||
warning("failed to load texture %s (texpath %s)", nameStr.c_str(), matPath.toString().c_str());
|
||||
}
|
||||
|
||||
material._ambientColor.deserialize(stream);
|
||||
material._diffuseColor.deserialize(stream);
|
||||
material._specularColor.deserialize(stream);
|
||||
// TODO: Confirm this - Surely this should be emission color,
|
||||
// but the original doesn't assign the result
|
||||
// to _emissionColor. It does read though.
|
||||
TeColor c;
|
||||
c.deserialize(stream);
|
||||
material._shininess = stream.readFloatLE();
|
||||
}
|
||||
|
||||
/*static*/ void TeMaterial::serialize(Common::SeekableWriteStream &stream, TeMaterial &material) {
|
||||
Te3DTexture *tex = material._texture.get();
|
||||
Common::String texName;
|
||||
if (tex) {
|
||||
texName = tex->getAccessName().toString('/');
|
||||
// "Remove extension" twice for some reason..
|
||||
size_t offset = texName.rfind('.');
|
||||
if (offset != Common::String::npos) {
|
||||
texName.substr(0, offset);
|
||||
}
|
||||
offset = texName.rfind('.');
|
||||
if (offset != Common::String::npos) {
|
||||
texName.substr(0, offset);
|
||||
}
|
||||
}
|
||||
stream.writeUint32LE(texName.size());
|
||||
stream.write(texName.c_str(), texName.size());
|
||||
TeModel::saveAlign(stream);
|
||||
stream.writeUint32LE(static_cast<uint32>(material._mode));
|
||||
material._ambientColor.serialize(stream);
|
||||
material._diffuseColor.serialize(stream);
|
||||
material._specularColor.serialize(stream);
|
||||
material._emissionColor.serialize(stream);
|
||||
stream.writeFloatLE(material._shininess);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
74
engines/tetraedge/te/te_material.h
Normal file
74
engines/tetraedge/te/te_material.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MATERIAL_H
|
||||
#define TETRAEDGE_TE_TE_MATERIAL_H
|
||||
|
||||
#include "common/ptr.h"
|
||||
#include "common/path.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeMaterial {
|
||||
public:
|
||||
enum Mode {
|
||||
MaterialMode0,
|
||||
MaterialMode1,
|
||||
MaterialMode2 // alpha only?
|
||||
};
|
||||
|
||||
TeMaterial();
|
||||
TeMaterial(const TeMaterial &other) = default;
|
||||
TeMaterial(TeIntrusivePtr<Te3DTexture> texture, Mode mode);
|
||||
|
||||
// Note: apply() function from original moved to TeRenderer to remove OGL specific code from here
|
||||
void defaultValues();
|
||||
static void deserialize(Common::SeekableReadStream &stream, TeMaterial &material, const Common::Path &path);
|
||||
static void serialize(Common::SeekableWriteStream &stream, TeMaterial &material);
|
||||
|
||||
bool operator==(const TeMaterial &other) const;
|
||||
bool operator!=(const TeMaterial &other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
TeMaterial &operator=(const TeMaterial &other);
|
||||
|
||||
Common::String dump() const;
|
||||
|
||||
TeIntrusivePtr<Te3DTexture> _texture;
|
||||
Mode _mode;
|
||||
TeColor _ambientColor;
|
||||
TeColor _diffuseColor;
|
||||
TeColor _specularColor;
|
||||
TeColor _emissionColor;
|
||||
float _shininess;
|
||||
bool _isShadowTexture;
|
||||
bool _enableLights;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MATERIAL_H
|
||||
79
engines/tetraedge/te/te_matricies_stack.cpp
Normal file
79
engines/tetraedge/te/te_matricies_stack.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 "tetraedge/te/te_matricies_stack.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMatriciesStack::TeMatriciesStack() {
|
||||
_stack.push(TeMatrix4x4());
|
||||
}
|
||||
|
||||
const TeMatrix4x4 &TeMatriciesStack::currentMatrix() const {
|
||||
return _stack.top();
|
||||
}
|
||||
|
||||
bool TeMatriciesStack::isEmpty() const {
|
||||
return _stack.empty();
|
||||
}
|
||||
|
||||
void TeMatriciesStack::loadIdentity() {
|
||||
_stack.top() = TeMatrix4x4();
|
||||
}
|
||||
|
||||
void TeMatriciesStack::loadMatrix(const TeMatrix4x4 &matrix) {
|
||||
_stack.top() = matrix;
|
||||
}
|
||||
|
||||
void TeMatriciesStack::multiplyMatrix(const TeMatrix4x4 &matrix) {
|
||||
_stack.top() = _stack.top() * matrix;
|
||||
}
|
||||
|
||||
void TeMatriciesStack::popMatrix() {
|
||||
if (_stack.size() > 1)
|
||||
_stack.pop();
|
||||
}
|
||||
|
||||
void TeMatriciesStack::pushMatrix() {
|
||||
_stack.push(_stack.top());
|
||||
}
|
||||
|
||||
void TeMatriciesStack::rotate(const TeQuaternion &rot) {
|
||||
_stack.top() = _stack.top() * rot.toTeMatrix();
|
||||
}
|
||||
|
||||
void TeMatriciesStack::rotate(float angle, const TeVector3f32 &axis) {
|
||||
rotate(TeQuaternion::fromAxisAndAngle(axis, angle));
|
||||
}
|
||||
|
||||
void TeMatriciesStack::scale(const TeVector3f32 &scale) {
|
||||
_stack.top().scale(scale);
|
||||
}
|
||||
|
||||
uint TeMatriciesStack::size() {
|
||||
return _stack.size();
|
||||
}
|
||||
|
||||
void TeMatriciesStack::translate(const TeVector3f32 &trans) {
|
||||
_stack.top().translate(trans);
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
56
engines/tetraedge/te/te_matricies_stack.h
Normal file
56
engines/tetraedge/te/te_matricies_stack.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MATRICIES_STACK_H
|
||||
#define TETRAEDGE_TE_TE_MATRICIES_STACK_H
|
||||
|
||||
#include "common/stack.h"
|
||||
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_quaternion.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeMatriciesStack {
|
||||
public:
|
||||
TeMatriciesStack();
|
||||
|
||||
const TeMatrix4x4 ¤tMatrix() const;
|
||||
bool isEmpty() const;
|
||||
void loadIdentity();
|
||||
void loadMatrix(const TeMatrix4x4 &matrix);
|
||||
void multiplyMatrix(const TeMatrix4x4 &matrix);
|
||||
void popMatrix();
|
||||
void pushMatrix();
|
||||
void rotate(const TeQuaternion &rot);
|
||||
void rotate(float f, const TeVector3f32 &rot);
|
||||
void scale(const TeVector3f32 &scale);
|
||||
uint size();
|
||||
void translate(const TeVector3f32 &trans);
|
||||
|
||||
private:
|
||||
Common::Stack<TeMatrix4x4> _stack;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MATRICIES_STACK_H
|
||||
360
engines/tetraedge/te/te_matrix4x4.cpp
Normal file
360
engines/tetraedge/te/te_matrix4x4.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
/* 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 "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_trs.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMatrix4x4::TeMatrix4x4() {
|
||||
setToIdentity();
|
||||
}
|
||||
|
||||
void TeMatrix4x4::setToIdentity() {
|
||||
_data[0] = _data[5] = _data[10] = _data[15] = 1.0f;
|
||||
_data[1] = _data[2] = _data[3] = _data[4] = 0.0f;
|
||||
_data[6] = _data[7] = _data[8] = _data[9] = 0.0f;
|
||||
_data[11] = _data[12] = _data[13] = _data[14] = 0.0f;
|
||||
}
|
||||
|
||||
TeMatrix4x4::TeMatrix4x4(const Math::Matrix<4, 4> &matrix) {
|
||||
// Transpose - row-major to column-major.
|
||||
float *d = getData();
|
||||
const float *s = matrix.getData();
|
||||
for (int c = 0; c < 4; c++) {
|
||||
for (int r = 0; r < 4; r++) {
|
||||
d[c * 4 + r] = s[r * 4 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TeMatrix4x4 operator*(const TeMatrix4x4 &left, const TeMatrix4x4 &right) {
|
||||
TeMatrix4x4 retval;
|
||||
const float *d1 = left.getData();
|
||||
const float *d2 = right.getData();
|
||||
float *res = retval.getData();
|
||||
|
||||
res[0] = res[5] = res[10] = res[15] = 0.0f;
|
||||
|
||||
for (int r = 0; r < 4; r++) {
|
||||
for (int c = 0; c < 16; c += 4) {
|
||||
res[c + r] = (d1[r + 0] * d2[c + 0]) +
|
||||
(d1[r + 4] * d2[c + 1]) +
|
||||
(d1[r + 8] * d2[c + 2]) +
|
||||
(d1[r + 12] * d2[c + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
TeMatrix4x4 &TeMatrix4x4::operator*=(const TeMatrix4x4 &mul) {
|
||||
TeMatrix4x4 result = operator*(*this, mul);
|
||||
*this = result;
|
||||
return *this;
|
||||
}*/
|
||||
|
||||
bool TeMatrix4x4::operator==(const TeMatrix4x4 &other) const {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (_data[i] != other._data[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeMatrix4x4::scale(const TeVector3f32 &vec) {
|
||||
TeMatrix4x4 scaleMatrix;
|
||||
scaleMatrix(0, 0) = vec.x();
|
||||
scaleMatrix(1, 1) = vec.y();
|
||||
scaleMatrix(2, 2) = vec.z();
|
||||
//scaleMatrix(3, 3) = 1.0; // default.
|
||||
*this = (*this * scaleMatrix);
|
||||
}
|
||||
|
||||
void TeMatrix4x4::translate(const TeVector3f32 &vec) {
|
||||
TeMatrix4x4 translMatrix;
|
||||
translMatrix(0, 3) = vec.x();
|
||||
translMatrix(1, 3) = vec.y();
|
||||
translMatrix(2, 3) = vec.z();
|
||||
*this = (*this * translMatrix);
|
||||
}
|
||||
|
||||
void TeMatrix4x4::rotate(const TeQuaternion &rot) {
|
||||
const TeMatrix4x4 rotMatrix = rot.toTeMatrix();
|
||||
*this = (*this * rotMatrix);
|
||||
}
|
||||
|
||||
TeVector3f32 TeMatrix4x4::translation() const {
|
||||
return TeVector3f32(_data[12], _data[13], _data[14]);
|
||||
}
|
||||
|
||||
TeVector3f32 TeMatrix4x4::mult4x3(const TeVector3f32 &vec) const {
|
||||
const float f1 = vec.x();
|
||||
const float f2 = vec.y();
|
||||
const float f3 = vec.z();
|
||||
const float *data = getData();
|
||||
|
||||
return TeVector3f32(data[0] * f1 + data[4] * f2 + data[8] * f3 + data[12],
|
||||
data[1] * f1 + data[5] * f2 + data[9] * f3 + data[13],
|
||||
data[2] * f1 + data[6] * f2 + data[10] * f3 + data[14]);
|
||||
|
||||
}
|
||||
|
||||
TeVector3f32 TeMatrix4x4::mult3x3(const TeVector3f32 &vec) const {
|
||||
const float f1 = vec.x();
|
||||
const float f2 = vec.y();
|
||||
const float f3 = vec.z();
|
||||
const float *data = getData();
|
||||
|
||||
return TeVector3f32(data[0] * f1 + data[4] * f2 + data[8] * f3,
|
||||
data[1] * f1 + data[5] * f2 + data[9] * f3,
|
||||
data[2] * f1 + data[6] * f2 + data[10] * f3);
|
||||
}
|
||||
|
||||
TeMatrix4x4 TeMatrix4x4::meshScale(float factor) const {
|
||||
TeMatrix4x4 result;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result._data[i] = _data[i] * factor;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void TeMatrix4x4::meshAdd(const TeMatrix4x4 &other) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
_data[i] += other._data[i];
|
||||
}
|
||||
}
|
||||
|
||||
TeVector3f32 TeMatrix4x4::operator*(const TeVector3f32 &mul) const {
|
||||
float x = mul.x();
|
||||
float y = mul.y();
|
||||
float z = mul.z();
|
||||
const float *d = getData();
|
||||
float w = d[3] * x + d[7] * y + d[11] * z + d[15];
|
||||
if (w == 0.0)
|
||||
w = 1e-09f;
|
||||
|
||||
return TeVector3f32
|
||||
((d[0] * x + d[4] * y + d[8] * z + d[12]) / w,
|
||||
(d[1] * x + d[5] * y + d[9] * z + d[13]) / w,
|
||||
(d[2] * x + d[6] * y + d[10] * z + d[14]) / w);
|
||||
}
|
||||
|
||||
Common::String TeMatrix4x4::toString() const {
|
||||
const float *data = getData();
|
||||
return Common::String::format("[[%.03f %.03f %.03f %.03f] [%.03f %.03f %.03f %.03f] [%.03f %.03f %.03f %.03f] [%.03f %.03f %.03f %.03f]]",
|
||||
data[0], data[4], data[8], data[12],
|
||||
data[1], data[5], data[9], data[13],
|
||||
data[2], data[6], data[10], data[14],
|
||||
data[3], data[7], data[11], data[15]);
|
||||
}
|
||||
|
||||
Math::Matrix<4, 4> TeMatrix4x4::toScummVMMatrix() const {
|
||||
const TeMatrix4x4 trans = transpose();
|
||||
Math::Matrix<4, 4> retval;
|
||||
retval.setData(trans.getData());
|
||||
return retval;
|
||||
}
|
||||
|
||||
TeMatrix4x4 TeMatrix4x4::transpose() const {
|
||||
TeMatrix4x4 ret;
|
||||
const float *s = getData();
|
||||
float *d = ret.getData();
|
||||
for (int c = 0; c < 4; c++) {
|
||||
for (int r = 0; r < 4; r++) {
|
||||
d[c * 4 + r] = s[r * 4 + c];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TeMatrix4x4::inverse() {
|
||||
TeMatrix4x4 invMatrix;
|
||||
float *inv = invMatrix.getData();
|
||||
TeMatrix4x4 temp = transpose();
|
||||
float *m = temp.getData();
|
||||
|
||||
inv[0] = m[5] * m[10] * m[15] -
|
||||
m[5] * m[11] * m[14] -
|
||||
m[9] * m[6] * m[15] +
|
||||
m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] -
|
||||
m[13] * m[7] * m[10];
|
||||
|
||||
inv[4] = -m[4] * m[10] * m[15] +
|
||||
m[4] * m[11] * m[14] +
|
||||
m[8] * m[6] * m[15] -
|
||||
m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] +
|
||||
m[12] * m[7] * m[10];
|
||||
|
||||
inv[8] = m[4] * m[9] * m[15] -
|
||||
m[4] * m[11] * m[13] -
|
||||
m[8] * m[5] * m[15] +
|
||||
m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] -
|
||||
m[12] * m[7] * m[9];
|
||||
|
||||
inv[12] = -m[4] * m[9] * m[14] +
|
||||
m[4] * m[10] * m[13] +
|
||||
m[8] * m[5] * m[14] -
|
||||
m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] +
|
||||
m[12] * m[6] * m[9];
|
||||
|
||||
inv[1] = -m[1] * m[10] * m[15] +
|
||||
m[1] * m[11] * m[14] +
|
||||
m[9] * m[2] * m[15] -
|
||||
m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] +
|
||||
m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] = m[0] * m[10] * m[15] -
|
||||
m[0] * m[11] * m[14] -
|
||||
m[8] * m[2] * m[15] +
|
||||
m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] -
|
||||
m[12] * m[3] * m[10];
|
||||
|
||||
inv[9] = -m[0] * m[9] * m[15] +
|
||||
m[0] * m[11] * m[13] +
|
||||
m[8] * m[1] * m[15] -
|
||||
m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] +
|
||||
m[12] * m[3] * m[9];
|
||||
|
||||
inv[13] = m[0] * m[9] * m[14] -
|
||||
m[0] * m[10] * m[13] -
|
||||
m[8] * m[1] * m[14] +
|
||||
m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] -
|
||||
m[12] * m[2] * m[9];
|
||||
|
||||
inv[2] = m[1] * m[6] * m[15] -
|
||||
m[1] * m[7] * m[14] -
|
||||
m[5] * m[2] * m[15] +
|
||||
m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] -
|
||||
m[13] * m[3] * m[6];
|
||||
|
||||
inv[6] = -m[0] * m[6] * m[15] +
|
||||
m[0] * m[7] * m[14] +
|
||||
m[4] * m[2] * m[15] -
|
||||
m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] +
|
||||
m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] = m[0] * m[5] * m[15] -
|
||||
m[0] * m[7] * m[13] -
|
||||
m[4] * m[1] * m[15] +
|
||||
m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] -
|
||||
m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] = -m[0] * m[5] * m[14] +
|
||||
m[0] * m[6] * m[13] +
|
||||
m[4] * m[1] * m[14] -
|
||||
m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] +
|
||||
m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] = -m[1] * m[6] * m[11] +
|
||||
m[1] * m[7] * m[10] +
|
||||
m[5] * m[2] * m[11] -
|
||||
m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] +
|
||||
m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] = m[0] * m[6] * m[11] -
|
||||
m[0] * m[7] * m[10] -
|
||||
m[4] * m[2] * m[11] +
|
||||
m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] -
|
||||
m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] = -m[0] * m[5] * m[11] +
|
||||
m[0] * m[7] * m[9] +
|
||||
m[4] * m[1] * m[11] -
|
||||
m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] +
|
||||
m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] = m[0] * m[5] * m[10] -
|
||||
m[0] * m[6] * m[9] -
|
||||
m[4] * m[1] * m[10] +
|
||||
m[4] * m[2] * m[9] +
|
||||
m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0)
|
||||
return false;
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
m[i] = inv[i] * det;
|
||||
}
|
||||
|
||||
*this = temp.transpose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TeMatrix4x4::deserialize(Common::ReadStream &stream) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
_data[i] = stream.readFloatLE();
|
||||
}
|
||||
}
|
||||
|
||||
void TeMatrix4x4::serialize(Common::WriteStream &stream) const {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
stream.writeFloatLE(_data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeMatrix4x4 TeMatrix4x4::fromTRS(const TeTRS &trs) {
|
||||
TeMatrix4x4 result;
|
||||
const TeVector3f32 trans = trs.getTranslation();
|
||||
TeMatrix4x4 transm;
|
||||
transm(0, 3) = trans.x();
|
||||
transm(1, 3) = trans.y();
|
||||
transm(2, 3) = trans.z();
|
||||
result = result * transm;
|
||||
|
||||
const TeMatrix4x4 rotm = trs.getRotation().toTeMatrix();
|
||||
result = result * rotm;
|
||||
|
||||
const TeVector3f32 scle = trs.getScale();
|
||||
TeMatrix4x4 scalem;
|
||||
scalem(0, 0) = scle.x();
|
||||
scalem(1, 1) = scle.y();
|
||||
scalem(2, 2) = scle.z();
|
||||
result = result * scalem;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
98
engines/tetraedge/te/te_matrix4x4.h
Normal file
98
engines/tetraedge/te/te_matrix4x4.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MATRIX4X4_H
|
||||
#define TETRAEDGE_TE_TE_MATRIX4X4_H
|
||||
|
||||
#include "math/matrix4.h"
|
||||
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeTRS;
|
||||
|
||||
/**
|
||||
* A 4x4 matrix, but stored in *column-major* order to match
|
||||
* OpenGL (and the original engine)
|
||||
*/
|
||||
class TeMatrix4x4 {
|
||||
public:
|
||||
TeMatrix4x4();
|
||||
TeMatrix4x4(const Math::Matrix<4, 4> &matrix);
|
||||
|
||||
void setToIdentity();
|
||||
|
||||
float &operator()(int row, int col) {
|
||||
return *(_data + col * 4 + row);
|
||||
}
|
||||
|
||||
const float &operator()(int row, int col) const {
|
||||
return *(_data + col * 4 + row);
|
||||
}
|
||||
|
||||
bool operator==(const TeMatrix4x4 &other) const;
|
||||
bool operator!=(const TeMatrix4x4 &other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
//TeMatrix4x4 &operator*=(const TeMatrix4x4 &mul);
|
||||
|
||||
TeVector3f32 operator*(const TeVector3f32 &mul) const;
|
||||
|
||||
void scale(const TeVector3f32 &vec);
|
||||
void translate(const TeVector3f32 &vec);
|
||||
void rotate(const TeQuaternion &rot);
|
||||
TeVector3f32 translation() const;
|
||||
TeVector3f32 mult3x3(const TeVector3f32 &vec) const;
|
||||
TeVector3f32 mult4x3(const TeVector3f32 &vec) const;
|
||||
|
||||
Common::String toString() const;
|
||||
Math::Matrix<4, 4> toScummVMMatrix() const;
|
||||
|
||||
void setValue(int row, int col, float val) {
|
||||
operator()(row, col) = val;
|
||||
}
|
||||
|
||||
TeMatrix4x4 transpose() const;
|
||||
TeMatrix4x4 meshScale(float factor) const;
|
||||
void meshAdd(const TeMatrix4x4 &other);
|
||||
|
||||
bool inverse();
|
||||
|
||||
static TeMatrix4x4 fromTRS(const TeTRS &trs);
|
||||
|
||||
const float *getData() const { return _data; }
|
||||
float *getData() { return _data; }
|
||||
|
||||
void deserialize(Common::ReadStream &stream);
|
||||
void serialize(Common::WriteStream &stream) const;
|
||||
|
||||
private:
|
||||
float _data[16];
|
||||
|
||||
};
|
||||
|
||||
TeMatrix4x4 operator*(const TeMatrix4x4 &left, const TeMatrix4x4 &right);
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MATRIX4X4_H
|
||||
251
engines/tetraedge/te/te_mesh.cpp
Normal file
251
engines/tetraedge/te/te_mesh.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/* 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 "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
#include "tetraedge/te/te_light.h"
|
||||
#include "tetraedge/te/te_mesh.h"
|
||||
#include "tetraedge/te/te_mesh_opengl.h"
|
||||
#include "tetraedge/te/te_mesh_tinygl.h"
|
||||
#include "tetraedge/te/te_material.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMesh::TeMesh() : _matrixForced(false), _hasAlpha(false), _initialMaterialIndexCount(0),
|
||||
_drawWires(false), _shouldDraw(true) {
|
||||
}
|
||||
|
||||
|
||||
void TeMesh::defaultMaterial(const TeIntrusivePtr<Te3DTexture> &texture) {
|
||||
TeMaterial::Mode mode = TeMaterial::MaterialMode1;
|
||||
if (texture && !texture->hasAlpha())
|
||||
mode = TeMaterial::MaterialMode0;
|
||||
_materials.resize(1);
|
||||
_materials[0] = TeMaterial(texture, mode);
|
||||
}
|
||||
|
||||
TeMaterial *TeMesh::material(uint index) {
|
||||
assert(!_materials.empty());
|
||||
if (index < _materials.size()) {
|
||||
return &_materials[index];
|
||||
} else {
|
||||
return &_materials[0];
|
||||
}
|
||||
}
|
||||
|
||||
const TeMaterial *TeMesh::material(uint index) const {
|
||||
assert(!_materials.empty());
|
||||
if (index < _materials.size()) {
|
||||
return &_materials[index];
|
||||
} else {
|
||||
return &_materials[0];
|
||||
}
|
||||
}
|
||||
|
||||
void TeMesh::destroy() {
|
||||
_hasAlpha = false;
|
||||
_updatedVerticies.clear();
|
||||
_updatedNormals.clear();
|
||||
_verticies.clear();
|
||||
_normals.clear();
|
||||
_uvs.clear();
|
||||
_colors.clear();
|
||||
_indexes.clear();
|
||||
_materialIndexes.clear();
|
||||
_faceCounts.clear();
|
||||
_matricies.clear();
|
||||
}
|
||||
|
||||
bool TeMesh::hasAlpha(uint idx) {
|
||||
// Note: I don't understand this logic, but it's what the game does..
|
||||
bool hasGlobalAlpha = _hasAlpha && !_colors.empty();
|
||||
|
||||
bool retval = hasGlobalAlpha;
|
||||
if (idx < _materials.size()) {
|
||||
const TeMaterial &material = _materials[idx];
|
||||
if (material._isShadowTexture) {
|
||||
retval = false;
|
||||
} else {
|
||||
retval = true;
|
||||
if (!hasGlobalAlpha && material._mode != TeMaterial::MaterialMode1 && material._ambientColor.a() == 255)
|
||||
retval = (material._diffuseColor.a() != 255);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
TeVector3f32 TeMesh::normal(uint idx) const {
|
||||
if (!_updatedNormals.empty())
|
||||
return _updatedNormals[idx];
|
||||
else
|
||||
return _normals[idx];
|
||||
}
|
||||
|
||||
void TeMesh::resizeUpdatedTables(uint newSize) {
|
||||
_updatedVerticies.resize(newSize);
|
||||
_updatedNormals.resize(newSize);
|
||||
}
|
||||
|
||||
void TeMesh::setColor(const TeColor &col) {
|
||||
Te3DObject2::setColor(col);
|
||||
|
||||
if (!_verticies.empty()) {
|
||||
const TeColor colnow = Te3DObject2::color();
|
||||
_colors.resize(_verticies.size());
|
||||
if (colnow.a() != 255)
|
||||
_hasAlpha = true;
|
||||
|
||||
for (uint i = 0; i < _verticies.size(); i++) {
|
||||
_colors[i] = colnow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeMesh::setColor(uint idx, const TeColor &col) {
|
||||
if (col.a() != 255) {
|
||||
_hasAlpha = true;
|
||||
}
|
||||
_colors.resize(_verticies.size());
|
||||
_colors[idx] = col;
|
||||
}
|
||||
|
||||
void TeMesh::setConf(uint vertexCount, uint indexCount, enum Mode mode, uint materialCount, uint materialIndexCount) {
|
||||
destroy();
|
||||
_initialMaterialIndexCount = materialIndexCount;
|
||||
_verticies.resize(vertexCount);
|
||||
_indexes.resize(indexCount);
|
||||
_materials.resize(materialCount);
|
||||
_matricies.resize(vertexCount);
|
||||
setMode(mode);
|
||||
}
|
||||
|
||||
void TeMesh::setIndex(uint idx, uint val) {
|
||||
_indexes[idx] = val;
|
||||
}
|
||||
|
||||
void TeMesh::setNormal(uint idx, const TeVector3f32 &val) {
|
||||
_normals.resize(_verticies.size());
|
||||
_normals[idx] = val;
|
||||
}
|
||||
|
||||
void TeMesh::setTextureUV(uint idx, const TeVector2f32 &val) {
|
||||
_uvs.resize(_verticies.size());
|
||||
_uvs[idx] = val;
|
||||
}
|
||||
|
||||
void TeMesh::setVertex(uint idx, const TeVector3f32 &val) {
|
||||
_verticies[idx] = val;
|
||||
}
|
||||
|
||||
TeVector3f32 TeMesh::vertex(uint idx) const {
|
||||
if (!_updatedVerticies.empty())
|
||||
return _updatedVerticies[idx];
|
||||
else
|
||||
return _verticies[idx];
|
||||
}
|
||||
|
||||
void TeMesh::attachMaterial(uint idx, const TeMaterial &src) {
|
||||
TeMaterial &dest = _materials[idx];
|
||||
dest._texture = src._texture;
|
||||
dest._enableLights = src._enableLights;
|
||||
dest._isShadowTexture = src._isShadowTexture;
|
||||
dest._emissionColor = src._emissionColor;
|
||||
dest._shininess = src._shininess;
|
||||
dest._diffuseColor = src._diffuseColor;
|
||||
dest._specularColor = src._specularColor;
|
||||
dest._mode = src._mode;
|
||||
dest._ambientColor = src._ambientColor;
|
||||
}
|
||||
|
||||
void TeMesh::facesPerMaterial(uint idx, unsigned short value) {
|
||||
_faceCounts.resize(_materials.size());
|
||||
_faceCounts[idx] = value;
|
||||
}
|
||||
|
||||
void TeMesh::matrixIndex(uint num, unsigned short val) {
|
||||
_matricies[num] = val;
|
||||
}
|
||||
|
||||
void TeMesh::update(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2) {
|
||||
if (visible()) {
|
||||
if (matricies1) {
|
||||
_updatedVerticies.resize(_verticies.size());
|
||||
_updatedNormals.resize(_normals.size());
|
||||
updateTo(matricies1, matricies2, _updatedVerticies, _updatedNormals);
|
||||
} else {
|
||||
_updatedVerticies.clear();
|
||||
_updatedNormals.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeMesh::update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim) {
|
||||
_updatedVerticies.resize(_verticies.size());
|
||||
_updatedNormals.resize(_normals.size());
|
||||
|
||||
const Common::Array<TeVector3f32> animverts = vertexanim->getVertices();
|
||||
assert(animverts.size() >= _verticies.size());
|
||||
for (uint i = 0; i < _verticies.size(); i++) {
|
||||
_updatedVerticies[i] = animverts[i];
|
||||
}
|
||||
for (uint i = 0; i < _normals.size(); i++) {
|
||||
_updatedNormals[i] = _normals[i];
|
||||
}
|
||||
}
|
||||
|
||||
void TeMesh::updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2,
|
||||
Common::Array<TeVector3f32> &verts, Common::Array<TeVector3f32> &normals) {
|
||||
static const TeMatrix4x4 emptyMatrix;
|
||||
for (uint i = 0; i < _verticies.size(); i++) {
|
||||
uint m = _matricies[i];
|
||||
const TeMatrix4x4 *mat;
|
||||
if (m < matricies1->size()) {
|
||||
mat = &((*matricies1)[m]);
|
||||
} else {
|
||||
m -= matricies1->size();
|
||||
if (m < matricies2->size())
|
||||
mat = &((*matricies2)[m]);
|
||||
else
|
||||
mat = &emptyMatrix;
|
||||
}
|
||||
verts[i] = mat->mult4x3(_verticies[i]);
|
||||
normals[i] = mat->mult3x3(_normals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
TeMesh *TeMesh::makeInstance() {
|
||||
Graphics::RendererType r = g_engine->preferredRendererType();
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
if (r == Graphics::kRendererTypeOpenGL)
|
||||
return new TeMeshOpenGL();
|
||||
#endif
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
if (r == Graphics::kRendererTypeTinyGL)
|
||||
return new TeMeshTinyGL();
|
||||
#endif
|
||||
error("Couldn't create TeMesh for selected renderer");
|
||||
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
149
engines/tetraedge/te/te_mesh.h
Normal file
149
engines/tetraedge/te/te_mesh.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MESH_H
|
||||
#define TETRAEDGE_TE_TE_MESH_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/ptr.h"
|
||||
|
||||
#include "tetraedge/te/te_3d_object2.h"
|
||||
#include "tetraedge/te/te_3d_texture.h"
|
||||
#include "tetraedge/te/te_color.h"
|
||||
#include "tetraedge/te/te_intrusive_ptr.h"
|
||||
#include "tetraedge/te/te_vector2f32.h"
|
||||
#include "tetraedge/te/te_vector3f32.h"
|
||||
#include "tetraedge/te/te_matrix4x4.h"
|
||||
#include "tetraedge/te/te_material.h"
|
||||
#include "tetraedge/te/te_model_vertex_animation.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeModel;
|
||||
class TeModelVertexAnimation;
|
||||
|
||||
class TeMesh : public Te3DObject2 {
|
||||
public:
|
||||
TeMesh();
|
||||
|
||||
virtual ~TeMesh() {};
|
||||
|
||||
enum Mode {
|
||||
MeshMode_None = 0,
|
||||
MeshMode_Points,
|
||||
MeshMode_Lines,
|
||||
MeshMode_LineLoop,
|
||||
MeshMode_LineStrip,
|
||||
MeshMode_Triangles,
|
||||
MeshMode_TriangleStrip,
|
||||
MeshMode_TriangleFan
|
||||
};
|
||||
|
||||
void attachMaterial(uint idx, const TeMaterial &material);
|
||||
void boundingBox(TeVector3f32 &boxmin, TeVector3f32 boxmax);
|
||||
void checkArrays() {};
|
||||
void clearColors() { _colors.clear(); }
|
||||
TeColor color(uint idx) const { return _colors[idx]; }
|
||||
void copy(const TeMesh &other);
|
||||
void create();
|
||||
void defaultMaterial(const TeIntrusivePtr<Te3DTexture> &texture);
|
||||
void destroy();
|
||||
void facesPerMaterial(uint idx, unsigned short value);
|
||||
unsigned short facesPerMaterial(uint idx) const { return _faceCounts[idx]; }
|
||||
void forceMatrix(const TeMatrix4x4 &matrix);
|
||||
byte getFaceMaterial(uint idx);
|
||||
virtual uint32 getTexEnvMode() const = 0;
|
||||
virtual TeMesh::Mode getMode() const = 0;
|
||||
virtual void setMode(enum Mode mode) = 0;
|
||||
bool hasAlpha(uint idx);
|
||||
bool hasColor() const { return !_colors.empty(); }
|
||||
bool hasUvs() const { return !_uvs.empty(); }
|
||||
unsigned short index(uint num) const { return _indexes[num]; }
|
||||
TeMaterial *material(uint idx);
|
||||
const TeMaterial *material(uint idx) const;
|
||||
void materialIndex(uint idx, byte val);
|
||||
byte materialIndex(uint idx) const { return _materialIndexes[idx]; }
|
||||
void matrixIndex(uint num, unsigned short val);
|
||||
unsigned short matrixIndex(uint num) const { return _matricies[num]; }
|
||||
TeVector3f32 normal(uint idx) const;
|
||||
|
||||
void optimizeVerticies();
|
||||
void resizeUpdatedTables(uint newSize);
|
||||
|
||||
void setColor(const TeColor &col) override;
|
||||
void setColor(uint idx, const TeColor &col);
|
||||
void setConf(uint vertexCount, uint indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
|
||||
void setIndex(uint idx, uint val);
|
||||
void setNormal(uint idx, const TeVector3f32 &val);
|
||||
void setTextureUV(uint idx, const TeVector2f32 &val);
|
||||
void setVertex(uint idx, const TeVector3f32 &val);
|
||||
void sortFaces();
|
||||
|
||||
void update(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2);
|
||||
void update(TeIntrusivePtr<TeModelVertexAnimation> vertexanim);
|
||||
void updateTo(const Common::Array<TeMatrix4x4> *matricies1, const Common::Array<TeMatrix4x4> *matricies2,
|
||||
Common::Array<TeVector3f32> &verts, Common::Array<TeVector3f32> &normals);
|
||||
|
||||
TeVector2f32 textureUV(uint idx) const { return _uvs[idx]; }
|
||||
TeVector3f32 vertex(uint idx) const;
|
||||
|
||||
uint numIndexes() const { return _indexes.size(); }
|
||||
uint numVerticies() const { return _verticies.size(); }
|
||||
bool shouldDrawMaybe() const { return _shouldDraw; }
|
||||
|
||||
void setShouldDraw(bool val) { _shouldDraw = val; }
|
||||
virtual void setglTexEnvBlend() = 0;
|
||||
void setHasAlpha(bool val) { _hasAlpha = val; }
|
||||
|
||||
Common::Array<TeMaterial> &materials() { return _materials; }
|
||||
void setUpdatedVertex(uint idx, const TeVector3f32 &val) { _updatedVerticies[idx] = val; }
|
||||
void setUpdatedNormal(uint idx, const TeVector3f32 &val) { _updatedNormals[idx] = val; }
|
||||
|
||||
const TeVector3f32 &preUpdatedVertex(uint idx) const { return _verticies[idx]; }
|
||||
const TeVector3f32 &preUpdatedNormal(uint idx) const { return _normals[idx]; }
|
||||
|
||||
static TeMesh *makeInstance();
|
||||
|
||||
protected:
|
||||
Common::Array<unsigned char> _materialIndexes;
|
||||
Common::Array<TeVector3f32> _verticies;
|
||||
Common::Array<TeVector3f32> _normals;
|
||||
Common::Array<TeVector3f32> _updatedVerticies;
|
||||
Common::Array<TeVector3f32> _updatedNormals;
|
||||
Common::Array<TeVector2f32> _uvs;
|
||||
Common::Array<unsigned short> _indexes;
|
||||
Common::Array<unsigned short> _faceCounts;
|
||||
Common::Array<unsigned short> _matricies;
|
||||
Common::Array<TeColor> _colors;
|
||||
Common::Array<TeMaterial> _materials;
|
||||
|
||||
bool _matrixForced;
|
||||
TeMatrix4x4 _forcedMatrix;
|
||||
bool _hasAlpha;
|
||||
uint _initialMaterialIndexCount;
|
||||
bool _drawWires;
|
||||
bool _shouldDraw;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MESH_H
|
||||
262
engines/tetraedge/te/te_mesh_opengl.cpp
Normal file
262
engines/tetraedge/te/te_mesh_opengl.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/* 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 "graphics/opengl/system_headers.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
#include "tetraedge/te/te_light.h"
|
||||
#include "tetraedge/te/te_mesh_opengl.h"
|
||||
#include "tetraedge/te/te_material.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMeshOpenGL::TeMeshOpenGL() : _glMeshMode(GL_POINTS), _gltexEnvMode(GL_MODULATE) {
|
||||
}
|
||||
|
||||
void TeMeshOpenGL::draw() {
|
||||
if (!worldVisible())
|
||||
return;
|
||||
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->pushMatrix();
|
||||
if (_matrixForced)
|
||||
renderer->multiplyMatrix(_forcedMatrix);
|
||||
else
|
||||
renderer->multiplyMatrix(worldTransformationMatrix());
|
||||
|
||||
/*
|
||||
debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
|
||||
debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
|
||||
if (!_materials.empty())
|
||||
debug(" material %s", _materials[0].dump().c_str());
|
||||
debug(" position %s", position().dump().c_str());
|
||||
debug(" worldPos %s", worldPosition().dump().c_str());
|
||||
debug(" scale %s", scale().dump().c_str());
|
||||
debug(" worldScale %s", worldScale().dump().c_str());
|
||||
debug(" rotation %s", rotation().dump().c_str());
|
||||
debug(" worldRot %s", worldRotation().dump().c_str());
|
||||
*/
|
||||
|
||||
if (renderer->shadowMode() != TeRenderer::ShadowModeCreating) {
|
||||
if (_faceCounts.empty()) {
|
||||
if (hasAlpha(0) && _shouldDraw) {
|
||||
renderer->addTransparentMesh(*this, 0, 0, 0);
|
||||
renderer->popMatrix();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
assert(_faceCounts.size() == _materials.size());
|
||||
int totalFaceCount = 0;
|
||||
for (uint i = 0; i < _faceCounts.size(); i++) {
|
||||
if (!_faceCounts[i])
|
||||
continue;
|
||||
if (hasAlpha(i)) {
|
||||
renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
|
||||
}
|
||||
totalFaceCount += _faceCounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
renderer->pushMatrix();
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
|
||||
const Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
|
||||
const Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
if (!normals.empty())
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
if (!_colors.empty())
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(TeVector3f32), verticies.data());
|
||||
if (!normals.empty())
|
||||
glNormalPointer(GL_FLOAT, sizeof(TeVector3f32), normals.data());
|
||||
|
||||
if (!_uvs.empty() && renderer->shadowMode() != TeRenderer::ShadowModeDrawing)
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(TeVector2f32), _uvs.data());
|
||||
|
||||
if (!_colors.empty())
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(TeColor), _colors.data());
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _gltexEnvMode);
|
||||
if (renderer->scissorEnabled()) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
uint scissorx = renderer->scissorX();
|
||||
uint scissory = renderer->scissorY();
|
||||
uint scissorwidth = renderer->scissorWidth();
|
||||
uint scissorheight = renderer->scissorHeight();
|
||||
glScissor(scissorx, scissory, scissorwidth, scissorheight);
|
||||
}
|
||||
|
||||
if (_faceCounts.empty()) {
|
||||
if (!_materials.empty())
|
||||
renderer->applyMaterial(_materials[0]);
|
||||
|
||||
glDrawElements(_glMeshMode, _indexes.size(), GL_UNSIGNED_SHORT, _indexes.data());
|
||||
if (!_materials.empty()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
renderer->disableTexture();
|
||||
}
|
||||
} else {
|
||||
int totalFaceCount = 0;
|
||||
assert(_faceCounts.size() == _materials.size());
|
||||
for (uint i = 0; i < _materials.size(); i++) {
|
||||
if (!_faceCounts[i])
|
||||
continue;
|
||||
if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowModeCreating || !_shouldDraw) {
|
||||
renderer->applyMaterial(_materials[i]);
|
||||
glDrawElements(_glMeshMode, _faceCounts[i] * 3, GL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
renderer->disableTexture();
|
||||
}
|
||||
totalFaceCount += _faceCounts[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!renderer->scissorEnabled())
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
//renderer->setCurrentColor(renderer->currentColor()); // pointless?
|
||||
|
||||
if (_drawWires && !normals.empty()) {
|
||||
renderer->disableAllLights();
|
||||
error("TODO: Properly implement _drawWires case in TeMesh::draw");
|
||||
/*
|
||||
// TODO: Reimplement without glBegin/glEnd
|
||||
glBegin(GL_LINES);
|
||||
renderer->setCurrentColor(TeColor(255, 255, 255, 255));
|
||||
for (uint i = 0; i < verticies.size(); i++) {
|
||||
glVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
|
||||
glVertex3f(verticies[i].x() + normals[i].x(),
|
||||
verticies[i].y() + normals[i].y(),
|
||||
verticies[i].z() + normals[i].z());
|
||||
}
|
||||
glEnd();
|
||||
*/
|
||||
}
|
||||
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
renderer->popMatrix();
|
||||
renderer->popMatrix();
|
||||
}
|
||||
|
||||
TeMesh::Mode TeMeshOpenGL::getMode() const {
|
||||
// Do the reverse translation of setConf... why? I dunno.. the game does that..
|
||||
switch(_glMeshMode) {
|
||||
case GL_POINTS:
|
||||
return MeshMode_Points;
|
||||
case GL_LINES:
|
||||
return MeshMode_Lines;
|
||||
case GL_LINE_LOOP:
|
||||
return MeshMode_LineLoop;
|
||||
case GL_LINE_STRIP:
|
||||
return MeshMode_LineStrip;
|
||||
case GL_TRIANGLES:
|
||||
return MeshMode_Triangles;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
return MeshMode_TriangleStrip;
|
||||
case GL_TRIANGLE_FAN:
|
||||
return MeshMode_TriangleFan;
|
||||
default:
|
||||
return MeshMode_None;
|
||||
}
|
||||
}
|
||||
|
||||
void TeMeshOpenGL::setMode(enum Mode mode) {
|
||||
switch(mode) {
|
||||
case MeshMode_Points:
|
||||
_glMeshMode = GL_POINTS;
|
||||
break;
|
||||
case MeshMode_Lines:
|
||||
_glMeshMode = GL_LINES;
|
||||
break;
|
||||
case MeshMode_LineLoop:
|
||||
_glMeshMode = GL_LINE_LOOP;
|
||||
break;
|
||||
case MeshMode_LineStrip:
|
||||
_glMeshMode = GL_LINE_STRIP;
|
||||
break;
|
||||
case MeshMode_Triangles:
|
||||
_glMeshMode = GL_TRIANGLES;
|
||||
break;
|
||||
case MeshMode_TriangleStrip:
|
||||
_glMeshMode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
case MeshMode_TriangleFan:
|
||||
_glMeshMode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
default:
|
||||
error("Invalid mesh mode %d", (int)mode);
|
||||
}
|
||||
}
|
||||
|
||||
void TeMeshOpenGL::setglTexEnvBlend() {
|
||||
_gltexEnvMode = GL_BLEND;
|
||||
}
|
||||
|
||||
uint32 TeMeshOpenGL::getTexEnvMode() const {
|
||||
return _gltexEnvMode;
|
||||
}
|
||||
|
||||
void TeMeshOpenGL::setConf(uint vertexCount, uint indexCount, enum Mode mode, uint materialCount, uint materialIndexCount) {
|
||||
destroy();
|
||||
_initialMaterialIndexCount = materialIndexCount;
|
||||
_verticies.resize(vertexCount);
|
||||
_indexes.resize(indexCount);
|
||||
_materials.resize(materialCount);
|
||||
_matricies.resize(vertexCount);
|
||||
switch(mode) {
|
||||
case MeshMode_Points:
|
||||
_glMeshMode = GL_POINTS;
|
||||
break;
|
||||
case MeshMode_Lines:
|
||||
_glMeshMode = GL_LINES;
|
||||
break;
|
||||
case MeshMode_LineLoop:
|
||||
_glMeshMode = GL_LINE_LOOP;
|
||||
break;
|
||||
case MeshMode_LineStrip:
|
||||
_glMeshMode = GL_LINE_STRIP;
|
||||
break;
|
||||
case MeshMode_Triangles:
|
||||
_glMeshMode = GL_TRIANGLES;
|
||||
break;
|
||||
case MeshMode_TriangleStrip:
|
||||
_glMeshMode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
case MeshMode_TriangleFan:
|
||||
_glMeshMode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
default:
|
||||
error("Setting invalid mesh mode.");
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Tetraedge
|
||||
55
engines/tetraedge/te/te_mesh_opengl.h
Normal file
55
engines/tetraedge/te/te_mesh_opengl.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MESH_OPENGL_H
|
||||
#define TETRAEDGE_TE_TE_MESH_OPENGL_H
|
||||
|
||||
#if defined(USE_OPENGL_GAME)
|
||||
|
||||
#include "tetraedge/te/te_mesh.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeMeshOpenGL : public TeMesh {
|
||||
public:
|
||||
TeMeshOpenGL();
|
||||
|
||||
void copy(const TeMesh &other);
|
||||
void draw() override;
|
||||
TeMesh::Mode getMode() const override;
|
||||
void setMode(enum Mode mode) override;
|
||||
|
||||
void setConf(uint vertexCount, uint indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
|
||||
|
||||
void setglTexEnvBlend() override;
|
||||
uint32 getTexEnvMode() const override;
|
||||
|
||||
private:
|
||||
uint _glMeshMode;
|
||||
uint32 _gltexEnvMode;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_OPENGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MESH_H
|
||||
230
engines/tetraedge/te/te_mesh_tinygl.cpp
Normal file
230
engines/tetraedge/te/te_mesh_tinygl.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/* 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 "graphics/tinygl/tinygl.h"
|
||||
|
||||
#include "tetraedge/tetraedge.h"
|
||||
#include "tetraedge/te/te_renderer.h"
|
||||
#include "tetraedge/te/te_light.h"
|
||||
#include "tetraedge/te/te_mesh_tinygl.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
TeMeshTinyGL::TeMeshTinyGL() : _glMeshMode(TGL_POINTS), _gltexEnvMode(TGL_MODULATE) {
|
||||
}
|
||||
|
||||
void TeMeshTinyGL::draw() {
|
||||
if (!worldVisible())
|
||||
return;
|
||||
|
||||
TeRenderer *renderer = g_engine->getRenderer();
|
||||
renderer->pushMatrix();
|
||||
if (_matrixForced)
|
||||
renderer->multiplyMatrix(_forcedMatrix);
|
||||
else
|
||||
renderer->multiplyMatrix(worldTransformationMatrix());
|
||||
|
||||
/*
|
||||
debug("Draw mesh %p (%s, %d verts %d norms %d indexes %d materials %d updated)", this, name().empty() ? "no name" : name().c_str(), _verticies.size(), _normals.size(), _indexes.size(), _materials.size(), _updatedVerticies.size());
|
||||
debug(" renderMatrix %s", renderer->currentMatrix().toString().c_str());
|
||||
if (!_materials.empty())
|
||||
debug(" material %s", _materials[0].dump().c_str());
|
||||
debug(" position %s", position().dump().c_str());
|
||||
debug(" worldPos %s", worldPosition().dump().c_str());
|
||||
debug(" scale %s", scale().dump().c_str());
|
||||
debug(" worldScale %s", worldScale().dump().c_str());
|
||||
debug(" rotation %s", rotation().dump().c_str());
|
||||
debug(" worldRot %s", worldRotation().dump().c_str());
|
||||
*/
|
||||
|
||||
if (renderer->shadowMode() != TeRenderer::ShadowModeCreating) {
|
||||
if (_faceCounts.empty()) {
|
||||
if (hasAlpha(0) && _shouldDraw) {
|
||||
renderer->addTransparentMesh(*this, 0, 0, 0);
|
||||
renderer->popMatrix();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
assert(_faceCounts.size() == _materials.size());
|
||||
int totalFaceCount = 0;
|
||||
for (uint i = 0; i < _faceCounts.size(); i++) {
|
||||
if (!_faceCounts[i])
|
||||
continue;
|
||||
if (hasAlpha(i)) {
|
||||
renderer->addTransparentMesh(*this, totalFaceCount, _faceCounts[i], i);
|
||||
}
|
||||
totalFaceCount += _faceCounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Common::Array<TeVector3f32> &normals = (_updatedVerticies.empty() ? _normals : _updatedNormals);
|
||||
const Common::Array<TeVector3f32> &verticies = (_updatedVerticies.empty() ? _verticies : _updatedVerticies);
|
||||
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
renderer->pushMatrix();
|
||||
renderer->loadCurrentMatrixToGL();
|
||||
tglEnableClientState(TGL_VERTEX_ARRAY);
|
||||
if (!normals.empty())
|
||||
tglEnableClientState(TGL_NORMAL_ARRAY);
|
||||
|
||||
if (!_colors.empty())
|
||||
tglEnableClientState(TGL_COLOR_ARRAY);
|
||||
|
||||
tglVertexPointer(3, TGL_FLOAT, sizeof(TeVector3f32), verticies.data());
|
||||
if (!normals.empty())
|
||||
tglNormalPointer(TGL_FLOAT, sizeof(TeVector3f32), normals.data());
|
||||
|
||||
if (!_uvs.empty() && renderer->shadowMode() != TeRenderer::ShadowModeDrawing)
|
||||
tglTexCoordPointer(2, TGL_FLOAT, sizeof(TeVector2f32), _uvs.data());
|
||||
|
||||
if (!_colors.empty())
|
||||
tglColorPointer(4, TGL_UNSIGNED_BYTE, sizeof(TeColor), _colors.data());
|
||||
|
||||
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, _gltexEnvMode);
|
||||
if (renderer->scissorEnabled()) {
|
||||
tglEnable(TGL_SCISSOR_TEST);
|
||||
// TODO: Scissor not supported by TGL
|
||||
/*
|
||||
uint scissorx = renderer->scissorX();
|
||||
uint scissory = renderer->scissorY();
|
||||
uint scissorwidth = renderer->scissorWidth();
|
||||
uint scissorheight = renderer->scissorHeight();
|
||||
//tglScissor(scissorx, scissory, scissorwidth, scissorheight);
|
||||
*/
|
||||
}
|
||||
|
||||
if (_faceCounts.empty()) {
|
||||
if (!_materials.empty())
|
||||
renderer->applyMaterial(_materials[0]);
|
||||
|
||||
tglDrawElements(_glMeshMode, _indexes.size(), TGL_UNSIGNED_SHORT, _indexes.data());
|
||||
if (!_materials.empty()) {
|
||||
tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
|
||||
renderer->disableTexture();
|
||||
}
|
||||
} else {
|
||||
int totalFaceCount = 0;
|
||||
assert(_faceCounts.size() == _materials.size());
|
||||
for (uint i = 0; i < _materials.size(); i++) {
|
||||
if (!_faceCounts[i])
|
||||
continue;
|
||||
if (!hasAlpha(i) || renderer->shadowMode() == TeRenderer::ShadowModeCreating || !_shouldDraw) {
|
||||
renderer->applyMaterial(_materials[i]);
|
||||
tglDrawElements(_glMeshMode, _faceCounts[i] * 3, TGL_UNSIGNED_SHORT, _indexes.data() + totalFaceCount * 3);
|
||||
tglDisableClientState(TGL_TEXTURE_COORD_ARRAY);
|
||||
renderer->disableTexture();
|
||||
}
|
||||
totalFaceCount += _faceCounts[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!renderer->scissorEnabled())
|
||||
tglDisable(TGL_SCISSOR_TEST);
|
||||
|
||||
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE);
|
||||
tglDisableClientState(TGL_VERTEX_ARRAY);
|
||||
tglDisableClientState(TGL_NORMAL_ARRAY);
|
||||
tglDisableClientState(TGL_COLOR_ARRAY);
|
||||
|
||||
//renderer->setCurrentColor(renderer->currentColor()); // pointless?
|
||||
|
||||
if (_drawWires && !normals.empty()) {
|
||||
renderer->disableAllLights();
|
||||
//error("TODO: Properly implement _drawWires case in TeMesh::draw");
|
||||
///*
|
||||
// TODO: Reimplement without glBegin/glEnd
|
||||
tglBegin(TGL_LINES);
|
||||
renderer->setCurrentColor(TeColor(255, 255, 255, 255));
|
||||
for (uint i = 0; i < verticies.size(); i++) {
|
||||
tglVertex3f(verticies[i].x(), verticies[i].y(), verticies[i].z());
|
||||
tglVertex3f(verticies[i].x() + normals[i].x(),
|
||||
verticies[i].y() + normals[i].y(),
|
||||
verticies[i].z() + normals[i].z());
|
||||
}
|
||||
tglEnd();
|
||||
//*/
|
||||
}
|
||||
|
||||
renderer->setMatrixMode(TeRenderer::MM_GL_MODELVIEW);
|
||||
renderer->popMatrix();
|
||||
renderer->popMatrix();
|
||||
}
|
||||
|
||||
TeMesh::Mode TeMeshTinyGL::getMode() const {
|
||||
switch(_glMeshMode) {
|
||||
case TGL_POINTS:
|
||||
return MeshMode_Points;
|
||||
case TGL_LINES:
|
||||
return MeshMode_Lines;
|
||||
case TGL_LINE_LOOP:
|
||||
return MeshMode_LineLoop;
|
||||
case TGL_LINE_STRIP:
|
||||
return MeshMode_LineStrip;
|
||||
case TGL_TRIANGLES:
|
||||
return MeshMode_Triangles;
|
||||
case TGL_TRIANGLE_STRIP:
|
||||
return MeshMode_TriangleStrip;
|
||||
case TGL_TRIANGLE_FAN:
|
||||
return MeshMode_TriangleFan;
|
||||
default:
|
||||
return MeshMode_None;
|
||||
}
|
||||
}
|
||||
|
||||
void TeMeshTinyGL::setMode(enum Mode mode) {
|
||||
switch(mode) {
|
||||
case MeshMode_Points:
|
||||
_glMeshMode = TGL_POINTS;
|
||||
break;
|
||||
case MeshMode_Lines:
|
||||
_glMeshMode = TGL_LINES;
|
||||
break;
|
||||
case MeshMode_LineLoop:
|
||||
_glMeshMode = TGL_LINE_LOOP;
|
||||
break;
|
||||
case MeshMode_LineStrip:
|
||||
_glMeshMode = TGL_LINE_STRIP;
|
||||
break;
|
||||
case MeshMode_Triangles:
|
||||
_glMeshMode = TGL_TRIANGLES;
|
||||
break;
|
||||
case MeshMode_TriangleStrip:
|
||||
_glMeshMode = TGL_TRIANGLE_STRIP;
|
||||
break;
|
||||
case MeshMode_TriangleFan:
|
||||
_glMeshMode = TGL_TRIANGLE_FAN;
|
||||
break;
|
||||
default:
|
||||
error("Invalid mesh mode %d", (int)mode);
|
||||
}
|
||||
}
|
||||
|
||||
void TeMeshTinyGL::setglTexEnvBlend() {
|
||||
_gltexEnvMode = TGL_BLEND;
|
||||
}
|
||||
|
||||
uint32 TeMeshTinyGL::getTexEnvMode() const {
|
||||
return _gltexEnvMode;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Tetraedge
|
||||
54
engines/tetraedge/te/te_mesh_tinygl.h
Normal file
54
engines/tetraedge/te/te_mesh_tinygl.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TETRAEDGE_TE_TE_MESH_TINYGL_H
|
||||
#define TETRAEDGE_TE_TE_MESH_TINYGL_H
|
||||
|
||||
#if defined(USE_TINYGL)
|
||||
|
||||
#include "tetraedge/te/te_mesh.h"
|
||||
|
||||
namespace Tetraedge {
|
||||
|
||||
class TeMeshTinyGL : public TeMesh {
|
||||
public:
|
||||
TeMeshTinyGL();
|
||||
|
||||
void copy(const TeMesh &other);
|
||||
void draw() override;
|
||||
TeMesh::Mode getMode() const override;
|
||||
void setMode(enum Mode mode) override;
|
||||
|
||||
void setConf(uint vertexCount, uint indexCount, enum Mode mode, uint materialCount, uint materialIndexCount);
|
||||
|
||||
void setglTexEnvBlend() override;
|
||||
uint32 getTexEnvMode() const override;
|
||||
|
||||
private:
|
||||
uint _glMeshMode;
|
||||
uint32 _gltexEnvMode;
|
||||
};
|
||||
|
||||
} // end namespace Tetraedge
|
||||
|
||||
#endif // USE_TINYGL
|
||||
|
||||
#endif // TETRAEDGE_TE_TE_MESH_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user