// port/common: Win32 widths and MSVC CRT semantics the ported 40250 logic relies on. #include "common/StdAfx.h" #include "common/D3DXMath.h" #include #include #include static int g_failures = 0; #define CHECK(cond) \ do { \ if (!(cond)) { \ std::fprintf(stderr, "%s:%d: CHECK(%s)\n", __FILE__, __LINE__, #cond); \ ++g_failures; \ } \ } while (0) int main() { // MSVC _snprintf: shorter output is terminated. char buf[8]; std::memset(buf, 'x', sizeof(buf)); CHECK(_snprintf(buf, 8, "%s", "abc") == 3); CHECK(std::strcmp(buf, "abc") == 0); // Exactly `count` bytes: written unterminated, returns count. std::memset(buf, 'x', sizeof(buf)); CHECK(_snprintf(buf, 4, "%s", "abcd") == 4); CHECK(std::memcmp(buf, "abcdx", 5) == 0); // Longer: `count` bytes written unterminated, returns -1. std::memset(buf, 'x', sizeof(buf)); CHECK(_snprintf(buf, 4, "%d", 123456) == -1); CHECK(std::memcmp(buf, "1234x", 5) == 0); CHECK(stricmp("PLAYER", "player") == 0); CHECK(_strnicmp("d:/ymir work/A", "D:/YMIR WORK/b", 12) == 0); char s[] = "MixEd"; CHECK(std::strcmp(_strlwr(s), "mixed") == 0); CHECK(MAKELONG(0x1234, 0xABCD) == static_cast(0xABCD1234u)); CHECK(LOWORD(0xABCD1234u) == 0x1234 && HIWORD(0xABCD1234u) == 0xABCD); CHECK(MAKEWORD(0x34, 0x12) == 0x1234); // DWORD arithmetic wraps like the 32-bit original. DWORD t = 0xFFFFFFF0u; t += 0x20; CHECK(t == 0x10); const DWORD a = timeGetTime(); const DWORD b = timeGetTime(); CHECK(static_cast(b - a) < 1000); // D3DX8 math: row vectors, left-handed rotations, D3DX multiply order. const auto near = [](float x, float y) { return std::fabs(x - y) < 1e-5f; }; D3DXVECTOR3 v(3.0f, 0.0f, 4.0f); CHECK(D3DXVec3Length(&v) == 5.0f && D3DXVec3LengthSq(&v) == 25.0f); D3DXVECTOR3 n; D3DXVec3Normalize(&n, &v); CHECK(near(n.x, 0.6f) && n.y == 0.0f && near(n.z, 0.8f)); D3DXVECTOR3 zero(0.0f, 0.0f, 0.0f); D3DXVec3Normalize(&n, &zero); CHECK(n == zero); CHECK((v / 2.0f) == D3DXVECTOR3(1.5f, 0.0f, 2.0f) && (2.0f * v) == D3DXVECTOR3(6.0f, 0.0f, 8.0f)); CHECK(near(D3DXToRadian(180.0f), D3DX_PI) && near(D3DXToDegree(D3DX_PI / 2.0f), 90.0f)); D3DXMATRIX rz, tr, m; D3DXMatrixRotationZ(&rz, D3DX_PI / 2.0f); // x axis -> +y D3DXVECTOR3 p(1.0f, 0.0f, 0.0f), q; D3DXVec3TransformCoord(&q, &p, &rz); CHECK(near(q.x, 0.0f) && near(q.y, 1.0f) && near(q.z, 0.0f)); D3DXMatrixTranslation(&tr, 10.0f, 20.0f, 30.0f); m = rz * tr; // rotate, then translate D3DXVec3TransformCoord(&q, &p, &m); CHECK(near(q.x, 10.0f) && near(q.y, 21.0f) && near(q.z, 30.0f)); D3DXMATRIX inv, id; CHECK(D3DXMatrixInverse(&inv, nullptr, &m) != nullptr); D3DXMatrixMultiply(&id, &m, &inv); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) CHECK(near(id.m[i][j], i == j ? 1.0f : 0.0f)); D3DXQUATERNION qz; D3DXVECTOR3 zAxis(0.0f, 0.0f, 1.0f); D3DXQuaternionRotationAxis(&qz, &zAxis, D3DX_PI / 2.0f); D3DXMATRIX mq; D3DXMatrixRotationQuaternion(&mq, &qz); for (int i = 0; i < 16; ++i) CHECK(near((&mq._11)[i], (&rz._11)[i])); D3DXMATRIX ypr, ypr2; D3DXQUATERNION qypr; D3DXMatrixRotationYawPitchRoll(&ypr, 0.3f, 0.5f, 0.7f); D3DXQuaternionRotationYawPitchRoll(&qypr, 0.3f, 0.5f, 0.7f); D3DXMatrixRotationQuaternion(&ypr2, &qypr); for (int i = 0; i < 16; ++i) CHECK(near((&ypr._11)[i], (&ypr2._11)[i])); CHECK(static_cast(D3DXCOLOR(0xFF804020u)) == 0xFF804020u); CHECK(static_cast(D3DXCOLOR(2.0f, -1.0f, 0.5f, 1.0f)) == 0xFFFF0080u); if (g_failures) return EXIT_FAILURE; std::puts("port_common_test: ok"); return EXIT_SUCCESS; }