841 lines
25 KiB
C++
841 lines
25 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 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/>.
|
|
*
|
|
*/
|
|
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
|
|
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
|
|
|
|
#include "watchmaker/3d/render/opengl_3d.h"
|
|
#include "watchmaker/windows_hacks.h"
|
|
#include "watchmaker/t3d.h"
|
|
#include "watchmaker/3d/math/Matrix4x4.h"
|
|
#include "watchmaker/3d/render/opengl_renderer.h"
|
|
#include "watchmaker/ll/ll_system.h"
|
|
#include "watchmaker/3d/render/opengl_2d.h"
|
|
#include "watchmaker/renderer.h"
|
|
#include "watchmaker/globvar.h"
|
|
#include "watchmaker/work_dirs.h"
|
|
|
|
#ifdef USE_OPENGL_GAME
|
|
|
|
#include "graphics/opengl/system_headers.h"
|
|
#include "watchmaker/3d/render/shadows.h"
|
|
#include "watchmaker/file_utils.h"
|
|
#include "watchmaker/tga_util.h"
|
|
|
|
#define MAXTEXTURES 2000
|
|
|
|
namespace Watchmaker {
|
|
|
|
#define T3D_FASTFILE (1<<23) // fastfile
|
|
|
|
// Tecture formats
|
|
int NumAvailableFormats = 0;
|
|
gAvailFormat AvailableFormats[50];
|
|
gAvailFormat *gCurrentFormat;
|
|
|
|
// Point VB
|
|
int g_lpD3DPointsBuffer;
|
|
unsigned int gNumPointsBuffer;
|
|
|
|
// Tecture list
|
|
gTexture gTextureList[MAXTEXTURES];
|
|
unsigned int gNumTextureList = 0;
|
|
|
|
// {ines array
|
|
uint16 gLinesArray[MAX_LINES];
|
|
unsigned int gNumLinesArray = 0;
|
|
|
|
// screen traingles
|
|
Vertex gTriangles[100];
|
|
unsigned int gNumTrianglesArray = 0;
|
|
|
|
// camera info
|
|
Matrix4x4 rWorldMatrix;
|
|
Matrix4x4 rProjectionMatrix;
|
|
float gNearPlane, gFarPlane;
|
|
|
|
// saved matrix
|
|
Matrix4x4 rLinesViewMatrix;
|
|
|
|
// user matrix
|
|
#define MAX_USER_VIEW_MATRICES 2000 // TODO: Why do we get so many of them?
|
|
Matrix4x4 rUserViewMatrix[MAX_USER_VIEW_MATRICES];
|
|
unsigned int rNumUserViewMatrices = 0;
|
|
|
|
// user vertext buffer
|
|
void *g_lpD3DUserVertexBuffer = nullptr;
|
|
unsigned int g_dwD3DUserVertexBufferCounter = 0;
|
|
|
|
//***********************************************************************************************
|
|
uint16 *rGetLinesArrayPtr() {
|
|
return &gLinesArray[gNumLinesArray];
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void rAddLinesArray() {
|
|
gNumLinesArray++;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void *rLockPointArray() {
|
|
warning("TODO: Implement rLockPointArray");
|
|
#if 0
|
|
HRESULT hResult;
|
|
LPVOID v;
|
|
|
|
if ((hResult = g_lpD3DPointsBuffer->Lock(DDLOCK_SURFACEMEMORYPTR, &v, NULL)) != D3D_OK) {
|
|
char str[255];
|
|
GetDDErrorString(hResult, str, 1);
|
|
DebugLogFile("rLockPointArray: Unable to lock points vertexbuffer:\r\n%s", str);
|
|
return NULL;
|
|
}
|
|
|
|
gVertex *gv = (gVertex *)v;
|
|
return &gv[rGetNumPointArray()];
|
|
#endif
|
|
return nullptr;
|
|
}
|
|
|
|
void rAddTrianglesArray(float x, float y, int r, int g, int b, int a) {
|
|
gTriangles[gNumTrianglesArray].sx = x;
|
|
gTriangles[gNumTrianglesArray].sy = y;
|
|
gTriangles[gNumTrianglesArray].sz = 1.0f;
|
|
gTriangles[gNumTrianglesArray].color = RGBA_MAKE(r, g, b, a);
|
|
gNumTrianglesArray++;
|
|
}
|
|
|
|
|
|
//***********************************************************************************************
|
|
void rUnlockPointArray() {
|
|
warning("TODO: Implement rUnlockPointArray");
|
|
#if 0
|
|
g_lpD3DPointsBuffer->Unlock();
|
|
#endif
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
unsigned int rGetNumPointArray() {
|
|
return gNumPointsBuffer;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void rAddPointArray() {
|
|
gNumPointsBuffer++;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
bool rSetViewMatrix(float _00, float _01, float _02,
|
|
float _03, float _04, float _05,
|
|
float _06, float _07, float _08,
|
|
float _tx, float _ty, float _tz) {
|
|
Matrix4x4 rViewMatrix;
|
|
rViewMatrix.setIdentity();
|
|
|
|
rViewMatrix.setValue(1, 1, _00);
|
|
rViewMatrix.setValue(1, 2, _01);
|
|
rViewMatrix.setValue(1, 3, _02);
|
|
rViewMatrix.setValue(1, 4, _tx);
|
|
|
|
rViewMatrix.setValue(2, 1, _03);
|
|
rViewMatrix.setValue(2, 2, _04);
|
|
rViewMatrix.setValue(2, 3, _05);
|
|
rViewMatrix.setValue(2, 4, _ty);
|
|
|
|
rViewMatrix.setValue(3, 1, -_06);
|
|
rViewMatrix.setValue(3, 2, -_07);
|
|
rViewMatrix.setValue(3, 3, -_08);
|
|
rViewMatrix.setValue(3, 4, _tz);
|
|
|
|
rViewMatrix.setValue(4, 1, 0.0f);
|
|
rViewMatrix.setValue(4, 2, 0.0f);
|
|
rViewMatrix.setValue(4, 3, 0.0f);
|
|
rViewMatrix.setValue(4, 4, 1.0f);
|
|
|
|
g_renderer->setTransformMatrix(TransformMatrix::VIEW, rViewMatrix);
|
|
|
|
return true;
|
|
}
|
|
|
|
void rSetViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
|
|
rSetViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
|
|
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
|
|
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
|
|
translation.x, translation.y, -translation.z);
|
|
}
|
|
|
|
void rSaveViewMatrix() {
|
|
g_renderer->pushModelView();
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void rRestoreViewMatrix() {
|
|
g_renderer->popModelView();
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
bool rBuildLinesViewMatrix(float _00, float _01, float _02,
|
|
float _03, float _04, float _05,
|
|
float _06, float _07, float _08,
|
|
float _tx, float _ty, float _tz) {
|
|
rLinesViewMatrix.setIdentity();
|
|
|
|
rLinesViewMatrix.setValue(1, 1, _00);
|
|
rLinesViewMatrix.setValue(1, 2, _01);
|
|
rLinesViewMatrix.setValue(1, 3, _02);
|
|
rLinesViewMatrix.setValue(1, 4, _tx);
|
|
|
|
rLinesViewMatrix.setValue(2, 1, _03);
|
|
rLinesViewMatrix.setValue(2, 2, _04);
|
|
rLinesViewMatrix.setValue(2, 3, _05);
|
|
rLinesViewMatrix.setValue(2, 4, _ty);
|
|
|
|
rLinesViewMatrix.setValue(3, 1, -_06);
|
|
rLinesViewMatrix.setValue(3, 2, -_07);
|
|
rLinesViewMatrix.setValue(3, 3, -_08);
|
|
rLinesViewMatrix.setValue(3, 4, -_tz);
|
|
|
|
rLinesViewMatrix.setValue(4, 1, 0.0f);
|
|
rLinesViewMatrix.setValue(4, 2, 0.0f);
|
|
rLinesViewMatrix.setValue(4, 3, 0.0f);
|
|
rLinesViewMatrix.setValue(4, 4, 1.0f);
|
|
|
|
return true;
|
|
}
|
|
|
|
int rBuildLinesViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
|
|
return rBuildLinesViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
|
|
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
|
|
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
|
|
translation.x, translation.y, translation.z);
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
int rAddUserViewMatrix(float _00, float _01, float _02,
|
|
float _03, float _04, float _05,
|
|
float _06, float _07, float _08,
|
|
float _tx, float _ty, float _tz) {
|
|
Matrix4x4 rTempViewMatrix;
|
|
Matrix4x4 *um;
|
|
unsigned int i;
|
|
|
|
rTempViewMatrix.setIdentity();
|
|
|
|
rTempViewMatrix.setValue(1, 1, _00);
|
|
rTempViewMatrix.setValue(1, 2, _01);
|
|
rTempViewMatrix.setValue(1, 3, _02);
|
|
rTempViewMatrix.setValue(1, 4, _tx);
|
|
|
|
rTempViewMatrix.setValue(2, 1, _03);
|
|
rTempViewMatrix.setValue(2, 2, _04);
|
|
rTempViewMatrix.setValue(2, 3, _05);
|
|
rTempViewMatrix.setValue(2, 4, _ty);
|
|
|
|
rTempViewMatrix.setValue(3, 1, -_06);
|
|
rTempViewMatrix.setValue(3, 2, -_07);
|
|
rTempViewMatrix.setValue(3, 3, -_08);
|
|
rTempViewMatrix.setValue(3, 4, -_tz);
|
|
|
|
rTempViewMatrix.setValue(4, 1, 0.0f);
|
|
rTempViewMatrix.setValue(4, 2, 0.0f);
|
|
rTempViewMatrix.setValue(4, 3, 0.0f);
|
|
rTempViewMatrix.setValue(4, 4, 1.0f);
|
|
|
|
auto &tmp = rTempViewMatrix;
|
|
//warning("Adding: ");
|
|
//tmp.print();
|
|
for (i = 0, um = &rUserViewMatrix[0]; i < rNumUserViewMatrices; i++, um++) {
|
|
//warning("Comparing %d", i);
|
|
//um->print();
|
|
if (*um == tmp) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
if (i >= MAX_USER_VIEW_MATRICES) {
|
|
DebugLogFile("Too many UserViewMatrix %d (MAX is %d)\n", i, MAX_USER_VIEW_MATRICES);
|
|
return -1;
|
|
}
|
|
|
|
*um = tmp;
|
|
|
|
rNumUserViewMatrices ++;
|
|
return rNumUserViewMatrices - 1;
|
|
}
|
|
|
|
int rAddUserViewMatrix(const t3dM3X3F &viewMatrix, const t3dV3F &translation) {
|
|
return rAddUserViewMatrix(viewMatrix.M[0], viewMatrix.M[1], viewMatrix.M[2],
|
|
viewMatrix.M[3], viewMatrix.M[4], viewMatrix.M[5],
|
|
viewMatrix.M[6], viewMatrix.M[7], viewMatrix.M[8],
|
|
translation.x, translation.y, translation.z);
|
|
}
|
|
|
|
void rResetPipeline() {
|
|
gNumLinesArray = 0;
|
|
gNumPointsBuffer = 0;
|
|
gNumShadowBoxesList = 0;
|
|
rNumUserViewMatrices = 0;
|
|
g_dwD3DUserVertexBufferCounter = 0;
|
|
return;
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
void *rGetUserVertexBuffer() {
|
|
return g_lpD3DUserVertexBuffer;
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
unsigned int rGetUserVertexBufferCounter() {
|
|
return g_dwD3DUserVertexBufferCounter;
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
void rSetUserVertexBufferCounter(unsigned int uvbc) {
|
|
g_dwD3DUserVertexBufferCounter = uvbc;
|
|
}
|
|
|
|
gVertex *rLockVertexPtr(void *vb, int flags) {
|
|
warning("TODO: Implement rLockVertexPtr");
|
|
#if 0
|
|
LPVOID v;
|
|
DWORD dim, lock_flags;
|
|
HRESULT hResult;
|
|
|
|
LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuffer1 = (LPDIRECT3DVERTEXBUFFER7)vb;
|
|
|
|
lock_flags = DDLOCK_SURFACEMEMORYPTR;
|
|
if (flags & rVBLOCK_READONLY)
|
|
lock_flags |= DDLOCK_READONLY;
|
|
else if (flags & rVBLOCK_WRITEONLY)
|
|
lock_flags |= DDLOCK_WRITEONLY;
|
|
if (flags & rVBLOCK_NOSYSLOCK)
|
|
lock_flags |= DDLOCK_NOSYSLOCK;
|
|
|
|
if ((hResult = lpD3DVertexBuffer1->Lock(lock_flags, &v, &dim)) != D3D_OK) {
|
|
char str[255];
|
|
GetDDErrorString(hResult, str, 1);
|
|
DebugLogFile("Unable to lock vertexbuffer:\r\n%s", str);
|
|
return NULL;
|
|
}
|
|
return (gVertex *)v;
|
|
#endif
|
|
return nullptr;
|
|
}
|
|
|
|
Graphics::Surface *gCreateSurface(int width, int height, void *ptr) {
|
|
auto surface = new Graphics::Surface();
|
|
surface->w = width;
|
|
surface->h = height;
|
|
surface->pitch = width * 4; // TODO
|
|
surface->setPixels(ptr);
|
|
return surface;
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
bool rUnlockVertexPtr(void *vb) {
|
|
warning("Implement rUnlockVertexPtr");
|
|
#if 0
|
|
LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuffer1 = (LPDIRECT3DVERTEXBUFFER7)vb;
|
|
|
|
if (lpD3DVertexBuffer1->Unlock() != D3D_OK) {
|
|
DebugLogFile("VertexBuffer Unlock error");
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//***********************************************************************************************
|
|
void rSetLinesViewMatrix() {
|
|
g_renderer->setTransformMatrix(TransformMatrix::VIEW, rLinesViewMatrix);
|
|
}
|
|
|
|
//***********************************************************************************************
|
|
void rSetUserViewMatrix(int num) {
|
|
auto &matrix = rUserViewMatrix[num];
|
|
|
|
g_renderer->setTransformMatrix(TransformMatrix::VIEW, matrix);
|
|
}
|
|
|
|
|
|
//*********************************************************************************************
|
|
unsigned int gGetTextureListPosition() {
|
|
unsigned int pos = 1;
|
|
|
|
while (!gTextureList[pos].isEmpty()) { // TODO: Do we need the surface?
|
|
pos++;
|
|
}
|
|
|
|
if (pos > MAXTEXTURES)
|
|
return 0;
|
|
|
|
if (pos > gNumTextureList)
|
|
gNumTextureList = pos;
|
|
|
|
return pos;
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
void gBuildAlternateName(char *AltName, const char *Name) {
|
|
int len, i, j;
|
|
|
|
if (!Name || !AltName) return;
|
|
|
|
len = strlen(Name);
|
|
memset(AltName, 0, len + 4);
|
|
memcpy(AltName, Name, len);
|
|
|
|
for (i = len - 1; i >= 0; i--) {
|
|
if ((AltName[i] == '.') && (i < (len - 3))) {
|
|
AltName[i + 1] = 'd';
|
|
AltName[i + 2] = 'd';
|
|
AltName[i + 3] = 's';
|
|
}
|
|
if (AltName[i] == '\\' || AltName[i] == '/') {
|
|
for (j = len; j >= i; j--)
|
|
AltName[j + 3] = AltName[j];
|
|
|
|
AltName[i + 0] = 'D';
|
|
AltName[i + 1] = 'D';
|
|
AltName[i + 2] = 'S';
|
|
break;
|
|
}
|
|
}
|
|
|
|
//warning("Build alternate name %s -> %s", Name, AltName);
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
void gBuildAlternateName(char *AltName, char *Name) {
|
|
int len, i, j;
|
|
|
|
if (!Name || !AltName) return;
|
|
|
|
len = strlen(Name);
|
|
memset(AltName, 0, len + 4);
|
|
memcpy(AltName, Name, len);
|
|
|
|
for (i = len - 1; i >= 0; i--) {
|
|
if ((AltName[i] == '.') && (i < (len - 3))) {
|
|
AltName[i + 1] = 'd';
|
|
AltName[i + 2] = 'd';
|
|
AltName[i + 3] = 's';
|
|
}
|
|
if (AltName[i] == '\\') {
|
|
for (j = len; j >= i; j--)
|
|
AltName[j + 3] = AltName[j];
|
|
|
|
AltName[i + 0] = 'D';
|
|
AltName[i + 1] = 'D';
|
|
AltName[i + 2] = 'S';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
gTexture *gUserTexture(Texture *texture, unsigned int dimx, unsigned int dimy) {
|
|
gTexture *Texture;
|
|
int pos;
|
|
//DDSURFACEDESC2 DDSurfDesc;
|
|
|
|
pos = gGetTextureListPosition();
|
|
if (pos == 0) {
|
|
DebugLogFile("gUserTexture: Can't create more textures");
|
|
return nullptr;
|
|
}
|
|
Texture = &gTextureList[pos];
|
|
*Texture = gTexture();
|
|
Texture->Flags = CurLoaderFlags;
|
|
|
|
{
|
|
#if 0
|
|
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
|
|
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
|
|
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
|
if (gRenderFlags & gAGPSUPPORTED) {
|
|
//Alloc texture in AGP
|
|
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
|
|
DDSCAPS_TEXTURE;
|
|
} else {
|
|
//No AGP support; alloc in sysmem
|
|
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
}
|
|
#endif
|
|
if (dimx > 8) {
|
|
if (dimx > 16) {
|
|
if (dimx > 32) {
|
|
if (dimx > 64) {
|
|
if (dimx > 128) {
|
|
dimx = 256;
|
|
} else {
|
|
dimx = 128;
|
|
}
|
|
} else {
|
|
dimx = 64;
|
|
}
|
|
} else {
|
|
dimx = 32;
|
|
}
|
|
} else {
|
|
dimx = 16;
|
|
}
|
|
}
|
|
if (dimy > 8) {
|
|
if (dimy > 16) {
|
|
if (dimy > 32) {
|
|
if (dimy > 64) {
|
|
if (dimy > 128) {
|
|
dimy = 256;
|
|
} else {
|
|
dimy = 128;
|
|
}
|
|
} else {
|
|
dimy = 64;
|
|
}
|
|
} else {
|
|
dimy = 32;
|
|
}
|
|
} else {
|
|
dimy = 16;
|
|
}
|
|
}
|
|
#if 0
|
|
DDSurfDesc.dwWidth = dimx;
|
|
DDSurfDesc.dwHeight = dimy;
|
|
|
|
if (!(Texture->lpDDSurface = gCreateSurface(&DDSurfDesc, Texture->lpDDSurface))) {
|
|
DebugLogFile("gCreateSurface FAILED: Can't create surface");
|
|
return NULL;
|
|
}
|
|
strcpy(Texture->Name, "UserTexture");
|
|
gClear(Texture->lpDDSurface, 0, 0, dimx, dimy, 0, 0, 0);
|
|
#endif
|
|
Texture->ID = pos;
|
|
|
|
Texture->DimX = dimx;
|
|
Texture->DimY = dimy;
|
|
#if 0
|
|
DDCOLORKEY ddck;
|
|
ddck.dwColorSpaceLowValue = 0;
|
|
ddck.dwColorSpaceHighValue = 0;
|
|
Texture->lpDDSurface->SetColorKey(DDCKEY_SRCBLT, &ddck);
|
|
#endif
|
|
}
|
|
|
|
Texture->_texture = texture;
|
|
return Texture;
|
|
}
|
|
|
|
class SurfaceBackedTextureData : public TextureData {
|
|
bool _owned = true;
|
|
public:
|
|
Graphics::Surface *_surface;
|
|
SurfaceBackedTextureData(Graphics::Surface *surface, bool owned = true) : TextureData(DxtCompression::UNCOMPRESSED), _surface(surface), _owned(owned) {}
|
|
~SurfaceBackedTextureData() override {
|
|
if (_owned) {
|
|
_surface->free();
|
|
delete _surface;
|
|
}
|
|
}
|
|
int getWidth() const override {
|
|
return _surface->w;
|
|
}
|
|
int getHeight() const override {
|
|
return _surface->h;
|
|
}
|
|
int getDataSize() const override {
|
|
return _surface->w * _surface->h * _surface->format.bytesPerPixel;
|
|
}
|
|
const void *getData() const override {
|
|
return _surface->getPixels();
|
|
}
|
|
};
|
|
|
|
Common::SharedPtr<TextureData> createTextureFromSurface(Graphics::Surface &surface, int texFormat) {
|
|
return Common::SharedPtr<TextureData>(new SurfaceBackedTextureData(&surface, false));
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
gTexture *gLoadTexture(WorkDirs &workDirs, const char *TextName, unsigned int _LoaderFlags) {
|
|
//bool bAlpha = FALSE
|
|
bool bUseAlternate = FALSE;
|
|
gTexture *texture = nullptr;
|
|
int32 pos = 0;
|
|
char AlternateName[500] {};
|
|
uint32 date1 = 0, date2 = 0, time1 = 0, time2 = 0;
|
|
//uint32 magic,retv;
|
|
unsigned long dwWidth = 0, dwHeight = 0;
|
|
//DDSURFACEDESC2 DDSurfDesc;
|
|
//Graphics::Surface *lpSSource = nullptr;
|
|
|
|
if (!TextName) return nullptr;
|
|
//lpSSource = nullptr;
|
|
|
|
//warning("gLoadTexture(%s)", TextName);
|
|
// Check if already loaded
|
|
for (uint32 i = 0; i < gNumTextureList; i++) {
|
|
if (gTextureList[i].name.equalsIgnoreCase(TextName)) {
|
|
//Texture already loaded; just assign pointers
|
|
texture = &gTextureList[i];
|
|
texture->ID = i;
|
|
return texture;
|
|
}
|
|
}
|
|
|
|
/* VERSIONE ORIGINALE by FAB
|
|
gBuildAlternateName( AlternateName, TextName );
|
|
if( ( CurLoaderFlags & T3D_FASTFILE ) || ( !t3dGetFileDate( &date1, &time1, TextName ) ) )
|
|
bUseAlternate = TRUE;
|
|
if( !t3dGetFileDate( &date2, &time2, AlternateName ) )
|
|
{
|
|
if( bUseAlternate == TRUE )
|
|
{
|
|
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s and alternate %s.\n", TextName, AlternateName );
|
|
return NULL;
|
|
}
|
|
}
|
|
else if( bUseAlternate == FALSE )
|
|
{
|
|
if( ( date2 > date1 ) || ( ( date2 == date1 ) && ( time2 >= time1 ) ) )
|
|
bUseAlternate = TRUE;
|
|
}
|
|
*/
|
|
|
|
gBuildAlternateName(AlternateName, TextName);
|
|
|
|
if (!t3dGetFileDate(&date1, &time1, TextName)) // if it doesn't find the .tga texture, try the dds
|
|
bUseAlternate = TRUE;
|
|
|
|
if (!t3dGetFileDate(&date2, &time2, AlternateName)) { //se non trova la texture .dds
|
|
if (bUseAlternate == TRUE) { // does not find the .dds texture and furthermore the .tga does not exist
|
|
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s and alternate %s.\n", TextName, AlternateName);
|
|
return nullptr;
|
|
}
|
|
} else if (bUseAlternate == FALSE) { // if there is the .dds and there is also the .tga see which is newer
|
|
if ((date2 > date1) || ((date2 == date1) && (time2 >= time1)))
|
|
bUseAlternate = TRUE;
|
|
}
|
|
|
|
|
|
if ((pos = gGetTextureListPosition()) == 0) {
|
|
DebugLogFile("gLoadTexture: Can't create more textures");
|
|
return nullptr;
|
|
}
|
|
texture = &gTextureList[pos];
|
|
*texture = gTexture();
|
|
texture->_texture = createGLTexture();
|
|
|
|
if (bUseAlternate) {
|
|
auto stream = workDirs.resolveFile(AlternateName);
|
|
if (!stream) {
|
|
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s.\n", AlternateName);
|
|
return nullptr;
|
|
}
|
|
auto ddsTextureData = loadDdsTexture(*stream);
|
|
texture->_texture->assignData(*ddsTextureData);
|
|
dwWidth = ddsTextureData->getWidth();
|
|
dwHeight = ddsTextureData->getHeight();
|
|
//lpSSource = nullptr;
|
|
#if 0
|
|
if (gRenderFlags & gDXT1SUPPORTED) {
|
|
/* if( gRenderFlags & gAGPSUPPORTED )
|
|
{ // Alloc texture in AGP
|
|
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE;
|
|
}
|
|
else
|
|
*/ { //No AGP support; alloc in sysmem
|
|
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
}
|
|
lpSSource = Texture->lpDDSurface;
|
|
} else
|
|
DDSurfDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
|
if (!(lpSSource = gCreateSurface(&DDSurfDesc, lpSSource))) {
|
|
DebugLogFile("gLoadTexture: gCreateSurface FAILED: Can't create surface DDS");
|
|
return NULL;
|
|
}
|
|
|
|
if ((lpSSource->Lock(NULL, &DDSurfDesc, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL))) { // Lock and fill with the dds
|
|
DebugLogFile("gLoadTexture: Can't lock surface DDS");
|
|
return NULL;
|
|
}
|
|
|
|
t3dReadData(DDSurfDesc.lpSurface, DDSurfDesc.dwLinearSize);
|
|
|
|
if ((lpSSource->Unlock(NULL))) {
|
|
DebugLogFile("gLoadTexture: Can't unlock surface DDS");
|
|
return NULL;
|
|
}
|
|
#endif
|
|
stream = nullptr;
|
|
} else { // TGA
|
|
auto stream = workDirs.resolveFile(TextName);
|
|
auto image = ReadTgaImage(TextName, *stream, Graphics::PixelFormat::createFormatRGBA32(), 0); // TODO Flags
|
|
SurfaceBackedTextureData texData(image);
|
|
|
|
texture->_texture->assignData(texData);
|
|
#if 0
|
|
//warning("TODO: Handle TGA");
|
|
if (!t3dOpenFile(TextName)) {
|
|
DebugLogFile("gAddMaterial:gLoadTexture: Cannot find %s.\n", TextName);
|
|
return NULL;
|
|
}
|
|
// Parse the PPM header
|
|
if (!loadTGAHeader(&dwWidth, &dwHeight)) {
|
|
t3dCloseFile();
|
|
DebugLogFile("gAddMaterial: gLoadTexture: Could not load or parse TGA header in %s.\n", TextName);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
}
|
|
#if 0 // Replaced by createTextureFromSurface
|
|
if (!(gRenderFlags & gDXT1SUPPORTED) || (bUseAlternate == FALSE)) {
|
|
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
|
|
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
|
|
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
|
/* if (gRenderFlags&gAGPSUPPORTED)
|
|
{ //Alloc texture in AGP
|
|
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
|
|
DDSCAPS_TEXTURE;
|
|
}
|
|
else
|
|
*/ { //No AGP support; alloc in sysmem
|
|
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
}
|
|
DDSurfDesc.dwWidth = dwWidth;
|
|
DDSurfDesc.dwHeight = dwHeight;
|
|
if (!(Texture->lpDDSurface = gCreateSurface(&DDSurfDesc, Texture->lpDDSurface))) {
|
|
DebugLogFile("gLoadTexture: gCreateSurface FAILED: Can't create surface");
|
|
return NULL;
|
|
}
|
|
}
|
|
#endif
|
|
texture->name = TextName;
|
|
|
|
if (bUseAlternate) {
|
|
#if 0
|
|
// DebugFile( "Carico |%s|", AlternateName );
|
|
if (!(gRenderFlags & gDXT1SUPPORTED)) {
|
|
if (Texture->lpDDSurface->Blt(NULL, lpSSource, NULL, DDBLT_WAIT, NULL) != DD_OK) {
|
|
DebugLogFile("gLoadTexture: Can't Blit DDS texture");
|
|
return NULL;
|
|
}
|
|
lpSSource->Release();
|
|
} else
|
|
Texture->lpDDSurface = lpSSource;
|
|
#endif
|
|
} else {
|
|
#if 0
|
|
// DebugFile( "Carico |%s|", TextName );
|
|
Texture->lpDDSurface->Lock(NULL, &DDSurfDesc, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); //Lock and fill with the tga
|
|
if (gCurrentFormat->abits)
|
|
bAlpha = TRUE;
|
|
|
|
if (!ReadTgaImage(TextName, &DDSurfDesc, bAlpha)) {
|
|
DebugLogFile("gLoadTexture: Error reading TGA file");
|
|
return NULL;
|
|
}
|
|
Texture->lpDDSurface->Unlock(NULL);
|
|
#endif
|
|
}
|
|
texture->RealDimX = dwWidth;
|
|
texture->RealDimY = dwHeight;
|
|
|
|
if (_LoaderFlags & rSURFACEHALF) {
|
|
warning("Half-res loading not implemented");
|
|
#if 0
|
|
LPDIRECTDRAWSURFACE7 surf;
|
|
HRESULT err;
|
|
|
|
dwWidth /= 2;
|
|
dwHeight /= 2;
|
|
|
|
memset(&DDSurfDesc, 0, sizeof(DDSURFACEDESC2));
|
|
memcpy(&DDSurfDesc.ddpfPixelFormat, &gCurrentFormat->SurfaceDesc, sizeof(DDPIXELFORMAT));
|
|
DDSurfDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
|
/* if (gRenderFlags&gAGPSUPPORTED)
|
|
{ //Alloc texture in AGP
|
|
DDSurfDesc.ddsCaps.dwCaps= DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY |
|
|
DDSCAPS_TEXTURE;
|
|
}
|
|
else
|
|
*/ { //No AGP support; alloc in sysmem
|
|
DDSurfDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
DDSurfDesc.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
}
|
|
surf = NULL;
|
|
DDSurfDesc.dwWidth = dwWidth;
|
|
DDSurfDesc.dwHeight = dwHeight;
|
|
if (!(surf = gCreateSurface(&DDSurfDesc, surf))) {
|
|
DebugLogFile("gLoadTexture (rSURFACEHALF) FAILED: Can't create surface");
|
|
return NULL;
|
|
}
|
|
if ((err = surf->Blt(NULL, Texture->lpDDSurface, NULL, 0, NULL)) != DD_OK) {
|
|
char str[255];
|
|
GetDDErrorString(err, str, 1);
|
|
DebugLogFile("gLoadTexture: BltStretch failed.\n%s", str);
|
|
}
|
|
|
|
//Release old texture
|
|
Texture->lpDDSurface->Release();
|
|
//Assign the newone
|
|
Texture->lpDDSurface = surf;
|
|
#endif
|
|
}
|
|
|
|
texture->ID = pos;
|
|
|
|
texture->Flags = CurLoaderFlags;
|
|
texture->DimX = dwWidth;
|
|
texture->DimY = dwHeight;
|
|
|
|
return texture;
|
|
}
|
|
|
|
|
|
bool Renderer::addMaterial(gMaterial &material, const Common::String &name, int NumFaces, unsigned int _LoaderFlags) {
|
|
//warning("AddMaterial(%s)", name.c_str());
|
|
if (hasFileExtension(name, "avi")) {
|
|
auto tex = createGLTexture();
|
|
if ((material.Movie = gLoadMovie(*_workDirs, name.c_str(), tex)) == nullptr)
|
|
return false;
|
|
if ((material.Texture = gUserTexture(tex, 64, 128)) == nullptr)
|
|
// if( (Material->Texture=gUserTexture( Material->Movie->g_psiStreamInfo.rcFrame.right,
|
|
// Material->Movie->g_psiStreamInfo.rcFrame.bottom)) == NULL )
|
|
return false;
|
|
material.addProperty(T3D_MATERIAL_MOVIE);
|
|
} else {
|
|
if ((material.Texture = gLoadTexture(*_workDirs, name.c_str(), _LoaderFlags)) == nullptr)
|
|
return false;
|
|
}
|
|
|
|
//f
|
|
material.addProperty(T3D_MATERIAL_NOLIGHTMAP);
|
|
return true;
|
|
}
|
|
|
|
} // End of namespace Watchmaker
|
|
|
|
#endif // USE_OPENGL_GAME
|