pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/games/devilutionx



Module Name:    pkgsrc
Committed By:   nia
Date:           Sun Jul 28 10:26:43 UTC 2019

Modified Files:
        pkgsrc/games/devilutionx: Makefile distinfo
Added Files:
        pkgsrc/games/devilutionx/patches: patch-Source_inv.cpp
            patch-Source_loadsave.cpp patch-Source_loadsave.h patch-structs.h

Log Message:
devilutionx: Backport some fixes for 64-bit save files and UB.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 pkgsrc/games/devilutionx/Makefile
cvs rdiff -u -r1.2 -r1.3 pkgsrc/games/devilutionx/distinfo
cvs rdiff -u -r0 -r1.1 pkgsrc/games/devilutionx/patches/patch-Source_inv.cpp \
    pkgsrc/games/devilutionx/patches/patch-Source_loadsave.cpp \
    pkgsrc/games/devilutionx/patches/patch-Source_loadsave.h \
    pkgsrc/games/devilutionx/patches/patch-structs.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/games/devilutionx/Makefile
diff -u pkgsrc/games/devilutionx/Makefile:1.5 pkgsrc/games/devilutionx/Makefile:1.6
--- pkgsrc/games/devilutionx/Makefile:1.5       Thu Jul 11 12:56:04 2019
+++ pkgsrc/games/devilutionx/Makefile   Sun Jul 28 10:26:43 2019
@@ -1,6 +1,7 @@
-# $NetBSD: Makefile,v 1.5 2019/07/11 12:56:04 nia Exp $
+# $NetBSD: Makefile,v 1.6 2019/07/28 10:26:43 nia Exp $
 
 DISTNAME=      devilutionx-0.4.0
+PKGREVISION=   1
 CATEGORIES=    games
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=diasurgical/}
 GITHUB_PROJECT=        devilutionX

Index: pkgsrc/games/devilutionx/distinfo
diff -u pkgsrc/games/devilutionx/distinfo:1.2 pkgsrc/games/devilutionx/distinfo:1.3
--- pkgsrc/games/devilutionx/distinfo:1.2       Thu Jul 11 12:56:04 2019
+++ pkgsrc/games/devilutionx/distinfo   Sun Jul 28 10:26:43 2019
@@ -1,6 +1,10 @@
-$NetBSD: distinfo,v 1.2 2019/07/11 12:56:04 nia Exp $
+$NetBSD: distinfo,v 1.3 2019/07/28 10:26:43 nia Exp $
 
 SHA1 (devilutionx-0.4.0.tar.gz) = d5d71cf752dc0b5c89f9827b52f1567cb5cfb8f4
 RMD160 (devilutionx-0.4.0.tar.gz) = 0b647b8ee4641d9af000d4d54e1008a506a9fc66
 SHA512 (devilutionx-0.4.0.tar.gz) = ba8f650f8dd00e3b08f6ac082566351c8f3b6162d7bfa2fdf3464b38c201b08677d2f6151f2272e1d73eb972b8babc49b38364523d10763eb179f6b682641443
 Size (devilutionx-0.4.0.tar.gz) = 1351201 bytes
+SHA1 (patch-Source_inv.cpp) = 788414c9141da13391cd4f540e364a034fd87b41
+SHA1 (patch-Source_loadsave.cpp) = 22d8d6e4ca44358dfbc55741b8aebeac6af8e468
+SHA1 (patch-Source_loadsave.h) = 6d7e7cc9e188e5a406c10caceb0aa80139c6e301
+SHA1 (patch-structs.h) = d9cba47b2ca876529aef33d4190f082d134cdcb6

Added files:

Index: pkgsrc/games/devilutionx/patches/patch-Source_inv.cpp
diff -u /dev/null pkgsrc/games/devilutionx/patches/patch-Source_inv.cpp:1.1
--- /dev/null   Sun Jul 28 10:26:43 2019
+++ pkgsrc/games/devilutionx/patches/patch-Source_inv.cpp       Sun Jul 28 10:26:43 2019
@@ -0,0 +1,952 @@
+$NetBSD: patch-Source_inv.cpp,v 1.1 2019/07/28 10:26:43 nia Exp $
+
+[PATCH] Clean up CheckInvPaste (bin exact) (#1205)
+Fixes some item duplication.
+https://github.com/diasurgical/devilutionX/commit/a549d5ebc461e757065c4536cb351969dcf60fe9.patch
+
+--- Source/inv.cpp.orig        2019-05-19 17:06:45.000000000 +0000
++++ Source/inv.cpp
+@@ -686,562 +686,408 @@ int SwapItem(ItemStruct *a, ItemStruct *
+ 
+ void CheckInvPaste(int pnum, int mx, int my)
+ {
+-      int v3;              // ebx
+-      int v4;              // edi
+-      int v5;              // eax
+-      int v6;              // esi
+-      signed int v7;       // edi
+-      int v8;              // edx
+-      int v9;              // edx
+-      signed int v10;      // edi
+-      char v11;            // al
+-      signed int v12;      // ecx
+-      int v13;             // eax
+-      int v14;             // eax
+-      char *v15;           // edi
+-      int v16;             // esi
+-      int v17;             // ecx
+-      int v18;             // edx
+-      int v21;             // esi
+-      ItemStruct *v22;     // edi
+-      ItemStruct *v23;     // ecx
+-      int v24;             // eax
+-      int v25;             // eax
+-      int v26;             // edx
+-      ItemStruct *v27;     // esi
+-      int v28;             // eax
+-      int v29;             // ecx
+-      int v30;             // esi
+-      int v31;             // eax
+-      int v32;             // eax
+-      int v33;             // ecx
+-      int v34;             // eax
+-      int v35;             // ecx
+-      char *v36;           // eax
+-      int v37;             // edx
+-      int v38;             // ecx
+-      int v39;             // edi
+-      int v40;             // esi
+-      int v41;             // ebx
+-      int v42;             // edx
+-      int v43;             // eax
+-      int v44;             // eax
+-      signed int v45;      // ecx
+-      int v46;             // edx
+-      char *v47;           // eax
+-      int v48;             // edi
+-      int v49;             // eax
+-      int v50;             // ecx
+-      char *v51;           // esi
+-      char v52;            // cl
+-      int v53;             // ecx
+-      int v54;             // eax
+-      int v55;             // edi
+-      int v56;             // edx
+-      int v57;             // esi
+-      int v58;             // ebx
+-      int v59;             // eax
+-      int v60;             // esi
+-      ItemStruct tempitem; // [esp+Ch] [ebp-190h]
+-      int v62;             // [esp+17Ch] [ebp-20h]
+-      int p;               // [esp+180h] [ebp-1Ch]
+-      int v64;             // [esp+184h] [ebp-18h]
+-      int v65;             // [esp+188h] [ebp-14h]
+-      int v66;             // [esp+18Ch] [ebp-10h]
+-      int v67;             // [esp+190h] [ebp-Ch]
+-      int v68;             // [esp+194h] [ebp-8h]
+-      int v69;             // [esp+198h] [ebp-4h]
+-      int cursor_id;       // [esp+1A4h] [ebp+8h]
+-      int cursor_ida;      // [esp+1A4h] [ebp+8h]
+-
+-      p = pnum;
+-      v3 = pnum;
+-      v4 = mx;
++      int r, sx, sy;
++      int i, j, xx, yy, ii;
++      BOOL done, done2h;
++      int il, cn, it, iv, ig, gt;
++      ItemStruct tempitem;
++
+       SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
+-      v5 = my + (icursH >> 1);
+-      v6 = v4 + (icursW >> 1);
+-      v64 = icursW28;
+-      v7 = 0;
+-      v67 = icursH28;
+-      v68 = 0;
+-      do {
+-              if (v7)
+-                      goto LABEL_18;
+-              v8 = InvRect[v68].X;
+-              if (v6 >= v8 && v6 < v8 + 28) {
+-                      v9 = InvRect[v68].Y;
+-                      if (v5 >= v9 - 29 && v5 < v9) {
+-                              v7 = 1;
+-                              --v68;
+-                      }
+-              }
+-              if (v68 != 24)
+-                      goto LABEL_13;
+-              if (!(v64 & 1))
+-                      v6 -= 14;
+-              if (!(v67 & 1)) {
+-                      v5 -= 14;
+-              LABEL_13:
+-                      if (v68 == 64 && !(v67 & 1))
+-                              v5 += 14;
+-              }
+-              ++v68;
+-      } while ((unsigned int)v68 < 0x49);
+-      if (!v7)
++      i = mx + (icursW >> 1);
++      j = my + (icursH >> 1);
++      sx = icursW28;
++      sy = icursH28;
++      done = FALSE;
++      for (r = 0; r < sizeof(InvRect) / sizeof(InvRect[0]) && !done; r++) {
++              if (i >= InvRect[r].X && i < InvRect[r].X + INV_SLOT_SIZE_PX) {
++                      if (j >= InvRect[r].Y - INV_SLOT_SIZE_PX - 1 && j < InvRect[r].Y) {
++                              done = TRUE;
++                              r--;
++                      }
++              }
++              if (r == 24) {
++                      if ((sx & 1) == 0)
++                              i -= 14;
++                      if ((sy & 1) == 0) {
++                              j -= 14;
++                      }
++              }
++              if (r == 64 && (sy & 1) == 0)
++                      j += 14;
++      }
++      if (!done)
+               return;
+-LABEL_18:
+-      v10 = v68;
+-      v69 = ILOC_UNEQUIPABLE;
+-      if (v68 >= 0 && v68 <= ILOC_ARMOR)
+-              v69 = ILOC_HELM;
+-      if (v68 >= ILOC_HELM && v68 <= ILOC_RING)
+-              v69 = ILOC_RING;
+-      if (v68 == ILOC_AMULET)
+-              v69 = ILOC_AMULET;
+-      if (v68 >= ILOC_UNEQUIPABLE && v68 <= 18)
+-              v69 = ILOC_ONEHAND;
+-      if (v68 >= 19 && v68 <= 24)
+-              v69 = ILOC_ARMOR;
+-      if (v68 >= 65 && v68 <= 72)
+-              v69 = ILOC_BELT;
+-      v11 = plr[v3].HoldItem._iLoc;
+-      v12 = 0;
+-      if ((char)v11 == v69)
+-              v12 = 1;
+-      if (v69 == 1 && v11 == ILOC_TWOHAND) {
+-              v69 = ILOC_TWOHAND;
+-              v12 = 1;
+-      }
+-      if (v11 != 7 || v69 != ILOC_BELT) {
+-      LABEL_50:
+-              if (v69 != ILOC_UNEQUIPABLE)
+-                      goto LABEL_81;
+-              v66 = 0;
+-              cursor_id = 1;
+-              v13 = (v68 - 25) / 10;
+-              if (plr[v3].HoldItem._itype == ITYPE_GOLD) {
+-                      _LOBYTE(v13) = plr[0].InvGrid[10 * v13 + v3 * 21720 + (v68 - 25) % 10];
+-                      if (!(_BYTE)v13)
+-                              goto LABEL_93;
+-                      v13 = (char)v13;
+-                      if ((char)v13 <= 0) {
+-                              v13 = -v13;
+-                      } else if (*(int *)((char *)&plr[0].InvBody[v13 + 6]._itype + v3 * 21720) == ITYPE_GOLD) {
+-                              goto LABEL_93;
+-                      }
+-                      v66 = v13;
+-              LABEL_93:
+-                      v21 = p;
+-                      if (p == myplr) {
+-                              PlaySFX(ItemInvSnds[ItemCAnimTbl[plr[v3].HoldItem._iCurs]]);
+-                              v10 = v68;
+-                      }
+-                      cursor_ida = 1;
+-                      switch (v69) {
+-                      case ILOC_ONEHAND:
+-                              if (v10 > 12) {
+-                                      if (plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE) {
+-                                              v25 = plr[v3].InvBody[INVLOC_HAND_LEFT]._itype;
+-                                              if (v25 == ITYPE_NONE)
+-                                                      goto LABEL_232;
+-                                              if (plr[v3].InvBody[INVLOC_HAND_LEFT]._iLoc == ILOC_TWOHAND) {
+-                                                      NetSendCmdDelItem(FALSE, 4u);
+-                                                      NetSendCmdChItem(FALSE, 5u);
+-                                                      SwapItem(&plr[v3].InvBody[INVLOC_HAND_RIGHT], &plr[v3].InvBody[INVLOC_HAND_LEFT]);
+-                                                      v23 = &plr[v3].InvBody[INVLOC_HAND_RIGHT];
+-                                              LABEL_99:
+-                                                      v24 = SwapItem(v23, &plr[v3].HoldItem);
+-                                              LABEL_172:
+-                                                      cursor_ida = v24;
+-                                                      goto LABEL_226;
+-                                              }
+-                                              if (v25 == ITYPE_NONE || plr[v3].InvBody[INVLOC_HAND_LEFT]._iClass != plr[v3].HoldItem._iClass) {
+-                                              LABEL_232:
+-                                                      NetSendCmdChItem(FALSE, 5u);
+-                                                      v22 = &plr[v3].InvBody[INVLOC_HAND_RIGHT];
+-                                              LABEL_158:
+-                                                      qmemcpy(v22, &plr[v3].HoldItem, sizeof(ItemStruct));
+-                                                      goto LABEL_226;
+-                                              }
+-                                      } else if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE
+-                                          || plr[v3].InvBody[INVLOC_HAND_LEFT]._iClass != plr[v3].HoldItem._iClass) {
+-                                              goto LABEL_114;
++      il = ILOC_UNEQUIPABLE;
++      if (r >= 0 && r <= 3)
++              il = ILOC_HELM;
++      if (r >= 4 && r <= 5)
++              il = ILOC_RING;
++      if (r == 6)
++              il = ILOC_AMULET;
++      if (r >= 7 && r <= 18)
++              il = ILOC_ONEHAND;
++      if (r >= 19 && r <= 24)
++              il = ILOC_ARMOR;
++      if (r >= 65 && r <= 72)
++              il = ILOC_BELT;
++      done = FALSE;
++      if (plr[pnum].HoldItem._iLoc == il)
++              done = TRUE;
++      if (il == ILOC_ONEHAND && plr[pnum].HoldItem._iLoc == ILOC_TWOHAND) {
++              il = ILOC_TWOHAND;
++              done = TRUE;
++      }
++      if (plr[pnum].HoldItem._iLoc == ILOC_UNEQUIPABLE && il == ILOC_BELT) {
++              if (sx == 1 && sy == 1) {
++                      done = TRUE;
++                      if (!AllItemsList[plr[pnum].HoldItem.IDidx].iUsable)
++                              done = FALSE;
++                      if (!plr[pnum].HoldItem._iStatFlag)
++                              done = FALSE;
++                      if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
++                              done = FALSE;
++              }
++      }
++
++      if (il == ILOC_UNEQUIPABLE) {
++              done = TRUE;
++              it = 0;
++              ii = r - 25;
++              if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
++                      yy = 10 * (ii / 10);
++                      xx = ii % 10;
++                      if (plr[pnum].InvGrid[xx + yy] != 0) {
++                              iv = plr[pnum].InvGrid[xx + yy];
++                              if (iv > 0) {
++                                      if (plr[pnum].InvList[iv - 1]._itype != ITYPE_GOLD) {
++                                              it = iv;
+                                       }
+                               } else {
+-                                      if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE) {
+-                                              if (plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE
+-                                                  && plr[v3].InvBody[INVLOC_HAND_RIGHT]._iClass == plr[v3].HoldItem._iClass) {
+-                                              LABEL_114:
+-                                                      NetSendCmdChItem(FALSE, 5u);
+-                                                      v23 = &plr[v3].InvBody[INVLOC_HAND_RIGHT];
+-                                                      goto LABEL_99;
++                                      it = -iv;
++                              }
++                      }
++              } else {
++                      yy = 10 * ((ii / 10) - ((sy - 1) >> 1));
++                      if (yy < 0)
++                              yy = 0;
++                      for (j = 0; j < sy && done; j++) {
++                              if (yy >= NUM_INV_GRID_ELEM)
++                                      done = FALSE;
++                              xx = (ii % 10) - ((sx - 1) >> 1);
++                              if (xx < 0)
++                                      xx = 0;
++                              for (i = 0; i < sx && done; i++) {
++                                      if (xx >= 10) {
++                                              done = FALSE;
++                                      } else {
++                                              if (plr[pnum].InvGrid[xx + yy] != 0) {
++                                                      iv = plr[pnum].InvGrid[xx + yy];
++                                                      if (iv < 0)
++                                                              iv = -iv;
++                                                      if (it != 0) {
++                                                              if (it != iv)
++                                                                      done = FALSE;
++                                                      } else
++                                                              it = iv;
+                                               }
+-                                              NetSendCmdChItem(FALSE, 4u);
+-                                              v22 = &plr[v3].InvBody[INVLOC_HAND_LEFT];
+-                                              goto LABEL_158;
+-                                      }
+-                                      if (plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE
+-                                          && plr[v3].InvBody[INVLOC_HAND_RIGHT]._iClass == plr[v3].HoldItem._iClass) {
+-                                              goto LABEL_114;
+                                       }
++                                      xx++;
+                               }
+-                              NetSendCmdChItem(FALSE, 4u);
+-                              v23 = &plr[v3].InvBody[INVLOC_HAND_LEFT];
+-                              goto LABEL_99;
+-                      case ILOC_TWOHAND:
+-                              NetSendCmdDelItem(FALSE, 5u);
+-                              if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE)
+-                                      goto LABEL_147;
+-                              v26 = plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype;
+-                              if (v26 == -1)
+-                                      goto LABEL_146;
+-                              qmemcpy(&tempitem, &plr[v3].HoldItem, sizeof(tempitem));
+-                              v27 = &plr[v3].InvBody[INVLOC_HAND_RIGHT];
+-                              if (v26 != ITYPE_SHIELD)
+-                                      v27 = &plr[v3].InvBody[INVLOC_HAND_LEFT];
+-                              v28 = p;
+-                              qmemcpy(&plr[v3].HoldItem, v27, sizeof(plr[v3].HoldItem));
+-                              v29 = plr[v3].HoldItem._iCurs + CURSOR_FIRSTITEM;
+-                              if (v28 == myplr)
+-                                      SetCursor_(v29);
+-                              else
+-                                      SetICursor(v29);
+-                              v67 = 0;
+-                              v30 = 0;
+-                              do {
+-                                      if (v67)
+-                                              break;
+-                                      v31 = AutoPlace(p, v30++, icursW28, icursH28, 1);
+-                                      v67 = v31;
+-                              } while (v30 < 40);
+-                              v32 = p;
+-                              qmemcpy(&plr[v3].HoldItem, &tempitem, sizeof(plr[v3].HoldItem));
+-                              v33 = plr[v3].HoldItem._iCurs + CURSOR_FIRSTITEM;
+-                              if (v32 == myplr)
+-                                      SetCursor_(v33);
+-                              else
+-                                      SetICursor(v33);
+-                              if (!v67)
+-                                      return;
+-                              if (plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD)
+-                                      plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype = ITYPE_NONE;
+-                              else
+-                                      plr[v3].InvBody[INVLOC_HAND_LEFT]._itype = ITYPE_NONE;
+-                      LABEL_146:
+-                              if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE)
+-                                      goto LABEL_149;
+-                      LABEL_147:
+-                              if (plr[v3].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE) {
+-                                      NetSendCmdChItem(FALSE, 4u);
+-                                      qmemcpy(&plr[v3].InvBody[INVLOC_HAND_LEFT], &plr[v3].HoldItem, sizeof(plr[v3].InvBody[INVLOC_HAND_LEFT]));
++                              yy += 10;
++                      }
++              }
++      }
++
++      if (!done)
++              return;
++
++      if (il != ILOC_UNEQUIPABLE && il != ILOC_BELT && !plr[pnum].HoldItem._iStatFlag) {
++              done = FALSE;
++              if (plr[pnum]._pClass == PC_WARRIOR)
++                      PlaySFX(PS_WARR13);
++              else if (plr[pnum]._pClass == PC_ROGUE)
++                      PlaySFX(PS_ROGUE13);
++              else if (plr[pnum]._pClass == PC_SORCERER)
++                      PlaySFX(PS_MAGE13);
++      }
++
++      if (!done)
++              return;
++
++      if (pnum == myplr)
++              PlaySFX(ItemInvSnds[ItemCAnimTbl[plr[pnum].HoldItem._iCurs]]);
++
++      cn = CURSOR_HAND;
++      switch (il) {
++      case ILOC_HELM:
++              NetSendCmdChItem(FALSE, INVLOC_HEAD);
++              if (plr[pnum].InvBody[INVLOC_HEAD]._itype == ITYPE_NONE)
++                      plr[pnum].InvBody[INVLOC_HEAD] = plr[pnum].HoldItem;
++              else
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HEAD], &plr[pnum].HoldItem);
++              break;
++      case ILOC_RING:
++              if (r == 4) {
++                      NetSendCmdChItem(FALSE, INVLOC_RING_LEFT);
++                      if (plr[pnum].InvBody[INVLOC_RING_LEFT]._itype == ITYPE_NONE)
++                              plr[pnum].InvBody[INVLOC_RING_LEFT] = plr[pnum].HoldItem;
++                      else
++                              cn = SwapItem(&plr[pnum].InvBody[INVLOC_RING_LEFT], &plr[pnum].HoldItem);
++              } else {
++                      NetSendCmdChItem(FALSE, INVLOC_RING_RIGHT);
++                      if (plr[pnum].InvBody[INVLOC_RING_RIGHT]._itype == ITYPE_NONE)
++                              plr[pnum].InvBody[INVLOC_RING_RIGHT] = plr[pnum].HoldItem;
++                      else
++                              cn = SwapItem(&plr[pnum].InvBody[INVLOC_RING_RIGHT], &plr[pnum].HoldItem);
++              }
++              break;
++      case ILOC_AMULET:
++              NetSendCmdChItem(0, INVLOC_AMULET);
++              if (plr[pnum].InvBody[INVLOC_AMULET]._itype == ITYPE_NONE)
++                      plr[pnum].InvBody[INVLOC_AMULET] = plr[pnum].HoldItem;
++              else
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_AMULET], &plr[pnum].HoldItem);
++              break;
++      case ILOC_ONEHAND:
++              if (r <= 12) {
++                      if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE) {
++                              if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass != plr[pnum].HoldItem._iClass) {
++                                      NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                                      plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
+                               } else {
+-                              LABEL_149:
+-                                      NetSendCmdChItem(FALSE, 4u);
+-                                      if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE)
+-                                              SwapItem(&plr[v3].InvBody[INVLOC_HAND_LEFT], &plr[v3].InvBody[INVLOC_HAND_RIGHT]);
+-                                      cursor_ida = SwapItem(&plr[v3].InvBody[INVLOC_HAND_LEFT], &plr[v3].HoldItem);
+-                              }
+-                              if (plr[v3].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_STAFF) {
+-                                      v34 = plr[v3].InvBody[INVLOC_HAND_LEFT]._iSpell;
+-                                      if (v34) {
+-                                              if (plr[v3].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
+-                                                      plr[v3]._pRSpell = v34;
+-                                                      _LOBYTE(plr[v3]._pRSplType) = RSPLTYPE_CHARGES;
+-                                                      drawpanflag = 255;
+-                                              }
+-                                      }
++                                      NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
++                                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
+                               }
+-                              goto LABEL_226;
+-                      case ILOC_ARMOR:
+-                              NetSendCmdChItem(FALSE, 6u);
+-                              if (plr[v3].InvBody[INVLOC_CHEST]._itype == ITYPE_NONE) {
+-                                      v22 = &plr[v3].InvBody[INVLOC_CHEST];
+-                                      goto LABEL_158;
+-                              }
+-                              v23 = &plr[v3].InvBody[INVLOC_CHEST];
+-                              goto LABEL_99;
+-                      case ILOC_HELM:
+-                              NetSendCmdChItem(FALSE, 0);
+-                              if (plr[v3].InvBody[INVLOC_HEAD]._itype == ITYPE_NONE) {
+-                                      v22 = plr[v3].InvBody;
+-                                      goto LABEL_158;
+-                              }
+-                              v23 = plr[v3].InvBody;
+-                              goto LABEL_99;
+-                      case ILOC_RING:
+-                              if (v10 == 4) {
+-                                      NetSendCmdChItem(FALSE, 1u);
+-                                      if (plr[v3].InvBody[INVLOC_RING_LEFT]._itype == ITYPE_NONE) {
+-                                              v22 = &plr[v3].InvBody[INVLOC_RING_LEFT];
+-                                              goto LABEL_158;
+-                                      }
+-                                      v23 = &plr[v3].InvBody[INVLOC_RING_LEFT];
++                              break;
++                      }
++                      if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass != plr[pnum].HoldItem._iClass) {
++                              NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                              cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
++                              break;
++                      }
++
++                      NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
++                      break;
++              }
++              if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE) {
++                      if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_LEFT]._iLoc != ILOC_TWOHAND) {
++                              if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass != plr[pnum].HoldItem._iClass) {
++                                      NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
++                                      plr[pnum].InvBody[INVLOC_HAND_RIGHT] = plr[pnum].HoldItem;
++                                      break;
++                              }
++                              NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                              cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
++                              break;
++                      }
++                      NetSendCmdDelItem(FALSE, INVLOC_HAND_LEFT);
++                      NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
++                      SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].InvBody[INVLOC_HAND_LEFT]);
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
++                      break;
++              }
++
++              if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == plr[pnum].HoldItem._iClass) {
++                      NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
++                      break;
++              }
++              NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
++              cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
++              break;
++      case ILOC_TWOHAND:
++              NetSendCmdDelItem(FALSE, INVLOC_HAND_RIGHT);
++              if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
++                      tempitem = plr[pnum].HoldItem;
++                      if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD)
++                              plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_RIGHT];
++                      else
++                              plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_LEFT];
++                      if (pnum == myplr)
++                              SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
++                      else
++                              SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
++                      done2h = FALSE;
++                      for (i = 0; i < NUM_INV_GRID_ELEM && !done2h; i++)
++                              done2h = AutoPlace(pnum, i, icursW28, icursH28, TRUE);
++                      plr[pnum].HoldItem = tempitem;
++                      if (pnum == myplr)
++                              SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
++                      else
++                              SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
++                      if (!done2h)
++                              return;
++
++                      if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD)
++                              plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype = ITYPE_NONE;
++                      else
++                              plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype = ITYPE_NONE;
++              }
++
++              if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
++                      NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                      if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE)
++                              SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].InvBody[INVLOC_HAND_RIGHT]);
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
++              } else {
++                      NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
++                      plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
++              }
++              if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_STAFF && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iSpell != 0 && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
++                      plr[pnum]._pRSpell = plr[pnum].InvBody[INVLOC_HAND_LEFT]._iSpell;
++                      plr[pnum]._pRSplType = RSPLTYPE_CHARGES;
++                      drawpanflag = 255;
++              }
++              break;
++      case ILOC_ARMOR:
++              NetSendCmdChItem(FALSE, INVLOC_CHEST);
++              if (plr[pnum].InvBody[INVLOC_CHEST]._itype == ITYPE_NONE)
++                      plr[pnum].InvBody[INVLOC_CHEST] = plr[pnum].HoldItem;
++              else
++                      cn = SwapItem(&plr[pnum].InvBody[INVLOC_CHEST], &plr[pnum].HoldItem);
++              break;
++      case ILOC_UNEQUIPABLE:
++              if (plr[pnum].HoldItem._itype == ITYPE_GOLD && it == 0) {
++                      ii = r - 25;
++                      yy = 10 * (ii / 10);
++                      xx = ii % 10;
++                      if (plr[pnum].InvGrid[yy + xx] > 0) {
++                              il = plr[pnum].InvGrid[yy + xx];
++                              il--;
++                              gt = plr[pnum].InvList[il]._ivalue;
++                              ig = plr[pnum].HoldItem._ivalue + gt;
++                              if (ig <= 5000) {
++                                      plr[pnum].InvList[il]._ivalue = ig;
++                                      plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
++                                      if (ig >= 2500)
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
++                                      else if (ig <= 1000)
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_SMALL;
++                                      else
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_MEDIUM;
+                               } else {
+-                                      NetSendCmdChItem(FALSE, 2u);
+-                                      if (plr[v3].InvBody[INVLOC_RING_RIGHT]._itype == ITYPE_NONE) {
+-                                              v22 = &plr[v3].InvBody[INVLOC_RING_RIGHT];
+-                                              goto LABEL_158;
+-                                      }
+-                                      v23 = &plr[v3].InvBody[INVLOC_RING_RIGHT];
++                                      ig = 5000 - gt;
++                                      plr[pnum]._pGold += ig;
++                                      plr[pnum].HoldItem._ivalue -= ig;
++                                      plr[pnum].InvList[il]._ivalue = 5000;
++                                      plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
++                                      // BUGFIX: incorrect values here are leftover from beta
++                                      if (plr[pnum].HoldItem._ivalue >= 2500)
++                                              cn = 18;
++                                      else if (plr[pnum].HoldItem._ivalue <= 1000)
++                                              cn = 16;
++                                      else
++                                              cn = 17;
+                               }
+-                              goto LABEL_99;
+-                      case ILOC_AMULET:
+-                              NetSendCmdChItem(FALSE, 3u);
+-                              if (plr[v3].InvBody[INVLOC_AMULET]._itype == ITYPE_NONE) {
+-                                      v22 = &plr[v3].InvBody[INVLOC_AMULET];
+-                                      goto LABEL_158;
+-                              }
+-                              v23 = &plr[v3].InvBody[INVLOC_AMULET];
+-                              goto LABEL_99;
+-                      case ILOC_UNEQUIPABLE:
+-                              v35 = plr[v3].HoldItem._itype;
+-                              if (v35 == ITYPE_GOLD) {
+-                                      if (!v66) {
+-                                              v36 = &plr[0].InvGrid[10 * ((v68 - 25) / 10) + v3 * 21720 + (v68 - 25) % 10];
+-                                              if (*v36 <= 0) {
+-                                                      v42 = 368 * plr[v3]._pNumInv + v3 * 21720;
+-                                                      qmemcpy((char *)plr[0].InvList + v42, &plr[v3].HoldItem, 0x170u);
+-                                                      ++plr[v3]._pNumInv;
+-                                                      *v36 = plr[v3]._pNumInv;
+-                                                      v43 = plr[v3].HoldItem._ivalue;
+-                                                      plr[v3]._pGold += v43;
+-                                                      if (v43 <= 5000) {
+-                                                              if (v43 < 2500) {
+-                                                                      if (v43 > 1000)
+-                                                                              *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 5;
+-                                                                      else
+-                                                                              *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 4;
+-                                                              } else {
+-                                                                      *(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 6;
+-                                                              }
+-                                                      }
+-                                                      goto LABEL_226;
+-                                              }
+-                                              v37 = plr[v3].HoldItem._ivalue;
+-                                              v38 = 368 * (*v36 - 1) + v3 * 21720;
+-                                              v39 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v38);
+-                                              v40 = v37 + v39;
+-                                              if (v37 + v39 <= 5000) {
+-                                                      *(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = v40;
+-                                                      plr[v3]._pGold += plr[v3].HoldItem._ivalue;
+-                                                      if (v40 < 2500) {
+-                                                              if (v40 > 1000)
+-                                                                      *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 5;
+-                                                              else
+-                                                                      *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 4;
+-                                                      } else {
+-                                                              *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6;
+-                                                      }
+-                                                      goto LABEL_226;
+-                                              }
+-                                              plr[v3]._pGold += 5000 - v39;
+-                                              plr[v3].HoldItem._ivalue = v37 - (5000 - v39);
+-                                              *(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = 5000;
+-                                              *(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6;
+-                                              v41 = plr[v3].HoldItem._ivalue;
+-                                              if (v41 >= 2500) {
+-                                                      cursor_ida = 18;
+-                                                      goto LABEL_226;
+-                                              }
+-                                              v24 = (v41 > 1000) + 16;
+-                                              goto LABEL_172;
+-                                      }
+-                              } else if (!v66) {
+-                                      qmemcpy((char *)&plr[0].InvList[plr[v3]._pNumInv++] + v3 * 21720, &plr[v3].HoldItem, 0x170u);
+-                                      v66 = plr[v3]._pNumInv;
+-                              LABEL_191:
+-                                      v48 = v67;
+-                                      v49 = 10 * ((v68 - 25) / 10 - ((v67 - 1) >> 1));
+-                                      if (v49 < 0)
+-                                              v49 = 0;
+-                                      v65 = 0;
+-                                      if (v67 > 0) {
+-                                              v69 = (v68 - 25) % 10 - ((v64 - 1) >> 1);
+-                                              do {
+-                                                      v50 = v69;
+-                                                      if (v69 < 0)
+-                                                              v50 = 0;
+-                                                      v67 = 0;
+-                                                      if (v64 > 0) {
+-                                                              v51 = &plr[v3].InvGrid[v50 + v49];
+-                                                              do {
+-                                                                      if (v67 || v65 != v48 - 1)
+-                                                                              v52 = -(char)v66;
+-                                                                      else
+-                                                                              v52 = v66;
+-                                                                      *v51++ = v52;
+-                                                                      ++v67;
+-                                                              } while (v67 < v64);
+-                                                      }
+-                                                      v49 += 10;
+-                                                      ++v65;
+-                                              } while (v65 < v48);
+-                                      }
+-                                      goto LABEL_226;
++                      } else {
++                              il = plr[pnum]._pNumInv;
++                              plr[pnum].InvList[il] = plr[pnum].HoldItem;
++                              plr[pnum]._pNumInv++;
++                              plr[pnum].InvGrid[yy + xx] = plr[pnum]._pNumInv;
++                              plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
++                              if (plr[pnum].HoldItem._ivalue <= 5000) {
++                                      if (plr[pnum].HoldItem._ivalue >= 2500)
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
++                                      else if (plr[pnum].HoldItem._ivalue <= 1000)
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_SMALL;
++                                      else
++                                              plr[pnum].InvList[il]._iCurs = ICURS_GOLD_MEDIUM;
+                               }
+-                              v44 = v66 - 1;
+-                              if (v35 == ITYPE_GOLD)
+-                                      plr[v3]._pGold += plr[v3].HoldItem._ivalue;
+-                              cursor_ida = SwapItem((ItemStruct *)((char *)&plr[0].InvList[v44] + v3 * 21720), &plr[v3].HoldItem);
+-                              if (plr[v3].HoldItem._itype == ITYPE_GOLD)
+-                                      plr[v3]._pGold = CalculateGold(v21);
+-                              v45 = 0;
+-                              v46 = -v66;
+-                              do {
+-                                      v47 = &plr[v3].InvGrid[v45];
+-                                      if (*v47 == v66)
+-                                              *v47 = 0;
+-                                      if (*v47 == v46)
+-                                              *v47 = 0;
+-                                      ++v45;
+-                              } while (v45 < 40);
+-                              goto LABEL_191;
+-                      case ILOC_BELT:
+-                              v53 = v3 * 21720 + 368 * (v68 - 65);
+-                              if (plr[v3].HoldItem._itype != ITYPE_GOLD) {
+-                                      if (*(int *)((char *)&plr[0].SpdList[0]._itype + v53) == ITYPE_NONE) {
+-                                              qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u);
+-                                      } else {
+-                                              cursor_ida = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem);
+-                                              if (plr[v3].HoldItem._itype == ITYPE_GOLD)
+-                                                      plr[v3]._pGold = CalculateGold(p);
+-                                      }
+-                                      goto LABEL_225;
++                      }
++              } else {
++                      if (it == 0) {
++                              plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem;
++                              plr[pnum]._pNumInv++;
++                              it = plr[pnum]._pNumInv;
++                      } else {
++                              il = it - 1;
++                              if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
++                                      plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
++                              cn = SwapItem(&plr[pnum].InvList[il], &plr[pnum].HoldItem);
++                              if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
++                                      plr[pnum]._pGold = CalculateGold(pnum);
++                              for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
++                                      if (plr[pnum].InvGrid[i] == it)
++                                              plr[pnum].InvGrid[i] = 0;
++                                      if (plr[pnum].InvGrid[i] == -it)
++                                              plr[pnum].InvGrid[i] = 0;
++                              }
++                      }
++                      ii = r - 25;
++                      yy = 10 * (ii / 10 - ((sy - 1) >> 1));
++                      if (yy < 0)
++                              yy = 0;
++                      for (j = 0; j < sy; j++) {
++                              xx = (ii % 10 - ((sx - 1) >> 1));
++                              if (xx < 0)
++                                      xx = 0;
++                              for (i = 0; i < sx; i++) {
++                                      if (i != 0 || j != sy - 1)
++                                              plr[pnum].InvGrid[xx + yy] = -it;
++                                      else
++                                              plr[pnum].InvGrid[xx + yy] = it;
++                                      xx++;
+                               }
+-                              v54 = *(int *)((char *)&plr[0].SpdList[0]._itype + v53);
+-                              if (v54 != ITYPE_NONE) {
+-                                      if (v54 == ITYPE_GOLD) {
+-                                              v55 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53);
+-                                              v56 = plr[v3].HoldItem._ivalue;
+-                                              v57 = v55 + v56;
+-                                              if (v55 + v56 <= 5000) {
+-                                                      *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = v57;
+-                                                      plr[v3]._pGold += plr[v3].HoldItem._ivalue;
+-                                                      if (v57 < 2500) {
+-                                                              if (v57 > 1000)
+-                                                                      *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 5;
+-                                                              else
+-                                                                      *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 4;
+-                                                      } else {
+-                                                              *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6;
+-                                                      }
+-                                                      goto LABEL_225;
+-                                              }
+-                                              plr[v3]._pGold += 5000 - v55;
+-                                              plr[v3].HoldItem._ivalue = v56 - (5000 - v55);
+-                                              *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = 5000;
+-                                              *(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6;
+-                                              v58 = plr[v3].HoldItem._ivalue;
+-                                              if (v58 >= 2500) {
+-                                                      cursor_ida = 18;
+-                                                      goto LABEL_225;
+-                                              }
+-                                              v59 = (v58 > 1000) + 16;
++                              yy += 10;
++                      }
++              }
++              break;
++      case ILOC_BELT:
++              ii = r - 65;
++              if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
++                      if (plr[pnum].SpdList[ii]._itype != ITYPE_NONE) {
++                              if (plr[pnum].SpdList[ii]._itype == ITYPE_GOLD) {
++                                      i = plr[pnum].HoldItem._ivalue + plr[pnum].SpdList[ii]._ivalue;
++                                      if (i <= 5000) {
++                                              plr[pnum].SpdList[ii]._ivalue += plr[pnum].HoldItem._ivalue;
++                                              plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
++                                              if (i >= 2500)
++                                                      plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_LARGE;
++                                              else if (i <= 1000)
++                                                      plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_SMALL;
++                                              else
++                                                      plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_MEDIUM;
+                                       } else {
+-                                              plr[v3]._pGold += plr[v3].HoldItem._ivalue;
+-                                              v59 = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem);
++                                              i = 5000 - plr[pnum].SpdList[ii]._ivalue;
++                                              plr[pnum]._pGold += i;
++                                              plr[pnum].HoldItem._ivalue -= i;
++                                              plr[pnum].SpdList[ii]._ivalue = 5000;
++                                              plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_LARGE;
++
++                                              // BUGFIX: incorrect values here are leftover from beta
++                                              if (plr[pnum].HoldItem._ivalue >= 2500)
++                                                      cn = 18;
++                                              else if (plr[pnum].HoldItem._ivalue <= 1000)
++                                                      cn = 16;
++                                              else
++                                                      cn = 17;
+                                       }
+-                                      cursor_ida = v59;
+-                                      goto LABEL_225;
+-                              }
+-                              qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u);
+-                              plr[v3]._pGold += plr[v3].HoldItem._ivalue;
+-                      LABEL_225:
+-                              drawsbarflag = TRUE;
+-                      LABEL_226:
+-                              v60 = p;
+-                              CalcPlrInv(p, 1u);
+-                              if (v60 == myplr) {
+-                                      if (cursor_ida == 1)
+-                                              SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1));
+-                                      SetCursor_(cursor_ida);
++                              } else {
++                                      plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
++                                      cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem);
+                               }
+-                              return;
+-                      default:
+-                              goto LABEL_226;
++                      } else {
++                              plr[pnum].SpdList[ii] = plr[pnum].HoldItem;
++                              plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
+                       }
++              } else if (plr[pnum].SpdList[ii]._itype == ITYPE_NONE) {
++                      plr[pnum].SpdList[ii] = plr[pnum].HoldItem;
++              } else {
++                      cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem);
++                      if (plr[pnum].HoldItem._itype == 11)
++                              plr[pnum]._pGold = CalculateGold(pnum);
+               }
+-              v62 = (v68 - 25) % 10;
+-              v14 = 10 * (v13 - ((v67 - 1) >> 1));
+-              if (v14 < 0)
+-                      v14 = 0;
+-              v65 = 0;
+-              if (v67 <= 0)
+-                      goto LABEL_93;
+-              v15 = &plr[v3].InvGrid[v14];
+-              while (1) {
+-                      if (cursor_id == CURSOR_NONE)
+-                              return;
+-                      if (v14 >= 40)
+-                              cursor_id = 0;
+-                      v16 = v62 - ((v64 - 1) >> 1);
+-                      if (v16 < 0)
+-                              v16 = 0;
+-                      v17 = 0;
+-                      if (v64 > 0)
+-                              break;
+-              LABEL_79:
+-                      v14 += 10;
+-                      v15 += 10;
+-                      if (++v65 >= v67) {
+-                              v12 = cursor_id;
+-                              v10 = v68;
+-                              goto LABEL_81;
+-                      }
+-              }
+-              while (1) {
+-                      if (cursor_id == CURSOR_NONE)
+-                              goto LABEL_79;
+-                      if (v16 >= 10)
+-                              goto LABEL_233;
+-                      _LOBYTE(v18) = v15[v16];
+-                      if ((_BYTE)v18) {
+-                              v18 = (char)v18;
+-                              if ((v18 & 0x80u) != 0)
+-                                      v18 = -v18;
+-                              if (!v66) {
+-                                      v66 = v18;
+-                                      goto LABEL_78;
+-                              }
+-                              if (v66 != v18)
+-                              LABEL_233:
+-                                      cursor_id = 0;
+-                      }
+-              LABEL_78:
+-                      ++v16;
+-                      if (++v17 >= v64)
+-                              goto LABEL_79;
+-              }
+-      }
+-      if (v64 == 1 && v67 == 1) {
+-              v12 = 1;
+-              if (!AllItemsList[plr[v3].HoldItem.IDidx].iUsable)
+-                      v12 = 0;
+-              if (!plr[v3].HoldItem._iStatFlag)
+-                      v12 = 0;
+-              if (plr[v3].HoldItem._itype == ITYPE_GOLD) {
+-                      v12 = 0;
+-                      goto LABEL_50;
+-              }
+-      }
+-LABEL_81:
+-      if (!v12)
+-              return;
+-      if (v69 == ILOC_UNEQUIPABLE || v69 == ILOC_BELT || plr[v3].HoldItem._iStatFlag) {
+-              goto LABEL_93;
++              drawsbarflag = 1;
++              break;
+       }
+-      if (plr[v3]._pClass == PC_WARRIOR) {
+-              PlaySFX(PS_WARR13);
+-      } else if (plr[v3]._pClass == PC_ROGUE) {
+-              PlaySFX(PS_ROGUE13);
+-      } else if (plr[v3]._pClass == PC_SORCERER) {
+-              PlaySFX(PS_MAGE13);
++      CalcPlrInv(pnum, 1);
++      if (pnum == myplr) {
++              if (cn == 1)
++                      SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1));
++              SetCursor_(cn);
+       }
+ }
+-// 4B8C9C: using guessed type int cursH;
+-// 4B8CB4: using guessed type int icursH;
+-// 4B8CBC: using guessed type int icursW;
+-// 52571C: using guessed type int drawpanflag;
+ 
+ void CheckInvSwap(int pnum, BYTE bLoc, int idx, WORD wCI, int seed, BOOL bId)
+ {
Index: pkgsrc/games/devilutionx/patches/patch-Source_loadsave.cpp
diff -u /dev/null pkgsrc/games/devilutionx/patches/patch-Source_loadsave.cpp:1.1
--- /dev/null   Sun Jul 28 10:26:43 2019
+++ pkgsrc/games/devilutionx/patches/patch-Source_loadsave.cpp  Sun Jul 28 10:26:43 2019
@@ -0,0 +1,1092 @@
+$NetBSD: patch-Source_loadsave.cpp,v 1.1 2019/07/28 10:26:43 nia Exp $
+
+64bit Compatible Saves
+https://patch-diff.githubusercontent.com/raw/diasurgical/devilutionX/pull/162.patch
+
+[PATCH] Fix load/save monster padding
+https://github.com/diasurgical/devilutionX/commit/10ebca4efd422bbf46bad6d12ea4cdade9038b01.patch
+
+--- Source/loadsave.cpp.orig   2019-05-19 17:06:45.000000000 +0000
++++ Source/loadsave.cpp
+@@ -207,42 +207,829 @@ BOOL OLoad()
+               return FALSE;
+ }
+ 
++void CopyInt(const void *src, void * dst)
++{
++      memcpy(dst, src, 4);
++      tbuff += 4;
++}
++
++void CopyShort(const void *src, void * dst)
++{
++      memcpy(dst, src, 2);
++      tbuff += 2;
++}
++
++void CopyShorts(const void *src, const int n, void * dst)
++{
++      memcpy(dst, src, 2 * n);
++      tbuff += 2 * n;
++}
++
++void CopyInts(const void *src, const int n, void * dst)
++{
++      memcpy(dst, src, 4 * n);
++      tbuff += 4 * n;
++}
++
++void CopyBytes(const void *src, const int n, void * dst)
++{
++      memcpy(dst, src, n);
++      tbuff += n;
++}
++
++void CopyChar(const void *src, void * dst)
++{
++      memcpy(dst, src, 1);
++      tbuff += 1;
++}
++
++void CopyInt64(const void *src, void * dst)
++{
++      memcpy(dst, src, 8);
++      tbuff += 8;
++}
++
+ void LoadPlayer(int i)
+ {
+-      memcpy(&plr[i], tbuff, sizeof(*plr) - (10 * sizeof(void *)));
+-      tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers
++      PlayerStruct *pPlayer = &plr[i];
++
++      CopyInt(tbuff, &pPlayer->_pmode);
++
++      CopyBytes(tbuff, 25, pPlayer->walkpath);
++      CopyBytes(tbuff, 1, &pPlayer->plractive);
++      tbuff += 2;
++
++      CopyInt(tbuff, &pPlayer->destAction);
++      CopyInt(tbuff, &pPlayer->destParam1);
++      CopyInt(tbuff, &pPlayer->destParam2);
++      CopyInt(tbuff, &pPlayer->destParam3);
++      CopyInt(tbuff, &pPlayer->destParam4);
++      CopyInt(tbuff, &pPlayer->plrlevel);
++      CopyInt(tbuff, &pPlayer->WorldX);
++      CopyInt(tbuff, &pPlayer->WorldY);
++      CopyInt(tbuff, &pPlayer->_px);
++      CopyInt(tbuff, &pPlayer->_py);
++      CopyInt(tbuff, &pPlayer->_ptargx);
++      CopyInt(tbuff, &pPlayer->_ptargy);
++      CopyInt(tbuff, &pPlayer->_pownerx);
++      CopyInt(tbuff, &pPlayer->_pownery);
++      CopyInt(tbuff, &pPlayer->_poldx);
++      CopyInt(tbuff, &pPlayer->_poldy);
++      CopyInt(tbuff, &pPlayer->_pxoff);
++      CopyInt(tbuff, &pPlayer->_pyoff);
++      CopyInt(tbuff, &pPlayer->_pxvel);
++      CopyInt(tbuff, &pPlayer->_pyvel);
++      CopyInt(tbuff, &pPlayer->_pdir);
++      CopyInt(tbuff, &pPlayer->_nextdir);
++      CopyInt(tbuff, &pPlayer->_pgfxnum);
++      tbuff += 4; // Skip pointers
++      CopyInt(tbuff, &pPlayer->_pAnimDelay);
++      CopyInt(tbuff, &pPlayer->_pAnimCnt);
++      CopyInt(tbuff, &pPlayer->_pAnimLen);
++      CopyInt(tbuff, &pPlayer->_pAnimFrame);
++      CopyInt(tbuff, &pPlayer->_pAnimWidth);
++      CopyInt(tbuff, &pPlayer->_pAnimWidth2);
++      CopyInt(tbuff, &pPlayer->_peflag);
++      CopyInt(tbuff, &pPlayer->_plid);
++      CopyInt(tbuff, &pPlayer->_pvid);
++
++      CopyInt(tbuff, &pPlayer->_pSpell);
++      CopyChar(tbuff, &pPlayer->_pSplType);
++      CopyChar(tbuff, &pPlayer->_pSplFrom);
++      tbuff += 2;
++      CopyInt(tbuff, &pPlayer->_pTSpell);
++      CopyChar(tbuff, &pPlayer->_pTSplType);
++      tbuff += 3;
++      CopyInt(tbuff, &pPlayer->_pRSpell);
++      CopyChar(tbuff, &pPlayer->_pRSplType);
++      tbuff += 3;
++      CopyInt(tbuff, &pPlayer->_pSBkSpell);
++      CopyChar(tbuff, &pPlayer->_pSBkSplType);
++
++      CopyBytes(tbuff, 64, &pPlayer->_pSplLvl);
++      tbuff += 7;
++      CopyInt64(tbuff, &pPlayer->_pMemSpells);
++      CopyInt64(tbuff, &pPlayer->_pAblSpells);
++      CopyInt64(tbuff, &pPlayer->_pScrlSpells);
++      CopyChar(tbuff, &pPlayer->_pSpellFlags);
++      tbuff += 3;
++      CopyInts(tbuff, 4, &pPlayer->_pSplHotKey);
++      CopyBytes(tbuff, 4, &pPlayer->_pSplTHotKey);
++      CopyInt(tbuff, &pPlayer->_pwtype);
++      CopyChar(tbuff, &pPlayer->_pBlockFlag);
++      CopyChar(tbuff, &pPlayer->_pInvincible);
++      CopyChar(tbuff, &pPlayer->_pLightRad);
++      CopyChar(tbuff, &pPlayer->_pLvlChanging);
++      CopyBytes(tbuff, PLR_NAME_LEN, &pPlayer->_pName);
++      CopyChar(tbuff, &pPlayer->_pClass);
++      tbuff += 3;
++      CopyInt(tbuff, &pPlayer->_pStrength);
++      CopyInt(tbuff, &pPlayer->_pBaseStr);
++      CopyInt(tbuff, &pPlayer->_pMagic);
++      CopyInt(tbuff, &pPlayer->_pBaseMag);
++      CopyInt(tbuff, &pPlayer->_pDexterity);
++      CopyInt(tbuff, &pPlayer->_pBaseDex);
++      CopyInt(tbuff, &pPlayer->_pVitality);
++      CopyInt(tbuff, &pPlayer->_pBaseVit);
++      CopyInt(tbuff, &pPlayer->_pStatPts);
++      CopyInt(tbuff, &pPlayer->_pDamageMod);
++      CopyInt(tbuff, &pPlayer->_pBaseToBlk);
++      CopyInt(tbuff, &pPlayer->_pHPBase);
++      CopyInt(tbuff, &pPlayer->_pMaxHPBase);
++      CopyInt(tbuff, &pPlayer->_pHitPoints);
++      CopyInt(tbuff, &pPlayer->_pMaxHP);
++      CopyInt(tbuff, &pPlayer->_pHPPer);
++      CopyInt(tbuff, &pPlayer->_pManaBase);
++      CopyInt(tbuff, &pPlayer->_pMaxManaBase);
++      CopyInt(tbuff, &pPlayer->_pMana);
++      CopyInt(tbuff, &pPlayer->_pMaxMana);
++      CopyInt(tbuff, &pPlayer->_pManaPer);
++      CopyChar(tbuff, &pPlayer->_pLevel);
++      CopyChar(tbuff, &pPlayer->_pMaxLvl);
++      tbuff += 2;
++      CopyInt(tbuff, &pPlayer->_pExperience);
++      CopyInt(tbuff, &pPlayer->_pMaxExp);
++      CopyInt(tbuff, &pPlayer->_pNextExper);
++      CopyChar(tbuff, &pPlayer->_pArmorClass);
++      CopyChar(tbuff, &pPlayer->_pMagResist);
++      CopyChar(tbuff, &pPlayer->_pFireResist);
++      CopyChar(tbuff, &pPlayer->_pLghtResist);
++      CopyInt(tbuff, &pPlayer->_pGold);
++      CopyInt(tbuff, &pPlayer->_pInfraFlag);
++      CopyInt(tbuff, &pPlayer->_pVar1);
++      CopyInt(tbuff, &pPlayer->_pVar2);
++      CopyInt(tbuff, &pPlayer->_pVar3);
++      CopyInt(tbuff, &pPlayer->_pVar4);
++      CopyInt(tbuff, &pPlayer->_pVar5);
++      CopyInt(tbuff, &pPlayer->_pVar6);
++      CopyInt(tbuff, &pPlayer->_pVar7);
++      CopyInt(tbuff, &pPlayer->_pVar8);
++      CopyBytes(tbuff, NUMLEVELS, &pPlayer->_pLvlVisited);
++      CopyBytes(tbuff, NUMLEVELS, &pPlayer->_pSLvlVisited);
++      tbuff += 2;
++      CopyInt(tbuff, &pPlayer->_pGFXLoad);
++
++      tbuff += sizeof(__uint32_t) * 8;
++      CopyInt(tbuff, &pPlayer->_pNFrames);
++      CopyInt(tbuff, &pPlayer->_pNWidth);
++
++      tbuff += sizeof(__uint32_t) * 8;
++
++      CopyInt(tbuff, &pPlayer->_pWFrames);
++      CopyInt(tbuff, &pPlayer->_pWWidth);
++
++      tbuff += sizeof(__uint32_t) * 8;
++
++      CopyInt(tbuff, &pPlayer->_pAFrames);
++      CopyInt(tbuff, &pPlayer->_pAWidth);
++      CopyInt(tbuff, &pPlayer->_pAFNum);
++
++      tbuff += sizeof(__uint32_t) * 24;
++
++      CopyInt(tbuff, &pPlayer->_pSFrames);
++      CopyInt(tbuff, &pPlayer->_pSWidth);
++      CopyInt(tbuff, &pPlayer->_pSFNum);
++
++      tbuff += sizeof(__uint32_t) * 8;
++
++      CopyInt(tbuff, &pPlayer->_pHFrames);
++      CopyInt(tbuff, &pPlayer->_pHWidth);
++
++      tbuff += sizeof(__uint32_t) * 8;
++
++      CopyInt(tbuff, &pPlayer->_pDFrames);
++      CopyInt(tbuff, &pPlayer->_pDWidth);
++
++      tbuff += sizeof(__uint32_t) * 8;
++
++      CopyInt(tbuff, &pPlayer->_pBFrames);
++      CopyInt(tbuff, &pPlayer->_pBWidth);
++      CopyItems(NUM_INVLOC, pPlayer->InvBody);
++      CopyItems(NUM_INV_GRID_ELEM, pPlayer->InvList);
++      CopyInt(tbuff, &pPlayer->_pNumInv);
++      CopyBytes(tbuff, NUM_INV_GRID_ELEM, pPlayer->InvGrid);
++      CopyItems(MAXBELTITEMS, pPlayer->SpdList);
++      CopyItem(&pPlayer->HoldItem);
++      CopyInt(tbuff, &pPlayer->_pIMinDam);
++      CopyInt(tbuff, &pPlayer->_pIMaxDam);
++      CopyInt(tbuff, &pPlayer->_pIAC);
++      CopyInt(tbuff, &pPlayer->_pIBonusDam);
++      CopyInt(tbuff, &pPlayer->_pIBonusToHit);
++      CopyInt(tbuff, &pPlayer->_pIBonusAC);
++      CopyInt(tbuff, &pPlayer->_pIBonusDamMod);
++      tbuff += 4;
++      CopyInt64(tbuff, &pPlayer->_pISpells);
++      CopyInt(tbuff, &pPlayer->_pIFlags);
++      CopyInt(tbuff, &pPlayer->_pIGetHit);
++
++      CopyChar(tbuff, &pPlayer->_pISplLvlAdd);
++      CopyChar(tbuff, &pPlayer->_pISplCost);
++      tbuff += 2;
++
++      CopyInt(tbuff, &pPlayer->_pISplDur);
++      CopyInt(tbuff, &pPlayer->_pIEnAc);
++      CopyInt(tbuff, &pPlayer->_pIFMinDam);
++      CopyInt(tbuff, &pPlayer->_pIFMaxDam);
++      CopyInt(tbuff, &pPlayer->_pILMinDam);
++      CopyInt(tbuff, &pPlayer->_pILMaxDam);
++      CopyInt(tbuff, &pPlayer->_pOilType);
++
++      CopyChar(tbuff, &pPlayer->pTownWarps);
++      CopyChar(tbuff, &pPlayer->pDungMsgs);
++      CopyChar(tbuff, &pPlayer->pLvlLoad);
++      CopyChar(tbuff, &pPlayer->pBattleNet);
++
++      CopyChar(tbuff, &pPlayer->pManaShield);
++      CopyBytes(tbuff, 3, &pPlayer->bReserved);
++
++      CopyShorts(tbuff, 8, &pPlayer->wReserved);
++
++      CopyInt(tbuff, &pPlayer->pDiabloKillLevel);
++      CopyInts(tbuff, 7, &pPlayer->dwReserved);
++
++      // Omit 10 pointers
++      
++}
++
++void SavePlayer(int i)
++{
++      PlayerStruct *pPlayer = &plr[i];
++
++      CopyInt(&pPlayer->_pmode, tbuff);
++
++      CopyBytes(&pPlayer->walkpath, 25, tbuff);
++      CopyBytes(&pPlayer->plractive, 1, tbuff);
++      tbuff += 2;
++
++      CopyInt(&pPlayer->destAction, tbuff);
++      CopyInt(&pPlayer->destParam1, tbuff);
++      CopyInt(&pPlayer->destParam2, tbuff);
++      CopyInt(&pPlayer->destParam3, tbuff);
++      CopyInt(&pPlayer->destParam4, tbuff);
++      CopyInt(&pPlayer->plrlevel, tbuff);
++      CopyInt(&pPlayer->WorldX, tbuff);
++      CopyInt(&pPlayer->WorldY, tbuff);
++      CopyInt(&pPlayer->_px, tbuff);
++      CopyInt(&pPlayer->_py, tbuff);
++      CopyInt(&pPlayer->_ptargx, tbuff);
++      CopyInt(&pPlayer->_ptargy, tbuff);
++      CopyInt(&pPlayer->_pownerx, tbuff);
++      CopyInt(&pPlayer->_pownery, tbuff);
++      CopyInt(&pPlayer->_poldx, tbuff);
++      CopyInt(&pPlayer->_poldy, tbuff);
++      CopyInt(&pPlayer->_pxoff, tbuff);
++      CopyInt(&pPlayer->_pyoff, tbuff);
++      CopyInt(&pPlayer->_pxvel, tbuff);
++      CopyInt(&pPlayer->_pyvel, tbuff);
++      CopyInt(&pPlayer->_pdir, tbuff);
++      CopyInt(&pPlayer->_nextdir, tbuff);
++      CopyInt(&pPlayer->_pgfxnum, tbuff);
++      tbuff += 4; // Skip pointers
++      CopyInt(&pPlayer->_pAnimDelay, tbuff);
++      CopyInt(&pPlayer->_pAnimCnt, tbuff);
++      CopyInt(&pPlayer->_pAnimLen, tbuff);
++      CopyInt(&pPlayer->_pAnimFrame, tbuff);
++      CopyInt(&pPlayer->_pAnimWidth, tbuff);
++      CopyInt(&pPlayer->_pAnimWidth2, tbuff);
++      CopyInt(&pPlayer->_peflag, tbuff);
++      CopyInt(&pPlayer->_plid, tbuff);
++      CopyInt(&pPlayer->_pvid, tbuff);
++
++      CopyInt(&pPlayer->_pSpell, tbuff);
++
++      CopyChar(&pPlayer->_pSplType, tbuff);
++      CopyChar(&pPlayer->_pSplFrom, tbuff);
++      tbuff += 2;
++      
++      CopyInt(&pPlayer->_pTSpell, tbuff);
++      CopyChar(&pPlayer->_pTSplType, tbuff);
++      tbuff += 3;
++      CopyInt(&pPlayer->_pRSpell, tbuff);
++      CopyChar(&pPlayer->_pRSplType, tbuff);
++      tbuff += 3;
++      CopyInt(&pPlayer->_pSBkSpell, tbuff);
++      CopyChar(&pPlayer->_pSBkSplType, tbuff);
++
++      CopyBytes(&pPlayer->_pSplLvl, 64, tbuff);
++      tbuff += 7;
++      CopyInt64(&pPlayer->_pMemSpells, tbuff);
++      CopyInt64(&pPlayer->_pAblSpells, tbuff);
++      CopyInt64(&pPlayer->_pScrlSpells, tbuff);
++      CopyChar(&pPlayer->_pSpellFlags, tbuff);
++      tbuff += 3;
++      CopyInts(&pPlayer->_pSplHotKey, 4, tbuff);
++      CopyBytes(&pPlayer->_pSplTHotKey, 4, tbuff);
++      CopyInt(&pPlayer->_pwtype, tbuff);
++      CopyChar(&pPlayer->_pBlockFlag, tbuff);
++      CopyChar(&pPlayer->_pInvincible, tbuff);
++      CopyChar(&pPlayer->_pLightRad, tbuff);
++      CopyChar(&pPlayer->_pLvlChanging, tbuff);
++      CopyBytes(&pPlayer->_pName, PLR_NAME_LEN, tbuff);
++      CopyChar(&pPlayer->_pClass, tbuff);
++      tbuff += 3;
++      CopyInt(&pPlayer->_pStrength, tbuff);
++      CopyInt(&pPlayer->_pBaseStr, tbuff);
++      CopyInt(&pPlayer->_pMagic, tbuff);
++      CopyInt(&pPlayer->_pBaseMag, tbuff);
++      CopyInt(&pPlayer->_pDexterity, tbuff);
++      CopyInt(&pPlayer->_pBaseDex, tbuff);
++      CopyInt(&pPlayer->_pVitality, tbuff);
++      CopyInt(&pPlayer->_pBaseVit, tbuff);
++      CopyInt(&pPlayer->_pStatPts, tbuff);
++      CopyInt(&pPlayer->_pDamageMod, tbuff);
++      CopyInt(&pPlayer->_pBaseToBlk, tbuff);
++      CopyInt(&pPlayer->_pHPBase, tbuff);
++      CopyInt(&pPlayer->_pMaxHPBase, tbuff);
++      CopyInt(&pPlayer->_pHitPoints, tbuff);
++      CopyInt(&pPlayer->_pMaxHP, tbuff);
++      CopyInt(&pPlayer->_pHPPer, tbuff);
++      CopyInt(&pPlayer->_pManaBase, tbuff);
++      CopyInt(&pPlayer->_pMaxManaBase, tbuff);
++      CopyInt(&pPlayer->_pMana, tbuff);
++      CopyInt(&pPlayer->_pMaxMana, tbuff);
++      CopyInt(&pPlayer->_pManaPer, tbuff);
++      CopyChar(&pPlayer->_pLevel, tbuff);
++      CopyChar(&pPlayer->_pMaxLvl, tbuff);
++      tbuff += 2;
++      CopyInt(&pPlayer->_pExperience, tbuff);
++      CopyInt(&pPlayer->_pMaxExp, tbuff);
++      CopyInt(&pPlayer->_pNextExper, tbuff);
++      CopyChar(&pPlayer->_pArmorClass, tbuff);
++      CopyChar(&pPlayer->_pMagResist, tbuff);
++      CopyChar(&pPlayer->_pFireResist, tbuff);
++      CopyChar(&pPlayer->_pLghtResist, tbuff);
++      CopyInt(&pPlayer->_pGold, tbuff);
++      CopyInt(&pPlayer->_pInfraFlag, tbuff);
++      CopyInt(&pPlayer->_pVar1, tbuff);
++      CopyInt(&pPlayer->_pVar2, tbuff);
++      CopyInt(&pPlayer->_pVar3, tbuff);
++      CopyInt(&pPlayer->_pVar4, tbuff);
++      CopyInt(&pPlayer->_pVar5, tbuff);
++      CopyInt(&pPlayer->_pVar6, tbuff);
++      CopyInt(&pPlayer->_pVar7, tbuff);
++      CopyInt(&pPlayer->_pVar8, tbuff);
++      CopyBytes(&pPlayer->_pLvlVisited, NUMLEVELS, tbuff);
++      CopyBytes(&pPlayer->_pSLvlVisited, NUMLEVELS, tbuff); // only 10 used
++      tbuff += 2;
++      CopyInt(&pPlayer->_pGFXLoad, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++      CopyInt(&pPlayer->_pNFrames, tbuff);
++      CopyInt(&pPlayer->_pNWidth, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++
++      CopyInt(&pPlayer->_pWFrames, tbuff);
++      CopyInt(&pPlayer->_pWWidth, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++
++      CopyInt(&pPlayer->_pAFrames, tbuff);
++      CopyInt(&pPlayer->_pAWidth, tbuff);
++      CopyInt(&pPlayer->_pAFNum, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 24; // Skip 24 pointers
++
++      CopyInt(&pPlayer->_pSFrames, tbuff);
++      CopyInt(&pPlayer->_pSWidth, tbuff);
++      CopyInt(&pPlayer->_pSFNum, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++
++      CopyInt(&pPlayer->_pHFrames, tbuff);
++      CopyInt(&pPlayer->_pHWidth, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++
++      CopyInt(&pPlayer->_pDFrames, tbuff);
++      CopyInt(&pPlayer->_pDWidth, tbuff);
++
++      tbuff += sizeof(__uint32_t) * 8; // Skip 8 pointers
++
++      CopyInt(&pPlayer->_pBFrames, tbuff);
++      CopyInt(&pPlayer->_pBWidth, tbuff);
++      SaveItems(pPlayer->InvBody, NUM_INVLOC);
++      SaveItems(pPlayer->InvList, NUM_INV_GRID_ELEM);
++      CopyInt(&pPlayer->_pNumInv, tbuff);
++      CopyBytes(pPlayer->InvGrid, NUM_INV_GRID_ELEM, tbuff);
++      SaveItems(pPlayer->SpdList, MAXBELTITEMS);
++      SaveItem(&pPlayer->HoldItem);
++      CopyInt(&pPlayer->_pIMinDam, tbuff);
++      CopyInt(&pPlayer->_pIMaxDam, tbuff);
++      CopyInt(&pPlayer->_pIAC, tbuff);
++      CopyInt(&pPlayer->_pIBonusDam, tbuff);
++      CopyInt(&pPlayer->_pIBonusToHit, tbuff);
++      CopyInt(&pPlayer->_pIBonusAC, tbuff);
++      CopyInt(&pPlayer->_pIBonusDamMod, tbuff);
++      tbuff += 4;
++      CopyInt64(&pPlayer->_pISpells, tbuff);
++      CopyInt(&pPlayer->_pIFlags, tbuff);
++      CopyInt(&pPlayer->_pIGetHit, tbuff);
++
++      CopyChar(&pPlayer->_pISplLvlAdd, tbuff);
++      CopyChar(&pPlayer->_pISplCost, tbuff);
++      tbuff += 2;
++
++      CopyInt(&pPlayer->_pISplDur, tbuff);
++      CopyInt(&pPlayer->_pIEnAc, tbuff);
++      CopyInt(&pPlayer->_pIFMinDam, tbuff);
++      CopyInt(&pPlayer->_pIFMaxDam, tbuff);
++      CopyInt(&pPlayer->_pILMinDam, tbuff);
++      CopyInt(&pPlayer->_pILMaxDam, tbuff);
++      CopyInt(&pPlayer->_pOilType, tbuff);
++
++      CopyChar(&pPlayer->pTownWarps, tbuff);
++      CopyChar(&pPlayer->pDungMsgs, tbuff);
++      CopyChar(&pPlayer->pLvlLoad, tbuff);
++      CopyChar(&pPlayer->pBattleNet, tbuff);
++
++      CopyChar(&pPlayer->pManaShield, tbuff);
++      CopyBytes(&pPlayer->bReserved, 3, tbuff);
++
++      CopyShorts(&pPlayer->wReserved, 8, tbuff);
++
++      CopyInt(&pPlayer->pDiabloKillLevel, tbuff);
++      CopyInts(&pPlayer->dwReserved, 7, tbuff);
++
++      // Omit 10 pointers
++      
+ }
+ 
+ void LoadMonster(int i)
+ {
+-      memcpy(&monster[i], tbuff, sizeof(*monster) - (3 * sizeof(void *)));
+-      tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers
++      MonsterStruct *pMonster = &monster[i];
++
++      CopyInt(tbuff, &pMonster->_mMTidx);
++      CopyInt(tbuff, &pMonster->_mmode);
++
++      CopyChar(tbuff, &pMonster->_mgoal);
++      tbuff += 3;
++
++      CopyInt(tbuff, &pMonster->_mgoalvar1);
++      CopyInt(tbuff, &pMonster->_mgoalvar2);
++      CopyInt(tbuff, &pMonster->_mgoalvar3);
++      CopyInt(tbuff, &pMonster->field_18);
++
++      CopyChar(tbuff, &pMonster->_pathcount);
++      tbuff += 3;
++
++      CopyInt(tbuff, &pMonster->_mx);
++      CopyInt(tbuff, &pMonster->_my);
++      CopyInt(tbuff, &pMonster->_mfutx);
++      CopyInt(tbuff, &pMonster->_mfuty);
++      CopyInt(tbuff, &pMonster->_moldx);
++      CopyInt(tbuff, &pMonster->_moldy);
++      CopyInt(tbuff, &pMonster->_mxoff);
++      CopyInt(tbuff, &pMonster->_myoff);
++      CopyInt(tbuff, &pMonster->_mxvel);
++      CopyInt(tbuff, &pMonster->_myvel);
++      CopyInt(tbuff, &pMonster->_mdir);
++      CopyInt(tbuff, &pMonster->_menemy);
++
++      CopyChar(tbuff, &pMonster->_menemyx);
++      CopyChar(tbuff, &pMonster->_menemyy);
++      CopyShort(tbuff, &pMonster->falign_52);
++
++      tbuff += 4; // Skip pointer
++      CopyInt(tbuff, &pMonster->_mAnimDelay);
++      CopyInt(tbuff, &pMonster->_mAnimCnt);
++      CopyInt(tbuff, &pMonster->_mAnimLen);
++      CopyInt(tbuff, &pMonster->_mAnimFrame);
++      CopyInt(tbuff, &pMonster->_meflag);
++      CopyInt(tbuff, &pMonster->_mDelFlag);
++      CopyInt(tbuff, &pMonster->_mVar1);
++      CopyInt(tbuff, &pMonster->_mVar2);
++      CopyInt(tbuff, &pMonster->_mVar3);
++      CopyInt(tbuff, &pMonster->_mVar4);
++      CopyInt(tbuff, &pMonster->_mVar5);
++      CopyInt(tbuff, &pMonster->_mVar6);
++      CopyInt(tbuff, &pMonster->_mVar7);
++      CopyInt(tbuff, &pMonster->_mVar8);
++      CopyInt(tbuff, &pMonster->_mmaxhp);
++      CopyInt(tbuff, &pMonster->_mhitpoints);
++
++      CopyChar(tbuff, &pMonster->_mAi);
++      CopyChar(tbuff, &pMonster->_mint);
++      CopyShort(tbuff, &pMonster->falign_9A);
++
++      CopyInt(tbuff, &pMonster->_mFlags);
++
++      CopyChar(tbuff, &pMonster->_msquelch);
++      tbuff += 3;
++
++      CopyInt(tbuff, &pMonster->falign_A4);
++      CopyInt(tbuff, &pMonster->_lastx);
++      CopyInt(tbuff, &pMonster->_lasty);
++      CopyInt(tbuff, &pMonster->_mRndSeed);
++      CopyInt(tbuff, &pMonster->_mAISeed);
++      CopyInt(tbuff, &pMonster->falign_B8);
++
++      CopyChar(tbuff, &pMonster->_uniqtype);
++      CopyChar(tbuff, &pMonster->_uniqtrans);
++      CopyChar(tbuff, &pMonster->_udeadval);
++      CopyChar(tbuff, &pMonster->mWhoHit);
++
++      CopyChar(tbuff, &pMonster->mLevel);
++      tbuff += 1;
++      CopyShort(tbuff, &pMonster->mExp);
++      
++      CopyChar(tbuff, &pMonster->mHit);
++      CopyChar(tbuff, &pMonster->mMinDamage);
++      CopyChar(tbuff, &pMonster->mMaxDamage);
++      CopyChar(tbuff, &pMonster->mHit2);
++      
++      CopyChar(tbuff, &pMonster->mMinDamage2);
++      CopyChar(tbuff, &pMonster->mMaxDamage2);
++      CopyChar(tbuff, &pMonster->mArmorClass);
++      CopyChar(tbuff, &pMonster->falign_CB);
++      
++      CopyShort(tbuff, &pMonster->mMagicRes);
++      tbuff += 2;
++
++      CopyInt(tbuff, &pMonster->mtalkmsg);
++
++      CopyChar(tbuff, &pMonster->leader);
++      CopyChar(tbuff, &pMonster->leaderflag);
++      CopyChar(tbuff, &pMonster->packsize);
++      CopyChar(tbuff, &pMonster->mlid);
++      
+       SyncMonsterAnim(i);
+ }
+ 
+ void LoadMissile(int i)
+ {
+-      memcpy(&missile[i], tbuff, sizeof(*missile));
+-      tbuff += sizeof(*missile);
++      MissileStruct *pMissile = &missile[i];
++
++      CopyInt(tbuff, &pMissile->_mitype);
++      CopyInt(tbuff, &pMissile->_mix);
++      CopyInt(tbuff, &pMissile->_miy);
++      CopyInt(tbuff, &pMissile->_mixoff);
++      CopyInt(tbuff, &pMissile->_miyoff);
++      CopyInt(tbuff, &pMissile->_mixvel);
++      CopyInt(tbuff, &pMissile->_miyvel);
++      CopyInt(tbuff, &pMissile->_misx);
++      CopyInt(tbuff, &pMissile->_misy);
++      CopyInt(tbuff, &pMissile->_mitxoff);
++      CopyInt(tbuff, &pMissile->_mityoff);
++      CopyInt(tbuff, &pMissile->_mimfnum);
++      CopyInt(tbuff, &pMissile->_mispllvl);
++      CopyInt(tbuff, &pMissile->_miDelFlag);
++      CopyChar(tbuff, &pMissile->_miAnimType);
++      tbuff += 3;
++      
++      CopyInt(tbuff, &pMissile->_miAnimFlags);
++      tbuff += 4;
++      CopyInt(tbuff, &pMissile->_miAnimDelay);
++      CopyInt(tbuff, &pMissile->_miAnimLen);
++      CopyInt(tbuff, &pMissile->_miAnimWidth);
++      CopyInt(tbuff, &pMissile->_miAnimWidth2);
++      CopyInt(tbuff, &pMissile->_miAnimCnt);
++      CopyInt(tbuff, &pMissile->_miAnimAdd);
++      CopyInt(tbuff, &pMissile->_miAnimFrame);
++      CopyInt(tbuff, &pMissile->_miDrawFlag);
++      CopyInt(tbuff, &pMissile->_miLightFlag);
++      CopyInt(tbuff, &pMissile->_miPreFlag);
++      CopyInt(tbuff, &pMissile->_miUniqTrans);
++      CopyInt(tbuff, &pMissile->_mirange);
++      CopyInt(tbuff, &pMissile->_misource);
++      CopyInt(tbuff, &pMissile->_micaster);
++      CopyInt(tbuff, &pMissile->_midam);
++      CopyInt(tbuff, &pMissile->_miHitFlag);
++      CopyInt(tbuff, &pMissile->_midist);
++      CopyInt(tbuff, &pMissile->_mlid);
++      CopyInt(tbuff, &pMissile->_mirnd);
++      CopyInt(tbuff, &pMissile->_miVar1);
++      CopyInt(tbuff, &pMissile->_miVar2);
++      CopyInt(tbuff, &pMissile->_miVar3);
++      CopyInt(tbuff, &pMissile->_miVar4);
++      CopyInt(tbuff, &pMissile->_miVar5);
++      CopyInt(tbuff, &pMissile->_miVar6);
++      CopyInt(tbuff, &pMissile->_miVar7);
++      CopyInt(tbuff, &pMissile->_miVar8);
+ }
+ 
+ void LoadObject(int i)
+ {
+-      memcpy(&object[i], tbuff, sizeof(*object));
+-      tbuff += sizeof(*object);
++      ObjectStruct *pObject = &object[i];
++      CopyInt(tbuff, &pObject->_otype);
++      CopyInt(tbuff, &pObject->_ox);
++      CopyInt(tbuff, &pObject->_oy);
++      CopyInt(tbuff, &pObject->_oLight);
++      CopyInt(tbuff, &pObject->_oAnimFlag);
++      tbuff += 4;
++      CopyInt(tbuff, &pObject->_oAnimDelay);
++      CopyInt(tbuff, &pObject->_oAnimCnt);
++      CopyInt(tbuff, &pObject->_oAnimLen);
++      CopyInt(tbuff, &pObject->_oAnimFrame);
++      CopyInt(tbuff, &pObject->_oAnimWidth);
++      CopyInt(tbuff, &pObject->_oAnimWidth2);
++      CopyInt(tbuff, &pObject->_oDelFlag);
++
++      CopyChar(tbuff, &pObject->_oBreak);
++      tbuff += 3;
++
++      CopyInt(tbuff, &pObject->_oSolidFlag);
++      CopyInt(tbuff, &pObject->_oMissFlag);
++
++      CopyChar(tbuff, &pObject->_oSelFlag); 
++      tbuff += 3;
++
++      CopyInt(tbuff, &pObject->_oPreFlag);
++      CopyInt(tbuff, &pObject->_oTrapFlag);
++      CopyInt(tbuff, &pObject->_oDoorFlag);
++      CopyInt(tbuff, &pObject->_olid);
++      CopyInt(tbuff, &pObject->_oRndSeed);
++      CopyInt(tbuff, &pObject->_oVar1);
++      CopyInt(tbuff, &pObject->_oVar2);
++      CopyInt(tbuff, &pObject->_oVar3);
++      CopyInt(tbuff, &pObject->_oVar4);
++      CopyInt(tbuff, &pObject->_oVar5);
++      CopyInt(tbuff, &pObject->_oVar6);
++      CopyInt(tbuff, &pObject->_oVar7);
++      CopyInt(tbuff, &pObject->_oVar8);
+ }
+ 
+ void LoadItem(int i)
+ {
+-      memcpy(&item[i], tbuff, sizeof(*item));
+-      tbuff += sizeof(*item);
++      CopyItem(&item[i]);
+       GetItemFrm(i);
+ }
+ 
++void CopyItem(ItemStruct *pItem)
++{
++      CopyInt(tbuff, &pItem->_iSeed);
++      CopyShort(tbuff, &pItem->_iCreateInfo);
++      tbuff += 2;
++      CopyInt(tbuff, &pItem->_itype);
++      CopyInt(tbuff, &pItem->_ix);
++      CopyInt(tbuff, &pItem->_iy);
++      CopyInt(tbuff, &pItem->_iAnimFlag);
++      tbuff += 4; // Skip pointer _iAnimData
++      CopyInt(tbuff, &pItem->_iAnimLen);
++      CopyInt(tbuff, &pItem->_iAnimFrame);
++      CopyInt(tbuff, &pItem->_iAnimWidth);
++      CopyInt(tbuff, &pItem->_iAnimWidth2);
++      CopyInt(tbuff, &pItem->_isin);
++      CopyChar(tbuff, &pItem->_iSelFlag);
++      tbuff += 3;
++      CopyInt(tbuff, &pItem->_iPostDraw);
++      CopyInt(tbuff, &pItem->_iIdentified);
++      CopyChar(tbuff, &pItem->_iMagical);
++      CopyBytes(tbuff, 64, &pItem->_iName);
++      CopyBytes(tbuff, 64, &pItem->_iIName);
++      CopyChar(tbuff, &pItem->_iLoc);
++      CopyChar(tbuff, &pItem->_iClass);
++      tbuff += 1;
++      CopyInt(tbuff, &pItem->_iCurs);
++      CopyInt(tbuff, &pItem->_ivalue);
++      CopyInt(tbuff, &pItem->_iIvalue);
++      CopyInt(tbuff, &pItem->_iMinDam);
++      CopyInt(tbuff, &pItem->_iMaxDam);
++      CopyInt(tbuff, &pItem->_iAC);
++      CopyInt(tbuff, &pItem->_iFlags);
++      CopyInt(tbuff, &pItem->_iMiscId);
++      CopyInt(tbuff, &pItem->_iSpell);
++      CopyInt(tbuff, &pItem->_iCharges);
++      CopyInt(tbuff, &pItem->_iMaxCharges);
++      CopyInt(tbuff, &pItem->_iDurability);
++      CopyInt(tbuff, &pItem->_iMaxDur);
++      CopyInt(tbuff, &pItem->_iPLDam);
++      CopyInt(tbuff, &pItem->_iPLToHit);
++      CopyInt(tbuff, &pItem->_iPLAC);
++      CopyInt(tbuff, &pItem->_iPLStr);
++      CopyInt(tbuff, &pItem->_iPLMag);
++      CopyInt(tbuff, &pItem->_iPLDex);
++      CopyInt(tbuff, &pItem->_iPLVit);
++      CopyInt(tbuff, &pItem->_iPLFR);
++      CopyInt(tbuff, &pItem->_iPLLR);
++      CopyInt(tbuff, &pItem->_iPLMR);
++      CopyInt(tbuff, &pItem->_iPLMana);
++      CopyInt(tbuff, &pItem->_iPLHP);
++      CopyInt(tbuff, &pItem->_iPLDamMod);
++      CopyInt(tbuff, &pItem->_iPLGetHit);
++      CopyInt(tbuff, &pItem->_iPLLight);
++      CopyChar(tbuff, &pItem->_iSplLvlAdd);
++      CopyChar(tbuff, &pItem->_iRequest);
++      tbuff += 2;
++      CopyInt(tbuff, &pItem->_iUid);
++      CopyInt(tbuff, &pItem->_iFMinDam);
++      CopyInt(tbuff, &pItem->_iFMaxDam);
++      CopyInt(tbuff, &pItem->_iLMinDam);
++      CopyInt(tbuff, &pItem->_iLMaxDam);
++      CopyInt(tbuff, &pItem->_iPLEnAc);
++      CopyChar(tbuff, &pItem->_iPrePower);
++      CopyChar(tbuff, &pItem->_iSufPower);
++      tbuff += 2;
++      CopyInt(tbuff, &pItem->_iVAdd1);
++      CopyInt(tbuff, &pItem->_iVMult1);
++      CopyInt(tbuff, &pItem->_iVAdd2);
++      CopyInt(tbuff, &pItem->_iVMult2);
++      CopyChar(tbuff, &pItem->_iMinStr);
++      CopyChar(tbuff, &pItem->_iMinMag);
++      CopyChar(tbuff, &pItem->_iMinDex);
++      tbuff += 1;
++      CopyInt(tbuff, &pItem->_iStatFlag);
++      CopyInt(tbuff, &pItem->IDidx);
++      CopyInt(tbuff, &pItem->offs016C);
++}
++
++void CopyItems(const int n, ItemStruct *pItem)
++{
++      for (int i = 0; i < n; i++)
++      {
++              CopyItem(&pItem[i]);
++      }
++}
++
++void SaveItem(ItemStruct *pItem)
++{
++      CopyInt(&pItem->_iSeed, tbuff);
++      CopyShort(&pItem->_iCreateInfo, tbuff);
++      tbuff += 2;
++      CopyInt(&pItem->_itype, tbuff);
++      CopyInt(&pItem->_ix, tbuff);
++      CopyInt(&pItem->_iy, tbuff);
++      CopyInt(&pItem->_iAnimFlag, tbuff);
++      tbuff += 4; // Skip pointer _iAnimData
++      CopyInt(&pItem->_iAnimLen, tbuff);
++      CopyInt(&pItem->_iAnimFrame, tbuff);
++      CopyInt(&pItem->_iAnimWidth, tbuff);
++      CopyInt(&pItem->_iAnimWidth2, tbuff); // width 2?
++      CopyInt(&pItem->_isin, tbuff);        // set when item is flagged for deletion, deprecated in 1.02
++      CopyChar(&pItem->_iSelFlag, tbuff);
++      tbuff += 3;
++      CopyInt(&pItem->_iPostDraw, tbuff);
++      CopyInt(&pItem->_iIdentified, tbuff);
++      CopyChar(&pItem->_iMagical, tbuff);
++      CopyBytes(&pItem->_iName, 64, tbuff);
++      CopyBytes(&pItem->_iIName, 64, tbuff);
++      CopyChar(&pItem->_iLoc, tbuff);
++      CopyChar(&pItem->_iClass, tbuff);
++      tbuff += 1;
++      CopyInt(&pItem->_iCurs, tbuff);
++      CopyInt(&pItem->_ivalue, tbuff);
++      CopyInt(&pItem->_iIvalue, tbuff);
++      CopyInt(&pItem->_iMinDam, tbuff);
++      CopyInt(&pItem->_iMaxDam, tbuff);
++      CopyInt(&pItem->_iAC, tbuff);
++      CopyInt(&pItem->_iFlags, tbuff);
++      CopyInt(&pItem->_iMiscId, tbuff);
++      CopyInt(&pItem->_iSpell, tbuff);
++      CopyInt(&pItem->_iCharges, tbuff);
++      CopyInt(&pItem->_iMaxCharges, tbuff);
++      CopyInt(&pItem->_iDurability, tbuff);
++      CopyInt(&pItem->_iMaxDur, tbuff);
++      CopyInt(&pItem->_iPLDam, tbuff);
++      CopyInt(&pItem->_iPLToHit, tbuff);
++      CopyInt(&pItem->_iPLAC, tbuff);
++      CopyInt(&pItem->_iPLStr, tbuff);
++      CopyInt(&pItem->_iPLMag, tbuff);
++      CopyInt(&pItem->_iPLDex, tbuff);
++      CopyInt(&pItem->_iPLVit, tbuff);
++      CopyInt(&pItem->_iPLFR, tbuff);
++      CopyInt(&pItem->_iPLLR, tbuff);
++      CopyInt(&pItem->_iPLMR, tbuff);
++      CopyInt(&pItem->_iPLMana, tbuff);
++      CopyInt(&pItem->_iPLHP, tbuff);
++      CopyInt(&pItem->_iPLDamMod, tbuff);
++      CopyInt(&pItem->_iPLGetHit, tbuff);
++      CopyInt(&pItem->_iPLLight, tbuff);
++      CopyChar(&pItem->_iSplLvlAdd, tbuff);
++      CopyChar(&pItem->_iRequest, tbuff);
++      tbuff += 2;
++      CopyInt(&pItem->_iUid, tbuff);
++      CopyInt(&pItem->_iFMinDam, tbuff);
++      CopyInt(&pItem->_iFMaxDam, tbuff);
++      CopyInt(&pItem->_iLMinDam, tbuff);
++      CopyInt(&pItem->_iLMaxDam, tbuff);
++      CopyInt(&pItem->_iPLEnAc, tbuff);
++      CopyChar(&pItem->_iPrePower, tbuff);
++      CopyChar(&pItem->_iSufPower, tbuff);
++      tbuff += 2;
++      CopyInt(&pItem->_iVAdd1, tbuff);
++      CopyInt(&pItem->_iVMult1, tbuff);
++      CopyInt(&pItem->_iVAdd2, tbuff);
++      CopyInt(&pItem->_iVMult2, tbuff);
++      CopyChar(&pItem->_iMinStr, tbuff);
++      CopyChar(&pItem->_iMinMag, tbuff);
++      CopyChar(&pItem->_iMinDex, tbuff);
++      tbuff += 1;
++      CopyInt(&pItem->_iStatFlag, tbuff);
++      CopyInt(&pItem->IDidx, tbuff);
++      CopyInt(&pItem->offs016C, tbuff);
++}
++
++void SaveItems(ItemStruct *pItem, const int n)
++{
++      for (int i = 0; i < n; i++)
++      {
++              SaveItem(&pItem[i]);
++      }
++}
++
+ void LoadPremium(int i)
+ {
+-      memcpy(&premiumitem[i], tbuff, sizeof(*premiumitem));
+-      tbuff += sizeof(*premiumitem);
++      CopyItem(&item[i]);
+ }
+ 
+ void LoadQuest(int i)
+@@ -348,7 +1135,7 @@ void SaveGame()
+       for (i = 0; i < MAXITEMS; i++)
+               BSave(itemavail[i]);
+       for (i = 0; i < numitems; i++)
+-              SaveItem(itemactive[i]);
++              SaveItem(&item[itemactive[i]]);
+       for (i = 0; i < 128; i++)
+               OSave(UniqueItemFlag[i]);
+ 
+@@ -446,40 +1233,201 @@ void OSave(BOOL v)
+               *tbuff++ = FALSE;
+ }
+ 
+-void SavePlayer(int i)
+-{
+-      memcpy(tbuff, &plr[i], sizeof(*plr) - (10 * sizeof(void *)));
+-      tbuff += sizeof(*plr) - (10 * sizeof(void *)); // omit last 10 pointers
+-}
+-
+ void SaveMonster(int i)
+ {
+-      memcpy(tbuff, &monster[i], sizeof(*monster) - (3 * sizeof(void *)));
+-      tbuff += sizeof(*monster) - (3 * sizeof(void *)); // omit last 3 pointers
++      MonsterStruct *pMonster = &monster[i];
++
++      CopyInt(&pMonster->_mMTidx, tbuff);
++      CopyInt(&pMonster->_mmode, tbuff);
++
++      CopyChar(&pMonster->_mgoal, tbuff);
++      tbuff += 3;
++
++      CopyInt(&pMonster->_mgoalvar1, tbuff);
++      CopyInt(&pMonster->_mgoalvar2, tbuff);
++      CopyInt(&pMonster->_mgoalvar3, tbuff);
++      CopyInt(&pMonster->field_18, tbuff);
++
++      CopyChar(&pMonster->_pathcount, tbuff);
++      tbuff += 3;
++
++      CopyInt(&pMonster->_mx, tbuff);
++      CopyInt(&pMonster->_my, tbuff);
++      CopyInt(&pMonster->_mfutx, tbuff);
++      CopyInt(&pMonster->_mfuty, tbuff);
++      CopyInt(&pMonster->_moldx, tbuff);
++      CopyInt(&pMonster->_moldy, tbuff);
++      CopyInt(&pMonster->_mxoff, tbuff);
++      CopyInt(&pMonster->_myoff, tbuff);
++      CopyInt(&pMonster->_mxvel, tbuff);
++      CopyInt(&pMonster->_myvel, tbuff);
++      CopyInt(&pMonster->_mdir, tbuff);
++      CopyInt(&pMonster->_menemy, tbuff);
++
++      CopyChar(&pMonster->_menemyx, tbuff);
++      CopyChar(&pMonster->_menemyy, tbuff);
++      CopyShort(&pMonster->falign_52, tbuff);
++
++      tbuff += 4; // Skip pointer
++      CopyInt(&pMonster->_mAnimDelay, tbuff);
++      CopyInt(&pMonster->_mAnimCnt, tbuff);
++      CopyInt(&pMonster->_mAnimLen, tbuff);
++      CopyInt(&pMonster->_mAnimFrame, tbuff);
++      CopyInt(&pMonster->_meflag, tbuff);
++      CopyInt(&pMonster->_mDelFlag, tbuff);
++      CopyInt(&pMonster->_mVar1, tbuff);
++      CopyInt(&pMonster->_mVar2, tbuff);
++      CopyInt(&pMonster->_mVar3, tbuff);
++      CopyInt(&pMonster->_mVar4, tbuff);
++      CopyInt(&pMonster->_mVar5, tbuff);
++      CopyInt(&pMonster->_mVar6, tbuff);
++      CopyInt(&pMonster->_mVar7, tbuff);
++      CopyInt(&pMonster->_mVar8, tbuff);
++      CopyInt(&pMonster->_mmaxhp, tbuff);
++      CopyInt(&pMonster->_mhitpoints, tbuff);
++
++      CopyChar(&pMonster->_mAi, tbuff);
++      CopyChar(&pMonster->_mint, tbuff);
++      CopyShort(&pMonster->falign_9A, tbuff);
++
++      CopyInt(&pMonster->_mFlags, tbuff);
++
++      CopyChar(&pMonster->_msquelch, tbuff);
++      tbuff += 3;
++
++      CopyInt(&pMonster->falign_A4, tbuff);
++      CopyInt(&pMonster->_lastx, tbuff);
++      CopyInt(&pMonster->_lasty, tbuff);
++      CopyInt(&pMonster->_mRndSeed, tbuff);
++      CopyInt(&pMonster->_mAISeed, tbuff);
++      CopyInt(&pMonster->falign_B8, tbuff);
++
++      CopyChar(&pMonster->_uniqtype, tbuff);
++      CopyChar(&pMonster->_uniqtrans, tbuff);
++      CopyChar(&pMonster->_udeadval, tbuff);
++      CopyChar(&pMonster->mWhoHit, tbuff);
++
++      CopyChar(&pMonster->mLevel, tbuff);
++      tbuff += 1;
++      CopyShort(&pMonster->mExp, tbuff);
++      
++      CopyChar(&pMonster->mHit, tbuff);
++      CopyChar(&pMonster->mMinDamage, tbuff);
++      CopyChar(&pMonster->mMaxDamage, tbuff);
++      CopyChar(&pMonster->mHit2, tbuff);
++      
++      CopyChar(&pMonster->mMinDamage2, tbuff);
++      CopyChar(&pMonster->mMaxDamage2, tbuff);
++      CopyChar(&pMonster->mArmorClass, tbuff);
++      CopyChar(&pMonster->falign_CB, tbuff);
++      
++      CopyShort(&pMonster->mMagicRes, tbuff);
++      tbuff += 2;
++
++      CopyInt(&pMonster->mtalkmsg, tbuff);
++
++      CopyChar(&pMonster->leader, tbuff);
++      CopyChar(&pMonster->leaderflag, tbuff);
++      CopyChar(&pMonster->packsize, tbuff);
++      CopyChar(&pMonster->mlid, tbuff);
+ }
+ 
+ void SaveMissile(int i)
+ {
+-      memcpy(tbuff, &missile[i], sizeof(*missile));
+-      tbuff += sizeof(*missile);
+-}
++      MissileStruct *pMissile = &missile[i];
+ 
+-void SaveObject(int i)
+-{
+-      memcpy(tbuff, &object[i], sizeof(*object));
+-      tbuff += sizeof(*object);
++      CopyInt(&pMissile->_mitype, tbuff);
++      CopyInt(&pMissile->_mix, tbuff);
++      CopyInt(&pMissile->_miy, tbuff);
++      CopyInt(&pMissile->_mixoff, tbuff);
++      CopyInt(&pMissile->_miyoff, tbuff);
++      CopyInt(&pMissile->_mixvel, tbuff);
++      CopyInt(&pMissile->_miyvel, tbuff);
++      CopyInt(&pMissile->_misx, tbuff);
++      CopyInt(&pMissile->_misy, tbuff);
++      CopyInt(&pMissile->_mitxoff, tbuff);
++      CopyInt(&pMissile->_mityoff, tbuff);
++      CopyInt(&pMissile->_mimfnum, tbuff);
++      CopyInt(&pMissile->_mispllvl, tbuff);
++      CopyInt(&pMissile->_miDelFlag, tbuff);
++      CopyChar(&pMissile->_miAnimType, tbuff);
++      tbuff += 3;
++      
++      CopyInt(&pMissile->_miAnimFlags, tbuff);
++      tbuff += 4;
++      CopyInt(&pMissile->_miAnimDelay, tbuff);
++      CopyInt(&pMissile->_miAnimLen, tbuff);
++      CopyInt(&pMissile->_miAnimWidth, tbuff);
++      CopyInt(&pMissile->_miAnimWidth2, tbuff);
++      CopyInt(&pMissile->_miAnimCnt, tbuff);
++      CopyInt(&pMissile->_miAnimAdd, tbuff);
++      CopyInt(&pMissile->_miAnimFrame, tbuff);
++      CopyInt(&pMissile->_miDrawFlag, tbuff);
++      CopyInt(&pMissile->_miLightFlag, tbuff);
++      CopyInt(&pMissile->_miPreFlag, tbuff);
++      CopyInt(&pMissile->_miUniqTrans, tbuff);
++      CopyInt(&pMissile->_mirange, tbuff);
++      CopyInt(&pMissile->_misource, tbuff);
++      CopyInt(&pMissile->_micaster, tbuff);
++      CopyInt(&pMissile->_midam, tbuff);
++      CopyInt(&pMissile->_miHitFlag, tbuff);
++      CopyInt(&pMissile->_midist, tbuff);
++      CopyInt(&pMissile->_mlid, tbuff);
++      CopyInt(&pMissile->_mirnd, tbuff);
++      CopyInt(&pMissile->_miVar1, tbuff);
++      CopyInt(&pMissile->_miVar2, tbuff);
++      CopyInt(&pMissile->_miVar3, tbuff);
++      CopyInt(&pMissile->_miVar4, tbuff);
++      CopyInt(&pMissile->_miVar5, tbuff);
++      CopyInt(&pMissile->_miVar6, tbuff);
++      CopyInt(&pMissile->_miVar7, tbuff);
++      CopyInt(&pMissile->_miVar8, tbuff);
+ }
+ 
+-void SaveItem(int i)
++void SaveObject(int i)
+ {
+-      memcpy(tbuff, &item[i], sizeof(*item));
+-      tbuff += sizeof(*item);
++      ObjectStruct *pObject = &object[i];
++      CopyInt(tbuff, &pObject->_otype);
++      CopyInt(&pObject->_ox, tbuff);
++      CopyInt(&pObject->_oy, tbuff);
++      CopyInt(&pObject->_oLight, tbuff);
++      CopyInt(&pObject->_oAnimFlag, tbuff);
++      tbuff += 4;
++      CopyInt(&pObject->_oAnimDelay, tbuff);
++      CopyInt(&pObject->_oAnimCnt, tbuff);
++      CopyInt(&pObject->_oAnimLen, tbuff);
++      CopyInt(&pObject->_oAnimFrame, tbuff);
++      CopyInt(&pObject->_oAnimWidth, tbuff);
++      CopyInt(&pObject->_oAnimWidth2, tbuff);
++      CopyInt(&pObject->_oDelFlag, tbuff);
++
++      CopyChar(&pObject->_oBreak, tbuff);
++      tbuff += 3;
++
++      CopyInt(&pObject->_oSolidFlag, tbuff);
++      CopyInt(&pObject->_oMissFlag, tbuff);
++
++      CopyChar(&pObject->_oSelFlag, tbuff); 
++      tbuff += 3;
++
++      CopyInt(&pObject->_oPreFlag, tbuff);
++      CopyInt(&pObject->_oTrapFlag, tbuff);
++      CopyInt(&pObject->_oDoorFlag, tbuff);
++      CopyInt(&pObject->_olid, tbuff);
++      CopyInt(&pObject->_oRndSeed, tbuff);
++      CopyInt(&pObject->_oVar1, tbuff);
++      CopyInt(&pObject->_oVar2, tbuff);
++      CopyInt(&pObject->_oVar3, tbuff);
++      CopyInt(&pObject->_oVar4, tbuff);
++      CopyInt(&pObject->_oVar5, tbuff);
++      CopyInt(&pObject->_oVar6, tbuff);
++      CopyInt(&pObject->_oVar7, tbuff);
++      CopyInt(&pObject->_oVar8, tbuff);
+ }
+ 
+ void SavePremium(int i)
+ {
+-      memcpy(tbuff, &premiumitem[i], sizeof(*premiumitem));
+-      tbuff += sizeof(*premiumitem);
++      SaveItem(&item[i]);
+ }
+ 
+ void SaveQuest(int i)
+@@ -554,7 +1502,7 @@ void SaveLevel()
+       for (i = 0; i < MAXITEMS; i++)
+               BSave(itemavail[i]);
+       for (i = 0; i < numitems; i++)
+-              SaveItem(itemactive[i]);
++              SaveItem(&item[itemactive[i]]);
+ 
+       for (j = 0; j < MAXDUNY; j++) {
+               for (i = 0; i < MAXDUNX; i++)
Index: pkgsrc/games/devilutionx/patches/patch-Source_loadsave.h
diff -u /dev/null pkgsrc/games/devilutionx/patches/patch-Source_loadsave.h:1.1
--- /dev/null   Sun Jul 28 10:26:43 2019
+++ pkgsrc/games/devilutionx/patches/patch-Source_loadsave.h    Sun Jul 28 10:26:43 2019
@@ -0,0 +1,19 @@
+$NetBSD: patch-Source_loadsave.h,v 1.1 2019/07/28 10:26:43 nia Exp $
+
+64bit Compatible Saves
+https://patch-diff.githubusercontent.com/raw/diasurgical/devilutionX/pull/162.patch
+
+--- Source/loadsave.h.orig     2019-05-19 17:06:45.000000000 +0000
++++ Source/loadsave.h
+@@ -9,6 +9,11 @@ char BLoad();
+ int WLoad();
+ int ILoad();
+ BOOL OLoad();
++void CopyItems(const int n, ItemStruct *pItem);
++void CopyItem(ItemStruct *pItem);
++void SaveItem(ItemStruct *pItem);
++void SaveItems(ItemStruct *pItem, const int n);
++
+ void LoadPlayer(int i);
+ void LoadMonster(int i);
+ void LoadMissile(int i);
Index: pkgsrc/games/devilutionx/patches/patch-structs.h
diff -u /dev/null pkgsrc/games/devilutionx/patches/patch-structs.h:1.1
--- /dev/null   Sun Jul 28 10:26:43 2019
+++ pkgsrc/games/devilutionx/patches/patch-structs.h    Sun Jul 28 10:26:43 2019
@@ -0,0 +1,53 @@
+$NetBSD: patch-structs.h,v 1.1 2019/07/28 10:26:43 nia Exp $
+
+64bit Compatible Saves
+https://patch-diff.githubusercontent.com/raw/diasurgical/devilutionX/pull/162.patch
+
+--- structs.h.orig     2019-05-19 17:06:45.000000000 +0000
++++ structs.h
+@@ -655,6 +655,7 @@ typedef struct ObjDataStruct {
+       BOOL oTrapFlag;
+ } ObjDataStruct;
+ 
++#pragma pack(push, 4)
+ typedef struct ObjectStruct {
+       int _otype;
+       int _ox;
+@@ -687,11 +688,13 @@ typedef struct ObjectStruct {
+       int _oVar7;
+       int _oVar8;
+ } ObjectStruct;
++#pragma pack(pop)
+ 
+ //////////////////////////////////////////////////
+ // portal
+ //////////////////////////////////////////////////
+ 
++#pragma pack(push, 4)
+ typedef struct PortalStruct {
+       BOOL open;
+       int x;
+@@ -700,6 +703,7 @@ typedef struct PortalStruct {
+       int ltype;
+       BOOL setlvl;
+ } PortalStruct;
++#pragma pack(pop)
+ 
+ //////////////////////////////////////////////////
+ // msg
+@@ -966,6 +970,7 @@ typedef struct TBuffer {
+ // quests
+ //////////////////////////////////////////////////
+ 
++#pragma pack(push, 4)
+ typedef struct QuestStruct {
+       unsigned char _qlevel;
+       unsigned char _qtype;
+@@ -980,6 +985,7 @@ typedef struct QuestStruct {
+       unsigned char _qvar2;
+       int _qlog;
+ } QuestStruct;
++#pragma pack(pop)
+ 
+ typedef struct QuestData {
+       unsigned char _qdlvl;



Home | Main Index | Thread Index | Old Index