2 void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u,
\r
3 s32 v, s32 width, s32 height, u32 color)
\r
5 u32 left_offset = u & 0x7;
\r
6 u32 width_rounded = width + left_offset + 7;
\r
8 u16 *fb_ptr = psx_gpu->vram_out_ptr + (y * 1024) + (s32)(x - left_offset * 2);
\r
9 u32 right_width = width_rounded & 0x7;
\r
10 u32 block_width = width_rounded / 8;
\r
11 u32 fb_ptr_pitch = (2048 + 16) - (block_width * 16);
\r
13 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));
\r
14 u32 right_mask_bits = 0xFFFC << (right_width * 2);
\r
16 u32 texture_offset_base = u + (v * 1024);
\r
18 psx_gpu->texture_mask_width | (psx_gpu->texture_mask_height * 1024);
\r
20 u32 blocks_remaining;
\r
21 u32 num_blocks = psx_gpu->num_blocks;
\r
22 block_struct *block = psx_gpu->blocks + num_blocks;
\r
24 u16 *texture_page_ptr = psx_gpu->texture_page_ptr;
\r
25 u16 *texture_block_ptr;
\r
27 texture_offset_base &= ~0x7;
\r
31 if(block_width == 1)
\r
33 u32 mask_bits = left_mask_bits | right_mask_bits;
\r
34 u32 mask_bits_a = mask_bits & 0xFF;
\r
35 u32 mask_bits_b = mask_bits >> 8;
\r
38 vec_8x16u texels_wide;
\r
45 if(num_blocks > MAX_BLOCKS)
\r
47 flush_render_block_buffer(psx_gpu);
\r
49 block = psx_gpu->blocks;
\r
53 texture_page_ptr + (texture_offset_base & texture_mask);
\r
55 load_128b(texels, texture_block_ptr);
\r
57 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
58 block->texels = texels_wide;
\r
59 block->draw_mask_bits = mask_bits_a;
\r
60 block->fb_ptr = fb_ptr;
\r
63 block->texels = texels_wide;
\r
64 block->draw_mask_bits = mask_bits_a;
\r
65 block->fb_ptr = fb_ptr + 1024;
\r
68 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
69 block->texels = texels_wide;
\r
70 block->draw_mask_bits = mask_bits_b;
\r
71 block->fb_ptr = fb_ptr + 8;
\r
74 block->texels = texels_wide;
\r
75 block->draw_mask_bits = mask_bits_b;
\r
76 block->fb_ptr = fb_ptr + 8 + 1024;
\r
79 texture_offset_base += 1024;
\r
83 psx_gpu->num_blocks = num_blocks;
\r
90 u32 left_mask_bits_a = left_mask_bits & 0xFF;
\r
91 u32 left_mask_bits_b = left_mask_bits >> 8;
\r
92 u32 right_mask_bits_a = right_mask_bits & 0xFF;
\r
93 u32 right_mask_bits_b = right_mask_bits >> 8;
\r
96 vec_8x16u texels_wide;
\r
100 blocks_remaining = block_width - 2;
\r
101 num_blocks += block_width * 4;
\r
102 sprite_blocks += block_width * 4;
\r
104 if(num_blocks > MAX_BLOCKS)
\r
106 flush_render_block_buffer(psx_gpu);
\r
107 num_blocks = block_width * 4;
\r
108 block = psx_gpu->blocks;
\r
111 texture_offset = texture_offset_base;
\r
112 texture_offset_base += 1024;
\r
114 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
116 load_128b(texels, texture_block_ptr);
\r
118 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
119 block->texels = texels_wide;
\r
120 block->draw_mask_bits = left_mask_bits_a;
\r
121 block->fb_ptr = fb_ptr;
\r
124 block->texels = texels_wide;
\r
125 block->draw_mask_bits = left_mask_bits_a;
\r
126 block->fb_ptr = fb_ptr + 1024;
\r
129 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
130 block->texels = texels_wide;
\r
131 block->draw_mask_bits = left_mask_bits_b;
\r
132 block->fb_ptr = fb_ptr + 8;
\r
135 block->texels = texels_wide;
\r
136 block->draw_mask_bits = left_mask_bits_b;
\r
137 block->fb_ptr = fb_ptr + 8 + 1024;
\r
140 texture_offset += 8;
\r
143 while(blocks_remaining)
\r
145 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
146 load_128b(texels, texture_block_ptr);
\r
148 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
149 block->texels = texels_wide;
\r
150 block->draw_mask_bits = 0;
\r
151 block->fb_ptr = fb_ptr;
\r
154 block->texels = texels_wide;
\r
155 block->draw_mask_bits = 0;
\r
156 block->fb_ptr = fb_ptr + 1024;
\r
159 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
160 block->texels = texels_wide;
\r
161 block->draw_mask_bits = 0;
\r
162 block->fb_ptr = fb_ptr + 8;
\r
165 block->texels = texels_wide;
\r
166 block->draw_mask_bits = 0;
\r
167 block->fb_ptr = fb_ptr + 8 + 1024;
\r
170 texture_offset += 8;
\r
173 blocks_remaining--;
\r
176 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
177 load_128b(texels, texture_block_ptr);
\r
179 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
180 block->texels = texels_wide;
\r
181 block->draw_mask_bits = right_mask_bits_a;
\r
182 block->fb_ptr = fb_ptr;
\r
185 block->texels = texels_wide;
\r
186 block->draw_mask_bits = right_mask_bits_a;
\r
187 block->fb_ptr = fb_ptr + 1024;
\r
190 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
191 block->texels = texels_wide;
\r
192 block->draw_mask_bits = right_mask_bits_b;
\r
193 block->fb_ptr = fb_ptr + 8;
\r
196 block->texels = texels_wide;
\r
197 block->draw_mask_bits = right_mask_bits_b;
\r
198 block->fb_ptr = fb_ptr + 8 + 1024;
\r
201 fb_ptr += fb_ptr_pitch;
\r
204 psx_gpu->num_blocks = num_blocks;
\r
211 static void setup_sprite_untextured_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y,
\r
212 s32 u, s32 v, s32 width, s32 height, u32 color)
\r
214 setup_sprite_untextured(psx_gpu, x, y, u, v, width * 2, height * 2, color);
\r
217 #define setup_sprite_blocks_switch_textured_4x(texture_mode) \
\r
218 setup_sprite_##texture_mode##_4x \
\r
220 #define setup_sprite_blocks_switch_untextured_4x(texture_mode) \
\r
221 setup_sprite_untextured_4x \
\r
223 #define setup_sprite_blocks_switch_4x(texturing, texture_mode) \
\r
224 setup_sprite_blocks_switch_##texturing##_4x(texture_mode) \
\r
227 #define render_sprite_blocks_switch_block_modulation_4x(texture_mode, \
\r
228 blend_mode, mask_evaluate, shading, dithering, texturing, blending, \
\r
231 setup_sprite_blocks_switch_4x(texturing, texture_mode), \
\r
232 texture_sprite_blocks_switch_##texturing(texture_mode), \
\r
233 shade_blocks_switch(unshaded, texturing, modulation, undithered, blending, \
\r
235 blend_blocks_switch(texturing, blending, blend_mode, mask_evaluate) \
\r
238 #define render_sprite_blocks_switch_block_blending_4x(texture_mode, \
\r
239 blend_mode, mask_evaluate, shading, dithering, texturing, blending) \
\r
240 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \
\r
241 mask_evaluate, shading, dithering, texturing, blending, modulated), \
\r
242 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \
\r
243 mask_evaluate, shading, dithering, texturing, blending, unmodulated) \
\r
245 #define render_sprite_blocks_switch_block_texturing_4x(texture_mode, \
\r
246 blend_mode, mask_evaluate, shading, dithering, texturing) \
\r
247 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \
\r
248 mask_evaluate, shading, dithering, texturing, unblended), \
\r
249 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \
\r
250 mask_evaluate, shading, dithering, texturing, blended) \
\r
252 #define render_sprite_blocks_switch_block_dithering_4x(texture_mode, \
\r
253 blend_mode, mask_evaluate, shading, dithering) \
\r
254 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \
\r
255 mask_evaluate, shading, dithering, untextured), \
\r
256 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \
\r
257 mask_evaluate, shading, dithering, textured) \
\r
259 #define render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
260 mask_evaluate, shading) \
\r
261 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \
\r
262 mask_evaluate, shading, undithered), \
\r
263 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \
\r
264 mask_evaluate, shading, dithered) \
\r
266 #define render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, \
\r
267 blend_mode, mask_evaluate) \
\r
268 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
269 mask_evaluate, unshaded), \
\r
270 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
271 mask_evaluate, shaded) \
\r
273 #define render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, \
\r
275 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\r
277 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\r
280 #define render_sprite_blocks_switch_block_texture_mode_4x(texture_mode) \
\r
281 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, average), \
\r
282 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add), \
\r
283 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, subtract), \
\r
284 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add_fourth) \
\r
286 #define render_sprite_blocks_switch_block_4x() \
\r
287 render_sprite_blocks_switch_block_texture_mode_4x(4bpp), \
\r
288 render_sprite_blocks_switch_block_texture_mode_4x(8bpp), \
\r
289 render_sprite_blocks_switch_block_texture_mode_4x(16bpp), \
\r
290 render_sprite_blocks_switch_block_texture_mode_4x(4bpp) \
\r
293 render_block_handler_struct render_sprite_block_handlers_4x[] =
\r
295 render_sprite_blocks_switch_block_4x()
\r
299 void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
\r
300 s32 width, s32 height, u32 flags, u32 color)
\r
302 s32 x_right = x + width - 1;
\r
303 s32 y_bottom = y + height - 1;
\r
309 if(x < psx_gpu->viewport_start_x)
\r
311 u32 clip = psx_gpu->viewport_start_x - x;
\r
317 if(y < psx_gpu->viewport_start_y)
\r
319 s32 clip = psx_gpu->viewport_start_y - y;
\r
325 if(x_right > psx_gpu->viewport_end_x)
\r
326 width -= x_right - psx_gpu->viewport_end_x;
\r
328 if(y_bottom > psx_gpu->viewport_end_y)
\r
329 height -= y_bottom - psx_gpu->viewport_end_y;
\r
331 if((width <= 0) || (height <= 0))
\r
338 span_pixels += width * height;
\r
342 u32 render_state = flags &
\r
343 (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND |
\r
344 RENDER_FLAGS_TEXTURE_MAP);
\r
346 (psx_gpu->render_state_base & ~RENDER_STATE_DITHER);
\r
348 if((psx_gpu->render_state != render_state) ||
\r
349 (psx_gpu->primitive_type != PRIMITIVE_TYPE_SPRITE))
\r
351 psx_gpu->render_state = render_state;
\r
352 flush_render_block_buffer(psx_gpu);
\r
358 psx_gpu->primitive_type = PRIMITIVE_TYPE_SPRITE;
\r
362 if(psx_gpu->triangle_color != color)
\r
364 flush_render_block_buffer(psx_gpu);
\r
365 psx_gpu->triangle_color = color;
\r
368 if(color == 0x808080)
\r
369 render_state |= RENDER_FLAGS_MODULATE_TEXELS;
\r
371 render_block_handler_struct *render_block_handler =
\r
372 &(render_sprite_block_handlers_4x[render_state]);
\r
373 psx_gpu->render_block_handler = render_block_handler;
\r
375 ((setup_sprite_function_type *)render_block_handler->setup_blocks)
\r
376 (psx_gpu, x, y, u, v, width, height, color);
\r