1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-30 08:24:05 +00:00

Changed GLideN64 so it works with framebuffer emulation enabled with OOT.

This commit is contained in:
DaMarkov 2022-02-08 03:44:17 +01:00
parent dca837e446
commit e5332785fc
6 changed files with 182 additions and 14 deletions

View File

@ -193,6 +193,7 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")</Command>
<ConformanceMode Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|x64'">true</ConformanceMode>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|x64'">stdcpp17</LanguageStandard>
<RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">MultiThreadedDebug</RuntimeLibrary>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">Disabled</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>

View File

@ -677,7 +677,8 @@ void FrameBufferList::setBufferChanged(f32 _maxY)
void FrameBufferList::clearBuffersChanged()
{
gDP.colorImage.changed = FALSE;
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
//FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
FrameBuffer* pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
if (pBuffer != nullptr)
pBuffer->m_changed = false;
}
@ -1229,7 +1230,7 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
if ((vitype & 2) == 0) {
prevwasblank = true;
return false;
//return false;//HACK
}
prevwasblank = false;
@ -1247,7 +1248,8 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
_result.vi_maxhpass = hres_clamped ? 0 : 7;
_result.vi_width = _SHIFTR(*REG.VI_WIDTH, 0, 12);
_result.vi_lowerfield = lowerfield;
_result.vi_origin = _SHIFTR(*REG.VI_ORIGIN, 0, 24);
//_result.vi_origin = _SHIFTR(*REG.VI_ORIGIN, 0, 24);
_result.vi_origin = *REG.VI_ORIGIN;//This is incorrect REG.VI_ORIGIN should contain only 24 bits of the frame buffer address
_result.vi_fsaa = (*REG.VI_STATUS & 512) == 0;
_result.vi_divot = (*REG.VI_STATUS & VI_STATUS_DIVOT_ENABLED) != 0;
return true;

View File

@ -145,7 +145,7 @@ public:
static FrameBufferList & get();
private:
//private:
FrameBufferList() : m_pCurrent(nullptr), m_pCopy(nullptr), m_prevColorImageHeight(0) {}
FrameBufferList(const FrameBufferList &) = delete;

View File

@ -684,7 +684,8 @@ namespace glsl {
void activate() override {
FXAAShaderBase::activate();
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
//FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
FrameBuffer* pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
if (pBuffer != nullptr && pBuffer->m_pTexture != nullptr &&
(m_width != pBuffer->m_pTexture->width || m_height != pBuffer->m_pTexture->height)) {
m_width = pBuffer->m_pTexture->width;

View File

@ -254,7 +254,8 @@ void VI_UpdateScreen()
if (config.frameBufferEmulation.enable) {
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
//FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN & 0xffffff);
FrameBuffer* pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
if (pBuffer == nullptr) {
gDP.changed |= CHANGED_CPU_FB_WRITE;
} else if (!FBInfo::fbInfo.isSupported() &&
@ -289,7 +290,8 @@ void VI_UpdateScreen()
}
const u32 size = *REG.VI_STATUS & VI_STATUS_TYPE_32;
if (VI.height > 0 && size > G_IM_SIZ_8b && VI.width > 0)
frameBufferList().saveBuffer(*REG.VI_ORIGIN & 0xffffff, G_IM_FMT_RGBA, size, VI.width, true);
frameBufferList().saveBuffer(*REG.VI_ORIGIN, G_IM_FMT_RGBA, size, VI.width, true);
//frameBufferList().saveBuffer(*REG.VI_ORIGIN & 0xffffff, G_IM_FMT_RGBA, size, VI.width, true);
}
}
// if ((((*REG.VI_STATUS) & 3) > 0) && (gDP.colorImage.changed || bCFB)) { // Does not work in release build!!!
@ -298,7 +300,8 @@ void VI_UpdateScreen()
VI_UpdateSize();
bVIUpdated = true;
}
FrameBuffer_CopyFromRDRAM(*REG.VI_ORIGIN & 0xffffff, bCFB);
//FrameBuffer_CopyFromRDRAM(*REG.VI_ORIGIN & 0xffffff, bCFB);
FrameBuffer_CopyFromRDRAM(*REG.VI_ORIGIN, bCFB);
}
frameBufferList().renderBuffer();
frameBufferList().clearBuffersChanged();

View File

@ -7,13 +7,18 @@
#include "DebugDump.h"
#include "Config.h"
#include "DisplayWindow.h"
#include "FrameBuffer.h"
#include "FrameBufferInfo.h"
#include <wchar.h>
#include "settings.h"
#define START_WIDTH 1280
#define START_HEIGHT 720
//#define START_WIDTH 1280
//#define START_HEIGHT 720
static u64 g_width = START_WIDTH;
#define START_WIDTH 320
#define START_HEIGHT 240
static u64 g_width = START_WIDTH;
static u64 g_height = START_HEIGHT;
extern "C" {
@ -97,7 +102,7 @@ extern "C"
config.video.windowedWidth = g_width;
config.video.windowedHeight = g_height;
dwnd().setWindowSize(g_width, g_height);
(*REG.VI_ORIGIN)++;
//(*REG.VI_ORIGIN)++;
}
}
@ -106,6 +111,111 @@ void _CheckInterrupts() {
//Copied over from OOT - needs cleanup
struct Gfx;
struct OSThread;
typedef void* OSMesg;
typedef struct OSMesgQueue {
/* 0x00 */ OSThread* mtqueue;
/* 0x04 */ OSThread* fullqueue;
/* 0x08 */ s32 validCount;
/* 0x0C */ s32 first;
/* 0x10 */ s32 msgCount;
/* 0x14 */ OSMesg* msg;
} OSMesgQueue; // size = 0x18
typedef struct {
/* 0x0000 */ u32 size;
/* 0x0004 */ Gfx* bufp;
/* 0x0008 */ Gfx* p;
/* 0x000C */ Gfx* d;
} TwoHeadGfxArena; // size = 0x10
typedef struct CfbInfo {
/* 0x00 */ u32* fb1;//Address to the frame buffer
/* 0x04 */ u32* swapBuffer;
/* 0x08 */ OSViMode* viMode;
/* 0x0C */ u32 features;
/* 0x10 */ u8 unk_10;
/* 0x11 */ s8 updateRate;
/* 0x12 */ s8 updateRate2;
/* 0x13 */ u8 unk_13;
/* 0x14 */ f32 xScale;
/* 0x18 */ f32 yScale;
} CfbInfo; // size = 0x1C
typedef union {
OSTask_t t;
long long int force_structure_alignment;
} OSTask;
typedef struct OSScTask {
/* 0x00 */ struct OSScTask* next;
/* 0x04 */ u32 state;
/* 0x08 */ u32 flags;
/* 0x0C */ CfbInfo* framebuffer;
/* 0x10 */ OSTask list;
/* 0x50 */ OSMesgQueue* msgQ;
/* 0x54 */ OSMesg msg;
} OSScTask;
typedef struct GraphicsContext {
/* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0"
/* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1"
/* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3"
/* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4"
/* 0x0014 */ u32 unk_014;
/* 0x0018 */ char unk_018[0x20];
/* 0x0038 */ OSMesg msgBuff[0x08];
/* 0x0058 */ OSMesgQueue* schedMsgQ;
/* 0x005C */ OSMesgQueue queue;
/* 0x0074 */ char unk_074[0x04];
/* 0x0078 */ OSScTask task; // size of OSScTask might be wrong
/* 0x00D0 */ char unk_0D0[0xE0];
/* 0x01B0 */ Gfx* workBuffer;
/* 0x01B4 */ TwoHeadGfxArena work;
/* 0x01C4 */ char unk_01C4[0xC0];
/* 0x0284 */ OSViMode* viMode;
/* 0x0288 */ char unk_0288[0x20]; // Unused, could this be Zelda 2/3 ?
/* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4"
/* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0"
/* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1"
/* 0x02D8 */ u32 gfxPoolIdx;
/* 0x02DC */ u32* curFrameBuffer;
/* 0x02E0 */ char unk_2E0[0x04];
/* 0x02E4 */ u32 viFeatures;
/* 0x02E8 */ s32 fbIdx;
/* 0x02EC */ void (*callback)(struct GraphicsContext*, void*);
/* 0x02F0 */ void* callbackParam;
/* 0x02F4 */ f32 xScale;
/* 0x02F8 */ f32 yScale;
/* 0x02FC */ char unk_2FC[0x04];
} GraphicsContext; // size = 0x300
#define REG_GROUPS 29 // number of REG groups, i.e. REG, SREG, OREG, etc.
#define REG_PAGES 6
#define REG_PER_PAGE 16
#define REG_PER_GROUP REG_PAGES * REG_PER_PAGE
typedef struct {
/* 0x00 */ s32 regPage; // 1 is first page
/* 0x04 */ s32 regGroup; // "register" group (R, RS, RO, RP etc.)
/* 0x08 */ s32 regCur; // selected register within page
/* 0x0C */ s32 dpadLast;
/* 0x10 */ s32 repeat;
/* 0x14 */ s16 data[REG_GROUPS * REG_PER_GROUP]; // 0xAE0 entries
} GameInfo; // size = 0x15D4
#define BASE_REG(n, r) GameInfo->data[n * REG_PER_GROUP + r]
#define SREG(r) BASE_REG(1, r)
#define R_UPDATE_RATE SREG(30)
//End of copy
extern "C" {
void gfx_init(const char* romName, OSViMode* viMode) {
REG.VI_STATUS = &viMode->comRegs.ctrl;
@ -133,9 +243,10 @@ extern "C" {
api().RomOpen(romName);
config.frameBufferEmulation.enable = 0;
config.frameBufferEmulation.aspect = Config::aAdjust;
config.frameBufferEmulation.enable = 0;//Frame buffer disabled, will be enabled by OOT
//config.frameBufferEmulation.aspect = Config::aAdjust;
config.generalEmulation.hacks |= hack_subscreen | hack_ZeldaMonochrome;
}
void gfx_shutdown() {
@ -152,6 +263,56 @@ extern "C" {
api().UpdateScreen();
//Sleep(30);
}
int gfx_fbe_is_enabled() {
return config.frameBufferEmulation.enable;
}
void gfx_fbe_enable(int enable) {
config.frameBufferEmulation.enable = enable;
//gfx_resize(g_width, g_height);
}
void gfx_fbe_sync(GraphicsContext* gfxCtx, GameInfo* GameInfo) {
if (!config.frameBufferEmulation.enable)
return;
CfbInfo* cfb = gfxCtx->task.framebuffer;//Current frame buffer (according the the game)
FrameBufferList& frameBuffers = FrameBufferList::get();//GLideN64's frame buffer list
if (!frameBuffers.getCurrent())
return;
gfxCtx->curFrameBuffer = &frameBuffers.getCurrent()->m_startAddress;
gfxCtx->viMode->fldRegs->origin = frameBuffers.getCurrent()->m_startAddress;
cfb->fb1 = gfxCtx->curFrameBuffer;
cfb->swapBuffer = gfxCtx->curFrameBuffer;
cfb->viMode = gfxCtx->viMode;
cfb->features = gfxCtx->viFeatures;
cfb->xScale = gfxCtx->xScale;
cfb->xScale = gfxCtx->yScale;
cfb->unk_10 = 0;
cfb->updateRate = R_UPDATE_RATE;
REG.VI_STATUS = &cfb->viMode->comRegs.ctrl;
REG.VI_WIDTH = &cfb->viMode->comRegs.width;
REG.VI_TIMING = &cfb->viMode->comRegs.burst;
REG.VI_V_SYNC = &cfb->viMode->comRegs.vSync;
REG.VI_H_SYNC = &cfb->viMode->comRegs.hSync;
REG.VI_LEAP = &cfb->viMode->comRegs.leap;
REG.VI_H_START = &cfb->viMode->comRegs.hStart;
REG.VI_X_SCALE = &cfb->viMode->comRegs.xScale;
REG.VI_V_CURRENT_LINE = &cfb->viMode->comRegs.vCurrent;
REG.VI_ORIGIN = &cfb->viMode->fldRegs->origin;//This is incorrect REG.VI_ORIGIN should contain only 24 bits of the frame buffer address
REG.VI_Y_SCALE = &cfb->viMode->fldRegs->yScale;
REG.VI_V_START = &cfb->viMode->fldRegs->vStart;
REG.VI_V_BURST = &cfb->viMode->fldRegs->vBurst;
REG.VI_INTR = &cfb->viMode->fldRegs->vIntr;
}
}
Config config;