git subrepo clone --force --branch=develop git@github.com:libretro/GLideN64.git GLideN64

subrepo:
  subdir:   "GLideN64"
  merged:   "d359d8f8"
upstream:
  origin:   "git@github.com:libretro/GLideN64.git"
  branch:   "develop"
  commit:   "d359d8f8"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
This commit is contained in:
M4xw 2020-11-19 18:05:26 +01:00
parent 524050007b
commit 3063b995dd
51 changed files with 1008 additions and 720 deletions

7
GLideN64/.gitignore vendored
View File

@ -13,6 +13,13 @@ src/Revision.h
/projects/msvc/GLideN64.VC.VC.opendb
/projects/msvc/GLideN64.VC.db
/projects/msvc/GeneratedFiles
/projects/cmake/CMakeCache.txt
/projects/cmake/CMakeFiles/
/projects/cmake/GLideNHQ/
/projects/cmake/Makefile
/projects/cmake/cmake_install.cmake
/projects/cmake/osal/
/projects/cmake/mupen64plus-video-GLideN64_autogen/
.vs
/translations/wtl
.vscode/ipch/*

View File

@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:libretro/GLideN64.git
branch = develop
commit = aa83d46b01ecf2551d56884c57dfe2ba499912c6
parent = ec89a72b52d92b89537234153fb2a86a33dddb4b
commit = d359d8f8e0e881fbc64d6ebd9b02b01a14dd3e70
parent = 524050007bf4b904115e68fa3f7911e044138d4f
method = rebase
cmdver = 0.4.1
cmdver = 0.4.0

View File

@ -3,10 +3,6 @@ image: Visual Studio 2017
version: 1.0.{build}
pull_requests:
do_not_increment_build_number: true
branches:
only:
- master
skip_branch_with_pr: true
environment:
BUILD_PATH: $(APPVEYOR_BUILD_FOLDER)\build

View File

@ -0,0 +1,284 @@
@echo off
setlocal enableextensions disabledelayedexpansion
cls
set DPROJ=GLideN64.sln
set DMN=REM
set ERR=if errorlevel 1 goto err
set MSG=%DPROJ% does not exist in the same directory
if not exist "%~dp0%DPROJ%" goto err
set ARCH=
set BOTH=0
set CONF=Release
set DLQT=0
set REB=
set NOQT=0
set NOWTL=0
set NOM64=0
set ESIM=0
set EBQ=explorer "."
taskkill /im msbuild.exe /f 2>nul
taskkill /im vctip.exe /f 2>nul
taskkill /im mspdbsrv.exe /f 2>nul
if "%*"=="" goto help
for %%P in (%*) do (
if /i "%%P"=="--clean" goto clean
if /i "%%P"=="--x86" set ARCH=x86
if /i "%%P"=="--x64" set ARCH=x64& set BOTH=0
if /i "%%P"=="--all" set ARCH=x64& set BOTH=1
if /i "%%P"=="--debug" set CONF=Debug
if /i "%%P"=="--rebuild" set REB=/t:Rebuild
if /i "%%P"=="--noqt" set NOQT=1
if /i "%%P"=="--nowtl" set NOWTL=1
if /i "%%P"=="--nom64" set NOM64=1
if /i "%%P"=="--dlqt" set DLQT=1
if /i "%%P"=="--sim" set ESIM=1
if /i "%%P"=="--q" set EBQ=REM
)
if not defined ARCH goto help
set /a MOD=%NOQT%+%NOWTL%+%NOM64%
set MSG=All compilation tasks were disabled on request
if %MOD%==3 goto err
set MSG=7z was not found in the environment
7z >nul 2>&1
%ERR%
set tVSPF=%ProgramFiles(x86)%
if "%PROCESSOR_ARCHITECTURE%"=="x86" set tVSPF=%ProgramFiles%
set "tVSPF=%tVSPF%\Microsoft Visual Studio"
set tVSDS=Common7\Tools\VsDevCmd.bat
set MOD=\Community\ \Enterprise\ \Professional\
goto vsbeg
:vsenv
for %%V in (%MOD%) do (
if exist "%tVSPF%%~1%%V%tVSDS%" set "tVSDS=%tVSPF%%~1%%V%tVSDS%"
)
goto:eof
:vsbeg
call :vsenv "\2019"
call :vsenv "\2017"
set MOD=\
call :vsenv " 14.0"
call :vsenv " 12.0"
set MSG=Visual Studio developer environment was not loaded
msbuild -version >nul 2>&1
if errorlevel 1 call "%tVSDS%"
%ERR%
set MSG=Git was not found in the environment
git --version >nul 2>&1
%ERR%
set "TARCH=%ARCH%"
:X86
pushd "%~dp0..\..\"
if "%ARCH%"=="x86" set TARCH=Win32
if %NOQT%==1 goto noqt
if defined QTDIR_%ARCH% goto nodl
set "QTVER=qt-5_7_1-%ARCH%-msvc2017-static"
if exist "..\Qt\%QTVER%\include\QtCore" goto nodl
set MSG=Path to Qt %ARCH% was not specified or detected
if %DLQT%==0 goto err
set MSG=cURL was not found in the environment
curl --version >nul 2>&1
%ERR%
del /f /q "..\%QTVER%.7z" 2>nul
set errorlevel=0
set QTURL=https://github.com/gonetz/GLideN64/releases/download/qt_build
set MSG=cURL failed to download:^& echo %QTURL%/%QTVER%.7z
curl -L -o "..\%QTVER%.7z" "%QTURL%/%QTVER%.7z"
%ERR%
set MSG=7z failed to extract:^& echo %QTVER%.7z
7z x -y "..\%QTVER%.7z" -o"..\Qt"
%ERR%
:nodl
set "QTDIR=%~dp0..\..\..\Qt\%QTVER%"
if "%ARCH%"=="x64" (
if defined QTDIR_x64 set "QTDIR="%QTDIR_x64%""
) else (
if defined QTDIR_x86 set "QTDIR="%QTDIR_x86%""
)
set QTDIR=%QTDIR:"=%
set MSG=Something went wrong when detecting Qt:^& echo %QTDIR%
if not exist "%QTDIR%\include\QtCore" goto err
:noqt
if not defined BUILDROUTE set "BUILDROUTE="%~dp0..\..\build""
set BUILDROUTE=%BUILDROUTE:"=%
set "PJ64QT=%BUILDROUTE%\QT_for_Project64_%ARCH%"
set "PJ64WTL=%BUILDROUTE%\WTL_for_Project64_%ARCH%"
set "M64CL=%BUILDROUTE%\for_Mupen64Plus_%ARCH%"
set JACK=
if "%ARCH%"=="x64" set JACK=_x64
set "PJ64PluginsDirQT%JACK%=%PJ64QT%"
set "PJ64PluginsDirWTL%JACK%=%PJ64WTL%"
set "Mupen64PluginsDir%JACK%=%M64CL%"
set MOD=%random:~0,1%
if %MOD% LEQ 4 (set MOD=Lylat) else (
if %MOD% GEQ 8 (set MOD=Kildean) else set MOD=Caryll)
set MBQT=msbuild
if %ESIM%==1 (
set "MBQT=echo %MBQT%"
md "translations\wtl" 2>nul
cd.>"translations\wtl\%MOD%.Lang"
del /f /q "%BUILDROUTE%\*_%ARCH%.7z" 2>nul
set errorlevel=0
)
set "MBWTL=%MBQT%"
set "MBM64=%MBQT%"
if %NOQT%==1 set MBQT=REM
if %NOWTL%==1 set MBWTL=REM
if %NOM64%==1 set MBM64=REM
set "PTS=Platform=%TARCH%"
if defined TOOLSET set "PTS="%PTS%;PlatformToolset=%TOOLSET%""
set PTS=%PTS:"=%
goto mbbeg
:mbcl
%~1 "%~dp0%~2" /m /p:Configuration=%CONF%%~3;%PTS% %REB%
%ERR%
echo.
goto:eof
:mbbeg
set MSG=Qt version, architecture and path are really correct?^& echo %QTDIR%
call :mbcl "%MBQT%" "GLideNUI.vcxproj" ""
%DMN%
call :mbcl "%MBQT%" "%DPROJ%" "_qt"
%DMN%
set MSG=ERROR!
call :mbcl "%MBWTL%" "GLideNUI-wtl.vcxproj" ""
%DMN%
call :mbcl "%MBWTL%" "%DPROJ%" "_wtl"
%DMN%
call :mbcl "%MBM64%" "%DPROJ%" "_mupenplus"
%DMN%
goto pjqt
:cini
set MSG=Failed to copy some project files to:^&echo %~1
if %ESIM%==1 md "%~1" 2>nul
set errorlevel=0
copy /y ini\GLideN64.custom.ini "%~1\"
%ERR%
del /f /q "%~1\*.lib" "%~1\*.exp" 2>nul
set errorlevel=0
goto:eof
:pjqt
if %NOQT%==1 goto pjwtl
call :cini "%PJ64QT%"
%DMN%
copy /y translations\release\*.qm "%PJ64QT%\"
%ERR%
:pjwtl
if %NOWTL%==1 goto mpcl
call :cini "%PJ64WTL%"
%DMN%
md "%PJ64WTL%\translations" 2>nul
set errorlevel=0
copy /y translations\wtl\*.Lang "%PJ64WTL%\translations\"
%ERR%
:mpcl
if %NOM64%==1 goto pkg
call :cini "%M64CL%"
%DMN%
:pkg
for /f "tokens=1" %%R in ('git describe --always') do set "REV=%%R"
set MSG=The route could not be accessed:^& echo %BUILDROUTE%
pushd "%BUILDROUTE%"
%ERR%
for /f "tokens=*" %%Z in ('dir /ad /b *_%ARCH%') do 7z a -t7z "GLideN64-%REV%-%%Z.7z" ".\%%Z\*"
if "%ARCH%"=="x64" (
if %BOTH%==1 set ARCH=x86& goto X86
)
set MSG=DONE!^& echo Path to the compressed files:^& echo %CD%
%EBQ%
:err
set WTF=%errorlevel%
set DMN=exit /b %WTF%
echo.
echo %MSG%
exit /b %WTF%
:clean
pushd "%~dp0"
for /f "tokens=*" %%E in ('dir /ad /b') do (
if /i "%%E" NEQ "lib" rd /s /q "%%E"
)
cd ..\..
del /f /q "src\Revision.h" 2>nul
rd /s /q "build" 2>nul
rd /s /q "translations\wtl" 2>nul
exit /b 0
:help
echo.
echo GLideN64's simplified build and packaging script
echo.
echo Usage:
echo set ^<variable^>
echo %~nx0 ^<architecture^> ^<other^>
echo.
echo ^<Variables^>
echo set BUILDROUTE=^<Custom build folder^>
echo e.g. "Z:\My share folder"
echo set QTDIR_x86=^<Your Qt x86 path^>
echo e.g. "D:\Static Qt\qt-5.7.1-x86-msvc2013"
echo set QTDIR_x64=^<Your Qt x64 path^>
echo e.g. F:\Qt\qt-5_7_1-x64-msvc2015-static
echo set TOOLSET=^<Custom PlatformToolset^>
echo e.g. v141_xp
echo.
echo ^<Architectures^>
echo --x86 To compile x86
echo --x64 To compile x64
echo --all To compile x86 and x64
echo n.b. If more than one of these is used, only the last one will
echo take effect
echo.
echo ^<Others^>
echo --clean Clean ALL auto-generated build files within the project
echo --debug For debug builds
echo --dlqt Auto download and configure Qt for VS2017-2019, it
echo would have no effect if QTDIR_x* is used or if the
echo same version has already been extracted
echo --noqt To build without Qt support, it will ignore the
echo effects of QTDIR_x* and "--dlqt"
echo --nowtl To skip WTL builds
echo --nom64 To skip mupen64plus builds
echo --rebuild To rebuild without cleaning
echo --sim Simulated build, quick environment check without compiling
echo It's destructive to the final product by creating
echo dummy files, make sure to use "--clean" afterwards
echo --q Don't interact with Windows Explorer at the end
echo.
echo Usage examples:
echo.
echo %~nx0 --all --dlqt
echo.
echo %~nx0 --x86 --debug --rebuild
echo.
echo set BUILDROUTE=H:\%USERNAME%\experiment
echo set TOOLSET=ClangCL
echo %~nx0 --noqt --x64
echo.
echo set QTDIR_x86="G:\Static Qt\qt-5.7.1-x86-msvc2015"
echo set QTDIR_x64=G:\Static Qt\qt-5.7.1-x64-msvc2015
echo %~nx0 --nowtl --nom64 --all
exit /b 0

View File

@ -79,7 +79,7 @@ End:
float len;
len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
if (len != 0.0) {
if (len != 0.0f) {
len = sqrtf( len );
v[0] /= len;
v[1] /= len;
@ -92,7 +92,7 @@ void InverseTransformVectorNormalizeN(float src[][3], float dst[][3], float mtx[
{
for (u32 i = 0; i < count; i++)
{
InverseTransformVectorNormalize((float(*))src[i], (float(*))dst[i], mtx);
InverseTransformVectorNormalize(static_cast<float*>(src[i]), static_cast<float*>(dst[i]), mtx);
}
}

View File

@ -42,7 +42,7 @@ inline float DotProduct(const float v0[3], const float v1[3])
inline float GetFloatMatrixElement(s16 _int, u16 _fract)
{
const s32 element = (_int << 16) | _fract;
const s32 element = static_cast<s32>((static_cast<u16>(_int) << 16) | _fract);
return _FIXED2FLOAT(element, 16);
}

View File

@ -97,6 +97,8 @@ void RDRAMtoColorBuffer::addAddress(u32 _address, u32 _size)
template <typename TSrc>
bool _copyBufferFromRdram(u32 _address, u32* _dst, u32(*converter)(TSrc _c, bool _bCFB), u32 _xor, u32 _x0, u32 _y0, u32 _width, u32 _height, bool _fullAlpha)
{
if ((_address & 1) != 0)
return false;
TSrc * src = reinterpret_cast<TSrc*>(RDRAM + _address);
const u32 bound = (RDRAMSize + 1 - _address) >> (sizeof(TSrc) / 2);
TSrc col;

View File

@ -1,17 +1,17 @@
#include "CRC.h"
#define CRC32_POLYNOMIAL 0x04C11DB7
#define CRC32_POLYNOMIAL 0x04C11DB7U
unsigned int CRCTable[ 256 ];
static unsigned int CRCTable[ 256 ];
static
u32 Reflect( u32 ref, char ch )
u32 Reflect( u32 ref, u32 ch )
{
u32 value = 0;
// Swap bit 0 for bit 7
// bit 1 for bit 6, etc.
for (int i = 1; i < (ch + 1); ++i) {
for (u32 i = 1; i < (ch + 1); ++i) {
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
@ -23,22 +23,21 @@ void CRC_Init()
{
u32 crc;
for (int i = 0; i < 256; ++i) {
crc = Reflect( i, 8 ) << 24;
for (u32 i = 0; i < 256; ++i) {
crc = Reflect( i, 8U ) << 24U;
for (int j = 0; j < 8; ++j)
crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
crc = (crc << 1U) ^ (crc & (1U << 31U) ? CRC32_POLYNOMIAL : 0U);
CRCTable[i] = Reflect( crc, 32 );
CRCTable[i] = Reflect( crc, 32U );
}
}
u64 CRC_Calculate( u64 crc, const void * buffer, u32 count )
{
u8 *p;
u32 crc32 = static_cast<u32>(crc);
u32 orig = crc32;
p = (u8*) buffer;
const u8 *p = reinterpret_cast<const u8*>(buffer);
while (count--)
crc32 = (crc32 >> 8) ^ CRCTable[(crc32 & 0xFF) ^ *p++];
@ -47,16 +46,15 @@ u64 CRC_Calculate( u64 crc, const void * buffer, u32 count )
u32 CRC_Calculate_Strict( u32 crc, const void * buffer, u32 count )
{
return CRC_Calculate(crc, buffer, count);
return static_cast<u32>(CRC_Calculate(crc, buffer, count));
}
u64 CRC_CalculatePalette(u64 crc, const void * buffer, u32 count )
{
u8 *p;
u32 crc32 = static_cast<u32>(crc);
u32 orig = crc32;
p = (u8*) buffer;
const u8 *p = reinterpret_cast<const u8*>(buffer);
while (count--) {
crc32 = (crc32 >> 8) ^ CRCTable[(crc32 & 0xFF) ^ *p++];
crc32 = (crc32 >> 8) ^ CRCTable[(crc32 & 0xFF) ^ *p++];

View File

@ -51,10 +51,10 @@
#define EncodeCombineMode( a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1 ) \
(u64)(((u64)(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \
static_cast<u64>((static_cast<u64>(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \
_SHIFTL( G_ACMUX_##Aa0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ac0, 9, 3 ) | \
_SHIFTL( G_CCMUX_##a1, 5, 4 ) | _SHIFTL( G_CCMUX_##c1, 0, 5 )) << 32) | \
(u64)(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \
static_cast<u64>(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \
_SHIFTL( G_ACMUX_##Ab0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ad0, 9, 3 ) | \
_SHIFTL( G_CCMUX_##b1, 24, 4 ) | _SHIFTL( G_ACMUX_##Aa1, 21, 3 ) | \
_SHIFTL( G_ACMUX_##Ac1, 18, 3 ) | _SHIFTL( G_CCMUX_##d1, 6, 3 ) | \
@ -91,30 +91,32 @@
#define G_GCI_ZERO 20
#define G_GCI_HALF 21
#define G_GCI_HW_LIGHT 22
#define G_GCI_HW_LIGHT 22
#define G_GCI_LAST 23
struct CombinerOp
{
int op = LOAD;
int param1 = -1;
int param2 = -1;
int param3 = -1;
u32 op = LOAD;
u32 param1 = G_GCI_LAST;
u32 param2 = G_GCI_LAST;
u32 param3 = G_GCI_LAST;
};
struct CombinerStage
{
int numOps;
u32 numOps;
CombinerOp op[6];
};
struct Combiner
{
int numStages;
u32 numStages;
CombinerStage stage[2];
};
struct CombineCycle
{
int sa, sb, m, a;
u32 sa, sb, m, a;
};
class CombinerInfo

View File

@ -66,7 +66,7 @@ bool CombinerKey::isRectKey() const
void CombinerKey::read(std::istream & _is)
{
_is.read((char*)&m_key.mux, sizeof(m_key.mux));
_is.read(reinterpret_cast<char*>(&m_key.mux), sizeof(m_key.mux));
}
const CombinerKey & CombinerKey::getEmpty()

View File

@ -257,7 +257,6 @@ void Debugger::_fillTriInfo(TriInfo & _info)
_info.fill_color = gDP.fillColor;
_info.blend_color = gDP.blendColor;
_info.env_color = gDP.envColor;
_info.fill_color = gDP.fillColor;
_info.prim_color = gDP.primColor;
_info.primDepthZ = gDP.primDepth.z;
_info.primDepthDeltaZ = gDP.primDepth.deltaZ;

View File

@ -17,17 +17,6 @@
using namespace graphics;
DepthBuffer::DepthBuffer()
: m_address(0)
, m_width(0)
, m_pDepthImageZTexture(nullptr)
, m_pDepthImageDeltaZTexture(nullptr)
, m_pDepthBufferTexture(nullptr)
, m_depthRenderbufferWidth(0)
, m_cleared(false)
, m_pResolveDepthBufferTexture(nullptr)
, m_resolved(false)
, m_pDepthBufferCopyTexture(nullptr)
, m_copied(false)
{
m_copyFBO = gfxContext.createFramebuffer();
}
@ -50,15 +39,15 @@ void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture&
{
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
_cachedTexture.width = (u32)(_pBuffer->m_pTexture->width);
_cachedTexture.height = (u32)(_pBuffer->m_pTexture->height);
_cachedTexture.width = _pBuffer->m_pTexture->width;
_cachedTexture.height = _pBuffer->m_pTexture->height;
_cachedTexture.format = 0;
_cachedTexture.size = 2;
_cachedTexture.clampS = 1;
_cachedTexture.clampT = 1;
_cachedTexture.address = _pBuffer->m_startAddress;
_cachedTexture.clampWidth = _pBuffer->m_width;
_cachedTexture.clampHeight = _pBuffer->m_height;
_cachedTexture.clampWidth = static_cast<u16>(_pBuffer->m_width);
_cachedTexture.clampHeight = static_cast<u16>(_pBuffer->m_height);
_cachedTexture.frameBufferTexture = CachedTexture::fbOneSample;
_cachedTexture.maskS = 0;
_cachedTexture.maskT = 0;
@ -117,22 +106,22 @@ void DepthBuffer::_initDepthBufferTexture(const FrameBuffer * _pBuffer, CachedTe
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
if (_pBuffer != nullptr) {
_pTexture->width = (u32)(_pBuffer->m_pTexture->width);
_pTexture->height = (u32)(_pBuffer->m_pTexture->height);
_pTexture->width = _pBuffer->m_pTexture->width;
_pTexture->height = _pBuffer->m_pTexture->height;
_pTexture->address = _pBuffer->m_startAddress;
_pTexture->clampWidth = _pBuffer->m_width;
_pTexture->clampHeight = VI_GetMaxBufferHeight(_pBuffer->m_width);
_pTexture->clampWidth = static_cast<u16>(_pBuffer->m_width);
_pTexture->clampHeight = VI_GetMaxBufferHeight(static_cast<u16>(_pBuffer->m_width));
} else {
const u16 maxHeight = VI_GetMaxBufferHeight(VI.width);
const u16 maxHeight = VI_GetMaxBufferHeight(static_cast<u16>(VI.width));
if (config.frameBufferEmulation.nativeResFactor == 0) {
_pTexture->width = dwnd().getWidth();
_pTexture->height = (u16)(u32)(maxHeight * dwnd().getScaleX());
_pTexture->width = static_cast<u16>(dwnd().getWidth());
_pTexture->height = static_cast<u16>(static_cast<u32>(static_cast<f32>(maxHeight) * dwnd().getScaleX()));
} else {
_pTexture->width = VI.width * config.frameBufferEmulation.nativeResFactor;
_pTexture->height = maxHeight * config.frameBufferEmulation.nativeResFactor;
_pTexture->width = static_cast<u16>(VI.width * config.frameBufferEmulation.nativeResFactor);
_pTexture->height = static_cast<u16>(maxHeight * config.frameBufferEmulation.nativeResFactor);
}
_pTexture->address = gDP.depthImageAddress;
_pTexture->clampWidth = VI.width;
_pTexture->clampWidth = static_cast<u16>(VI.width);
_pTexture->clampHeight = maxHeight;
}
_pTexture->format = 0;
@ -175,16 +164,16 @@ void DepthBuffer::_initDepthBufferRenderbuffer(FrameBuffer * _pBuffer)
if (m_depthRenderbuffer.isNotNull())
return;
u32 height;
if (_pBuffer != NULL) {
m_depthRenderbufferWidth = (u32)(_pBuffer->m_pTexture->width);
height = (u32)(_pBuffer->m_pTexture->height);
if (_pBuffer != nullptr) {
m_depthRenderbufferWidth = _pBuffer->m_pTexture->width;
height = _pBuffer->m_pTexture->height;
} else {
if (config.frameBufferEmulation.nativeResFactor == 0) {
m_depthRenderbufferWidth = dwnd().getWidth();
height = (u32)(VI_GetMaxBufferHeight(VI.width) * dwnd().getScaleX());
height = static_cast<u32>(static_cast<f32>(VI_GetMaxBufferHeight(static_cast<u16>(VI.width))) * dwnd().getScaleX());
} else {
m_depthRenderbufferWidth = VI.width * config.frameBufferEmulation.nativeResFactor;
height = VI_GetMaxBufferHeight(VI.width) * config.frameBufferEmulation.nativeResFactor;
height = VI_GetMaxBufferHeight(static_cast<u16>(VI.width)) * config.frameBufferEmulation.nativeResFactor;
}
}
@ -342,7 +331,7 @@ void DepthBuffer::bindDepthImageTexture(ObjectHandle _fbo)
bindParams.imageUnit = textureImageUnits::DepthDeltaZ;
bindParams.texture = m_pDepthImageDeltaZTexture->name;
gfxContext.bindImageTexture(bindParams);
} else if (Context::FramebufferFetch) {
} else if (Context::FramebufferFetchDepth) {
Context::FrameBufferRenderTarget targetParams;
targetParams.bufferHandle = _fbo;
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
@ -362,7 +351,7 @@ void DepthBuffer::bindDepthImageTexture(ObjectHandle _fbo)
DepthBufferList::DepthBufferList() : m_pCurrent(nullptr), m_pzLUT(nullptr)
{
m_pzLUT = new u16[0x40000];
for (int i = 0; i<0x40000; i++) {
for (u32 i = 0; i<0x40000; i++) {
u32 exponent = 0;
u32 testbit = 1 << 17;
while ((i & testbit) && (exponent < 7)) {
@ -371,7 +360,7 @@ DepthBufferList::DepthBufferList() : m_pCurrent(nullptr), m_pzLUT(nullptr)
}
const u32 mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff;
m_pzLUT[i] = (u16)(((exponent << 11) | mantissa) << 2);
m_pzLUT[i] = static_cast<u16>(((exponent << 11) | mantissa) << 2);
}
}

View File

@ -22,27 +22,28 @@ struct DepthBuffer
void bindDepthImageTexture(graphics::ObjectHandle _fbo);
u32 m_address, m_width;
bool m_cleared;
u32 m_address = 0;
u32 m_width = 0;
bool m_cleared = false;
CachedTexture *m_pDepthBufferTexture;
CachedTexture *m_pDepthBufferTexture = nullptr;
graphics::ObjectHandle m_depthRenderbuffer;
u32 m_depthRenderbufferWidth;
u32 m_depthRenderbufferWidth = 0;
CachedTexture *m_pDepthImageZTexture;
CachedTexture *m_pDepthImageDeltaZTexture;
CachedTexture *m_pDepthImageZTexture = nullptr;
CachedTexture *m_pDepthImageDeltaZTexture = nullptr;
graphics::ObjectHandle m_ZTextureClearFBO;
graphics::ObjectHandle m_DeltaZTextureClearFBO;
// multisampling
CachedTexture *m_pResolveDepthBufferTexture;
bool m_resolved;
CachedTexture *m_pResolveDepthBufferTexture = nullptr;
bool m_resolved = false;
// render to depth buffer
graphics::ObjectHandle m_copyFBO;
CachedTexture *m_pDepthBufferCopyTexture;
bool m_copied;
CachedTexture *m_pDepthBufferCopyTexture = nullptr;
bool m_copied = false;
static void copyDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *& _pTexture, graphics::ObjectHandle _copyFBO);
static void _initDepthBufferTexture(const FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample);

View File

@ -31,23 +31,33 @@ static int left_z, left_dzdy;
__inline int imul16(int x, int y) // (x * y) >> 16
{
return (((long long)x) * ((long long)y)) >> 16;
return (int)((unsigned long long)(((long long)x) * ((long long)y)) >> 16);
}
__inline int imul14(int x, int y) // (x * y) >> 14
{
return (((long long)x) * ((long long)y)) >> 14;
return (int)((unsigned long long)(((long long)x) * ((long long)y)) >> 14);
}
__inline int idiv16(int x, int y) // (x << 16) / y
{
x = (((long long)x) << 16) / ((long long)y);
return x;
return (int)((long long)((((unsigned long long)x) << 16)) / ((long long)y));
}
__inline int iceil(int x)
{
x += 0xffff;
return (x >> 16);
return x / 0x10000;
}
__inline int isub(int x, int y) // safe x - y
{
return (int)((long long)x - (long long)y);
}
__inline int isumm(int x, int y) // safe x + y
{
return (int)((long long)x + (long long)y);
}
static
@ -67,7 +77,7 @@ void RightSection(void)
// Calculate number of scanlines in this section
right_height = iceil(v2->y) - iceil(v1->y);
right_height = isub(iceil(v2->y), iceil(v1->y));
if (right_height <= 0)
return;
@ -77,21 +87,21 @@ void RightSection(void)
// OK, no worries, we have a section that is at least
// one pixel high. Calculate slope as usual.
int height = v2->y - v1->y;
right_dxdy = idiv16(v2->x - v1->x, height);
int height = isub(v2->y, v1->y);
right_dxdy = idiv16(isub(v2->x, v1->x), height);
} else {
// Height is less or equal to one pixel.
// Calculate slope = width * 1/height
// using 18:14 bit precision to avoid overflows.
int inv_height = (0x10000 << 14) / (v2->y - v1->y);
right_dxdy = imul14(v2->x - v1->x, inv_height);
int inv_height = (0x10000 << 14) / (isub(v2->y, v1->y));
right_dxdy = imul14(isub(v2->x, v1->x), inv_height);
}
// Prestep initial values
int prestep = (iceil(v1->y) << 16) - v1->y;
right_x = v1->x + imul16(prestep, right_dxdy);
int prestep = isub((iceil(v1->y) << 16), v1->y);
right_x = isumm(v1->x, imul16(prestep, right_dxdy));
}
static
@ -111,7 +121,7 @@ void LeftSection(void)
// Calculate number of scanlines in this section
left_height = iceil(v2->y) - iceil(v1->y);
left_height = isub(iceil(v2->y), iceil(v1->y));
if (left_height <= 0)
return;
@ -121,24 +131,24 @@ void LeftSection(void)
// OK, no worries, we have a section that is at least
// one pixel high. Calculate slope as usual.
int height = v2->y - v1->y;
left_dxdy = idiv16(v2->x - v1->x, height);
left_dzdy = idiv16(v2->z - v1->z, height);
int height = isub(v2->y, v1->y);
left_dxdy = idiv16(isub(v2->x, v1->x), height);
left_dzdy = idiv16(isub(v2->z, v1->z), height);
} else {
// Height is less or equal to one pixel.
// Calculate slope = width * 1/height
// using 18:14 bit precision to avoid overflows.
int inv_height = (0x10000 << 14) / (v2->y - v1->y);
left_dxdy = imul14(v2->x - v1->x, inv_height);
left_dzdy = imul14(v2->z - v1->z, inv_height);
int inv_height = (0x10000 << 14) / isub(v2->y, v1->y);
left_dxdy = imul14(isub(v2->x, v1->x), inv_height);
left_dzdy = imul14(isub(v2->z, v1->z), inv_height);
}
// Prestep initial values
int prestep = (iceil(v1->y) << 16) - v1->y;
left_x = v1->x + imul16(prestep, left_dxdy);
left_z = v1->z + imul16(prestep, left_dzdy);
left_x = isumm(v1->x, imul16(prestep, left_dxdy));
left_z = isumm(v1->z, imul16(prestep, left_dzdy));
}
@ -198,7 +208,7 @@ void Rasterize(vertexi * vtx, int vertices, int dzdx)
int shift;
const u16 * const zLUT = depthBufferList().getZLUT();
const u32 depthBufferWidth = depthBufferList().getCurrent()->m_width;
const s32 depthBufferWidth = static_cast<s32>(depthBufferList().getCurrent()->m_width);
for (;;) {
int x1 = iceil(left_x);
@ -212,8 +222,8 @@ void Rasterize(vertexi * vtx, int vertices, int dzdx)
// Prestep initial z
int prestep = (x1 << 16) - left_x;
int z = left_z + imul16(prestep, dzdx);
int prestep = isub((int)((unsigned int)x1 << 16), left_x);
int z = isumm(left_z, imul16(prestep, dzdx));
shift = x1 + y1*depthBufferWidth;
//draw to depth buffer
@ -228,7 +238,7 @@ void Rasterize(vertexi * vtx, int vertices, int dzdx)
idx = (shift + x) ^ 1;
if (encodedZ < destptr[idx])
destptr[idx] = encodedZ;
z = std::min(z + dzdx, 0x7fffffff);
z = isumm(z, dzdx);
}
}
@ -257,8 +267,8 @@ void Rasterize(vertexi * vtx, int vertices, int dzdx)
LeftSection();
} while (left_height <= 0);
} else {
left_x += left_dxdy;
left_z += left_dzdy;
left_x = isumm(left_x, left_dxdy);
left_z = isumm(left_z, left_dzdy);
}
}
}

View File

@ -129,8 +129,8 @@ void DisplayWindow::updateScale()
{
if (VI.width == 0 || VI.height == 0)
return;
m_scaleX = m_width / (float)VI.width;
m_scaleY = m_height / (float)VI.height;
m_scaleX = static_cast<f32>(m_width) / static_cast<f32>(VI.width);
m_scaleY = static_cast<f32>(m_height) / static_cast<f32>(VI.height);
}
void DisplayWindow::_setBufferSize()

View File

@ -7,7 +7,6 @@
#include "N64.h"
#include "RSP.h"
#include "RDP.h"
#include "gDP.h"
#include "VI.h"
#include "Textures.h"
#include "Combiner.h"
@ -32,41 +31,12 @@ using namespace std;
using namespace graphics;
FrameBuffer::FrameBuffer()
: m_startAddress(0)
, m_endAddress(0)
, m_size(0)
, m_width(0)
, m_height(0)
, m_originX(0)
, m_originY(0)
, m_swapCount(0)
, m_scale(0)
, m_copiedToRdram(false)
, m_fingerprint(false)
, m_cleared(false)
, m_changed(false)
, m_cfb(false)
, m_isDepthBuffer(false)
, m_isPauseScreen(false)
, m_isOBScreen(false)
, m_isMainBuffer(false)
, m_readable(false)
, m_loadType(LOADTYPE_BLOCK)
, m_pDepthBuffer(nullptr)
, m_pResolveTexture(nullptr)
, m_resolved(false)
, m_pSubTexture(nullptr)
, m_copied(false)
, m_pFrameBufferCopyTexture(nullptr)
, m_copyFBO(ObjectHandle::defaultFramebuffer)
, m_validityChecked(0)
: m_copyFBO(ObjectHandle::defaultFramebuffer)
{
m_loadTileOrigin.uls = m_loadTileOrigin.ult = 0;
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0 ?
textureTarget::TEXTURE_2D_MULTISAMPLE : textureTarget::TEXTURE_2D);
m_FBO = gfxContext.createFramebuffer();
m_pDepthTexture = nullptr;
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0)
m_depthFBO = gfxContext.createFramebuffer();
}
@ -91,8 +61,8 @@ void _initFrameBufferTexture(u32 _address, u16 _width, u16 _height, f32 _scale,
{
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
_pTexture->width = (u16)(u32)(_width * _scale);
_pTexture->height = (u16)(u32)(_height * _scale);
_pTexture->width = static_cast<u16>(static_cast<u32>(static_cast<f32>(_width) * _scale));
_pTexture->height = static_cast<u16>(static_cast<u32>(static_cast<f32>(_height) * _scale));
_pTexture->format = _format;
_pTexture->size = _size;
_pTexture->clampS = 1;
@ -253,7 +223,7 @@ void FrameBuffer::copyRdram()
// Validity check will see that the RDRAM is the same and thus the buffer is valid, which is false.
const u32 twoPercent = max(4U, dataSize / 200);
u32 start = m_startAddress >> 2;
u32 * pData = (u32*)RDRAM;
u32 * pData = reinterpret_cast<u32*>(RDRAM);
for (u32 i = 0; i < twoPercent; ++i) {
if (i < 4)
pData[start++] = fingerprint[i];
@ -282,17 +252,17 @@ bool FrameBuffer::isValid(bool _forceCheck) const
m_validityChecked = dwnd().getBuffersSwapCount();
}
const u32 * const pData = (const u32*)RDRAM;
const u32 * const pData = reinterpret_cast<const u32*>(RDRAM);
if (m_cleared) {
const u32 testColor = m_clearParams.fillcolor & 0xFFFEFFFE;
const u32 stride = m_width << m_size >> 1;
const s32 lry = (s32)_cutHeight(m_startAddress, m_clearParams.lry, stride);
const s32 lry = static_cast<s32>(_cutHeight(m_startAddress, static_cast<u32>(m_clearParams.lry), stride));
if (lry == 0)
return false;
const u32 ci_width_in_dwords = m_width >> (3 - m_size);
const u32 start = (m_startAddress >> 2) + m_clearParams.uly * ci_width_in_dwords;
const u32 start = (m_startAddress >> 2) + static_cast<u32>(m_clearParams.uly) * ci_width_in_dwords;
const u32 * dst = pData + start;
u32 wrongPixels = 0;
for (s32 y = m_clearParams.uly; y < lry; ++y) {
@ -381,7 +351,7 @@ bool FrameBuffer::_initSubTexture(u32 _t)
}
m_pSubTexture = textureCache().addFrameBufferTexture(textureTarget::TEXTURE_2D);
_initTexture(width, height, m_pTexture->format, m_pTexture->size, m_pSubTexture);
_initTexture(static_cast<u16>(width), static_cast<u16>(height), m_pTexture->format, m_pTexture->size, m_pSubTexture);
m_pSubTexture->clampS = pTile->clamps;
m_pSubTexture->clampT = pTile->clampt;
@ -404,8 +374,8 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t)
if (!_initSubTexture(_t))
return m_pTexture;
s32 x0 = (s32)(m_pTexture->offsetS * m_scale);
s32 y0 = (s32)(m_pTexture->offsetT * m_scale);
s32 x0 = static_cast<s32>(m_pTexture->offsetS * m_scale);
s32 y0 = static_cast<s32>(m_pTexture->offsetT * m_scale);
s32 copyWidth = m_pSubTexture->width;
if (x0 + copyWidth > m_pTexture->width)
copyWidth = m_pTexture->width - x0;
@ -448,7 +418,8 @@ void FrameBuffer::_initCopyTexture()
m_copyFBO = gfxContext.createFramebuffer();
m_pFrameBufferCopyTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0 ?
textureTarget::TEXTURE_2D_MULTISAMPLE : textureTarget::TEXTURE_2D);
_initTexture(m_width, VI_GetMaxBufferHeight(m_width), m_pTexture->format, m_pTexture->size, m_pFrameBufferCopyTexture);
_initTexture(static_cast<u16>(m_width), VI_GetMaxBufferHeight(static_cast<u16>(m_width)),
m_pTexture->format, m_pTexture->size, m_pFrameBufferCopyTexture);
_setAndAttachTexture(m_copyFBO, m_pFrameBufferCopyTexture, 0, config.video.multisampling != 0);
if (config.video.multisampling != 0)
m_pFrameBufferCopyTexture->frameBufferTexture = CachedTexture::fbMultiSample;
@ -503,37 +474,37 @@ CachedTexture * FrameBuffer::getTexture(u32 _t)
const u32 shift = (gSP.textureTile[_t]->imageAddress - m_startAddress) >> (m_size - 1);
const u32 factor = m_width;
if (m_loadType == LOADTYPE_TILE) {
pTexture->offsetS = (float)(m_loadTileOrigin.uls + (shift % factor));
pTexture->offsetT = (float)(m_loadTileOrigin.ult + shift / factor);
pTexture->offsetS = static_cast<f32>(m_loadTileOrigin.uls + (shift % factor));
pTexture->offsetT = static_cast<f32>(m_loadTileOrigin.ult + shift / factor);
} else {
pTexture->offsetS = (float)(shift % factor);
pTexture->offsetT = (float)(shift / factor);
pTexture->offsetS = static_cast<f32>(shift % factor);
pTexture->offsetT = static_cast<f32>(shift / factor);
}
if (!getDepthTexture && (gSP.textureTile[_t]->clamps == 0 || gSP.textureTile[_t]->clampt == 0))
pTexture = _getSubTexture(_t);
pTexture->scaleS = m_scale / (float)pTexture->width;
pTexture->scaleT = m_scale / (float)pTexture->height;
pTexture->scaleS = m_scale / static_cast<f32>(pTexture->width);
pTexture->scaleT = m_scale / static_cast<f32>(pTexture->height);
if (gSP.textureTile[_t]->shifts > 10)
pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[_t]->shifts));
pTexture->shiftScaleS = static_cast<f32>(1 << (16 - gSP.textureTile[_t]->shifts));
else if (gSP.textureTile[_t]->shifts > 0)
pTexture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[_t]->shifts);
pTexture->shiftScaleS = 1.0f / static_cast<f32>(1 << gSP.textureTile[_t]->shifts);
else
pTexture->shiftScaleS = 1.0f;
if (gSP.textureTile[_t]->shiftt > 10)
pTexture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[_t]->shiftt));
pTexture->shiftScaleT = static_cast<f32>(1 << (16 - gSP.textureTile[_t]->shiftt));
else if (gSP.textureTile[_t]->shiftt > 0)
pTexture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[_t]->shiftt);
pTexture->shiftScaleT = 1.0f / static_cast<f32>(1 << gSP.textureTile[_t]->shiftt);
else
pTexture->shiftScaleT = 1.0f;
return pTexture;
}
CachedTexture * FrameBuffer::getTextureBG(u32 _t)
CachedTexture * FrameBuffer::getTextureBG()
{
CachedTexture *pTexture = m_pTexture;
@ -544,8 +515,8 @@ CachedTexture * FrameBuffer::getTextureBG(u32 _t)
pTexture = _copyFrameBufferTexture();
}
pTexture->scaleS = m_scale / (float)pTexture->width;
pTexture->scaleT = m_scale / (float)pTexture->height;
pTexture->scaleS = m_scale / static_cast<f32>(pTexture->width);
pTexture->scaleT = m_scale / static_cast<f32>(pTexture->height);
pTexture->shiftScaleS = 1.0f;
pTexture->shiftScaleT = 1.0f;
@ -582,8 +553,8 @@ void FrameBufferList::destroy() {
void FrameBufferList::setBufferChanged(f32 _maxY)
{
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max(gDP.colorImage.height, (u32)_maxY);
gDP.colorImage.height = min(gDP.colorImage.height, (u32)gDP.scissor.lry);
gDP.colorImage.height = max(gDP.colorImage.height, static_cast<u32>(_maxY));
gDP.colorImage.height = min(gDP.colorImage.height, static_cast<u32>(gDP.scissor.lry));
if (m_pCurrent != nullptr) {
m_pCurrent->m_height = max(m_pCurrent->m_height, gDP.colorImage.height);
m_pCurrent->m_cfb = false;
@ -687,7 +658,7 @@ void FrameBufferList::_createScreenSizeBuffer()
return;
m_list.emplace_front();
FrameBuffer & buffer = m_list.front();
buffer.init(VI.width * 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, VI.width, false);
buffer.init(VI.width * 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, static_cast<u16>(VI.width), false);
}
void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb)
@ -696,7 +667,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
return;
if (_width == 512 && (config.generalEmulation.hacks & hack_RE2) != 0)
_width = *REG.VI_WIDTH;
_width = static_cast<u16>(*REG.VI_WIDTH);
if (config.frameBufferEmulation.enable == 0) {
if (m_list.empty())
@ -939,7 +910,7 @@ void FrameBufferList::attachDepthBuffer()
goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width == pCurrent->m_pTexture->width;
else
goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width >= pCurrent->m_pTexture->width ||
std::abs((s32)(pCurrent->m_width - pDepthBuffer->m_width)) < 2;
std::abs(static_cast<s32>(pCurrent->m_width) - static_cast<s32>(pDepthBuffer->m_width)) < 2;
} else {
goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->width;
}
@ -1077,7 +1048,7 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
const s32 delta_y = y2 - y1;
const u32 vitype = _SHIFTR( *REG.VI_STATUS, 0, 2 );
const bool serration_pulses = (*REG.VI_STATUS & 0x40) != 0;
const bool serration_pulses = (*REG.VI_STATUS & VI_STATUS_SERRATE_ENABLED) != 0;
const bool validinterlace = ((vitype & 2) != 0 ) && serration_pulses;
if (validinterlace && prevserrate && emucontrolsvicurrent < 0)
emucontrolsvicurrent = (*REG.VI_V_CURRENT_LINE & 1) != prevvicurrent ? 1 : 0;
@ -1107,8 +1078,8 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
s32 vres = delta_y;
s32 h_start = x1 - (ispal ? 128 : 108);
s32 v_start = (y1 - (ispal ? 44 : 34)) / 2;
u32 x_start = _SHIFTR(*REG.VI_X_SCALE, 16, 12);
u32 y_start = _SHIFTR(*REG.VI_Y_SCALE, 16, 12);
s32 x_start = _SHIFTR(*REG.VI_X_SCALE, 16, 12);
s32 y_start = _SHIFTR(*REG.VI_Y_SCALE, 16, 12);
bool h_start_clamped = h_start < 0;
if (h_start < 0) {
@ -1119,7 +1090,7 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
}
if (v_start < 0) {
y_start += (y_add * (u32)(-v_start));
y_start += (y_add * (-v_start));
v_start = 0;
}
@ -1131,7 +1102,7 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
if (vres + v_start > PRESCALE_HEIGHT)
vres = PRESCALE_HEIGHT - v_start;
s32 vactivelines = v_sync - (ispal ? 44 : 34);
s32 vactivelines = static_cast<s32>(v_sync - (ispal ? 44 : 34));
if (vactivelines > PRESCALE_HEIGHT) {
LOG(LOG_VERBOSE, "VI_V_SYNC_REG too big");
return false;
@ -1152,22 +1123,22 @@ bool FrameBufferList::RdpUpdate::update(RdpUpdateResult & _result)
prevwasblank = false;
_result.vi_hres = hres;
_result.vi_vres = vres;
_result.vi_hres = static_cast<u32>(hres);
_result.vi_vres = static_cast<u32>(vres);
_result.vi_ispal = ispal;
_result.vi_h_start = h_start;
_result.vi_v_start = v_start;
_result.vi_x_start = x_start;
_result.vi_y_start = y_start;
_result.vi_x_add = x_add;
_result.vi_y_add = y_add;
_result.vi_h_start = static_cast<u32>(h_start);
_result.vi_v_start = static_cast<u32>(v_start);
_result.vi_x_start = static_cast<u32>(x_start);
_result.vi_y_start = static_cast<u32>(y_start);
_result.vi_x_add = static_cast<u32>(x_add);
_result.vi_y_add = static_cast<u32>(y_add);
_result.vi_minhpass = h_start_clamped ? 0 : 8;
_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_fsaa = (*REG.VI_STATUS & 512) == 0;
_result.vi_divot = (*REG.VI_STATUS & 16) != 0;
_result.vi_divot = (*REG.VI_STATUS & VI_STATUS_DIVOT_ENABLED) != 0;
return true;
#if 0
@ -1236,7 +1207,7 @@ f32 FrameBufferList::OverscanBuffer::getScaleY(u32 _fullHeight) const
if (m_enabled)
return m_scale;
return (float)dwnd().getHeight() / float(_fullHeight);
return static_cast<f32>(dwnd().getHeight()) / static_cast<f32>(_fullHeight);
}
void FrameBufferList::OverscanBuffer::init()
@ -1342,14 +1313,14 @@ void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL)
const s32 bottom = static_cast<s32>(overscan.bottom * m_scale);
blitParams.srcX0 = left;
blitParams.srcY0 = static_cast<s32>(_fullHeight * m_scale) - bottom;
blitParams.srcX1 = m_bufferWidth - right;
blitParams.srcX1 = static_cast<s32>(m_bufferWidth) - right;
blitParams.srcY1 = top;
blitParams.srcWidth = m_pTexture->width;
blitParams.srcHeight = m_pTexture->height;
blitParams.dstX0 = m_hOffset;
blitParams.dstY0 = m_vOffset + wnd.getHeightOffset();
blitParams.dstX1 = m_hOffset + wnd.getWidth();
blitParams.dstY1 = m_vOffset + wnd.getHeight() + wnd.getHeightOffset();
blitParams.dstY0 = m_vOffset + static_cast<s32>(wnd.getHeightOffset());
blitParams.dstX1 = m_hOffset + static_cast<s32>(wnd.getWidth());
blitParams.dstY1 = m_vOffset + static_cast<s32>(wnd.getHeight() + wnd.getHeightOffset());
blitParams.dstWidth = wnd.getScreenWidth();
blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
blitParams.mask = blitMask::COLOR_BUFFER;
@ -1414,23 +1385,23 @@ void FrameBufferList::renderBuffer()
s32 srcPartHeight = 0;
s32 dstPartHeight = 0;
dstY0 = rdpRes.vi_v_start;
dstY0 = static_cast<s32>(rdpRes.vi_v_start);
const u32 vFullHeight = rdpRes.vi_ispal ? 288 : 240;
const f32 dstScaleY = m_overscan.getScaleY(vFullHeight);
const u32 addrOffset = ((rdpRes.vi_origin - pBuffer->m_startAddress) << 1 >> pBuffer->m_size);
srcY0 = addrOffset / pBuffer->m_width;
srcY0 = static_cast<s32>(addrOffset / pBuffer->m_width);
if ((addrOffset != 0) && (pBuffer->m_width == addrOffset * 2))
srcY0 = 1;
if ((rdpRes.vi_width != addrOffset * 2) && (addrOffset % rdpRes.vi_width != 0))
XoffsetRight = rdpRes.vi_width - addrOffset % rdpRes.vi_width;
if (XoffsetRight == pBuffer->m_width) {
XoffsetRight = static_cast<s32>(rdpRes.vi_width - addrOffset % rdpRes.vi_width);
if (XoffsetRight == static_cast<s32>(pBuffer->m_width)) {
XoffsetRight = 0;
} else if (XoffsetRight > static_cast<s32>(pBuffer->m_width / 2)) {
XoffsetRight = 0;
XoffsetLeft = addrOffset % rdpRes.vi_width;
XoffsetLeft = static_cast<s32>(addrOffset % rdpRes.vi_width);
}
if (!rdpRes.vi_lowerfield) {
@ -1445,8 +1416,8 @@ void FrameBufferList::renderBuffer()
XoffsetRight = XoffsetLeft = 0;
}
srcWidth = min(rdpRes.vi_width, (rdpRes.vi_hres * rdpRes.vi_x_add) >> 10);
srcHeight = rdpRes.vi_width * ((rdpRes.vi_vres*rdpRes.vi_y_add + rdpRes.vi_y_start) >> 10) / pBuffer->m_width;
srcWidth = static_cast<s32>(min(rdpRes.vi_width, (rdpRes.vi_hres * rdpRes.vi_x_add) >> 10));
srcHeight = static_cast<s32>(rdpRes.vi_width * ((rdpRes.vi_vres*rdpRes.vi_y_add + rdpRes.vi_y_start) >> 10) / pBuffer->m_width);
const u32 stride = pBuffer->m_width << pBuffer->m_size >> 1;
FrameBuffer *pNextBuffer = findBuffer(rdpRes.vi_origin + stride * min(u32(srcHeight) - 1, pBuffer->m_height - 1) - 1);
@ -1457,9 +1428,9 @@ void FrameBufferList::renderBuffer()
dstPartHeight = srcY0;
srcPartHeight = srcY0;
srcY1 = srcHeight;
dstY1 = dstY0 + rdpRes.vi_vres - dstPartHeight;
dstY1 = dstY0 + static_cast<s32>(rdpRes.vi_vres) - dstPartHeight;
} else {
dstY1 = dstY0 + rdpRes.vi_vres;
dstY1 = dstY0 + static_cast<s32>(rdpRes.vi_vres);
srcY1 = srcY0 + srcHeight;
}
PostProcessor & postProcessor = PostProcessor::get();
@ -1470,22 +1441,22 @@ void FrameBufferList::renderBuffer()
const f32 viScaleX = _FIXED2FLOAT(_SHIFTR(*REG.VI_X_SCALE, 0, 12), 10);
const f32 srcScaleX = pFilteredBuffer->m_scale;
const f32 dstScaleX = m_overscan.getDrawingWidth() / (640 * viScaleX);
const s32 hx0 = rdpRes.vi_h_start + rdpRes.vi_minhpass;
const s32 hx0 = static_cast<s32>(rdpRes.vi_h_start + rdpRes.vi_minhpass);
const s32 h0 = (rdpRes.vi_ispal ? 128 : 108);
const s32 hEnd = _SHIFTR(*REG.VI_H_START, 0, 10);
const s32 hx1 = max(0, h0 + 640 - hEnd + (s32)rdpRes.vi_maxhpass);
const s32 hx1 = max(0, h0 + 640 - hEnd + static_cast<s32>(rdpRes.vi_maxhpass));
//const s32 hx1 = hx0 + rdpRes.vi_hres;
dstX0 = (s32)((hx0 * viScaleX + f32(XoffsetRight)) * dstScaleX);
dstX1 = m_overscan.getDrawingWidth() - (s32)(hx1 * viScaleX * dstScaleX);
dstX0 = static_cast<s32>((hx0 * viScaleX + f32(XoffsetRight)) * dstScaleX);
dstX1 = static_cast<s32>(m_overscan.getDrawingWidth()) - static_cast<s32>(hx1 * viScaleX * dstScaleX);
const f32 srcScaleY = pFilteredBuffer->m_scale;
CachedTexture * pBufferTexture = pFilteredBuffer->m_pTexture;
const s32 cutleft = static_cast<s32>(rdpRes.vi_minhpass * viScaleX * srcScaleX);
const s32 cutright = static_cast<s32>(rdpRes.vi_maxhpass * viScaleX * srcScaleX);
s32 srcCoord[4] = { (s32)((XoffsetLeft) * srcScaleX) + cutleft,
(s32)(srcY0*srcScaleY),
(s32)((srcWidth + XoffsetLeft - XoffsetRight) * srcScaleX) - cutright,
min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->height) };
s32 srcCoord[4] = { static_cast<s32>((XoffsetLeft) * srcScaleX) + cutleft,
static_cast<s32>(srcY0*srcScaleY),
static_cast<s32>((srcWidth + XoffsetLeft - XoffsetRight) * srcScaleX) - cutright,
min(static_cast<s32>(srcY1*srcScaleY), static_cast<s32>(pBufferTexture->height)) };
if (srcCoord[2] > pBufferTexture->width || srcCoord[3] > pBufferTexture->height) {
removeBuffer(pBuffer->m_startAddress);
return;
@ -1494,9 +1465,9 @@ void FrameBufferList::renderBuffer()
const s32 hOffset = m_overscan.getHOffset();
const s32 vOffset = m_overscan.getVOffset();
s32 dstCoord[4] = { dstX0 + hOffset,
vOffset + (s32)(dstY0*dstScaleY),
vOffset + static_cast<s32>(dstY0*dstScaleY),
hOffset + dstX1,
vOffset + (s32)(dstY1*dstScaleY) };
vOffset + static_cast<s32>(dstY1*dstScaleY) };
ObjectHandle readBuffer;
@ -1566,11 +1537,11 @@ void FrameBufferList::renderBuffer()
}
blitParams.srcY0 = 0;
blitParams.srcY1 = min((s32)(srcY1*srcScaleY), (s32)pFilteredBuffer->m_pTexture->height);
blitParams.srcY1 = min(static_cast<s32>(srcY1*srcScaleY), static_cast<s32>(pFilteredBuffer->m_pTexture->height));
blitParams.srcWidth = pBufferTexture->width;
blitParams.srcHeight = pBufferTexture->height;
blitParams.dstY0 = vOffset + (s32)(dstY0*dstScaleY);
blitParams.dstY1 = vOffset + (s32)(dstY1*dstScaleY);
blitParams.dstY0 = vOffset + static_cast<s32>(dstY0*dstScaleY);
blitParams.dstY1 = vOffset + static_cast<s32>(dstY1*dstScaleY);
blitParams.dstWidth = m_overscan.getBufferWidth();
blitParams.dstHeight = m_overscan.getBufferHeight();
blitParams.tex[0] = pBufferTexture;
@ -1593,9 +1564,9 @@ void FrameBufferList::renderBuffer()
}
const s32 X = hOffset;
const s32 Y = wnd.getHeightOffset();
const s32 W = wnd.getWidth();
const s32 H = wnd.getHeight();
const s32 Y = static_cast<s32>(wnd.getHeightOffset());
const s32 W = static_cast<s32>(wnd.getWidth());
const s32 H = static_cast<s32>(wnd.getHeight());
gfxContext.setScissor(X, Y, W, H);
gDP.changed |= CHANGED_SCISSOR;
@ -1610,20 +1581,20 @@ void FrameBufferList::fillRDRAM(s32 ulx, s32 uly, s32 lrx, s32 lry)
// Do not write to RDRAM color buffer if copyFromRDRAM enabled.
return;
ulx = (s32)min(max((float)ulx, gDP.scissor.ulx), gDP.scissor.lrx);
lrx = (s32)min(max((float)lrx, gDP.scissor.ulx), gDP.scissor.lrx);
uly = (s32)min(max((float)uly, gDP.scissor.uly), gDP.scissor.lry);
lry = (s32)min(max((float)lry, gDP.scissor.uly), gDP.scissor.lry);
ulx = static_cast<s32>(min(max(static_cast<f32>(ulx), gDP.scissor.ulx), gDP.scissor.lrx));
lrx = static_cast<s32>(min(max(static_cast<f32>(lrx), gDP.scissor.ulx), gDP.scissor.lrx));
uly = static_cast<s32>(min(max(static_cast<f32>(uly), gDP.scissor.uly), gDP.scissor.lry));
lry = static_cast<s32>(min(max(static_cast<f32>(lry), gDP.scissor.uly), gDP.scissor.lry));
const u32 stride = gDP.colorImage.width << gDP.colorImage.size >> 1;
const u32 lowerBound = gDP.colorImage.address + lry*stride;
const u32 lowerBound = gDP.colorImage.address + static_cast<u32>(lry)*stride;
if (lowerBound > RDRAMSize)
lry -= (lowerBound - RDRAMSize) / stride;
u32 ci_width_in_dwords = gDP.colorImage.width >> (3 - gDP.colorImage.size);
ulx >>= (3 - gDP.colorImage.size);
lrx >>= (3 - gDP.colorImage.size);
u32 * dst = (u32*)(RDRAM + gDP.colorImage.address);
dst += uly * ci_width_in_dwords;
u32 * dst = reinterpret_cast<u32*>(RDRAM + gDP.colorImage.address);
dst += static_cast<u32>(uly) * ci_width_in_dwords;
if (!isMemoryWritable(dst, lowerBound - gDP.colorImage.address))
return;
for (s32 y = uly; y < lry; ++y) {
@ -1657,7 +1628,7 @@ void FrameBuffer_ActivateBufferTextureBG(u32 t, u32 _frameBufferAddress)
if (pBuffer == nullptr)
return;
CachedTexture *pTexture = pBuffer->getTextureBG(t);
CachedTexture *pTexture = pBuffer->getTextureBG();
if (pTexture == nullptr)
return;
@ -1719,7 +1690,7 @@ u32 cutHeight(u32 _address, u32 _height, u32 _stride)
void calcCoordsScales(const FrameBuffer * _pBuffer, f32 & _scaleX, f32 & _scaleY)
{
const u32 bufferWidth = _pBuffer != nullptr ? _pBuffer->m_width : VI.width;
const u32 bufferHeight = VI_GetMaxBufferHeight(bufferWidth);
const u32 bufferHeight = VI_GetMaxBufferHeight(static_cast<u16>(bufferWidth));
_scaleX = 1.0f / f32(bufferWidth);
_scaleY = 1.0f / f32(bufferHeight);
}

View File

@ -4,14 +4,14 @@
#include <list>
#include <vector>
#include "Types.h"
#include "gDP.h"
#include "Textures.h"
#include "Graphics/ObjectHandle.h"
struct gDPTile;
struct DepthBuffer;
const int fingerprint[4] = { 2, 6, 4, 3 };
const u32 fingerprint[4] = { 2, 6, 4, 3 };
struct FrameBuffer
{
@ -22,59 +22,60 @@ struct FrameBuffer
void resolveMultisampledTexture(bool _bForce = false);
void copyDepthTexture();
CachedTexture * getTexture(u32 _t);
CachedTexture * getTextureBG(u32 _t);
CachedTexture * getTextureBG();
void setBufferClearParams(u32 _fillcolor, s32 _ulx, s32 _uly, s32 _lrx, s32 _lry);
void copyRdram();
void setDirty();
bool isValid(bool _forceCheck) const;
bool isAuxiliary() const;
u32 m_startAddress;
u32 m_endAddress;
u32 m_size;
u32 m_width;
u32 m_height;
u32 m_originX;
u32 m_originY;
u32 m_swapCount;
float m_scale;
bool m_copiedToRdram;
bool m_fingerprint;
bool m_cleared;
bool m_changed;
bool m_cfb;
bool m_isDepthBuffer;
bool m_isPauseScreen;
bool m_isOBScreen;
bool m_isMainBuffer;
bool m_readable;
bool m_copied;
u32 m_startAddress = 0;
u32 m_endAddress = 0;
u32 m_size = 0;
u32 m_width = 0;
u32 m_height = 0;
u32 m_originX = 0;
u32 m_originY = 0;
u32 m_swapCount = 0;
float m_scale = 0.0f;
bool m_copiedToRdram = false;
bool m_fingerprint = false;
bool m_cleared = false;
bool m_changed = false;
bool m_cfb = false;
bool m_isDepthBuffer = false;
bool m_isPauseScreen = false;
bool m_isOBScreen = false;
bool m_isMainBuffer = false;
bool m_readable = false;
bool m_copied = false;
struct {
u32 uls, ult;
u32 uls = 0;
u32 ult = 0;;
} m_loadTileOrigin;
u32 m_loadType;
u32 m_loadType = LOADTYPE_BLOCK;
graphics::ObjectHandle m_FBO;
CachedTexture *m_pTexture;
CachedTexture *m_pTexture = nullptr;
graphics::ObjectHandle m_depthFBO;
CachedTexture *m_pDepthTexture;
CachedTexture *m_pDepthTexture = nullptr;
DepthBuffer *m_pDepthBuffer;
DepthBuffer *m_pDepthBuffer = nullptr;
// multisampling
graphics::ObjectHandle m_resolveFBO;
CachedTexture *m_pResolveTexture;
bool m_resolved;
CachedTexture *m_pResolveTexture = nullptr;
bool m_resolved = false;
// subtexture
graphics::ObjectHandle m_SubFBO;
CachedTexture *m_pSubTexture;
CachedTexture *m_pSubTexture = nullptr;
// copy FBO
graphics::ObjectHandle m_copyFBO;
CachedTexture * m_pFrameBufferCopyTexture;
CachedTexture * m_pFrameBufferCopyTexture = nullptr;
std::vector<u8> m_RdramCopy;
@ -94,7 +95,7 @@ private:
CachedTexture * _copyFrameBufferTexture();
CachedTexture * _getSubTexture(u32 _t);
mutable u32 m_validityChecked;
mutable u32 m_validityChecked = false;
};
class FrameBufferList

View File

@ -199,6 +199,7 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
switch (m_pCurrent->type) {
case F3D:
case Turbo3D:
F3D_Init();
m_hwlSupported = true;
break;
@ -262,10 +263,6 @@ void GBIInfo::_makeCurrent(MicrocodeInfo * _pCurrent)
F3DAM_Init();
m_hwlSupported = true;
break;
case Turbo3D:
F3D_Init();
m_hwlSupported = true;
break;
case ZSortp:
ZSort_Init();
m_hwlSupported = true;

View File

@ -56,21 +56,21 @@
#define FIXED2FLOATRECIP16 1.52587890625e-05f
#define _FIXED2FLOAT( v, b ) \
((f32)v * FIXED2FLOATRECIP##b)
(static_cast<f32>(v) * FIXED2FLOATRECIP##b)
#define FIXED2FLOATRECIPCOLOR5 3.22580635547637939453125e-02f
#define FIXED2FLOATRECIPCOLOR7 7.8740157186985015869140625e-03f
#define FIXED2FLOATRECIPCOLOR8 3.9215688593685626983642578125e-03f
#define _FIXED2FLOATCOLOR( v, b ) \
((f32)v * FIXED2FLOATRECIPCOLOR##b)
(static_cast<f32>(v) * FIXED2FLOATRECIPCOLOR##b)
// Useful macros for decoding GBI command's parameters
#define _SHIFTL( v, s, w ) \
(((u32)v & ((0x01 << w) - 1)) << s)
((static_cast<u32>(v) & ((0x01 << w) - 1)) << s)
#define _SHIFTR( v, s, w ) \
(((u32)v >> s) & ((0x01 << w) - 1))
((static_cast<u32>(v) >> s) & ((0x01 << w) - 1))
// These are all the constant flags
#define G_ZBUFFER 0x00000001

View File

@ -13,7 +13,8 @@ bool Context::ShaderProgramBinary = false;
bool Context::ImageTextures = false;
bool Context::IntegerTextures = false;
bool Context::ClipControl = false;
bool Context::FramebufferFetch = false;
bool Context::FramebufferFetchDepth = false;
bool Context::FramebufferFetchColor = false;
bool Context::TextureBarrier = false;
bool Context::EglImage = false;
bool Context::EglImageFramebuffer = false;
@ -39,7 +40,8 @@ void Context::init()
ImageTextures = m_impl->isSupported(SpecialFeatures::ImageTextures);
IntegerTextures = m_impl->isSupported(SpecialFeatures::IntegerTextures);
ClipControl = m_impl->isSupported(SpecialFeatures::ClipControl);
FramebufferFetch = m_impl->isSupported(SpecialFeatures::FramebufferFetch);
FramebufferFetchDepth = m_impl->isSupported(SpecialFeatures::FramebufferFetchDepth);
FramebufferFetchColor = m_impl->isSupported(SpecialFeatures::FramebufferFetchColor);
TextureBarrier = m_impl->isSupported(SpecialFeatures::TextureBarrier);
EglImage = m_impl->isSupported(SpecialFeatures::EglImage);
EglImageFramebuffer = m_impl->isSupported(SpecialFeatures::EglImageFramebuffer);

View File

@ -24,7 +24,8 @@ namespace graphics {
ImageTextures,
IntegerTextures,
ClipControl,
FramebufferFetch,
FramebufferFetchDepth,
FramebufferFetchColor,
TextureBarrier,
EglImage,
EglImageFramebuffer,
@ -299,7 +300,8 @@ namespace graphics {
static bool ImageTextures;
static bool IntegerTextures;
static bool ClipControl;
static bool FramebufferFetch;
static bool FramebufferFetchDepth;
static bool FramebufferFetchColor;
static bool TextureBarrier;
static bool EglImage;
static bool EglImageFramebuffer;

View File

@ -37,9 +37,6 @@ namespace graphics {
u32 noiseFormatBytes;
virtual ~FramebufferTextureFormats() {}
protected:
virtual void init() = 0;
};
}

View File

@ -40,7 +40,7 @@ bool CombinerInputs::usesHwLighting() const
return (m_inputs & (1 << G_GCI_HW_LIGHT)) != 0;
}
void CombinerInputs::addInput(int _input)
void CombinerInputs::addInput(u32 _input)
{
m_inputs |= 1 << _input;
}

View File

@ -26,7 +26,7 @@ namespace glsl {
bool usesHwLighting() const;
void addInput(int _input);
void addInput(u32 _input);
void operator+=(const CombinerInputs & _other);

View File

@ -95,7 +95,7 @@ const char *AlphaInput[] = {
};
inline
int correctFirstStageParam(int _param)
u32 correctFirstStageParam(u32 _param)
{
switch (_param) {
case G_GCI_TEXEL1:
@ -109,7 +109,7 @@ int correctFirstStageParam(int _param)
static
void _correctFirstStageParams(CombinerStage & _stage)
{
for (int i = 0; i < _stage.numOps; ++i) {
for (u32 i = 0; i < _stage.numOps; ++i) {
_stage.op[i].param1 = correctFirstStageParam(_stage.op[i].param1);
_stage.op[i].param2 = correctFirstStageParam(_stage.op[i].param2);
_stage.op[i].param3 = correctFirstStageParam(_stage.op[i].param3);
@ -117,7 +117,7 @@ void _correctFirstStageParams(CombinerStage & _stage)
}
inline
int correctFirstStageParam2Cyc(int _param)
u32 correctFirstStageParam2Cyc(u32 _param)
{
switch (_param) {
case G_GCI_COMBINED:
@ -129,7 +129,7 @@ int correctFirstStageParam2Cyc(int _param)
static
void _correctFirstStageParams2Cyc(CombinerStage & _stage)
{
for (int i = 0; i < _stage.numOps; ++i) {
for (u32 i = 0; i < _stage.numOps; ++i) {
_stage.op[i].param1 = correctFirstStageParam2Cyc(_stage.op[i].param1);
_stage.op[i].param2 = correctFirstStageParam2Cyc(_stage.op[i].param2);
_stage.op[i].param3 = correctFirstStageParam2Cyc(_stage.op[i].param3);
@ -137,7 +137,7 @@ void _correctFirstStageParams2Cyc(CombinerStage & _stage)
}
inline
int correctSecondStageParam(int _param)
u32 correctSecondStageParam(u32 _param)
{
switch (_param) {
case G_GCI_TEXEL0:
@ -154,7 +154,7 @@ int correctSecondStageParam(int _param)
static
void _correctSecondStageParams(CombinerStage & _stage) {
for (int i = 0; i < _stage.numOps; ++i) {
for (u32 i = 0; i < _stage.numOps; ++i) {
_stage.op[i].param1 = correctSecondStageParam(_stage.op[i].param1);
_stage.op[i].param2 = correctSecondStageParam(_stage.op[i].param2);
_stage.op[i].param3 = correctSecondStageParam(_stage.op[i].param3);
@ -165,7 +165,7 @@ static
CombinerInputs _compileCombiner(const CombinerStage & _stage, const char** _Input, std::stringstream & _strShader) {
bool bBracketOpen = false;
CombinerInputs inputs;
for (int i = 0; i < _stage.numOps; ++i) {
for (u32 i = 0; i < _stage.numOps; ++i) {
switch (_stage.op[i].op) {
case LOAD:
// sprintf(buf, "(%s ", _Input[_stage.op[i].param1]);
@ -516,12 +516,16 @@ public:
ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl;
if (_glinfo.dual_source_blending)
ss << "#extension GL_EXT_blend_func_extended : enable" << std::endl;
if (_glinfo.ext_fetch)
ss << "#extension GL_EXT_shader_framebuffer_fetch : enable" << std::endl;
if (_glinfo.ext_fetch_arm)
ss << "#extension GL_ARM_shader_framebuffer_fetch : enable" << std::endl;
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast) {
if (_glinfo.imageTextures && _glinfo.fragment_interlockNV) {
ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
} else if (_glinfo.ext_fetch)
ss << "#extension GL_EXT_shader_framebuffer_fetch : enable" << std::endl;
}
}
ss << "# define IN in" << std::endl
<< "# define OUT out" << std::endl
@ -585,17 +589,9 @@ public:
" srcColor1 = muxp; \n"
" dstFactor1 = muxaf; \n"
" } \n"
" fragColor = srcColor1; \n"
" fragColor1 = vec4(dstFactor1); \n"
;
if (_glinfo.dual_source_blending) {
m_part +=
" fragColor = srcColor1; \n"
" fragColor1 = vec4(dstFactor1); \n"
;
} else {
m_part +=
" fragColor = vec4(srcColor1.rgb, clampedColor.a); \n"
;
}
#else
// Keep old code for reference
m_part =
@ -637,17 +633,9 @@ public:
" srcColor2 = muxp; \n"
" dstFactor2 = muxaf; \n"
" } \n"
" fragColor = srcColor2; \n"
" fragColor1 = vec4(dstFactor2); \n"
;
if (_glinfo.dual_source_blending) {
m_part +=
" fragColor = srcColor2; \n"
" fragColor1 = vec4(dstFactor2); \n"
;
} else {
m_part +=
" fragColor = vec4(srcColor2.rgb, clampedColor.a); \n"
;
}
#else
// Keep old code for reference
@ -670,18 +658,23 @@ class ShaderBlenderAlpha : public ShaderPart
public:
ShaderBlenderAlpha(const opengl::GLInfo & _glinfo)
{
if (_glinfo.dual_source_blending)
m_part +=
"if (uBlendAlphaMode != 2) { \n"
" lowp float cvg = clampedColor.a; \n"
" lowp vec4 srcAlpha = vec4(cvg, cvg, 1.0, 0.0); \n"
" lowp vec4 dstFactorAlpha = vec4(1.0, 1.0, 0.0, 1.0); \n"
" if (uBlendAlphaMode == 0) \n"
" dstFactorAlpha[0] = 0.0; \n"
" fragColor.a = srcAlpha[uCvgDest]; \n"
" fragColor1.a = dstFactorAlpha[uCvgDest]; \n"
"} else fragColor.a = clampedColor.a; \n"
;
if (_glinfo.dual_source_blending || _glinfo.ext_fetch || _glinfo.ext_fetch_arm) {
m_part +=
"if (uBlendAlphaMode != 2) { \n"
" lowp float cvg = clampedColor.a; \n"
" lowp vec4 srcAlpha = vec4(cvg, cvg, 1.0, 0.0); \n"
" lowp vec4 dstFactorAlpha = vec4(1.0, 1.0, 0.0, 1.0); \n"
" if (uBlendAlphaMode == 0) \n"
" dstFactorAlpha[0] = 0.0; \n"
" fragColor1.a = dstFactorAlpha[uCvgDest]; \n"
" fragColor.a = srcAlpha[uCvgDest] + lastFragColor.a * fragColor1.a;\n"
"} else fragColor.a = clampedColor.a; \n";
}
else {
m_part +=
"fragColor.a = clampedColor.a;"
;
}
}
};
@ -829,14 +822,14 @@ public:
}
m_part +=
" lowp mat4 bayer = mat4( 0.0, 0.75, 0.1875, 0.9375, \n"
" 0.5, 0.25, 0.6875, 0.4375, \n"
" 0.125, 0.875, 0.0625, 0.8125, \n"
" 0.625, 0.375, 0.5625, 0.3125); \n"
" lowp mat4 mSquare = mat4( 0.0, 0.6875, 0.75, 0.4375, \n"
" 0.875, 0.3125, 0.125, 0.5625, \n"
" 0.1875, 0.5, 0.9375, 0.25, \n"
" 0.8125, 0.375, 0.0625, 0.625); \n"
" lowp mat4 bayer = mat4( 0.0, 0.5, 0.125, 0.625, \n"
" 0.5, 0.0, 0.625, 0.125, \n"
" 0.375, 0.875, 0.25, 0.75, \n"
" 0.875, 0.375, 0.75, 0.25); \n"
" lowp mat4 mSquare = mat4( 0.0, 0.75, 0.125, 0.875, \n"
" 0.5, 0.25, 0.625, 0.375, \n"
" 0.375, 0.625, 0.25, 0.5, \n"
" 0.875, 0.125, 0.75, 0.0); \n"
// Try to keep dithering visible even at higher resolutions
" lowp float divider = 1.0 + step(3.0, uScreenScale.x); \n"
" mediump ivec2 position = ivec2(mod((gl_FragCoord.xy - 0.5) / divider,4.0));\n"
@ -991,13 +984,28 @@ public:
if (_glinfo.dual_source_blending) {
m_part +=
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n"
;
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n" // SECONDARY FRAGMENT SHADER OUTPUT
"#define LAST_FRAG_COLOR vec4(0.0) \n" // DUMMY
;
} else if (_glinfo.ext_fetch) {
m_part +=
"layout(location = 0) inout lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR fragColor \n" // CURRENT FRAMEBUFFER COLOR/ALPHA
;
} else if (_glinfo.ext_fetch_arm) {
m_part +=
"OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR gl_LastFragColorARM \n" // CURRENT FRAMEBUFFER COLOR/ALPHA
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
;
"OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR vec4(0.0) \n" // DUMMY
;
}
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
@ -1082,13 +1090,28 @@ public:
if (_glinfo.dual_source_blending) {
m_part +=
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n"
;
"layout(location = 0, index = 0) OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"layout(location = 0, index = 1) OUT lowp vec4 fragColor1; \n" // SECONDARY FRAGMENT SHADER OUTPUT
"#define LAST_FRAG_COLOR vec4(0.0) \n" // DUMMY
;
} else if (_glinfo.ext_fetch) {
m_part +=
"layout(location = 0) inout lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR fragColor \n" // CURRENT FRAMEBUFFER COLOR/ALPHA
;
} else if (_glinfo.ext_fetch_arm) {
m_part +=
"OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR gl_LastFragColorARM \n" // CURRENT FRAMEBUFFER COLOR/ALPHA
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
;
"OUT lowp vec4 fragColor; \n" // MAIN FRAGMENT SHADER OUTPUT
"lowp vec4 fragColor1; \n" // DUMMY
"#define LAST_FRAG_COLOR vec4(0.0) \n" // DUMMY
;
}
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
@ -1502,13 +1525,14 @@ public:
" #define MUXB(pos) dot(muxB, STVEC(pos)) \n"
" #define MUXPM(pos) muxPM*(STVEC(pos)) \n"
" #define MUXF(pos) dot(muxF, STVEC(pos)) \n"
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n"
" lowp vec4 lastFragColor = LAST_FRAG_COLOR; \n"
" lowp mat4 muxPM = mat4(vec4(0.0), lastFragColor, uBlendColor, uFogColor); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, shadeColor.a, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, lastFragColor.a, 1.0, 0.0); \n"
" lowp vec4 muxF = vec4(0.0, 1.0, 0.0, 0.0); \n"
" lowp vec4 muxp, muxm, srcColor1, srcColor2; \n"
" lowp float muxa, muxb, dstFactor1, dstFactor2, muxaf, muxbf; \n"
;
;
}
}
};
@ -1706,10 +1730,10 @@ public:
}
};
class ShaderFragmentMainEnd : public ShaderPart
class ShaderFragmentMainEndSpecial : public ShaderPart
{
public:
ShaderFragmentMainEnd(const opengl::GLInfo & _glinfo)
ShaderFragmentMainEndSpecial(const opengl::GLInfo & _glinfo)
{
if (_glinfo.isGLES2) {
m_part =
@ -1724,6 +1748,23 @@ public:
}
};
class ShaderFragmentMainEnd : public ShaderPart
{
public:
ShaderFragmentMainEnd(const opengl::GLInfo & _glinfo)
{
if (_glinfo.isGLES2) {
m_part =
" gl_FragColor = fragColor; \n"
"} \n\n";
} else {
m_part =
"} \n\n"
;
}
}
};
class ShaderNoise : public ShaderPart
{
public:
@ -2121,7 +2162,7 @@ public:
class ShaderCalcLight : public ShaderPart
{
public:
ShaderCalcLight(const opengl::GLInfo & _glinfo)
ShaderCalcLight(const opengl::GLInfo & /*_glinfo*/)
{
m_part =
"uniform mediump vec3 uLightDirection[8]; \n"
@ -2673,7 +2714,7 @@ CombinerInputs CombinerProgramBuilder::compileCombiner(const CombinerKey & _key,
m_legacyBlender->write(ssShader);
}
_strShader = std::move(ssShader.str());
_strShader = ssShader.str();
return inputs;
}
@ -2815,7 +2856,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_shaderN64DepthRender->write(ssShader);
const std::string strFragmentShader(std::move(ssShader.str()));
const std::string strFragmentShader(ssShader.str());
/* Create shader program */
@ -2869,7 +2910,7 @@ GLuint _createVertexShader(ShaderPart * _header, ShaderPart * _body, ShaderPart
_header->write(ssShader);
_body->write(ssShader);
_footer->write(ssShader);
const std::string strShader(std::move(ssShader.str()));
const std::string strShader(ssShader.str());
const GLchar * strShaderData = strShader.data();
GLuint shader_object = glCreateShader(GL_VERTEX_SHADER);

View File

@ -974,12 +974,12 @@ public:
void update(bool _force) override
{
std::array<f32, 2> aTexWrap[2] = { {0.0f,0.0f}, {0.0f,0.0f} };
std::array<f32, 2> aTexClamp[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexWrapEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexClampEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexMirrorEn[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexSize[2] = { { 0.0f,0.0f },{ 0.0f,0.0f } };
std::array<f32, 2> aTexWrap[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
std::array<f32, 2> aTexClamp[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
std::array<f32, 2> aTexWrapEn[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
std::array<f32, 2> aTexClampEn[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
std::array<f32, 2> aTexMirrorEn[2] = { { 0.0f, 0.0f }, { 0.0f,0.0f }};
std::array<f32, 2> aTexSize[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
TextureCache & cache = textureCache();
const bool replaceTex1ByTex0 = needReplaceTex1ByTex0();
@ -997,12 +997,8 @@ public:
aTexSize[t][1] = pTexture->height * pTexture->hdRatioT;
/* Not sure if special treatment of framebuffer textures is correct */
if (pTexture->frameBufferTexture != CachedTexture::fbNone ||
pTile->textureMode != TEXTUREMODE_NORMAL ||
g_debugger.isDebugMode())
if (pTexture->frameBufferTexture != CachedTexture::fbNone)
{
aTexWrap[t][0] = pTexture->hdRatioS;
aTexWrap[t][1] = pTexture->hdRatioT;
aTexClamp[t][0] = f32(pTexture->width) * pTexture->hdRatioS - 1.0f;
aTexClamp[t][1] = f32(pTexture->height) * pTexture->hdRatioT - 1.0f;
aTexWrapEn[t][0] = 0.0;
@ -1011,6 +1007,13 @@ public:
aTexClampEn[t][1] = 1.0;
aTexMirrorEn[t][0] = 0.0;
aTexMirrorEn[t][1] = 0.0;
} else if (pTile->textureMode != TEXTUREMODE_NORMAL || g_debugger.isDebugMode()) {
aTexWrapEn[t][0] = 0.0;
aTexWrapEn[t][1] = 0.0;
aTexClampEn[t][0] = 0.0;
aTexClampEn[t][1] = 0.0;
aTexMirrorEn[t][0] = 0.0;
aTexMirrorEn[t][1] = 0.0;
} else {
aTexWrap[t][0] = f32(1 << pTile->masks) * pTexture->hdRatioS;
aTexWrap[t][1] = f32(1 << pTile->maskt) * pTexture->hdRatioT;

View File

@ -7,6 +7,7 @@ namespace glsl {
class ShaderPart
{
public:
virtual ~ShaderPart() {}
virtual void write(std::stringstream & shader) const
{
shader << m_part;

View File

@ -20,7 +20,7 @@ namespace glsl {
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
const u32 m_formatVersion = 0x2EU;
const u32 m_formatVersion = 0x2FU;
const u32 m_keysFormatVersion = 0x04;
const opengl::GLInfo & m_glinfo;
opengl::CachedUseProgram * m_useProgram;

View File

@ -360,48 +360,48 @@ namespace glsl {
static std::string strFilter =
"uniform sampler2D uTex0; \n"
" \n"
"ivec2 get_texture_size(sampler2D tex) \n"
"ivec2 get_texture_size() \n"
"{ \n"
" return textureSize(tex, 0); \n"
" return textureSize(uTex0, 0); \n"
"} \n"
" \n"
"mediump vec2 norm2denorm(sampler2D tex, mediump vec2 uv) \n"
"mediump vec2 norm2denorm(mediump vec2 uv) \n"
"{ \n"
" return uv * vec2(get_texture_size(tex)) - 0.5; \n"
" return uv * vec2(get_texture_size()) - 0.5; \n"
"} \n"
" \n"
"mediump vec2 denorm2norm(sampler2D tex, mediump vec2 denorm_uv) \n"
"mediump vec2 denorm2norm(mediump vec2 denorm_uv) \n"
"{ \n"
" return (denorm_uv + 0.5) / vec2(get_texture_size(tex)); \n"
" return (denorm_uv + 0.5) / vec2(get_texture_size()); \n"
"} \n"
" \n"
"mediump vec4 hybridFilter(sampler2D tex, mediump vec2 uv) \n"
"mediump vec4 hybridFilter(mediump vec2 uv) \n"
"{ \n"
" mediump vec2 denorm_uv = norm2denorm(tex, uv); \n"
" mediump vec2 denorm_uv = norm2denorm(uv); \n"
" mediump vec2 low_corner = floor(denorm_uv); \n"
" mediump vec2 ratio = denorm_uv - low_corner; \n"
" \n"
" /* \n"
" * 'radius' is the distance from the edge where interpolation happens. \n"
" * It's calculated based on how big a fragment is in denormalized \n"
" * texture coordinates. \n"
" * \n"
" * E.g.: If a texel maps to 5 fragments, then each fragment is \n"
" * 1/5 texels big. So the smooth transition should be between one and \n"
" * two fragments big, since there are enough fragments to show the full \n"
" * color of the texel. \n"
" * \n"
" * If a fragment is larger than one texel, we don't care, we're already \n"
" * sampling the wrong texels, and should be using mipmaps instead. \n"
" */ \n"
" \n"
" // Here, fwidth() is used to estimte how much denorm_uv changes per fragment.\n"
" // But we divide it by 2, since fwidth() is adding abs(dx) + abs(dy). \n"
/*
* 'radius' is the distance from the edge where interpolation happens.
* It's calculated based on how big a fragment is in denormalized
* texture coordinates.
*
* E.g.: If a texel maps to 5 fragments, then each fragment is
* 1/5 texels big. So the smooth transition should be between one and
* two fragments big, since there are enough fragments to show the full
* color of the texel.
*
* If a fragment is larger than one texel, we don't care, we're already
* sampling the wrong texels, and should be using mipmaps instead.
*/
// Here, fwidth() is used to estimte how much denorm_uv changes per fragment.
// But we divide it by 2, since fwidth() is adding abs(dx) + abs(dy).
" mediump vec2 fragment_size = fwidth(denorm_uv) / 2.0; \n"
" \n"
" mediump float is_frag_gt1, radius; \n"
" // Do nothing if fragment is greater than 1 texel \n"
" // Don't make the transition more than one fragment (+/- 0.5 fragment) \n"
// Do nothing if fragment is greater than 1 texel
// Don't make the transition more than one fragment (+/- 0.5 fragment)
" is_frag_gt1 = step(1.0, fragment_size.s); \n"
" radius = min(fragment_size.s, 0.5); \n"
" ratio.s = ratio.s * is_frag_gt1 + smoothstep(0.5 - radius, \n"
@ -411,10 +411,10 @@ namespace glsl {
" ratio.t = ratio.t * is_frag_gt1 + smoothstep(0.5 - radius, \n"
" 0.5 + radius, ratio.t) * (1.0 - is_frag_gt1); \n"
" \n"
" // now bump the coord to the texel using ratio \n"
// now bump the coord to the texel using ratio
" mediump vec2 new_denorm_uv = low_corner + ratio; \n"
" mediump vec2 new_uv = denorm2norm(tex, new_denorm_uv); \n"
" return texture2D(tex, new_uv); \n"
" mediump vec2 new_uv = denorm2norm(new_denorm_uv); \n"
" return texture2D(uTex0, new_uv); \n"
"} \n"
;
return strFilter;
@ -435,7 +435,7 @@ namespace glsl {
" \n"
"void main() \n"
"{ \n"
" fragColor = hybridFilter(uTex0, vTexCoord0); \n"
" fragColor = hybridFilter(vTexCoord0); \n"
;
} else {
m_part =
@ -484,7 +484,7 @@ namespace glsl {
" \n"
"void main() \n"
"{ \n"
" fragColor = hybridFilter(uTex0, vTexCoord0); \n"
" fragColor = hybridFilter(vTexCoord0); \n"
" gl_FragDepth = texture2D(uTex1, vTexCoord0).r; \n"
;
} else {

View File

@ -1595,43 +1595,29 @@ namespace opengl {
switch (format)
{
case GL_RED:
case GL_RED_INTEGER:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_LUMINANCE:
components = 1;
break;
case GL_RG:
case GL_RG_INTEGER:
case GL_DEPTH_STENCIL:
components = 2;
break;
case GL_RGB:
case GL_BGR:
components = 3;
break;
case GL_RGBA:
case GL_BGRA:
components = 4;
break;
case GL_RED_INTEGER:
components = 1;
break;
case GL_RG_INTEGER:
components = 2;
break;
case GL_RGB_INTEGER:
case GL_BGR_INTEGER:
components = 3;
break;
case GL_RGBA:
case GL_BGRA:
case GL_RGBA_INTEGER:
case GL_BGRA_INTEGER:
components = 4;
break;
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
components = 1;
break;
case GL_DEPTH_STENCIL:
components = 2;
break;
case GL_LUMINANCE:
components = 1;
break;
default:
components = -1;
}
@ -1644,15 +1630,11 @@ namespace opengl {
break;
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_HALF_FLOAT:
bytesPerPixel = components * 2;
break;
case GL_UNSIGNED_INT:
case GL_INT:
bytesPerPixel = components * 4;
break;
case GL_HALF_FLOAT:
bytesPerPixel = components * 2;
break;
case GL_FLOAT:
bytesPerPixel = components * 4;
break;

View File

@ -251,21 +251,14 @@ struct FramebufferTextureFormatsGLES2 : public graphics::FramebufferTextureForma
return _glinfo.isGLES2;
}
FramebufferTextureFormatsGLES2(const GLInfo & _glinfo):
m_glinfo(_glinfo)
{
init();
}
protected:
void init() override
FramebufferTextureFormatsGLES2(const GLInfo & _glinfo)
{
monochromeInternalFormat = GL_RGB;
monochromeFormat = GL_RGB;
monochromeType = GL_UNSIGNED_SHORT_5_6_5;
monochromeFormatBytes = 2;
if (Utils::isExtensionSupported(m_glinfo, "GL_OES_depth_texture")) {
if (Utils::isExtensionSupported(_glinfo, "GL_OES_depth_texture")) {
depthInternalFormat = GL_DEPTH_COMPONENT;
depthFormatBytes = 4;
} else {
@ -276,7 +269,7 @@ protected:
depthFormat = GL_DEPTH_COMPONENT;
depthType = GL_UNSIGNED_INT;
if (Utils::isExtensionSupported(m_glinfo, "GL_OES_rgb8_rgba8")) {
if (Utils::isExtensionSupported(_glinfo, "GL_OES_rgb8_rgba8")) {
colorInternalFormat = GL_RGBA;
colorFormat = GL_RGBA;
colorType = GL_UNSIGNED_BYTE;
@ -294,9 +287,6 @@ protected:
noiseType = GL_UNSIGNED_BYTE;
noiseFormatBytes = 1;
}
private:
const GLInfo & m_glinfo;
};
struct FramebufferTextureFormatsGLES3 : public graphics::FramebufferTextureFormats
@ -305,16 +295,9 @@ struct FramebufferTextureFormatsGLES3 : public graphics::FramebufferTextureForma
return _glinfo.isGLESX && !_glinfo.isGLES2;
}
FramebufferTextureFormatsGLES3(const GLInfo & _glinfo):
m_glinfo(_glinfo)
FramebufferTextureFormatsGLES3(const GLInfo & _glinfo)
{
init();
}
protected:
void init() override
{
if (m_glinfo.renderer == Renderer::Adreno530) {
if (_glinfo.renderer == Renderer::Adreno530) {
colorInternalFormat = GL_RGBA32F;
colorFormat = GL_RGBA;
colorType = GL_FLOAT;
@ -328,7 +311,7 @@ protected:
#ifdef OS_ANDROID
// If EGL image support is available, override above
if (m_glinfo.eglImage) {
if (_glinfo.eglImage) {
colorInternalFormat = GL_RGBA8;
colorFormat = GL_RGBA;
colorType = GL_UNSIGNED_BYTE;
@ -361,8 +344,6 @@ protected:
noiseType = GL_UNSIGNED_BYTE;
noiseFormatBytes = 1;
}
const GLInfo & m_glinfo;
};
struct FramebufferTextureFormatsOpenGL : public graphics::FramebufferTextureFormats
@ -372,12 +353,6 @@ struct FramebufferTextureFormatsOpenGL : public graphics::FramebufferTextureForm
}
FramebufferTextureFormatsOpenGL()
{
init();
}
protected:
void init() override
{
colorInternalFormat = GL_RGBA8;
colorFormat = GL_RGBA;

View File

@ -191,6 +191,7 @@ namespace opengl {
class CachedVertexAttribArray {
public:
CachedVertexAttribArray() = default;
void enableVertexAttribArray(u32 _index, bool _enable);
void reset();

View File

@ -492,7 +492,6 @@ void ContextImpl::drawLine(f32 _width, SPVertex * _vertices)
m_graphicsDrawer->drawLine(_width, _vertices);
}
f32 ContextImpl::getMaxLineWidth()
{
GLfloat lineWidthRange[2] = { 0.0f, 0.0f };
@ -519,8 +518,10 @@ bool ContextImpl::isSupported(graphics::SpecialFeatures _feature) const
return !m_glInfo.isGLES2;
case graphics::SpecialFeatures::ClipControl:
return !m_glInfo.isGLESX;
case graphics::SpecialFeatures::FramebufferFetch:
case graphics::SpecialFeatures::FramebufferFetchDepth:
return m_glInfo.ext_fetch;
case graphics::SpecialFeatures::FramebufferFetchColor:
return m_glInfo.ext_fetch || m_glInfo.ext_fetch_arm;
case graphics::SpecialFeatures::TextureBarrier:
return m_glInfo.texture_barrier || m_glInfo.texture_barrierNV;
case graphics::SpecialFeatures::EglImage:

View File

@ -52,6 +52,8 @@ void GLInfo::init() {
LOG(LOG_VERBOSE, "OpenGL vendor: %s", glGetString(GL_VENDOR));
const char * strRenderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
bool isAnyAdreno = strstr(strRenderer, "Adreno") != nullptr;
if (std::regex_match(std::string(strRenderer), std::regex("Adreno.*530")))
renderer = Renderer::Adreno530;
else if (std::regex_match(std::string(strRenderer), std::regex("Adreno.*540")) ||
@ -170,8 +172,9 @@ void GLInfo::init() {
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTexturesInterlock;
eglImage = (Utils::isEGLExtensionSupported("EGL_KHR_image_base") || Utils::isEGLExtensionSupported("EGL_KHR_image"));
ext_fetch_arm = Utils::isExtensionSupported(*this, "GL_ARM_shader_framebuffer_fetch") && !ext_fetch;
dual_source_blending = !(isGLESX) || Utils::isExtensionSupported(*this, "GL_EXT_blend_func_extended");
dual_source_blending = !isGLESX || (Utils::isExtensionSupported(*this, "GL_EXT_blend_func_extended") && !isAnyAdreno);
#ifdef OS_ANDROID
eglImage = eglImage &&

View File

@ -33,6 +33,7 @@ struct GLInfo {
bool fragment_interlockNV = false;
bool fragment_ordering = false;
bool ext_fetch = false;
bool ext_fetch_arm = false;
bool eglImage = false;
bool eglImageFramebuffer = false;
bool dual_source_blending = false;

View File

@ -23,6 +23,7 @@
#include "RSP.h"
#include "RDP.h"
#include "VI.h"
#include "Log.h"
using namespace graphics;
@ -41,12 +42,12 @@ GraphicsDrawer::~GraphicsDrawer()
{
}
void GraphicsDrawer::addTriangle(int _v0, int _v1, int _v2)
void GraphicsDrawer::addTriangle(u32 _v0, u32 _v1, u32 _v2)
{
const u32 firstIndex = triangles.num;
triangles.elements[triangles.num++] = _v0;
triangles.elements[triangles.num++] = _v1;
triangles.elements[triangles.num++] = _v2;
triangles.elements[triangles.num++] = static_cast<u16>(_v0);
triangles.elements[triangles.num++] = static_cast<u16>(_v1);
triangles.elements[triangles.num++] = static_cast<u16>(_v2);
triangles.maxElement = std::max(triangles.maxElement, _v0);
triangles.maxElement = std::max(triangles.maxElement, _v1);
triangles.maxElement = std::max(triangles.maxElement, _v2);
@ -239,8 +240,8 @@ float _adjustViewportX(f32 _X0)
inline
void _adjustViewportToClipRatio(s32 & x, s32 & y, s32 & width, s32 & height)
{
x -= (gSP.clipRatio - 1) * width / 2;
y -= (gSP.clipRatio - 1) * height / 2;
x -= static_cast<s32>(gSP.clipRatio - 1) * width / 2;
y -= static_cast<s32>(gSP.clipRatio - 1) * height / 2;
width *= gSP.clipRatio;
height *= gSP.clipRatio;
}
@ -256,10 +257,10 @@ void GraphicsDrawer::_updateViewport() const
float Xf = gSP.viewport.vscale[0] < 0 ? (gSP.viewport.x + gSP.viewport.vscale[0] * 2.0f) : gSP.viewport.x;
if (_needAdjustCoordinate(wnd))
Xf = _adjustViewportX(Xf);
s32 X = (s32)(Xf * scaleX);
s32 Y = (s32)(gSP.viewport.y * scaleY);
s32 WIDTH = std::max((s32)(gSP.viewport.width * scaleX), 0);
s32 HEIGHT = std::max((s32)(gSP.viewport.height * scaleY), 0);
s32 X = static_cast<s32>(Xf * scaleX);
s32 Y = static_cast<s32>(gSP.viewport.y * scaleY);
s32 WIDTH = std::max(static_cast<s32>(gSP.viewport.width * scaleX), 0);
s32 HEIGHT = std::max(static_cast<s32>(gSP.viewport.height * scaleY), 0);
_adjustViewportToClipRatio(X, Y, WIDTH, HEIGHT);
gfxContext.setViewport(X, Y, WIDTH, HEIGHT);
} else {
@ -296,11 +297,11 @@ void GraphicsDrawer::_updateScreenCoordsViewport(const FrameBuffer * _pBuffer) c
viewportScaleY = wnd.getScaleY();
} else {
bufferWidth = pCurrentBuffer->m_width;
bufferHeight = VI_GetMaxBufferHeight(bufferWidth);
bufferHeight = VI_GetMaxBufferHeight(static_cast<u16>(bufferWidth));
viewportScaleX = viewportScaleY = pCurrentBuffer->m_scale;
X = roundup(f32(pCurrentBuffer->m_originX), viewportScaleX);
Y = roundup(f32(pCurrentBuffer->m_originY), viewportScaleY);
if (RSP.LLE || gSP.viewport.width == 0) {
if (RSP.LLE || gSP.viewport.width == 0.0f) {
gSP.viewport.width = f32(bufferWidth);
gSP.viewport.height = f32(bufferHeight);
}
@ -673,6 +674,11 @@ void GraphicsDrawer::setBlendMode(bool _forceLegacyBlending) const
return;
}
if (Context::FramebufferFetchColor && !isTexrectDrawerMode()) {
gfxContext.enable(enable::BLEND, false);
return;
}
_ordinaryBlending();
}
@ -907,7 +913,7 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx)
}
}
void GraphicsDrawer::_drawThickLine(int _v0, int _v1, float _width)
void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width)
{
if ((gSP.geometryMode & G_LIGHTING) == 0) {
if ((gSP.geometryMode & G_SHADE) == 0) {
@ -957,13 +963,11 @@ void GraphicsDrawer::_drawThickLine(int _v0, int _v1, float _width)
const f32 Y = pVtx[0].y;
pVtx[0].y = pVtx[2].y = Y - _width;
pVtx[1].y = pVtx[3].y = Y + _width;
}
else if (fabs(pVtx[0].x - pVtx[2].x) < 0.0001) {
} else if (fabs(pVtx[0].x - pVtx[2].x) < 0.0001) {
const f32 X = pVtx[0].x;
pVtx[0].x = pVtx[2].x = X - _width;
pVtx[1].x = pVtx[3].x = X + _width;
}
else {
} else {
const f32 X0 = pVtx[0].x;
const f32 Y0 = pVtx[0].y;
const f32 X1 = pVtx[2].x;
@ -985,7 +989,7 @@ void GraphicsDrawer::_drawThickLine(int _v0, int _v1, float _width)
drawScreenSpaceTriangle(4);
}
void GraphicsDrawer::drawLine(int _v0, int _v1, float _width)
void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width)
{
m_texrectDrawer.draw();
@ -1039,16 +1043,16 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry)
calcCoordsScales(frameBufferList().getCurrent(), scaleX, scaleY);
const float Z = (gDP.otherMode.depthSource == G_ZS_PRIM) ? gDP.primDepth.z : 0.0f;
const float W = 1.0f;
m_rect[0].x = (float)_ulx * (2.0f * scaleX) - 1.0f;
m_rect[0].y = (float)_uly * (2.0f * scaleY) - 1.0f;
m_rect[0].x = static_cast<f32>(_ulx) * (2.0f * scaleX) - 1.0f;
m_rect[0].y = static_cast<f32>(_uly) * (2.0f * scaleY) - 1.0f;
m_rect[0].z = Z;
m_rect[0].w = W;
m_rect[1].x = (float)_lrx * (2.0f * scaleX) - 1.0f;
m_rect[1].x = static_cast<f32>(_lrx) * (2.0f * scaleX) - 1.0f;
m_rect[1].y = m_rect[0].y;
m_rect[1].z = Z;
m_rect[1].w = W;
m_rect[2].x = m_rect[0].x;
m_rect[2].y = (float)_lry * (2.0f * scaleY) - 1.0f;
m_rect[2].y = static_cast<f32>(_lry) * (2.0f * scaleY) - 1.0f;
m_rect[2].z = Z;
m_rect[2].w = W;
m_rect[3].x = m_rect[1].x;
@ -1057,7 +1061,7 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry)
m_rect[3].w = W;
DisplayWindow & wnd = dwnd();
if (wnd.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && ((u32)(_lrx - _ulx) < VI.width * 9 / 10)) {
if (wnd.isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100) && (static_cast<u32>(_lrx - _ulx) < VI.width * 9 / 10)) {
const float scale = wnd.getAdjustScale();
for (u32 i = 0; i < 4; ++i)
m_rect[i].x *= scale;
@ -1124,10 +1128,10 @@ bool texturedRectDepthBufferCopy(const GraphicsDrawer::TexturedRectParams & _par
RDP_RepeatLastLoadBlock();
}
const u32 width = (u32)(_params.lrx - _params.ulx);
const u32 ulx = (u32)_params.ulx;
u16 * pSrc = ((u16*)TMEM) + _params.s/32;
u16 *pDst = (u16*)(RDRAM + gDP.colorImage.address);
const u32 width = static_cast<u32>(_params.lrx - _params.ulx);
const u32 ulx = static_cast<u32>(_params.ulx);
u16 * pSrc = reinterpret_cast<u16*>(TMEM) + _params.s/32;
u16 *pDst = reinterpret_cast<u16*>(RDRAM + gDP.colorImage.address);
for (u32 x = 0; x < width; ++x)
pDst[(ulx + x) ^ 1] = swapword(pSrc[x]);
@ -1155,13 +1159,13 @@ bool texturedRectBGCopy(const GraphicsDrawer::TexturedRectParams & _params)
if (flry > gDP.scissor.lry)
flry = gDP.scissor.lry;
const u32 width = (u32)(_params.lrx - _params.ulx);
const u32 width = static_cast<u32>(_params.lrx - _params.ulx);
const u32 tex_width = gSP.textureTile[0]->line << 3;
const u32 uly = (u32)_params.uly;
const u32 lry = (u32)flry;
const u32 uly = static_cast<u32>(_params.uly);
const u32 lry = static_cast<u32>(flry);
u8 * texaddr = RDRAM + gDP.loadInfo[gSP.textureTile[0]->tmem].texAddress + tex_width*_params.t/32 + _params.s/32;
u8 * fbaddr = RDRAM + gDP.colorImage.address + (u32)_params.ulx;
u8 * fbaddr = RDRAM + gDP.colorImage.address + static_cast<u32>(_params.ulx);
// LOG(LOG_VERBOSE, "memrect (%d, %d, %d, %d), ci_width: %d texaddr: 0x%08lx fbaddr: 0x%08lx\n", (u32)_params.ulx, uly, (u32)_params.lrx, lry, gDP.colorImage.width, gSP.textureTile[0]->imageAddress + tex_width*(u32)_params.ult + (u32)_params.uls, gDP.colorImage.address + (u32)_params.ulx);
for (u32 y = uly; y < lry; ++y) {
@ -1199,16 +1203,16 @@ bool texturedRectPaletteMod(const GraphicsDrawer::TexturedRectParams & _params)
// Modify palette for Paper Mario "2D lighting" effect
if (gDP.scissor.lrx != 16 || gDP.scissor.lry != 1 || _params.lrx != 16 || _params.lry != 1)
return false;
u8 envr = (u8)(gDP.envColor.r * 31.0f);
u8 envg = (u8)(gDP.envColor.g * 31.0f);
u8 envb = (u8)(gDP.envColor.b * 31.0f);
u16 env16 = (u16)((envr << 11) | (envg << 6) | (envb << 1) | 1);
u8 prmr = (u8)(gDP.primColor.r * 31.0f);
u8 prmg = (u8)(gDP.primColor.g * 31.0f);
u8 prmb = (u8)(gDP.primColor.b * 31.0f);
u16 prim16 = (u16)((prmr << 11) | (prmg << 6) | (prmb << 1) | 1);
u16 * src = (u16*)&TMEM[256];
u16 * dst = (u16*)(RDRAM + gDP.colorImage.address);
u8 envr = static_cast<u8>(gDP.envColor.r * 31.0f);
u8 envg = static_cast<u8>(gDP.envColor.g * 31.0f);
u8 envb = static_cast<u8>(gDP.envColor.b * 31.0f);
u16 env16 = static_cast<u16>((envr << 11) | (envg << 6) | (envb << 1) | 1);
u8 prmr = static_cast<u8>(gDP.primColor.r * 31.0f);
u8 prmg = static_cast<u8>(gDP.primColor.g * 31.0f);
u8 prmb = static_cast<u8>(gDP.primColor.b * 31.0f);
u16 prim16 = static_cast<u16>((prmr << 11) | (prmg << 6) | (prmb << 1) | 1);
u16 * src = reinterpret_cast<u16*>(&TMEM[256]);
u16 * dst = reinterpret_cast<u16*>(RDRAM + gDP.colorImage.address);
for (u32 i = 0; i < 16; ++i)
dst[i ^ 1] = (src[i << 2] & 0x100) ? prim16 : env16;
return true;
@ -1216,7 +1220,7 @@ bool texturedRectPaletteMod(const GraphicsDrawer::TexturedRectParams & _params)
// Special processing of textured rect.
// Return true if actuial rendering is not necessary
bool(*texturedRectSpecial)(const GraphicsDrawer::TexturedRectParams & _params) = nullptr;
static bool(*texturedRectSpecial)(const GraphicsDrawer::TexturedRectParams & _params) = nullptr;
void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
{
@ -1309,12 +1313,12 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
s16 S = _params.s;
if (gSP.textureTile[t]->shifts > 10) {
const u32 shifts = 16 - gSP.textureTile[t]->shifts;
S = (s16)(S << shifts);
shiftScaleS = (f32)(1 << shifts);
S = static_cast<s16>(S << shifts);
shiftScaleS = static_cast<f32>(1 << shifts);
} else if (gSP.textureTile[t]->shifts > 0) {
const u32 shifts = gSP.textureTile[t]->shifts;
S = (s16)(S >> shifts);
shiftScaleS /= (f32)(1 << shifts);
S = static_cast<s16>(S >> shifts);
shiftScaleS /= static_cast<f32>(1 << shifts);
}
const f32 uls = _FIXED2FLOAT(S, 5);
const f32 lrs = uls + offsetX * shiftScaleS;
@ -1322,12 +1326,12 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
s16 T = _params.t;
if (gSP.textureTile[t]->shiftt > 10) {
const u32 shiftt = 16 - gSP.textureTile[t]->shiftt;
T = (s16)(T << shiftt);
shiftScaleT = (f32)(1 << shiftt);
T = static_cast<s16>(T << shiftt);
shiftScaleT = static_cast<f32>(1 << shiftt);
} else if (gSP.textureTile[t]->shiftt > 0) {
const u32 shiftt = gSP.textureTile[t]->shiftt;
T = (s16)(T >> shiftt);
shiftScaleT /= (f32)(1 << shiftt);
T = static_cast<s16>(T >> shiftt);
shiftScaleT /= static_cast<f32>(1 << shiftt);
}
const f32 ult = _FIXED2FLOAT(T, 5);
const f32 lrt = ult + offsetY * shiftScaleT;
@ -1358,15 +1362,15 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
if ((cache.current[t]->mirrorS == 0 && cache.current[t]->maskS == 0 &&
(texST[t].s0 < texST[t].s1 ?
texST[t].s0 >= 0.0 && texST[t].s1 <= (float)cache.current[t]->width :
texST[t].s1 >= 0.0 && texST[t].s0 <= (float)cache.current[t]->width))
texST[t].s0 >= 0.0f && texST[t].s1 <= static_cast<f32>(cache.current[t]->width) :
texST[t].s1 >= 0.0f && texST[t].s0 <= static_cast<f32>(cache.current[t]->width)))
|| (cache.current[t]->maskS == 0 && (texST[t].s0 < -1024.0f || texST[t].s1 > 1023.99f)))
texParams.wrapS = textureParameters::WRAP_CLAMP_TO_EDGE;
if (cache.current[t]->mirrorT == 0 &&
(texST[t].t0 < texST[t].t1 ?
texST[t].t0 >= 0.0f && texST[t].t1 <= (float)cache.current[t]->height :
texST[t].t1 >= 0.0f && texST[t].t0 <= (float)cache.current[t]->height))
texST[t].t0 >= 0.0f && texST[t].t1 <= static_cast<f32>(cache.current[t]->height) :
texST[t].t1 >= 0.0f && texST[t].t0 <= static_cast<f32>(cache.current[t]->height)))
texParams.wrapT = textureParameters::WRAP_CLAMP_TO_EDGE;
if (texParams.wrapS.isValid() || texParams.wrapT.isValid()) {
@ -1436,7 +1440,7 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
if (wnd.isAdjustScreen() &&
(_params.forceAjustScale ||
((gDP.colorImage.width > VI.width * 98 / 100) && ((u32)(_params.lrx - _params.ulx) < VI.width * 9 / 10))))
((gDP.colorImage.width > VI.width * 98 / 100) && (static_cast<u32>(_params.lrx - _params.ulx) < VI.width * 9 / 10))))
{
const float scale = wnd.getAdjustScale();
for (u32 i = 0; i < 4; ++i)
@ -1539,7 +1543,7 @@ void GraphicsDrawer::clearColorBuffer(float *_pColor)
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
}
bool GraphicsDrawer::isRejected(s32 _v0, s32 _v1, s32 _v2) const
bool GraphicsDrawer::isRejected(u32 _v0, u32 _v1, u32 _v2) const
{
if (!GBI.isRej() || gSP.clipRatio < 2)
return false;
@ -1554,7 +1558,7 @@ bool GraphicsDrawer::isRejected(s32 _v0, s32 _v1, s32 _v2) const
rejectBox.lry = gDP.scissor.lry + scissorHeight2;
gDP.changed ^= CHANGED_REJECT_BOX;
}
s32 verts[3] = { _v0, _v1, _v2 };
u32 verts[3] = { _v0, _v1, _v2 };
const f32 ySign = GBI.isNegativeY() ? -1.0f : 1.0f;
for (u32 i = 0; i < 3; ++i) {
const SPVertex & v = triangles.vertices[verts[i]];
@ -1649,7 +1653,7 @@ void GraphicsDrawer::copyTexturedRect(const CopyRectParams & _params)
gfxContext.setTextureParameters(texParams);
}
gfxContext.setViewport(0, 0, _params.dstWidth, _params.dstHeight);
gfxContext.setViewport(0, 0, static_cast<s32>(_params.dstWidth), static_cast<s32>(_params.dstHeight));
gfxContext.enable(enable::CULL_FACE, false);
gfxContext.enable(enable::BLEND, false);
@ -1728,11 +1732,12 @@ void GraphicsDrawer::_initStates()
}
DisplayWindow & wnd = DisplayWindow::get();
gfxContext.setViewport(0, wnd.getHeightOffset(), wnd.getScreenWidth(), wnd.getScreenHeight());
gfxContext.setViewport(0, static_cast<s32>(wnd.getHeightOffset()),
static_cast<s32>(wnd.getScreenWidth()), static_cast<s32>(wnd.getScreenHeight()));
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
srand((unsigned int)time(nullptr));
srand(static_cast<u32>(time(nullptr)));
wnd.swapBuffers();
}

View File

@ -41,7 +41,7 @@ typedef std::chrono::milliseconds Milliseconds;
class GraphicsDrawer
{
public:
void addTriangle(int _v0, int _v1, int _v2);
void addTriangle(u32 _v0, u32 _v1, u32 _v2);
void drawTriangles();
@ -49,7 +49,7 @@ public:
void drawDMATriangles(u32 _numVtx);
void drawLine(int _v0, int _v1, float _width);
void drawLine(u32 _v0, u32 _v1, float _width);
void drawRect(int _ulx, int _uly, int _lrx, int _lry);
@ -128,12 +128,12 @@ public:
int getTrianglesCount() const { return triangles.num; }
bool isClipped(s32 _v0, s32 _v1, s32 _v2) const
bool isClipped(u32 _v0, u32 _v1, u32 _v2) const
{
return (triangles.vertices[_v0].clip & triangles.vertices[_v1].clip & triangles.vertices[_v2].clip) != 0;
}
bool isRejected(s32 _v0, s32 _v1, s32 _v2) const;
bool isRejected(u32 _v0, u32 _v1, u32 _v2) const;
SPVertex & getVertex(u32 _v) { return triangles.vertices[_v]; }
@ -187,7 +187,7 @@ private:
void _updateStates(DrawingState _drawingState) const;
void _prepareDrawTriangle(DrawingState _drawingState);
bool _canDraw() const;
void _drawThickLine(int _v0, int _v1, float _width);
void _drawThickLine(u32 _v0, u32 _v1, float _width);
void _drawOSD(const char *_pText, float _x, float & _y);
@ -201,7 +201,7 @@ private:
std::array<SPVertex, VERTBUFF_SIZE> vertices;
std::array<u16, ELEMBUFF_SIZE> elements;
u32 num = 0;
int maxElement = 0;
u32 maxElement = 0;
} triangles;
std::vector<SPVertex> m_dmaVertices;

View File

@ -5,6 +5,7 @@
#include "PostProcessor.h"
#include "FrameBuffer.h"
#include "Config.h"
#include "VI.h"
#include <Graphics/Context.h>
#include <Graphics/Parameters.h>
@ -156,7 +157,7 @@ FrameBuffer * PostProcessor::_doGammaCorrection(FrameBuffer * _pBuffer)
if (_pBuffer == nullptr)
return nullptr;
if (((*REG.VI_STATUS & 8) | config.gammaCorrection.force) == 0)
if (((*REG.VI_STATUS & VI_STATUS_GAMMA_ENABLED) | config.gammaCorrection.force) == 0)
return _pBuffer;
return _doPostProcessing(_pBuffer, m_gammaCorrectionProgram.get());

View File

@ -1332,9 +1332,10 @@ u64 _calculateCRC(u32 _t, const TextureParams & _params, u32 _bytes)
if (rgba32)
_bytes >>= 1;
const u32 tMemMask = (gDP.otherMode.textureLUT == G_TT_NONE && !rgba32) ? 0x1FF : 0xFF;
const u64 *src = (u64*)&TMEM[gSP.textureTile[_t]->tmem & tMemMask];
const u32 tMem = gSP.textureTile[_t]->tmem & tMemMask;
const u64 *src = (u64*)&TMEM[tMem];
const u32 maxBytes = (tMemMask + 1) << 3;
const u32 tileTmemInBytes = gSP.textureTile[_t]->tmem << 3;
const u32 tileTmemInBytes = tMem << 3;
if (!rgba32 && (tileTmemInBytes + _bytes > maxBytes))
_bytes = maxBytes - tileTmemInBytes;
u64 crc = UINT64_MAX;
@ -1409,6 +1410,8 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
case DrawingState::ScreenSpaceTriangle:
params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF);
break;
default:
break;
}
}
}

View File

@ -49,7 +49,7 @@ void VI_UpdateSize()
VI.real_height = vEnd > vStart ? (((vEnd - vStart) >> 1) * vScale) >> 10 : 0;
VI.width = *REG.VI_WIDTH;
VI.interlaced = (*REG.VI_STATUS & 0x40) != 0;
VI.interlaced = (*REG.VI_STATUS & VI_STATUS_SERRATE_ENABLED) != 0;
if (VI.interlaced) {
f32 fullWidth = 640.0f;
@ -164,13 +164,13 @@ void VI_UpdateScreen()
wnd.updateScale();
bVIUpdated = true;
}
const u32 size = *REG.VI_STATUS & 3;
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);
}
}
// if ((((*REG.VI_STATUS) & 3) > 0) && (gDP.colorImage.changed || bCFB)) { // Does not work in release build!!!
if (((*REG.VI_STATUS) & 3) > 0) {
if (((*REG.VI_STATUS) & VI_STATUS_TYPE_32) > 0) {
if (!bVIUpdated) {
VI_UpdateSize();
bVIUpdated = true;

View File

@ -2,6 +2,22 @@
#define VI_H
#include "Types.h"
// VI status register
#define VI_STATUS_TYPE_16 0x000002 /* 16 bit 5/5/5/3 */
#define VI_STATUS_TYPE_32 0x000003 /* 32 bit 8/8/8/8 */
#define VI_STATUS_GAMMA_DITHER_ENABLED 0x000004
#define VI_STATUS_GAMMA_ENABLED 0x000008
#define VI_STATUS_DIVOT_ENABLED 0x000010
#define VI_STATUS_SERRATE_ENABLED 0x000040
#define VI_STATUS_AA_MASK 0x000300 /* see AA modes */
#define VI_STATUS_DITHER_FILTER_ENABLED 0x010000
// AA modes
#define AA_MODE_AA_RESAMPLE_ALWAYS_FETCH 0x000000 /* Always fetch lines */
#define AA_MODE_AA_RESAMPLE 0x000100 /* Fetch extra line if needed */
#define AA_MODE_RESAMPLE_ONLY 0x000200
#define AA_MODE_NEITHER 0x000300 /* Replicate pixels, no interpolation */
struct VIInfo
{
u32 width, widthPrev, height, real_height;

View File

@ -105,7 +105,7 @@ void UnswapCopyWrap(const u8 *src, u32 srcIdx, u8 *dest, u32 destIdx, u32 destMa
u32 leadingBytes = srcIdx & 3;
if (leadingBytes != 0) {
leadingBytes = 4 - leadingBytes;
if ((u32)leadingBytes > numBytes)
if (leadingBytes > numBytes)
leadingBytes = numBytes;
numBytes -= leadingBytes;

View File

@ -102,7 +102,7 @@ void gDPSetTextureLUT( u32 mode )
#endif
}
void gDPSetCombine( s32 muxs0, s32 muxs1 )
void gDPSetCombine( u32 muxs0, u32 muxs1 )
{
gDP.combine.muxs0 = muxs0;
gDP.combine.muxs1 = muxs1;
@ -143,7 +143,7 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
gDP.colorImage.height = 0;
gDP.colorImage.address = address;
frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, false);
frameBufferList().saveBuffer(address, static_cast<u16>(format), static_cast<u16>(size), static_cast<u16>(width), false);
#ifdef DEBUG_DUMP
DebugMsg( DEBUG_NORMAL, "gDPSetColorImage( %s, %s, %i, 0x%08X );\n",
@ -163,7 +163,7 @@ void gDPSetTextureImage(u32 format, u32 size, u32 width, u32 address)
gDP.textureImage.bpl = gDP.textureImage.width << gDP.textureImage.size >> 1;
if (gSP.DMAOffsets.tex_offset != 0) {
if (format == G_IM_FMT_RGBA) {
u16 * t = (u16*)(RDRAM + gSP.DMAOffsets.tex_offset);
u16 * t = reinterpret_cast<u16*>(RDRAM + gSP.DMAOffsets.tex_offset);
gSP.DMAOffsets.tex_shift = t[gSP.DMAOffsets.tex_count ^ 1];
gDP.textureImage.address += gSP.DMAOffsets.tex_shift;
} else {
@ -227,8 +227,8 @@ void gDPSetFogColor( u32 r, u32 g, u32 b, u32 a )
void gDPSetFillColor( u32 c )
{
gDP.fillColor.color = c;
gDP.fillColor.z = (f32)_SHIFTR( c, 2, 14 );
gDP.fillColor.dz = (f32)_SHIFTR( c, 0, 2 );
gDP.fillColor.z = static_cast<f32>(_SHIFTR( c, 2, 14 ));
gDP.fillColor.dz = static_cast<f32>(_SHIFTR( c, 0, 2 ));
DebugMsg( DEBUG_NORMAL, "gDPSetFillColor( 0x%08X );\n", c );
}
@ -240,7 +240,7 @@ void gDPGetFillColor(f32 _fillColor[4])
_fillColor[0] = _FIXED2FLOATCOLOR( _SHIFTR( c, 11, 5 ), 5 );
_fillColor[1] = _FIXED2FLOATCOLOR( _SHIFTR( c, 6, 5 ), 5 );
_fillColor[2] = _FIXED2FLOATCOLOR( _SHIFTR( c, 1, 5 ), 5 );
_fillColor[3] = (f32)_SHIFTR( c, 0, 1 );
_fillColor[3] = static_cast<f32>(_SHIFTR( c, 0, 1 ));
} else {
_fillColor[0] = _FIXED2FLOATCOLOR( _SHIFTR( c, 24, 8 ), 8 );
_fillColor[1] = _FIXED2FLOATCOLOR( _SHIFTR( c, 16, 8 ), 8 );
@ -380,7 +380,7 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _width, u32 _bytes)
const u32 texEndAddress = _address + _bytes - 1;
if (_address > pBuffer->m_startAddress &&
std::abs((s32)pBuffer->m_width - (s32)_width) > 1 &&
std::abs(static_cast<s32>(pBuffer->m_width) - static_cast<s32>(_width)) > 1 &&
texEndAddress > (pBuffer->m_endAddress + (pBuffer->m_width << pBuffer->m_size >> 1))) {
//fbList.removeBuffer(pBuffer->m_startAddress);
bRes = false;
@ -409,7 +409,7 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _width, u32 _bytes)
break;
}
for (int nTile = gSP.texture.tile; nTile < 6; ++nTile) {
for (u32 nTile = gSP.texture.tile; nTile < 6; ++nTile) {
if (gDP.tiles[nTile].tmem == gDP.loadTile->tmem) {
gDPTile & curTile = gDP.tiles[nTile];
curTile.textureMode = gDP.loadTile->textureMode;
@ -432,8 +432,8 @@ void gDPLoadTile32b(u32 uls, u32 ult, u32 lrs, u32 lrt)
const u32 line = gDP.loadTile->line << 2;
const u32 tbase = gDP.loadTile->tmem << 2;
const u32 addr = gDP.textureImage.address >> 2;
const u32 * src = (const u32*)RDRAM;
u16 * tmem16 = (u16*)TMEM;
const u32 * src = reinterpret_cast<const u32*>(RDRAM);
u16 * tmem16 = reinterpret_cast<u16*>(TMEM);
u32 c, ptr, tline, s, xorval;
for (u32 j = 0; j < height; ++j) {
@ -483,14 +483,14 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt)
gDPLoadTileInfo &info = gDP.loadInfo[gDP.loadTile->tmem];
info.texAddress = gDP.loadTile->imageAddress;
info.uls = gDP.loadTile->uls;
info.ult = gDP.loadTile->ult;
info.lrs = gDP.loadTile->lrs;
info.lrt = gDP.loadTile->lrt;
info.width = gDP.loadTile->masks != 0 ? (u16)min(width, 1U << gDP.loadTile->masks) : (u16)width;
info.height = gDP.loadTile->maskt != 0 ? (u16)min(height, 1U << gDP.loadTile->maskt) : (u16)height;
info.texWidth = gDP.textureImage.width;
info.size = gDP.textureImage.size;
info.uls = static_cast<u16>(gDP.loadTile->uls);
info.ult = static_cast<u16>(gDP.loadTile->ult);
info.lrs = static_cast<u16>(gDP.loadTile->lrs);
info.lrt = static_cast<u16>(gDP.loadTile->lrt);
info.width = static_cast<u16>(gDP.loadTile->masks != 0 ? min(width, 1U << gDP.loadTile->masks) : width);
info.height = static_cast<u16>(gDP.loadTile->maskt != 0 ? min(height, 1U << gDP.loadTile->maskt) : height);
info.texWidth = static_cast<u16>(gDP.textureImage.width);
info.size = static_cast<u8>(gDP.textureImage.size);
info.loadType = LOADTYPE_TILE;
info.bytes = bpl * height;
if (gDP.loadTile->size == G_IM_SIZ_32b)
@ -504,7 +504,7 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt)
gDP.loadTile->loadWidth = max(gDP.loadTile->loadWidth, info.width);
if (gDP.loadTile->maskt == 0) {
if (gDP.otherMode.cycleType != G_CYC_2CYCLE && gDP.loadTile->tmem % gDP.loadTile->line == 0) {
u16 theight = info.height + gDP.loadTile->tmem / gDP.loadTile->line;
u16 theight = static_cast<u16>(info.height + gDP.loadTile->tmem / gDP.loadTile->line);
gDP.loadTile->loadHeight = max(gDP.loadTile->loadHeight, theight);
} else
gDP.loadTile->loadHeight = max(gDP.loadTile->loadHeight, info.height);
@ -516,7 +516,7 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt)
bpl2 = (gDP.textureImage.width - gDP.loadTile->uls);
u32 height2 = height;
if (gDP.loadTile->lrt > gDP.scissor.lry)
height2 = (u32)gDP.scissor.lry - gDP.loadTile->ult;
height2 = static_cast<u32>(gDP.scissor.lry) - gDP.loadTile->ult;
if (CheckForFrameBufferTexture(address, info.width, bpl2*height2))
return;
@ -529,11 +529,11 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt)
const u32 qwpr = bpr >> 3;
for (u32 y = 0; y < height; ++y) {
if (address + bpl > RDRAMSize)
UnswapCopyWrap(RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, RDRAMSize - address);
UnswapCopyWrap(RDRAM, address, reinterpret_cast<u8*>(TMEM), tmemAddr << 3, 0xFFF, RDRAMSize - address);
else
UnswapCopyWrap(RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bpr);
UnswapCopyWrap(RDRAM, address, reinterpret_cast<u8*>(TMEM), tmemAddr << 3, 0xFFF, bpr);
if (y & 1)
DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, qwpr);
DWordInterleaveWrap(reinterpret_cast<u32*>(TMEM), tmemAddr << 1, 0x3FF, qwpr);
address += gDP.textureImage.bpl;
if (address >= RDRAMSize)
@ -552,17 +552,17 @@ void gDPLoadTile(u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt)
//
void gDPLoadBlock32(u32 uls,u32 lrs, u32 dxt)
{
const u32 * src = (const u32*)RDRAM;
const u32 * src = reinterpret_cast<const u32*>(RDRAM);
const u32 tb = gDP.loadTile->tmem << 2;
const u32 line = gDP.loadTile->line << 2;
u16 *tmem16 = (u16*)TMEM;
u16 *tmem16 = reinterpret_cast<u16*>(TMEM);
u32 addr = gDP.loadTile->imageAddress >> 2;
u32 width = (lrs - uls + 1) << 2;
if (width == 4) // lr_s == 0, 1x1 texture
width = 1;
else if (width & 7)
width = (width & (~7)) + 8;
width = (width & (~7U)) + 8;
if (dxt != 0) {
u32 j = 0;
@ -617,19 +617,19 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt)
gDPLoadTileInfo &info = gDP.loadInfo[gDP.loadTile->tmem];
info.texAddress = gDP.loadTile->imageAddress;
info.uls = gDP.loadTile->uls;
info.ult = gDP.loadTile->ult;
info.lrs = gDP.loadTile->lrs;
info.lrt = gDP.loadTile->lrt;
info.width = gDP.loadTile->lrs;
info.uls = static_cast<u16>(gDP.loadTile->uls);
info.ult = static_cast<u16>(gDP.loadTile->ult);
info.lrs = static_cast<u16>(gDP.loadTile->lrs);
info.lrt = static_cast<u16>(gDP.loadTile->lrt);
info.width = static_cast<u16>(gDP.loadTile->lrs);
info.dxt = dxt;
info.size = gDP.textureImage.size;
info.size = static_cast<u8>(gDP.textureImage.size);
info.loadType = LOADTYPE_BLOCK;
const u32 width = (lrs - uls + 1) & 0x0FFF;
u32 bytes = width << gDP.loadTile->size >> 1;
if ((bytes & 7) != 0)
bytes = (bytes & (~7)) + 8;
bytes = (bytes & (~7U)) + 8;
info.bytes = bytes;
u32 address = gDP.textureImage.address + ult * gDP.textureImage.bpl + (uls << gDP.textureImage.size >> 1);
@ -658,7 +658,7 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt)
memcpy(TMEM, &RDRAM[address], bytes); // HACK!
else {
u32 tmemAddr = gDP.loadTile->tmem;
UnswapCopyWrap(RDRAM, address, (u8*)TMEM, tmemAddr << 3, 0xFFF, bytes);
UnswapCopyWrap(RDRAM, address, reinterpret_cast<u8*>(TMEM), tmemAddr << 3, 0xFFF, bytes);
if (dxt != 0) {
u32 dxtCounter = 0;
u32 qwords = (bytes >> 3);
@ -678,12 +678,12 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt)
goto end_dxt_test;
dxtCounter += dxt;
} while ((dxtCounter & 0x800) != 0);
DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line);
DWordInterleaveWrap(reinterpret_cast<u32*>(TMEM), tmemAddr << 1, 0x3FF, line);
tmemAddr += line;
line = 0;
}
end_dxt_test:
DWordInterleaveWrap((u32*)TMEM, tmemAddr << 1, 0x3FF, line);
DWordInterleaveWrap(reinterpret_cast<u32*>(TMEM), tmemAddr << 1, 0x3FF, line);
}
}
@ -697,16 +697,16 @@ void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt )
DebugMsg(DEBUG_NORMAL | DEBUG_ERROR, "gDPLoadTLUT wrong tile tmem addr: tile[%d].tmem=%04x;\n", tile, gDP.tiles[tile].tmem);
return;
}
u16 count = (u16)((gDP.tiles[tile].lrs - gDP.tiles[tile].uls + 1) * (gDP.tiles[tile].lrt - gDP.tiles[tile].ult + 1));
u16 count = static_cast<u16>((gDP.tiles[tile].lrs - gDP.tiles[tile].uls + 1) * (gDP.tiles[tile].lrt - gDP.tiles[tile].ult + 1));
u32 address = gDP.textureImage.address + gDP.tiles[tile].ult * gDP.textureImage.bpl + (gDP.tiles[tile].uls << gDP.textureImage.size >> 1);
u16 pal = (u16)((gDP.tiles[tile].tmem - 256) >> 4);
u16 pal = static_cast<u16>((gDP.tiles[tile].tmem - 256) >> 4);
u16 * dest = reinterpret_cast<u16*>(TMEM);
u32 destIdx = gDP.tiles[tile].tmem << 2;
int i = 0;
while (i < count) {
for (u16 j = 0; (j < 16) && (i < count); ++j, ++i) {
dest[(destIdx | 0x0400) & 0x07FF] = swapword(*(u16*)(RDRAM + (address ^ 2)));
dest[(destIdx | 0x0400) & 0x07FF] = swapword(*reinterpret_cast<u16*>(RDRAM + (address ^ 2)));
address += 2;
destIdx += 4;
}
@ -718,9 +718,9 @@ void gDPLoadTLUT( u32 tile, u32 uls, u32 ult, u32 lrs, u32 lrt )
gDP.paletteCRC256 = CRC_Calculate(UINT64_MAX, gDP.paletteCRC16, sizeof(u64) * 16);
if (TFH.isInited()) {
const u16 start = gDP.tiles[tile].tmem - 256; // starting location in the palettes
u16 *spal = (u16*)(RDRAM + gDP.textureImage.address);
memcpy((u8*)(gDP.TexFilterPalette + start), spal, count<<1);
const u16 start = static_cast<u16>(gDP.tiles[tile].tmem) - 256; // starting location in the palettes
u16 *spal = reinterpret_cast<u16*>(RDRAM + gDP.textureImage.address);
memcpy(reinterpret_cast<u8*>(gDP.TexFilterPalette + start), spal, u32(count)<<1);
}
gDP.changed |= CHANGED_TMEM;
@ -814,10 +814,10 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
void gDPSetConvert( s32 k0, s32 k1, s32 k2, s32 k3, s32 k4, s32 k5 )
{
gDP.convert.k0 = (SIGN(k0, 9) << 1) + 1;
gDP.convert.k1 = (SIGN(k1, 9) << 1) + 1;
gDP.convert.k2 = (SIGN(k2, 9) << 1) + 1;
gDP.convert.k3 = (SIGN(k3, 9) << 1) + 1;
gDP.convert.k0 = static_cast<s32>(static_cast<u32>(SIGN(k0, 9) << 1)) + 1;
gDP.convert.k1 = static_cast<s32>(static_cast<u32>(SIGN(k1, 9) << 1)) + 1;
gDP.convert.k2 = static_cast<s32>(static_cast<u32>(SIGN(k2, 9) << 1)) + 1;
gDP.convert.k3 = static_cast<s32>(static_cast<u32>(SIGN(k3, 9) << 1)) + 1;
gDP.convert.k4 = k4;
gDP.convert.k5 = k5;
@ -863,6 +863,8 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, s16 s, s1
if (s == 0x4000 && (gDP.colorImage.width + gSP.textureTile[0]->uls < 512))
s = 0;
gDP.rectColor = gDPInfo::Color();
GraphicsDrawer & drawer = dwnd().getDrawer();
GraphicsDrawer::TexturedRectParams params(ulx, uly, lrx, lry, dsdx, dtdy, s, t,
flip, false, true, frameBufferList().getCurrent());
@ -896,7 +898,8 @@ void gDPFullSync()
frameBufferList().updateCurrentBufferEndAddress();
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
pCurrentBuffer->copyDepthTexture();
if (pCurrentBuffer != nullptr)
pCurrentBuffer->copyDepthTexture();
if ((config.frameBufferEmulation.copyToRDRAM != Config::ctDisable || (config.generalEmulation.hacks & hack_subscreen) != 0) &&
!FBInfo::fbInfo.isSupported() &&
pCurrentBuffer != nullptr &&
@ -1279,7 +1282,7 @@ void LLETriangle::flush(u32 _cmd)
#ifndef OLD_LLE
if (_cmd >= 0x08 && _cmd <= 0x0f)
return;
GraphicsDrawer & drawer = dwnd().getDrawer();
if (drawer.getDMAVerticesCount() > 0) {
drawer.drawScreenSpaceTriangle(drawer.getDMAVerticesCount(), graphics::drawmode::TRIANGLES);
@ -1292,7 +1295,7 @@ void LLETriangle::flush(u32 _cmd)
#endif
}
void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, u32 * _pData)
{
DebugMsg(DEBUG_NORMAL, "gDPLLETriangle shade: %d, texture: %d, zbuffer: %d\n",
int(_shade), int(_texture), int(_zbuffer));
@ -1302,21 +1305,22 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
if (tile != m_tile)
flush(0);
m_tile = tile;
const int flip = (_pData[0] & 0x800000) >> 23;
// const int flip = (_pData[0] & 0x800000) >> 23; // unused
start(tile);
int yl = SIGN(_pData[0], 14);
int ym = _pData[1] >> 16;
s32* pDataSigned = reinterpret_cast<s32*>(_pData);
int yl = SIGN(pDataSigned[0], 14);
int ym = pDataSigned[1] >> 16;
ym = SIGN(ym, 14);
int yh = SIGN(_pData[1], 14);
int yh = SIGN(pDataSigned[1], 14);
int xl = SIGN(_pData[2], 28);
int xh = SIGN(_pData[4], 28);
int xm = SIGN(_pData[6], 28);
int xl = SIGN(pDataSigned[2], 28);
int xh = SIGN(pDataSigned[4], 28);
int xm = SIGN(pDataSigned[6], 28);
const int dxldy = SIGN(_pData[3], 30);
const int dxhdy = SIGN(_pData[5], 30);
const int dxmdy = SIGN(_pData[7], 30);
const int dxldy = SIGN(pDataSigned[3], 30);
const int dxhdy = SIGN(pDataSigned[5], 30);
const int dxmdy = SIGN(pDataSigned[7], 30);
yh &= ~3;
@ -1325,41 +1329,41 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
int drde = 0, dgde = 0, dbde = 0, dade = 0;
if (_shade) {
r = (_pData[8] & 0xffff0000) | ((_pData[12] >> 16) & 0x0000ffff);
g = ((_pData[8] << 16) & 0xffff0000) | (_pData[12] & 0x0000ffff);
b = (_pData[9] & 0xffff0000) | ((_pData[13] >> 16) & 0x0000ffff);
a = ((_pData[9] << 16) & 0xffff0000) | (_pData[13] & 0x0000ffff);
drdx = (_pData[10] & 0xffff0000) | ((_pData[14] >> 16) & 0x0000ffff);
dgdx = ((_pData[10] << 16) & 0xffff0000) | (_pData[14] & 0x0000ffff);
dbdx = (_pData[11] & 0xffff0000) | ((_pData[15] >> 16) & 0x0000ffff);
dadx = ((_pData[11] << 16) & 0xffff0000) | (_pData[15] & 0x0000ffff);
drde = (_pData[16] & 0xffff0000) | ((_pData[20] >> 16) & 0x0000ffff);
dgde = ((_pData[16] << 16) & 0xffff0000) | (_pData[20] & 0x0000ffff);
dbde = (_pData[17] & 0xffff0000) | ((_pData[21] >> 16) & 0x0000ffff);
dade = ((_pData[17] << 16) & 0xffff0000) | (_pData[21] & 0x0000ffff);
r = static_cast<int>((_pData[8] & 0xffff0000) | ((_pData[12] >> 16) & 0x0000ffff));
g = static_cast<int>(((_pData[8] << 16) & 0xffff0000) | (_pData[12] & 0x0000ffff));
b = static_cast<int>((_pData[9] & 0xffff0000) | ((_pData[13] >> 16) & 0x0000ffff));
a = static_cast<int>(((_pData[9] << 16) & 0xffff0000) | (_pData[13] & 0x0000ffff));
drdx = static_cast<int>((_pData[10] & 0xffff0000) | ((_pData[14] >> 16) & 0x0000ffff));
dgdx = static_cast<int>(((_pData[10] << 16) & 0xffff0000) | (_pData[14] & 0x0000ffff));
dbdx = static_cast<int>((_pData[11] & 0xffff0000) | ((_pData[15] >> 16) & 0x0000ffff));
dadx = static_cast<int>(((_pData[11] << 16) & 0xffff0000) | (_pData[15] & 0x0000ffff));
drde = static_cast<int>((_pData[16] & 0xffff0000) | ((_pData[20] >> 16) & 0x0000ffff));
dgde = static_cast<int>(((_pData[16] << 16) & 0xffff0000) | (_pData[20] & 0x0000ffff));
dbde = static_cast<int>((_pData[17] & 0xffff0000) | ((_pData[21] >> 16) & 0x0000ffff));
dade = static_cast<int>(((_pData[17] << 16) & 0xffff0000) | (_pData[21] & 0x0000ffff));
}
int s = 0, t = 0, w = 0x30000;
int dsdx = 0, dtdx = 0, dwdx = 0;
int dsde = 0, dtde = 0, dwde = 0;
if (_texture) {
s = (_pData[24] & 0xffff0000) | ((_pData[28] >> 16) & 0x0000ffff);
t = ((_pData[24] << 16) & 0xffff0000) | (_pData[28] & 0x0000ffff);
w = (_pData[25] & 0xffff0000) | ((_pData[29] >> 16) & 0x0000ffff);
dsdx = (_pData[26] & 0xffff0000) | ((_pData[30] >> 16) & 0x0000ffff);
dtdx = ((_pData[26] << 16) & 0xffff0000) | (_pData[30] & 0x0000ffff);
dwdx = (_pData[27] & 0xffff0000) | ((_pData[31] >> 16) & 0x0000ffff);
dsde = (_pData[32] & 0xffff0000) | ((_pData[36] >> 16) & 0x0000ffff);
dtde = ((_pData[32] << 16) & 0xffff0000) | (_pData[36] & 0x0000ffff);
dwde = (_pData[33] & 0xffff0000) | ((_pData[37] >> 16) & 0x0000ffff);
s = static_cast<int>((_pData[24] & 0xffff0000) | ((_pData[28] >> 16) & 0x0000ffff));
t = static_cast<int>(((_pData[24] << 16) & 0xffff0000) | (_pData[28] & 0x0000ffff));
w = static_cast<int>((_pData[25] & 0xffff0000) | ((_pData[29] >> 16) & 0x0000ffff));
dsdx = static_cast<int>((_pData[26] & 0xffff0000) | ((_pData[30] >> 16) & 0x0000ffff));
dtdx = static_cast<int>(((_pData[26] << 16) & 0xffff0000) | (_pData[30] & 0x0000ffff));
dwdx = static_cast<int>((_pData[27] & 0xffff0000) | ((_pData[31] >> 16) & 0x0000ffff));
dsde = static_cast<int>((_pData[32] & 0xffff0000) | ((_pData[36] >> 16) & 0x0000ffff));
dtde = static_cast<int>(((_pData[32] << 16) & 0xffff0000) | (_pData[36] & 0x0000ffff));
dwde = static_cast<int>((_pData[33] & 0xffff0000) | ((_pData[37] >> 16) & 0x0000ffff));
}
int z = 0xffff0000;
int dzdx = 0, dzde = 0;
if (_zbuffer) {
z = _pData[40];
dzdx = _pData[41];
dzde = _pData[42];
z = pDataSigned[40];
dzdx = pDataSigned[41];
dzde = pDataSigned[42];
}
std::array<SPVertex, 8> vertices;
@ -1443,8 +1447,6 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
if (_texture) {
if (gDP.otherMode.texturePersp != 0) {
f32 vw = wf + dwdef * diffY + dwdxf * diffx * 4.0f;
if (vw == 0)
int t = 0;
vtx->w = static_cast<f32>(1.0f / (vw > 0.0f ? vw : (1.0f + vw - ceil(vw))));
//vtx->w = static_cast<f32>(1.0f / vw);
if (vw <= 0.0f) {
@ -1500,24 +1502,24 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
SPVertex * vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(xhyf);
vtx->y = static_cast<f32>(yf * 0.25);
vtx->y = static_cast<f32>(yf * 0.25f);
updateVtx(vtx, diffyf, 0.0f);
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(xmyf);
vtx->y = static_cast<f32>(yf * 0.25);
vtx->y = static_cast<f32>(yf * 0.25f);
updateVtx(vtx, diffyf, diffxf);
}
#endif
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(xhym);
vtx->y = static_cast<f32>(ymf * 0.25);
vtx->y = static_cast<f32>(ymf * 0.25f);
updateVtx(vtx, diffym, 0.0f);
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(xmym);
vtx->y = static_cast<f32>(ymf * 0.25);
vtx->y = static_cast<f32>(ymf * 0.25f);
updateVtx(vtx, diffym, diffxm);
if (dxldy != dxmdy && ym < yl) {
@ -1527,7 +1529,7 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
f32 y4f = (lc - hc) / (hk - lk);
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(hk * y4f + hc);
vtx->y = static_cast<f32>(y4f * 0.25);
vtx->y = static_cast<f32>(y4f * 0.25f);
updateVtx(vtx, (y4f - yhf), 0.0f);
}
} else {
@ -1554,7 +1556,7 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(xlf);
vtx->y = static_cast<f32>(y1f * 0.25);
vtx->y = static_cast<f32>(y1f * 0.25f);
f32 x1f = hk * y1f + hc;
f32 diffx1 = xlf - x1f;
@ -1616,20 +1618,17 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
f32 x2f = hk * ylf + hc;
f32 diffx2 = vtx->x - x2f;
updateVtx(vtx, ydiff, diffx2);
}
else if (mk == lk) {
} else if (mk == lk) {
vtx = &vertices[vtxCount++];
vtx->x = static_cast<f32>(hk * ylf + hc);
vtx->y = static_cast<f32>(ylf * 0.25f);
updateVtx(vtx, (ylf - yhf), 0.0f);
}
else {
} else {
f32 y2f = ylf;
if (yl == ym) {
y2f = (lc - mc) / (mk - lk);
}
else {
} else {
y2f = (lc - hc) / (hk - lk);
}
@ -1645,9 +1644,6 @@ void LLETriangle::draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData)
if (_zbuffer)
gSP.geometryMode |= G_ZBUFFER;
if (vtxCount < 3)
return;
GraphicsDrawer & drawer = dwnd().getDrawer();
for (u32 i = 0; i < vtxCount - 2; ++i) {
@ -1668,7 +1664,7 @@ static void gDPTriangle(u32 _w1, u32 _w2, int shade, int texture, int zbuffer)
void gDPTriFill(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 8 * sizeof(s32));
memset(&ewdata[8], 0, 36 * sizeof(s32));
LLETriangle::get().draw(0, 0, 0, ewdata);
@ -1681,7 +1677,7 @@ void gDPTriFill(u32 w0, u32 w1)
void gDPTriShade(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 24 * sizeof(s32));
memset(&ewdata[24], 0, 20 * sizeof(s32));
LLETriangle::get().draw(1, 0, 0, ewdata);
@ -1694,7 +1690,7 @@ void gDPTriShade(u32 w0, u32 w1)
void gDPTriTxtr(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 8 * sizeof(s32));
memset(&ewdata[8], 0, 16 * sizeof(s32));
memcpy(&ewdata[24], RDP.cmd_data + RDP.cmd_cur + 8, 16 * sizeof(s32));
@ -1709,7 +1705,7 @@ void gDPTriTxtr(u32 w0, u32 w1)
void gDPTriShadeTxtr(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 40 * sizeof(s32));
memset(&ewdata[40], 0, 4 * sizeof(s32));
LLETriangle::get().draw(1, 1, 0, ewdata);
@ -1722,7 +1718,7 @@ void gDPTriShadeTxtr(u32 w0, u32 w1)
void gDPTriFillZ(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 8 * sizeof(s32));
memset(&ewdata[8], 0, 32 * sizeof(s32));
memcpy(&ewdata[40], RDP.cmd_data + RDP.cmd_cur + 8, 4 * sizeof(s32));
@ -1736,7 +1732,7 @@ void gDPTriFillZ(u32 w0, u32 w1)
void gDPTriShadeZ(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 24 * sizeof(s32));
memset(&ewdata[24], 0, 16 * sizeof(s32));
memcpy(&ewdata[40], RDP.cmd_data + RDP.cmd_cur + 24, 4 * sizeof(s32));
@ -1750,7 +1746,7 @@ void gDPTriShadeZ(u32 w0, u32 w1)
void gDPTriTxtrZ(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 8 * sizeof(s32));
memset(&ewdata[8], 0, 16 * sizeof(s32));
memcpy(&ewdata[24], RDP.cmd_data + RDP.cmd_cur + 8, 16 * sizeof(s32));
@ -1765,7 +1761,7 @@ void gDPTriTxtrZ(u32 w0, u32 w1)
void gDPTriShadeTxtrZ(u32 w0, u32 w1)
{
#ifndef OLD_LLE
s32 ewdata[44];
u32 ewdata[44];
memcpy(&ewdata[0], RDP.cmd_data + RDP.cmd_cur, 44 * sizeof(s32));
LLETriangle::get().draw(1, 1, 1, ewdata);
#else

View File

@ -3,20 +3,20 @@
#include "Types.h"
#define CHANGED_RENDERMODE 0x001
#define CHANGED_CYCLETYPE 0x002
#define CHANGED_SCISSOR 0x004
#define CHANGED_TMEM 0x008
#define CHANGED_TILE 0x010
#define CHANGED_REJECT_BOX 0x020
#define CHANGED_RENDERMODE 0x001U
#define CHANGED_CYCLETYPE 0x002U
#define CHANGED_SCISSOR 0x004U
#define CHANGED_TMEM 0x008U
#define CHANGED_TILE 0x010U
#define CHANGED_REJECT_BOX 0x020U
//#define CHANGED_COMBINE_COLORS 0x020
#define CHANGED_COMBINE 0x040
#define CHANGED_ALPHACOMPARE 0x080
#define CHANGED_FOGCOLOR 0x100
#define CHANGED_BLENDCOLOR 0x200
#define CHANGED_FB_TEXTURE 0x400
#define CHANGED_COLORBUFFER 0x1000
#define CHANGED_CPU_FB_WRITE 0x2000
#define CHANGED_COMBINE 0x040U
#define CHANGED_ALPHACOMPARE 0x080U
#define CHANGED_FOGCOLOR 0x100U
#define CHANGED_BLENDCOLOR 0x200U
#define CHANGED_FB_TEXTURE 0x400U
#define CHANGED_COLORBUFFER 0x1000U
#define CHANGED_CPU_FB_WRITE 0x2000U
#define TEXTUREMODE_NORMAL 0
#define TEXTUREMODE_BGIMAGE 2
@ -265,7 +265,7 @@ extern gDPInfo gDP;
class LLETriangle
{
public:
void draw(bool _shade, bool _texture, bool _zbuffer, s32 * _pData);
void draw(bool _shade, bool _texture, bool _zbuffer, u32 * _pData);
void flush(u32 _cmd);
static LLETriangle& get();
@ -284,7 +284,7 @@ void gDPSetOtherMode( u32 mode0, u32 mode1 );
void gDPSetPrimDepth( u16 z, u16 dz );
void gDPSetTexturePersp( u32 enable );
void gDPSetTextureLUT( u32 mode );
void gDPSetCombine( s32 muxs0, s32 muxs1 );
void gDPSetCombine( u32 muxs0, u32 muxs1 );
void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address );
void gDPSetTextureImage( u32 format, u32 size, u32 width, u32 address );
void gDPSetDepthImage( u32 address );

View File

@ -66,7 +66,7 @@ void gSPCombineMatrices(u32 _mode)
DebugMsg(DEBUG_NORMAL, "gSPCombineMatrices();\n");
}
void gSPTriangle(s32 v0, s32 v1, s32 v2)
void gSPTriangle(u32 v0, u32 v1, u32 v2)
{
GraphicsDrawer & drawer = dwnd().getDrawer();
if ((v0 < INDEXMAP_SIZE) && (v1 < INDEXMAP_SIZE) && (v2 < INDEXMAP_SIZE)) {
@ -83,7 +83,7 @@ void gSPTriangle(s32 v0, s32 v1, s32 v2)
}
}
void gSP1Triangle( const s32 v0, const s32 v1, const s32 v2)
void gSP1Triangle( const u32 v0, const u32 v1, const u32 v2)
{
DebugMsg(DEBUG_NORMAL, "gSP1Triangle (%i, %i, %i)\n", v0, v1, v2);
@ -91,8 +91,8 @@ void gSP1Triangle( const s32 v0, const s32 v1, const s32 v2)
gSPFlushTriangles();
}
void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0,
const s32 v10, const s32 v11, const s32 v12, const s32 flag1 )
void gSP2Triangles(const u32 v00, const u32 v01, const u32 v02, const u32 flag0,
const u32 v10, const u32 v11, const u32 v12, const u32 flag1 )
{
DebugMsg(DEBUG_NORMAL, "gSP2Triangle (%i, %i, %i)-(%i, %i, %i)\n", v00, v01, v02, v10, v11, v12);
@ -101,10 +101,10 @@ void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0,
gSPFlushTriangles();
}
void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02,
const s32 v10, const s32 v11, const s32 v12,
const s32 v20, const s32 v21, const s32 v22,
const s32 v30, const s32 v31, const s32 v32 )
void gSP4Triangles(const u32 v00, const u32 v01, const u32 v02,
const u32 v10, const u32 v11, const u32 v12,
const u32 v20, const u32 v21, const u32 v22,
const u32 v30, const u32 v31, const u32 v32 )
{
DebugMsg(DEBUG_NORMAL, "gSP4Triangle (%i, %i, %i)-(%i, %i, %i)-(%i, %i, %i)-(%i, %i, %i)\n",
v00, v01, v02, v10, v11, v12, v20, v21, v22, v30, v31, v32);
@ -1944,14 +1944,14 @@ void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data)
DebugMsg(DEBUG_NORMAL, " result: %08x\n", gDP.otherMode.l);
}
void gSPLine3D( s32 v0, s32 v1, s32 flag )
void gSPLine3D(u32 v0, u32 v1, u32 flag )
{
dwnd().getDrawer().drawLine(v0, v1, 1.5f);
DebugMsg(DEBUG_NORMAL, "gSPLine3D( %i, %i, %i )\n", v0, v1, flag);
}
void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag )
void gSPLineW3D(u32 v0, u32 v1, u32 wd, u32 flag )
{
dwnd().getDrawer().drawLine(v0, v1, 1.5f + wd * 0.5f);

View File

@ -5,15 +5,15 @@
#include "GBI.h"
#include "gDP.h"
#define CHANGED_VIEWPORT 0x01
#define CHANGED_MATRIX 0x02
#define CHANGED_TEXTURE 0x04
#define CHANGED_GEOMETRYMODE 0x08
#define CHANGED_FOGPOSITION 0x10
#define CHANGED_LIGHT 0x20
#define CHANGED_LOOKAT 0x40
#define CHANGED_TEXTURESCALE 0x80
#define CHANGED_HW_LIGHT 0x100
#define CHANGED_VIEWPORT 0x01U
#define CHANGED_MATRIX 0x02U
#define CHANGED_TEXTURE 0x04U
#define CHANGED_GEOMETRYMODE 0x08U
#define CHANGED_FOGPOSITION 0x10U
#define CHANGED_LIGHT 0x20U
#define CHANGED_LOOKAT 0x40U
#define CHANGED_TEXTURESCALE 0x80U
#define CHANGED_HW_LIGHT 0x100U
#define CLIP_X 0x03
#define CLIP_NEGX 0x01
@ -192,22 +192,22 @@ void gSPSetGeometryMode( u32 mode );
void gSPClearGeometryMode( u32 mode );
void gSPSetOtherMode_H(u32 _length, u32 _shift, u32 _data);
void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data);
void gSPLine3D(s32 v0, s32 v1, s32 flag);
void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag );
void gSPLine3D(u32 v0, u32 v1, u32 flag);
void gSPLineW3D( u32 v0, u32 v1, u32 wd, u32 flag );
void gSPSetStatus(u32 sid, u32 val);
void gSPSetDMAOffsets( u32 mtxoffset, u32 vtxoffset );
void gSPSetDMATexOffset(u32 _addr);
void gSPSetVertexColorBase( u32 base );
void gSPCombineMatrices(u32 _mode);
void gSPTriangle(s32 v0, s32 v1, s32 v2);
void gSP1Triangle(s32 v0, s32 v1, s32 v2);
void gSP2Triangles(const s32 v00, const s32 v01, const s32 v02, const s32 flag0,
const s32 v10, const s32 v11, const s32 v12, const s32 flag1 );
void gSP4Triangles(const s32 v00, const s32 v01, const s32 v02,
const s32 v10, const s32 v11, const s32 v12,
const s32 v20, const s32 v21, const s32 v22,
const s32 v30, const s32 v31, const s32 v32 );
void gSPTriangle(u32 v0, u32 v1, u32 v2);
void gSP1Triangle(u32 v0, u32 v1, u32 v2);
void gSP2Triangles(const u32 v00, const u32 v01, const u32 v02, const u32 flag0,
const u32 v10, const u32 v11, const u32 v12, const u32 flag1 );
void gSP4Triangles(const u32 v00, const u32 v01, const u32 v02,
const u32 v10, const u32 v11, const u32 v12,
const u32 v20, const u32 v21, const u32 v22,
const u32 v30, const u32 v31, const u32 v32 );
void gSPLightVertex(SPVertex & _vtx);

View File

@ -17,13 +17,13 @@ u32 G_GOLDEN_MOVEWORD;
void F3D_TriX(u32 w0, u32 w1)
{
while(w1 != 0) {
s32 v0 = w1 & 0xf;
u32 v0 = w1 & 0xf;
w1 >>= 4;
s32 v1 = w1 & 0xf;
u32 v1 = w1 & 0xf;
w1 >>= 4;
s32 v2 = w0 & 0xf;
u32 v2 = w0 & 0xf;
w0 >>= 4;
gSPTriangle(v0, v1, v2);

View File

@ -630,14 +630,14 @@ void F5INDI_CalcST(const u32* params, u32 * _st)
s32 X1 = X * mtx[0 + 4 * 0] + Y * mtx[0 + 4 * 1] + Z * mtx[0 + 4 * 2] + mtx[0 + 4 * 3];
s32 Y1 = X * mtx[1 + 4 * 0] + Y * mtx[1 + 4 * 1] + Z * mtx[1 + 4 * 2] + mtx[1 + 4 * 3];
s32 Z1 = X * mtx[2 + 4 * 0] + Y * mtx[2 + 4 * 1] + Z * mtx[2 + 4 * 2] + mtx[2 + 4 * 3];
X1 -= subs[0 ^ 1] << 16;
Y1 -= subs[1 ^ 1] << 16;
Z1 -= subs[2 ^ 1] << 16;
u64 X2 = static_cast<s32>(X1);
X1 -= static_cast<s32>(static_cast<u32>(subs[0 ^ 1]) << 16);
Y1 -= static_cast<s32>(static_cast<u32>(subs[1 ^ 1]) << 16);
Z1 -= static_cast<s32>(static_cast<u32>(subs[2 ^ 1]) << 16);
u64 X2 = static_cast<u64>(X1);
u64 X2_2 = (X2 * X2) >> 16;
u64 Y2 = static_cast<s32>(Y1);
u64 Y2 = static_cast<u64>(Y1);
u64 Y2_2 = (Y2 * Y2) >> 16;
u64 Z2 = static_cast<s32>(Z1);
u64 Z2 = static_cast<u64>(Z1);
u64 Z2_2 = (Z2 * Z2) >> 16;
u64 R = X2_2 + Y2_2 + Z2_2;
u32 R1 = static_cast<u32>(R);
@ -2277,7 +2277,8 @@ void F5INDI_MoveWord(u32 _w0, u32 _w1)
static
void F5INDI_SetOtherMode(u32 w0, u32 w1)
{
u32 mask = (s32)0x80000000 >> _SHIFTR(w0, 0, 5);
//u32 mask = (s32)0x80000000 >> _SHIFTR(w0, 0, 5); // unspecified behaviour
u32 mask = static_cast<u32>(s32(0x80000000) / (1 << _SHIFTR(w0, 0, 5)));
mask >>= _SHIFTR(w0, 8, 5);
const u32 A0 = _SHIFTR(w0, 16, 3);

View File

@ -127,7 +127,7 @@ void StoreMatrix( f32 mtx[4][4], u32 address )
s16 integer[4][4];
u16 fraction[4][4];
} *n64Mat = (struct _N64Matrix *)&RDRAM[address];
for (u32 i = 0; i < 4; i++) {
for (u32 j = 0; j < 4; j++) {
const auto element = GetIntMatrixElement(mtx[i][j]);
@ -509,8 +509,6 @@ void ZSortBOSS_Lighting( u32 _w0, u32 _w1 )
tdest >>= 1;
u32 r4 = _w0 << 7;
assert(r4 >= 0);
u32 r9 = DMEM[0x944];
assert(r9 == 0);
@ -540,11 +538,11 @@ void ZSortBOSS_Lighting( u32 _w0, u32 _w1 )
//DMEM[(cdest++)^3] = (u8)(vtx.g * 255.0f);
//DMEM[(cdest++)^3] = (u8)(vtx.b * 255.0f);
//DMEM[(cdest++)^3] = (u8)(vtx.a * 255.0f);
((s16*)DMEM)[(tdest++)^1] = (s16)vtx.s;
((s16*)DMEM)[(tdest++)^1] = (s16)vtx.t;
}
LOG(LOG_VERBOSE, "ZSortBOSS_Lighting (0x%08x, 0x%08x)", _w0, _w1);
}
@ -784,7 +782,8 @@ void ZSortBOSS_UpdateMask( u32 _w0, u32 _w1 )
void ZSortBOSS_SetOtherMode_L( u32 _w0, u32 _w1 )
{
u32 mask = (s32)0x80000000 >> (_w0 & 0x1f);
//u32 mask = (s32)0x80000000 >> (_w0 & 0x1f); // unspecified behaviour
u32 mask = static_cast<u32>(s32(0x80000000) / (1 << (_w0 & 0x1f)));
mask >>= (_w0 >> 8) & 0x1f;
gDP.otherMode.l = (gDP.otherMode.l & ~mask) | _w1;
@ -799,7 +798,8 @@ void ZSortBOSS_SetOtherMode_L( u32 _w0, u32 _w1 )
void ZSortBOSS_SetOtherMode_H( u32 _w0, u32 _w1 )
{
u32 mask = (s32)0x80000000 >> (_w0 & 0x1f);
//u32 mask = (s32)0x80000000 >> (_w0 & 0x1f); // unspecified behaviour
u32 mask = static_cast<u32>(s32(0x80000000) / (1 << (_w0 & 0x1f)));
mask >>= (_w0 >> 8) & 0x1f;
gDP.otherMode.h = (gDP.otherMode.h & ~mask) | _w1;

View File

@ -121,12 +121,12 @@
<message>
<location filename="configDialog.ui" line="108"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option selects the resolution for windowed mode. You can also type in a custom window size.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;640 x 480, 800 x 600, 1024 x 768, 1280 x 960&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción selecciona la resolución del modo ventana. Puedes introducir un tamaño personalizado.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;640 x 480, 800 x 600, 1024 x 768, 1280 x 960&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción selecciona la resolución del modo ventana. Puedes introducir un tamaño personalizado.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;640 x 480, 800 x 600, 1024 x 768, 1280 x 960&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="216"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Threaded video can improve performance with poor OpenGL drivers at the cost of very marginal input lag, usually less than half a frame.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Usually off, unless there are performance issues&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El vídeo multihilo puede mejorar el rendimiento con controladores inferiores de OpenGL a costa de provocar un retraso de entrada (input lag) muy escaso, por lo generla de menos de medio fotograma.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Por norma general desactivado, a menos que haya problemas de rendimiento&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El vídeo multihilo puede mejorar el rendimiento con controladores inferiores de OpenGL a costa de provocar un retraso de entrada (input lag) muy escaso, por lo general de menos de medio fotograma.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Por norma general desactivado, a menos que haya problemas de rendimiento&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="219"/>
@ -162,7 +162,7 @@
<message>
<location filename="configDialog.ui" line="397"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;GLideN64 offers two methods to smooth jagged polygons:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Fast approximate anti-aliasing (FXAA)&lt;/span&gt;: FXAA is a post-processing filter that can provide a decent result, but as good as MSAA. The main reason to use FXAA is to use with &lt;span style=&quot; font-weight:600;&quot;&gt;N64-style depth compare&lt;/span&gt;. FXAA adds some blurriness to the output image, causing some textures like text to possibly look worse.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Multisample anti-aliasing (MSAA)&lt;/span&gt;: MSAA is a standard anti-aliasing technique used in computer graphics to improve image quality. Most modern GPUs support 2, 4, 8, and 16 samples. More samples mean better quality, but are slower. There are two downsides: it&apos;s incompatible with &lt;span style=&quot; font-weight:600;&quot;&gt;N64-style depth compare&lt;/span&gt; and may cause minor glitches in some games.&lt;/p&gt;&lt;p&gt;Recommendation: [&lt;span style=&quot; font-style:italic;&quot;&gt;Usually 16x MSAA, or FXAA with N64-style depth compare&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;GLideN64 ofrece dos métodos para suavizar los dientes de sierra entre polígonos:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Fast Approximate Anti-Aliasing (FXAA)&lt;/span&gt;: FXAA es un filtro de posprocesado que puede ofrecer un resultado decente, casi tan bueno como el MSAA. El principal motivo para usar FXAA es en conjunto con la &lt;span style=&quot; font-weight:600;&quot;&gt;comparación de profundidad al estilo de N64&lt;/span&gt;. FXAA genera una imagen algo borrosa y hará que ciertas texturas, como los textos, puedan tener una peor calidad.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Multisample Anti-Aliasing (MSAA)&lt;/span&gt;: MSAA es una técnica estándar para suavizar de bordes en gráficos informáticos con la que mejorar la calidad de imagen. La mayoría de GPU modernas admiten 2, 4, 8 y 16 muestras. A mayor muestras, mayor calidad, pero mayor lentitud. Hay dos inconvenientes: es incompatible con la &lt;span style=&quot; font-weight:600;&quot;&gt;comparación de profundidad al estilo de N64&lt;/span&gt; y puede provocar defectos leves en ciertos juegos.&lt;/p&gt;&lt;p&gt;Recomendación: [&lt;span style=&quot; font-style:italic;&quot;&gt;Por norma general MSAA 16x o FSAA si se utiliza la comparación de profundidad al estilo de N64&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;GLideN64 ofrece dos métodos para suavizar los dientes de sierra entre polígonos:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Fast Approximate Anti-Aliasing (FXAA)&lt;/span&gt;: FXAA es un filtro de posprocesado que puede ofrecer un resultado decente, casi tan bueno como el MSAA. El principal motivo para usar FXAA es en conjunto con la &lt;span style=&quot; font-weight:600;&quot;&gt;comparación de profundidad al estilo de N64&lt;/span&gt;. FXAA genera una imagen algo borrosa y hará que ciertas texturas, como los textos, puedan tener una peor calidad.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Multisample Anti-Aliasing (MSAA)&lt;/span&gt;: MSAA es una técnica estándar para suavizar de bordes en gráficos informáticos y mejorar la calidad de imagen. La mayoría de GPU modernas admiten 2, 4, 8 y 16 muestras. A mayor muestras, mayor calidad, pero mayor lentitud. Hay dos inconvenientes: es incompatible con la &lt;span style=&quot; font-weight:600;&quot;&gt;comparación de profundidad al estilo de N64&lt;/span&gt; y puede provocar defectos leves en ciertos juegos.&lt;/p&gt;&lt;p&gt;Recomendación: [&lt;span style=&quot; font-style:italic;&quot;&gt;Por norma general MSAA 16x o FSAA si se utiliza la comparación de profundidad al estilo de N64&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="418"/>
@ -218,12 +218,12 @@
<message>
<location filename="configDialog.ui" line="1086"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When enabled, all non-default values of settings are stored individually for each game.&lt;/p&gt;&lt;p&gt;When a game is running, settings are displayed and saved for the currently running game.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; GLideN64 already contains settings for the optimal performance of most games. Be careful when altering options on &apos;Emulation&apos; and &apos;Frame buffer&apos; tab.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Checked&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Al activar esta opción, se almacenarán todos los ajustes diferentes a los predeterminados en función de cada juego.&lt;/p&gt;&lt;p&gt;Cuando se ejecute un juego, se mostrarán los ajustes y se guardarán para el juego cargado.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Nota:&lt;/span&gt; GLideN64 ya contiene ajustes para conseguir un rendimiento óptimo en la mayoría de juegos. Ten cuidado al cambiar las opciones de las pestañas Emulación y «Frame buffer».&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Activada&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Al activar esta opción, se almacenarán todos los ajustes diferentes a los predeterminados en función de cada juego.&lt;/p&gt;&lt;p&gt;Cuando se ejecute un juego, se mostrarán los ajustes y se guardarán para el juego cargado.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Nota:&lt;/span&gt; GLideN64 ya contiene ajustes para conseguir un rendimiento óptimo en la mayoría de juegos. Ten cuidado al cambiar las opciones de las pestañas Emulación y «Frame buffer».&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Activada&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1089"/>
<source>Use per-game settings</source>
<translation type="unfinished">Usar ajustes individuales por juego</translation>
<translation>Usar ajustes individuales por juego</translation>
</message>
<message>
<location filename="configDialog.ui" line="1170"/>
@ -243,82 +243,82 @@
<message>
<location filename="configDialog.ui" line="1263"/>
<source>Custom gamma correction level:</source>
<translation type="unfinished">Corrección de gamma personalizada:</translation>
<translation>Corrección de gamma personalizada:</translation>
</message>
<message>
<location filename="configDialog.ui" line="1355"/>
<source>Selecting this option overrides gamma correction specified by the game.</source>
<translation type="unfinished">Al seleccionar esta opción, se ignorará la corrección de gamma especificada por el juego.</translation>
<translation>Al seleccionar esta opción, se ignorará la corrección de gamma especificada por el juego.</translation>
</message>
<message>
<location filename="configDialog.ui" line="1386"/>
<source>Dithering</source>
<translation type="unfinished"></translation>
<translation>Tramado</translation>
</message>
<message>
<location filename="configDialog.ui" line="1392"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Like real hardware this setting reduces the number of colors if dithering is used. Removes undesired dithering fragments. Default = enabled.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Tal y como pasaría en un hardware real, este ajuste reduce el número de colores usando un tramado. Elimina fragmentos tramados indeseados. Valor predeterminado: activado.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1395"/>
<source>Enable 5bit quantization</source>
<translation type="unfinished"></translation>
<translation>Activar cuantificación a 5 bits</translation>
</message>
<message>
<location filename="configDialog.ui" line="1402"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This setting doubles noise resolution to get a finer noise effect at higher resolutions. Default = disabled.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Duplica la resolución del ruido para producir un efecto de ruido más fino en resoluciones más altas. Valor predeterminado: desactivado.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1405"/>
<source>High resolution noise dithering</source>
<translation type="unfinished"></translation>
<translation>Tramado de ruido en alta resolución</translation>
</message>
<message>
<location filename="configDialog.ui" line="1412"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This setting enables game controlled ordered grid dithering. Enable it for accurate representation. Default = disabled.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Activa el tramado de cuadrícula organizada según el juego. Produce una imagen más fiel al original. Valor predeterminado: desactivado.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1415"/>
<source>Dithering pattern on output image</source>
<translation type="unfinished"></translation>
<translation>Patrón de tramado en la imagen de salida</translation>
</message>
<message>
<location filename="configDialog.ui" line="1424"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;RDRAM dithering prevents color banding in games with framebuffer effects.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El tramado en la RDRAM evita que los colores en los juegos con efectos del «frame buffer» se muestren bandeados.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1427"/>
<source>RDRAM image dithering:</source>
<translation type="unfinished"></translation>
<translation>Tramado de imagen en la RDRAM:</translation>
</message>
<message>
<location filename="configDialog.ui" line="1434"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Settings: Disabled, Bayer ordered grid dithering, Magic Square ordered grid dithering or blue noise dithering. Blue noise dithering produces unobtrusive results. Default = blue noise dithering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ajustes disponibles: desactivado, tramado de cuadrícula organizada Bayer, tramado de cuadrícula organizada Cuadrado mágico o tramado de ruido azul. El tramado de ruido azul genera resultados más discretos. Valor predeterminado: tramado de ruido azul.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1438"/>
<source>disable</source>
<translation type="unfinished"></translation>
<translation>Desactivar</translation>
</message>
<message>
<location filename="configDialog.ui" line="1443"/>
<source>Bayer</source>
<translation type="unfinished"></translation>
<translation>Bayer</translation>
</message>
<message>
<location filename="configDialog.ui" line="1448"/>
<source>Magic square</source>
<translation type="unfinished"></translation>
<translation>Cuadrado mágico</translation>
</message>
<message>
<location filename="configDialog.ui" line="1453"/>
<source>Blue noise</source>
<translation type="unfinished"></translation>
<translation>Ruido azul</translation>
</message>
<message>
<location filename="configDialog.ui" line="1466"/>
@ -343,12 +343,12 @@
<message>
<location filename="configDialog.ui" line="1528"/>
<source>Try to remove colored halos around transparent objects</source>
<translation type="unfinished">Intenta eliminar los bordes de colores alrededor de los objetos transparentes</translation>
<translation>Intenta eliminar los bordes de colores alrededor de los objetos transparentes</translation>
</message>
<message>
<location filename="configDialog.ui" line="1628"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Background is a complex macro command used to render large (normally full screen) images. Since background images usually don&apos;t fit texture memory, the microcode splits them on narrow strips and renders them one by one. HLE code has two modes to emulate background commands:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;One piece&lt;/span&gt;: The whole background image rendred as one textured rectangle. This method is normally much faster, but the result is not always correct.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Stripped&lt;/span&gt;: This method emulates background commands as close as possible to actual microcode implementation. It&apos;s slower but more precise. Another problem: some games may have gaps between rendered strips in high resolution. Use &amp;quot;Render 2D elements in N64 resolution&amp;quot; option to remove the gaps.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Game dependent, mostly Stripped&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El fondo es un comando complejo de macros utilizado para renderizar imágenes grandes (por lo general, a pantalla completa). Ya que las imágenes de fondo no suelen caber en la memoria de texturas, el microcódigo las fragmenta en forma de franjas estrechas y las renderiza una por una. El código HLE tiene dos modos de emular los comandos de fondo:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Monopieza&lt;/span&gt;: Toda la imagen de fondo se renderiza como un rectángulo texturizado. Este método suele ser mucho más rápido, pero el resultado no siempre es el correcto.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Por franjas&lt;/span&gt;: Este método emula los comandos de fondo de una forma lo más fiel posible a la implementación real del microcódigo. Es más lento, pero más preciso. Tiene otro problema: algunos juegos pueden mostrar desajustes entre franja y franja a resoluciones elevadas. Utiliza la opción «Renderizar elementos 2D en la resolución de N64» para eliminar los desajustes.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;En función de cada juego, por lo general, por franjas&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;El fondo es un comando complejo de macros utilizado para renderizar imágenes grandes (por lo general, a pantalla completa). Ya que las imágenes de fondo no suelen caber en la memoria de texturas, el microcódigo las fragmenta en franjas estrechas y las renderiza una por una. El código HLE tiene dos modos de emular los comandos de fondo:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Monopieza&lt;/span&gt;: Toda la imagen de fondo se renderiza como un rectángulo texturizado. Este método suele ser mucho más rápido, pero el resultado no siempre es el correcto.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Por franjas&lt;/span&gt;: Este método emula los comandos de fondo de una forma lo más fiel posible a la implementación real del microcódigo. Es más lento, pero más preciso. Tiene otro problema: algunos juegos pueden mostrar desajustes entre franja y franja a resoluciones elevadas. Utiliza la opción «Renderizar elementos 2D en la resolución de N64» para eliminar los desajustes.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;En función de cada juego, por lo general, por franjas&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1649"/>
@ -374,47 +374,47 @@
<location filename="configDialog.ui" line="2133"/>
<location filename="configDialog.ui" line="2143"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The N64 uses a unique method of calculating depth to the camera. When enabled, GlideN64 uses shaders to try to emulate these calculations correctly. Not compatible with anti-aliasing. &lt;span style=&quot; font-weight:600;&quot;&gt;Experimental!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Fast mode requires OpenGL 4.2 and &amp;quot;fragment shader interlock&amp;quot; extensions.&lt;/p&gt;&lt;p&gt;Compatible mode requires only core OpenGL 4.2 &lt;span style=&quot; font-weight:600;&quot;&gt;Can be slow!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Sometimes checked, for several games&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;N64 utiliza un método especial para calcular la profundidad que hay hasta la cámara. Al activar esta opción, GlideN64 utilizará shaders para intentar emular estos cálculos correctamente. No es compatible con el suavizado de bordes. &lt;span style=&quot; font-weight:600;&quot;&gt;¡Experimental!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;El modo rápido requiere OpenGL 4.y las extensiones «fragment shader interlock».&lt;/p&gt;&lt;p&gt;El modo compatible solo necesita el modo básico de OpenGL 4.2 &lt;span style=&quot; font-weight:600;&quot;&gt;¡Puede ser lento!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Activar solo en ciertos juegos&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="2136"/>
<source>N64-style depth compare (experimental, disables MSAA)</source>
<translation type="unfinished"></translation>
<translation>Comparación de profundidad de N64 (experimental, desactivará el MSAA)</translation>
</message>
<message>
<location filename="configDialog.ui" line="2152"/>
<source>Fast</source>
<translation type="unfinished"></translation>
<translation>Rápida</translation>
</message>
<message>
<location filename="configDialog.ui" line="2157"/>
<source>Compatible</source>
<translation type="unfinished"></translation>
<translation>Compatible</translation>
</message>
<message>
<location filename="configDialog.ui" line="2683"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option enables alternative storage for hi-res textures.&lt;/p&gt;&lt;p&gt;Normally memory cache is used. It keeps all hi-res textures in RAM and thus limited by available RAM size.&lt;/p&gt;&lt;p&gt;File storage keeps texture cache on HDD. It is slower than memory cache, but has virtually no limits on cache size.&lt;/p&gt;&lt;p&gt;Disable &amp;quot;Compress texture cache&amp;quot; option for better performance.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Permite almacenar las texturas en alta resolución en un sitio alternativo.&lt;/p&gt;&lt;p&gt;Normalmente se utiliza la caché de memoria para mantener todas las texturas en alta resolución dentro de la RAM, por lo que hay un límite impuesto por la cantidad de RAM disponible.&lt;/p&gt;&lt;p&gt;El almacenamiento en archivo mantiene la caché de texturas en el disco duro. Es más lenta que la caché de memoria, pero prácticamente no tiene límite de tamaño.&lt;/p&gt;&lt;p&gt;Desactiva la opción «comprimir caché de texturas» para mejorar el rendimiento.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="2696"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option dumps textures on screen to a texture pack folder. &lt;/p&gt;&lt;p&gt;Hotkey:&lt;br/&gt;Use &lt;span style=&quot; font-weight:600;&quot;&gt;D&lt;/span&gt; to toggle texture dumping on or off&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción vuelca las texturas que aparezcan en pantalla a una carpeta con un paquete de texturas. &lt;/p&gt;&lt;p&gt;Tecla de acceso directo:&lt;br/&gt;Utiliza &lt;span style=&quot; font-weight:600;&quot;&gt;D&lt;/span&gt; para activar o desactivar el volcado de texturas.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="2699"/>
<source>Press &apos;d&apos; to dump N64 textures (for texture artists)</source>
<translation type="unfinished"></translation>
<translation>Pulsa D para volcar las texturas de N64 (para diseñadores de texturas)</translation>
</message>
<message>
<location filename="configDialog.ui" line="2706"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows texture artists to reload hi-res textures while the game is running to instantly see how they look big time saver!&lt;/p&gt;&lt;p&gt;Hotkey:&lt;br/&gt;Use &lt;span style=&quot; font-weight:600;&quot;&gt;R&lt;/span&gt; to reload textures from the texture pack&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción permite a los diseñadores recargar las texturas en alta definición mientras el juego está en marcha, de esta forma podrán ver al instante cómo quedarán. ¡Ahorra mucho tiempo!&lt;/p&gt;&lt;p&gt;Tecla de acceso directo:&lt;br/&gt;Utiliza &lt;span style=&quot; font-weight:600;&quot;&gt;R&lt;/span&gt; para recargar las texturas que se encuentren en el paquete de texturas.&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="2709"/>
<source>Press &apos;r&apos; to reload hi-res textures (for texture artists)</source>
<translation type="unfinished"></translation>
<translation>Pulsa R para recargar las texturas en alta resolución (para diseñadores de texturas)</translation>
</message>
<message>
<location filename="configDialog.ui" line="3350"/>
@ -487,18 +487,18 @@
<message>
<location filename="configDialog.ui" line="3741"/>
<source>This game</source>
<translation type="unfinished">En este juego</translation>
<translation>En este juego</translation>
</message>
<message>
<location filename="configDialog.ui" line="3748"/>
<source>Save settings for:</source>
<translation type="unfinished">Guardar configuración para:</translation>
<translation>Guardar configuración para:</translation>
</message>
<message>
<location filename="configDialog.ui" line="3755"/>
<location filename="configDialog.ui" line="3765"/>
<source>Settings profile:</source>
<translation type="unfinished">Perfil de configuración:</translation>
<translation>Perfil de configuración:</translation>
</message>
<message>
<location filename="configDialog.ui" line="3785"/>
@ -734,7 +734,7 @@
<location filename="configDialog.ui" line="1136"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In N64 games lighting is calculated per vertex. This option enables Phong shading, which provides smoother and more realistic lighting.&lt;br/&gt;&lt;br/&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Your preference&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option emulates effects that use random color input. Checking this option may cause rare performance problems.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Checked&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Emula los efectos que utilizan una generación de colores aleatorios. Esta opción podría provocar problemas de rendimiento en casos puntuales.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Activado&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Emula los efectos que utilizan una generación de colores aleatorios. Esta opción podría provocar problemas de rendimiento en casos puntuales.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;Activado&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="1139"/>
@ -896,7 +896,7 @@
<message>
<location filename="configDialog.ui" line="2187"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option is required for some Reshade depth dependant effects, such as SSAO and depth of field.&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;only if you use Reshade and need depth dependant effects&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción es necesaria para ciertos efectos de Reshade que dependen de la profundidad, como SSAO y la profundidad de campo.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;activar solo si utilizas Reshade y necesitas los efectos que dependen de la profundidad&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Esta opción es necesaria para ciertos efectos de Reshade que dependen de la profundidad, como SSAO y la profundidad de campo.&lt;/p&gt;&lt;p&gt;[Recomendación: &lt;span style=&quot; font-style:italic;&quot;&gt;activar solo si utilizas Reshade y necesitas los efectos que dependen de la profundidad&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="configDialog.ui" line="2190"/>
@ -987,7 +987,7 @@ No texture enhancement</extracomment>
<location filename="configDialog.ui" line="2491"/>
<location filename="configDialog.ui" line="2686"/>
<source>Use file storage instead of memory cache</source>
<translation type="unfinished">Usar almacenamiento de archivos en lugar de la caché de memoria</translation>
<translation>Usar almacenamiento de archivos en lugar de la caché de memoria</translation>
</message>
<message>
<location filename="configDialog.ui" line="2578"/>