Skip to content

Commit

Permalink
Improved custom texture loader
Browse files Browse the repository at this point in the history
  • Loading branch information
krystalgamer committed Jul 20, 2019
1 parent e751899 commit 70aec5a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 76 deletions.
15 changes: 6 additions & 9 deletions texture_loader/hooks.s
@@ -1,4 +1,4 @@
extern _OpenFileFromDisk, _fileName, _fileDirectory, _buffer, _fileSize, _curPkr, _psxId, _PVRIdHandler, _SearchKeyValue, _printf, _option
extern _OpenFileFromDisk, _fileName, _fileDirectory, _buffer, _curPkr, _psxId, _PVRIdHandler, _printf, _option, _get_texture

section .data

Expand Down Expand Up @@ -29,15 +29,12 @@ jmp _PVRIdHandler

%define ConvertVQToBmpAdd 0x005115D0
_ConvertVQHook:
mov dword eax, [_psxId]
mov dword ecx, 0x11
mul ecx
mov dword edx, [eax * 4 + 0x6B2440]
mov dword eax, [esp+0xC]
xor eax, edx
mov eax, [esp+0xCC]
push dword [esp+8]
push dword [esp+8]
push eax
call _SearchKeyValue
add esp, 4
call _get_texture
add esp, 0xC
test eax, eax
jz noTexture
ret
Expand Down
2 changes: 1 addition & 1 deletion texture_loader/loader.c
Expand Up @@ -88,5 +88,5 @@ BOOL CheckBinkwVersion(){

BOOL ApplyHooks(){

return (DisableIntros() && FileLoader() && TextureLoader() && ModOptions());
return (FileLoader() && TextureLoader());
}
102 changes: 36 additions & 66 deletions texture_loader/patches.c
Expand Up @@ -138,61 +138,13 @@ void* ConvertVQHook();
typedef void* (*createTexturePVRInIdP)(DWORD id, DWORD, DWORD , DWORD type, DWORD textureBUffer, void *a6, void *a7, void *a8);
createTexturePVRInIdP CreateTexturePVRInId = (void*)0x0050F6D0;

DWORD *EnviroList = (void*)0x6B2440;
DWORD *UnkList = (void*)0x6B2440;
DWORD psxId = 0;

typedef struct _List{
DWORD key;
DWORD value;
struct _List *next;
}List;

List *texList = NULL;//list that contains the textures

BOOL AddToList(DWORD key, DWORD value){

//Find an empty spot
List **walker = &texList;
while(*walker){
//the game frees old textures so need to this here
if((*walker)->key == key){
(*walker)->value = value;
(*walker)->next = NULL;
return TRUE;
}
walker = &((*walker)->next);
}

*walker = malloc(sizeof(List));
if(!(*walker)){
printf("There was a problem allocating a node for the tree");
return FALSE;
}

//new entry
(*walker)->key = key;
(*walker)->value = value;
(*walker)->next = NULL;
return TRUE;
}

DWORD SearchKeyValue(DWORD key){

List *walker = texList;
while(walker){
if(walker->key == key)
return walker->value;

walker = walker->next;
}

return 0;//Didnt find
}


void* textures[1024];

BOOL TextureLoader(){

memset(textures, 0, sizeof(textures));
Hook(0x0050F45F, (DWORD)CreateTexturePVRInIdHook, "Hooks a call to CreateTexturePVRInIdHook for the PSXPVR files")
Hook(0x0050F951, (DWORD)ConvertVQHook, "Hooks ConvertVQToBmp")
return TRUE;
Expand All @@ -201,57 +153,75 @@ BOOL TextureLoader(){

void *PVRIdHandler(DWORD id, DWORD width, DWORD height, DWORD type, DWORD textureBuffer, void *a6, void *a7, void *a8){


void* res = NULL;
static char path[64];
sprintf(path, "textures/%s/%08X.bmp\0", &EnviroList[0x11 * psxId], textureBuffer - EnviroList[0x11 * psxId + 6]);
sprintf(path, "textures/%s/%08X.bmp\0", &UnkList[0x11 * psxId], textureBuffer - UnkList[0x11 * psxId + 6]);

FILE *fp;
fp = fopen(path, "rb");
if(!fp)
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
goto load_texture_fail;

//Guarantees there's no problems with the files
DWORD textureSize = MyGetFileSize(fp);
if(textureSize < width * height * 2 + 0xA){
printf("There seems to be a problem with the texture %08X for %s\n", textureBuffer - EnviroList[0x11 * psxId + 6], &EnviroList[0x11 * psxId]);
printf("There seems to be a problem with the texture %08X for %s\n", textureBuffer - UnkList[0x11 * psxId + 6], &UnkList[0x11 * psxId]);
fclose(fp);
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
goto load_texture_fail;
}

//opens the bmp and reads the pixel info
DWORD offset;
fseek(fp, 0xA, SEEK_SET);
if(!fread(&offset, 4, 1, fp)){
fclose(fp);
printf("Couldn't read offset %s\n", &EnviroList[0x11 * psxId]);
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
printf("Couldn't read offset %s\n", &UnkList[0x11 * psxId]);
goto load_texture_fail;
}

fseek(fp, offset, SEEK_SET);
void *texBuffer = new(width * height * 2);
if(!texBuffer){
fclose(fp);
printf("Couldn't allocate space for %s\n", &EnviroList[0x11 * psxId]);
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
printf("Couldn't allocate space for %s\n", &UnkList[0x11 * psxId]);
goto load_texture_fail;
}

if(!fread(texBuffer, width * height * 2, 1, fp)){
fclose(fp);
delete(texBuffer);
printf("Couldn't read offset %s\n", &EnviroList[0x11 * psxId]);
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
printf("Couldn't read offset %s\n", &UnkList[0x11 * psxId]);
goto load_texture_fail;
}

fclose(fp);//Dont leak file pointers
res = texBuffer;
printf("Successfully loaded a texture! %s %08X\n", path, res);

//ids get reused so cant use them as key, will use the texture buffer hoping no other uses the same
if(!AddToList(textureBuffer ^ EnviroList[0x11 * psxId], (DWORD)texBuffer)){
delete(texBuffer);
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
load_texture_fail:
if (textures[id] != NULL && res == NULL) {
delete(textures[id]);
}

textures[id] = res;
return CreateTexturePVRInId(id, width, height, type, textureBuffer, a6, a7, a8);
}

void* get_texture(int id, int width, int height) {
if (id > 1024)
return NULL;

void* cur = textures[id];
if (!cur)
return NULL;

void* res = new(width * height * 2);
if (!res)
return NULL;
memcpy(res, cur, width * height * 2);
return res;
}

/************************************************
OPTIONS
Expand Down

0 comments on commit 70aec5a

Please sign in to comment.