comparison vdp.c @ 2566:e5de445e2cf0

Fix regression in right border of OD2 Titancade border dissolve
author Michael Pavone <pavone@retrodev.com>
date Mon, 27 Jan 2025 23:46:00 -0800
parents 553a0b4888db
children 8872c8e3e0fc 80606ebec74c
comparison
equal deleted inserted replaced
2565:eb588f22ec76 2566:e5de445e2cf0
374 } 374 }
375 } 375 }
376 376
377 static void render_sprite_cells(vdp_context * context) 377 static void render_sprite_cells(vdp_context * context)
378 { 378 {
379 if (context->cur_slot > MAX_SPRITES_LINE) { 379 if (context->cur_slot < 0) {
380 //should this be 16 in H32?
381 context->cur_slot += 32;
382 }
383 if (context->cur_slot >= MAX_SPRITES_LINE) {
380 context->cur_slot--; 384 context->cur_slot--;
381 return;
382 }
383 if (context->cur_slot < 0) {
384 return; 385 return;
385 } 386 }
386 sprite_draw * d = context->sprite_draw_list + context->cur_slot; 387 sprite_draw * d = context->sprite_draw_list + context->cur_slot;
387 uint16_t address = d->address; 388 uint16_t address = d->address;
388 address += context->sprite_x_offset * d->height * 4; 389 address += context->sprite_x_offset * d->height * 4;
389 context->serial_address = address; 390 context->serial_address = address;
390 uint16_t dir;
391 int16_t x;
392 if (d->h_flip) {
393 x = d->x_pos + 7 + 8 * (d->width - context->sprite_x_offset - 1);
394 dir = -1;
395 } else {
396 x = d->x_pos + context->sprite_x_offset * 8;
397 dir = 1;
398 }
399 if (d->x_pos) { 391 if (d->x_pos) {
392 uint16_t dir;
393 int16_t x;
394 if (d->h_flip) {
395 x = d->x_pos + 7 + 8 * (d->width - context->sprite_x_offset - 1);
396 dir = -1;
397 } else {
398 x = d->x_pos + context->sprite_x_offset * 8;
399 dir = 1;
400 }
400 context->flags |= FLAG_CAN_MASK; 401 context->flags |= FLAG_CAN_MASK;
401 if (!(context->flags & FLAG_MASKED)) { 402 if (!(context->flags & FLAG_MASKED)) {
402 x -= 128; 403 x -= 128;
403 //printf("Draw Slot %d of %d, Rendering sprite cell from %X to x: %d\n", context->cur_slot, context->sprite_draws, d->address, x); 404 //printf("Draw Slot %d of %d, Rendering sprite cell from %X to x: %d\n", context->cur_slot, context->sprite_draws, d->address, x);
404 uint8_t collide = 0; 405 uint8_t collide = 0;
2795 advance_output_line(context);\ 2796 advance_output_line(context);\
2796 if (!context->output) {\ 2797 if (!context->output) {\
2797 context->output = dummy_buffer;\ 2798 context->output = dummy_buffer;\
2798 }\ 2799 }\
2799 }\ 2800 }\
2801 render_sprite_cells( context);\
2800 if (slot == 168 || slot == 247 || slot == 248) {\ 2802 if (slot == 168 || slot == 247 || slot == 248) {\
2801 render_border_garbage(\ 2803 render_border_garbage(\
2802 context,\ 2804 context,\
2803 context->sprite_draw_list[context->cur_slot].address,\ 2805 context->serial_address,\
2804 context->tmp_buf_b,\ 2806 context->tmp_buf_b,\
2805 context->buf_b_off + (slot == 247 ? 0 : 8),\ 2807 context->buf_b_off + (slot == 247 ? 0 : 8),\
2806 slot == 247 ? context->col_1 : context->col_2\ 2808 slot == 247 ? context->col_1 : context->col_2\
2807 );\ 2809 );\
2808 if (slot == 248) {\ 2810 if (slot == 248) {\
2810 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;\ 2812 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;\
2811 }\ 2813 }\
2812 } else if (slot == 243) {\ 2814 } else if (slot == 243) {\
2813 render_border_garbage(\ 2815 render_border_garbage(\
2814 context,\ 2816 context,\
2815 context->sprite_draw_list[context->cur_slot].address,\ 2817 context->serial_address,\
2816 context->tmp_buf_a,\ 2818 context->tmp_buf_a,\
2817 context->buf_a_off,\ 2819 context->buf_a_off,\
2818 context->col_1\ 2820 context->col_1\
2819 );\ 2821 );\
2820 } else if (slot == 169) {\ 2822 } else if (slot == 169) {\
2821 draw_right_border(context);\ 2823 draw_right_border(context);\
2822 }\ 2824 }\
2823 render_sprite_cells( context);\
2824 scan_sprite_table(context->vcounter, context);\ 2825 scan_sprite_table(context->vcounter, context);\
2825 CHECK_LIMIT_HSYNC(slot) 2826 CHECK_LIMIT_HSYNC(slot)
2826 2827
2827 //Note that the line advancement check will fail if BG_START_SLOT is > 6 2828 //Note that the line advancement check will fail if BG_START_SLOT is > 6
2828 //as we're bumping up against the hcounter jump 2829 //as we're bumping up against the hcounter jump
2833 advance_output_line(context);\ 2834 advance_output_line(context);\
2834 if (!context->output) {\ 2835 if (!context->output) {\
2835 context->output = dummy_buffer;\ 2836 context->output = dummy_buffer;\
2836 }\ 2837 }\
2837 }\ 2838 }\
2839 render_sprite_cells( context);\
2838 if (slot == 136 || slot == 247 || slot == 248) {\ 2840 if (slot == 136 || slot == 247 || slot == 248) {\
2839 render_border_garbage(\ 2841 render_border_garbage(\
2840 context,\ 2842 context,\
2841 context->sprite_draw_list[context->cur_slot].address,\ 2843 context->serial_address,\
2842 context->tmp_buf_b,\ 2844 context->tmp_buf_b,\
2843 context->buf_b_off + (slot == 247 ? 0 : 8),\ 2845 context->buf_b_off + (slot == 247 ? 0 : 8),\
2844 slot == 247 ? context->col_1 : context->col_2\ 2846 slot == 247 ? context->col_1 : context->col_2\
2845 );\ 2847 );\
2846 if (slot == 248) {\ 2848 if (slot == 248) {\
2848 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;\ 2850 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;\
2849 }\ 2851 }\
2850 } else if (slot == 137) {\ 2852 } else if (slot == 137) {\
2851 draw_right_border(context);\ 2853 draw_right_border(context);\
2852 }\ 2854 }\
2853 render_sprite_cells( context);\
2854 scan_sprite_table(context->vcounter, context);\ 2855 scan_sprite_table(context->vcounter, context);\
2855 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ 2856 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \
2856 if (slot == 147) {\ 2857 if (slot == 147) {\
2857 context->hslot = 233;\ 2858 context->hslot = 233;\
2858 } else {\ 2859 } else {\
2933 //166 2934 //166
2934 render_sprite_cells(context); 2935 render_sprite_cells(context);
2935 //167 2936 //167
2936 context->sprite_index = 0x80; 2937 context->sprite_index = 0x80;
2937 context->slot_counter = 0; 2938 context->slot_counter = 0;
2939 render_sprite_cells(context);
2938 render_border_garbage( 2940 render_border_garbage(
2939 context, 2941 context,
2940 context->sprite_draw_list[context->cur_slot].address, 2942 context->serial_address,
2941 context->tmp_buf_b, context->buf_b_off, 2943 context->tmp_buf_b, context->buf_b_off,
2942 context->col_1 2944 context->col_1
2943 ); 2945 );
2944 render_sprite_cells(context);
2945 scan_sprite_table(context->vcounter, context); 2946 scan_sprite_table(context->vcounter, context);
2946 //168 2947 //168
2948 render_sprite_cells(context);
2947 render_border_garbage( 2949 render_border_garbage(
2948 context, 2950 context,
2949 context->sprite_draw_list[context->cur_slot].address, 2951 context->serial_address,
2950 context->tmp_buf_b, 2952 context->tmp_buf_b,
2951 context->buf_b_off + 8, 2953 context->buf_b_off + 8,
2952 context->col_2 2954 context->col_2
2953 ); 2955 );
2956 scan_sprite_table(context->vcounter, context);
2954 2957
2955 //Do palette lookup for end of previous line 2958 //Do palette lookup for end of previous line
2956 uint8_t *src = context->compositebuf + (LINE_CHANGE_H40 - BG_START_SLOT) *2; 2959 uint8_t *src = context->compositebuf + (LINE_CHANGE_H40 - BG_START_SLOT) *2;
2957 uint32_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2; 2960 uint32_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2;
2958 if (context->output) { 2961 if (context->output) {
2971 } 2974 }
2972 } 2975 }
2973 } 2976 }
2974 } 2977 }
2975 advance_output_line(context); 2978 advance_output_line(context);
2976 //168-242 (inclusive) 2979 //169-242 (inclusive)
2977 for (int i = 0; i < 28; i++) 2980 for (int i = 0; i < 27; i++)
2978 { 2981 {
2979 render_sprite_cells(context); 2982 render_sprite_cells(context);
2980 scan_sprite_table(context->vcounter, context); 2983 scan_sprite_table(context->vcounter, context);
2981 } 2984 }
2982 //243 2985 //243
2986 render_sprite_cells(context);
2983 render_border_garbage( 2987 render_border_garbage(
2984 context, 2988 context,
2985 context->sprite_draw_list[context->cur_slot].address, 2989 context->serial_address,
2986 context->tmp_buf_a, 2990 context->tmp_buf_a,
2987 context->buf_a_off, 2991 context->buf_a_off,
2988 context->col_1 2992 context->col_1
2989 ); 2993 );
2994 scan_sprite_table(context->vcounter, context);
2990 //244 2995 //244
2991 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; 2996 address = (context->regs[REG_HSCROLL] & 0x3F) << 10;
2992 mask = 0; 2997 mask = 0;
2993 if (context->regs[REG_MODE_3] & 0x2) { 2998 if (context->regs[REG_MODE_3] & 0x2) {
2994 mask |= 0xF8; 2999 mask |= 0xF8;
3008 { 3013 {
3009 render_sprite_cells(context); 3014 render_sprite_cells(context);
3010 scan_sprite_table(context->vcounter, context); 3015 scan_sprite_table(context->vcounter, context);
3011 } 3016 }
3012 //247 3017 //247
3018 render_sprite_cells(context);
3013 render_border_garbage( 3019 render_border_garbage(
3014 context, 3020 context,
3015 context->sprite_draw_list[context->cur_slot].address, 3021 context->serial_address,
3016 context->tmp_buf_b, 3022 context->tmp_buf_b,
3017 context->buf_b_off, 3023 context->buf_b_off,
3018 context->col_1 3024 context->col_1
3019 ); 3025 );
3020 render_sprite_cells(context);
3021 scan_sprite_table(context->vcounter, context); 3026 scan_sprite_table(context->vcounter, context);
3022 //248 3027 //248
3028
3029 render_sprite_cells(context);
3023 render_border_garbage( 3030 render_border_garbage(
3024 context, 3031 context,
3025 context->sprite_draw_list[context->cur_slot].address, 3032 context->serial_address,
3026 context->tmp_buf_b, 3033 context->tmp_buf_b,
3027 context->buf_b_off + 8, 3034 context->buf_b_off + 8,
3028 context->col_2 3035 context->col_2
3029 ); 3036 );
3030 render_sprite_cells(context);
3031 scan_sprite_table(context->vcounter, context); 3037 scan_sprite_table(context->vcounter, context);
3032 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; 3038 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
3033 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; 3039 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
3034 //250 3040 //250
3035 render_sprite_cells(context); 3041 render_sprite_cells(context);
3071 read_sprite_x(context->vcounter, context); 3077 read_sprite_x(context->vcounter, context);
3072 } 3078 }
3073 //163 3079 //163
3074 context->cur_slot = MAX_SPRITES_LINE-1; 3080 context->cur_slot = MAX_SPRITES_LINE-1;
3075 memset(context->linebuf, 0, LINEBUF_SIZE); 3081 memset(context->linebuf, 0, LINEBUF_SIZE);
3076 render_border_garbage(
3077 context,
3078 context->sprite_draw_list[context->cur_slot].address,
3079 context->tmp_buf_a, context->buf_a_off,
3080 context->col_1
3081 );
3082 context->flags &= ~FLAG_MASKED; 3082 context->flags &= ~FLAG_MASKED;
3083 while (context->sprite_draws) { 3083 while (context->sprite_draws) {
3084 context->sprite_draws--; 3084 context->sprite_draws--;
3085 context->sprite_draw_list[context->sprite_draws].x_pos = 0; 3085 context->sprite_draw_list[context->sprite_draws].x_pos = 0;
3086 } 3086 }
3087 render_sprite_cells(context); 3087 render_sprite_cells(context);
3088 //164
3089 render_border_garbage( 3088 render_border_garbage(
3090 context, 3089 context,
3091 context->sprite_draw_list[context->cur_slot].address, 3090 context->serial_address,
3091 context->tmp_buf_a, context->buf_a_off,
3092 context->col_1
3093 );
3094 //164
3095 render_sprite_cells(context);
3096 render_border_garbage(
3097 context,
3098 context->serial_address,
3092 context->tmp_buf_a, context->buf_a_off + 8, 3099 context->tmp_buf_a, context->buf_a_off + 8,
3093 context->col_2 3100 context->col_2
3094 ); 3101 );
3095 render_sprite_cells(context);
3096 context->cycles += MCLKS_LINE; 3102 context->cycles += MCLKS_LINE;
3097 vdp_advance_line(context); 3103 vdp_advance_line(context);
3098 src = context->compositebuf; 3104 src = context->compositebuf;
3099 if (!context->output) { 3105 if (!context->output) {
3100 return; 3106 return;
3176 //sprite attribute table scan starts 3182 //sprite attribute table scan starts
3177 case 167: 3183 case 167:
3178 OUTPUT_PIXEL(167) 3184 OUTPUT_PIXEL(167)
3179 context->sprite_index = 0x80; 3185 context->sprite_index = 0x80;
3180 context->slot_counter = 0; 3186 context->slot_counter = 0;
3187 render_sprite_cells(context);
3181 render_border_garbage( 3188 render_border_garbage(
3182 context, 3189 context,
3183 context->sprite_draw_list[context->cur_slot].address, 3190 context->serial_address,
3184 context->tmp_buf_b, context->buf_b_off, 3191 context->tmp_buf_b, context->buf_b_off,
3185 context->col_1 3192 context->col_1
3186 ); 3193 );
3187 render_sprite_cells(context);
3188 scan_sprite_table(context->vcounter, context); 3194 scan_sprite_table(context->vcounter, context);
3189 CHECK_LIMIT 3195 CHECK_LIMIT
3190 SPRITE_RENDER_H40(168) 3196 SPRITE_RENDER_H40(168)
3191 SPRITE_RENDER_H40(169) 3197 SPRITE_RENDER_H40(169)
3192 SPRITE_RENDER_H40(170) 3198 SPRITE_RENDER_H40(170)
3310 //sprite render to line buffer starts 3316 //sprite render to line buffer starts
3311 case 163: 3317 case 163:
3312 OUTPUT_PIXEL(163) 3318 OUTPUT_PIXEL(163)
3313 context->cur_slot = MAX_SPRITES_LINE-1; 3319 context->cur_slot = MAX_SPRITES_LINE-1;
3314 memset(context->linebuf, 0, LINEBUF_SIZE); 3320 memset(context->linebuf, 0, LINEBUF_SIZE);
3315 render_border_garbage(
3316 context,
3317 context->sprite_draw_list[context->cur_slot].address,
3318 context->tmp_buf_a, context->buf_a_off,
3319 context->col_1
3320 );
3321 context->flags &= ~FLAG_MASKED; 3321 context->flags &= ~FLAG_MASKED;
3322 while (context->sprite_draws) { 3322 while (context->sprite_draws) {
3323 context->sprite_draws--; 3323 context->sprite_draws--;
3324 context->sprite_draw_list[context->sprite_draws].x_pos = 0; 3324 context->sprite_draw_list[context->sprite_draws].x_pos = 0;
3325 } 3325 }
3326 render_sprite_cells(context); 3326 render_sprite_cells(context);
3327 render_border_garbage(
3328 context,
3329 context->serial_address,
3330 context->tmp_buf_a, context->buf_a_off,
3331 context->col_1
3332 );
3327 CHECK_LIMIT 3333 CHECK_LIMIT
3328 case 164: 3334 case 164:
3329 OUTPUT_PIXEL(164) 3335 OUTPUT_PIXEL(164)
3336 render_sprite_cells(context);
3330 render_border_garbage( 3337 render_border_garbage(
3331 context, 3338 context,
3332 context->sprite_draw_list[context->cur_slot].address, 3339 context->serial_address,
3333 context->tmp_buf_a, context->buf_a_off + 8, 3340 context->tmp_buf_a, context->buf_a_off + 8,
3334 context->col_2 3341 context->col_2
3335 ); 3342 );
3336 render_sprite_cells(context);
3337 if (context->flags & FLAG_DMA_RUN) { 3343 if (context->flags & FLAG_DMA_RUN) {
3338 run_dma_src(context, -1); 3344 run_dma_src(context, -1);
3339 } 3345 }
3340 context->hslot++; 3346 context->hslot++;
3341 context->cycles += slot_cycles; 3347 context->cycles += slot_cycles;
3389 //sprite attribute table scan starts 3395 //sprite attribute table scan starts
3390 case 135: 3396 case 135:
3391 OUTPUT_PIXEL(135) 3397 OUTPUT_PIXEL(135)
3392 context->sprite_index = 0x80; 3398 context->sprite_index = 0x80;
3393 context->slot_counter = 0; 3399 context->slot_counter = 0;
3400 render_sprite_cells(context);
3394 render_border_garbage( 3401 render_border_garbage(
3395 context, 3402 context,
3396 context->sprite_draw_list[context->cur_slot].address, 3403 context->serial_address,
3397 context->tmp_buf_b, context->buf_b_off, 3404 context->tmp_buf_b, context->buf_b_off,
3398 context->col_1 3405 context->col_1
3399 ); 3406 );
3400 render_sprite_cells(context);
3401 scan_sprite_table(context->vcounter, context); 3407 scan_sprite_table(context->vcounter, context);
3402 CHECK_LIMIT 3408 CHECK_LIMIT
3403 SPRITE_RENDER_H32(136) 3409 SPRITE_RENDER_H32(136)
3404 SPRITE_RENDER_H32(137) 3410 SPRITE_RENDER_H32(137)
3405 SPRITE_RENDER_H32(138) 3411 SPRITE_RENDER_H32(138)
3438 } 3444 }
3439 external_slot(context); 3445 external_slot(context);
3440 //provides "garbage" for border when plane A selected 3446 //provides "garbage" for border when plane A selected
3441 render_border_garbage( 3447 render_border_garbage(
3442 context, 3448 context,
3443 context->sprite_draw_list[context->cur_slot].address, 3449 context->serial_address,
3444 context->tmp_buf_a, 3450 context->tmp_buf_a,
3445 context->buf_a_off, 3451 context->buf_a_off,
3446 context->col_1 3452 context->col_1
3447 ); 3453 );
3448 CHECK_LIMIT 3454 CHECK_LIMIT
3532 //sprite render to line buffer starts 3538 //sprite render to line buffer starts
3533 case 131: 3539 case 131:
3534 OUTPUT_PIXEL(131) 3540 OUTPUT_PIXEL(131)
3535 context->cur_slot = MAX_SPRITES_LINE_H32-1; 3541 context->cur_slot = MAX_SPRITES_LINE_H32-1;
3536 memset(context->linebuf, 0, LINEBUF_SIZE); 3542 memset(context->linebuf, 0, LINEBUF_SIZE);
3537 render_border_garbage(
3538 context,
3539 context->sprite_draw_list[context->cur_slot].address,
3540 context->tmp_buf_a, context->buf_a_off,
3541 context->col_1
3542 );
3543 context->flags &= ~FLAG_MASKED; 3543 context->flags &= ~FLAG_MASKED;
3544 while (context->sprite_draws) { 3544 while (context->sprite_draws) {
3545 context->sprite_draws--; 3545 context->sprite_draws--;
3546 context->sprite_draw_list[context->sprite_draws].x_pos = 0; 3546 context->sprite_draw_list[context->sprite_draws].x_pos = 0;
3547 } 3547 }
3548 render_sprite_cells(context); 3548 render_sprite_cells(context);
3549 render_border_garbage(
3550 context,
3551 context->serial_address,
3552 context->tmp_buf_a, context->buf_a_off,
3553 context->col_1
3554 );
3549 CHECK_LIMIT 3555 CHECK_LIMIT
3550 case 132: 3556 case 132:
3551 OUTPUT_PIXEL(132) 3557 OUTPUT_PIXEL(132)
3558 render_sprite_cells(context);
3552 render_border_garbage( 3559 render_border_garbage(
3553 context, 3560 context,
3554 context->sprite_draw_list[context->cur_slot].address, 3561 context->serial_address,
3555 context->tmp_buf_a, context->buf_a_off + 8, 3562 context->tmp_buf_a, context->buf_a_off + 8,
3556 context->col_2 3563 context->col_2
3557 ); 3564 );
3558 render_sprite_cells(context);
3559 if (context->flags & FLAG_DMA_RUN) { 3565 if (context->flags & FLAG_DMA_RUN) {
3560 run_dma_src(context, -1); 3566 run_dma_src(context, -1);
3561 } 3567 }
3562 context->hslot++; 3568 context->hslot++;
3563 context->cycles += slot_cycles; 3569 context->cycles += slot_cycles;