Skip to content

Commit

Permalink
Implemented work around to disable mipmaps on palettized textures.
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-fadely committed Sep 6, 2015
1 parent 741c083 commit 4a27d13
Showing 1 changed file with 74 additions and 13 deletions.
87 changes: 74 additions & 13 deletions SADXModLoader/AutoMipmap.cpp
Expand Up @@ -3,10 +3,31 @@
#include <SADXModLoader.h>
#include "AutoMipmap.h"

static IDirect3DTexture8* __fastcall GenerateMipmaps_c(IDirect3DTexture8* d3d_texture, NJS_TEXMEMLIST* njs_texture)
inline void SetSurface(IDirect3DTexture8* d3d_texture, NJS_TEXSURFACE* texsurface)
{
D3DSURFACE_DESC info;
d3d_texture->GetLevelDesc(0, &info);

texsurface->pSurface = (Uint32*)d3d_texture;
texsurface->TextureSize = info.Size;
}

/// <summary>
/// Generates mipmaps if the specified texture has the levels to accommodate them.
/// </summary>
/// <param name="d3d_texture">The DirectX texture to apply mipmaps to.</param>
/// <param name="njs_texture">The Dremcast texture to receive the DirectX texture.</param>
/// <returns></returns>
static void __fastcall GenerateMipmaps_c(IDirect3DTexture8* d3d_texture, NJS_TEXMEMLIST* njs_texture)
{
if (d3d_texture == nullptr || njs_texture == nullptr)
return nullptr;
return;

if (d3d_texture->GetLevelCount() < 2)
{
SetSurface(d3d_texture, &njs_texture->texinfo.texsurface);
return;
}

Uint32 format = njs_texture->texinfo.texsurface.PixelFormat;

Expand All @@ -20,16 +41,10 @@ static IDirect3DTexture8* __fastcall GenerateMipmaps_c(IDirect3DTexture8* d3d_te
if (result != 0)
PrintDebug("Mipmap generation failed with error code 0x%08X\n", result);

D3DSURFACE_DESC info;
d3d_texture->GetLevelDesc(0, &info);

njs_texture->texinfo.texsurface.pSurface = (Uint32*)d3d_texture;
njs_texture->texinfo.texsurface.TextureSize = info.Size;

return d3d_texture;
SetSurface(d3d_texture, &njs_texture->texinfo.texsurface);
}

void* ret_addr = (void*)0x0078CD37;
void* GenerateMipmaps_ret = (void*)0x0078CD37;
static void __declspec(naked) GenerateMipmaps_asm()
{
// This could probably use some optimizing.
Expand All @@ -42,13 +57,59 @@ static void __declspec(naked) GenerateMipmaps_asm()
call GenerateMipmaps_c
pop eax

jmp ret_addr
jmp GenerateMipmaps_ret
}
}

bool mipmapsEnabled = false;
/// <summary>
/// Disables mipmaps for palettized textures as a work around.
/// </summary>
/// <param name="format">The texture's pixel format.</param>
static void _stdcall EnableMipmaps(uint32_t format)
{
if (format == NJD_PIXELFORMAT_PALETTIZED_4BPP || format == NJD_PIXELFORMAT_PALETTIZED_8BPP)
{
if (mipmapsEnabled)
{
// Default behavior
WriteData((uint8_t*)0x0078C8B0, (uint8_t)1);
WriteData((uint8_t*)0x0078C8F6, (uint8_t)1);
mipmapsEnabled = false;
}
}
else if (!mipmapsEnabled)
{
// Forces generation of empty mipmap levels for textures that don't normally have them
WriteData((uint8_t*)0x0078C8B0, (uint8_t)0);
WriteData((uint8_t*)0x0078C8F6, (uint8_t)0);
mipmapsEnabled = true;
}
}

void* EnableMipmaps_ret = (void*)0x0078C889;
static void __declspec(naked) EnableMipmaps_asm()
{
__asm
{
push eax
push ecx
push [esp + 16]
call EnableMipmaps
pop ecx
pop eax

// Stuff overwritten by the jump to this code
sub esp, 14h
push ebx
push ebp
mov ebp, [esp+1Ch+0Ch]
jmp EnableMipmaps_ret
}
}

void ConfigureAutoMipmaps()
{
WriteJump((void*)0x0078CD2A, GenerateMipmaps_asm); // Hooks the end of the function that converts PVRs to D3D textures
WriteData((uint8_t*)0x0078C8B0, (uint8_t)0); // Forces generation of empty mipmap levels for textures that don't normally have them
WriteData((uint8_t*)0x0078C8F6, (uint8_t)0); // Ditto
WriteJump((void*)0x0078C880, EnableMipmaps_asm);
}

0 comments on commit 4a27d13

Please sign in to comment.