1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-25 05:49:34 +00:00

Implement Overscan feature.

Remove Crop feature.
Change settings save-load when "per game settings" enabled:
    * When config dialog opens, show custom settings for the running game. If no game run yet, show main settings.
    * When user press OK button, save settings to the custom ini file and to the main ini file.
This commit is contained in:
Sergey Lipskiy 2018-05-05 14:45:18 +07:00
parent 3fe0f5ec67
commit 2322f5f53f
15 changed files with 610 additions and 240 deletions

View File

@ -24,8 +24,6 @@ void Config::resetToDefaults()
video.fullscreenRefresh = 60;
video.multisampling = 0;
video.verticalSync = 0;
video.cropMode = cmDisable;
video.cropWidth = video.cropHeight = 0;
texture.maxAnisotropy = 0;
texture.bilinearMode = BILINEAR_STANDARD;
@ -67,6 +65,9 @@ void Config::resetToDefaults()
#else
frameBufferEmulation.fbInfoDisabled = 1;
#endif
frameBufferEmulation.enableOverscan = 0;
frameBufferEmulation.overscanPAL.init();
frameBufferEmulation.overscanNTSC.init();
textureFilter.txFilterMode = 0;
textureFilter.txEnhancementMode = 0;

View File

@ -4,7 +4,7 @@
#include <string>
#include "Types.h"
#define CONFIG_VERSION_CURRENT 21U
#define CONFIG_VERSION_CURRENT 22U
#define BILINEAR_3POINT 0
#define BILINEAR_STANDARD 1
@ -17,12 +17,6 @@ struct Config
std::string translationFile;
enum CropMode {
cmDisable = 0,
cmAuto,
cmCustom
};
struct
{
u32 fullscreen;
@ -30,9 +24,6 @@ struct Config
u32 fullscreenWidth, fullscreenHeight, fullscreenRefresh;
u32 multisampling;
u32 verticalSync;
u32 cropMode;
u32 cropWidth;
u32 cropHeight;
} video;
struct
@ -113,6 +104,18 @@ struct Config
u32 fbInfoDisabled;
u32 fbInfoReadColorChunk;
u32 fbInfoReadDepthChunk;
// Overscan
u32 enableOverscan;
struct {
s32 left;
s32 right;
s32 top;
s32 bottom;
void init() {
left = right = top = bottom = 0;
}
} overscanPAL, overscanNTSC;
} frameBufferEmulation;
struct

View File

@ -75,17 +75,18 @@ FrameBuffer::~FrameBuffer()
textureCache().removeFrameBufferTexture(m_pFrameBufferCopyTexture);
}
void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture)
static
void _initFrameBufferTexture(u32 _address, u16 _width, u16 _height, f32 _scale, u16 _format, u16 _size, CachedTexture *_pTexture)
{
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
_pTexture->width = (u16)(u32)(_width * m_scale);
_pTexture->height = (u16)(u32)(_height * m_scale);
_pTexture->width = (u16)(u32)(_width * _scale);
_pTexture->height = (u16)(u32)(_height * _scale);
_pTexture->format = _format;
_pTexture->size = _size;
_pTexture->clampS = 1;
_pTexture->clampT = 1;
_pTexture->address = m_startAddress;
_pTexture->address = _address;
_pTexture->clampWidth = _width;
_pTexture->clampHeight = _height;
_pTexture->frameBufferTexture = CachedTexture::fbOneSample;
@ -102,7 +103,13 @@ void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size,
_pTexture->textureBytes *= fbTexFormats.monochromeFormatBytes;
}
void FrameBuffer::_setAndAttachTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling)
void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture)
{
_initFrameBufferTexture(m_startAddress, _width, _height, m_scale, _format, _size, _pTexture);
}
static
void _setAndAttachBufferTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling)
{
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
Context::InitTextureParams initParams;
@ -143,6 +150,11 @@ void FrameBuffer::_setAndAttachTexture(ObjectHandle _fbo, CachedTexture *_pTextu
assert(!gfxContext.isFramebufferError());
}
void FrameBuffer::_setAndAttachTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling)
{
_setAndAttachBufferTexture(_fbo, _pTexture, _t, _multisampling);
}
bool FrameBuffer::_isMarioTennisScoreboard() const
{
if ((config.generalEmulation.hacks&hack_scoreboard) != 0) {
@ -196,7 +208,7 @@ void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, bool _c
} else
_setAndAttachTexture(m_FBO, m_pTexture, 0, false);
wnd.getDrawer().clearColorBuffer(nullptr);
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
}
void FrameBuffer::updateEndAddress()
@ -546,6 +558,7 @@ void FrameBufferList::init()
m_pCopy = nullptr;
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
m_prevColorImageHeight = 0;
m_overscan.init();
}
void FrameBufferList::destroy() {
@ -553,6 +566,7 @@ void FrameBufferList::destroy() {
m_list.clear();
m_pCurrent = nullptr;
m_pCopy = nullptr;
m_overscan.destroy();
}
void FrameBufferList::setBufferChanged(f32 _maxY)
@ -931,8 +945,7 @@ void FrameBufferList::_renderScreenSizeBuffer()
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
drawer.clearColorBuffer(clearColor);
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
TextureParam filter = textureParameters::FILTER_LINEAR;
@ -1105,6 +1118,135 @@ bool rdp_update(RdpUpdateResult & _result)
#endif
}
s32 FrameBufferList::OverscanBuffer::getHOffset() const
{
if (m_enabled)
return 0;
return m_hOffset;
}
s32 FrameBufferList::OverscanBuffer::getVOffset() const
{
if (m_enabled)
return 0;
return m_vOffset;
}
f32 FrameBufferList::OverscanBuffer::getScaleX() const
{
return m_scale;
}
f32 FrameBufferList::OverscanBuffer::getScaleY(u32 _fullHeight) const
{
if (m_enabled)
return m_scale;
return (float)dwnd().getHeight() / float(_fullHeight);
}
void FrameBufferList::OverscanBuffer::init()
{
m_enabled = config.frameBufferEmulation.enableOverscan != 0;
if (m_enabled)
m_FBO = gfxContext.createFramebuffer();
DisplayWindow & wnd = dwnd();
m_hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2;
m_vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2;
m_scale = wnd.getScaleX();
m_drawingWidth = wnd.getWidth();
m_bufferWidth = wnd.getScreenWidth();
m_bufferHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
}
void FrameBufferList::OverscanBuffer::destroy()
{
gfxContext.deleteFramebuffer(m_FBO);
m_FBO = graphics::ObjectHandle::null;
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = nullptr;
}
void FrameBufferList::OverscanBuffer::setInputBuffer(const FrameBuffer * _pBuffer)
{
if (!m_enabled) {
return;
}
if (m_pTexture != nullptr &&
m_pTexture->width == _pBuffer->m_pTexture->width &&
m_pTexture->height == _pBuffer->m_pTexture->height &&
m_scale == _pBuffer->m_scale) {
return;
}
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = textureCache().addFrameBufferTexture(false);
const CachedTexture * pSrcTexture = _pBuffer->m_pTexture;
_initFrameBufferTexture(0,
_pBuffer->m_width,
VI_GetMaxBufferHeight(_pBuffer->m_width),
_pBuffer->m_scale,
pSrcTexture->format,
pSrcTexture->size,
m_pTexture);
_setAndAttachBufferTexture(m_FBO, m_pTexture, 0, false);
m_scale = _pBuffer->m_scale;
m_drawingWidth = m_bufferWidth = m_pTexture->width;
m_bufferHeight = m_pTexture->height;
}
void FrameBufferList::OverscanBuffer::activate()
{
if (!m_enabled) {
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
return;
}
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_FBO);
}
void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL)
{
if (!m_enabled)
return;
DisplayWindow & wnd = dwnd();
GraphicsDrawer & drawer = wnd.getDrawer();
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
GraphicsDrawer::BlitOrCopyRectParams blitParams;
const auto & overscan = _PAL ? config.frameBufferEmulation.overscanPAL : config.frameBufferEmulation.overscanNTSC;
const s32 left = static_cast<s32>(overscan.left * m_scale);
const s32 right = static_cast<s32>(overscan.right * m_scale);
const s32 top = static_cast<s32>(overscan.top * m_scale);
const s32 bottom = static_cast<s32>(overscan.bottom * m_scale);
blitParams.srcX0 = left;
blitParams.srcY0 = top;
blitParams.srcX1 = m_bufferWidth - right;
blitParams.srcY1 = static_cast<s32>(_fullHeight * m_scale) - bottom;
blitParams.srcWidth = m_pTexture->realWidth;
blitParams.srcHeight = m_pTexture->realHeight;
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.dstWidth = wnd.getScreenWidth();
blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
blitParams.filter = textureParameters::FILTER_LINEAR;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.tex[0] = m_pTexture;
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
blitParams.readBuffer = m_FBO;
blitParams.invertY = true;
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
drawer.blitOrCopyTexturedRect(blitParams);
// drawer.copyTexturedRect(blitParams);
}
void FrameBufferList::renderBuffer()
{
@ -1129,6 +1271,7 @@ void FrameBufferList::renderBuffer()
if (pBuffer == nullptr)
return;
pBuffer->m_isMainBuffer = true;
m_overscan.setInputBuffer(pBuffer);
DisplayWindow & wnd = dwnd();
GraphicsDrawer & drawer = wnd.getDrawer();
@ -1143,7 +1286,7 @@ void FrameBufferList::renderBuffer()
dstY0 = rdpRes.vi_v_start;
const u32 vFullHeight = rdpRes.vi_ispal ? 288 : 240;
const float dstScaleY = (float)wnd.getHeight() / float(vFullHeight);
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;
@ -1165,7 +1308,6 @@ void FrameBufferList::renderBuffer()
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;
const u32 stride = pBuffer->m_width << pBuffer->m_size >> 1;
FrameBuffer *pNextBuffer = findBuffer(rdpRes.vi_origin + stride * (srcHeight - 1));
if (pNextBuffer == pBuffer)
@ -1188,35 +1330,33 @@ void FrameBufferList::renderBuffer()
const f32 viScaleX = _FIXED2FLOAT(_SHIFTR(*REG.VI_X_SCALE, 0, 12), 10);
const f32 srcScaleX = pFilteredBuffer->m_scale;
const f32 dstScaleX = wnd.getScaleX();
const f32 dstScaleX = m_overscan.getScaleX();
const s32 hx0 = rdpRes.vi_h_start;
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);
//const s32 hx1 = hx0 + rdpRes.vi_hres;
dstX0 = (s32)((hx0 * viScaleX + Xoffset) * dstScaleX);
dstX1 = wnd.getWidth() - (s32)((hx1*viScaleX + Xdivot) * dstScaleX);
dstX1 = m_overscan.getDrawingWidth() - (s32)((hx1*viScaleX + Xdivot) * dstScaleX);
srcWidth -= Xoffset + Xdivot;
const f32 srcScaleY = pFilteredBuffer->m_scale;
CachedTexture * pBufferTexture = pFilteredBuffer->m_pTexture;
const s32 hCrop = config.video.cropMode == Config::cmDisable ? 0 : s32(config.video.cropWidth * srcScaleX);
const s32 vCrop = config.video.cropMode == Config::cmDisable ? 0 : s32(config.video.cropHeight * srcScaleY);
s32 srcCoord[4] = { hCrop,
vCrop + (s32)(srcY0*srcScaleY),
(s32)(srcWidth * srcScaleX) - hCrop,
min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->realHeight) - vCrop };
s32 srcCoord[4] = { 0,
(s32)(srcY0*srcScaleY),
(s32)(srcWidth * srcScaleX),
min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->realHeight) };
if (srcCoord[2] > pBufferTexture->realWidth || srcCoord[3] > pBufferTexture->realHeight) {
removeBuffer(pBuffer->m_startAddress);
return;
}
const s32 hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2;
const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2;// +wnd.getHeightOffset();
const s32 hOffset = m_overscan.getHOffset();
const s32 vOffset = m_overscan.getVOffset();
s32 dstCoord[4] = { dstX0 + hOffset,
vOffset + (s32)(dstY0*dstScaleY),
hOffset + dstX1,
vOffset + (s32)(dstY1*dstScaleY) };
vOffset + (s32)(dstY0*dstScaleY),
hOffset + dstX1,
vOffset + (s32)(dstY1*dstScaleY) };
TextureParam filter = textureParameters::FILTER_LINEAR;
ObjectHandle readBuffer;
@ -1229,9 +1369,8 @@ void FrameBufferList::renderBuffer()
readBuffer = pFilteredBuffer->m_FBO;
}
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
drawer.clearColorBuffer(clearColor);
m_overscan.activate();
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
GraphicsDrawer::BlitOrCopyRectParams blitParams;
blitParams.srcX0 = srcCoord[0];
@ -1244,14 +1383,14 @@ void FrameBufferList::renderBuffer()
blitParams.dstY0 = dstCoord[1];
blitParams.dstX1 = dstCoord[2];
blitParams.dstY1 = dstCoord[3];
blitParams.dstWidth = wnd.getScreenWidth();
blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
blitParams.dstWidth = m_overscan.getBufferWidth();
blitParams.dstHeight = m_overscan.getBufferHeight();
blitParams.filter = filter;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.tex[0] = pBufferTexture;
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
blitParams.readBuffer = readBuffer;
blitParams.invertY = true;
blitParams.invertY = config.frameBufferEmulation.enableOverscan == 0;
drawer.copyTexturedRect(blitParams);
@ -1279,8 +1418,8 @@ void FrameBufferList::renderBuffer()
blitParams.dstY0 = vOffset + (s32)(dstY0*dstScaleY);
blitParams.dstX1 = hOffset + dstX1;
blitParams.dstY1 = vOffset + (s32)(dstY1*dstScaleY);
blitParams.dstWidth = wnd.getScreenWidth();
blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
blitParams.dstWidth = m_overscan.getBufferWidth();
blitParams.dstHeight = m_overscan.getBufferHeight();
blitParams.tex[0] = pBufferTexture;
blitParams.readBuffer = readBuffer;
@ -1288,6 +1427,7 @@ void FrameBufferList::renderBuffer()
}
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
m_overscan.draw(vFullHeight, rdpRes.vi_ispal);
wnd.swapBuffers();
if (m_pCurrent != nullptr) {

View File

@ -126,11 +126,43 @@ private:
void _createScreenSizeBuffer();
void _renderScreenSizeBuffer();
class OverscanBuffer
{
public:
void init();
void destroy();
void setInputBuffer(const FrameBuffer * _pBuffer);
void activate();
void draw(u32 _fullHeight, bool _PAL);
s32 getHOffset() const;
s32 getVOffset() const;
f32 getScaleX() const;
f32 getScaleY(u32 _fullHeight) const;
u32 getDrawingWidth() const { return m_drawingWidth; }
u32 getBufferWidth() const { return m_bufferWidth; }
u32 getBufferHeight() const { return m_bufferHeight; }
private:
s32 m_hOffset = 0;
s32 m_vOffset = 0;
f32 m_scale = 1.0f;
u32 m_drawingWidth = 0U;
u32 m_bufferWidth = 0U;
u32 m_bufferHeight = 0U;
bool m_enabled = false;
graphics::ObjectHandle m_FBO;
CachedTexture *m_pTexture = nullptr;
};
typedef std::list<FrameBuffer> FrameBuffers;
FrameBuffers m_list;
FrameBuffer * m_pCurrent;
FrameBuffer * m_pCopy;
u32 m_prevColorImageHeight;
OverscanBuffer m_overscan;
};
inline

View File

@ -91,10 +91,16 @@ void ConfigDialog::_init()
QValidator *windowedValidator = new QRegExpValidator(windowedRegExp, this);
ui->windowedResolutionComboBox->setValidator(windowedValidator);
ui->cropImageComboBox->setCurrentIndex(config.video.cropMode);
ui->cropImageWidthSpinBox->setValue(config.video.cropWidth);
ui->cropImageHeightSpinBox->setValue(config.video.cropHeight);
ui->cropImageCustomFrame->setVisible(config.video.cropMode == Config::cmCustom);
ui->overscanCheckBox->toggle();
ui->overscanCheckBox->setChecked(config.frameBufferEmulation.enableOverscan != 0);
ui->overscanNtscLeftSpinBox->setValue(config.frameBufferEmulation.overscanNTSC.left);
ui->overscanNtscRightSpinBox->setValue(config.frameBufferEmulation.overscanNTSC.right);
ui->overscanNtscTopSpinBox->setValue(config.frameBufferEmulation.overscanNTSC.top);
ui->overscanNtscBottomSpinBox->setValue(config.frameBufferEmulation.overscanNTSC.bottom);
ui->overscanPalLeftSpinBox->setValue(config.frameBufferEmulation.overscanPAL.left);
ui->overscanPalRightSpinBox->setValue(config.frameBufferEmulation.overscanPAL.right);
ui->overscanPalTopSpinBox->setValue(config.frameBufferEmulation.overscanPAL.top);
ui->overscanPalBottomSpinBox->setValue(config.frameBufferEmulation.overscanPAL.bottom);
QStringList fullscreenModesList, fullscreenRatesList;
int fullscreenMode, fullscreenRate;
@ -299,7 +305,6 @@ void ConfigDialog::_getTranslations(QStringList & _translationFiles) const
_translationFiles = pluginFolder.entryList(nameFilters, QDir::Files, QDir::Name);
}
void ConfigDialog::setIniPath(const QString & _strIniPath)
{
m_strIniPath = _strIniPath;
@ -328,6 +333,11 @@ void ConfigDialog::setIniPath(const QString & _strIniPath)
ui->translationsComboBox->setCurrentIndex(listIndex);
}
void ConfigDialog::setRomName(const char * _romName)
{
m_romName = _romName;
}
ConfigDialog::ConfigDialog(QWidget *parent, Qt::WindowFlags f) :
QDialog(parent, f),
ui(new Ui::ConfigDialog),
@ -360,10 +370,6 @@ void ConfigDialog::accept()
getFullscreenResolutions(ui->fullScreenResolutionComboBox->currentIndex(), config.video.fullscreenWidth, config.video.fullscreenHeight);
getFullscreenRefreshRate(ui->fullScreenRefreshRateComboBox->currentIndex(), config.video.fullscreenRefresh);
config.video.cropMode = ui->cropImageComboBox->currentIndex();
config.video.cropWidth = ui->cropImageWidthSpinBox->value();
config.video.cropHeight = ui->cropImageHeightSpinBox->value();
config.video.multisampling = ui->n64DepthCompareCheckBox->isChecked() ? 0 : pow2(ui->aliasingSlider->value());
config.texture.maxAnisotropy = ui->anisotropicSlider->value();
@ -438,6 +444,16 @@ void ConfigDialog::accept()
config.frameBufferEmulation.fbInfoReadColorChunk = ui->readColorChunkCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.fbInfoReadDepthChunk = ui->readDepthChunkCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.enableOverscan = ui->overscanCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.overscanNTSC.left = ui->overscanNtscLeftSpinBox->value();
config.frameBufferEmulation.overscanNTSC.right = ui->overscanNtscRightSpinBox->value();
config.frameBufferEmulation.overscanNTSC.top = ui->overscanNtscTopSpinBox->value();
config.frameBufferEmulation.overscanNTSC.bottom = ui->overscanNtscBottomSpinBox->value();
config.frameBufferEmulation.overscanPAL.left = ui->overscanPalLeftSpinBox->value();
config.frameBufferEmulation.overscanPAL.right = ui->overscanPalRightSpinBox->value();
config.frameBufferEmulation.overscanPAL.top = ui->overscanPalTopSpinBox->value();
config.frameBufferEmulation.overscanPAL.bottom = ui->overscanPalBottomSpinBox->value();
// Texture filter settings
config.textureFilter.txFilterMode = ui->filterComboBox->currentIndex();
config.textureFilter.txEnhancementMode = ui->enhancementComboBox->currentIndex();
@ -509,6 +525,9 @@ void ConfigDialog::accept()
if (ui->dumpDetailCheckBox->isChecked())
config.debug.dumpMode |= DEBUG_DETAIL;
if (config.generalEmulation.enableCustomSettings != 0 && m_romName != nullptr && strlen(m_romName) != 0)
saveCustomRomSettings(m_strIniPath, m_romName);
writeSettings(m_strIniPath);
QDialog::accept();
@ -546,8 +565,11 @@ void ConfigDialog::on_buttonBox_clicked(QAbstractButton *button)
msgBox.setButtonText(QMessageBox::RestoreDefaults, tr("Restore Defaults"));
msgBox.setButtonText(QMessageBox::Cancel, tr("Cancel"));
if (msgBox.exec() == QMessageBox::RestoreDefaults) {
const u32 enableCustomSettings = config.generalEmulation.enableCustomSettings;
config.resetToDefaults();
config.generalEmulation.enableCustomSettings = enableCustomSettings;
_init();
setTitle();
}
}
}
@ -608,10 +630,9 @@ void ConfigDialog::on_windowedResolutionComboBox_currentTextChanged(QString text
ui->windowedResolutionComboBox->setCurrentText("");
}
void ConfigDialog::on_cropImageComboBox_currentIndexChanged(int index)
void ConfigDialog::on_overscanCheckBox_toggled(bool checked)
{
const bool bCustom = index == Config::cmCustom;
ui->cropImageCustomFrame->setVisible(bCustom);
ui->overscanCheckBox->setText(tr("Overscan") + (checked ? QString(":") : QString("")));
}
void ConfigDialog::on_frameBufferCheckBox_toggled(bool checked)
@ -683,3 +704,27 @@ void ConfigDialog::on_tabWidget_currentChanged(int tab)
m_fontsInited = true;
}
}
void ConfigDialog::on_customSettingsCheckBox_clicked()
{
if (ui->customSettingsCheckBox->isChecked()) {
loadCustomRomSettings(m_strIniPath, m_romName);
config.generalEmulation.enableCustomSettings = 1;
} else {
loadSettings(m_strIniPath);
config.generalEmulation.enableCustomSettings = 0;
}
_init();
setTitle();
}
void ConfigDialog::setTitle()
{
if (config.generalEmulation.enableCustomSettings != 0 && m_romName != nullptr && strlen(m_romName) != 0) {
QString title(tr("GLideN64 Settings for "));
title += QString::fromLatin1(m_romName);
setWindowTitle(title);
} else {
setWindowTitle(tr("GLideN64 Settings"));
}
}

View File

@ -18,6 +18,8 @@ public:
~ConfigDialog();
void setIniPath(const QString & _strIniPath);
void setRomName(const char * _romName);
void setTitle();
bool isAccepted() const { return m_accepted; }
public Q_SLOTS:
@ -36,7 +38,7 @@ private slots:
void on_windowedResolutionComboBox_currentTextChanged(QString text);
void on_cropImageComboBox_currentIndexChanged(int index);
void on_overscanCheckBox_toggled(bool checked);
void on_frameBufferCheckBox_toggled(bool checked);
@ -52,6 +54,8 @@ private slots:
void on_texDumpPathButton_clicked();
void on_customSettingsCheckBox_clicked();
private:
void _init();
void _getTranslations(QStringList & _translationFiles) const;
@ -62,6 +66,7 @@ private:
bool m_accepted;
bool m_fontsInited;
QString m_strIniPath;
const char * m_romName;
};
#endif // CONFIGDIALOG_H

View File

@ -6,6 +6,7 @@
#include "AboutDialog.h"
#include "ConfigDialog.h"
#include "Settings.h"
#include "../Config.h"
#ifdef QT_STATICPLUGIN
#include <QtPlugin>
@ -19,12 +20,14 @@ inline void initMyResource() { Q_INIT_RESOURCE(icon); }
inline void cleanMyResource() { Q_CLEANUP_RESOURCE(icon); }
static
int openConfigDialog(const wchar_t * _strFileName, bool & _accepted)
int openConfigDialog(const wchar_t * _strFileName, const char * _romName, bool & _accepted)
{
cleanMyResource();
initMyResource();
QString strIniFileName = QString::fromWCharArray(_strFileName);
loadSettings(strIniFileName);
if (config.generalEmulation.enableCustomSettings != 0 && _romName != nullptr && strlen(_romName) != 0)
loadCustomRomSettings(strIniFileName, _romName);
int argc = 0;
char * argv = 0;
@ -37,6 +40,8 @@ int openConfigDialog(const wchar_t * _strFileName, bool & _accepted)
ConfigDialog w(Q_NULLPTR, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
w.setIniPath(strIniFileName);
w.setRomName(_romName);
w.setTitle();
w.show();
const int res = a.exec();
_accepted = w.isAccepted();
@ -62,13 +67,13 @@ int openAboutDialog(const wchar_t * _strFileName)
return a.exec();
}
bool runConfigThread(const wchar_t * _strFileName) {
bool runConfigThread(const wchar_t * _strFileName, const char * _romName) {
bool accepted = false;
#ifdef RUN_DIALOG_IN_THREAD
std::thread configThread(openConfigDialog, _strFileName, std::ref(accepted));
configThread.join();
#else
openConfigDialog(_strFileName, accepted);
openConfigDialog(_strFileName, _romName, accepted);
#endif
return accepted;
@ -84,9 +89,9 @@ int runAboutThread(const wchar_t * _strFileName) {
return 0;
}
EXPORT bool CALL RunConfig(const wchar_t * _strFileName)
EXPORT bool CALL RunConfig(const wchar_t * _strFileName, const char * _romName)
{
return runConfigThread(_strFileName);
return runConfigThread(_strFileName, _romName);
}
EXPORT int CALL RunAbout(const wchar_t * _strFileName)

View File

@ -13,7 +13,7 @@ extern "C" {
#define CALL
#endif
EXPORT bool CALL RunConfig(const wchar_t * _strFileName);
EXPORT bool CALL RunConfig(const wchar_t * _strFileName, const char * _romName);
EXPORT int CALL RunAbout(const wchar_t * _strFileName);
EXPORT void CALL LoadConfig(const wchar_t * _strFileName);
EXPORT void CALL LoadCustomRomSettings(const wchar_t * _strFileName, const char * _romName);

View File

@ -27,9 +27,6 @@ void _loadSettings(QSettings & settings)
config.video.fullscreenRefresh = settings.value("fullscreenRefresh", config.video.fullscreenRefresh).toInt();
config.video.multisampling = settings.value("multisampling", config.video.multisampling).toInt();
config.video.verticalSync = settings.value("verticalSync", config.video.verticalSync).toInt();
config.video.cropMode = settings.value("cropMode", config.video.cropMode).toInt();
config.video.cropWidth = settings.value("cropWidth", config.video.cropWidth).toInt();
config.video.cropHeight = settings.value("cropHeight", config.video.cropHeight).toInt();
settings.endGroup();
settings.beginGroup("texture");
@ -62,7 +59,15 @@ void _loadSettings(QSettings & settings)
config.frameBufferEmulation.fbInfoDisabled = settings.value("fbInfoDisabled", config.frameBufferEmulation.fbInfoDisabled).toInt();
config.frameBufferEmulation.fbInfoReadColorChunk = settings.value("fbInfoReadColorChunk", config.frameBufferEmulation.fbInfoReadColorChunk).toInt();
config.frameBufferEmulation.fbInfoReadDepthChunk = settings.value("fbInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk).toInt();
config.frameBufferEmulation.enableOverscan = settings.value("enableOverscan", config.frameBufferEmulation.enableOverscan).toInt();
config.frameBufferEmulation.overscanPAL.left = settings.value("overscanPalLeft", config.frameBufferEmulation.overscanPAL.left).toInt();
config.frameBufferEmulation.overscanPAL.right = settings.value("overscanPalRight", config.frameBufferEmulation.overscanPAL.right).toInt();
config.frameBufferEmulation.overscanPAL.top = settings.value("overscanPalTop", config.frameBufferEmulation.overscanPAL.top).toInt();
config.frameBufferEmulation.overscanPAL.bottom= settings.value("overscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom).toInt();
config.frameBufferEmulation.overscanNTSC.left = settings.value("overscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left).toInt();
config.frameBufferEmulation.overscanNTSC.right = settings.value("overscanNtscRight", config.frameBufferEmulation.overscanNTSC.right).toInt();
config.frameBufferEmulation.overscanNTSC.top = settings.value("overscanNtscTop", config.frameBufferEmulation.overscanNTSC.top).toInt();
config.frameBufferEmulation.overscanNTSC.bottom = settings.value("overscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom).toInt();
settings.endGroup();
settings.beginGroup("textureFilter");
@ -156,9 +161,6 @@ void writeSettings(const QString & _strIniFolder)
settings.setValue("fullscreenRefresh", config.video.fullscreenRefresh);
settings.setValue("multisampling", config.video.multisampling);
settings.setValue("verticalSync", config.video.verticalSync);
settings.setValue("cropMode", config.video.cropMode);
settings.setValue("cropWidth", config.video.cropWidth);
settings.setValue("cropHeight", config.video.cropHeight);
settings.endGroup();
settings.beginGroup("texture");
@ -191,6 +193,15 @@ void writeSettings(const QString & _strIniFolder)
settings.setValue("fbInfoDisabled", config.frameBufferEmulation.fbInfoDisabled);
settings.setValue("fbInfoReadColorChunk", config.frameBufferEmulation.fbInfoReadColorChunk);
settings.setValue("fbInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk);
settings.setValue("enableOverscan", config.frameBufferEmulation.enableOverscan);
settings.setValue("overscanPalLeft", config.frameBufferEmulation.overscanPAL.left);
settings.setValue("overscanPalRight", config.frameBufferEmulation.overscanPAL.right);
settings.setValue("overscanPalTop", config.frameBufferEmulation.overscanPAL.top);
settings.setValue("overscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom);
settings.setValue("overscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left);
settings.setValue("overscanNtscRight", config.frameBufferEmulation.overscanNTSC.right);
settings.setValue("overscanNtscTop", config.frameBufferEmulation.overscanNTSC.top);
settings.setValue("overscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom);
settings.endGroup();
settings.beginGroup("textureFilter");
@ -263,16 +274,23 @@ u32 Adler32(u32 crc, const void *buffer, u32 count)
return (s2 << 16) | s1;
}
void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomName)
{
QSettings settings(_strIniFolder + "/" + strCustomSettingsFileName, QSettings::IniFormat);
static
QString _getRomName(const char * _strRomName) {
const QByteArray bytes(_strRomName);
bool bASCII = true;
for (int i = 0; i < bytes.length() && bASCII; ++i)
bASCII = bytes.at(i) >= 0;
const QString romName = bASCII ? QString::fromLatin1(_strRomName).toUpper() : QString::number(Adler32(0xFFFFFFFF, bytes.data(), bytes.length()), 16).toUpper();
return bASCII ?
QString::fromLatin1(_strRomName).toUpper() :
QString::number(Adler32(0xFFFFFFFF, bytes.data(), bytes.length()), 16).toUpper();
}
void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomName)
{
QSettings settings(_strIniFolder + "/" + strCustomSettingsFileName, QSettings::IniFormat);
const QString romName = _getRomName(_strRomName);
if (settings.childGroups().indexOf(romName) < 0)
return;
@ -281,6 +299,103 @@ void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomNa
settings.endGroup();
}
void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomName)
{
Config origConfig;
origConfig.resetToDefaults();
QSettings settings(_strIniFolder + "/" + strCustomSettingsFileName, QSettings::IniFormat);
const QString romName = _getRomName(_strRomName);
#define WriteCustomSetting(G, S) \
if (config.G.S != settings.value(#S, origConfig.G.S).toInt()) \
settings.setValue(#S, config.G.S)
settings.beginGroup(romName);
settings.beginGroup("video");
WriteCustomSetting(video, multisampling);
WriteCustomSetting(video, verticalSync);
settings.endGroup();
settings.beginGroup("texture");
WriteCustomSetting(texture, maxAnisotropy);
WriteCustomSetting(texture, bilinearMode);
settings.endGroup();
settings.beginGroup("generalEmulation");
WriteCustomSetting(generalEmulation, enableNoise);
WriteCustomSetting(generalEmulation, enableLOD);
WriteCustomSetting(generalEmulation, enableHWLighting);
WriteCustomSetting(generalEmulation, correctTexrectCoords);
WriteCustomSetting(generalEmulation, enableNativeResTexrects);
settings.endGroup();
settings.beginGroup("frameBufferEmulation");
WriteCustomSetting(frameBufferEmulation, enable);
WriteCustomSetting(frameBufferEmulation, aspect);
WriteCustomSetting(frameBufferEmulation, nativeResFactor);
WriteCustomSetting(frameBufferEmulation, bufferSwapMode);
WriteCustomSetting(frameBufferEmulation, N64DepthCompare);
WriteCustomSetting(frameBufferEmulation, forceDepthBufferClear);
WriteCustomSetting(frameBufferEmulation, copyAuxToRDRAM);
WriteCustomSetting(frameBufferEmulation, copyFromRDRAM);
WriteCustomSetting(frameBufferEmulation, copyToRDRAM);
WriteCustomSetting(frameBufferEmulation, copyDepthToRDRAM);
WriteCustomSetting(frameBufferEmulation, fbInfoDisabled);
WriteCustomSetting(frameBufferEmulation, fbInfoReadColorChunk);
WriteCustomSetting(frameBufferEmulation, fbInfoReadDepthChunk);
WriteCustomSetting(frameBufferEmulation, enableOverscan);
if (config.frameBufferEmulation.overscanPAL.left !=
settings.value("overscanPalLeft", origConfig.frameBufferEmulation.overscanPAL.left).toInt())
settings.setValue("overscanPalLeft", config.frameBufferEmulation.overscanPAL.left);
if (config.frameBufferEmulation.overscanPAL.right !=
settings.value("overscanPalRight", origConfig.frameBufferEmulation.overscanPAL.right).toInt())
settings.setValue("overscanPalRight", config.frameBufferEmulation.overscanPAL.right);
if (config.frameBufferEmulation.overscanPAL.top !=
settings.value("overscanPalTop", origConfig.frameBufferEmulation.overscanPAL.top).toInt())
settings.setValue("overscanPalTop", config.frameBufferEmulation.overscanPAL.top);
if (config.frameBufferEmulation.overscanPAL.bottom !=
settings.value("overscanPalBottom", origConfig.frameBufferEmulation.overscanPAL.bottom).toInt())
settings.setValue("overscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom);
if (config.frameBufferEmulation.overscanNTSC.left !=
settings.value("overscanNtscLeft", origConfig.frameBufferEmulation.overscanNTSC.left).toInt())
settings.setValue("overscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left);
if (config.frameBufferEmulation.overscanNTSC.right !=
settings.value("overscanNtscRight", origConfig.frameBufferEmulation.overscanNTSC.right).toInt())
settings.setValue("overscanNtscRight", config.frameBufferEmulation.overscanNTSC.right);
if (config.frameBufferEmulation.overscanNTSC.top !=
settings.value("overscanNtscTop", origConfig.frameBufferEmulation.overscanNTSC.top).toInt())
settings.setValue("overscanNtscTop", config.frameBufferEmulation.overscanNTSC.top);
if (config.frameBufferEmulation.overscanNTSC.bottom !=
settings.value("overscanNtscBottom", origConfig.frameBufferEmulation.overscanNTSC.bottom).toInt())
settings.setValue("overscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom);
settings.endGroup();
settings.beginGroup("textureFilter");
WriteCustomSetting(textureFilter, txFilterMode);
WriteCustomSetting(textureFilter, txEnhancementMode);
WriteCustomSetting(textureFilter, txDeposterize);
WriteCustomSetting(textureFilter, txFilterIgnoreBG);
WriteCustomSetting(textureFilter, txCacheSize);
WriteCustomSetting(textureFilter, txHiresEnable);
WriteCustomSetting(textureFilter, txHiresFullAlphaChannel);
WriteCustomSetting(textureFilter, txHresAltCRC);
WriteCustomSetting(textureFilter, txForce16bpp);
WriteCustomSetting(textureFilter, txCacheCompression);
WriteCustomSetting(textureFilter, txSaveCache);
settings.endGroup();
settings.beginGroup("gammaCorrection");
WriteCustomSetting(gammaCorrection, force);
if (config.gammaCorrection.level != settings.value("level", origConfig.gammaCorrection.level).toFloat())
settings.setValue("level", config.gammaCorrection.level);
settings.endGroup();
settings.endGroup();
}
QString getTranslationFile()
{
return config.translationFile.c_str();

View File

@ -4,6 +4,7 @@
void loadSettings(const QString & _strIniFolder);
void writeSettings(const QString & _strIniFolder);
void loadCustomRomSettings(const QString & _strIniFolder, const char * _strRomName);
void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomName);
QString getTranslationFile();
#endif // SETTINGS_H

View File

@ -158,11 +158,17 @@
</widget>
</item>
<item>
<widget class="QFrame" name="cropImageFrame">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You can use this option to crop black borders. Use &lt;span style=&quot; font-weight:600;&quot;&gt;Auto per game&lt;/span&gt; to crop automatically based on the game or &lt;span style=&quot; font-weight:600;&quot;&gt;Custom&lt;/span&gt; to set the number of pixels yourself. The number of pixels is based on the original N64 resolution.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<widget class="QFrame" name="overscanFrame">
<property name="minimumSize">
<size>
<width>147</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_25">
<property name="toolTip">
<string>When enabled, the image is cropped by values specified in N64 pixels. Useful to remove black borders in some games.</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
<property name="spacing">
<number>5</number>
</property>
@ -179,121 +185,114 @@
<number>0</number>
</property>
<item>
<widget class="QLabel" name="cropImageLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<widget class="QCheckBox" name="overscanCheckBox">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Crop image:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Overscan</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cropImageComboBox">
<property name="locale">
<locale language="English" country="UnitedStates"/>
<widget class="QTabWidget" name="overscanTabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Disable</string>
</property>
</item>
<item>
<property name="text">
<string>Auto per game</string>
</property>
</item>
<item>
<property name="text">
<string>Custom</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QFrame" name="cropImageCustomFrame">
<layout class="QHBoxLayout" name="horizontalLayout_23">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="cropImageWidthLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string extracomment="Abbreviation for &quot;width&quot;.">W:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="cropImageWidthSpinBox">
<property name="minimumSize">
<size>
<width>52</width>
<height>0</height>
</size>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="maximum">
<number>64</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="cropImageHeightLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string extracomment="Abbreviation for &quot;height&quot;.">H:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="cropImageHeightSpinBox">
<property name="minimumSize">
<size>
<width>52</width>
<height>0</height>
</size>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="maximum">
<number>48</number>
</property>
</widget>
</item>
</layout>
<widget class="QWidget" name="overscanNtscTab">
<attribute name="title">
<string>NTSC</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="1" column="0">
<widget class="QSpinBox" name="overscanNtscLeftSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="overscanNtscRightSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="overscanNtscTopSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="overscanNtscBottomSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="overscanPalTab">
<attribute name="title">
<string>PAL</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="2" column="1">
<widget class="QSpinBox" name="overscanPalBottomSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="overscanPalRightSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="overscanPalLeftSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="overscanPalTopSpinBox">
<property name="minimum">
<number>-99</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -374,7 +373,7 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer_11">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -1082,10 +1081,10 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;GLideN64 contains settings for the optimal performance of some games. When this option is checked some options on this tab and the frame buffer tab may be overridden.&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;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When enabled, all non-default values of settings stored individually for each game.&lt;/p&gt;&lt;p&gt;When game is running, configuration dialog displays individual settings for 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 some games. Be careful when altering options on 'Emulation' and 'Frame buffer' 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;</string>
</property>
<property name="text">
<string>Use GlideN64 per-game settings</string>
<string>Use per-game settings</string>
</property>
<property name="checked">
<bool>true</bool>
@ -3798,22 +3797,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>frameBufferCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>cropImageFrame</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>100</x>
<y>41</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>278</y>
</hint>
</hints>
</connection>
<connection>
<sender>fbInfoEnableCheckBox</sender>
<signal>toggled(bool)</signal>
@ -3949,12 +3932,12 @@
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>85</x>
<y>72</y>
<x>99</x>
<y>71</y>
</hint>
<hint type="destinationlabel">
<x>78</x>
<y>88</y>
<x>92</x>
<y>85</y>
</hint>
</hints>
</connection>
@ -4006,12 +3989,28 @@
</hint>
</hints>
</connection>
<connection>
<sender>overscanCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>overscanTabWidget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>149</x>
<y>307</y>
</hint>
<hint type="destinationlabel">
<x>144</x>
<y>332</y>
</hint>
</hints>
</connection>
</connections>
<buttongroups>
<buttongroup name="factorButtonGroup"/>
<buttongroup name="screenshotButtonGroup"/>
<buttongroup name="factorButtonGroup"/>
<buttongroup name="osdButtonGroup"/>
<buttongroup name="fixTexrectCoordsButtonGroup"/>
<buttongroup name="aspectButtonGroup"/>
<buttongroup name="fixTexrectCoordsButtonGroup"/>
</buttongroups>
</ui>

View File

@ -1644,6 +1644,12 @@ void GraphicsDrawer::blitOrCopyTexturedRect(const BlitOrCopyRectParams & _params
blitParams.dstY1 = _params.dstY1;
blitParams.mask = _params.mask;
blitParams.filter = _params.filter;
if (_params.invertX) {
std::swap(blitParams.srcX0, blitParams.srcX1);
}
if (_params.invertY) {
std::swap(blitParams.srcY0, blitParams.srcY1);
}
if (gfxContext.blitFramebuffers(blitParams))
return;

View File

@ -672,17 +672,6 @@ void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry )
gDP.changed |= CHANGED_SCISSOR;
if (config.video.cropMode == Config::cmAuto && gDP.depthImageAddress != gDP.colorImage.address) {
const u32 maxCropH = VI.width / 16;
const u32 maxCropV = VI.height / 10;
if (ulx > 0 && ulx < maxCropH &&
uly > 0 && uly < maxCropV &&
(VI.width - lrx) < maxCropH && (VI.height - lry) < maxCropV) {
config.video.cropWidth = (u32)ulx;
config.video.cropHeight = (u32)uly;
}
}
#ifdef DEBUG_DUMP
DebugMsg( DEBUG_NORMAL, "gDPSetScissor( %s, %.2f, %.2f, %.2f, %.2f );\n",
ScissorModeText[gDP.scissor.mode],

View File

@ -45,13 +45,6 @@ bool Config_SetDefault()
res = ConfigSetDefaultInt(g_configVideoGliden64, "configVersion", CONFIG_VERSION_CURRENT, "Settings version. Don't touch it.");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "CropMode", config.video.cropMode, "Crop resulted image (0=disable, 1=auto crop, 2=user defined crop)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "CropWidth", config.video.cropWidth, "Crop width pixels from left and right of resulted image (in native resolution)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "CropHeight", config.video.cropHeight, "Crop height pixels from top and bottom of resulted image (in native resolution)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "MultiSampling", config.video.multisampling, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "AspectRatio", config.frameBufferEmulation.aspect, "Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust)");
@ -116,6 +109,24 @@ bool Config_SetDefault()
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM", config.frameBufferEmulation.copyFromRDRAM, "Enable color buffer copy from RDRAM.");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableOverscan", config.frameBufferEmulation.enableOverscan, "Enable resulted image crop by Overscan.");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanPalLeft", config.frameBufferEmulation.overscanPAL.left, "PAL mode. Left bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanPalRight", config.frameBufferEmulation.overscanPAL.right, "PAL mode. Right bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanPalTop", config.frameBufferEmulation.overscanPAL.top, "PAL mode. Top bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanPalBottom", config.frameBufferEmulation.overscanPAL.bottom, "PAL mode. Bottom bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanNtscLeft", config.frameBufferEmulation.overscanNTSC.left, "NTSC mode. Left bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanNtscRight", config.frameBufferEmulation.overscanNTSC.right, "NTSC mode. Right bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanNtscTop", config.frameBufferEmulation.overscanNTSC.top, "NTSC mode. Top bound of Overscan");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultInt(g_configVideoGliden64, "OverscanNtscBottom", config.frameBufferEmulation.overscanNTSC.bottom, "NTSC mode. Bottom bound of Overscan");
assert(res == M64ERR_SUCCESS);
//#Texture filter settings
res = ConfigSetDefaultInt(g_configVideoGliden64, "txFilterMode", config.textureFilter.txFilterMode, "Texture filter (0=none, 1=Smooth filtering 1, 2=Smooth filtering 2, 3=Smooth filtering 3, 4=Smooth filtering 4, 5=Sharp filtering 1, 6=Sharp filtering 2)");
assert(res == M64ERR_SUCCESS);
@ -222,12 +233,6 @@ void Config_LoadCustomConfig()
if (result == M64ERR_SUCCESS) config.video.fullscreenRefresh = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "video\\multisampling", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.video.multisampling = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "video\\cropMode", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.video.cropMode = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "video\\cropWidth", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.video.cropWidth = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "video\\cropHeight", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.video.cropHeight = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "texture\\maxAnisotropy", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.texture.maxAnisotropy = atoi(value);
@ -279,6 +284,24 @@ void Config_LoadCustomConfig()
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.fbInfoReadColorChunk = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\fbInfoReadDepthChunk", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.fbInfoReadDepthChunk = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\EnableOverscan", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.enableOverscan = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanPalLeft", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanPAL.left = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanPalRight", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanPAL.right = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanPalTop", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanPAL.top = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanPalBottom", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanPAL.bottom = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanNtscLeft", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanNTSC.left = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanNtscRight", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanNTSC.right = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanNtscTop", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanNTSC.top = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "frameBufferEmulation\\OverscanNtscBottom", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.frameBufferEmulation.overscanNTSC.bottom = atoi(value);
result = ConfigExternalGetParameter(fileHandle, sectionName, "textureFilter\\txFilterMode", value, sizeof(value));
if (result == M64ERR_SUCCESS) config.textureFilter.txFilterMode = atoi(value);
@ -317,9 +340,6 @@ void Config_LoadConfig()
config.video.windowedHeight = ConfigGetParamInt(g_configVideoGeneral, "ScreenHeight");
config.video.verticalSync = ConfigGetParamBool(g_configVideoGeneral, "VerticalSync");
config.video.cropMode = ConfigGetParamInt(g_configVideoGliden64, "CropMode");
config.video.cropWidth = ConfigGetParamInt(g_configVideoGliden64, "CropWidth");
config.video.cropHeight = ConfigGetParamInt(g_configVideoGliden64, "CropHeight");
const u32 multisampling = ConfigGetParamInt(g_configVideoGliden64, "MultiSampling");
config.video.multisampling = multisampling == 0 ? 0 : pow2(multisampling);
config.frameBufferEmulation.aspect = ConfigGetParamInt(g_configVideoGliden64, "AspectRatio");
@ -356,6 +376,15 @@ void Config_LoadConfig()
config.frameBufferEmulation.fbInfoDisabled = ConfigGetParamBool(g_configVideoGliden64, "DisableFBInfo");
config.frameBufferEmulation.fbInfoReadColorChunk = ConfigGetParamBool(g_configVideoGliden64, "FBInfoReadColorChunk");
config.frameBufferEmulation.fbInfoReadDepthChunk = ConfigGetParamBool(g_configVideoGliden64, "FBInfoReadDepthChunk");
config.frameBufferEmulation.enableOverscan = ConfigGetParamBool(g_configVideoGliden64, "EnableOverscan");
config.frameBufferEmulation.overscanPAL.left = ConfigGetParamInt(g_configVideoGliden64, "OverscanPalLeft");
config.frameBufferEmulation.overscanPAL.right = ConfigGetParamInt(g_configVideoGliden64, "OverscanPalRight");
config.frameBufferEmulation.overscanPAL.top = ConfigGetParamInt(g_configVideoGliden64, "OverscanPalTop");
config.frameBufferEmulation.overscanPAL.bottom = ConfigGetParamInt(g_configVideoGliden64, "OverscanPalBottom");
config.frameBufferEmulation.overscanNTSC.left = ConfigGetParamInt(g_configVideoGliden64, "OverscanNtscLeft");
config.frameBufferEmulation.overscanNTSC.right = ConfigGetParamInt(g_configVideoGliden64, "OverscanNtscRight");
config.frameBufferEmulation.overscanNTSC.top = ConfigGetParamInt(g_configVideoGliden64, "OverscanNtscTop");
config.frameBufferEmulation.overscanNTSC.bottom = ConfigGetParamInt(g_configVideoGliden64, "OverscanNtscBottom");
//#Texture filter settings
config.textureFilter.txFilterMode = ConfigGetParamInt(g_configVideoGliden64, "txFilterMode");
config.textureFilter.txEnhancementMode = ConfigGetParamInt(g_configVideoGliden64, "txEnhancementMode");

View File

@ -15,7 +15,7 @@ void Config_DoConfig(/*HWND hParent*/)
api().FindPluginPath(strIniFolderPath);
ConfigOpen = true;
const bool bRestart = RunConfig(strIniFolderPath);
const bool bRestart = RunConfig(strIniFolderPath, api().isRomOpen() ? RSP.romname : nullptr);
if (config.generalEmulation.enableCustomSettings != 0)
LoadCustomRomSettings(strIniFolderPath, RSP.romname);
if (bRestart)