240 lines
7.2 KiB
C++
240 lines
7.2 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** 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 TEXTURELOADER_H
|
|
#define TEXTURELOADER_H
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "always.h"
|
|
#include "texture.h"
|
|
|
|
class StringClass;
|
|
struct IDirect3DTexture8;
|
|
class TextureLoadTaskClass;
|
|
|
|
class TextureLoader
|
|
{
|
|
public:
|
|
static void Init(void);
|
|
static void Deinit(void);
|
|
|
|
// Modify given texture size to nearest valid size on current hardware.
|
|
static void Validate_Texture_Size(unsigned& width, unsigned& height);
|
|
|
|
static IDirect3DTexture8 * Load_Thumbnail(
|
|
const StringClass& filename);
|
|
// WW3DFormat texture_format); // Pass WW3D_FORMAT_UNKNOWN if you don't care
|
|
|
|
static IDirect3DSurface8 * Load_Surface_Immediate(
|
|
const StringClass& filename,
|
|
WW3DFormat surface_format, // Pass WW3D_FORMAT_UNKNOWN if you don't care
|
|
bool allow_compression);
|
|
|
|
static void Request_Thumbnail(TextureClass* tc);
|
|
|
|
// Adds a loading task to the system. The task if processed in a separate
|
|
// thread as soon as possible. The task will appear in finished tasks list
|
|
// when it's been completed. The texture will be refreshed on the next
|
|
// update call after appearing to the finished tasks list.
|
|
static void Request_Background_Loading(TextureClass* tc);
|
|
|
|
// Textures can only be created and locked by the main thread so this function sends a request to the texture
|
|
// handling system to load the texture immediatelly next time it enters the main thread. If this function
|
|
// is called from the main thread the texture is loaded immediatelly.
|
|
static void Request_Foreground_Loading(TextureClass* tc);
|
|
|
|
static void Flush_Pending_Load_Tasks(void);
|
|
static void Update(void(*network_callback)(void) = NULL);
|
|
|
|
// returns true if current thread of execution is allowed to make DX8 calls.
|
|
static bool Is_DX8_Thread(void);
|
|
|
|
static void Suspend_Texture_Load();
|
|
static void Continue_Texture_Load();
|
|
|
|
private:
|
|
static void Process_Foreground_Load (TextureLoadTaskClass *task);
|
|
static void Process_Foreground_Thumbnail (TextureLoadTaskClass *task);
|
|
|
|
static void Begin_Load_And_Queue (TextureLoadTaskClass *task);
|
|
static void Load_Thumbnail (TextureClass *tc);
|
|
|
|
static bool TextureLoadSuspended;
|
|
};
|
|
|
|
class TextureLoadTaskListNodeClass
|
|
{
|
|
friend class TextureLoadTaskListClass;
|
|
|
|
public:
|
|
TextureLoadTaskListNodeClass(void) : Next(0), Prev(0) { }
|
|
|
|
TextureLoadTaskListClass *Get_List(void) { return List; }
|
|
|
|
TextureLoadTaskListNodeClass *Next;
|
|
TextureLoadTaskListNodeClass *Prev;
|
|
TextureLoadTaskListClass * List;
|
|
};
|
|
|
|
|
|
class TextureLoadTaskListClass
|
|
{
|
|
// This class implements an unsynchronized, double-linked list of TextureLoadTaskClass
|
|
// objects, using an embedded list node.
|
|
|
|
public:
|
|
TextureLoadTaskListClass(void);
|
|
|
|
// Returns true if list is empty, false otherwise.
|
|
bool Is_Empty (void) const { return (Root.Next == &Root); }
|
|
|
|
// Add a task to beginning of list
|
|
void Push_Front (TextureLoadTaskClass *task);
|
|
|
|
// Add a task to end of list
|
|
void Push_Back (TextureLoadTaskClass *task);
|
|
|
|
// Remove and return a task from beginning of list, or NULL if list is empty.
|
|
TextureLoadTaskClass * Pop_Front (void);
|
|
|
|
// Remove and return a task from end of list, or NULL if list is empty
|
|
TextureLoadTaskClass * Pop_Back (void);
|
|
|
|
// Remove specified task from list, if present
|
|
void Remove (TextureLoadTaskClass *task);
|
|
|
|
private:
|
|
// This list is implemented using a sentinel node.
|
|
TextureLoadTaskListNodeClass Root;
|
|
};
|
|
|
|
|
|
class SynchronizedTextureLoadTaskListClass : public TextureLoadTaskListClass
|
|
{
|
|
// This class added thread-safety to the basic TextureLoadTaskListClass.
|
|
|
|
public:
|
|
SynchronizedTextureLoadTaskListClass(void);
|
|
|
|
// See comments above for description of member functions.
|
|
void Push_Front (TextureLoadTaskClass *task);
|
|
void Push_Back (TextureLoadTaskClass *task);
|
|
TextureLoadTaskClass * Pop_Front (void);
|
|
TextureLoadTaskClass * Pop_Back (void);
|
|
void Remove (TextureLoadTaskClass *task);
|
|
|
|
private:
|
|
FastCriticalSectionClass CriticalSection;
|
|
};
|
|
|
|
|
|
class TextureLoadTaskClass : public TextureLoadTaskListNodeClass
|
|
{
|
|
public:
|
|
enum TaskType {
|
|
TASK_NONE,
|
|
TASK_THUMBNAIL,
|
|
TASK_LOAD,
|
|
};
|
|
|
|
enum PriorityType {
|
|
PRIORITY_LOW,
|
|
PRIORITY_HIGH,
|
|
};
|
|
|
|
enum StateType {
|
|
STATE_NONE,
|
|
|
|
STATE_LOAD_BEGUN,
|
|
STATE_LOAD_MIPMAP,
|
|
STATE_LOAD_COMPLETE,
|
|
|
|
STATE_COMPLETE,
|
|
};
|
|
|
|
|
|
TextureLoadTaskClass(void);
|
|
~TextureLoadTaskClass(void);
|
|
|
|
static TextureLoadTaskClass * Create (TextureClass *tc, TaskType type, PriorityType priority);
|
|
void Destroy (void);
|
|
static void Delete_Free_Pool (void);
|
|
|
|
void Init (TextureClass *tc, TaskType type, PriorityType priority);
|
|
void Deinit (void);
|
|
|
|
TaskType Get_Type (void) const { return Type; }
|
|
PriorityType Get_Priority (void) const { return Priority; }
|
|
StateType Get_State (void) const { return State; }
|
|
|
|
WW3DFormat Get_Format (void) const { return Format; }
|
|
unsigned int Get_Width (void) const { return Width; }
|
|
unsigned int Get_Height (void) const { return Height; }
|
|
unsigned int Get_Mip_Level_Count (void) const { return MipLevelCount; }
|
|
unsigned int Get_Reduction (void) const { return Reduction; }
|
|
|
|
unsigned char * Get_Locked_Surface_Ptr (unsigned int level);
|
|
unsigned int Get_Locked_Surface_Pitch(unsigned int level) const;
|
|
|
|
TextureClass * Peek_Texture (void) { return Texture; }
|
|
IDirect3DTexture8 * Peek_D3D_Texture (void) { return D3DTexture; }
|
|
|
|
void Set_Type (TaskType t) { Type = t; }
|
|
void Set_Priority (PriorityType p) { Priority = p; }
|
|
void Set_State (StateType s) { State = s; }
|
|
|
|
bool Begin_Load (void);
|
|
bool Load (void);
|
|
void End_Load (void);
|
|
void Finish_Load (void);
|
|
void Apply_Missing_Texture (void);
|
|
|
|
private:
|
|
bool Begin_Compressed_Load (void);
|
|
bool Begin_Uncompressed_Load (void);
|
|
|
|
bool Load_Compressed_Mipmap (void);
|
|
bool Load_Uncompressed_Mipmap(void);
|
|
|
|
void Lock_Surfaces (void);
|
|
void Unlock_Surfaces (void);
|
|
|
|
void Apply (bool initialize);
|
|
|
|
TextureClass* Texture;
|
|
IDirect3DTexture8 * D3DTexture;
|
|
WW3DFormat Format;
|
|
|
|
unsigned int Width;
|
|
unsigned int Height;
|
|
unsigned int MipLevelCount;
|
|
unsigned int Reduction;
|
|
|
|
unsigned char * LockedSurfacePtr[TextureClass::MIP_LEVELS_MAX];
|
|
unsigned int LockedSurfacePitch[TextureClass::MIP_LEVELS_MAX];
|
|
|
|
TaskType Type;
|
|
PriorityType Priority;
|
|
StateType State;
|
|
};
|
|
|
|
|
|
#endif
|