diff --git a/CHANGES b/CHANGES index 23d8cf6ca..178f4307a 100644 --- a/CHANGES +++ b/CHANGES @@ -83,6 +83,8 @@ Emulation fixes: - GBA Video: Fix rare regression blending semitransparent sprites (fixes mgba.io/i/1876) - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) + - GBA Video: Fix deferred blending when OBJWIN matches window (fixes mgba.io/i/1905) + - GBA Video: Fix mode 4 transparency in OpenGL (fixes mgba.io/i/1907) - SM83: Emulate HALT bug Other fixes: - 3DS: Redo video sync to be more precise @@ -104,6 +106,9 @@ Other fixes: - Qt: Add dummy English translation file (fixes mgba.io/i/1469) - Qt: Fix Battle Chip view not displaying chips on some DPI settings - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) + - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) + - Qt: Load/save bytes from memory viewer in the order visible (fixes mgba.io/i/1900) + - Qt: Fix stride changing when toggling SGB borders (fixes mgba.io/i/1898) - mGUI: Fix closing down a game if an exit is signalled - mVL: Fix injecting accidentally draining non-injection buffer - SM83: Simplify register pair access on big endian diff --git a/include/mgba/internal/gb/renderers/proxy.h b/include/mgba/internal/gb/renderers/proxy.h index 244c5e39b..bde4e2ddb 100644 --- a/include/mgba/internal/gb/renderers/proxy.h +++ b/include/mgba/internal/gb/renderers/proxy.h @@ -17,9 +17,6 @@ struct GBVideoProxyRenderer { struct GBVideoRenderer d; struct GBVideoRenderer* backend; struct mVideoLogger* logger; - - struct GBObj objThisLine[40]; - size_t oamMax; }; void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend); diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index fe4b1ff98..11e107f6d 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -40,6 +40,9 @@ struct GBVideoSoftwareRenderer { GBRegisterLCDC lcdc; enum GBModel model; + struct GBObj obj[10]; + int objMax; + int16_t objOffsetX; int16_t objOffsetY; int16_t offsetScx; diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index 13473776a..cd5a1e8d1 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -77,7 +77,7 @@ struct GBVideoRenderer { void (*writeVRAM)(struct GBVideoRenderer* renderer, uint16_t address); void (*writePalette)(struct GBVideoRenderer* renderer, int index, uint16_t value); void (*writeOAM)(struct GBVideoRenderer* renderer, uint16_t oam); - void (*drawRange)(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* objOnLine, size_t nObj); + void (*drawRange)(struct GBVideoRenderer* renderer, int startX, int endX, int y); void (*finishScanline)(struct GBVideoRenderer* renderer, int y); void (*finishFrame)(struct GBVideoRenderer* renderer); void (*enableSGBBorder)(struct GBVideoRenderer* renderer, bool enable); @@ -139,7 +139,6 @@ struct GBVideo { int vramCurrentBank; union GBOAM oam; - struct GBObj objThisLine[10]; int objMax; int bcpIndex; diff --git a/src/gb/core.c b/src/gb/core.c index ec6c8c2dc..9c0eaf38e 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -301,6 +301,12 @@ static void _GBCoreReloadConfigOption(struct mCore* core, const char* option, co } return; } + if (strcmp("sgb.borders", option) == 0) { + if (mCoreConfigGetIntValue(config, "sgb.borders", &fakeBool)) { + gb->video.sgbBorders = fakeBool; + gb->video.renderer->enableSGBBorder(gb->video.renderer, fakeBool); + } + } } static void _GBCoreDesiredVideoDimensions(const struct mCore* core, unsigned* width, unsigned* height) { diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index f7b21cbda..24758cd2a 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -19,7 +19,7 @@ static void GBVideoProxyRendererWriteSGBPacket(struct GBVideoRenderer* renderer, static void GBVideoProxyRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address); static void GBVideoProxyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam); static void GBVideoProxyRendererWritePalette(struct GBVideoRenderer* renderer, int address, uint16_t value); -static void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); +static void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y); static void GBVideoProxyRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer); static void GBVideoProxyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); @@ -68,8 +68,6 @@ static void _reset(struct GBVideoProxyRenderer* proxyRenderer) { memcpy(proxyRenderer->logger->oam, &proxyRenderer->d.oam->raw, GB_SIZE_OAM); memcpy(proxyRenderer->logger->vram, proxyRenderer->d.vram, GB_SIZE_VRAM); - proxyRenderer->oamMax = 0; - mVideoLoggerRendererReset(proxyRenderer->logger); } @@ -117,6 +115,7 @@ void GBVideoProxyRendererDeinit(struct GBVideoRenderer* renderer) { static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* item) { struct GBVideoProxyRenderer* proxyRenderer = logger->context; uint8_t sgbPacket[16]; + struct GBObj legacyBuffer[40]; switch (item->type) { case DIRTY_REGISTER: proxyRenderer->backend->writeVideoRegister(proxyRenderer->backend, item->address, item->value); @@ -145,7 +144,7 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD break; case DIRTY_RANGE: if (item->value < item->value2 && item->value2 <= GB_VIDEO_HORIZONTAL_PIXELS && item->address < GB_VIDEO_VERTICAL_PIXELS) { - proxyRenderer->backend->drawRange(proxyRenderer->backend, item->value, item->value2, item->address, proxyRenderer->objThisLine, proxyRenderer->oamMax); + proxyRenderer->backend->drawRange(proxyRenderer->backend, item->value, item->value2, item->address); } break; case DIRTY_FRAME: @@ -154,12 +153,10 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD case DIRTY_BUFFER: switch (item->address) { case BUFFER_OAM: - proxyRenderer->oamMax = item->value2 / sizeof(struct GBObj); - if (proxyRenderer->oamMax > 40) { - proxyRenderer->oamMax = 0; + if (item->value2 / sizeof(struct GBObj) > 40) { return false; } - logger->readData(logger, &proxyRenderer->objThisLine, item->value2, true); + logger->readData(logger, legacyBuffer, item->value2, true); break; case BUFFER_SGB: logger->readData(logger, sgbPacket, 16, true); @@ -228,12 +225,11 @@ void GBVideoProxyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam mVideoLoggerRendererWriteOAM(proxyRenderer->logger, oam, ((uint8_t*) proxyRenderer->d.oam->raw)[oam]); } -void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { +void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (!proxyRenderer->logger->block) { - proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y, obj, oamMax); + proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y); } - mVideoLoggerWriteBuffer(proxyRenderer->logger, BUFFER_OAM, 0, oamMax * sizeof(*obj), obj); mVideoLoggerRendererDrawRange(proxyRenderer->logger, startX, endX, y); } diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 637bae496..f6c4f9818 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -18,7 +18,7 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value); static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address); static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam); -static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); +static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y); static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer); static void GBVideoSoftwareRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); @@ -499,7 +499,31 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, ui // Nothing to do } -static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { +static void _cleanOAM(struct GBVideoSoftwareRenderer* renderer, int y) { + // TODO: GBC differences + // TODO: Optimize + int spriteHeight = 8; + if (GBRegisterLCDCIsObjSize(renderer->lcdc)) { + spriteHeight = 16; + } + int o = 0; + int i; + for (i = 0; i < 40 && o < 10; ++i) { + uint8_t oy = renderer->d.oam->obj[i].y; + if (y < oy - 16 || y >= oy - 16 + spriteHeight) { + continue; + } + // TODO: Sort + renderer->obj[o] = renderer->d.oam->obj[i]; + ++o; + if (o == 10) { + break; + } + } + renderer->objMax = o; +} + +static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; softwareRenderer->lastY = y; softwareRenderer->lastX = endX; @@ -536,9 +560,12 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i } if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ) { - size_t i; - for (i = 0; i < oamMax; ++i) { - GBVideoSoftwareRendererDrawObj(softwareRenderer, &obj[i], startX, endX, y); + if (startX == 0) { + _cleanOAM(softwareRenderer, y); + } + int i; + for (i = 0; i < softwareRenderer->objMax; ++i) { + GBVideoSoftwareRendererDrawObj(softwareRenderer, &softwareRenderer->obj[i], startX, endX, y); } } diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 002b5a650..35a54c752 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -256,7 +256,6 @@ void GBSGBSerialize(struct GB* gb, struct GBSerializedState* state) { if (gb->video.renderer->sgbAttributes) { memcpy(state->sgb.attributes, gb->video.renderer->sgbAttributes, sizeof(state->sgb.attributes)); } - gb->video.renderer->enableSGBBorder(gb->video.renderer, gb->video.sgbBorders); } void GBSGBDeserialize(struct GB* gb, const struct GBSerializedState* state) { diff --git a/src/gb/video.c b/src/gb/video.c index 6c207297d..8bf173797 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -403,26 +403,18 @@ void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLat } static void _cleanOAM(struct GBVideo* video, int y) { - // TODO: GBC differences - // TODO: Optimize - video->objMax = 0; int spriteHeight = 8; if (GBRegisterLCDCIsObjSize(video->p->memory.io[REG_LCDC])) { spriteHeight = 16; } int o = 0; int i; - for (i = 0; i < 40; ++i) { + for (i = 0; i < 40 && o < 10; ++i) { uint8_t oy = video->oam.obj[i].y; if (y < oy - 16 || y >= oy - 16 + spriteHeight) { continue; } - // TODO: Sort - video->objThisLine[o] = video->oam.obj[i]; ++o; - if (o == 10) { - break; - } } video->objMax = o; } @@ -442,7 +434,7 @@ void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate) { oldX = 0; } if (video->frameskipCounter <= 0) { - video->renderer->drawRange(video->renderer, oldX, video->x, video->ly, video->objThisLine, video->objMax); + video->renderer->drawRange(video->renderer, oldX, video->x, video->ly); } } diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 5d22a6442..101510461 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -391,7 +391,11 @@ static const char* const _renderMode4 = " }\n" " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" " int twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0).r;\n" - " int paletteEntry = palette[(twoEntries >> (8 * (address & 1)) & 255)];\n" + " int entry = (twoEntries >> (8 * (address & 1))) & 255;\n" + " if (entry == 0) {\n" + " discard;\n" + " }\n" + " int paletteEntry = palette[entry];\n" " color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" "}"; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 083b3d230..8c990d15f 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -654,18 +654,19 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render } } if (softwareRenderer->forceTarget1 && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) { - uint32_t mask = FLAG_REBLEND | FLAG_IS_BACKGROUND; - uint32_t match = FLAG_REBLEND; - if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { - mask |= FLAG_OBJWIN; - if (GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed)) { - match |= FLAG_OBJWIN; - } - } int x = 0; for (w = 0; w < softwareRenderer->nWindows; ++w) { int end = softwareRenderer->windows[w].endX; - if (!GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { + uint32_t mask = FLAG_REBLEND | FLAG_IS_BACKGROUND; + uint32_t match = FLAG_REBLEND; + bool objBlend = GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed); + bool winBlend = GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed); + if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt) && objBlend != winBlend) { + mask |= FLAG_OBJWIN; + if (objBlend) { + match |= FLAG_OBJWIN; + } + } else if (!winBlend) { x = end; continue; } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 4d761d0c2..ae587d246 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -267,11 +267,23 @@ void CoreController::loadConfig(ConfigController* config) { m_fastForwardMute = config->getOption("fastForwardMute", -1).toInt(); mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "volume"); mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "mute"); + + QSize sizeBefore = screenDimensions(); mCoreLoadForeignConfig(m_threadContext.core, config->config()); + QSize sizeAfter = screenDimensions(); if (hasStarted()) { updateFastForward(); mCoreThreadRewindParamsChanged(&m_threadContext); } + if (sizeBefore != sizeAfter) { + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); +#ifdef M_CORE_GB + mCoreConfigSetIntValue(&m_threadContext.core->config, "sgb.borders", 0); + m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); + mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "sgb.borders"); + m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); +#endif + } } #ifdef USE_DEBUGGERS diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 50cdc83b4..bd62f6f63 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -148,7 +148,9 @@ void DisplayGL::pauseDrawing() { m_isDrawing = false; CoreController::Interrupter interrupter(m_context); QMetaObject::invokeMethod(m_painter, "pause", Qt::BlockingQueuedConnection); +#ifndef Q_OS_MAC setUpdatesEnabled(true); +#endif } } @@ -157,7 +159,9 @@ void DisplayGL::unpauseDrawing() { m_isDrawing = true; CoreController::Interrupter interrupter(m_context); QMetaObject::invokeMethod(m_painter, "unpause", Qt::BlockingQueuedConnection); +#ifndef Q_OS_MAC setUpdatesEnabled(false); +#endif } } diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 856592a30..67b09e05e 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -246,7 +246,7 @@ QByteArray MemoryModel::serialize() { for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) { quint16 datum = m_core->rawRead16(m_core, i, m_currentBank); char leDatum[2]; - STORE_16LE(datum, 0, (uint16_t*) leDatum); + STORE_16BE(datum, 0, (uint16_t*) leDatum); bytes.append(leDatum, 2); } break; @@ -254,7 +254,7 @@ QByteArray MemoryModel::serialize() { for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) { quint32 datum = m_core->rawRead32(m_core, i, m_currentBank); char leDatum[4]; - STORE_32LE(datum, 0, (uint16_t*) leDatum); + STORE_32BE(datum, 0, (uint32_t*) leDatum); bytes.append(leDatum, 4); } break; @@ -275,7 +275,7 @@ void MemoryModel::deserialize(const QByteArray& bytes) { for (int i = 0; i < bytes.size(); i += m_align, addr += m_align) { char leDatum[2]{ bytes[i], bytes[i + 1] }; uint16_t datum; - LOAD_16LE(datum, 0, leDatum); + LOAD_16BE(datum, 0, leDatum); m_core->rawWrite16(m_core, addr, m_currentBank, datum); } break; @@ -283,7 +283,7 @@ void MemoryModel::deserialize(const QByteArray& bytes) { for (int i = 0; i < bytes.size(); i += m_align, addr += m_align) { char leDatum[4]{ bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3] }; uint32_t datum; - LOAD_32LE(datum, 0, leDatum); + LOAD_32BE(datum, 0, leDatum); m_core->rawWrite32(m_core, addr, m_currentBank, datum); } break; diff --git a/src/platform/windows/setup/setup.iss.in b/src/platform/windows/setup/setup.iss.in index fb164136a..9421d8fa9 100644 --- a/src/platform/windows/setup/setup.iss.in +++ b/src/platform/windows/setup/setup.iss.in @@ -64,11 +64,17 @@ ArchitecturesInstallIn64BitMode=x64 ArchitecturesAllowed=x86 x64 [Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" -Name: "french"; MessagesFile: "compiler:Languages\French.isl" Name: "german"; MessagesFile: "compiler:Languages\German.isl" -Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "english"; MessagesFile: "compiler:Default.isl" Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" +Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" +Name: "korean"; MessagesFile: "compiler:Languages\Korean.isl" +Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" +Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" +Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" @@ -83,13 +89,13 @@ Source: "{#BinDir}\{#AppName2}-sdl.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#BinDir}\CHANGES.txt"; DestDir: "{app}\"; Flags: ignoreversion isreadme Source: "{#BinDir}\LICENSE.txt"; DestDir: "{app}\"; Flags: ignoreversion Source: "{#ResDir}\nointro.dat"; DestDir: "{app}\"; Flags: ignoreversion -Source: "{#BinDir}\README.html"; DestDir: "{app}\"; Flags: ignoreversion isreadme; Languages: english italian spanish +Source: "{#BinDir}\README.html"; DestDir: "{app}\"; Flags: ignoreversion isreadme; Languages: not german Source: "{#BinDir}\README_DE.html"; DestDir: "{app}\"; DestName: "LIESMICH.html"; Flags: ignoreversion isreadme; Languages: german Source: "{#ResDir}\shaders\*"; DestDir: "{app}\shaders\"; Flags: ignoreversion recursesubdirs Source: "{#ResDir}\licenses\*"; DestDir: "{app}\licenses\"; Flags: ignoreversion recursesubdirs [Icons] -Name: "{commonstartmenu}\{#AppName}"; Filename: "{app}\{#AppName}.exe" +Name: "{commonstartmenu}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; Check: not WizardNoIcons Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; Tasks: desktopicon [Run] @@ -129,9 +135,15 @@ procedure InitializeWizard(); begin if ExpandConstant('{language}') = 'english' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; if ExpandConstant('{language}') = 'french' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; - if ExpandConstant('{language}') = 'italian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'german' then noReleaseWarning := 'Sie möchten eine Entwicklerversion von {#AppName} installieren.' + #13#10#13#10 + 'Entwicklerversionen können bislang noch nicht endeckte Fehler beinhalten. Bitte melden Sie alle Fehler, die Sie finden können, auf der GitHub-Projektseite.'; if ExpandConstant('{language}') = 'spanish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; if ExpandConstant('{language}') = 'spanish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; - if ExpandConstant('{language}') = 'german' then noReleaseWarning := 'Sie möchten eine Entwicklerversion von {#AppName} installieren.' + #13#10#13#10 + 'Entwicklerversionen können bislang noch nicht endeckte Fehler beinhalten. Bitte melden Sie alle Fehler, die Sie finden können, auf der GitHub-Projektseite.'; + if ExpandConstant('{language}') = 'italian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'japanese' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'korean' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'dutch' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'russian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'turkish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'chinesesimplified' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; MsgBox(noReleaseWarning, mbInformation, MB_OK); end; end;