From 309693b9ffcf51d277f724df48a2718daa52e464 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sat, 25 Jan 2020 13:58:54 +0000 Subject: [PATCH] OpenDingux: GKD350h support Start and Select are swapped in this version because Start + D-Pad controls backlight on the GKD350h. There is nothing to map mouse emulation to in this version because of this but it isn't necessary to play the game. This version looks uglier than on RG350 because it uses software scaling beacuse the IPU on the GKD350h doesn't work. --- .gitignore | 5 +- CMake/gkd350h_defs.cmake | 49 +++++++++++++++++++ CMakeLists.txt | 10 ++-- Packaging/OpenDingux/build-retrofw.sh | 4 -- Packaging/OpenDingux/build-rg350.sh | 4 -- Packaging/OpenDingux/build.sh | 29 ++++++++--- Packaging/OpenDingux/gkd350h.desktop | 11 +++++ Packaging/OpenDingux/package-ipk.sh | 6 +-- Packaging/OpenDingux/package-opk.sh | 21 ++------ ...efconfig => retrofw_devilutionx_defconfig} | 0 Packaging/OpenDingux/rg350.desktop | 12 +++++ ..._defconfig => rg350_devilutionx_defconfig} | 0 README.md | 18 +++---- SourceX/miniwin/misc.cpp | 30 ++++++++++-- 14 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 CMake/gkd350h_defs.cmake delete mode 100755 Packaging/OpenDingux/build-retrofw.sh delete mode 100755 Packaging/OpenDingux/build-rg350.sh create mode 100644 Packaging/OpenDingux/gkd350h.desktop rename Packaging/OpenDingux/{buildroot_retrofw_defconfig => retrofw_devilutionx_defconfig} (100%) create mode 100644 Packaging/OpenDingux/rg350.desktop rename Packaging/OpenDingux/{buildroot_rg350_defconfig => rg350_devilutionx_defconfig} (100%) 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();