From 34b4ed759a5834af99ef0c2cebdae67a381bfa4c Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 2 May 2021 01:59:02 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20Clean=20up=20and=20fix=20invento?= =?UTF-8?q?ry=20sprite=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/cursor.cpp | 106 +++++++++++++++++++++++++++----------------- Source/cursor.h | 14 +++--- Source/inv.cpp | 75 +++++++++++++------------------ Source/scrollrt.cpp | 21 +++------ 4 files changed, 112 insertions(+), 104 deletions(-) diff --git a/Source/cursor.cpp b/Source/cursor.cpp index 8147ea7f5..1e416f531 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -16,45 +16,14 @@ #include "utils/language.h" namespace devilution { - -/** Pixel width of the current cursor image */ -int cursW; -/** Pixel height of the current cursor image */ -int cursH; -/** Current highlighted monster */ -int pcursmonst = -1; -/** Width of current cursor in inventory cells */ -int icursW28; -/** Height of current cursor in inventory cells */ -int icursH28; +namespace { /** Cursor images CEL */ std::optional pCursCels; std::optional pCursCels2; +constexpr int InvItems1Size = 180; -/** inv_item value */ -int8_t pcursinvitem; -/** Pixel width of the current cursor image */ -int icursW; -/** Pixel height of the current cursor image */ -int icursH; -/** Current highlighted item */ -int8_t pcursitem; -/** Current highlighted object */ -int8_t pcursobj; -/** Current highlighted player */ -int8_t pcursplr; -/** Current highlighted tile row */ -int cursmx; -/** Current highlighted tile column */ -int cursmy; -/** Previously highlighted monster */ -int pcurstemp; -/** Index of current cursor image */ -int pcurs; - -/* rdata */ /** Maps from objcurs.cel frame number to frame width. */ -const int InvItemWidth[] = { +const int InvItemWidth1[] = { // clang-format off // Cursors 0, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 23, @@ -76,6 +45,9 @@ const int InvItemWidth[] = { 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, 2 * 28, +}; +const int InvItemWidth2[] = { + 0, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, @@ -86,7 +58,7 @@ const int InvItemWidth[] = { }; /** Maps from objcurs.cel frame number to frame height. */ -const int InvItemHeight[] = { +const int InvItemHeight1[] = { // clang-format off // Cursors 0, 29, 32, 32, 32, 32, 32, 32, 32, 32, 32, 35, @@ -108,6 +80,9 @@ const int InvItemHeight[] = { 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, 3 * 28, +}; +const int InvItemHeight2[] = { + 0, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, 1 * 28, @@ -117,12 +92,46 @@ const int InvItemHeight[] = { // clang-format on }; +} // namespace + +/** Pixel width of the current cursor image */ +int cursW; +/** Pixel height of the current cursor image */ +int cursH; +/** Current highlighted monster */ +int pcursmonst = -1; +/** Width of current cursor in inventory cells */ +int icursW28; +/** Height of current cursor in inventory cells */ +int icursH28; + +/** inv_item value */ +int8_t pcursinvitem; +/** Pixel width of the current cursor image */ +int icursW; +/** Pixel height of the current cursor image */ +int icursH; +/** Current highlighted item */ +int8_t pcursitem; +/** Current highlighted object */ +int8_t pcursobj; +/** Current highlighted player */ +int8_t pcursplr; +/** Current highlighted tile row */ +int cursmx; +/** Current highlighted tile column */ +int cursmy; +/** Previously highlighted monster */ +int pcurstemp; +/** Index of current cursor image */ +int pcurs; + void InitCursor() { assert(!pCursCels); - pCursCels = LoadCel("Data\\Inv\\Objcurs.CEL", InvItemWidth); + pCursCels = LoadCel("Data\\Inv\\Objcurs.CEL", InvItemWidth1); if (gbIsHellfire) - pCursCels2 = LoadCel("Data\\Inv\\Objcurs2.CEL", InvItemWidth); + pCursCels2 = LoadCel("Data\\Inv\\Objcurs2.CEL", InvItemWidth2); ClearCursor(); } @@ -133,10 +142,26 @@ void FreeCursor() ClearCursor(); } +const CelSprite &GetInvItemSprite(int i) +{ + return i < InvItems1Size ? *pCursCels : *pCursCels2; +} + +int GetInvItemFrame(int i) +{ + return i < InvItems1Size ? i : i - (InvItems1Size - 1); +} + +std::pair GetInvItemSize(int i) +{ + if (i >= InvItems1Size) + return { InvItemWidth2[i - (InvItems1Size - 1)], InvItemHeight2[i - (InvItems1Size - 1)] }; + return { InvItemWidth1[i], InvItemHeight1[i] }; +} + void SetICursor(int i) { - icursW = InvItemWidth[i]; - icursH = InvItemHeight[i]; + std::tie(icursW, icursH) = GetInvItemSize(i); icursW28 = icursW / 28; icursH28 = icursH / 28; } @@ -144,8 +169,7 @@ void SetICursor(int i) void NewCursor(int i) { pcurs = i; - cursW = InvItemWidth[i]; - cursH = InvItemHeight[i]; + std::tie(cursW, cursH) = GetInvItemSize(i); SetICursor(i); } diff --git a/Source/cursor.h b/Source/cursor.h index 4e26df96f..91bf368b1 100644 --- a/Source/cursor.h +++ b/Source/cursor.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include "engine.h" #include "miniwin/miniwin.h" @@ -34,8 +35,6 @@ extern int cursH; extern int pcursmonst; extern int icursW28; extern int icursH28; -extern std::optional pCursCels; -extern std::optional pCursCels2; extern int icursH; extern int8_t pcursinvitem; extern int icursW; @@ -55,8 +54,13 @@ void CheckRportal(); void CheckTown(); void CheckCursMove(); -/* rdata */ -extern const int InvItemWidth[]; -extern const int InvItemHeight[]; +/** Returns the sprite for the given inventory index. */ +const CelSprite &GetInvItemSprite(int i); + +/** Returns the CEL frame index for the given inventory index. */ +int GetInvItemFrame(int i); + +/** Returns the width and height for an inventory index. */ +std::pair GetInvItemSize(int i); } // namespace devilution diff --git a/Source/inv.cpp b/Source/inv.cpp index db109af4c..7aedb864f 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -3,6 +3,7 @@ * * Implementation of player inventory. */ +#include #include "cursor.h" #include "minitext.h" @@ -174,7 +175,7 @@ static void InvDrawSlotBack(const CelOutputBuffer &out, int X, int Y, int W, int void DrawInv(const CelOutputBuffer &out) { - int frame, frame_width, i, j, ii; + int frame, i, j, ii; CelDrawTo(out, RIGHT_PANEL_X, 351, *pInvCels, 1); InvXY slotSize[] = { @@ -204,33 +205,31 @@ void DrawInv(const CelOutputBuffer &out) InvDrawSlotBack(out, RIGHT_PANEL_X + screen_x, screen_y, slotSize[slot].X * INV_SLOT_SIZE_PX, slotSize[slot].Y * INV_SLOT_SIZE_PX); frame = plr[myplr].InvBody[slot]._iCurs + CURSOR_FIRSTITEM; - frame_width = InvItemWidth[frame]; + + int frameW; + int frameH; + std::tie(frameW, frameH) = GetInvItemSize(frame); // calc item offsets for weapons smaller than 2x3 slots if (slot == INVLOC_HAND_LEFT) { - screen_x += frame_width == INV_SLOT_SIZE_PX ? 14 : 0; - screen_y += InvItemHeight[frame] == (3 * INV_SLOT_SIZE_PX) ? 0 : -14; + screen_x += frameW == INV_SLOT_SIZE_PX ? 14 : 0; + screen_y += frameH == (3 * INV_SLOT_SIZE_PX) ? 0 : -14; } else if (slot == INVLOC_HAND_RIGHT) { - screen_x += frame_width == INV_SLOT_SIZE_PX ? 13 : 1; - screen_y += InvItemHeight[frame] == 3 * INV_SLOT_SIZE_PX ? 0 : -14; + screen_x += frameW == INV_SLOT_SIZE_PX ? 13 : 1; + screen_y += frameH == 3 * INV_SLOT_SIZE_PX ? 0 : -14; } - const CelSprite *cels; - if (frame <= 179) { - cels = &*pCursCels; - } else { - frame -= 179; - cels = &*pCursCels2; - } + const auto &cel = GetInvItemSprite(frame); + const int celFrame = GetInvItemFrame(frame); if (pcursinvitem == slot) { - CelBlitOutlineTo(out, GetOutlineColor(plr[myplr].InvBody[slot], true), RIGHT_PANEL_X + screen_x, screen_y, *cels, frame, false); + CelBlitOutlineTo(out, GetOutlineColor(plr[myplr].InvBody[slot], true), RIGHT_PANEL_X + screen_x, screen_y, cel, celFrame, false); } if (plr[myplr].InvBody[slot]._iStatFlag) { - CelClippedDrawTo(out, RIGHT_PANEL_X + screen_x, screen_y, *cels, frame); + CelClippedDrawTo(out, RIGHT_PANEL_X + screen_x, screen_y, cel, celFrame); } else { - CelDrawLightRedTo(out, RIGHT_PANEL_X + screen_x, screen_y, *cels, frame, 1); + CelDrawLightRedTo(out, RIGHT_PANEL_X + screen_x, screen_y, cel, celFrame, 1); } if (slot == INVLOC_HAND_LEFT) { @@ -242,9 +241,9 @@ void DrawInv(const CelOutputBuffer &out) light_table_index = 0; cel_transparency_active = true; - const int dst_x = RIGHT_PANEL_X + slotPos[INVLOC_HAND_RIGHT].X + (frame_width == INV_SLOT_SIZE_PX ? 13 : -1); + const int dst_x = RIGHT_PANEL_X + slotPos[INVLOC_HAND_RIGHT].X + (frameW == INV_SLOT_SIZE_PX ? 13 : -1); const int dst_y = slotPos[INVLOC_HAND_RIGHT].Y; - CelClippedBlitLightTransTo(out, dst_x, dst_y, *cels, frame); + CelClippedBlitLightTransTo(out, dst_x, dst_y, cel, celFrame); cel_transparency_active = false; } @@ -268,15 +267,9 @@ void DrawInv(const CelOutputBuffer &out) if (plr[myplr].InvGrid[j] > 0) { // first slot of an item ii = plr[myplr].InvGrid[j] - 1; frame = plr[myplr].InvList[ii]._iCurs + CURSOR_FIRSTITEM; - frame_width = InvItemWidth[frame]; - const CelSprite *cels; - if (frame <= 179) { - cels = &*pCursCels; - } else { - frame -= 179; - cels = &*pCursCels2; - } + const auto &cel = GetInvItemSprite(frame); + const int celFrame = GetInvItemFrame(frame); if (pcursinvitem == ii + INVITEM_INV_FIRST) { CelBlitOutlineTo( @@ -284,7 +277,7 @@ void DrawInv(const CelOutputBuffer &out) GetOutlineColor(plr[myplr].InvList[ii], true), InvRect[j + SLOTXY_INV_FIRST].X + RIGHT_PANEL_X, InvRect[j + SLOTXY_INV_FIRST].Y - 1, - *cels, frame, false); + cel, celFrame, false); } if (plr[myplr].InvList[ii]._iStatFlag) { @@ -292,13 +285,13 @@ void DrawInv(const CelOutputBuffer &out) out, InvRect[j + SLOTXY_INV_FIRST].X + RIGHT_PANEL_X, InvRect[j + SLOTXY_INV_FIRST].Y - 1, - *cels, frame); + cel, celFrame); } else { CelDrawLightRedTo( out, InvRect[j + SLOTXY_INV_FIRST].X + RIGHT_PANEL_X, InvRect[j + SLOTXY_INV_FIRST].Y - 1, - *cels, frame, 1); + cel, celFrame, 1); } } } @@ -322,24 +315,19 @@ void DrawInvBelt(const CelOutputBuffer &out) InvDrawSlotBack(out, InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, INV_SLOT_SIZE_PX, INV_SLOT_SIZE_PX); int frame = plr[myplr].SpdList[i]._iCurs + CURSOR_FIRSTITEM; - const CelSprite *cels; - if (frame <= 179) { - cels = &*pCursCels; - } else { - frame -= 179; - cels = &*pCursCels2; - } + const auto &cel = GetInvItemSprite(frame); + const int celFrame = GetInvItemFrame(frame); if (pcursinvitem == i + INVITEM_BELT_FIRST) { if (!sgbControllerActive || invflag) { - CelBlitOutlineTo(out, GetOutlineColor(plr[myplr].SpdList[i], true), InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, *cels, frame, false); + CelBlitOutlineTo(out, GetOutlineColor(plr[myplr].SpdList[i], true), InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, cel, celFrame, false); } } if (plr[myplr].SpdList[i]._iStatFlag) { - CelClippedDrawTo(out, InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, *cels, frame); + CelClippedDrawTo(out, InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, cel, celFrame); } else { - CelDrawLightRedTo(out, InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, *cels, frame, 1); + CelDrawLightRedTo(out, InvRect[i + SLOTXY_BELT_FIRST].X + PANEL_X, InvRect[i + SLOTXY_BELT_FIRST].Y + PANEL_Y - 1, cel, celFrame, 1); } if (AllItemsList[plr[myplr].SpdList[i].IDidx].iUsable @@ -382,11 +370,10 @@ static void AddItemToInvGrid(int playerNumber, int invGridIndex, int invListInde InvXY GetInventorySize(const ItemStruct &item) { int itemSizeIndex = item._iCurs + CURSOR_FIRSTITEM; - - return { - InvItemWidth[itemSizeIndex] / INV_SLOT_SIZE_PX, - InvItemHeight[itemSizeIndex] / INV_SLOT_SIZE_PX, - }; + int w; + int h; + std::tie(w, h) = GetInvItemSize(itemSizeIndex); + return { w / INV_SLOT_SIZE_PX, h / INV_SLOT_SIZE_PX }; } /** diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 2d72f90b1..7099b4f8c 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -215,6 +215,8 @@ static void scrollrt_draw_cursor_item(const CelOutputBuffer &out) my++; const CelOutputBuffer &sub = out.subregion(0, 0, out.w() - 2, out.h()); + const auto &sprite = GetInvItemSprite(pcurs); + const int frame = GetInvItemFrame(pcurs); if (pcurs >= CURSOR_FIRSTITEM) { col = PAL16_YELLOW + 5; if (plr[myplr].HoldItem._iMagical != 0) { @@ -223,23 +225,14 @@ static void scrollrt_draw_cursor_item(const CelOutputBuffer &out) if (!plr[myplr].HoldItem._iStatFlag) { col = PAL16_RED + 5; } - if (pcurs <= 179) { - CelBlitOutlineTo(sub, col, mx, my + cursH - 1, *pCursCels, pcurs, false); - if (col != PAL16_RED + 5) { - CelClippedDrawSafeTo(sub, mx, my + cursH - 1, *pCursCels, pcurs); - } else { - CelDrawLightRedSafeTo(sub, mx, my + cursH - 1, *pCursCels, pcurs, 1); - } + CelBlitOutlineTo(sub, col, mx, my + cursH - 1, sprite, frame, false); + if (col != PAL16_RED + 5) { + CelClippedDrawSafeTo(sub, mx, my + cursH - 1, sprite, frame); } else { - CelBlitOutlineTo(sub, col, mx, my + cursH - 1, *pCursCels2, pcurs - 179, false); - if (col != PAL16_RED + 5) { - CelClippedDrawSafeTo(sub, mx, my + cursH - 1, *pCursCels2, pcurs - 179); - } else { - CelDrawLightRedSafeTo(sub, mx, my + cursH - 1, *pCursCels2, pcurs - 179, 0); - } + CelDrawLightRedSafeTo(sub, mx, my + cursH - 1, sprite, frame, 1); } } else { - CelClippedDrawSafeTo(sub, mx, my + cursH - 1, *pCursCels, pcurs); + CelClippedDrawSafeTo(sub, mx, my + cursH - 1, sprite, frame); } }