Enable SDL1 build option for Windows

This commit is contained in:
staphen 2021-11-04 21:39:04 -04:00 committed by Anders Jenbo
commit b5d96665c9
6 changed files with 249 additions and 35 deletions

View file

@ -63,6 +63,11 @@ if(NIGHTLY_BUILD OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(CPACK ON)
endif()
if(USE_SDL1)
list(APPEND VCPKG_MANIFEST_FEATURES "sdl1")
else()
list(APPEND VCPKG_MANIFEST_FEATURES "sdl2")
endif()
if(PACKET_ENCRYPTION)
list(APPEND VCPKG_MANIFEST_FEATURES "encryption")
endif()

View file

@ -379,7 +379,7 @@ void PrintSBookHotkey(const Surface &out, Point position, const std::string &tex
*/
void DrawFlaskTop(const Surface &out, Point position, const Surface &celBuf, int y0, int y1)
{
out.BlitFrom(celBuf, SDL_Rect { 0, static_cast<decltype(SDL_Rect {}.y)>(y0), celBuf.w(), y1 - y0 }, position);
out.BlitFrom(celBuf, MakeSdlRect(0, static_cast<decltype(SDL_Rect {}.y)>(y0), celBuf.w(), y1 - y0), position);
}
/**
@ -436,7 +436,7 @@ void DrawFlaskLower(const Surface &out, const Surface &sourceBuffer, int offset,
// It appears that the panel defaults to having a filled flask and DrawFlaskTop only overlays the appropriate amount of empty space.
// This draw might not be necessary?
if (filled > 0)
DrawPanelBox(out, { offset, 85 - filled, 88, filled }, { PANEL_X + offset, PANEL_Y + 69 - filled });
DrawPanelBox(out, MakeSdlRect(offset, 85 - filled, 88, filled), { PANEL_X + offset, PANEL_Y + 69 - filled });
}
void SetButtonStateDown(int btnId)
@ -1037,7 +1037,7 @@ void InitControlPan()
void DrawCtrlPan(const Surface &out)
{
DrawPanelBox(out, { 0, sgbPlrTalkTbl + 16, PANEL_WIDTH, PANEL_HEIGHT }, { PANEL_X, PANEL_Y });
DrawPanelBox(out, MakeSdlRect(0, sgbPlrTalkTbl + 16, PANEL_WIDTH, PANEL_HEIGHT), { PANEL_X, PANEL_Y });
DrawInfoBox(out);
}
@ -1045,7 +1045,7 @@ void DrawCtrlBtns(const Surface &out)
{
for (int i = 0; i < 6; i++) {
if (!PanelButtons[i]) {
DrawPanelBox(out, { PanBtnPos[i].x, PanBtnPos[i].y + 16, 71, 20 }, { PanBtnPos[i].x + PANEL_X, PanBtnPos[i].y + PANEL_Y });
DrawPanelBox(out, MakeSdlRect(PanBtnPos[i].x, PanBtnPos[i].y + 16, 71, 20), { PanBtnPos[i].x + PANEL_X, PanBtnPos[i].y + PANEL_Y });
} else {
Point position { PanBtnPos[i].x + PANEL_X, PanBtnPos[i].y + PANEL_Y + 18 };
CelDrawTo(out, position, *pPanelButtons, i + 1);
@ -1696,17 +1696,17 @@ void DrawTalkPan(const Surface &out)
force_redraw = 255;
DrawPanelBox(out, { 175, sgbPlrTalkTbl + 20, 294, 5 }, { PANEL_X + 175, PANEL_Y + 4 });
DrawPanelBox(out, MakeSdlRect(175, sgbPlrTalkTbl + 20, 294, 5), { PANEL_X + 175, PANEL_Y + 4 });
int off = 0;
for (int i = 293; i > 283; off++, i--) {
DrawPanelBox(out, { (off / 2) + 175, sgbPlrTalkTbl + off + 25, i, 1 }, { (off / 2) + PANEL_X + 175, off + PANEL_Y + 9 });
DrawPanelBox(out, MakeSdlRect((off / 2) + 175, sgbPlrTalkTbl + off + 25, i, 1), { (off / 2) + PANEL_X + 175, off + PANEL_Y + 9 });
}
DrawPanelBox(out, { 185, sgbPlrTalkTbl + 35, 274, 30 }, { PANEL_X + 185, PANEL_Y + 19 });
DrawPanelBox(out, { 180, sgbPlrTalkTbl + 65, 284, 5 }, { PANEL_X + 180, PANEL_Y + 49 });
DrawPanelBox(out, MakeSdlRect(185, sgbPlrTalkTbl + 35, 274, 30), { PANEL_X + 185, PANEL_Y + 19 });
DrawPanelBox(out, MakeSdlRect(180, sgbPlrTalkTbl + 65, 284, 5), { PANEL_X + 180, PANEL_Y + 49 });
for (int i = 0; i < 10; i++) {
DrawPanelBox(out, { 180, sgbPlrTalkTbl + i + 70, i + 284, 1 }, { PANEL_X + 180, i + PANEL_Y + 54 });
DrawPanelBox(out, MakeSdlRect(180, sgbPlrTalkTbl + i + 70, i + 284, 1), { PANEL_X + 180, i + PANEL_Y + 54 });
}
DrawPanelBox(out, { 170, sgbPlrTalkTbl + 80, 310, 55 }, { PANEL_X + 170, PANEL_Y + 64 });
DrawPanelBox(out, MakeSdlRect(170, sgbPlrTalkTbl + 80, 310, 55), { PANEL_X + 170, PANEL_Y + 64 });
int x = PANEL_LEFT + 200;
int y = PANEL_Y + 10;

View file

@ -132,7 +132,7 @@ bool SpawnWindow(const char *lpWindowName)
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(USE_SDL1)
// The default WASAPI backend causes distortions
// https://github.com/diasurgical/devilutionX/issues/1434
SDL_setenv("SDL_AUDIODRIVER", "winmm", /*overwrite=*/false);

View file

@ -5,6 +5,14 @@
#include "./console.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#define UNICODE 1
#include <shlobj.h>
#include <windows.h>
#endif
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
@ -477,6 +485,216 @@ int SDL_BlitScaled(SDL_Surface *src, SDL_Rect *srcrect,
// = Filesystem
Sint64 SDL_RWsize(SDL_RWops *context)
{
const int current = SDL_RWtell(context);
if (current == -1)
return -1;
const int begin = SDL_RWseek(context, 0, RW_SEEK_SET);
if (begin == -1)
return -1;
const int end = SDL_RWseek(context, 0, RW_SEEK_END);
if (end == -1)
return -1;
if (SDL_RWseek(context, current, RW_SEEK_SET) == -1)
return -1;
return end - begin;
}
#ifdef _WIN32
namespace {
// From sdl2-2.0.9/src/core/windows/SDL_windows.h
#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (wcslen(S) + 1) * sizeof(WCHAR))
#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S) + 1)
/* Sets an error message based on an HRESULT */
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
{
// From sdl2-2.0.9/src/core/windows/SDL_windows.c
TCHAR buffer[1024];
char *message;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0,
buffer, SDL_arraysize(buffer), NULL);
message = WIN_StringToUTF8(buffer);
SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
SDL_free(message);
return -1;
}
/* Sets an error message based on GetLastError() */
int WIN_SetError(const char *prefix)
{
// From sdl2-2.0.9/src/core/windows/SDL_windows.c
return WIN_SetErrorFromHRESULT(prefix, GetLastError());
}
} // namespace
char *SDL_GetBasePath(void)
{
// From sdl2-2.0.9/src/filesystem/windows/SDL_sysfilesystem.c
typedef DWORD(WINAPI * GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD);
GetModuleFileNameExW_t pGetModuleFileNameExW;
DWORD buflen = 128;
WCHAR *path = NULL;
HMODULE psapi = LoadLibrary(L"psapi.dll");
char *retval = NULL;
DWORD len = 0;
int i;
if (!psapi) {
WIN_SetError("Couldn't load psapi.dll");
return NULL;
}
pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW");
if (!pGetModuleFileNameExW) {
WIN_SetError("Couldn't find GetModuleFileNameExW");
FreeLibrary(psapi);
return NULL;
}
while (SDL_TRUE) {
void *ptr = SDL_realloc(path, buflen * sizeof(WCHAR));
if (!ptr) {
SDL_free(path);
FreeLibrary(psapi);
SDL_OutOfMemory();
return NULL;
}
path = (WCHAR *)ptr;
len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen);
if (len != buflen) {
break;
}
/* buffer too small? Try again. */
buflen *= 2;
}
FreeLibrary(psapi);
if (len == 0) {
SDL_free(path);
WIN_SetError("Couldn't locate our .exe");
return NULL;
}
for (i = len - 1; i > 0; i--) {
if (path[i] == '\\') {
break;
}
}
path[i + 1] = '\0'; /* chop off filename. */
retval = WIN_StringToUTF8(path);
SDL_free(path);
return retval;
}
char *SDL_GetPrefPath(const char *org, const char *app)
{
// From sdl2-2.0.9/src/filesystem/windows/SDL_sysfilesystem.c
/*
* Vista and later has a new API for this, but SHGetFolderPath works there,
* and apparently just wraps the new API. This is the new way to do it:
*
* SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE,
* NULL, &wszPath);
*/
WCHAR path[MAX_PATH];
char *retval = NULL;
WCHAR *worg = NULL;
WCHAR *wapp = NULL;
size_t new_wpath_len = 0;
BOOL api_result = FALSE;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) {
WIN_SetError("Couldn't locate our prefpath");
return NULL;
}
worg = WIN_UTF8ToString(org);
if (worg == NULL) {
SDL_OutOfMemory();
return NULL;
}
wapp = WIN_UTF8ToString(app);
if (wapp == NULL) {
SDL_free(worg);
SDL_OutOfMemory();
return NULL;
}
new_wpath_len = lstrlenW(worg) + lstrlenW(wapp) + lstrlenW(path) + 3;
if ((new_wpath_len + 1) > MAX_PATH) {
SDL_free(worg);
SDL_free(wapp);
WIN_SetError("Path too long.");
return NULL;
}
if (*worg) {
lstrcatW(path, L"\\");
lstrcatW(path, worg);
}
SDL_free(worg);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
SDL_free(wapp);
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
lstrcatW(path, L"\\");
lstrcatW(path, wapp);
SDL_free(wapp);
api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
WIN_SetError("Couldn't create a prefpath.");
return NULL;
}
}
lstrcatW(path, L"\\");
retval = WIN_StringToUTF8(path);
return retval;
}
#else
namespace {
#if !defined(__QNXNTO__)
char *readSymLink(const char *path)
@ -512,26 +730,6 @@ char *readSymLink(const char *path)
#endif
} // namespace
Sint64 SDL_RWsize(SDL_RWops *context)
{
const int current = SDL_RWtell(context);
if (current == -1)
return -1;
const int begin = SDL_RWseek(context, 0, RW_SEEK_SET);
if (begin == -1)
return -1;
const int end = SDL_RWseek(context, 0, RW_SEEK_END);
if (end == -1)
return -1;
if (SDL_RWseek(context, current, RW_SEEK_SET) == -1)
return -1;
return end - begin;
}
char *SDL_GetBasePath()
{
// From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c
@ -719,3 +917,5 @@ char *SDL_GetPrefPath(const char *org, const char *app)
return retval;
}
#endif

View file

@ -1,7 +1,6 @@
#pragma once
#include <SDL.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <sys/stat.h>
@ -12,6 +11,10 @@
#include "utils/attributes.h"
#include "utils/console.h"
#ifndef _WIN32
#include <unistd.h>
#endif
#define WINDOW_ICON_NAME 0
//== Utility

View file

@ -2,11 +2,17 @@
"name": "devilutionx",
"version-string": "1.2.1",
"dependencies": [
"fmt",
"sdl2",
"sdl2-image"
"fmt"
],
"features": {
"sdl1": {
"description": "Use SDL1.2 instead of SDL2",
"dependencies": [ "sdl1", "libpng" ]
},
"sdl2": {
"description": "Use SDL2",
"dependencies": [ "sdl2", "sdl2-image" ]
},
"encryption": {
"description": "Build libsodium for packet encryption",
"dependencies": [ "libsodium" ]