citra-emu
/
citra-canary
Archived
1
0
Fork 0

common/vector_math: Move Vec[x] types into the Common namespace

These types are within the common library, so they should be using the
Common namespace.
This commit is contained in:
Lioncash 2019-02-26 22:38:34 -05:00 committed by fearlessTobi
parent db58652680
commit 643472e24a
40 changed files with 309 additions and 301 deletions

View File

@ -29,7 +29,7 @@ QImage LoadTexture(const u8* src, const Pica::Texture::TextureInfo& info) {
QImage decoded_image(info.width, info.height, QImage::Format_ARGB32);
for (u32 y = 0; y < info.height; ++y) {
for (u32 x = 0; x < info.width; ++x) {
Math::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(src, x, y, info, true);
decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
}
}

View File

@ -585,7 +585,7 @@ void GraphicsSurfaceWidget::OnUpdate() {
for (unsigned int y = 0; y < surface_height; ++y) {
for (unsigned int x = 0; x < surface_width; ++x) {
Math::Vec4<u8> color = Pica::Texture::LookupTexture(buffer, x, y, info, true);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(buffer, x, y, info, true);
decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a()));
}
}
@ -605,7 +605,7 @@ void GraphicsSurfaceWidget::OnUpdate() {
const u32 coarse_y = y & ~7;
u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
const u8* pixel = buffer + offset;
Math::Vec4<u8> color = {0, 0, 0, 0};
Common::Vec4<u8> color = {0, 0, 0, 0};
switch (surface_format) {
case Format::D16: {
@ -622,14 +622,14 @@ void GraphicsSurfaceWidget::OnUpdate() {
break;
}
case Format::D24X8: {
Math::Vec2<u32> data = Color::DecodeD24S8(pixel);
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
color.r() = data.x & 0xFF;
color.g() = (data.x >> 8) & 0xFF;
color.b() = (data.x >> 16) & 0xFF;
break;
}
case Format::X24S8: {
Math::Vec2<u32> data = Color::DecodeD24S8(pixel);
Common::Vec2<u32> data = Color::DecodeD24S8(pixel);
color.r() = color.g() = color.b() = data.y;
break;
}

View File

@ -55,36 +55,36 @@ constexpr u8 Convert8To6(u8 value) {
/**
* Decode a color stored in RGBA8 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGBA8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGBA8(const u8* bytes) {
return {bytes[3], bytes[2], bytes[1], bytes[0]};
}
/**
* Decode a color stored in RGB8 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB8(const u8* bytes) {
return {bytes[2], bytes[1], bytes[0], 255};
}
/**
* Decode a color stored in RG8 (aka HILO8) format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRG8(const u8* bytes) {
inline Common::Vec4<u8> DecodeRG8(const u8* bytes) {
return {bytes[1], bytes[0], 0, 255};
}
/**
* Decode a color stored in RGB565 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB565(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F),
@ -94,9 +94,9 @@ inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
/**
* Decode a color stored in RGB5A1 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F),
@ -106,9 +106,9 @@ inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
/**
* Decode a color stored in RGBA4 format
* @param bytes Pointer to encoded source color
* @return Result color decoded as Math::Vec4<u8>
* @return Result color decoded as Common::Vec4<u8>
*/
inline Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
inline Common::Vec4<u8> DecodeRGBA4(const u8* bytes) {
u16_le pixel;
std::memcpy(&pixel, bytes, sizeof(pixel));
return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF),
@ -138,9 +138,9 @@ inline u32 DecodeD24(const u8* bytes) {
/**
* Decode a depth value and a stencil value stored in D24S8 format
* @param bytes Pointer to encoded source values
* @return Resulting values stored as a Math::Vec2
* @return Resulting values stored as a Common::Vec2
*/
inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
inline Common::Vec2<u32> DecodeD24S8(const u8* bytes) {
return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]};
}
@ -149,7 +149,7 @@ inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGBA8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGBA8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[3] = color.r();
bytes[2] = color.g();
bytes[1] = color.b();
@ -161,7 +161,7 @@ inline void EncodeRGBA8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[2] = color.r();
bytes[1] = color.g();
bytes[0] = color.b();
@ -172,7 +172,7 @@ inline void EncodeRGB8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRG8(const Common::Vec4<u8>& color, u8* bytes) {
bytes[1] = color.r();
bytes[0] = color.g();
}
@ -181,7 +181,7 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB565(const Common::Vec4<u8>& color, u8* bytes) {
const u16_le data =
(Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b());
@ -193,7 +193,7 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGB5A1(const Common::Vec4<u8>& color, u8* bytes) {
const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To5(color.g()) << 6) |
(Convert8To5(color.b()) << 1) | Convert8To1(color.a());
@ -205,7 +205,7 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
* @param color Source color to encode
* @param bytes Destination pointer to store encoded color
*/
inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
inline void EncodeRGBA4(const Common::Vec4<u8>& color, u8* bytes) {
const u16 data = (Convert8To4(color.r()) << 12) | (Convert8To4(color.g()) << 8) |
(Convert8To4(color.b()) << 4) | Convert8To4(color.a());

View File

@ -11,8 +11,8 @@ namespace Common {
template <typename T>
class Quaternion {
public:
Math::Vec3<T> xyz;
T w;
Vec3<T> xyz;
T w{};
Quaternion<decltype(-T{})> Inverse() const {
return {-xyz, w};
@ -38,11 +38,11 @@ public:
};
template <typename T>
auto QuaternionRotate(const Quaternion<T>& q, const Math::Vec3<T>& v) {
auto QuaternionRotate(const Quaternion<T>& q, const Vec3<T>& v) {
return v + 2 * Cross(q.xyz, Cross(q.xyz, v) + v * q.w);
}
inline Quaternion<float> MakeQuaternion(const Math::Vec3<float>& axis, float angle) {
inline Quaternion<float> MakeQuaternion(const Vec3<float>& axis, float angle) {
return {axis * std::sin(angle / 2), std::cos(angle / 2)};
}

View File

@ -33,7 +33,7 @@
#include <cmath>
#include <type_traits>
namespace Math {
namespace Common {
template <typename T>
class Vec2;
@ -702,4 +702,4 @@ constexpr Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) {
return MakeVec(x, yzw[0], yzw[1], yzw[2]);
}
} // namespace Math
} // namespace Common

View File

@ -124,7 +124,7 @@ using AnalogDevice = InputDevice<std::tuple<float, float>>;
* Orientation is determined by right-hand rule.
* Units: deg/sec
*/
using MotionDevice = InputDevice<std::tuple<Math::Vec3<float>, Math::Vec3<float>>>;
using MotionDevice = InputDevice<std::tuple<Common::Vec3<float>, Common::Vec3<float>>>;
/**
* A touch device is an input device that returns a tuple of two floats and a bool. The floats are

View File

@ -179,7 +179,7 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) {
mem->accelerometer.index = next_accelerometer_index;
next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
Math::Vec3<float> accel;
Common::Vec3<float> accel;
std::tie(accel, std::ignore) = motion_device->GetStatus();
accel *= accelerometer_coef;
// TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback
@ -226,7 +226,7 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) {
GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index];
Math::Vec3<float> gyro;
Common::Vec3<float> gyro;
std::tie(std::ignore, gyro) = motion_device->GetStatus();
double stretch = system.perf_stats.GetLastFrameTimeScale();
gyro *= gyroscope_coef * static_cast<float>(stretch);

View File

@ -48,7 +48,7 @@ inline void Read(T& var, const u32 raw_addr) {
var = g_regs[addr / 4];
}
static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
static Common::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
switch (input_format) {
case Regs::PixelFormat::RGBA8:
return Color::DecodeRGBA8(src_pixel);
@ -196,7 +196,7 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
for (u32 y = 0; y < output_height; ++y) {
for (u32 x = 0; x < output_width; ++x) {
Math::Vec4<u8> src_color;
Common::Vec4<u8> src_color;
// Calculate the [x,y] position of the input image
// based on the current output position and the scale
@ -259,15 +259,15 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
const u8* src_pixel = src_pointer + src_offset;
src_color = DecodePixel(config.input_format, src_pixel);
if (config.scaling == config.ScaleX) {
Math::Vec4<u8> pixel =
Common::Vec4<u8> pixel =
DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel);
src_color = ((src_color + pixel) / 2).Cast<u8>();
} else if (config.scaling == config.ScaleXY) {
Math::Vec4<u8> pixel1 =
Common::Vec4<u8> pixel1 =
DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel);
Math::Vec4<u8> pixel2 =
Common::Vec4<u8> pixel2 =
DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel);
Math::Vec4<u8> pixel3 =
Common::Vec4<u8> pixel3 =
DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel);
src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>();
}

View File

@ -110,7 +110,7 @@ static void SendData(const u32* input, ConversionBuffer& buf, int amount_of_data
u8* unit_end = output + buf.transfer_unit;
while (output < unit_end) {
u32 color = *input++;
Math::Vec4<u8> col_vec{(u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha};
Common::Vec4<u8> col_vec{(u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha};
switch (output_format) {
case OutputFormat::RGBA8:

View File

@ -33,12 +33,12 @@ public:
}
void BeginTilt(int x, int y) {
mouse_origin = Math::MakeVec(x, y);
mouse_origin = Common::MakeVec(x, y);
is_tilting = true;
}
void Tilt(int x, int y) {
auto mouse_move = Math::MakeVec(x, y) - mouse_origin;
auto mouse_move = Common::MakeVec(x, y) - mouse_origin;
if (is_tilting) {
std::lock_guard<std::mutex> guard(tilt_mutex);
if (mouse_move.x == 0 && mouse_move.y == 0) {
@ -57,7 +57,7 @@ public:
is_tilting = false;
}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() {
std::lock_guard<std::mutex> guard(status_mutex);
return status;
}
@ -67,10 +67,10 @@ private:
const std::chrono::steady_clock::duration update_duration;
const float sensitivity;
Math::Vec2<int> mouse_origin;
Common::Vec2<int> mouse_origin;
std::mutex tilt_mutex;
Math::Vec2<float> tilt_direction;
Common::Vec2<float> tilt_direction;
float tilt_angle = 0;
float tilt_clamp = 90;
@ -78,7 +78,7 @@ private:
Common::Event shutdown_event;
std::tuple<Math::Vec3<float>, Math::Vec3<float>> status;
std::tuple<Common::Vec3<float>, Common::Vec3<float>> status;
std::mutex status_mutex;
// Note: always keep the thread declaration at the end so that other objects are initialized
@ -87,7 +87,7 @@ private:
void MotionEmuThread() {
auto update_time = std::chrono::steady_clock::now();
Common::Quaternion<float> q = Common::MakeQuaternion(Math::Vec3<float>(), 0);
Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0);
Common::Quaternion<float> old_q;
while (!shutdown_event.WaitUntil(update_time)) {
@ -98,14 +98,14 @@ private:
std::lock_guard<std::mutex> guard(tilt_mutex);
// Find the quaternion describing current 3DS tilting
q = Common::MakeQuaternion(Math::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x),
tilt_angle);
q = Common::MakeQuaternion(
Common::MakeVec(-tilt_direction.y, 0.0f, tilt_direction.x), tilt_angle);
}
auto inv_q = q.Inverse();
// Set the gravity vector in world space
auto gravity = Math::MakeVec(0.0f, -1.0f, 0.0f);
auto gravity = Common::MakeVec(0.0f, -1.0f, 0.0f);
// Find the angular rate vector in world space
auto angular_rate = ((q - old_q) * inv_q).xyz * 2;
@ -133,7 +133,7 @@ public:
device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity, tilt_clamp);
}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const override {
return device->GetStatus();
}

View File

@ -162,8 +162,8 @@ void Client::OnPadData(Response::PadData data) {
// Due to differences between the 3ds and cemuhookudp motion directions, we need to invert
// accel.x and accel.z and also invert pitch and yaw. See
// https://github.com/citra-emu/citra/pull/4049 for more details on gyro/accel
Math::Vec3f accel = Math::MakeVec<float>(-data.accel.x, data.accel.y, -data.accel.z);
Math::Vec3f gyro = Math::MakeVec<float>(-data.gyro.pitch, -data.gyro.yaw, data.gyro.roll);
Common::Vec3f accel = Common::MakeVec<float>(-data.accel.x, data.accel.y, -data.accel.z);
Common::Vec3f gyro = Common::MakeVec<float>(-data.gyro.pitch, -data.gyro.yaw, data.gyro.roll);
{
std::lock_guard<std::mutex> guard(status->update_mutex);
@ -217,8 +217,7 @@ void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 clie
success_callback();
else
failure_callback();
})
.detach();
}).detach();
}
CalibrationConfigurationJob::CalibrationConfigurationJob(
@ -269,8 +268,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
complete_event.Wait();
socket.Stop();
worker_thread.join();
})
.detach();
}).detach();
}
CalibrationConfigurationJob::~CalibrationConfigurationJob() {

View File

@ -31,7 +31,7 @@ struct Version;
struct DeviceStatus {
std::mutex update_mutex;
std::tuple<Math::Vec3<float>, Math::Vec3<float>> motion_status;
std::tuple<Common::Vec3<float>, Common::Vec3<float>> motion_status;
std::tuple<float, float, bool> touch_status;
// calibration data for scaling the device's touch area to 3ds

View File

@ -26,7 +26,7 @@ private:
class UDPMotionDevice final : public Input::MotionDevice {
public:
explicit UDPMotionDevice(std::shared_ptr<DeviceStatus> status_) : status(std::move(status_)) {}
std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const {
std::tuple<Common::Vec3<float>, Common::Vec3<float>> GetStatus() const {
std::lock_guard<std::mutex> guard(status->update_mutex);
return status->motion_status;
}

View File

@ -63,7 +63,7 @@ static void WriteUniformBoolReg(Shader::ShaderSetup& setup, u32 value) {
}
static void WriteUniformIntReg(Shader::ShaderSetup& setup, unsigned index,
const Math::Vec4<u8>& values) {
const Common::Vec4<u8>& values) {
ASSERT(index < setup.uniforms.i.size());
setup.uniforms.i[index] = values;
LOG_TRACE(HW_GPU, "Set {} integer uniform {} to {:02x} {:02x} {:02x} {:02x}",
@ -186,7 +186,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
break;
}
Math::Vec4<float24> attribute;
Common::Vec4<float24> attribute;
// NOTE: The destination component order indeed is "backwards"
attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
@ -447,7 +447,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[0], 0x281));
auto values = regs.gs.int_uniforms[index];
WriteUniformIntReg(g_state.gs, index,
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
Common::Vec4<u8>(values.x, values.y, values.z, values.w));
break;
}
@ -515,7 +515,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
auto values = regs.vs.int_uniforms[index];
WriteUniformIntReg(g_state.vs, index,
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
Common::Vec4<u8>(values.x, values.y, values.z, values.w));
break;
}

View File

@ -76,8 +76,8 @@ private:
const Regs& regs;
Shader::GSUnitState& unit;
Shader::AttributeBuffer attribute_buffer;
Math::Vec4<float24>* buffer_cur;
Math::Vec4<float24>* buffer_end;
Common::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_end;
unsigned int vs_output_num;
};
@ -106,7 +106,7 @@ public:
// The number of vertex input is put to the uniform register
float24 vertex_num = float24::FromFloat32(static_cast<float>(val));
setup.uniforms.f[0] = Math::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num);
setup.uniforms.f[0] = Common::MakeVec(vertex_num, vertex_num, vertex_num, vertex_num);
// The second uniform register and so on are used for receiving input vertices
buffer_cur = setup.uniforms.f + 1;
@ -142,7 +142,7 @@ private:
Shader::ShaderSetup& setup;
unsigned int main_vertex_num;
unsigned int total_vertex_num;
Math::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_cur;
unsigned int vs_output_num;
};
@ -186,9 +186,9 @@ public:
private:
const Regs& regs;
Shader::ShaderSetup& setup;
Math::Vec4<float24>* buffer_begin;
Math::Vec4<float24>* buffer_cur;
Math::Vec4<float24>* buffer_end;
Common::Vec4<float24>* buffer_begin;
Common::Vec4<float24>* buffer_cur;
Common::Vec4<float24>* buffer_end;
unsigned int vs_output_num;
};

View File

@ -56,7 +56,7 @@ struct State {
BitField<16, 8, u32> b;
BitField<24, 8, u32> a;
Math::Vec4<u8> ToVector() const {
Common::Vec4<u8> ToVector() const {
return {static_cast<u8>(r), static_cast<u8>(g), static_cast<u8>(b),
static_cast<u8>(a)};
}
@ -69,8 +69,8 @@ struct State {
BitField<16, 8, s32> b;
BitField<24, 8, s32> a;
Math::Vec4<s32> ToVector() const {
return Math::Vec4<s32>{r, g, b, a} * 2;
Common::Vec4<s32> ToVector() const {
return Common::Vec4<s32>{r, g, b, a} * 2;
}
};

View File

@ -90,10 +90,10 @@ struct LightingRegs {
BitField<10, 10, u32> g;
BitField<20, 10, u32> r;
Math::Vec3f ToVec3f() const {
Common::Vec3f ToVec3f() const {
// These fields are 10 bits wide, however 255 corresponds to 1.0f for each color
// component
return Math::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f);
return Common::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f);
}
};

View File

@ -36,7 +36,7 @@ struct RasterizerRegs {
BitField<0, 1, u32> clip_enable;
BitField<0, 24, u32> clip_coef[4]; // float24
Math::Vec4<float24> GetClipCoef() const {
Common::Vec4<float24> GetClipCoef() const {
return {float24::FromRaw(clip_coef[0]), float24::FromRaw(clip_coef[1]),
float24::FromRaw(clip_coef[2]), float24::FromRaw(clip_coef[3])};
}

View File

@ -224,11 +224,11 @@ void RasterizerOpenGL::SyncEntireState() {
* Fortunately however, the 3DS hardware happens to also use this exact same logic to work around
* these issues, making this basic implementation actually more accurate to the hardware.
*/
static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) {
Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()};
Math::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()};
static bool AreQuaternionsOpposite(Common::Vec4<Pica::float24> qa, Common::Vec4<Pica::float24> qb) {
Common::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()};
Common::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()};
return (Math::Dot(a, b) < 0.f);
return (Common::Dot(a, b) < 0.f);
}
void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0,

View File

@ -431,7 +431,7 @@ static bool FillSurface(const Surface& surface, const u8* fill_data,
Pica::Texture::TextureInfo tex_info{};
tex_info.format = static_cast<Pica::TexturingRegs::TextureFormat>(surface->pixel_format);
Math::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
std::array<GLfloat, 4> color_values = {color.x / 255.f, color.y / 255.f, color.z / 255.f,
color.w / 255.f};

View File

@ -54,18 +54,18 @@ struct DebugData<true> {
LOOP_INT_IN = 0x800,
};
Math::Vec4<float24> src1;
Math::Vec4<float24> src2;
Math::Vec4<float24> src3;
Common::Vec4<float24> src1;
Common::Vec4<float24> src2;
Common::Vec4<float24> src3;
Math::Vec4<float24> dest_in;
Math::Vec4<float24> dest_out;
Common::Vec4<float24> dest_in;
Common::Vec4<float24> dest_out;
s32 address_registers[2];
bool conditional_code[2];
bool cond_bool;
bool cond_cmp[2];
Math::Vec4<u8> loop_int;
Common::Vec4<u8> loop_int;
u32 instruction_offset;
u32 next_instruction;
@ -152,7 +152,7 @@ inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool
}
template <>
inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) {
inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Common::Vec4<u8> value) {
record.loop_int = value;
}

View File

@ -85,7 +85,7 @@ void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input
}
}
static void CopyRegistersToOutput(const Math::Vec4<float24>* regs, u32 mask,
static void CopyRegistersToOutput(const Common::Vec4<float24>* regs, u32 mask,
AttributeBuffer& buffer) {
int output_i = 0;
for (int reg : Common::BitSet<u32>(mask)) {
@ -107,7 +107,7 @@ GSEmitter::~GSEmitter() {
delete handlers;
}
void GSEmitter::Emit(Math::Vec4<float24> (&output_regs)[16]) {
void GSEmitter::Emit(Common::Vec4<float24> (&output_regs)[16]) {
ASSERT(vertex_id < 3);
// TODO: This should be merged with UnitState::WriteOutput somehow
CopyRegistersToOutput(output_regs, output_mask, buffer[vertex_id]);

View File

@ -28,7 +28,7 @@ constexpr unsigned MAX_PROGRAM_CODE_LENGTH = 4096;
constexpr unsigned MAX_SWIZZLE_DATA_LENGTH = 4096;
struct AttributeBuffer {
alignas(16) Math::Vec4<float24> attr[16];
alignas(16) Common::Vec4<float24> attr[16];
};
/// Handler type for receiving vertex outputs from vertex shader or geometry shader
@ -38,16 +38,16 @@ using VertexHandler = std::function<void(const AttributeBuffer&)>;
using WindingSetter = std::function<void()>;
struct OutputVertex {
Math::Vec4<float24> pos;
Math::Vec4<float24> quat;
Math::Vec4<float24> color;
Math::Vec2<float24> tc0;
Math::Vec2<float24> tc1;
Common::Vec4<float24> pos;
Common::Vec4<float24> quat;
Common::Vec4<float24> color;
Common::Vec2<float24> tc0;
Common::Vec2<float24> tc1;
float24 tc0_w;
INSERT_PADDING_WORDS(1);
Math::Vec3<float24> view;
Common::Vec3<float24> view;
INSERT_PADDING_WORDS(1);
Math::Vec2<float24> tc2;
Common::Vec2<float24> tc2;
static void ValidateSemantics(const RasterizerRegs& regs);
static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs,
@ -87,7 +87,7 @@ struct GSEmitter {
GSEmitter();
~GSEmitter();
void Emit(Math::Vec4<float24> (&output_regs)[16]);
void Emit(Common::Vec4<float24> (&output_regs)[16]);
};
static_assert(std::is_standard_layout<GSEmitter>::value, "GSEmitter is not standard layout type");
@ -102,9 +102,9 @@ struct UnitState {
struct Registers {
// The registers are accessed by the shader JIT using SSE instructions, and are therefore
// required to be 16-byte aligned.
alignas(16) Math::Vec4<float24> input[16];
alignas(16) Math::Vec4<float24> temporary[16];
alignas(16) Math::Vec4<float24> output[16];
alignas(16) Common::Vec4<float24> input[16];
alignas(16) Common::Vec4<float24> temporary[16];
alignas(16) Common::Vec4<float24> output[16];
} registers;
static_assert(std::is_pod<Registers>::value, "Structure is not POD");
@ -120,11 +120,11 @@ struct UnitState {
switch (reg.GetRegisterType()) {
case RegisterType::Input:
return offsetof(UnitState, registers.input) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
case RegisterType::Temporary:
return offsetof(UnitState, registers.temporary) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
default:
UNREACHABLE();
@ -136,11 +136,11 @@ struct UnitState {
switch (reg.GetRegisterType()) {
case RegisterType::Output:
return offsetof(UnitState, registers.output) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
case RegisterType::Temporary:
return offsetof(UnitState, registers.temporary) +
reg.GetIndex() * sizeof(Math::Vec4<float24>);
reg.GetIndex() * sizeof(Common::Vec4<float24>);
default:
UNREACHABLE();
@ -175,13 +175,13 @@ struct GSUnitState : public UnitState {
struct Uniforms {
// The float uniforms are accessed by the shader JIT using SSE instructions, and are
// therefore required to be 16-byte aligned.
alignas(16) Math::Vec4<float24> f[96];
alignas(16) Common::Vec4<float24> f[96];
std::array<bool, 16> b;
std::array<Math::Vec4<u8>, 4> i;
std::array<Common::Vec4<u8>, 4> i;
static std::size_t GetFloatUniformOffset(unsigned index) {
return offsetof(Uniforms, f) + index * sizeof(Math::Vec4<float24>);
return offsetof(Uniforms, f) + index * sizeof(Common::Vec4<float24>);
}
static std::size_t GetBoolUniformOffset(unsigned index) {
@ -189,7 +189,7 @@ struct Uniforms {
}
static std::size_t GetIntUniformOffset(unsigned index) {
return offsetof(Uniforms, i) + index * sizeof(Math::Vec4<u8>);
return offsetof(Uniforms, i) + index * sizeof(Common::Vec4<u8>);
}
};

View File

@ -622,10 +622,10 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData
}
case OpCode::Id::LOOP: {
Math::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x,
uniforms.i[instr.flow_control.int_uniform_id].y,
uniforms.i[instr.flow_control.int_uniform_id].z,
uniforms.i[instr.flow_control.int_uniform_id].w);
Common::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x,
uniforms.i[instr.flow_control.int_uniform_id].y,
uniforms.i[instr.flow_control.int_uniform_id].z,
uniforms.i[instr.flow_control.int_uniform_id].w);
state.address_registers[2] = loop_param.y;
Record<DebugDataRecord::LOOP_INT_IN>(debug_data, iteration, loop_param);
@ -688,7 +688,7 @@ DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup,
DebugData<true> debug_data;
// Setup input register table
boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero()));
boost::fill(state.registers.input, Common::Vec4<float24>::AssignToAll(float24::Zero()));
state.LoadInput(config, input);
RunInterpreter(setup, state, debug_data, setup.engine_data.entry_point);
return debug_data;

View File

@ -777,7 +777,7 @@ void JitShader::Compile_JMP(Instruction instr) {
}
}
static void Emit(GSEmitter* emitter, Math::Vec4<float24> (*output)[16]) {
static void Emit(GSEmitter* emitter, Common::Vec4<float24> (*output)[16]) {
emitter->Emit(*output);
}

View File

@ -23,13 +23,15 @@ namespace Pica::Clipper {
struct ClippingEdge {
public:
ClippingEdge(Math::Vec4<float24> coeffs, Math::Vec4<float24> bias = Math::Vec4<float24>(
float24::FromFloat32(0), float24::FromFloat32(0),
float24::FromFloat32(0), float24::FromFloat32(0)))
ClippingEdge(Common::Vec4<float24> coeffs,
Common::Vec4<float24> bias = Common::Vec4<float24>(float24::FromFloat32(0),
float24::FromFloat32(0),
float24::FromFloat32(0),
float24::FromFloat32(0)))
: coeffs(coeffs), bias(bias) {}
bool IsInside(const Vertex& vertex) const {
return Math::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
return Common::Dot(vertex.pos + bias, coeffs) >= float24::FromFloat32(0);
}
bool IsOutSide(const Vertex& vertex) const {
@ -37,8 +39,8 @@ public:
}
Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const {
float24 dp = Math::Dot(v0.pos + bias, coeffs);
float24 dp_prev = Math::Dot(v1.pos + bias, coeffs);
float24 dp = Common::Dot(v0.pos + bias, coeffs);
float24 dp_prev = Common::Dot(v1.pos + bias, coeffs);
float24 factor = dp_prev / (dp_prev - dp);
return Vertex::Lerp(factor, v0, v1);
@ -46,8 +48,8 @@ public:
private:
float24 pos;
Math::Vec4<float24> coeffs;
Math::Vec4<float24> bias;
Common::Vec4<float24> coeffs;
Common::Vec4<float24> bias;
};
static void InitScreenCoordinates(Vertex& vtx) {
@ -95,7 +97,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
static_vector<Vertex, MAX_VERTICES> buffer_b;
auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) {
if (Math::Dot(a, b) < float24::Zero())
if (Common::Dot(a, b) < float24::Zero())
a = a * float24::FromFloat32(-1.0f);
};
@ -114,13 +116,14 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
static const float24 f0 = float24::FromFloat32(0.0);
static const float24 f1 = float24::FromFloat32(1.0);
static const std::array<ClippingEdge, 7> clipping_edges = {{
{Math::MakeVec(-f1, f0, f0, f1)}, // x = +w
{Math::MakeVec(f1, f0, f0, f1)}, // x = -w
{Math::MakeVec(f0, -f1, f0, f1)}, // y = +w
{Math::MakeVec(f0, f1, f0, f1)}, // y = -w
{Math::MakeVec(f0, f0, -f1, f0)}, // z = 0
{Math::MakeVec(f0, f0, f1, f1)}, // z = -w
{Math::MakeVec(f0, f0, f0, f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
{Common::MakeVec(-f1, f0, f0, f1)}, // x = +w
{Common::MakeVec(f1, f0, f0, f1)}, // x = -w
{Common::MakeVec(f0, -f1, f0, f1)}, // y = +w
{Common::MakeVec(f0, f1, f0, f1)}, // y = -w
{Common::MakeVec(f0, f0, -f1, f0)}, // z = 0
{Common::MakeVec(f0, f0, f1, f1)}, // z = -w
{Common::MakeVec(f0, f0, f0, f1),
Common::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
}};
// Simple implementation of the Sutherland-Hodgman clipping algorithm.

View File

@ -18,7 +18,7 @@
namespace Pica::Rasterizer {
void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
void DrawPixel(int x, int y, const Common::Vec4<u8>& color) {
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
@ -61,7 +61,7 @@ void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
}
}
const Math::Vec4<u8> GetPixel(int x, int y) {
const Common::Vec4<u8> GetPixel(int x, int y) {
const auto& framebuffer = g_state.regs.framebuffer.framebuffer;
const PAddr addr = framebuffer.GetColorBufferPhysicalAddress();
@ -257,10 +257,12 @@ u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u
}
}
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation) {
Math::Vec4<int> result;
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
const Common::Vec4<u8>& srcfactor,
const Common::Vec4<u8>& dest,
const Common::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation) {
Common::Vec4<int> result;
auto src_result = (src * srcfactor).Cast<int>();
auto dst_result = (dest * destfactor).Cast<int>();
@ -299,8 +301,8 @@ Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4
UNIMPLEMENTED();
}
return Math::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
return Common::Vec4<u8>(std::clamp(result.r(), 0, 255), std::clamp(result.g(), 0, 255),
std::clamp(result.b(), 0, 255), std::clamp(result.a(), 0, 255));
};
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
@ -359,7 +361,7 @@ u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op) {
// Decode/Encode for shadow map format. It is similar to D24S8 format, but the depth field is in
// big-endian
static const Math::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
static const Common::Vec2<u32> DecodeD24S8Shadow(const u8* bytes) {
return {static_cast<u32>((bytes[0] << 16) | (bytes[1] << 8) | bytes[2]), bytes[3]};
}

View File

@ -10,17 +10,19 @@
namespace Pica::Rasterizer {
void DrawPixel(int x, int y, const Math::Vec4<u8>& color);
const Math::Vec4<u8> GetPixel(int x, int y);
void DrawPixel(int x, int y, const Common::Vec4<u8>& color);
const Common::Vec4<u8> GetPixel(int x, int y);
u32 GetDepth(int x, int y);
u8 GetStencil(int x, int y);
void SetDepth(int x, int y, u32 value);
void SetStencil(int x, int y, u8 value);
u8 PerformStencilAction(FramebufferRegs::StencilAction action, u8 old_stencil, u8 ref);
Math::Vec4<u8> EvaluateBlendEquation(const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor,
const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation);
Common::Vec4<u8> EvaluateBlendEquation(const Common::Vec4<u8>& src,
const Common::Vec4<u8>& srcfactor,
const Common::Vec4<u8>& dest,
const Common::Vec4<u8>& destfactor,
FramebufferRegs::BlendEquation equation);
u8 LogicOp(u8 src, u8 dest, FramebufferRegs::LogicOp op);

View File

@ -20,63 +20,63 @@ static float LookupLightingLut(const Pica::State::Lighting& lighting, std::size_
return lut_value + lut_diff * delta;
}
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
const Math::Vec4<u8> (&texture_color)[4]) {
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
const Common::Vec4<u8> (&texture_color)[4]) {
Math::Vec4<float> shadow;
Common::Vec4<float> shadow;
if (lighting.config0.enable_shadow) {
shadow = texture_color[lighting.config0.shadow_selector].Cast<float>() / 255.0f;
if (lighting.config0.shadow_invert) {
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow;
}
} else {
shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
shadow = Common::MakeVec(1.0f, 1.0f, 1.0f, 1.0f);
}
Math::Vec3<float> surface_normal;
Math::Vec3<float> surface_tangent;
Common::Vec3<float> surface_normal;
Common::Vec3<float> surface_tangent;
if (lighting.config0.bump_mode != LightingRegs::LightingBumpMode::None) {
Math::Vec3<float> perturbation =
Common::Vec3<float> perturbation =
texture_color[lighting.config0.bump_selector].xyz().Cast<float>() / 127.5f -
Math::MakeVec(1.0f, 1.0f, 1.0f);
Common::MakeVec(1.0f, 1.0f, 1.0f);
if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::NormalMap) {
if (!lighting.config0.disable_bump_renorm) {
const float z_square = 1 - perturbation.xy().Length2();
perturbation.z = std::sqrt(std::max(z_square, 0.0f));
}
surface_normal = perturbation;
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
} else if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::TangentMap) {
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = perturbation;
} else {
LOG_ERROR(HW_GPU, "Unknown bump mode {}",
static_cast<u32>(lighting.config0.bump_mode.Value()));
}
} else {
surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f);
surface_normal = Common::MakeVec(0.0f, 0.0f, 1.0f);
surface_tangent = Common::MakeVec(1.0f, 0.0f, 0.0f);
}
// Use the normalized the quaternion when performing the rotation
auto normal = Math::QuaternionRotate(normquat, surface_normal);
auto tangent = Math::QuaternionRotate(normquat, surface_tangent);
auto normal = Common::QuaternionRotate(normquat, surface_normal);
auto tangent = Common::QuaternionRotate(normquat, surface_tangent);
Math::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Math::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Common::Vec4<float> diffuse_sum = {0.0f, 0.0f, 0.0f, 1.0f};
Common::Vec4<float> specular_sum = {0.0f, 0.0f, 0.0f, 1.0f};
for (unsigned light_index = 0; light_index <= lighting.max_light_index; ++light_index) {
unsigned num = lighting.light_enable.GetNum(light_index);
const auto& light_config = lighting.light[num];
Math::Vec3<float> refl_value = {};
Math::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
float16::FromRaw(light_config.y).ToFloat32(),
float16::FromRaw(light_config.z).ToFloat32()};
Math::Vec3<float> light_vector;
Common::Vec3<float> refl_value = {};
Common::Vec3<float> position = {float16::FromRaw(light_config.x).ToFloat32(),
float16::FromRaw(light_config.y).ToFloat32(),
float16::FromRaw(light_config.z).ToFloat32()};
Common::Vec3<float> light_vector;
if (light_config.config.directional)
light_vector = position;
@ -85,8 +85,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
light_vector.Normalize();
Math::Vec3<float> norm_view = view.Normalized();
Math::Vec3<float> half_vector = norm_view + light_vector;
Common::Vec3<float> norm_view = view.Normalized();
Common::Vec3<float> half_vector = norm_view + light_vector;
float dist_atten = 1.0f;
if (!lighting.IsDistAttenDisabled(num)) {
@ -111,33 +111,33 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
switch (input) {
case LightingRegs::LightingLutInput::NH:
result = Math::Dot(normal, half_vector.Normalized());
result = Common::Dot(normal, half_vector.Normalized());
break;
case LightingRegs::LightingLutInput::VH:
result = Math::Dot(norm_view, half_vector.Normalized());
result = Common::Dot(norm_view, half_vector.Normalized());
break;
case LightingRegs::LightingLutInput::NV:
result = Math::Dot(normal, norm_view);
result = Common::Dot(normal, norm_view);
break;
case LightingRegs::LightingLutInput::LN:
result = Math::Dot(light_vector, normal);
result = Common::Dot(light_vector, normal);
break;
case LightingRegs::LightingLutInput::SP: {
Math::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
light_config.spot_z.Value()};
result = Math::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
Common::Vec3<s32> spot_dir{light_config.spot_x.Value(), light_config.spot_y.Value(),
light_config.spot_z.Value()};
result = Common::Dot(light_vector, spot_dir.Cast<float>() / 2047.0f);
break;
}
case LightingRegs::LightingLutInput::CP:
if (lighting.config0.config == LightingRegs::LightingConfig::Config7) {
const Math::Vec3<float> norm_half_vector = half_vector.Normalized();
const Math::Vec3<float> half_vector_proj =
norm_half_vector - normal * Math::Dot(normal, norm_half_vector);
result = Math::Dot(half_vector_proj, tangent);
const Common::Vec3<float> norm_half_vector = half_vector.Normalized();
const Common::Vec3<float> half_vector_proj =
norm_half_vector - normal * Common::Dot(normal, norm_half_vector);
result = Common::Dot(half_vector_proj, tangent);
} else {
result = 0.0f;
}
@ -192,7 +192,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
lighting.lut_scale.d0, LightingRegs::LightingSampler::Distribution0);
}
Math::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
Common::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f();
// If enabled, lookup ReflectRed value, otherwise, 1.0 is used
if (lighting.config1.disable_lut_rr == 0 &&
@ -237,7 +237,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
lighting.lut_scale.d1, LightingRegs::LightingSampler::Distribution1);
}
Math::Vec3<float> specular_1 =
Common::Vec3<float> specular_1 =
d1_lut_value * refl_value * light_config.specular_1.ToVec3f();
// Fresnel
@ -261,7 +261,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
auto dot_product = Math::Dot(light_vector, normal);
auto dot_product = Common::Dot(light_vector, normal);
if (light_config.config.two_sided_diffuse)
dot_product = std::abs(dot_product);
else
@ -297,8 +297,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
diffuse_sum += Math::MakeVec(diffuse, 0.0f);
specular_sum += Math::MakeVec(specular, 0.0f);
diffuse_sum += Common::MakeVec(diffuse, 0.0f);
specular_sum += Common::MakeVec(specular, 0.0f);
}
if (lighting.config0.shadow_alpha) {
@ -314,17 +314,17 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
}
}
diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
diffuse_sum += Common::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f);
auto diffuse = Math::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
auto diffuse = Common::MakeVec<float>(std::clamp(diffuse_sum.x, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.y, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.z, 0.0f, 1.0f) * 255,
std::clamp(diffuse_sum.w, 0.0f, 1.0f) * 255)
.Cast<u8>();
auto specular = Math::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
auto specular = Common::MakeVec<float>(std::clamp(specular_sum.x, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.y, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.z, 0.0f, 1.0f) * 255,
std::clamp(specular_sum.w, 0.0f, 1.0f) * 255)
.Cast<u8>();
return std::make_tuple(diffuse, specular);
}

View File

@ -11,9 +11,9 @@
namespace Pica {
std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(
std::tuple<Common::Vec4<u8>, Common::Vec4<u8>> ComputeFragmentsColors(
const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state,
const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view,
const Math::Vec4<u8> (&texture_color)[4]);
const Common::Quaternion<float>& normquat, const Common::Vec3<float>& view,
const Common::Vec4<u8> (&texture_color)[4]);
} // namespace Pica

View File

@ -63,7 +63,7 @@ static float NoiseCoef(float u, float v, TexturingRegs regs, State::ProcTex stat
const float g3 = NoiseRand2D(x_int + 1, y_int + 1) * (x_frac + y_frac - 2);
const float x_noise = LookupLUT(state.noise_table, x_frac);
const float y_noise = LookupLUT(state.noise_table, y_frac);
return Math::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
return Common::BilinearInterp(g0, g1, g2, g3, x_noise, y_noise);
}
static float GetShiftOffset(float v, ProcTexShift mode, ProcTexClamp clamp_mode) {
@ -154,7 +154,7 @@ float CombineAndMap(float u, float v, ProcTexCombiner combiner,
return LookupLUT(map_table, f);
}
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state) {
u = std::abs(u);
v = std::abs(v);
@ -187,7 +187,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
const u32 offset = regs.proctex_lut_offset.level0;
const u32 width = regs.proctex_lut.width;
const float index = offset + (lut_coord * (width - 1));
Math::Vec4<u8> final_color;
Common::Vec4<u8> final_color;
// TODO(wwylele): implement mipmap
switch (regs.proctex_lut.filter) {
case ProcTexFilter::Linear:
@ -212,7 +212,7 @@ Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex stat
// uses the output of CombineAndMap directly instead.
const float final_alpha =
CombineAndMap(u, v, regs.proctex.alpha_combiner, state.alpha_map_table);
return Math::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
return Common::MakeVec<u8>(final_color.rgb(), static_cast<u8>(final_alpha * 255));
} else {
return final_color;
}

View File

@ -9,6 +9,6 @@
namespace Pica::Rasterizer {
/// Generates procedural texture color for the given coordinates
Math::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
Common::Vec4<u8> ProcTex(float u, float v, TexturingRegs regs, State::ProcTex state);
} // namespace Pica::Rasterizer

View File

@ -64,12 +64,12 @@ private:
*
* @todo define orientation concretely.
*/
static int SignedArea(const Math::Vec2<Fix12P4>& vtx1, const Math::Vec2<Fix12P4>& vtx2,
const Math::Vec2<Fix12P4>& vtx3) {
const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0);
const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0);
static int SignedArea(const Common::Vec2<Fix12P4>& vtx1, const Common::Vec2<Fix12P4>& vtx2,
const Common::Vec2<Fix12P4>& vtx3) {
const auto vec1 = Common::MakeVec(vtx2 - vtx1, 0);
const auto vec2 = Common::MakeVec(vtx3 - vtx1, 0);
// TODO: There is a very small chance this will overflow for sizeof(int) == 4
return Math::Cross(vec1, vec2).z;
return Common::Cross(vec1, vec2).z;
};
/// Convert a 3D vector for cube map coordinates to 2D texture coordinates along with the face name
@ -134,13 +134,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// triangle borders. Is it that the correct solution, though?
return Fix12P4(static_cast<unsigned short>(round(flt.ToFloat32() * 16.0f)));
};
static auto ScreenToRasterizerCoordinates = [](const Math::Vec3<float24>& vec) {
return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
static auto ScreenToRasterizerCoordinates = [](const Common::Vec3<float24>& vec) {
return Common::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)};
};
Math::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
ScreenToRasterizerCoordinates(v1.screenpos),
ScreenToRasterizerCoordinates(v2.screenpos)};
Common::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos),
ScreenToRasterizerCoordinates(v1.screenpos),
ScreenToRasterizerCoordinates(v2.screenpos)};
if (regs.rasterizer.cull_mode == RasterizerRegs::CullMode::KeepAll) {
// Make sure we always end up with a triangle wound counter-clockwise
@ -189,9 +189,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// drawn. Pixels on any other triangle border are drawn. This is implemented with three bias
// values which are added to the barycentric coordinates w0, w1 and w2, respectively.
// NOTE: These are the PSP filling rules. Not sure if the 3DS uses the same ones...
auto IsRightSideOrFlatBottomEdge = [](const Math::Vec2<Fix12P4>& vtx,
const Math::Vec2<Fix12P4>& line1,
const Math::Vec2<Fix12P4>& line2) {
auto IsRightSideOrFlatBottomEdge = [](const Common::Vec2<Fix12P4>& vtx,
const Common::Vec2<Fix12P4>& line1,
const Common::Vec2<Fix12P4>& line2) {
if (line1.y == line2.y) {
// just check if vertex is above us => bottom line parallel to x-axis
return vtx.y < line1.y;
@ -210,7 +210,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
int bias2 =
IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0;
auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
auto w_inverse = Common::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w);
auto textures = regs.texturing.GetTextures();
auto tev_stages = regs.texturing.GetTevStages();
@ -243,11 +243,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
continue;
auto baricentric_coordinates =
Math::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
float24::FromFloat32(static_cast<float>(w1)),
float24::FromFloat32(static_cast<float>(w2)));
Common::MakeVec(float24::FromFloat32(static_cast<float>(w0)),
float24::FromFloat32(static_cast<float>(w1)),
float24::FromFloat32(static_cast<float>(w2)));
float24 interpolated_w_inverse =
float24::FromFloat32(1.0f) / Math::Dot(w_inverse, baricentric_coordinates);
float24::FromFloat32(1.0f) / Common::Dot(w_inverse, baricentric_coordinates);
// interpolated_z = z / w
float interpolated_z_over_w =
@ -288,12 +288,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
//
// The generalization to three vertices is straightforward in baricentric coordinates.
auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) {
auto attr_over_w = Math::MakeVec(attr0, attr1, attr2);
float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates);
auto attr_over_w = Common::MakeVec(attr0, attr1, attr2);
float24 interpolated_attr_over_w =
Common::Dot(attr_over_w, baricentric_coordinates);
return interpolated_attr_over_w * interpolated_w_inverse;
};
Math::Vec4<u8> primary_color{
Common::Vec4<u8> primary_color{
static_cast<u8>(round(
GetInterpolatedAttribute(v0.color.r(), v1.color.r(), v2.color.r()).ToFloat32() *
255)),
@ -308,7 +309,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
255)),
};
Math::Vec2<float24> uv[3];
Common::Vec2<float24> uv[3];
uv[0].u() = GetInterpolatedAttribute(v0.tc0.u(), v1.tc0.u(), v2.tc0.u());
uv[0].v() = GetInterpolatedAttribute(v0.tc0.v(), v1.tc0.v(), v2.tc0.v());
uv[1].u() = GetInterpolatedAttribute(v0.tc1.u(), v1.tc1.u(), v2.tc1.u());
@ -316,7 +317,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
uv[2].u() = GetInterpolatedAttribute(v0.tc2.u(), v1.tc2.u(), v2.tc2.u());
uv[2].v() = GetInterpolatedAttribute(v0.tc2.v(), v1.tc2.v(), v2.tc2.v());
Math::Vec4<u8> texture_color[4]{};
Common::Vec4<u8> texture_color[4]{};
for (int i = 0; i < 3; ++i) {
const auto& texture = textures[i];
if (!texture.enabled)
@ -391,9 +392,10 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
if (use_border_s || use_border_t) {
auto border_color = texture.config.border_color;
texture_color[i] = Math::MakeVec(border_color.r.Value(), border_color.g.Value(),
border_color.b.Value(), border_color.a.Value())
.Cast<u8>();
texture_color[i] =
Common::MakeVec(border_color.r.Value(), border_color.g.Value(),
border_color.b.Value(), border_color.a.Value())
.Cast<u8>();
} else {
// Textures are laid out from bottom to top, hence we invert the t coordinate.
// NOTE: This may not be the right place for the inversion.
@ -442,21 +444,21 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// operations on each of them (e.g. inversion) and then calculate the output color
// with some basic arithmetic. Alpha combiners can be configured separately but work
// analogously.
Math::Vec4<u8> combiner_output;
Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
Math::Vec4<u8> next_combiner_buffer =
Math::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
regs.texturing.tev_combiner_buffer_color.g.Value(),
regs.texturing.tev_combiner_buffer_color.b.Value(),
regs.texturing.tev_combiner_buffer_color.a.Value())
Common::Vec4<u8> combiner_output;
Common::Vec4<u8> combiner_buffer = {0, 0, 0, 0};
Common::Vec4<u8> next_combiner_buffer =
Common::MakeVec(regs.texturing.tev_combiner_buffer_color.r.Value(),
regs.texturing.tev_combiner_buffer_color.g.Value(),
regs.texturing.tev_combiner_buffer_color.b.Value(),
regs.texturing.tev_combiner_buffer_color.a.Value())
.Cast<u8>();
Math::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
Math::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
Common::Vec4<u8> primary_fragment_color = {0, 0, 0, 0};
Common::Vec4<u8> secondary_fragment_color = {0, 0, 0, 0};
if (!g_state.regs.lighting.disable) {
Math::Quaternion<float> normquat =
Math::Quaternion<float>{
Common::Quaternion<float> normquat =
Common::Quaternion<float>{
{GetInterpolatedAttribute(v0.quat.x, v1.quat.x, v2.quat.x).ToFloat32(),
GetInterpolatedAttribute(v0.quat.y, v1.quat.y, v2.quat.y).ToFloat32(),
GetInterpolatedAttribute(v0.quat.z, v1.quat.z, v2.quat.z).ToFloat32()},
@ -464,7 +466,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
}
.Normalized();
Math::Vec3<float> view{
Common::Vec3<float> view{
GetInterpolatedAttribute(v0.view.x, v1.view.x, v2.view.x).ToFloat32(),
GetInterpolatedAttribute(v0.view.y, v1.view.y, v2.view.y).ToFloat32(),
GetInterpolatedAttribute(v0.view.z, v1.view.z, v2.view.z).ToFloat32(),
@ -478,7 +480,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
const auto& tev_stage = tev_stages[tev_stage_index];
using Source = TexturingRegs::TevStageConfig::Source;
auto GetSource = [&](Source source) -> Math::Vec4<u8> {
auto GetSource = [&](Source source) -> Common::Vec4<u8> {
switch (source) {
case Source::PrimaryColor:
return primary_color;
@ -505,8 +507,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
return combiner_buffer;
case Source::Constant:
return Math::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
tev_stage.const_b.Value(), tev_stage.const_a.Value())
return Common::MakeVec(tev_stage.const_r.Value(), tev_stage.const_g.Value(),
tev_stage.const_b.Value(), tev_stage.const_a.Value())
.Cast<u8>();
case Source::Previous:
@ -524,7 +526,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// stage as input. Hence, we currently don't directly write the result to
// combiner_output.rgb(), but instead store it in a temporary variable until
// alpha combining has been done.
Math::Vec3<u8> color_result[3] = {
Common::Vec3<u8> color_result[3] = {
GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)),
GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)),
GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)),
@ -631,10 +633,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
// store the depth etc. Using float for now until we know more
// about Pica datatypes
if (regs.texturing.fog_mode == TexturingRegs::FogMode::Fog) {
const Math::Vec3<u8> fog_color = Math::MakeVec(regs.texturing.fog_color.r.Value(),
regs.texturing.fog_color.g.Value(),
regs.texturing.fog_color.b.Value())
.Cast<u8>();
const Common::Vec3<u8> fog_color =
Common::MakeVec(regs.texturing.fog_color.r.Value(),
regs.texturing.fog_color.g.Value(),
regs.texturing.fog_color.b.Value())
.Cast<u8>();
// Get index into fog LUT
float fog_index;
@ -778,7 +781,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
UpdateStencil(stencil_test.action_depth_pass);
auto dest = GetPixel(x >> 4, y >> 4);
Math::Vec4<u8> blend_output = combiner_output;
Common::Vec4<u8> blend_output = combiner_output;
if (output_merger.alphablend_enable) {
auto params = output_merger.alpha_blending;
@ -787,11 +790,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
FramebufferRegs::BlendFactor factor) -> u8 {
DEBUG_ASSERT(channel < 4);
const Math::Vec4<u8> blend_const =
Math::MakeVec(output_merger.blend_const.r.Value(),
output_merger.blend_const.g.Value(),
output_merger.blend_const.b.Value(),
output_merger.blend_const.a.Value())
const Common::Vec4<u8> blend_const =
Common::MakeVec(output_merger.blend_const.r.Value(),
output_merger.blend_const.g.Value(),
output_merger.blend_const.b.Value(),
output_merger.blend_const.a.Value())
.Cast<u8>();
switch (factor) {
@ -852,15 +855,15 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
return combiner_output[channel];
};
auto srcfactor = Math::MakeVec(LookupFactor(0, params.factor_source_rgb),
LookupFactor(1, params.factor_source_rgb),
LookupFactor(2, params.factor_source_rgb),
LookupFactor(3, params.factor_source_a));
auto srcfactor = Common::MakeVec(LookupFactor(0, params.factor_source_rgb),
LookupFactor(1, params.factor_source_rgb),
LookupFactor(2, params.factor_source_rgb),
LookupFactor(3, params.factor_source_a));
auto dstfactor = Math::MakeVec(LookupFactor(0, params.factor_dest_rgb),
LookupFactor(1, params.factor_dest_rgb),
LookupFactor(2, params.factor_dest_rgb),
LookupFactor(3, params.factor_dest_a));
auto dstfactor = Common::MakeVec(LookupFactor(0, params.factor_dest_rgb),
LookupFactor(1, params.factor_dest_rgb),
LookupFactor(2, params.factor_dest_rgb),
LookupFactor(3, params.factor_dest_a));
blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor,
params.blend_equation_rgb);
@ -869,13 +872,13 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve
.a();
} else {
blend_output =
Math::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
Common::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op),
LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op),
LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op),
LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op));
}
const Math::Vec4<u8> result = {
const Common::Vec4<u8> result = {
output_merger.red_enable ? blend_output.r() : dest.r(),
output_merger.green_enable ? blend_output.g() : dest.g(),
output_merger.blue_enable ? blend_output.b() : dest.b(),

View File

@ -13,7 +13,7 @@ struct Vertex : Shader::OutputVertex {
// Attributes used to store intermediate results
// position after perspective divide
Math::Vec3<float24> screenpos;
Common::Vec3<float24> screenpos;
// Linear interpolation
// factor: 0=this, 1=vtx

View File

@ -51,8 +51,8 @@ int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, uns
}
};
Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
const Math::Vec4<u8>& values) {
Common::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
const Common::Vec4<u8>& values) {
using ColorModifier = TevStageConfig::ColorModifier;
switch (factor) {
@ -60,37 +60,37 @@ Math::Vec3<u8> GetColorModifier(TevStageConfig::ColorModifier factor,
return values.rgb();
case ColorModifier::OneMinusSourceColor:
return (Math::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.rgb()).Cast<u8>();
case ColorModifier::SourceAlpha:
return values.aaa();
case ColorModifier::OneMinusSourceAlpha:
return (Math::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.aaa()).Cast<u8>();
case ColorModifier::SourceRed:
return values.rrr();
case ColorModifier::OneMinusSourceRed:
return (Math::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.rrr()).Cast<u8>();
case ColorModifier::SourceGreen:
return values.ggg();
case ColorModifier::OneMinusSourceGreen:
return (Math::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.ggg()).Cast<u8>();
case ColorModifier::SourceBlue:
return values.bbb();
case ColorModifier::OneMinusSourceBlue:
return (Math::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
return (Common::Vec3<u8>(255, 255, 255) - values.bbb()).Cast<u8>();
}
UNREACHABLE();
};
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>& values) {
u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Common::Vec4<u8>& values) {
using AlphaModifier = TevStageConfig::AlphaModifier;
switch (factor) {
@ -122,7 +122,7 @@ u8 GetAlphaModifier(TevStageConfig::AlphaModifier factor, const Math::Vec4<u8>&
UNREACHABLE();
};
Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> input[3]) {
Common::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Common::Vec3<u8> input[3]) {
using Operation = TevStageConfig::Operation;
switch (op) {
@ -144,7 +144,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
// TODO(bunnei): Verify that the color conversion from (float) 0.5f to
// (byte) 128 is correct
auto result =
input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128);
input[0].Cast<int>() + input[1].Cast<int>() - Common::MakeVec<int>(128, 128, 128);
result.r() = std::clamp<int>(result.r(), 0, 255);
result.g() = std::clamp<int>(result.g(), 0, 255);
result.b() = std::clamp<int>(result.b(), 0, 255);
@ -153,7 +153,7 @@ Math::Vec3<u8> ColorCombine(TevStageConfig::Operation op, const Math::Vec3<u8> i
case Operation::Lerp:
return ((input[0] * input[2] +
input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
input[1] * (Common::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) /
255)
.Cast<u8>();

View File

@ -12,14 +12,14 @@ namespace Pica::Rasterizer {
int GetWrappedTexCoord(TexturingRegs::TextureConfig::WrapMode mode, int val, unsigned size);
Math::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
const Math::Vec4<u8>& values);
Common::Vec3<u8> GetColorModifier(TexturingRegs::TevStageConfig::ColorModifier factor,
const Common::Vec4<u8>& values);
u8 GetAlphaModifier(TexturingRegs::TevStageConfig::AlphaModifier factor,
const Math::Vec4<u8>& values);
const Common::Vec4<u8>& values);
Math::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
const Math::Vec3<u8> input[3]);
Common::Vec3<u8> ColorCombine(TexturingRegs::TevStageConfig::Operation op,
const Common::Vec3<u8> input[3]);
u8 AlphaCombine(TexturingRegs::TevStageConfig::Operation op, const std::array<u8, 3>& input);

View File

@ -69,14 +69,14 @@ union ETC1Tile {
BitField<60, 4, u64> r1;
} separate;
const Math::Vec3<u8> GetRGB(unsigned int x, unsigned int y) const {
const Common::Vec3<u8> GetRGB(unsigned int x, unsigned int y) const {
int texel = 4 * x + y;
if (flip)
std::swap(x, y);
// Lookup base value
Math::Vec3<int> ret;
Common::Vec3<int> ret;
if (differential_mode) {
ret.r() = static_cast<int>(differential.r);
ret.g() = static_cast<int>(differential.g);
@ -119,7 +119,7 @@ union ETC1Tile {
} // anonymous namespace
Math::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y) {
Common::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y) {
ETC1Tile tile{value};
return tile.GetRGB(x, y);
}

View File

@ -9,6 +9,6 @@
namespace Pica::Texture {
Math::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y);
Common::Vec3<u8> SampleETC1Subtile(u64 value, unsigned int x, unsigned int y);
} // namespace Pica::Texture

View File

@ -56,8 +56,8 @@ size_t CalculateTileSize(TextureFormat format) {
}
}
Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
Common::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
// Coordinate in tiles
const unsigned int coarse_x = x / 8;
const unsigned int coarse_y = y / 8;
@ -71,8 +71,8 @@ Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
return LookupTexelInTile(tile, fine_x, fine_y, info, disable_alpha);
}
Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
Common::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha) {
DEBUG_ASSERT(x < 8);
DEBUG_ASSERT(y < 8);
@ -200,8 +200,8 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int
u64_le subtile_data;
memcpy(&subtile_data, subtile_ptr, sizeof(u64));
return Math::MakeVec(SampleETC1Subtile(subtile_data, x, y),
disable_alpha ? (u8)255 : alpha);
return Common::MakeVec(SampleETC1Subtile(subtile_data, x, y),
disable_alpha ? (u8)255 : alpha);
}
default:

View File

@ -40,8 +40,8 @@ struct TextureInfo {
* channel.
* @todo Eventually we should get rid of the disable_alpha parameter.
*/
Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha = false);
Common::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha = false);
/**
* Looks up a texel from a single 8x8 texture tile.
@ -52,7 +52,7 @@ Math::Vec4<u8> LookupTexture(const u8* source, unsigned int x, unsigned int y,
* @param disable_alpha Used for debugging. Sets the result alpha to 255 and either discards the
* real alpha or inserts it in an otherwise unused channel.
*/
Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha);
Common::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int y,
const TextureInfo& info, bool disable_alpha);
} // namespace Pica::Texture