Skip to content

Commit

Permalink
fix: transparent image background and others
Browse files Browse the repository at this point in the history
Fixed transparent background
Circular includes
Zoom in/out grid
  • Loading branch information
dudantas committed Feb 3, 2024
1 parent b78acf8 commit cf1d150
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 32 deletions.
12 changes: 7 additions & 5 deletions source/client_assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "gui.h"
#include "otml.h"

#include <appearances.pb.h>

namespace {
bool logErrorAndSetMessage(const std::string &message, wxString &error) {
spdlog::error(message);
Expand Down Expand Up @@ -111,16 +113,16 @@ bool ClientAssets::loadAppearanceProtobuf(wxString &error, wxArrayString &warnin
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
g_gui.appearances = Appearances();
if (!g_gui.appearances.ParseFromIstream(&fileStream)) {
g_gui.m_appearancesPtr = std::make_unique<Appearances>();
if (!g_gui.m_appearancesPtr->ParseFromIstream(&fileStream)) {
error = "Failed to parse binary file " + appearanceFileName + ", file is invalid";
spdlog::error("[{}] - Failed to parse binary file {}, file is invalid", __func__, appearanceFileName);
fileStream.close();
return false;
}

// Parsing all items into ItemType
bool rt = g_items.loadFromProtobuf(error, warnings, g_gui.appearances);
bool rt = g_items.loadFromProtobuf(error, warnings, *g_gui.m_appearancesPtr);
if (!rt) {
error = "Failed to parse item types from protobuf";
spdlog::error("[{}] - Failed to parse item types from protobuf", __func__);
Expand All @@ -129,8 +131,8 @@ bool ClientAssets::loadAppearanceProtobuf(wxString &error, wxArrayString &warnin
}

// Load looktypes
for (int i = 0; i < g_gui.appearances.outfit().size(); i++) {
const auto &outfit = g_gui.appearances.outfit().Get(i);
for (int i = 0; i < g_gui.m_appearancesPtr->outfit().size(); i++) {
const auto &outfit = g_gui.m_appearancesPtr->outfit().Get(i);
if (!g_gui.gfx.loadOutfitSpriteMetadata(outfit, error, warnings)) {
error = "Failed to parse outfit types from protobuf";
spdlog::error("[{}] - Failed to parse outfit types from protobuf", __func__);
Expand Down
25 changes: 15 additions & 10 deletions source/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

#include <wx/rawbmp.h>

#include <appearances.pb.h>

GraphicManager g_graphics;
GameSprite g_gameSprite;

Expand Down Expand Up @@ -1123,22 +1125,25 @@ std::shared_ptr<GameSprite::OutfitImage> GameSprite::getOutfitImage(int spriteId
}

wxMemoryDC* GameSprite::getDC(SpriteSize spriteSize) {
ASSERT(spriteSize == SPRITE_SIZE_16x16 || spriteSize == SPRITE_SIZE_32x32);

if (!m_wxMemoryDc[spriteSize]) {
const int bgshade = g_settings.getInteger(Config::ICON_BACKGROUND);
wxImage background(getWidth(), getHeight());
ASSERT(width >= 1 && height >= 1);

wxImage background(getWidth(), getHeight());
auto backgroundBmp = wxBitmap(background);
m_wxMemoryDc[spriteSize] = new wxMemoryDC(backgroundBmp);

m_wxMemoryDc[spriteSize]->SelectObject(wxNullBitmap);

auto spriteId = spriteList[0]->getHardwareID();
wxImage wxImage = g_spriteAppearances.getWxImageBySpriteId(spriteId);

// Resize image to 32x32
// Resize the image to rme::SpritePixels x rme::SpritePixels, if necessary
if (getWidth() > rme::SpritePixels || getHeight() > rme::SpritePixels) {
wxImage.Rescale(rme::SpritePixels, rme::SpritePixels);
}

// Create a bitmap with the sprite image
auto bitMap = wxBitmap(wxImage);
m_wxMemoryDc[spriteSize]->SelectObject(bitMap);
g_gui.gfx.addSpriteToCleanup(this);
Expand Down Expand Up @@ -1215,8 +1220,8 @@ void GameSprite::Image::createGLTexture(GLuint textureId) {
g_gui.gfx.loaded_textures += 1;

glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F); // GL_CLAMP_TO_EDGE
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F); // GL_CLAMP_TO_EDGE
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spriteWidth, spriteHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, invertedBuffer);
Expand Down Expand Up @@ -1331,8 +1336,8 @@ void GameSprite::EditorImage::createGLTexture(GLuint textureId) {
g_gui.gfx.loaded_textures += 1;

glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F); // GL_CLAMP_TO_EDGE
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F); // GL_CLAMP_TO_EDGE
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rme::SpritePixels, rme::SpritePixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
Expand Down Expand Up @@ -1465,8 +1470,8 @@ void GameSprite::OutfitImage::createGLTexture(GLuint spriteId) {
g_gui.gfx.loaded_textures += 1;

glBindTexture(GL_TEXTURE_2D, spriteId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F); // GL_CLAMP_TO_EDGE
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F); // GL_CLAMP_TO_EDGE
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spriteWidth, spriteHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, invertedBuffer);
Expand Down
9 changes: 8 additions & 1 deletion source/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@

#include <wx/artprov.h>

#include <appearances.pb.h>
// Forward declarations
namespace canary {
namespace protobuf {
namespace appearances {
class Appearance;
}
}
}

enum SpriteSize {
SPRITE_SIZE_16x16,
Expand Down
2 changes: 1 addition & 1 deletion source/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ class GUI {
FlagBrush* pvp_brush;
ZoneBrush* zone_brush;

canary::protobuf::appearances::Appearances appearances; // Protobuf appearances file parsed
std::unique_ptr<canary::protobuf::appearances::Appearances> m_appearancesPtr; // Protobuf appearances file parsed

protected:
//=========================================================================
Expand Down
2 changes: 1 addition & 1 deletion source/items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ bool ItemDatabase::loadFromOtb(const FileName &datafile, wxString &error, wxArra
}
#endif

bool ItemDatabase::loadFromProtobuf(wxString &error, wxArrayString &warnings, canary::protobuf::appearances::Appearances appearances) {
bool ItemDatabase::loadFromProtobuf(wxString &error, wxArrayString &warnings, canary::protobuf::appearances::Appearances &appearances) {
using namespace canary::protobuf::appearances;

for (uint16_t it = 0; it < static_cast<uint16_t>(appearances.object_size()); ++it) {
Expand Down
2 changes: 1 addition & 1 deletion source/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ class ItemDatabase {
bool isValidID(uint16_t id) const;

bool loadFromOtb(const FileName &datafile, wxString &error, wxArrayString &warnings);
bool loadFromProtobuf(wxString &error, wxArrayString &warnings, canary::protobuf::appearances::Appearances appearances);
bool loadFromProtobuf(wxString &error, wxArrayString &warnings, canary::protobuf::appearances::Appearances &appearances);
bool loadFromGameXml(const FileName &datafile, wxString &error, wxArrayString &warnings);
bool loadItemFromGameXml(pugi::xml_node itemNode, uint16_t id);
bool loadMetaItem(pugi::xml_node node);
Expand Down
2 changes: 0 additions & 2 deletions source/preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,6 @@ wxNotebookPage* PreferencesWindow::CreateClientPage() {
topsizer->Add(client_list_window, 0, wxALL, 5);
client_page->SetSizerAndFit(topsizer);

spdlog::warn("text window {}", client_page->GetLabel().ToStdString());

return client_page;
}

Expand Down
26 changes: 15 additions & 11 deletions source/sprite_appearances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,6 @@ bool SpriteAppearances::loadSpriteSheet(const SpriteSheetPtr &sheet) {
}
}

// Fix magenta (remove transparency by black collor)
for (int offset = 0; offset < BYTES_IN_SPRITE_SHEET; offset += 4) {
std::memcpy(&data, bufferStart + offset, 4);
if (data == 0xFF00FF) {
std::memset(bufferStart + offset, 0x00, 4);
}
}

sheet->data = std::make_unique<uint8_t[]>(LZMA_UNCOMPRESSED_SIZE);
std::memcpy(sheet->data.get(), bufferStart, BYTES_IN_SPRITE_SHEET);

Expand Down Expand Up @@ -227,16 +219,28 @@ wxImage SpriteAppearances::getWxImageBySpriteId(int id, bool toSavePng /* = fals
return {};
}

const int bgshade = g_settings.getInteger(Config::ICON_BACKGROUND);
const uint32_t magenta = 0xFF00FF;
const uint32_t lightMagenta = 0xD000CF;

const int width = sprite->size.width;
const int height = sprite->size.height;
auto pixels = sprite->pixels.data();
wxImage image(width, height);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
const int index = (y * width + x) * 4;
const uint8_t r = pixels[index + 2];
const uint8_t g = pixels[index + 1];
const uint8_t b = pixels[index];
uint8_t r = pixels[index + 2];
uint8_t g = pixels[index + 1];
uint8_t b = pixels[index];

// Combines the color channels into a single 32-bit value
uint32_t color = (r << 16) | (g << 8) | b;

// Replaces magenta with the background color
if (color == magenta || color == lightMagenta) {
r = g = b = bgshade; // Sets RGB to the background color
}
image.SetRGB(x, y, r, g, b);
}
}
Expand Down

0 comments on commit cf1d150

Please sign in to comment.