diff --git a/.gitignore b/.gitignore index 126611c7d..a0fb0136b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,7 @@ devilution-comparer comparer-config.toml #ignore cmake cache -/build/ -/build-retrofw/ -/build-rg350/ -/build32/ +/build-*/ .vscode/tasks.json # ELF object file. diff --git a/CMake/gkd350h_defs.cmake b/CMake/gkd350h_defs.cmake new file mode 100644 index 000000000..b1780ad28 --- /dev/null +++ b/CMake/gkd350h_defs.cmake @@ -0,0 +1,49 @@ +set(NONET ON) +set(USE_SDL1 ON) + +# GKD350h IPU scaler is broken at the moment +set(SDL1_VIDEO_MODE_WIDTH 320) +set(SDL1_VIDEO_MODE_HEIGHT 240) + +set(SDL1_VIDEO_MODE_BPP 16) +set(PREFILL_PLAYER_NAME ON) + +# In joystick mode, GKD350h reports D-Pad as left stick, +# so we have to use keyboard mode instead. + +set(HAS_KBCTRL 1) +set(KBCTRL_BUTTON_DPAD_LEFT SDLK_LEFT) +set(KBCTRL_BUTTON_DPAD_RIGHT SDLK_RIGHT) +set(KBCTRL_BUTTON_DPAD_UP SDLK_UP) +set(KBCTRL_BUTTON_DPAD_DOWN SDLK_DOWN) +set(KBCTRL_BUTTON_B SDLK_LCTRL) +set(KBCTRL_BUTTON_A SDLK_LALT) +set(KBCTRL_BUTTON_Y SDLK_SPACE) +set(KBCTRL_BUTTON_X SDLK_LSHIFT) +set(KBCTRL_BUTTON_RIGHTSHOULDER SDLK_BACKSPACE) +set(KBCTRL_BUTTON_LEFTSHOULDER SDLK_TAB) + +# We swap Select and Start because Start + D-Pad is overtaken by the kernel. +set(KBCTRL_BUTTON_START SDLK_ESCAPE) # Select +set(KBCTRL_BUTTON_BACK SDLK_RETURN) # Start + +set(JOY_AXIS_LEFTX 0) +set(JOY_AXIS_LEFTY 1) + +# Unused joystick mappings (kept here for future reference). +set(JOY_HAT_DPAD_UP_HAT 0) +set(JOY_HAT_DPAD_UP 1) +set(JOY_HAT_DPAD_DOWN_HAT 0) +set(JOY_HAT_DPAD_DOWN 4) +set(JOY_HAT_DPAD_LEFT_HAT 0) +set(JOY_HAT_DPAD_LEFT 8) +set(JOY_HAT_DPAD_RIGHT_HAT 0) +set(JOY_HAT_DPAD_RIGHT 2) +set(JOY_BUTTON_A 0) +set(JOY_BUTTON_B 1) +set(JOY_BUTTON_Y 2) +set(JOY_BUTTON_X 3) +set(JOY_BUTTON_RIGHTSHOULDER 7) +set(JOY_BUTTON_LEFTSHOULDER 6) +set(JOY_BUTTON_START 5) +set(JOY_BUTTON_BACK 4) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06d0f72bb..72cb1600c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,10 @@ if(RG350) include(rg350_defs) endif() +if (GKD350H) + include(gkd350h_defs) +endif() + if(RETROFW) include(retrofw_defs) endif() @@ -346,6 +350,8 @@ endforeach(def_name) # Defines with value foreach( def_name + SDL1_VIDEO_MODE_WIDTH + SDL1_VIDEO_MODE_HEIGHT SDL1_VIDEO_MODE_BPP SDL1_VIDEO_MODE_FLAGS HAS_KBCTRL @@ -522,7 +528,3 @@ if(SWITCH) include(nx-utils) build_switch_binaries(${BIN_TARGET}) endif() - -if(RETROFW OR RG350) - set_target_properties(${BIN_TARGET} PROPERTIES OUTPUT_NAME "devilutionx.dge") -endif() diff --git a/Packaging/OpenDingux/build-retrofw.sh b/Packaging/OpenDingux/build-retrofw.sh deleted file mode 100755 index 7036e8a47..000000000 --- a/Packaging/OpenDingux/build-retrofw.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -declare -r DIR="$(dirname "${BASH_SOURCE[0]}")" -"${DIR}/build.sh" retrofw diff --git a/Packaging/OpenDingux/build-rg350.sh b/Packaging/OpenDingux/build-rg350.sh deleted file mode 100755 index fa6c99751..000000000 --- a/Packaging/OpenDingux/build-rg350.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -declare -r DIR="$(dirname "${BASH_SOURCE[0]}")" -"${DIR}/build.sh" rg350 diff --git a/Packaging/OpenDingux/build.sh b/Packaging/OpenDingux/build.sh index 363f87fcb..7b055f231 100755 --- a/Packaging/OpenDingux/build.sh +++ b/Packaging/OpenDingux/build.sh @@ -4,7 +4,7 @@ set -euo pipefail usage() { echo "Usage: build.sh [target]" - echo " target: target architecture. Either rg350 or retrofw" + echo " target: target architecture: rg350, gkd350h, or retrofw" } if [[ $# -ne 1 ]]; then @@ -13,7 +13,7 @@ if [[ $# -ne 1 ]]; then exit 1 fi -if [[ "$1" != "rg350" ]] && [[ "$1" != "retrofw" ]]; then +if [[ $1 != rg350 ]] && [[ $1 != retrofw ]] && [[ $1 != gkd350h ]]; then echo "Error: invalid target" usage exit 1 @@ -28,7 +28,22 @@ declare -rA BUILDROOT_REPOS=( [retrofw]=https://github.com/retrofw/buildroot.git [rg350]=https://github.com/tonyjih/RG350_buildroot.git ) -BUILDROOT="${BUILDROOT:-$HOME/buildroot-${TARGET}-devilutionx}" + +declare BUILDROOT_DEFCONFIG +declare BUILDROOT_REPO + +set_buildroot_vars() { + BUILDROOT_DEFCONFIG="$1_devilutionx_defconfig" + BUILDROOT_REPO="${BUILDROOT_REPOS[$1]}" + BUILDROOT="${BUILDROOT:-$HOME/buildroot-$1-devilutionx}" +} + +# Use the rg350 buildroot for gkd350h because gkd350h buildroot is not open-source. +if [[ $TARGET == gkd350h ]]; then + set_buildroot_vars rg350 +else + set_buildroot_vars "$TARGET" +fi main() { >&2 echo "Building for target ${TARGET} in ${BUILD_DIR}" @@ -47,10 +62,9 @@ prepare_buildroot() { } make_buildroot() { - cp Packaging/OpenDingux/buildroot_${TARGET}_defconfig \ - "$BUILDROOT/configs/${TARGET}_devilutionx_defconfig" + cp "Packaging/OpenDingux/$BUILDROOT_DEFCONFIG" "$BUILDROOT/configs/" cd "$BUILDROOT" - make "${TARGET}_devilutionx_defconfig" + make "$BUILDROOT_DEFCONFIG" BR2_JLEVEL=0 make toolchain libzip sdl sdl_mixer sdl_ttf cd - } @@ -69,7 +83,8 @@ package() { if [[ "$TARGET" == "retrofw" ]]; then Packaging/OpenDingux/package-ipk.sh "${PWD}/${BUILD_DIR}/devilutionx-${TARGET}.ipk" else - Packaging/OpenDingux/package-opk.sh "${PWD}/${BUILD_DIR}/devilutionx-${TARGET}.opk" + Packaging/OpenDingux/package-opk.sh "${PWD}/${BUILD_DIR}/devilutionx-${TARGET}.opk" \ + "${PWD}/Packaging/OpenDingux/${TARGET}.desktop" fi } diff --git a/Packaging/OpenDingux/gkd350h.desktop b/Packaging/OpenDingux/gkd350h.desktop new file mode 100644 index 000000000..1fa04dff6 --- /dev/null +++ b/Packaging/OpenDingux/gkd350h.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=DevilutionX +Comment=A port of DevilutionX for GKD350h. +Exec=devilutionx +Terminal=false +Type=Application +StartupNotify=true +Icon=Diablo_32 +Categories=games; +X-OD-Manual=readme.gcw0.txt +X-OD-NeedsDownscaling=true diff --git a/Packaging/OpenDingux/package-ipk.sh b/Packaging/OpenDingux/package-ipk.sh index a21b27179..66a79fff4 100755 --- a/Packaging/OpenDingux/package-ipk.sh +++ b/Packaging/OpenDingux/package-ipk.sh @@ -10,7 +10,7 @@ if [[ -z "$1" ]]; then fi readonly OUT="$1" -readonly IN="${2:-$(dirname "$OUT")/devilutionx.dge}" +readonly IN="${2:-$(dirname "$OUT")/devilutionx}" readonly PKG_TARGET=devilutionx readonly TMP="tmp/${PKG_TARGET}" @@ -32,7 +32,7 @@ mkdir -p "${TMP}" # data.tar.gz mkdir -p "${TMP}/root/${PKG_INSTALL_DIR}" "${TMP}/root/${PKG_LOCAL_DIR}" -cp "$IN" "${TMP}/root/${PKG_INSTALL_DIR}/${PKG_TARGET}.dge" +cp "$IN" "${TMP}/root/${PKG_INSTALL_DIR}/${PKG_TARGET}" cp ../resources/Diablo_32.png "${TMP}/root/${PKG_INSTALL_DIR}/devilutionx.png" cp ../resources/CharisSILB.ttf ../resources/LICENSE.CharisSILB.txt "${TMP}/root/${PKG_INSTALL_DIR}" cp devilutionx-retrofw.man.txt "${TMP}/root/${PKG_INSTALL_DIR}/devilutionx.man.txt" @@ -41,7 +41,7 @@ mkdir -p "${TMP}/root/$(dirname "$PKG_MENU_LNK_OUT")" printf "%s\n" \ "title=DevilutionX" \ "description=$(pkg_control_get Description)" \ - "exec=/${PKG_INSTALL_DIR}/${PKG_TARGET}.dge" \ + "exec=/${PKG_INSTALL_DIR}/${PKG_TARGET}" \ > "${TMP}/root/${PKG_MENU_LNK_OUT}" tar --owner=0 --group=0 -czvf "${TMP}/data.tar.gz" -C "${TMP}/root/" . diff --git a/Packaging/OpenDingux/package-opk.sh b/Packaging/OpenDingux/package-opk.sh index a2681e50b..e0c609d6e 100755 --- a/Packaging/OpenDingux/package-opk.sh +++ b/Packaging/OpenDingux/package-opk.sh @@ -8,34 +8,23 @@ if [[ -z "$1" ]]; then fi readonly OUT="$1" -readonly IN="${2:-$(dirname "$OUT")/devilutionx.dge}" +readonly DESKTOP_FILE="$2" + +readonly IN="$(dirname "$OUT")/devilutionx" readonly TMP="tmp/opk" echo 1>&2 Packaging ${OUT}... # To run with SDL2 controller mappings for RG350: -# Exec=env SDL_GAMECONTROLLERCONFIG=190000006c696e6b6465762064657600,RG350,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, ./devilutionx.dge +# Exec=env SDL_GAMECONTROLLERCONFIG=190000006c696e6b6465762064657600,RG350,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, ./devilutionx # # We use SDL1 instead as it's ~3x faster, likely because with SDL1 scaling is done in hardware. set -x rm -rf "${TMP}" mkdir -p "${TMP}" -cat > "${TMP}/default.gcw0.desktop" < ~~~ -### OpenDingux (RG350, GCW0) - -This OpenDingux build uses the buildroot at `$HOME/buildroot-rg350-devilutionx`. +Replace `` with one of: `retrofw`, `rg350`, or `gkd350h`. -~~~ bash -Packaging/OpenDingux/build-rg350.sh -~~~ +This prepares and uses the buildroot at `$HOME/buildroot-$PLATFORM-devilutionx`. diff --git a/SourceX/miniwin/misc.cpp b/SourceX/miniwin/misc.cpp index 1bc891f87..31fd82723 100644 --- a/SourceX/miniwin/misc.cpp +++ b/SourceX/miniwin/misc.cpp @@ -19,6 +19,12 @@ #ifndef SDL1_VIDEO_MODE_FLAGS #define SDL1_VIDEO_MODE_FLAGS SDL_SWSURFACE #endif +#ifndef SDL1_VIDEO_MODE_WIDTH +#define SDL1_VIDEO_MODE_WIDTH nWidth +#endif +#ifndef SDL1_VIDEO_MODE_HEIGHT +#define SDL1_VIDEO_MODE_HEIGHT nHeight +#endif #endif namespace dvl { @@ -73,6 +79,24 @@ WINBOOL DeleteFileA(LPCSTR lpFileName) return true; } +namespace { + +#ifdef USE_SDL1 +void InitVideoMode(int width, int height, int bpp, std::uint32_t flags) +{ + const auto &best = *SDL_GetVideoInfo(); + SDL_Log("Best video mode reported as: %dx%d bpp=%d hw_available=%u", + best.current_w, best.current_h, best.vfmt->BitsPerPixel, best.hw_available); + SDL_Log("Setting video mode %dx%d bpp=%u flags=0x%08X", width, height, bpp, flags); + SDL_SetVideoMode(width, height, bpp, flags); + const auto ¤t = *SDL_GetVideoInfo(); + SDL_Log("Video mode is now %dx%d bpp=%u", + current.current_w, current.current_h, current.vfmt->BitsPerPixel); +} +#endif + +} // namespace + bool SpawnWindow(LPCSTR lpWindowName, int nWidth, int nHeight) { if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) <= -1) { @@ -102,14 +126,14 @@ bool SpawnWindow(LPCSTR lpWindowName, int nWidth, int nHeight) flags |= SDL_FULLSCREEN; SDL_WM_SetCaption(lpWindowName, WINDOW_ICON_NAME); #ifndef RETROFW - SDL_SetVideoMode(nWidth, nHeight, SDL1_VIDEO_MODE_BPP, flags); + InitVideoMode(SDL1_VIDEO_MODE_WIDTH, SDL1_VIDEO_MODE_HEIGHT, SDL1_VIDEO_MODE_BPP, flags); #else // RETROFW // JZ4760 IPU scaler (e.g. on RG-300 v2/3) - automatic high-quality scaling. if (access("/proc/jz/ipu", F_OK) == 0 || access("/proc/jz/ipu_ratio", F_OK) == 0) { - SDL_SetVideoMode(nWidth, nHeight, SDL1_VIDEO_MODE_BPP, flags); + InitVideoMode(SDL1_VIDEO_MODE_WIDTH, SDL1_VIDEO_MODE_HEIGHT, SDL1_VIDEO_MODE_BPP, flags); } else { // Other RetroFW devices have 320x480 screens with non-square pixels. - SDL_SetVideoMode(320, 480, SDL1_VIDEO_MODE_BPP, flags); + InitVideoMode(320, 480, SDL1_VIDEO_MODE_BPP, flags); } #endif window = SDL_GetVideoSurface();