#!/bin/bash
# Fix Necronomicon: The Dawning of Darkness (Steam 302390) for CrossOver on macOS.
#   1. patches 4xm_sdk.dll so cutscenes play instead of a black screen with stuttering sound
#   2. installs dxwrapper (Dd7to9) so the 640x480 game fills the screen instead of one corner
#   3. tells Wine to load that ddraw.dll for Necrono.exe
# Safe to run repeatedly.
set -u

BOTTLE="Steam"
GAME_DIR="${1:-$HOME/Library/Application Support/CrossOver/Bottles/$BOTTLE/drive_c/Program Files (x86)/Steam/steamapps/common/Necronomicon The Dawning of Darkness}"
SDK="$GAME_DIR/4xm_sdk.dll"
INI="$GAME_DIR/dxwrapper.ini"
DXW_URL="https://github.com/elishacloud/dxwrapper/releases/latest/download/dxwrapper.zip"

# 4xm_sdk.dll as shipped by Steam (49152 bytes) and after the patch
ORIG_MD5="65cf88713a935d94749759a142ba6e15"
PATCHED_MD5="c268e75d01a96a92acaaa4ceacdfb9b0"

# critical: the four edits, as file offset + bytes. Together they move the decoder's
# runtime-generated code onto its own memory pages, away from the variables it writes.
HDR_OFF=$((0x1f0));  HDR_HEX="0040"                      # .text VirtualSize -> 0x4000 (covers the new loader)
SITE_OFF=$((0x1dbe)); SITE_HEX="89435c83c404e8b7300000eb51cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
LEA_OFF=$((0x1ee5));  LEA_HEX="0010"                      # marker scan starts at buffer+0x1000
CAVE_OFF=$((0x4e80)); CAVE_HEX="55565783ec046800600000e850fdffff83c4048b4b5c89410405ff0f00002500f0ffff8941088d90001000008911e8000000005e81c65d1100008bf8b908010000f3a58db800100000b92c0a0000f3a58b8e48c3ffff8bd4526a40680040000050ffd183c4045f5e5dc3"

pause_exit() { read -n1 -r -p "Press any key to exit..."; echo; exit "${1:-1}"; }
write_hex() { echo "$2" | xxd -r -p | dd of="$SDK" bs=1 seek="$1" conv=notrunc 2>/dev/null; }
set_ini() {
  sed -i '' -E "s/^(${1}[[:space:]]*=[[:space:]]*)[0-9]+/\1${2}/" "$INI"
  grep -q -E "^${1}[[:space:]]*=[[:space:]]*${2}" "$INI" || echo "!! could not set ${1} = ${2} in dxwrapper.ini - set it by hand."
}

WINE=""
for cx in "/Applications/CrossOver Preview.app" "/Applications/CrossOver.app"; do
  [ -x "$cx/Contents/SharedSupport/CrossOver/bin/wine" ] && WINE="$cx/Contents/SharedSupport/CrossOver/bin/wine" && break
done

echo "=== Fix Necronomicon: The Dawning of Darkness for CrossOver ==="
echo "Bottle:   $BOTTLE"
echo "Game dir: $GAME_DIR"
echo ""

if [ ! -f "$GAME_DIR/Necrono.exe" ] || [ ! -f "$SDK" ]; then
  echo "!! Necrono.exe / 4xm_sdk.dll not found."
  echo "   Install the game in Steam and run this script again."
  echo "   (or pass the game folder as the first argument)"
  pause_exit 1
fi

# --- 1. cutscene decoder --------------------------------------------------------------
CUR=$(md5 -q "$SDK")
if [ "$CUR" = "$PATCHED_MD5" ]; then
  echo "-- 4xm_sdk.dll is already patched."
elif [ "$CUR" = "$ORIG_MD5" ]; then
  cp "$SDK" "$SDK.orig"
  write_hex "$HDR_OFF" "$HDR_HEX"
  write_hex "$SITE_OFF" "$SITE_HEX"
  write_hex "$LEA_OFF" "$LEA_HEX"
  write_hex "$CAVE_OFF" "$CAVE_HEX"
  if [ "$(md5 -q "$SDK")" = "$PATCHED_MD5" ]; then
    echo "-- 4xm_sdk.dll patched. Original backed up to: 4xm_sdk.dll.orig"
  else
    echo "!! Patch failed, restoring original."
    cp "$SDK.orig" "$SDK"
    pause_exit 1
  fi
else
  echo "!! Unexpected 4xm_sdk.dll (md5 $CUR)."
  echo "   This script only knows the DLL that ships with the Steam version."
  echo "   File left untouched to avoid breaking it. Ping me and I'll add your version."
  pause_exit 1
fi

# --- 2. dxwrapper ---------------------------------------------------------------------
if [ -f "$GAME_DIR/dxwrapper.dll" ] && [ -f "$GAME_DIR/ddraw.dll" ] && [ -f "$INI" ]; then
  echo "-- dxwrapper is already in the game folder."
else
  TMP=$(mktemp -d /tmp/dxwrapper.XXXXXX)
  echo "-- Downloading dxwrapper..."
  if curl -fsSL -o "$TMP/dxwrapper.zip" "$DXW_URL" && unzip -q -o "$TMP/dxwrapper.zip" -d "$TMP/dxw" \
     && [ -f "$TMP/dxw/dxwrapper.dll" ] && [ -f "$TMP/dxw/Stub/ddraw.dll" ]; then
    cp "$TMP/dxw/dxwrapper.dll" "$GAME_DIR/"
    cp "$TMP/dxw/Stub/ddraw.dll" "$GAME_DIR/"
    [ -f "$INI" ] || cp "$TMP/dxw/dxwrapper.ini" "$INI"
    echo "-- dxwrapper.dll, ddraw.dll (stub) and dxwrapper.ini copied into the game folder."
  else
    echo "!! Could not download dxwrapper. Get dxwrapper.zip from"
    echo "   https://github.com/elishacloud/dxwrapper/releases and copy dxwrapper.dll,"
    echo "   Stub/ddraw.dll and dxwrapper.ini into the game folder, then re-run this script."
    rm -rf "$TMP"
    pause_exit 1
  fi
  rm -rf "$TMP"
fi

set_ini Dd7to9 1
set_ini SingleProcAffinity 1
set_ini DdrawUseNativeResolution 1
set_ini DdrawMaintainAspectRatio 1
set_ini FullscreenWindowMode 1
echo "-- dxwrapper.ini: Dd7to9, native resolution, aspect ratio, fullscreen window mode."

# --- 3. bottle: load the wrapper's ddraw.dll for the game ------------------------------
if [ -n "$WINE" ]; then
  echo "-- Setting ddraw=native,builtin for Necrono.exe in the bottle..."
  "$WINE" --bottle "$BOTTLE" --wait-children reg add "HKCU\\Software\\Wine\\AppDefaults\\Necrono.exe\\DllOverrides" /v ddraw /d "native,builtin" /f >/dev/null 2>&1
  echo "-- Bottle settings applied."
else
  echo "!! CrossOver not found - the ddraw override was not set."
  echo "   In CrossOver: bottle > Run Command... > winecfg > Libraries > add 'ddraw' as 'Native then Builtin'."
fi

echo ""
echo "=== Done! Launch Necronomicon from Steam as usual. ==="
echo "(Do not run 'Verify integrity of game files' in Steam - it restores the unpatched 4xm_sdk.dll.)"
pause_exit 0
