Browse Source

🐞 Clean up and fix inventory sprite handling

pull/1823/head
Gleb Mazovetskiy 5 years ago committed by Anders Jenbo
parent
commit
34b4ed759a
  1. 106
      Source/cursor.cpp
  2. 14
      Source/cursor.h
  3. 75
      Source/inv.cpp
  4. 21
      Source/scrollrt.cpp

106
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<CelSprite> pCursCels;
std::optional<CelSprite> 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<int, int> 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);
}

14
Source/cursor.h

@ -6,6 +6,7 @@
#pragma once
#include <cstdint>
#include <utility>
#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<CelSprite> pCursCels;
extern std::optional<CelSprite> 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<int, int> GetInvItemSize(int i);
} // namespace devilution

75
Source/inv.cpp

@ -3,6 +3,7 @@
*
* Implementation of player inventory.
*/
#include <utility>
#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 };
}
/**

21
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);
}
}

Loading…
Cancel
Save