mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 02:23:56 +00:00
Introduces a third person camera system with orbit camera, input handling (mouse/keyboard/touch/gamepad), display actor cloning, and camera-relative movement. Includes shared character utilities (animator, cloner, customizer) and an IExtraAnimHandler interface for optional animation extensions. Also includes generic base game fixes and extension system improvements.
129 lines
3.8 KiB
C++
129 lines
3.8 KiB
C++
#include "extensions/textureloader.h"
|
|
|
|
#include "extensions/common/pathutils.h"
|
|
#include "legovideomanager.h"
|
|
#include "misc.h"
|
|
#include "mxdirectx/mxdirect3d.h"
|
|
#include "mxmain.h"
|
|
#include "tgl/d3drm/impl.h"
|
|
|
|
using namespace Extensions;
|
|
|
|
std::map<std::string, std::string> TextureLoaderExt::options;
|
|
std::vector<std::string> TextureLoaderExt::excludedFiles;
|
|
bool TextureLoaderExt::enabled = false;
|
|
|
|
void TextureLoaderExt::Initialize()
|
|
{
|
|
for (const auto& option : defaults) {
|
|
if (!options.count(option.first.data())) {
|
|
options[option.first.data()] = option.second;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TextureLoaderExt::AddExcludedFile(const std::string& p_file)
|
|
{
|
|
excludedFiles.emplace_back(p_file);
|
|
}
|
|
|
|
bool TextureLoaderExt::PatchTexture(LegoTextureInfo* p_textureInfo)
|
|
{
|
|
SDL_Surface* surface = FindTexture(p_textureInfo->m_name);
|
|
if (!surface) {
|
|
return false;
|
|
}
|
|
|
|
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(surface->format);
|
|
|
|
DDSURFACEDESC desc;
|
|
memset(&desc, 0, sizeof(desc));
|
|
desc.dwSize = sizeof(desc);
|
|
desc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
|
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
|
|
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
|
|
desc.dwWidth = surface->w;
|
|
desc.dwHeight = surface->h;
|
|
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
desc.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel;
|
|
desc.ddpfPixelFormat.dwRBitMask = details->Rmask;
|
|
desc.ddpfPixelFormat.dwGBitMask = details->Gmask;
|
|
desc.ddpfPixelFormat.dwBBitMask = details->Bmask;
|
|
desc.ddpfPixelFormat.dwRGBAlphaBitMask = details->Amask;
|
|
|
|
LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw();
|
|
if (pDirectDraw->CreateSurface(&desc, &p_textureInfo->m_surface, NULL) != DD_OK) {
|
|
SDL_DestroySurface(surface);
|
|
return false;
|
|
}
|
|
|
|
memset(&desc, 0, sizeof(desc));
|
|
desc.dwSize = sizeof(desc);
|
|
|
|
if (p_textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) != DD_OK) {
|
|
SDL_DestroySurface(surface);
|
|
return false;
|
|
}
|
|
|
|
MxU8* dst = (MxU8*) desc.lpSurface;
|
|
Uint8* srcPixels = (Uint8*) surface->pixels;
|
|
|
|
if (details->bits_per_pixel == 8) {
|
|
SDL_Palette* sdlPalette = SDL_GetSurfacePalette(surface);
|
|
if (!sdlPalette) {
|
|
p_textureInfo->m_surface->Unlock(desc.lpSurface);
|
|
SDL_DestroySurface(surface);
|
|
return false;
|
|
}
|
|
|
|
PALETTEENTRY entries[256];
|
|
for (int i = 0; i < sdlPalette->ncolors; ++i) {
|
|
entries[i].peRed = sdlPalette->colors[i].r;
|
|
entries[i].peGreen = sdlPalette->colors[i].g;
|
|
entries[i].peBlue = sdlPalette->colors[i].b;
|
|
entries[i].peFlags = PC_NONE;
|
|
}
|
|
|
|
LPDIRECTDRAWPALETTE ddPalette = nullptr;
|
|
if (pDirectDraw->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, entries, &ddPalette, NULL) != DD_OK) {
|
|
p_textureInfo->m_surface->Unlock(desc.lpSurface);
|
|
SDL_DestroySurface(surface);
|
|
return false;
|
|
}
|
|
|
|
p_textureInfo->m_surface->SetPalette(ddPalette);
|
|
ddPalette->Release();
|
|
}
|
|
|
|
memcpy(dst, srcPixels, surface->pitch * surface->h);
|
|
p_textureInfo->m_surface->Unlock(desc.lpSurface);
|
|
p_textureInfo->m_palette = NULL;
|
|
|
|
if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer())
|
|
->CreateTextureFromSurface(p_textureInfo->m_surface, &p_textureInfo->m_texture) != D3DRM_OK) {
|
|
SDL_DestroySurface(surface);
|
|
return false;
|
|
}
|
|
|
|
p_textureInfo->m_texture->SetAppData((LPD3DRM_APPDATA) p_textureInfo);
|
|
SDL_DestroySurface(surface);
|
|
return true;
|
|
}
|
|
|
|
SDL_Surface* TextureLoaderExt::FindTexture(const char* p_name)
|
|
{
|
|
if (std::find(excludedFiles.begin(), excludedFiles.end(), p_name) != excludedFiles.end()) {
|
|
return nullptr;
|
|
}
|
|
|
|
const char* texturePath = options["texture loader:texture path"].c_str();
|
|
MxString relativePath = MxString(texturePath) + "/" + p_name + ".bmp";
|
|
|
|
MxString path;
|
|
if (!Common::ResolveGamePath(relativePath.GetData(), path)) {
|
|
return nullptr;
|
|
}
|
|
|
|
return SDL_LoadBMP(path.GetData());
|
|
}
|