1 #define select_enhancement_buf_ptr(psx_gpu, x) \
\r
2 ((psx_gpu)->enhancement_buf_ptr + \
\r
3 ((psx_gpu)->enhancement_buf_by_x16[(x) / 16] << 20))
\r
6 void setup_sprite_16bpp_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, s32 u,
\r
7 s32 v, s32 width, s32 height, u32 color)
\r
9 u32 left_offset = u & 0x7;
\r
10 u32 width_rounded = width + left_offset + 7;
\r
12 u16 *fb_ptr = psx_gpu->vram_out_ptr + (y * 1024) + (s32)(x - left_offset * 2);
\r
13 u32 right_width = width_rounded & 0x7;
\r
14 u32 block_width = width_rounded / 8;
\r
15 u32 fb_ptr_pitch = (2048 + 16) - (block_width * 16);
\r
17 u32 left_mask_bits = ~(0xFFFF << (left_offset * 2));
\r
18 u32 right_mask_bits = 0xFFFC << (right_width * 2);
\r
20 u32 texture_offset_base = u + (v * 1024);
\r
22 psx_gpu->texture_mask_width | (psx_gpu->texture_mask_height * 1024);
\r
24 u32 blocks_remaining;
\r
25 u32 num_blocks = psx_gpu->num_blocks;
\r
26 block_struct *block = psx_gpu->blocks + num_blocks;
\r
28 u16 *texture_page_ptr = psx_gpu->texture_page_ptr;
\r
29 u16 *texture_block_ptr;
\r
31 texture_offset_base &= ~0x7;
\r
35 if(block_width == 1)
\r
37 u32 mask_bits = left_mask_bits | right_mask_bits;
\r
38 u32 mask_bits_a = mask_bits & 0xFF;
\r
39 u32 mask_bits_b = mask_bits >> 8;
\r
42 vec_8x16u texels_wide;
\r
49 if(num_blocks > MAX_BLOCKS)
\r
51 flush_render_block_buffer(psx_gpu);
\r
53 block = psx_gpu->blocks;
\r
57 texture_page_ptr + (texture_offset_base & texture_mask);
\r
59 load_128b(texels, texture_block_ptr);
\r
61 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
62 block->texels = texels_wide;
\r
63 block->draw_mask_bits = mask_bits_a;
\r
64 block->fb_ptr = fb_ptr;
\r
67 block->texels = texels_wide;
\r
68 block->draw_mask_bits = mask_bits_a;
\r
69 block->fb_ptr = fb_ptr + 1024;
\r
72 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
73 block->texels = texels_wide;
\r
74 block->draw_mask_bits = mask_bits_b;
\r
75 block->fb_ptr = fb_ptr + 8;
\r
78 block->texels = texels_wide;
\r
79 block->draw_mask_bits = mask_bits_b;
\r
80 block->fb_ptr = fb_ptr + 8 + 1024;
\r
83 texture_offset_base += 1024;
\r
87 psx_gpu->num_blocks = num_blocks;
\r
94 u32 left_mask_bits_a = left_mask_bits & 0xFF;
\r
95 u32 left_mask_bits_b = left_mask_bits >> 8;
\r
96 u32 right_mask_bits_a = right_mask_bits & 0xFF;
\r
97 u32 right_mask_bits_b = right_mask_bits >> 8;
\r
100 vec_8x16u texels_wide;
\r
104 blocks_remaining = block_width - 2;
\r
105 num_blocks += block_width * 4;
\r
106 sprite_blocks += block_width * 4;
\r
108 if(num_blocks > MAX_BLOCKS)
\r
110 flush_render_block_buffer(psx_gpu);
\r
111 num_blocks = block_width * 4;
\r
112 block = psx_gpu->blocks;
\r
115 texture_offset = texture_offset_base;
\r
116 texture_offset_base += 1024;
\r
118 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
120 load_128b(texels, texture_block_ptr);
\r
122 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
123 block->texels = texels_wide;
\r
124 block->draw_mask_bits = left_mask_bits_a;
\r
125 block->fb_ptr = fb_ptr;
\r
128 block->texels = texels_wide;
\r
129 block->draw_mask_bits = left_mask_bits_a;
\r
130 block->fb_ptr = fb_ptr + 1024;
\r
133 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
134 block->texels = texels_wide;
\r
135 block->draw_mask_bits = left_mask_bits_b;
\r
136 block->fb_ptr = fb_ptr + 8;
\r
139 block->texels = texels_wide;
\r
140 block->draw_mask_bits = left_mask_bits_b;
\r
141 block->fb_ptr = fb_ptr + 8 + 1024;
\r
144 texture_offset += 8;
\r
147 while(blocks_remaining)
\r
149 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
150 load_128b(texels, texture_block_ptr);
\r
152 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
153 block->texels = texels_wide;
\r
154 block->draw_mask_bits = 0;
\r
155 block->fb_ptr = fb_ptr;
\r
158 block->texels = texels_wide;
\r
159 block->draw_mask_bits = 0;
\r
160 block->fb_ptr = fb_ptr + 1024;
\r
163 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
164 block->texels = texels_wide;
\r
165 block->draw_mask_bits = 0;
\r
166 block->fb_ptr = fb_ptr + 8;
\r
169 block->texels = texels_wide;
\r
170 block->draw_mask_bits = 0;
\r
171 block->fb_ptr = fb_ptr + 8 + 1024;
\r
174 texture_offset += 8;
\r
177 blocks_remaining--;
\r
180 texture_block_ptr = texture_page_ptr + (texture_offset & texture_mask);
\r
181 load_128b(texels, texture_block_ptr);
\r
183 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.low, texels.low);
\r
184 block->texels = texels_wide;
\r
185 block->draw_mask_bits = right_mask_bits_a;
\r
186 block->fb_ptr = fb_ptr;
\r
189 block->texels = texels_wide;
\r
190 block->draw_mask_bits = right_mask_bits_a;
\r
191 block->fb_ptr = fb_ptr + 1024;
\r
194 zip_4x32b(vector_cast(vec_4x32u, texels_wide), texels.high, texels.high);
\r
195 block->texels = texels_wide;
\r
196 block->draw_mask_bits = right_mask_bits_b;
\r
197 block->fb_ptr = fb_ptr + 8;
\r
200 block->texels = texels_wide;
\r
201 block->draw_mask_bits = right_mask_bits_b;
\r
202 block->fb_ptr = fb_ptr + 8 + 1024;
\r
205 fb_ptr += fb_ptr_pitch;
\r
208 psx_gpu->num_blocks = num_blocks;
\r
215 static void setup_sprite_untextured_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y,
\r
216 s32 u, s32 v, s32 width, s32 height, u32 color)
\r
218 setup_sprite_untextured(psx_gpu, x, y, u, v, width * 2, height * 2, color);
\r
221 #define setup_sprite_blocks_switch_textured_4x(texture_mode) \
\r
222 setup_sprite_##texture_mode##_4x \
\r
224 #define setup_sprite_blocks_switch_untextured_4x(texture_mode) \
\r
225 setup_sprite_untextured_4x \
\r
227 #define setup_sprite_blocks_switch_4x(texturing, texture_mode) \
\r
228 setup_sprite_blocks_switch_##texturing##_4x(texture_mode) \
\r
231 #define render_sprite_blocks_switch_block_modulation_4x(texture_mode, \
\r
232 blend_mode, mask_evaluate, shading, dithering, texturing, blending, \
\r
235 setup_sprite_blocks_switch_4x(texturing, texture_mode), \
\r
236 texture_sprite_blocks_switch_##texturing(texture_mode), \
\r
237 shade_blocks_switch(unshaded, texturing, modulation, undithered, blending, \
\r
239 blend_blocks_switch(texturing, blending, blend_mode, mask_evaluate) \
\r
242 #define render_sprite_blocks_switch_block_blending_4x(texture_mode, \
\r
243 blend_mode, mask_evaluate, shading, dithering, texturing, blending) \
\r
244 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \
\r
245 mask_evaluate, shading, dithering, texturing, blending, modulated), \
\r
246 render_sprite_blocks_switch_block_modulation_4x(texture_mode, blend_mode, \
\r
247 mask_evaluate, shading, dithering, texturing, blending, unmodulated) \
\r
249 #define render_sprite_blocks_switch_block_texturing_4x(texture_mode, \
\r
250 blend_mode, mask_evaluate, shading, dithering, texturing) \
\r
251 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \
\r
252 mask_evaluate, shading, dithering, texturing, unblended), \
\r
253 render_sprite_blocks_switch_block_blending_4x(texture_mode, blend_mode, \
\r
254 mask_evaluate, shading, dithering, texturing, blended) \
\r
256 #define render_sprite_blocks_switch_block_dithering_4x(texture_mode, \
\r
257 blend_mode, mask_evaluate, shading, dithering) \
\r
258 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \
\r
259 mask_evaluate, shading, dithering, untextured), \
\r
260 render_sprite_blocks_switch_block_texturing_4x(texture_mode, blend_mode, \
\r
261 mask_evaluate, shading, dithering, textured) \
\r
263 #define render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
264 mask_evaluate, shading) \
\r
265 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \
\r
266 mask_evaluate, shading, undithered), \
\r
267 render_sprite_blocks_switch_block_dithering_4x(texture_mode, blend_mode, \
\r
268 mask_evaluate, shading, dithered) \
\r
270 #define render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, \
\r
271 blend_mode, mask_evaluate) \
\r
272 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
273 mask_evaluate, unshaded), \
\r
274 render_sprite_blocks_switch_block_shading_4x(texture_mode, blend_mode, \
\r
275 mask_evaluate, shaded) \
\r
277 #define render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, \
\r
279 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\r
281 render_sprite_blocks_switch_block_mask_evaluate_4x(texture_mode, blend_mode, \
\r
284 #define render_sprite_blocks_switch_block_texture_mode_4x(texture_mode) \
\r
285 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, average), \
\r
286 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add), \
\r
287 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, subtract), \
\r
288 render_sprite_blocks_switch_block_blend_mode_4x(texture_mode, add_fourth) \
\r
290 #define render_sprite_blocks_switch_block_4x() \
\r
291 render_sprite_blocks_switch_block_texture_mode_4x(4bpp), \
\r
292 render_sprite_blocks_switch_block_texture_mode_4x(8bpp), \
\r
293 render_sprite_blocks_switch_block_texture_mode_4x(16bpp), \
\r
294 render_sprite_blocks_switch_block_texture_mode_4x(4bpp) \
\r
297 render_block_handler_struct render_sprite_block_handlers_4x[] =
\r
299 render_sprite_blocks_switch_block_4x()
\r
303 void render_sprite_4x(psx_gpu_struct *psx_gpu, s32 x, s32 y, u32 u, u32 v,
\r
304 s32 width, s32 height, u32 flags, u32 color)
\r
306 s32 x_right = x + width - 1;
\r
307 s32 y_bottom = y + height - 1;
\r
313 if(x < psx_gpu->viewport_start_x)
\r
315 u32 clip = psx_gpu->viewport_start_x - x;
\r
321 if(y < psx_gpu->viewport_start_y)
\r
323 s32 clip = psx_gpu->viewport_start_y - y;
\r
329 if(x_right > psx_gpu->viewport_end_x)
\r
330 width -= x_right - psx_gpu->viewport_end_x;
\r
332 if(y_bottom > psx_gpu->viewport_end_y)
\r
333 height -= y_bottom - psx_gpu->viewport_end_y;
\r
335 if((width <= 0) || (height <= 0))
\r
338 psx_gpu->vram_out_ptr = select_enhancement_buf_ptr(psx_gpu, x);
\r
344 span_pixels += width * height;
\r
348 u32 render_state = flags &
\r
349 (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND |
\r
350 RENDER_FLAGS_TEXTURE_MAP);
\r
352 (psx_gpu->render_state_base & ~RENDER_STATE_DITHER);
\r
354 if((psx_gpu->render_state != render_state) ||
\r
355 (psx_gpu->primitive_type != PRIMITIVE_TYPE_SPRITE))
\r
357 psx_gpu->render_state = render_state;
\r
358 flush_render_block_buffer(psx_gpu);
\r
364 psx_gpu->primitive_type = PRIMITIVE_TYPE_SPRITE;
\r
368 if(psx_gpu->triangle_color != color)
\r
370 flush_render_block_buffer(psx_gpu);
\r
371 psx_gpu->triangle_color = color;
\r
374 if(color == 0x808080)
\r
375 render_state |= RENDER_FLAGS_MODULATE_TEXELS;
\r
377 render_block_handler_struct *render_block_handler =
\r
378 &(render_sprite_block_handlers_4x[render_state]);
\r
379 psx_gpu->render_block_handler = render_block_handler;
\r
381 ((setup_sprite_function_type *)render_block_handler->setup_blocks)
\r
382 (psx_gpu, x, y, u, v, width, height, color);
\r