RetroArch/deps/Pigs-In-A-Blanket/src/patches.c

237 lines
8.9 KiB
C

/*****************************************************************************
*
* Copyright (c) 2020 by SonicMastr <sonicmastr@gmail.com>
*
* This file is part of Pigs In A Blanket
*
* 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 <https://www.gnu.org/licenses/>.
*
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <psp2/types.h>
#include <psp2/display.h>
#include "../include/patches.h"
#include "../include/hooks.h"
#include "../include/debug.h"
static int swap_interval = 1;
static void *displayBufferData[2];
static unsigned int bufferDataIndex;
int isCreatingSurface;
void glGetBooleanv_shaderCompilerPatch(unsigned int pname, unsigned char *data)
{
TAI_CONTINUE(void, hookRef[1], pname, data);
if (pname == 0x8DFA)
*data = 1;
}
void _pglPlatformTextureUploadParams_patch(int textureUploadParams)
{
if (*(int *)(textureUploadParams + 0xd0) != 0)
{
SceGxmTextureAddrMode addrMode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
int ret;
if (*(char *)(textureUploadParams + 0x38) != '\0') {
if ((*(char *)(textureUploadParams + 0x20) != '\x01') && (*(int *)(textureUploadParams + 0xbc) != 0x1902)) {
ret = *(int *)(textureUploadParams + 0x34);
if (ret == 0x8370) {
ret = sceGxmTextureSetVAddrMode((SceGxmTexture *)(textureUploadParams + 0x490),addrMode);
} else {
ret = 1;
}
if (ret == 0) {
*(char *)(textureUploadParams + 0x38) = 0;
}
}
}
if (*(char *)(textureUploadParams + 0x40) != '\0') {
if ((*(char *)(textureUploadParams + 0x20) != '\x01') && (*(int *)(textureUploadParams + 0xbc) != 0x1902)) {
ret = *(int *)(textureUploadParams + 0x3c);
if (ret == 0x8370) {
ret = sceGxmTextureSetUAddrMode((SceGxmTexture *)(textureUploadParams + 0x490),addrMode);
} else {
ret = 1;
}
if (ret == 0) {
*(char *)(textureUploadParams + 0x40) = 0;
}
}
}
}
TAI_CONTINUE(void, hookRef[2], textureUploadParams);
}
int eglCreateWindowSurface_resolutionPatch(int dpy, int config, int win, int *attrib_list)
{
if (customResolutionMode)
win = customResolutionMode;
switch (win)
{
case 5:
*(int16_t *)(dpy + 0x26) = 1280;
*(int16_t *)(dpy + 0x28) = 725;
*(int16_t *)(dpy + 0x2A) = 1280;
break;
case 6:
*(int16_t *)(dpy + 0x26) = 1920;
*(int16_t *)(dpy + 0x28) = 1088;
*(int16_t *)(dpy + 0x2A) = 1920;
break;
case 7:
*(int16_t *)(dpy + 0x26) = 960;
*(int16_t *)(dpy + 0x28) = 544;
*(int16_t *)(dpy + 0x2A) = 960;
break;
}
return TAI_CONTINUE(int, hookRef[3], dpy, config, win, attrib_list);
}
void *eglGetProcAddress_functionNamePatch(const char *procname)
{
void *ret = TAI_CONTINUE(void*, hookRef[4], procname);
if(ret)
return ret; // Got an Extension function address. No need to do anything else.
char digest[21];
SHA1(digest, procname, strlen(procname)); // This may be slow. Look into different solutions
void *function;
if(taiGetModuleExportFunc("libScePiglet", 0xB4FE1ABB, *(uint32_t*)(&digest), (uintptr_t *)&function) < 0)
return NULL;
return function;
}
unsigned int eglGetConfigAttrib_intervalPatch(void *display, void *config, int attrib, int *value)
{
unsigned int ret = TAI_CONTINUE(unsigned int, hookRef[5], display, config, attrib, value);
if (ret)
{
if (attrib == 0x303B) // EGL_MIN_SWAP_INTERVAL
*value = 0;
if (attrib == 0x303C) // EGL_MAX_SWAP_INTERVAL
*value = 4;
}
return ret;
}
unsigned int pglDisplaySetSwapInterval_intervalPatch(void *display, int interval)
{
unsigned int ret = TAI_CONTINUE(int, hookRef[6], display, interval);
if (ret)
{
if (interval < 0)
interval = 0;
if (interval > 4)
interval = 4;
swap_interval = interval;
}
return ret;
}
int sceDisplayWaitVblankStart_intervalPatch(void)
{
return sceDisplayWaitVblankStartMulti(swap_interval);
}
SceGxmErrorCode sceGxmColorSurfaceInit_msaaPatch(SceGxmColorSurface *surface,
SceGxmColorFormat colorFormat,
SceGxmColorSurfaceType surfaceType,
SceGxmColorSurfaceScaleMode scaleMode,
SceGxmOutputRegisterSize outputRegisterSize,
uint32_t width,
uint32_t height,
uint32_t strideInPixels,
void *data)
{
scaleMode = SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE;
return TAI_CONTINUE(SceGxmErrorCode, hookRef[16], surface, colorFormat, surfaceType, scaleMode, outputRegisterSize, width, height, strideInPixels, data);
}
SceGxmErrorCode sceGxmCreateRenderTarget_msaaPatch(const SceGxmRenderTargetParams *params, SceGxmRenderTarget **renderTarget)
{
SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, 0x14);
renderTargetParams.flags = 0;
renderTargetParams.width = params->width;
renderTargetParams.height = params->height;
renderTargetParams.multisampleMode = isCreatingSurface ? SCE_GXM_MULTISAMPLE_4X : SCE_GXM_MULTISAMPLE_NONE;
renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1;
return TAI_CONTINUE(SceGxmErrorCode, hookRef[17], &renderTargetParams, renderTarget);
}
SceGxmErrorCode sceGxmDepthStencilSurfaceInit_msaaPatch(SceGxmDepthStencilSurface *surface,
SceGxmDepthStencilFormat depthStencilFormat,
SceGxmDepthStencilSurfaceType surfaceType,
uint32_t strideInSamples,
void *depthData,
void *stencilData)
{
if (isCreatingSurface)
strideInSamples *= 2;
return TAI_CONTINUE(SceGxmErrorCode, hookRef[18], surface, depthStencilFormat, surfaceType, strideInSamples, depthData, stencilData);
}
SceGxmErrorCode sceGxmShaderPatcherCreateFragmentProgram_msaaPatch(SceGxmShaderPatcher *shaderPatcher,
SceGxmShaderPatcherId programId,
SceGxmOutputRegisterFormat outputFormat,
SceGxmMultisampleMode multisampleMode,
const SceGxmBlendInfo *blendInfo,
const SceGxmProgram *vertexProgram,
SceGxmFragmentProgram **fragmentProgram)
{
multisampleMode = SCE_GXM_MULTISAMPLE_4X;
return TAI_CONTINUE(SceGxmErrorCode, hookRef[19], shaderPatcher, programId, outputFormat, multisampleMode, blendInfo, vertexProgram, fragmentProgram);
}
unsigned int pglMemoryAllocAlign_patch(int memoryType, int size, int unused, int *memory)
{
if (systemMode && memoryType == 4 && isCreatingSurface) // ColorSurface/Framebuffer Allocation. We want to skip this and replace with SharedFb Framebuffer
{
memory[0] = displayBufferData[bufferDataIndex];
return 0;
}
if (msaaEnabled && memoryType == 5 && isCreatingSurface)
{
size *= 4; // For MSAA
}
return TAI_CONTINUE(unsigned int, hookRef[8], memoryType, size, unused, memory);
}
void *pglPlatformSurfaceCreateWindow_detect(int a1, int a2, int a3, int a4, int *a5)
{
isCreatingSurface = 1;
bufferDataIndex = 0;
void *ret = TAI_CONTINUE(void*, hookRef[10], a1, a2, a3, a4, a5);
isCreatingSurface = 0;
return ret;
}