X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fgpu_neon%2Fpsx_gpu%2Fpsx_gpu_parse.c;h=920c6388381a07554b088e862ef620af7658586f;hp=98f2d8538af5532a47793cac9f6575f00259061c;hb=c8eaa363acbafb84840b8d29b532ae1225d6d61c;hpb=75e28f62b2a50044b58075d63d207409e0148409 diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c index 98f2d853..920c6388 100644 --- a/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c +++ b/plugins/gpu_neon/psx_gpu/psx_gpu_parse.c @@ -16,6 +16,7 @@ #include "common.h" +#ifndef command_lengths const u8 command_lengths[256] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00 @@ -24,7 +25,7 @@ const u8 command_lengths[256] = 5, 5, 5, 5, 8, 8, 8, 8, 7, 7, 7, 7, 11, 11, 11, 11, // 30 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, // 40 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 50 - 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, // 60 + 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, // 60 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, // 70 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90 @@ -35,64 +36,57 @@ const u8 command_lengths[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // f0 }; +#endif void update_texture_ptr(psx_gpu_struct *psx_gpu) { + u8 *texture_base; u8 *texture_ptr; switch((psx_gpu->render_state_base >> 8) & 0x3) { default: case TEXTURE_MODE_4BPP: -#ifdef TEXTURE_CACHE_4BPP - texture_ptr = psx_gpu->texture_4bpp_cache[psx_gpu->current_texture_page]; + texture_base = psx_gpu->texture_4bpp_cache[psx_gpu->current_texture_page]; + + texture_ptr = texture_base; texture_ptr += psx_gpu->texture_window_x & 0xF; texture_ptr += (psx_gpu->texture_window_y & 0xF) << 4; texture_ptr += (psx_gpu->texture_window_x >> 4) << 8; texture_ptr += (psx_gpu->texture_window_y >> 4) << 12; -#else - texture_ptr = (u8 *)(psx_gpu->vram_ptr); - texture_ptr += (psx_gpu->current_texture_page & 0xF) * 128; - texture_ptr += ((psx_gpu->current_texture_page >> 4) * 256) * 2048; - texture_ptr += psx_gpu->texture_window_x / 2; - texture_ptr += (psx_gpu->texture_window_y) * 2048; -#endif break; case TEXTURE_MODE_8BPP: -#ifdef TEXTURE_CACHE_8BPP if(psx_gpu->current_texture_page & 0x1) { - texture_ptr = + texture_base = psx_gpu->texture_8bpp_odd_cache[psx_gpu->current_texture_page >> 1]; } else { - texture_ptr = + texture_base = psx_gpu->texture_8bpp_even_cache[psx_gpu->current_texture_page >> 1]; } + texture_ptr = texture_base; + texture_ptr += psx_gpu->texture_window_x & 0xF; texture_ptr += (psx_gpu->texture_window_y & 0xF) << 4; texture_ptr += (psx_gpu->texture_window_x >> 4) << 8; texture_ptr += (psx_gpu->texture_window_y >> 4) << 12; -#else - texture_ptr = (u8 *)(psx_gpu->vram_ptr); - texture_ptr += (psx_gpu->current_texture_page & 0xF) * 128; - texture_ptr += ((psx_gpu->current_texture_page >> 4) * 256) * 2048; - texture_ptr += psx_gpu->texture_window_x; - texture_ptr += (psx_gpu->texture_window_y) * 2048; -#endif break; case TEXTURE_MODE_16BPP: - texture_ptr = (u8 *)(psx_gpu->vram_ptr); - texture_ptr += (psx_gpu->current_texture_page & 0xF) * 128; - texture_ptr += ((psx_gpu->current_texture_page >> 4) * 256) * 2048; + texture_base = (u8 *)(psx_gpu->vram_ptr); + texture_base += (psx_gpu->current_texture_page & 0xF) * 128; + texture_base += ((psx_gpu->current_texture_page >> 4) * 256) * 2048; + + texture_ptr = texture_base; texture_ptr += psx_gpu->texture_window_x * 2; texture_ptr += (psx_gpu->texture_window_y) * 2048; break; } + psx_gpu->texture_page_base = texture_base; psx_gpu->texture_page_ptr = texture_ptr; } @@ -104,8 +98,7 @@ void set_texture(psx_gpu_struct *psx_gpu, u32 texture_settings) u32 texture_mode = (texture_settings >> 7) & 0x3; u32 render_state_base = psx_gpu->render_state_base; - if(psx_gpu->current_texture_page != new_texture_page) - flush_render_block_buffer(psx_gpu); + flush_render_block_buffer(psx_gpu); render_state_base &= ~(0xF << 6); render_state_base |= ((texture_settings >> 5) & 0xF) << 6; @@ -162,6 +155,13 @@ void set_triangle_color(psx_gpu_struct *psx_gpu, u32 triangle_color) #define sign_extend_12bit(value) \ (((s32)((value) << 20)) >> 20) \ +#define sign_extend_11bit(value) \ + (((s32)((value) << 21)) >> 21) \ + +#define sign_extend_10bit(value) \ + (((s32)((value) << 22)) >> 22) \ + + #define get_vertex_data_xy(vertex_number, offset16) \ vertexes[vertex_number].x = \ sign_extend_12bit(list_s16[offset16]) + psx_gpu->offset_x; \ @@ -199,12 +199,17 @@ void set_triangle_color(psx_gpu_struct *psx_gpu, u32 triangle_color) get_vertex_data_xy(vertex_number, offset16); \ set_vertex_color_constant(vertex_number, color) \ +#ifndef SET_Ex +#define SET_Ex(r, v) +#endif + vertex_struct vertexes[4] __attribute__((aligned(32))); -void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) +u32 gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size, u32 *last_command) { - u32 current_command, command_length; - + u32 current_command = 0, command_length; + + u32 *list_start = list; u32 *list_end = list + (size / 4); for(; list < list_end; list += 1 + command_length) @@ -212,16 +217,65 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) s16 *list_s16 = (void *)list; current_command = *list >> 24; command_length = command_lengths[current_command]; - + if (list + 1 + command_length > list_end) { + current_command = (u32)-1; + break; + } + switch(current_command) { case 0x00: break; case 0x02: - render_block_fill(psx_gpu, list[0] & 0xFFFFFF, list_s16[2], list_s16[3], - list_s16[4] & 0x3FF, list_s16[5] & 0x3FF); + { + u32 x = list_s16[2] & 0x3FF; + u32 y = list_s16[3] & 0x1FF; + u32 width = list_s16[4] & 0x3FF; + u32 height = list_s16[5] & 0x1FF; + u32 color = list[0] & 0xFFFFFF; + + x &= ~0xF; + width = ((width + 0xF) & ~0xF); + + if((x + width) > 1024) + { + u32 width_a = 1024 - x; + u32 width_b = width - width_a; + + if((y + height) > 512) + { + u32 height_a = 512 - y; + u32 height_b = height - height_a; + + render_block_fill(psx_gpu, color, x, y, width_a, height_a); + render_block_fill(psx_gpu, color, 0, y, width_b, height_a); + render_block_fill(psx_gpu, color, x, 0, width_a, height_b); + render_block_fill(psx_gpu, color, 0, 0, width_b, height_b); + } + else + { + render_block_fill(psx_gpu, color, x, y, width_a, height); + render_block_fill(psx_gpu, color, 0, y, width_b, height); + } + } + else + { + if((y + height) > 512) + { + u32 height_a = 512 - y; + u32 height_b = height - height_a; + + render_block_fill(psx_gpu, color, x, y, width, height_a); + render_block_fill(psx_gpu, color, x, 0, width, height_b); + } + else + { + render_block_fill(psx_gpu, color, x, y, width, height); + } + } break; + } case 0x20 ... 0x23: { @@ -230,7 +284,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) get_vertex_data_xy(0, 2); get_vertex_data_xy(1, 4); get_vertex_data_xy(2, 6); - + render_triangle(psx_gpu, vertexes, current_command); break; } @@ -358,27 +412,29 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) vertexes[1].x = (xy & 0xFFFF) + psx_gpu->offset_x; vertexes[1].y = (xy >> 16) + psx_gpu->offset_y; + xy = *list_position; while(1) { - xy = *list_position; - if(xy == 0x55555555) - break; - vertexes[0] = vertexes[1]; vertexes[1].x = (xy & 0xFFFF) + psx_gpu->offset_x; vertexes[1].y = (xy >> 16) + psx_gpu->offset_y; + render_line(psx_gpu, vertexes, current_command, list[0]); + list_position++; num_vertexes++; - render_line(psx_gpu, vertexes, current_command, list[0]); - } + if(list_position >= list_end) + break; - if(num_vertexes > 2) - command_length += (num_vertexes - 2); + xy = *list_position; + if((xy & 0xF000F000) == 0x50005000) + break; + } - break; + command_length += (num_vertexes - 2); + break; } case 0x50 ... 0x57: @@ -412,12 +468,9 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) vertexes[1].x = (xy & 0xFFFF) + psx_gpu->offset_x; vertexes[1].y = (xy >> 16) + psx_gpu->offset_y; + color = list_position[0]; while(1) { - color = list_position[0]; - if(color == 0x55555555) - break; - xy = list_position[1]; vertexes[0] = vertexes[1]; @@ -428,40 +481,42 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) vertexes[1].x = (xy & 0xFFFF) + psx_gpu->offset_x; vertexes[1].y = (xy >> 16) + psx_gpu->offset_y; + render_line(psx_gpu, vertexes, current_command, 0); + list_position += 2; num_vertexes++; - render_line(psx_gpu, vertexes, current_command, 0); - } + if(list_position >= list_end) + break; - if(num_vertexes > 2) - command_length += ((num_vertexes * 2) - 2); + color = list_position[0]; + if((color & 0xF000F000) == 0x50005000) + break; + } - break; + command_length += ((num_vertexes - 2) * 2); + break; } case 0x60 ... 0x63: { - u32 x = list_s16[2] + psx_gpu->offset_x; - u32 y = list_s16[3] + psx_gpu->offset_y; + u32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + u32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); u32 width = list_s16[4] & 0x3FF; u32 height = list_s16[5] & 0x1FF; - psx_gpu->primitive_color = list[0] & 0xFFFFFF; - render_sprite(psx_gpu, x, y, 0, 0, width, height, current_command, list[0]); break; } case 0x64 ... 0x67: { - u32 x = list_s16[2] + psx_gpu->offset_x; - u32 y = list_s16[3] + psx_gpu->offset_y; + u32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + u32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); u32 uv = list_s16[4]; u32 width = list_s16[6] & 0x3FF; u32 height = list_s16[7] & 0x1FF; - psx_gpu->primitive_color = list[0] & 0xFFFFFF; set_clut(psx_gpu, list_s16[5]); render_sprite(psx_gpu, x, y, uv & 0xFF, (uv >> 8) & 0xFF, width, height, @@ -474,10 +529,8 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x6A: case 0x6B: { - s32 x = list_s16[2] + psx_gpu->offset_x; - s32 y = list_s16[3] + psx_gpu->offset_y; - - psx_gpu->primitive_color = list[0] & 0xFFFFFF; + s32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + s32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); render_sprite(psx_gpu, x, y, 0, 0, 1, 1, current_command, list[0]); break; @@ -488,10 +541,8 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x72: case 0x73: { - s32 x = list_s16[2] + psx_gpu->offset_x; - s32 y = list_s16[3] + psx_gpu->offset_y; - - psx_gpu->primitive_color = list[0] & 0xFFFFFF; + s32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + s32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); render_sprite(psx_gpu, x, y, 0, 0, 8, 8, current_command, list[0]); break; @@ -502,11 +553,10 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x76: case 0x77: { - s32 x = list_s16[2] + psx_gpu->offset_x; - s32 y = list_s16[3] + psx_gpu->offset_y; + s32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + s32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); u32 uv = list_s16[4]; - psx_gpu->primitive_color = list[0] & 0xFFFFFF; set_clut(psx_gpu, list_s16[5]); render_sprite(psx_gpu, x, y, uv & 0xFF, (uv >> 8) & 0xFF, 8, 8, @@ -519,10 +569,9 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x7A: case 0x7B: { - s32 x = list_s16[2] + psx_gpu->offset_x; - s32 y = list_s16[3] + psx_gpu->offset_y; + s32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + s32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); - psx_gpu->primitive_color = list[0] & 0xFFFFFF; render_sprite(psx_gpu, x, y, 0, 0, 16, 16, current_command, list[0]); break; } @@ -532,11 +581,10 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x7E: case 0x7F: { - s32 x = list_s16[2] + psx_gpu->offset_x; - s32 y = list_s16[3] + psx_gpu->offset_y; + s32 x = sign_extend_11bit(list_s16[2] + psx_gpu->offset_x); + s32 y = sign_extend_11bit(list_s16[3] + psx_gpu->offset_y); u32 uv = list_s16[4]; - psx_gpu->primitive_color = list[0] & 0xFFFFFF; set_clut(psx_gpu, list_s16[5]); render_sprite(psx_gpu, x, y, uv & 0xFF, (uv >> 8) & 0xFF, 16, 16, @@ -546,35 +594,47 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) case 0x80: // vid -> vid render_block_move(psx_gpu, list_s16[2] & 0x3FF, list_s16[3] & 0x1FF, - list_s16[4] & 0x3FF, list_s16[5] & 0x1FF, list_s16[6], list_s16[7]); + list_s16[4] & 0x3FF, list_s16[5] & 0x1FF, + ((list_s16[6] - 1) & 0x3FF) + 1, ((list_s16[7] - 1) & 0x1FF) + 1); break; - + +#ifdef PCSX + case 0xA0: // sys -> vid + case 0xC0: // vid -> sys + goto breakloop; +#else case 0xA0: // sys -> vid { - u32 load_x = list_s16[2]; - u32 load_y = list_s16[3]; - u32 load_width = list_s16[4]; - u32 load_height = list_s16[5]; + u32 load_x = list_s16[2] & 0x3FF; + u32 load_y = list_s16[3] & 0x1FF; + u32 load_width = list_s16[4] & 0x3FF; + u32 load_height = list_s16[5] & 0x1FF; u32 load_size = load_width * load_height; command_length += load_size / 2; - + + if(load_size & 1) + command_length++; + render_block_copy(psx_gpu, (u16 *)&(list_s16[6]), load_x, load_y, load_width, load_height, load_width); break; } - + case 0xC0: // vid -> sys break; - +#endif + case 0xE1: set_texture(psx_gpu, list[0] & 0x1FF); + if(list[0] & (1 << 9)) psx_gpu->render_state_base |= RENDER_STATE_DITHER; else psx_gpu->render_state_base &= ~RENDER_STATE_DITHER; psx_gpu->display_area_draw_enable = (list[0] >> 10) & 0x1; + SET_Ex(1, list[0]); break; case 0xE2: @@ -599,6 +659,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) flush_render_block_buffer(psx_gpu); + psx_gpu->texture_window_settings = texture_window_settings; psx_gpu->texture_window_x = x; psx_gpu->texture_window_y = y; psx_gpu->texture_mask_width = w - 1; @@ -606,6 +667,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) update_texture_ptr(psx_gpu); } + SET_Ex(2, list[0]); break; } @@ -619,6 +681,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) psx_gpu->viewport_start_y, psx_gpu->viewport_end_x, psx_gpu->viewport_end_y); #endif + SET_Ex(3, list[0]); break; case 0xE4: @@ -631,6 +694,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) psx_gpu->viewport_start_y, psx_gpu->viewport_end_x, psx_gpu->viewport_end_y); #endif + SET_Ex(4, list[0]); break; case 0xE5: @@ -640,6 +704,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) psx_gpu->offset_x = offset_x >> 21; psx_gpu->offset_y = offset_y >> 21; + SET_Ex(5, list[0]); break; } @@ -659,6 +724,7 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) psx_gpu->mask_msb = mask_msb; } + SET_Ex(6, list[0]); break; } @@ -666,5 +732,12 @@ void gpu_parse(psx_gpu_struct *psx_gpu, u32 *list, u32 size) break; } } + +#ifdef PCSX +breakloop: +#endif + if (last_command != NULL) + *last_command = current_command; + return list - list_start; }