mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #4666 from FearlessTobi/port-2167
Port yuzu-emu/yuzu#2167: "common: Move Quaternion, Rectangle, Vec2, Vec3, and Vec4 into the Common namespace"
This commit is contained in:
		
						commit
						9560060f04
					
				
					 46 changed files with 390 additions and 380 deletions
				
			
		|  | @ -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())); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
|                 } | ||||
|  |  | |||
|  | @ -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()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
| #include <cstdlib> | ||||
| #include <type_traits> | ||||
| 
 | ||||
| namespace MathUtil { | ||||
| namespace Common { | ||||
| 
 | ||||
| constexpr float PI = 3.14159265f; | ||||
| 
 | ||||
|  | @ -41,4 +41,4 @@ struct Rectangle { | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| } // namespace MathUtil
 | ||||
| } // namespace Common
 | ||||
|  |  | |||
|  | @ -6,13 +6,13 @@ | |||
| 
 | ||||
| #include "common/vector_math.h" | ||||
| 
 | ||||
| namespace Math { | ||||
| 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,12 +38,12 @@ 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)}; | ||||
| } | ||||
| 
 | ||||
| } // namespace Math
 | ||||
| } // namespace Common
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -22,12 +22,12 @@ u16 FramebufferLayout::GetScalingRatio() const { | |||
| 
 | ||||
| // Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
 | ||||
| template <class T> | ||||
| static MathUtil::Rectangle<T> maxRectangle(MathUtil::Rectangle<T> window_area, | ||||
|                                            float screen_aspect_ratio) { | ||||
| static Common::Rectangle<T> maxRectangle(Common::Rectangle<T> window_area, | ||||
|                                          float screen_aspect_ratio) { | ||||
|     float scale = std::min(static_cast<float>(window_area.GetWidth()), | ||||
|                            window_area.GetHeight() / screen_aspect_ratio); | ||||
|     return MathUtil::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)), | ||||
|                                   static_cast<T>(std::round(scale * screen_aspect_ratio))}; | ||||
|     return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)), | ||||
|                                 static_cast<T>(std::round(scale * screen_aspect_ratio))}; | ||||
| } | ||||
| 
 | ||||
| FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool swapped) { | ||||
|  | @ -36,10 +36,10 @@ FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool swapp | |||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
|     // Default layout gives equal screen sizes to the top and bottom screen
 | ||||
|     MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2}; | ||||
|     MathUtil::Rectangle<unsigned> top_screen = | ||||
|     Common::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2}; | ||||
|     Common::Rectangle<unsigned> top_screen = | ||||
|         maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|     MathUtil::Rectangle<unsigned> bot_screen = | ||||
|     Common::Rectangle<unsigned> bot_screen = | ||||
|         maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
| 
 | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|  | @ -77,10 +77,10 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool swappe | |||
|     // so just calculate them both even if the other isn't showing.
 | ||||
|     FramebufferLayout res{width, height, !swapped, swapped, {}, {}}; | ||||
| 
 | ||||
|     MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     MathUtil::Rectangle<unsigned> top_screen = | ||||
|     Common::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<unsigned> top_screen = | ||||
|         maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|     MathUtil::Rectangle<unsigned> bot_screen = | ||||
|     Common::Rectangle<unsigned> bot_screen = | ||||
|         maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
| 
 | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|  | @ -116,13 +116,12 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped | |||
|     float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; | ||||
|     float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO; | ||||
| 
 | ||||
|     MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     MathUtil::Rectangle<unsigned> total_rect = | ||||
|     Common::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<unsigned> total_rect = | ||||
|         maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     MathUtil::Rectangle<unsigned> large_screen = | ||||
|         maxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     MathUtil::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f); | ||||
|     MathUtil::Rectangle<unsigned> small_screen = | ||||
|     Common::Rectangle<unsigned> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     Common::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f); | ||||
|     Common::Rectangle<unsigned> small_screen = | ||||
|         maxRectangle(fourth_size_rect, small_screen_aspect_ratio); | ||||
| 
 | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|  | @ -149,13 +148,13 @@ FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool swapped) | |||
|     const float emulation_aspect_ratio = static_cast<float>(Core::kScreenTopHeight) / | ||||
|                                          (Core::kScreenTopWidth + Core::kScreenBottomWidth); | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<unsigned> screen_window_area{0, 0, width, height}; | ||||
|     // Find largest Rectangle that can fit in the window size with the given aspect ratio
 | ||||
|     MathUtil::Rectangle<unsigned> screen_rect = | ||||
|     Common::Rectangle<unsigned> screen_rect = | ||||
|         maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     // Find sizes of top and bottom screen
 | ||||
|     MathUtil::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); | ||||
|     MathUtil::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<unsigned> bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO); | ||||
| 
 | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         // Apply borders to the left and right sides of the window.
 | ||||
|  | @ -180,10 +179,10 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) { | |||
| 
 | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
| 
 | ||||
|     MathUtil::Rectangle<unsigned> top_screen{ | ||||
|     Common::Rectangle<unsigned> top_screen{ | ||||
|         Settings::values.custom_top_left, Settings::values.custom_top_top, | ||||
|         Settings::values.custom_top_right, Settings::values.custom_top_bottom}; | ||||
|     MathUtil::Rectangle<unsigned> bot_screen{ | ||||
|     Common::Rectangle<unsigned> bot_screen{ | ||||
|         Settings::values.custom_bottom_left, Settings::values.custom_bottom_top, | ||||
|         Settings::values.custom_bottom_right, Settings::values.custom_bottom_bottom}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ struct FramebufferLayout { | |||
|     unsigned height; | ||||
|     bool top_screen_enabled; | ||||
|     bool bottom_screen_enabled; | ||||
|     MathUtil::Rectangle<unsigned> top_screen; | ||||
|     MathUtil::Rectangle<unsigned> bottom_screen; | ||||
|     Common::Rectangle<unsigned> top_screen; | ||||
|     Common::Rectangle<unsigned> bottom_screen; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Returns the ration of pixel size of the top screen, compared to the native size of the 3DS | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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>(); | ||||
|             } | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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) { | ||||
|  | @ -46,7 +46,7 @@ public: | |||
|             } else { | ||||
|                 tilt_direction = mouse_move.Cast<float>(); | ||||
|                 tilt_angle = std::clamp(tilt_direction.Normalize() * sensitivity, 0.0f, | ||||
|                                         MathUtil::PI * this->tilt_clamp / 180.0f); | ||||
|                                         Common::PI * this->tilt_clamp / 180.0f); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -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,8 +87,8 @@ private: | |||
| 
 | ||||
|     void MotionEmuThread() { | ||||
|         auto update_time = std::chrono::steady_clock::now(); | ||||
|         Math::Quaternion<float> q = MakeQuaternion(Math::Vec3<float>(), 0); | ||||
|         Math::Quaternion<float> old_q; | ||||
|         Common::Quaternion<float> q = Common::MakeQuaternion(Common::Vec3<float>(), 0); | ||||
|         Common::Quaternion<float> old_q; | ||||
| 
 | ||||
|         while (!shutdown_event.WaitUntil(update_time)) { | ||||
|             update_time += update_duration; | ||||
|  | @ -98,18 +98,18 @@ private: | |||
|                 std::lock_guard<std::mutex> guard(tilt_mutex); | ||||
| 
 | ||||
|                 // Find the quaternion describing current 3DS tilting
 | ||||
|                 q = 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; | ||||
|             angular_rate *= 1000 / update_millisecond / MathUtil::PI * 180; | ||||
|             angular_rate *= 1000 / update_millisecond / Common::PI * 180; | ||||
| 
 | ||||
|             // Transform the two vectors from world space to 3DS space
 | ||||
|             gravity = QuaternionRotate(inv_q, gravity); | ||||
|  | @ -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(); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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])}; | ||||
|     } | ||||
|  |  | |||
|  | @ -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, | ||||
|  | @ -522,7 +522,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|         (write_depth_fb || regs.framebuffer.output_merger.depth_test_enable != 0 || | ||||
|          (has_stencil && state.stencil.test_enabled)); | ||||
| 
 | ||||
|     MathUtil::Rectangle<s32> viewport_rect_unscaled{ | ||||
|     Common::Rectangle<s32> viewport_rect_unscaled{ | ||||
|         // These registers hold half-width and half-height, so must be multiplied by 2
 | ||||
|         regs.rasterizer.viewport_corner.x,  // left
 | ||||
|         regs.rasterizer.viewport_corner.y + // top
 | ||||
|  | @ -536,7 +536,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
| 
 | ||||
|     Surface color_surface; | ||||
|     Surface depth_surface; | ||||
|     MathUtil::Rectangle<u32> surfaces_rect; | ||||
|     Common::Rectangle<u32> surfaces_rect; | ||||
|     std::tie(color_surface, depth_surface, surfaces_rect) = | ||||
|         res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect_unscaled); | ||||
| 
 | ||||
|  | @ -544,7 +544,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                               ? color_surface->res_scale | ||||
|                               : (depth_surface == nullptr ? 1u : depth_surface->res_scale); | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> draw_rect{ | ||||
|     Common::Rectangle<u32> draw_rect{ | ||||
|         static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + | ||||
|                                              viewport_rect_unscaled.left * res_scale, | ||||
|                                          surfaces_rect.left, surfaces_rect.right)), // Left
 | ||||
|  | @ -841,9 +841,9 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|     } | ||||
| 
 | ||||
|     // Mark framebuffer surfaces as dirty
 | ||||
|     MathUtil::Rectangle<u32> draw_rect_unscaled{ | ||||
|         draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale, | ||||
|         draw_rect.bottom / res_scale}; | ||||
|     Common::Rectangle<u32> draw_rect_unscaled{draw_rect.left / res_scale, draw_rect.top / res_scale, | ||||
|                                               draw_rect.right / res_scale, | ||||
|                                               draw_rect.bottom / res_scale}; | ||||
| 
 | ||||
|     if (color_surface != nullptr && write_color_fb) { | ||||
|         auto interval = color_surface->GetSubRectInterval(draw_rect_unscaled); | ||||
|  | @ -1392,7 +1392,7 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe | |||
|     dst_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.output_format); | ||||
|     dst_params.UpdateParams(); | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> src_rect; | ||||
|     Common::Rectangle<u32> src_rect; | ||||
|     Surface src_surface; | ||||
|     std::tie(src_surface, src_rect) = | ||||
|         res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true); | ||||
|  | @ -1401,7 +1401,7 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe | |||
| 
 | ||||
|     dst_params.res_scale = src_surface->res_scale; | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> dst_rect; | ||||
|     Common::Rectangle<u32> dst_rect; | ||||
|     Surface dst_surface; | ||||
|     std::tie(dst_surface, dst_rect) = | ||||
|         res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, false); | ||||
|  | @ -1461,7 +1461,7 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon | |||
|     src_params.size = ((src_params.height - 1) * src_params.stride) + src_params.width; | ||||
|     src_params.end = src_params.addr + src_params.size; | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> src_rect; | ||||
|     Common::Rectangle<u32> src_rect; | ||||
|     Surface src_surface; | ||||
|     std::tie(src_surface, src_rect) = res_cache.GetTexCopySurface(src_params); | ||||
|     if (src_surface == nullptr) { | ||||
|  | @ -1486,7 +1486,7 @@ bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon | |||
| 
 | ||||
|     // Since we are going to invalidate the gap if there is one, we will have to load it first
 | ||||
|     const bool load_gap = output_gap != 0; | ||||
|     MathUtil::Rectangle<u32> dst_rect; | ||||
|     Common::Rectangle<u32> dst_rect; | ||||
|     Surface dst_surface; | ||||
|     std::tie(dst_surface, dst_rect) = | ||||
|         res_cache.GetSurfaceSubRect(dst_params, ScaleMatch::Upscale, load_gap); | ||||
|  | @ -1532,7 +1532,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con | |||
|     src_params.pixel_format = SurfaceParams::PixelFormatFromGPUPixelFormat(config.color_format); | ||||
|     src_params.UpdateParams(); | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> src_rect; | ||||
|     Common::Rectangle<u32> src_rect; | ||||
|     Surface src_surface; | ||||
|     std::tie(src_surface, src_rect) = | ||||
|         res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true); | ||||
|  | @ -1544,7 +1544,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con | |||
|     u32 scaled_width = src_surface->GetScaledWidth(); | ||||
|     u32 scaled_height = src_surface->GetScaledHeight(); | ||||
| 
 | ||||
|     screen_info.display_texcoords = MathUtil::Rectangle<float>( | ||||
|     screen_info.display_texcoords = Common::Rectangle<float>( | ||||
|         (float)src_rect.bottom / (float)scaled_height, (float)src_rect.left / (float)scaled_width, | ||||
|         (float)src_rect.top / (float)scaled_height, (float)src_rect.right / (float)scaled_width); | ||||
| 
 | ||||
|  |  | |||
|  | @ -347,8 +347,8 @@ static void AllocateTextureCube(GLuint texture, const FormatTuple& format_tuple, | |||
|     cur_state.Apply(); | ||||
| } | ||||
| 
 | ||||
| static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex, | ||||
|                          const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type, | ||||
| static bool BlitTextures(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex, | ||||
|                          const Common::Rectangle<u32>& dst_rect, SurfaceType type, | ||||
|                          GLuint read_fb_handle, GLuint draw_fb_handle) { | ||||
|     OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
|  | @ -407,7 +407,7 @@ static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rec | |||
| } | ||||
| 
 | ||||
| static bool FillSurface(const Surface& surface, const u8* fill_data, | ||||
|                         const MathUtil::Rectangle<u32>& fill_rect, GLuint draw_fb_handle) { | ||||
|                         const Common::Rectangle<u32>& fill_rect, GLuint draw_fb_handle) { | ||||
|     OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
| 
 | ||||
|  | @ -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}; | ||||
|  | @ -511,7 +511,7 @@ SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { | |||
|     return params; | ||||
| } | ||||
| 
 | ||||
| SurfaceInterval SurfaceParams::GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const { | ||||
| SurfaceInterval SurfaceParams::GetSubRectInterval(Common::Rectangle<u32> unscaled_rect) const { | ||||
|     if (unscaled_rect.GetHeight() == 0 || unscaled_rect.GetWidth() == 0) { | ||||
|         return {}; | ||||
|     } | ||||
|  | @ -534,24 +534,24 @@ SurfaceInterval SurfaceParams::GetSubRectInterval(MathUtil::Rectangle<u32> unsca | |||
|     return {addr + BytesInPixels(pixel_offset), addr + BytesInPixels(pixel_offset + pixels)}; | ||||
| } | ||||
| 
 | ||||
| MathUtil::Rectangle<u32> SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const { | ||||
| Common::Rectangle<u32> SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const { | ||||
|     const u32 begin_pixel_index = PixelsInBytes(sub_surface.addr - addr); | ||||
| 
 | ||||
|     if (is_tiled) { | ||||
|         const int x0 = (begin_pixel_index % (stride * 8)) / 8; | ||||
|         const int y0 = (begin_pixel_index / (stride * 8)) * 8; | ||||
|         // Top to bottom
 | ||||
|         return MathUtil::Rectangle<u32>(x0, height - y0, x0 + sub_surface.width, | ||||
|                                         height - (y0 + sub_surface.height)); | ||||
|         return Common::Rectangle<u32>(x0, height - y0, x0 + sub_surface.width, | ||||
|                                       height - (y0 + sub_surface.height)); | ||||
|     } | ||||
| 
 | ||||
|     const int x0 = begin_pixel_index % stride; | ||||
|     const int y0 = begin_pixel_index / stride; | ||||
|     // Bottom to top
 | ||||
|     return MathUtil::Rectangle<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0); | ||||
|     return Common::Rectangle<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0); | ||||
| } | ||||
| 
 | ||||
| MathUtil::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const { | ||||
| Common::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const { | ||||
|     auto rect = GetSubRect(sub_surface); | ||||
|     rect.left = rect.left * res_scale; | ||||
|     rect.right = rect.right * res_scale; | ||||
|  | @ -819,7 +819,7 @@ void CachedSurface::FlushGLBuffer(PAddr flush_start, PAddr flush_end) { | |||
| } | ||||
| 
 | ||||
| MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); | ||||
| void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
| void CachedSurface::UploadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|                                     GLuint draw_fb_handle) { | ||||
|     if (type == SurfaceType::Fill) | ||||
|         return; | ||||
|  | @ -883,7 +883,7 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||
| } | ||||
| 
 | ||||
| MICROPROFILE_DEFINE(OpenGL_TextureDL, "OpenGL", "Texture Download", MP_RGB(128, 192, 64)); | ||||
| void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
| void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|                                       GLuint draw_fb_handle) { | ||||
|     if (type == SurfaceType::Fill) | ||||
|         return; | ||||
|  | @ -918,7 +918,7 @@ void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLui | |||
|         OGLTexture unscaled_tex; | ||||
|         unscaled_tex.Create(); | ||||
| 
 | ||||
|         MathUtil::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0}; | ||||
|         Common::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0}; | ||||
|         AllocateSurfaceTexture(unscaled_tex.handle, tuple, rect.GetWidth(), rect.GetHeight()); | ||||
|         BlitTextures(texture.handle, scaled_rect, unscaled_tex.handle, unscaled_tex_rect, type, | ||||
|                      read_fb_handle, draw_fb_handle); | ||||
|  | @ -1122,9 +1122,9 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { | |||
| 
 | ||||
| MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64)); | ||||
| bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface, | ||||
|                                          const MathUtil::Rectangle<u32>& src_rect, | ||||
|                                          const Common::Rectangle<u32>& src_rect, | ||||
|                                          const Surface& dst_surface, | ||||
|                                          const MathUtil::Rectangle<u32>& dst_rect) { | ||||
|                                          const Common::Rectangle<u32>& dst_rect) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_BlitSurface); | ||||
| 
 | ||||
|     if (!SurfaceParams::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) | ||||
|  | @ -1138,9 +1138,9 @@ bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface, | |||
| } | ||||
| 
 | ||||
| void RasterizerCacheOpenGL::ConvertD24S8toABGR(GLuint src_tex, | ||||
|                                                const MathUtil::Rectangle<u32>& src_rect, | ||||
|                                                const Common::Rectangle<u32>& src_rect, | ||||
|                                                GLuint dst_tex, | ||||
|                                                const MathUtil::Rectangle<u32>& dst_rect) { | ||||
|                                                const Common::Rectangle<u32>& dst_rect) { | ||||
|     OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     SCOPE_EXIT({ prev_state.Apply(); }); | ||||
| 
 | ||||
|  | @ -1247,7 +1247,7 @@ SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& | |||
|                                                            ScaleMatch match_res_scale, | ||||
|                                                            bool load_if_create) { | ||||
|     if (params.addr == 0 || params.height * params.width == 0) { | ||||
|         return std::make_tuple(nullptr, MathUtil::Rectangle<u32>{}); | ||||
|         return std::make_tuple(nullptr, Common::Rectangle<u32>{}); | ||||
|     } | ||||
| 
 | ||||
|     // Attempt to find encompassing surface
 | ||||
|  | @ -1340,7 +1340,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Pica::Texture::TextureInf | |||
| 
 | ||||
|     if (info.width % 8 != 0 || info.height % 8 != 0) { | ||||
|         Surface src_surface; | ||||
|         MathUtil::Rectangle<u32> rect; | ||||
|         Common::Rectangle<u32> rect; | ||||
|         std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true); | ||||
| 
 | ||||
|         params.res_scale = src_surface->res_scale; | ||||
|  | @ -1447,7 +1447,7 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube | |||
| } | ||||
| 
 | ||||
| SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | ||||
|     bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport_rect) { | ||||
|     bool using_color_fb, bool using_depth_fb, const Common::Rectangle<s32>& viewport_rect) { | ||||
|     const auto& regs = Pica::g_state.regs; | ||||
|     const auto& config = regs.framebuffer.framebuffer; | ||||
| 
 | ||||
|  | @ -1461,7 +1461,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
|         texture_cube_cache.clear(); | ||||
|     } | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> viewport_clamped{ | ||||
|     Common::Rectangle<u32> viewport_clamped{ | ||||
|         static_cast<u32>(std::clamp(viewport_rect.left, 0, static_cast<s32>(config.GetWidth()))), | ||||
|         static_cast<u32>(std::clamp(viewport_rect.top, 0, static_cast<s32>(config.GetHeight()))), | ||||
|         static_cast<u32>(std::clamp(viewport_rect.right, 0, static_cast<s32>(config.GetWidth()))), | ||||
|  | @ -1495,19 +1495,19 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
|         using_depth_fb = false; | ||||
|     } | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> color_rect{}; | ||||
|     Common::Rectangle<u32> color_rect{}; | ||||
|     Surface color_surface = nullptr; | ||||
|     if (using_color_fb) | ||||
|         std::tie(color_surface, color_rect) = | ||||
|             GetSurfaceSubRect(color_params, ScaleMatch::Exact, false); | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> depth_rect{}; | ||||
|     Common::Rectangle<u32> depth_rect{}; | ||||
|     Surface depth_surface = nullptr; | ||||
|     if (using_depth_fb) | ||||
|         std::tie(depth_surface, depth_rect) = | ||||
|             GetSurfaceSubRect(depth_params, ScaleMatch::Exact, false); | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> fb_rect{}; | ||||
|     Common::Rectangle<u32> fb_rect{}; | ||||
|     if (color_surface != nullptr && depth_surface != nullptr) { | ||||
|         fb_rect = color_rect; | ||||
|         // Color and Depth surfaces must have the same dimensions and offsets
 | ||||
|  | @ -1560,7 +1560,7 @@ Surface RasterizerCacheOpenGL::GetFillSurface(const GPU::Regs::MemoryFillConfig& | |||
| } | ||||
| 
 | ||||
| SurfaceRect_Tuple RasterizerCacheOpenGL::GetTexCopySurface(const SurfaceParams& params) { | ||||
|     MathUtil::Rectangle<u32> rect{}; | ||||
|     Common::Rectangle<u32> rect{}; | ||||
| 
 | ||||
|     Surface match_surface = FindMatch<MatchFlags::TexCopy | MatchFlags::Invalid>( | ||||
|         surface_cache, params, ScaleMatch::Ignore); | ||||
|  |  | |||
|  | @ -88,8 +88,8 @@ static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval | |||
|                   std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(), | ||||
|               "incorrect interval types"); | ||||
| 
 | ||||
| using SurfaceRect_Tuple = std::tuple<Surface, MathUtil::Rectangle<u32>>; | ||||
| using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>; | ||||
| using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>; | ||||
| using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>; | ||||
| 
 | ||||
| using PageMap = boost::icl::interval_map<u32, int>; | ||||
| 
 | ||||
|  | @ -250,7 +250,7 @@ struct SurfaceParams { | |||
|     // Returns the outer rectangle containing "interval"
 | ||||
|     SurfaceParams FromInterval(SurfaceInterval interval) const; | ||||
| 
 | ||||
|     SurfaceInterval GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const; | ||||
|     SurfaceInterval GetSubRectInterval(Common::Rectangle<u32> unscaled_rect) const; | ||||
| 
 | ||||
|     // Returns the region of the biggest valid rectange within interval
 | ||||
|     SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; | ||||
|  | @ -263,11 +263,11 @@ struct SurfaceParams { | |||
|         return height * res_scale; | ||||
|     } | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> GetRect() const { | ||||
|     Common::Rectangle<u32> GetRect() const { | ||||
|         return {0, height, width, 0}; | ||||
|     } | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> GetScaledRect() const { | ||||
|     Common::Rectangle<u32> GetScaledRect() const { | ||||
|         return {0, GetScaledHeight(), GetScaledWidth(), 0}; | ||||
|     } | ||||
| 
 | ||||
|  | @ -284,8 +284,8 @@ struct SurfaceParams { | |||
|     bool CanExpand(const SurfaceParams& expanded_surface) const; | ||||
|     bool CanTexCopy(const SurfaceParams& texcopy_params) const; | ||||
| 
 | ||||
|     MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const; | ||||
|     MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const; | ||||
|     Common::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const; | ||||
|     Common::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const; | ||||
| 
 | ||||
|     PAddr addr = 0; | ||||
|     PAddr end = 0; | ||||
|  | @ -373,9 +373,9 @@ struct CachedSurface : SurfaceParams, std::enable_shared_from_this<CachedSurface | |||
|     void FlushGLBuffer(PAddr flush_start, PAddr flush_end); | ||||
| 
 | ||||
|     // Upload/Download data in gl_buffer in/to this surface's texture
 | ||||
|     void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|     void UploadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|                          GLuint draw_fb_handle); | ||||
|     void DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|     void DownloadGLTexture(const Common::Rectangle<u32>& rect, GLuint read_fb_handle, | ||||
|                            GLuint draw_fb_handle); | ||||
| 
 | ||||
|     std::shared_ptr<SurfaceWatcher> CreateWatcher() { | ||||
|  | @ -413,11 +413,11 @@ public: | |||
|     ~RasterizerCacheOpenGL(); | ||||
| 
 | ||||
|     /// Blit one surface's texture to another
 | ||||
|     bool BlitSurfaces(const Surface& src_surface, const MathUtil::Rectangle<u32>& src_rect, | ||||
|                       const Surface& dst_surface, const MathUtil::Rectangle<u32>& dst_rect); | ||||
|     bool BlitSurfaces(const Surface& src_surface, const Common::Rectangle<u32>& src_rect, | ||||
|                       const Surface& dst_surface, const Common::Rectangle<u32>& dst_rect); | ||||
| 
 | ||||
|     void ConvertD24S8toABGR(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, | ||||
|                             GLuint dst_tex, const MathUtil::Rectangle<u32>& dst_rect); | ||||
|     void ConvertD24S8toABGR(GLuint src_tex, const Common::Rectangle<u32>& src_rect, GLuint dst_tex, | ||||
|                             const Common::Rectangle<u32>& dst_rect); | ||||
| 
 | ||||
|     /// Copy one surface's region to another
 | ||||
|     void CopySurface(const Surface& src_surface, const Surface& dst_surface, | ||||
|  | @ -441,7 +441,7 @@ public: | |||
| 
 | ||||
|     /// Get the color and depth surfaces based on the framebuffer configuration
 | ||||
|     SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, | ||||
|                                                     const MathUtil::Rectangle<s32>& viewport_rect); | ||||
|                                                     const Common::Rectangle<s32>& viewport_rect); | ||||
| 
 | ||||
|     /// Get a surface that matches the fill config
 | ||||
|     Surface GetFillSurface(const GPU::Regs::MemoryFillConfig& config); | ||||
|  |  | |||
|  | @ -221,7 +221,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram | |||
|                                          static_cast<u32>(pixel_stride), screen_info)) { | ||||
|         // Reset the screen info's display texture to its own permanent texture
 | ||||
|         screen_info.display_texture = screen_info.texture.resource.handle; | ||||
|         screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); | ||||
|         screen_info.display_texcoords = Common::Rectangle<float>(0.f, 0.f, 1.f, 1.f); | ||||
| 
 | ||||
|         Memory::RasterizerFlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height); | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ struct TextureInfo { | |||
| /// Structure used for storing information about the display target for each 3DS screen
 | ||||
| struct ScreenInfo { | ||||
|     GLuint display_texture; | ||||
|     MathUtil::Rectangle<float> display_texcoords; | ||||
|     Common::Rectangle<float> display_texcoords; | ||||
|     TextureInfo texture; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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,8 @@ 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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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]); | ||||
|  |  | |||
|  | @ -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>); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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]}; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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(), | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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>(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue