Atlas - SDL_render_ops.cpp

Home / ext / SDL / src / render / ngage Lines: 1 | Size: 11901 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2026 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#include "SDL_render_ops.hpp" 24#include <3dtypes.h> 25 26void ApplyColorMod(void *dest, void *source, int pitch, int width, int height, SDL_FColor color) 27{ 28 TUint16 *src_pixels = static_cast<TUint16 *>(source); 29 TUint16 *dst_pixels = static_cast<TUint16 *>(dest); 30 31 // Fast path: no color modulation (white color). 32 if (color.r == 1.0f && color.g == 1.0f && color.b == 1.0f) { 33 if (dest != source) { 34 for (int y = 0; y < height; ++y) { 35 TUint16 *src_row = src_pixels + (y * pitch / 2); 36 TUint16 *dst_row = dst_pixels + (y * pitch / 2); 37 for (int x = 0; x < width; ++x) { 38 dst_row[x] = src_row[x]; 39 } 40 } 41 } 42 return; 43 } 44 45 TFixed rf = Real2Fix(color.r); 46 TFixed gf = Real2Fix(color.g); 47 TFixed bf = Real2Fix(color.b); 48 49 int pitch_offset = pitch / 2; 50 51 for (int y = 0; y < height; ++y) { 52 int row_offset = y * pitch_offset; 53 for (int x = 0; x < width; ++x) { 54 int idx = row_offset + x; 55 TUint16 pixel = src_pixels[idx]; 56 TUint8 r = (pixel & 0xF800) >> 8; 57 TUint8 g = (pixel & 0x07E0) >> 3; 58 TUint8 b = (pixel & 0x001F) << 3; 59 r = FixMul(r, rf); 60 g = FixMul(g, gf); 61 b = FixMul(b, bf); 62 dst_pixels[idx] = (r << 8) | (g << 3) | (b >> 3); 63 } 64 } 65} 66 67void ApplyFlip(void *dest, void *source, int pitch, int width, int height, SDL_FlipMode flip) 68{ 69 TUint16 *src_pixels = static_cast<TUint16 *>(source); 70 TUint16 *dst_pixels = static_cast<TUint16 *>(dest); 71 72 // Fast path: no flip. 73 if (flip == SDL_FLIP_NONE) { 74 if (dest != source) { 75 for (int y = 0; y < height; ++y) { 76 TUint16 *src_row = src_pixels + (y * pitch / 2); 77 TUint16 *dst_row = dst_pixels + (y * pitch / 2); 78 for (int x = 0; x < width; ++x) { 79 dst_row[x] = src_row[x]; 80 } 81 } 82 } 83 return; 84 } 85 86 int pitch_offset = pitch / 2; 87 88 // Fast path: horizontal flip only. 89 if (flip == SDL_FLIP_HORIZONTAL) { 90 for (int y = 0; y < height; ++y) { 91 int dst_row_offset = y * pitch_offset; 92 int src_row_offset = y * pitch_offset; 93 int width_minus_1 = width - 1; 94 for (int x = 0; x < width; ++x) { 95 dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; 96 } 97 } 98 return; 99 } 100 101 // Fast path: vertical flip only. 102 if (flip == SDL_FLIP_VERTICAL) { 103 int height_minus_1 = height - 1; 104 for (int y = 0; y < height; ++y) { 105 int dst_row_offset = y * pitch_offset; 106 int src_row_offset = (height_minus_1 - y) * pitch_offset; 107 for (int x = 0; x < width; ++x) { 108 dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + x]; 109 } 110 } 111 return; 112 } 113 114 // Both horizontal and vertical flip 115 int width_minus_1 = width - 1; 116 int height_minus_1 = height - 1; 117 for (int y = 0; y < height; ++y) { 118 int dst_row_offset = y * pitch_offset; 119 int src_row_offset = (height_minus_1 - y) * pitch_offset; 120 for (int x = 0; x < width; ++x) { 121 dst_pixels[dst_row_offset + x] = src_pixels[src_row_offset + (width_minus_1 - x)]; 122 } 123 } 124} 125 126void ApplyRotation(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed angle) 127{ 128 TUint16 *src_pixels = static_cast<TUint16 *>(source); 129 TUint16 *dst_pixels = static_cast<TUint16 *>(dest); 130 131 // Fast path: no rotation. 132 if (angle == 0) { 133 if (dest != source) { 134 int pitch_offset = pitch / 2; 135 for (int y = 0; y < height; ++y) { 136 TUint16 *src_row = src_pixels + (y * pitch_offset); 137 TUint16 *dst_row = dst_pixels + (y * pitch_offset); 138 for (int x = 0; x < width; ++x) { 139 dst_row[x] = src_row[x]; 140 } 141 } 142 } 143 return; 144 } 145 146 // Fast paths for 90-degree rotations 147 TFixed angle_90 = Int2Fix(90); 148 TFixed angle_180 = Int2Fix(180); 149 TFixed angle_270 = Int2Fix(270); 150 TFixed angle_360 = Int2Fix(360); 151 152 // Normalize angle to 0-360 range 153 TFixed normalized_angle = angle; 154 while (normalized_angle < 0) { 155 normalized_angle += angle_360; 156 } 157 while (normalized_angle >= angle_360) { 158 normalized_angle -= angle_360; 159 } 160 161 int pitch_offset = pitch / 2; 162 163 // Fast path: 90-degree rotation (clockwise). 164 if (normalized_angle == angle_90) { 165 TFixed center_x_int = Fix2Int(center_x); 166 TFixed center_y_int = Fix2Int(center_y); 167 for (int y = 0; y < height; ++y) { 168 for (int x = 0; x < width; ++x) { 169 // Translate to origin. 170 int tx = x - center_x_int; 171 int ty = y - center_y_int; 172 // Rotate 90 degrees clockwise: (x, y) -> (y, -x). 173 int rx = ty; 174 int ry = -tx; 175 // Translate back. 176 int src_x = rx + center_x_int; 177 int src_y = ry + center_y_int; 178 if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { 179 dst_pixels[y * pitch_offset + x] = src_pixels[src_y * pitch_offset + src_x]; 180 } else { 181 dst_pixels[y * pitch_offset + x] = 0; 182 } 183 } 184 } 185 return; 186 } 187 188 // Fast path: 180-degree rotation. 189 if (normalized_angle == angle_180) { 190 TFixed center_x_int = Fix2Int(center_x); 191 TFixed center_y_int = Fix2Int(center_y); 192 for (int y = 0; y < height; ++y) { 193 int dst_row_offset = y * pitch_offset; 194 for (int x = 0; x < width; ++x) { 195 // Translate to origin 196 int tx = x - center_x_int; 197 int ty = y - center_y_int; 198 // Rotate 180 degrees: (x, y) -> (-x, -y) 199 int rx = -tx; 200 int ry = -ty; 201 // Translate back 202 int src_x = rx + center_x_int; 203 int src_y = ry + center_y_int; 204 if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { 205 dst_pixels[dst_row_offset + x] = src_pixels[src_y * pitch_offset + src_x]; 206 } else { 207 dst_pixels[dst_row_offset + x] = 0; 208 } 209 } 210 } 211 return; 212 } 213 214 // Fast path: 270-degree rotation (clockwise). 215 if (normalized_angle == angle_270) { 216 TFixed center_x_int = Fix2Int(center_x); 217 TFixed center_y_int = Fix2Int(center_y); 218 for (int y = 0; y < height; ++y) { 219 for (int x = 0; x < width; ++x) { 220 // Translate to origin. 221 int tx = x - center_x_int; 222 int ty = y - center_y_int; 223 // Rotate 270 degrees clockwise (or 90 counter-clockwise): (x, y) -> (-y, x). 224 int rx = -ty; 225 int ry = tx; 226 // Translate back. 227 int src_x = rx + center_x_int; 228 int src_y = ry + center_y_int; 229 if (src_x >= 0 && src_x < width && src_y >= 0 && src_y < height) { 230 dst_pixels[y * pitch_offset + x] = src_pixels[src_y * pitch_offset + src_x]; 231 } else { 232 dst_pixels[y * pitch_offset + x] = 0; 233 } 234 } 235 } 236 return; 237 } 238 239 TFixed cos_angle = 0; 240 TFixed sin_angle = 0; 241 FixSinCos(angle, sin_angle, cos_angle); 242 243 // Pre-calculate the translation of center to origin. 244 TFixed neg_center_x = -center_x; 245 TFixed neg_center_y = -center_y; 246 247 for (int y = 0; y < height; ++y) { 248 int dst_row_offset = y * pitch_offset; 249 TFixed y_fixed = Int2Fix(y) + neg_center_y; 250 251 // Pre-calculate these values for the entire row. 252 TFixed cos_mul_ty = FixMul(y_fixed, cos_angle); 253 TFixed sin_mul_ty = FixMul(y_fixed, sin_angle); 254 255 // Starting position for the row (x=0). 256 // rotated_x = cos(angle) * (0 - center_x) + sin(angle) * (y - center_y) + center_x 257 // rotated_y = cos(angle) * (y - center_y) - sin(angle) * (0 - center_x) + center_y 258 TFixed rotated_x = sin_mul_ty + center_x + FixMul(neg_center_x, cos_angle); 259 TFixed rotated_y = cos_mul_ty + center_y - FixMul(neg_center_x, sin_angle); 260 261 for (int x = 0; x < width; ++x) { 262 // Convert to integer coordinates. 263 int final_x = Fix2Int(rotated_x); 264 int final_y = Fix2Int(rotated_y); 265 266 // Check bounds and copy pixel. 267 if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { 268 dst_pixels[dst_row_offset + x] = src_pixels[final_y * pitch_offset + final_x]; 269 } else { 270 dst_pixels[dst_row_offset + x] = 0; 271 } 272 273 // Increment to next pixel (add rotation matrix column). 274 rotated_x += cos_angle; 275 rotated_y -= sin_angle; 276 } 277 } 278} 279 280void ApplyScale(void *dest, void *source, int pitch, int width, int height, TFixed center_x, TFixed center_y, TFixed scale_x, TFixed scale_y) 281{ 282 TUint16 *src_pixels = static_cast<TUint16 *>(source); 283 TUint16 *dst_pixels = static_cast<TUint16 *>(dest); 284 285 TFixed one_fixed = Int2Fix(1); 286 287 // Fast path: no scaling (1.0x scale). 288 if (scale_x == one_fixed && scale_y == one_fixed) { 289 if (dest != source) { 290 for (int y = 0; y < height; ++y) { 291 TUint16 *src_row = src_pixels + (y * pitch / 2); 292 TUint16 *dst_row = dst_pixels + (y * pitch / 2); 293 for (int x = 0; x < width; ++x) { 294 dst_row[x] = src_row[x]; 295 } 296 } 297 } 298 return; 299 } 300 301 int pitch_offset = pitch / 2; 302 303 for (int y = 0; y < height; ++y) { 304 int dst_row_offset = y * pitch_offset; 305 TFixed y_fixed = Int2Fix(y); 306 TFixed translated_y = y_fixed - center_y; 307 TFixed scaled_y = FixDiv(translated_y, scale_y); 308 309 for (int x = 0; x < width; ++x) { 310 // Translate point to origin. 311 TFixed translated_x = Int2Fix(x) - center_x; 312 313 // Scale point. 314 TFixed scaled_x = FixDiv(translated_x, scale_x); 315 316 // Translate point back. 317 int final_x = Fix2Int(scaled_x + center_x); 318 int final_y = Fix2Int(scaled_y + center_y); 319 320 // Check bounds. 321 if (final_x >= 0 && final_x < width && final_y >= 0 && final_y < height) { 322 dst_pixels[dst_row_offset + x] = src_pixels[final_y * pitch_offset + final_x]; 323 } else { 324 dst_pixels[dst_row_offset + x] = 0; 325 } 326 } 327 } 328} 329
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.