feat(trans): add STrans functions

This commit is contained in:
Adam Heinermann 2025-09-23 00:08:41 -07:00 committed by fallenoak
parent b4e950a1c9
commit 50872dfc14
9 changed files with 2571 additions and 15 deletions

View file

@ -10,6 +10,7 @@ if(WHOA_TEST_STORMDLL)
Region.cpp
String.cpp
Test.cpp
Transparency.cpp
)
if(WHOA_STORMDLL_VERSION GREATER_EQUAL 2003)
@ -19,6 +20,7 @@ else()
file(GLOB TEST_SOURCES
"*.cpp"
"big/*.cpp"
"trans/*.cpp"
)
endif()

1559
test/Transparency.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -245,22 +245,22 @@ EXPORTS
;SRegGetNumSubKeys @430 NONAME
; Transparency
;STransBlt @431 NONAME
;STransBltUsingMask @432 NONAME
;STransCreateI @433 NONAME
;STransDelete @434 NONAME
STransBlt @431 NONAME
STransBltUsingMask @432 NONAME
STransCreateI @433 NONAME
STransDelete @434 NONAME
;STransDestroy @435 NONAME
;STransDuplicate @436 NONAME
;STransIntersectDirtyArray @437 NONAME
;STransInvertMask @438 NONAME
STransDuplicate @436 NONAME
STransIntersectDirtyArray @437 NONAME
STransInvertMask @438 NONAME
;STransLoadI @439 NONAME
;STransSetDirtyArrayInfo @440 NONAME
;STransUpdateDirtyArray @441 NONAME
;STransIsPixelInMask @442 NONAME
;STransCombineMasks @443 NONAME
;STransCreateMaskI @444 NONAME
;STransCreateE @445 NONAME
;STransCreateMaskE @446 NONAME
STransSetDirtyArrayInfo @440 NONAME
STransUpdateDirtyArray @441 NONAME
STransIsPixelInMask @442 NONAME
STransCombineMasks @443 NONAME
STransCreateMaskI @444 NONAME
STransCreateE @445 NONAME
STransCreateMaskE @446 NONAME
;STransLoadE @447 NONAME
; Video

View file

@ -117,6 +117,24 @@ int32_t STORMAPI SStrToInt(const char*) { return 0; }
uint32_t STORMAPI SStrToUnsigned(const char*) { return 0; }
void STORMAPI SStrUpper(char*) {}
#include <storm/Transparency.hpp>
int32_t STORMAPI STransBlt(uint8_t*, int32_t, int32_t, int32_t, HSTRANS) { return 0; }
int32_t STORMAPI STransBltUsingMask(uint8_t*, uint8_t*, int32_t, int32_t, HSTRANS) { return 0; }
int32_t STORMAPI STransCombineMasks(HSTRANS, HSTRANS, int32_t, int32_t, uint32_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransCreateE(uint8_t*, int32_t, int32_t, int32_t, RECT*, uint32_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransCreateI(uint8_t*, int32_t, int32_t, int32_t, RECT*, uint32_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransCreateMaskE(uint8_t*, int32_t, int32_t, int32_t, RECT*, uint32_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransCreateMaskI(uint8_t*, int32_t, int32_t, int32_t, RECT*, uint32_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransDelete(HSTRANS) { return 0; }
int32_t STORMAPI STransDestroy() { return 0; }
int32_t STORMAPI STransDuplicate(HSTRANS, HSTRANS*) { return 0; }
int32_t STORMAPI STransIntersectDirtyArray(HSTRANS, uint8_t*, uint8_t, HSTRANS*) { return 0; }
int32_t STORMAPI STransInvertMask(HSTRANS, HSTRANS*) { return 0; }
int32_t STORMAPI STransIsPixelInMask(HSTRANS, int32_t, int32_t) { return 0; }
int32_t STORMAPI STransSetDirtyArrayInfo(int32_t, int32_t, int32_t, int32_t) { return 0; }
int32_t STORMAPI STransUpdateDirtyArray(uint8_t*, uint8_t, int32_t, int32_t, HSTRANS, int32_t) { return 0; }
#include <storm/Unicode.hpp>
ptrdiff_t STORMAPI SUniConvertUTF16ToDos(char*, const char16_t*, uint32_t) { return 0; };

View file

@ -0,0 +1,120 @@
#include "test/Test.hpp"
#include "storm/Transparency.hpp"
#include "storm/List.hpp"
#include <vector>
#include <cstdint>
extern STORM_LIST(TRANS) s_translist;
struct TRANS : TSLinkedNode<TRANS> {
uint8_t* data;
uint32_t dataalloc;
uint32_t databytes;
uint32_t instructionoffset;
int32_t width;
int32_t height;
RECT boundrect;
};
const uint32_t ImageWidth = 100;
const uint32_t ImageHeight = 9;
uint8_t MaskBits[] = {
"##################..........................##############.........................................."
"##################..........................##############.........................................."
"##############..............................#########..............................................."
"##############..............................#########..............................................."
"##################..........................#########..............................................."
"##################...........................########..............................................."
"##################...........................########..............................................."
"##################...........................##########............................................."
"##################...........................##########............................................."
};
// Retrieved from Starcraft 1.17's Storm.dll output
const std::vector<uint8_t> ExpectedInternalBytes = {
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x00,
0x00, 0x12, 0x1A, 0x0E, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A, 0x0E, 0x2A, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x1E, 0x09, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1E, 0x09, 0x2F, 0x00, 0x00, 0x00,
0x00, 0x12, 0x1A, 0x09, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1B, 0x08, 0x2F, 0x00, 0x00, 0x00,
0x00, 0x12, 0x1B, 0x08, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1B, 0x0A, 0x2D, 0x00, 0x00, 0x00,
0x00, 0x12, 0x1B, 0x0A, 0x2D, 0x00, 0x00, 0x00,
};
TEST_CASE("STransCreateE internal", "[transparency]") {
SECTION("produces correct bytes") {
HSTRANS trans;
REQUIRE(STransCreateE(MaskBits, ImageWidth, ImageHeight, 8, nullptr, STRANS_COLORKEY('#'), &trans) == 1);
auto result = std::vector<uint8_t>(trans->data, trans->data + trans->databytes);
// This one specific byte actually gets skipped
// The allocation mechanism differs in squall so it ends up being unintentionally different, but has no meaning
result[655] = 0;
CHECK(result == ExpectedInternalBytes);
STransDestroy(); // cleanup
}
}
bool TransListContains(HSTRANS trans) {
for (TRANS* pTrans = s_translist.Head(); pTrans; pTrans = pTrans->Next()) {
if (pTrans == trans) return true;
}
return false;
}
TEST_CASE("STransDelete internal", "[transparency]") {
SECTION("removes the transparency record") {
HSTRANS trans;
CHECK(STransCreateE(MaskBits, ImageWidth, ImageHeight, 8, nullptr, 0, &trans));
CHECK(TransListContains(trans));
CHECK(STransDelete(trans) == 1);
CHECK_FALSE(TransListContains(trans));
STransDestroy(); // cleanup
}
}