mirror of https://github.com/mgba-emu/mgba.git
Compare commits
14 Commits
688ef4d521
...
922dddb86f
Author | SHA1 | Date |
---|---|---|
Dana Yatsuta | 922dddb86f | |
Vicki Pfau | 49fa1a30c5 | |
Vicki Pfau | f75f9fd5fd | |
Vicki Pfau | c64dbd6631 | |
Vicki Pfau | 11787df6cd | |
Vicki Pfau | 271c6dc129 | |
Vicki Pfau | b37bd308f2 | |
Vicki Pfau | 3853b699f4 | |
Imre Kristoffer Eilertsen | 9d9cb7450f | |
Evrins Hu | a60448d7bc | |
Milihraim | e4973a98d8 | |
Hexaae | 3ad4e62b02 | |
Vicki Pfau | bb8a6e05f9 | |
Dana Yatsuta | 56f08ab6ba |
|
@ -12,7 +12,11 @@ install:
|
|||
- vcpkg --no-dry-run upgrade
|
||||
- rd /Q /S C:\Tools\vcpkg\buildtrees
|
||||
before_build:
|
||||
- cmake . -DCMAKE_PREFIX_PATH=C:\Qt\5.15\msvc2019_64 -DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-release -DCMAKE_CONFIGURATION_TYPES=Release
|
||||
- cmake . -DCMAKE_PREFIX_PATH=C:\Qt\5.15\msvc2019_64 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake \
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows-release \
|
||||
-DCMAKE_CONFIGURATION_TYPES=Release \
|
||||
-DCMAKE_SYSTEM_VERSION=10.0.22000.1
|
||||
build:
|
||||
parallel: true
|
||||
project: mGBA.sln
|
||||
|
|
2
CHANGES
2
CHANGES
|
@ -52,6 +52,8 @@ Misc:
|
|||
- Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632)
|
||||
- Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095)
|
||||
- Qt: Show maker code and game version in ROM info
|
||||
- Qt: Make window corners square on Windows 11 (fixes mgba.io/i/3285)
|
||||
- Res: Port NSO-gba-colors shader (closes mgba.io/i/2834)
|
||||
- Scripting: Add `callbacks:oneshot` for single-call callbacks
|
||||
- Switch: Add bilinear filtering option (closes mgba.io/i/3111)
|
||||
- Vita: Add imc0 and xmc0 mount point support
|
||||
|
|
|
@ -20,6 +20,7 @@ struct mArguments {
|
|||
char* cheatsFile;
|
||||
char* savestate;
|
||||
char* bios;
|
||||
char* shader;
|
||||
int logLevel;
|
||||
int frameskip;
|
||||
|
||||
|
|
|
@ -1,34 +1,21 @@
|
|||
// Shader that replicates the LCD Colorspace from Gameboy Advance --
|
||||
varying vec2 texCoord;
|
||||
varying mat4 profile;
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 texSize;
|
||||
|
||||
uniform float darken_screen;
|
||||
const float target_gamma = 2.2;
|
||||
const float display_gamma = 2.5;
|
||||
const float sat = 1.0;
|
||||
const float lum = 0.99;
|
||||
const float contrast = 1.0;
|
||||
const vec3 bl = vec3(0.0, 0.0, 0.0);
|
||||
const vec3 r = vec3(0.84, 0.09, 0.15);
|
||||
const vec3 g = vec3(0.18, 0.67, 0.10);
|
||||
const vec3 b = vec3(0.0, 0.26, 0.73);
|
||||
const float target_gamma = 2.0;
|
||||
const float display_gamma = 2.0;
|
||||
|
||||
void main() {
|
||||
// bring out our stored luminance value
|
||||
float lum = profile[3].w;
|
||||
|
||||
// our adjustments need to happen in linear gamma
|
||||
vec4 screen = pow(texture2D(tex, texCoord), vec4(target_gamma + darken_screen)).rgba;
|
||||
vec4 avglum = vec4(0.5);
|
||||
screen = mix(screen, avglum, (1.0 - contrast));
|
||||
|
||||
mat4 color = mat4( r.r, r.g, r.b, 0.0,
|
||||
g.r, g.g, g.b, 0.0,
|
||||
b.r, b.g, b.b, 0.0,
|
||||
bl.r, bl.g, bl.b, 1.0);
|
||||
|
||||
mat4 adjust = mat4( (1.0 - sat) * 0.3086 + sat, (1.0 - sat) * 0.3086, (1.0 - sat) * 0.3086, 1.0,
|
||||
(1.0 - sat) * 0.6094, (1.0 - sat) * 0.6094 + sat, (1.0 - sat) * 0.6094, 1.0,
|
||||
(1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820 + sat, 1.0,
|
||||
0.0, 0.0, 0.0, 1.0);
|
||||
color *= adjust;
|
||||
screen = clamp(screen * lum, 0.0, 1.0);
|
||||
screen = color * screen;
|
||||
gl_FragColor = pow(screen, vec4(1.0 / display_gamma + (darken_screen * 0.125)));
|
||||
screen = profile * screen;
|
||||
gl_FragColor = pow(screen, vec4(1.0 / display_gamma));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
uniform int color_mode;
|
||||
attribute vec4 position;
|
||||
varying vec2 texCoord;
|
||||
varying mat4 profile;
|
||||
|
||||
const mat4 GBA_sRGB = mat4(
|
||||
0.80, 0.135, 0.195, 0.0, //red channel
|
||||
0.275, 0.64, 0.155, 0.0, //green channel
|
||||
-0.075, 0.225, 0.65, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 0.93 //alpha channel
|
||||
);
|
||||
|
||||
const mat4 GBA_DCI = mat4(
|
||||
0.685, 0.16, 0.20, 0.0, //red channel
|
||||
0.34, 0.629, 0.19, 0.0, //green channel
|
||||
-0.025, 0.211, 0.61, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 0.975 //alpha channel
|
||||
);
|
||||
|
||||
const mat4 GBA_Rec2020 = mat4(
|
||||
0.555, 0.1825, 0.20, 0.0, //red channel
|
||||
0.395, 0.61, 0.195, 0.0, //green channel
|
||||
0.05, 0.2075, 0.605, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 1.0 //alpha channel
|
||||
);
|
||||
|
||||
void main() {
|
||||
if (color_mode == 1) profile = GBA_sRGB;
|
||||
else if (color_mode == 2) profile = GBA_DCI;
|
||||
else if (color_mode == 3) profile = GBA_Rec2020;
|
||||
|
||||
gl_Position = position;
|
||||
texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5);
|
||||
}
|
|
@ -6,6 +6,7 @@ passes=1
|
|||
|
||||
[pass.0]
|
||||
fragmentShader=gba-color.fs
|
||||
vertexShader=gba-color.vs
|
||||
blend=1
|
||||
width=-1
|
||||
height=-1
|
||||
|
@ -14,3 +15,10 @@ height=-1
|
|||
type=float
|
||||
default=0.5
|
||||
readableName=Darken Screen
|
||||
|
||||
[pass.0.uniform.color_mode]
|
||||
type=int
|
||||
default=1
|
||||
min=1
|
||||
max=3
|
||||
readableName=Color Profile (1=sRGB, 2=DCI, 3=Rec2020)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
[shader]
|
||||
name=NSO GBA Color
|
||||
author=Pokefan531 and hunterk
|
||||
description=Shader that replicates the Nintendo Switch Online's GBA color filter.
|
||||
passes=1
|
||||
|
||||
[pass.0]
|
||||
fragmentShader=nso-gba-color.fs
|
||||
vertexShader=nso-gba-color.vs
|
||||
blend=1
|
||||
width=-1
|
||||
height=-1
|
||||
|
||||
[pass.0.uniform.darken_screen]
|
||||
type=float
|
||||
default=0.8
|
||||
readableName=Darken Screen
|
||||
|
||||
[pass.0.uniform.color_mode]
|
||||
type=int
|
||||
default=1
|
||||
min=1
|
||||
max=3
|
||||
readableName=Color Profile (1=sRGB, 2=DCI, 3=Rec2020)
|
|
@ -0,0 +1,21 @@
|
|||
// Shader that replicates the LCD Colorspace from Gameboy Advance --
|
||||
varying vec2 texCoord;
|
||||
varying mat4 profile;
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 texSize;
|
||||
|
||||
uniform float darken_screen;
|
||||
const float target_gamma = 2.2;
|
||||
const float display_gamma = 2.2;
|
||||
|
||||
void main() {
|
||||
// bring out our stored luminance value
|
||||
float lum = profile[3].w;
|
||||
|
||||
// our adjustments need to happen in linear gamma
|
||||
vec4 screen = pow(texture2D(tex, texCoord), vec4(target_gamma + darken_screen)).rgba;
|
||||
|
||||
screen = clamp(screen * lum, 0.0, 1.0);
|
||||
screen = profile * screen;
|
||||
gl_FragColor = pow(screen, vec4(1.0 / display_gamma));
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
uniform int color_mode;
|
||||
attribute vec4 position;
|
||||
varying vec2 texCoord;
|
||||
varying mat4 profile;
|
||||
|
||||
const mat4 GBA_sRGB = mat4(
|
||||
0.865, 0.0575, 0.0575, 0.0, //red channel
|
||||
0.1225, 0.925, 0.1225, 0.0, //green channel
|
||||
0.0125, 0.0125, 0.82, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 1.0 //alpha channel
|
||||
);
|
||||
|
||||
const mat4 GBA_DCI = mat4(
|
||||
0.72, 0.0875, 0.0725, 0.0, //red channel
|
||||
0.2675, 0.9, 0.185, 0.0, //green channel
|
||||
0.0125, 0.0125, 0.7425, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 1.0 //alpha channel
|
||||
);
|
||||
|
||||
const mat4 GBA_Rec2020 = mat4(
|
||||
0.57, 0.115, 0.0725, 0.0, //red channel
|
||||
0.3825, 0.8625, 0.195, 0.0, //green channel
|
||||
0.0475, 0.0225, 0.7325, 0.0, //blue channel
|
||||
0.0, 0.0, 0.0, 1.0 //alpha channel
|
||||
);
|
||||
|
||||
void main() {
|
||||
if (color_mode == 1) profile = GBA_sRGB;
|
||||
else if (color_mode == 2) profile = GBA_DCI;
|
||||
else if (color_mode == 3) profile = GBA_Rec2020;
|
||||
|
||||
gl_Position = position;
|
||||
texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5);
|
||||
}
|
|
@ -47,6 +47,7 @@ static const struct option _options[] = {
|
|||
{ "log-level", required_argument, 0, 'l' },
|
||||
{ "savestate", required_argument, 0, 't' },
|
||||
{ "patch", required_argument, 0, 'p' },
|
||||
{ "shader", required_argument, 0, 'a'},
|
||||
{ "version", no_argument, 0, '\0' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
@ -81,7 +82,7 @@ static void _tableApply(const char* key, void* value, void* user) {
|
|||
bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struct mSubParser* subparsers, int nSubparsers) {
|
||||
int ch;
|
||||
char options[128] =
|
||||
"b:c:C:hl:p:s:t:"
|
||||
"b:c:C:hl:p:s:t:a:"
|
||||
#ifdef USE_EDITLINE
|
||||
"d"
|
||||
#endif
|
||||
|
@ -172,6 +173,9 @@ bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struc
|
|||
case 't':
|
||||
args->savestate = strdup(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
args->shader = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
if (subparsers[i].parse) {
|
||||
|
@ -207,6 +211,9 @@ void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparser
|
|||
mCoreConfigSetOverrideValue(config, "bios", args->bios);
|
||||
mCoreConfigSetOverrideIntValue(config, "useBios", true);
|
||||
}
|
||||
if (args->shader) {
|
||||
mCoreConfigSetOverrideValue(config, "shader", args->shader);
|
||||
}
|
||||
HashTableEnumerate(&args->configOverrides, _tableApply, config);
|
||||
int i;
|
||||
for (i = 0; i < nSubparsers; ++i) {
|
||||
|
@ -292,6 +299,9 @@ void mArgumentsDeinit(struct mArguments* args) {
|
|||
free(args->bios);
|
||||
args->bios = 0;
|
||||
|
||||
free(args->shader);
|
||||
args->shader = 0;
|
||||
|
||||
HashTableDeinit(&args->configOverrides);
|
||||
}
|
||||
|
||||
|
|
|
@ -1350,10 +1350,22 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o
|
|||
}
|
||||
}
|
||||
|
||||
#define MUNGE8 \
|
||||
if (address & 1) { \
|
||||
oldValue = alignedValue >> 8; \
|
||||
alignedValue &= 0xFF; \
|
||||
alignedValue |= value << 8; \
|
||||
} else { \
|
||||
oldValue = alignedValue; \
|
||||
alignedValue &= 0xFF00; \
|
||||
alignedValue |= (uint8_t) value; \
|
||||
}
|
||||
|
||||
void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int8_t oldValue = -1;
|
||||
int16_t alignedValue;
|
||||
|
||||
switch (address >> BASE_OFFSET) {
|
||||
case GBA_REGION_EWRAM:
|
||||
|
@ -1368,13 +1380,29 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old)
|
|||
mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
|
||||
break;
|
||||
case GBA_REGION_PALETTE_RAM:
|
||||
mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
|
||||
LOAD_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette);
|
||||
MUNGE8;
|
||||
STORE_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette);
|
||||
gba->video.renderer->writePalette(gba->video.renderer, address & (GBA_SIZE_PALETTE_RAM - 2), alignedValue);
|
||||
break;
|
||||
case GBA_REGION_VRAM:
|
||||
mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
|
||||
if ((address & 0x0001FFFF) < GBA_SIZE_VRAM) {
|
||||
LOAD_16(alignedValue, address & 0x0001FFFE, gba->video.vram);
|
||||
MUNGE8;
|
||||
STORE_16(alignedValue, address & 0x0001FFFE, gba->video.vram);
|
||||
gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE);
|
||||
} else {
|
||||
LOAD_16(alignedValue, address & 0x00017FFE, gba->video.vram);
|
||||
MUNGE8;
|
||||
STORE_16(alignedValue, address & 0x00017FFE, gba->video.vram);
|
||||
gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE);
|
||||
}
|
||||
break;
|
||||
case GBA_REGION_OAM:
|
||||
mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address);
|
||||
LOAD_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw);
|
||||
MUNGE8;
|
||||
STORE_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw);
|
||||
gba->video.renderer->writeOAM(gba->video.renderer, (address & (GBA_SIZE_OAM - 2)) >> 1);
|
||||
break;
|
||||
case GBA_REGION_ROM0:
|
||||
case GBA_REGION_ROM0_EX:
|
||||
|
|
|
@ -427,6 +427,7 @@ set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PR
|
|||
|
||||
if(WIN32)
|
||||
set_target_properties(${BINARY_NAME}-qt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
target_link_libraries(${BINARY_NAME}-qt dwmapi)
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(${BINARY_NAME}-qt -municode)
|
||||
endif()
|
||||
|
@ -445,7 +446,7 @@ if(QT_STATIC)
|
|||
if(CMAKE_CROSSCOMPILING)
|
||||
set(QWINDOWS_DEPS ${QT}EventDispatcherSupport ${QT}FontDatabaseSupport ${QT}ThemeSupport ${QT}WindowsUIAutomationSupport)
|
||||
endif()
|
||||
list(APPEND QT_LIBRARIES ${QT}::QWindowsIntegrationPlugin ${QWINDOWS_DEPS} amstrmid dwmapi uxtheme imm32 -static-libgcc -static-libstdc++)
|
||||
list(APPEND QT_LIBRARIES ${QT}::QWindowsIntegrationPlugin ${QWINDOWS_DEPS} amstrmid uxtheme imm32 -static-libgcc -static-libstdc++)
|
||||
set_target_properties(${QT}::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32")
|
||||
set_target_properties(${QT}::Gui PROPERTIES INTERFACE_LINK_LIBRARIES ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY})
|
||||
elseif(APPLE)
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <dwmapi.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SQLITE3
|
||||
#include "ArchiveInspector.h"
|
||||
#include "library/LibraryController.h"
|
||||
|
@ -717,6 +721,11 @@ void Window::showEvent(QShowEvent* event) {
|
|||
return;
|
||||
}
|
||||
m_wasOpened = true;
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(winId());
|
||||
DWM_WINDOW_CORNER_PREFERENCE cornerPref = DWMWCP_DONOTROUND;
|
||||
DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref));
|
||||
#endif
|
||||
if (m_initialSize.isValid()) {
|
||||
resizeFrame(m_initialSize);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue