comparison vdp.c @ 1866:84f16a804ce5

Rework sprite rendering phase 3 to better match behavior documented by Kabuto/Titan and fix edge case in sprite overflow flag that was breaking the RPS minigame in Alex Kidd
author Michael Pavone <pavone@retrodev.com>
date Thu, 20 Jun 2019 22:31:31 -0700
parents 304d47a5c67f
children dc94354eab66
comparison
equal deleted inserted replaced
1865:4c322abd9fa5 1866:84f16a804ce5
142 context->output_pitch = 0; 142 context->output_pitch = 0;
143 } else { 143 } else {
144 context->cur_buffer = FRAMEBUFFER_ODD; 144 context->cur_buffer = FRAMEBUFFER_ODD;
145 context->fb = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch); 145 context->fb = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch);
146 } 146 }
147 context->sprite_draws = MAX_DRAWS; 147 context->sprite_draws = MAX_SPRITES_LINE;
148 context->fifo_write = 0; 148 context->fifo_write = 0;
149 context->fifo_read = -1; 149 context->fifo_read = -1;
150 context->regs[REG_HINT] = context->hint_counter = 0xFF; 150 context->regs[REG_HINT] = context->hint_counter = 0xFF;
151 151
152 if (!color_map_init_done) { 152 if (!color_map_init_done) {
267 } 267 }
268 } 268 }
269 269
270 static void render_sprite_cells(vdp_context * context) 270 static void render_sprite_cells(vdp_context * context)
271 { 271 {
272 if (context->cur_slot > MAX_SPRITES_LINE) {
273 context->cur_slot--;
274 return;
275 }
276 if (context->cur_slot < 0) {
277 return;
278 }
272 sprite_draw * d = context->sprite_draw_list + context->cur_slot; 279 sprite_draw * d = context->sprite_draw_list + context->cur_slot;
273 context->serial_address = d->address; 280 context->serial_address = d->address;
274 if (context->cur_slot >= context->sprite_draws) { 281 uint16_t dir;
275 282 int16_t x;
276 uint16_t dir; 283 if (d->h_flip) {
277 int16_t x; 284 x = d->x_pos + 7 + 8 * (d->width - 1);
278 if (d->h_flip) { 285 dir = -1;
279 x = d->x_pos + 7; 286 } else {
280 dir = -1; 287 x = d->x_pos;
281 } else { 288 dir = 1;
282 x = d->x_pos; 289 }
283 dir = 1; 290 if (d->x_pos) {
284 } 291 context->flags |= FLAG_CAN_MASK;
285 //printf("Draw Slot %d of %d, Rendering sprite cell from %X to x: %d\n", context->cur_slot, context->sprite_draws, d->address, x); 292 if (!(context->flags & FLAG_MASKED)) {
286 context->cur_slot--; 293 x -= 128;
287 for (uint16_t address = d->address; address != ((d->address+4) & 0xFFFF); address++) { 294 //printf("Draw Slot %d of %d, Rendering sprite cell from %X to x: %d\n", context->cur_slot, context->sprite_draws, d->address, x);
288 if (x >= 0 && x < 320) { 295
289 if (!(context->linebuf[x] & 0xF)) { 296 for (uint16_t address = d->address; address != ((d->address+4) & 0xFFFF); address++) {
290 context->linebuf[x] = (context->vdpmem[address] >> 4) | d->pal_priority; 297 if (x >= 0 && x < 320) {
291 } else if (context->vdpmem[address] >> 4) { 298 if (!(context->linebuf[x] & 0xF)) {
292 context->flags2 |= FLAG2_SPRITE_COLLIDE; 299 context->linebuf[x] = (context->vdpmem[address] >> 4) | d->pal_priority;
293 } 300 } else if (context->vdpmem[address] >> 4) {
294 } 301 context->flags2 |= FLAG2_SPRITE_COLLIDE;
295 x += dir; 302 }
296 if (x >= 0 && x < 320) { 303 }
297 if (!(context->linebuf[x] & 0xF)) { 304 x += dir;
298 context->linebuf[x] = (context->vdpmem[address] & 0xF) | d->pal_priority; 305 if (x >= 0 && x < 320) {
299 } else if (context->vdpmem[address] & 0xF) { 306 if (!(context->linebuf[x] & 0xF)) {
300 context->flags2 |= FLAG2_SPRITE_COLLIDE; 307 context->linebuf[x] = (context->vdpmem[address] & 0xF) | d->pal_priority;
301 } 308 } else if (context->vdpmem[address] & 0xF) {
302 } 309 context->flags2 |= FLAG2_SPRITE_COLLIDE;
303 x += dir; 310 }
304 } 311 }
305 } else { 312 x += dir;
313 }
314 }
315 } else if (context->flags & FLAG_CAN_MASK) {
316 context->flags |= FLAG_MASKED;
317 context->flags &= ~FLAG_CAN_MASK;
318 }
319 if (d->width) {
320 d->width--;
321 }
322 if (d->width) {
323 d->address += d->height * 4;
324 if (!d->h_flip) {
325 d->x_pos += 8;
326 }
327 } else {
328 d->x_pos = 0;
306 context->cur_slot--; 329 context->cur_slot--;
307 } 330 }
308 } 331 }
309 332
310 static void fetch_sprite_cells_mode4(vdp_context * context) 333 static void fetch_sprite_cells_mode4(vdp_context * context)
693 if (context->double_res) { 716 if (context->double_res) {
694 address = ((tileinfo & 0x3FF) << 6) + row * 4; 717 address = ((tileinfo & 0x3FF) << 6) + row * 4;
695 } else { 718 } else {
696 address = ((tileinfo & 0x7FF) << 5) + row * 4; 719 address = ((tileinfo & 0x7FF) << 5) + row * 4;
697 } 720 }
698 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF; 721 context->sprite_draws--;
699 if (x) { 722 context->sprite_draw_list[context->sprite_draws].x_pos = ((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF;
700 context->flags |= FLAG_CAN_MASK; 723 context->sprite_draw_list[context->sprite_draws].address = address;
701 } else if(context->flags & (FLAG_CAN_MASK | FLAG_DOT_OFLOW)) { 724 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority;
702 context->flags |= FLAG_MASKED; 725 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0;
703 } 726 context->sprite_draw_list[context->sprite_draws].width = width;
704 727 context->sprite_draw_list[context->sprite_draws].height = height;
705 context->flags &= ~FLAG_DOT_OFLOW;
706 int16_t i;
707 if (context->flags & FLAG_MASKED) {
708 for (i=0; i < width && context->sprite_draws; i++) {
709 --context->sprite_draws;
710 context->sprite_draw_list[context->sprite_draws].x_pos = -128;
711 context->sprite_draw_list[context->sprite_draws].address = address + i * height * 4;
712 }
713 } else {
714 x -= 128;
715 int16_t base_x = x;
716 int16_t dir;
717 if (tileinfo & MAP_BIT_H_FLIP) {
718 x += (width-1) * 8;
719 dir = -8;
720 } else {
721 dir = 8;
722 }
723 //printf("Sprite %d | x: %d, y: %d, width: %d, height: %d, pal_priority: %X, row: %d, tile addr: %X\n", context->sprite_info_list[context->cur_slot].index, x, context->sprite_info_list[context->cur_slot].y, width, height, pal_priority, row, address);
724 for (i=0; i < width && context->sprite_draws; i++, x += dir) {
725 --context->sprite_draws;
726 context->sprite_draw_list[context->sprite_draws].address = address + i * height * 4;
727 context->sprite_draw_list[context->sprite_draws].x_pos = x;
728 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority;
729 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0;
730 }
731 }
732 //Used to be i < width
733 //TODO: Confirm this is the right condition on hardware
734 if (!context->sprite_draws) {
735 context->flags |= FLAG_DOT_OFLOW;
736 }
737 } else {
738 context->flags |= FLAG_DOT_OFLOW;
739 } 728 }
740 } 729 }
741 context->cur_slot++; 730 context->cur_slot++;
742 } 731 }
743 732
2579 case 253: 2568 case 253:
2580 read_map_scroll_b(0, context->vcounter, context); 2569 read_map_scroll_b(0, context->vcounter, context);
2581 CHECK_LIMIT 2570 CHECK_LIMIT
2582 SPRITE_RENDER_H40(254) 2571 SPRITE_RENDER_H40(254)
2583 case 255: 2572 case 255:
2573 if (context->cur_slot >= 0 && context->sprite_draw_list[context->cur_slot].x_pos) {
2574 context->flags |= FLAG_DOT_OFLOW;
2575 }
2584 render_map_3(context); 2576 render_map_3(context);
2585 scan_sprite_table(context->vcounter, context);//Just a guess 2577 scan_sprite_table(context->vcounter, context);//Just a guess
2586 CHECK_LIMIT 2578 CHECK_LIMIT
2587 case 0: 2579 case 0:
2588 render_map_output(context->vcounter, 0, context); 2580 render_map_output(context->vcounter, 0, context);
2590 //seems like the sprite table scan fills a shift register 2582 //seems like the sprite table scan fills a shift register
2591 //values are FIFO, but unused slots precede used slots 2583 //values are FIFO, but unused slots precede used slots
2592 //so we set cur_slot to slot_counter and let it wrap around to 2584 //so we set cur_slot to slot_counter and let it wrap around to
2593 //the beginning of the list 2585 //the beginning of the list
2594 context->cur_slot = context->slot_counter; 2586 context->cur_slot = context->slot_counter;
2595 context->sprite_draws = MAX_DRAWS; 2587 context->sprite_draws = MAX_SPRITES_LINE;
2596 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED);
2597 CHECK_LIMIT 2588 CHECK_LIMIT
2598 COLUMN_RENDER_BLOCK(2, 1) 2589 COLUMN_RENDER_BLOCK(2, 1)
2599 COLUMN_RENDER_BLOCK(4, 9) 2590 COLUMN_RENDER_BLOCK(4, 9)
2600 COLUMN_RENDER_BLOCK(6, 17) 2591 COLUMN_RENDER_BLOCK(6, 17)
2601 COLUMN_RENDER_BLOCK_REFRESH(8, 25) 2592 COLUMN_RENDER_BLOCK_REFRESH(8, 25)
2624 external_slot(context); 2615 external_slot(context);
2625 CHECK_LIMIT 2616 CHECK_LIMIT
2626 //sprite render to line buffer starts 2617 //sprite render to line buffer starts
2627 case 163: 2618 case 163:
2628 OUTPUT_PIXEL(163) 2619 OUTPUT_PIXEL(163)
2629 context->cur_slot = MAX_DRAWS-1; 2620 context->cur_slot = MAX_SPRITES_LINE-1;
2630 memset(context->linebuf, 0, LINEBUF_SIZE); 2621 memset(context->linebuf, 0, LINEBUF_SIZE);
2631 render_border_garbage( 2622 render_border_garbage(
2632 context, 2623 context,
2633 context->sprite_draw_list[context->cur_slot].address, 2624 context->sprite_draw_list[context->cur_slot].address,
2634 context->tmp_buf_a, context->buf_a_off, 2625 context->tmp_buf_a, context->buf_a_off,
2635 context->col_1 2626 context->col_1
2636 ); 2627 );
2628 context->flags &= ~FLAG_MASKED;
2637 render_sprite_cells(context); 2629 render_sprite_cells(context);
2638 CHECK_LIMIT 2630 CHECK_LIMIT
2639 case 164: 2631 case 164:
2640 OUTPUT_PIXEL(164) 2632 OUTPUT_PIXEL(164)
2641 render_border_garbage( 2633 render_border_garbage(
2780 case 249: 2772 case 249:
2781 read_map_scroll_a(0, context->vcounter, context); 2773 read_map_scroll_a(0, context->vcounter, context);
2782 CHECK_LIMIT 2774 CHECK_LIMIT
2783 SPRITE_RENDER_H32(250) 2775 SPRITE_RENDER_H32(250)
2784 case 251: 2776 case 251:
2777 if (context->cur_slot >= 0 && context->sprite_draw_list[context->cur_slot].x_pos) {
2778 context->flags |= FLAG_DOT_OFLOW;
2779 }
2785 render_map_1(context); 2780 render_map_1(context);
2786 scan_sprite_table(context->vcounter, context);//Just a guess 2781 scan_sprite_table(context->vcounter, context);//Just a guess
2787 CHECK_LIMIT 2782 CHECK_LIMIT
2788 case 252: 2783 case 252:
2789 render_map_2(context); 2784 render_map_2(context);
2805 scan_sprite_table(context->vcounter, context);//Just a guess 2800 scan_sprite_table(context->vcounter, context);//Just a guess
2806 //reverse context slot counter so it counts the number of sprite slots 2801 //reverse context slot counter so it counts the number of sprite slots
2807 //filled rather than the number of available slots 2802 //filled rather than the number of available slots
2808 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; 2803 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter;
2809 context->cur_slot = context->slot_counter; 2804 context->cur_slot = context->slot_counter;
2810 context->sprite_draws = MAX_DRAWS_H32; 2805 context->sprite_draws = MAX_SPRITES_LINE_H32;
2811 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED);
2812 CHECK_LIMIT 2806 CHECK_LIMIT
2813 COLUMN_RENDER_BLOCK(2, 1) 2807 COLUMN_RENDER_BLOCK(2, 1)
2814 COLUMN_RENDER_BLOCK(4, 9) 2808 COLUMN_RENDER_BLOCK(4, 9)
2815 COLUMN_RENDER_BLOCK(6, 17) 2809 COLUMN_RENDER_BLOCK(6, 17)
2816 COLUMN_RENDER_BLOCK_REFRESH(8, 25) 2810 COLUMN_RENDER_BLOCK_REFRESH(8, 25)
2836 CHECK_LIMIT 2830 CHECK_LIMIT
2837 } 2831 }
2838 //sprite render to line buffer starts 2832 //sprite render to line buffer starts
2839 case 131: 2833 case 131:
2840 OUTPUT_PIXEL(131) 2834 OUTPUT_PIXEL(131)
2841 context->cur_slot = MAX_DRAWS_H32-1; 2835 context->cur_slot = MAX_SPRITES_LINE_H32-1;
2842 memset(context->linebuf, 0, LINEBUF_SIZE); 2836 memset(context->linebuf, 0, LINEBUF_SIZE);
2843 render_border_garbage( 2837 render_border_garbage(
2844 context, 2838 context,
2845 context->sprite_draw_list[context->cur_slot].address, 2839 context->sprite_draw_list[context->cur_slot].address,
2846 context->tmp_buf_a, context->buf_a_off, 2840 context->tmp_buf_a, context->buf_a_off,
2847 context->col_1 2841 context->col_1
2848 ); 2842 );
2843 context->flags &= ~FLAG_MASKED;
2849 render_sprite_cells(context); 2844 render_sprite_cells(context);
2850 CHECK_LIMIT 2845 CHECK_LIMIT
2851 case 132: 2846 case 132:
2852 OUTPUT_PIXEL(132) 2847 OUTPUT_PIXEL(132)
2853 render_border_garbage( 2848 render_border_garbage(
3070 if (is_h40) { 3065 if (is_h40) {
3071 latch_slot = 165; 3066 latch_slot = 165;
3072 buf_clear_slot = 163; 3067 buf_clear_slot = 163;
3073 index_reset_slot = 167; 3068 index_reset_slot = 167;
3074 bg_end_slot = BG_START_SLOT + LINEBUF_SIZE/2; 3069 bg_end_slot = BG_START_SLOT + LINEBUF_SIZE/2;
3075 max_draws = MAX_DRAWS-1; 3070 max_draws = MAX_SPRITES_LINE-1;
3076 max_sprites = MAX_SPRITES_LINE; 3071 max_sprites = MAX_SPRITES_LINE;
3077 index_reset_value = 0x80; 3072 index_reset_value = 0x80;
3078 vint_slot = VINT_SLOT_H40; 3073 vint_slot = VINT_SLOT_H40;
3079 line_change = LINE_CHANGE_H40; 3074 line_change = LINE_CHANGE_H40;
3080 jump_start = 182; 3075 jump_start = 182;
3081 jump_dest = 229; 3076 jump_dest = 229;
3082 } else { 3077 } else {
3083 bg_end_slot = BG_START_SLOT + (256+HORIZ_BORDER)/2; 3078 bg_end_slot = BG_START_SLOT + (256+HORIZ_BORDER)/2;
3084 max_draws = MAX_DRAWS_H32-1; 3079 max_draws = MAX_SPRITES_LINE_H32-1;
3085 max_sprites = MAX_SPRITES_LINE_H32; 3080 max_sprites = MAX_SPRITES_LINE_H32;
3086 buf_clear_slot = 128; 3081 buf_clear_slot = 128;
3087 index_reset_slot = 132; 3082 index_reset_slot = 132;
3088 index_reset_value = 0x80; 3083 index_reset_value = 0x80;
3089 vint_slot = VINT_SLOT_H32; 3084 vint_slot = VINT_SLOT_H32;
3932 context->flags2 &= ~FLAG2_HINT_PENDING; 3927 context->flags2 &= ~FLAG2_HINT_PENDING;
3933 } 3928 }
3934 } 3929 }
3935 } 3930 }
3936 3931
3932 #define VDP_STATE_VERSION 1
3937 void vdp_serialize(vdp_context *context, serialize_buffer *buf) 3933 void vdp_serialize(vdp_context *context, serialize_buffer *buf)
3938 { 3934 {
3935 save_int8(buf, VDP_STATE_VERSION);
3939 save_int8(buf, VRAM_SIZE / 1024);//VRAM size in KB, needed for future proofing 3936 save_int8(buf, VRAM_SIZE / 1024);//VRAM size in KB, needed for future proofing
3940 save_buffer8(buf, context->vdpmem, VRAM_SIZE); 3937 save_buffer8(buf, context->vdpmem, VRAM_SIZE);
3941 save_buffer16(buf, context->cram, CRAM_SIZE); 3938 save_buffer16(buf, context->cram, CRAM_SIZE);
3942 save_buffer16(buf, context->vsram, VSRAM_SIZE); 3939 save_buffer16(buf, context->vsram, VSRAM_SIZE);
3943 save_buffer8(buf, context->sat_cache, SAT_CACHE_SIZE); 3940 save_buffer8(buf, context->sat_cache, SAT_CACHE_SIZE);
3988 //FIXME: Sprite rendering state is currently a mess 3985 //FIXME: Sprite rendering state is currently a mess
3989 save_int8(buf, context->sprite_index); 3986 save_int8(buf, context->sprite_index);
3990 save_int8(buf, context->sprite_draws); 3987 save_int8(buf, context->sprite_draws);
3991 save_int8(buf, context->slot_counter); 3988 save_int8(buf, context->slot_counter);
3992 save_int8(buf, context->cur_slot); 3989 save_int8(buf, context->cur_slot);
3993 for (int i = 0; i < MAX_DRAWS; i++) 3990 for (int i = 0; i < MAX_SPRITES_LINE; i++)
3994 { 3991 {
3995 sprite_draw *draw = context->sprite_draw_list + i; 3992 sprite_draw *draw = context->sprite_draw_list + i;
3996 save_int16(buf, draw->address); 3993 save_int16(buf, draw->address);
3997 save_int16(buf, draw->x_pos); 3994 save_int16(buf, draw->x_pos);
3998 save_int8(buf, draw->pal_priority); 3995 save_int8(buf, draw->pal_priority);
3999 save_int8(buf, draw->h_flip); 3996 save_int8(buf, draw->h_flip);
3997 save_int8(buf, draw->width);
3998 save_int8(buf, draw->height);
4000 } 3999 }
4001 for (int i = 0; i < MAX_SPRITES_LINE; i++) 4000 for (int i = 0; i < MAX_SPRITES_LINE; i++)
4002 { 4001 {
4003 sprite_info *info = context->sprite_info_list + i; 4002 sprite_info *info = context->sprite_info_list + i;
4004 save_int8(buf, info->size); 4003 save_int8(buf, info->size);
4013 } 4012 }
4014 4013
4015 void vdp_deserialize(deserialize_buffer *buf, void *vcontext) 4014 void vdp_deserialize(deserialize_buffer *buf, void *vcontext)
4016 { 4015 {
4017 vdp_context *context = vcontext; 4016 vdp_context *context = vcontext;
4018 uint8_t vramk = load_int8(buf); 4017 uint8_t version = load_int8(buf);
4018 uint8_t vramk;
4019 if (version == 64) {
4020 vramk = version;
4021 version = 0;
4022 } else {
4023 vramk = load_int8(buf);
4024 }
4025 if (version > VDP_STATE_VERSION) {
4026 warning("Save state has VDP version %d, but this build only understands versions %d and lower", version, VDP_STATE_VERSION);
4027 }
4019 load_buffer8(buf, context->vdpmem, (vramk * 1024) <= VRAM_SIZE ? vramk * 1024 : VRAM_SIZE); 4028 load_buffer8(buf, context->vdpmem, (vramk * 1024) <= VRAM_SIZE ? vramk * 1024 : VRAM_SIZE);
4020 if ((vramk * 1024) > VRAM_SIZE) { 4029 if ((vramk * 1024) > VRAM_SIZE) {
4021 buf->cur_pos += (vramk * 1024) - VRAM_SIZE; 4030 buf->cur_pos += (vramk * 1024) - VRAM_SIZE;
4022 } 4031 }
4023 load_buffer16(buf, context->cram, CRAM_SIZE); 4032 load_buffer16(buf, context->cram, CRAM_SIZE);
4075 context->buf_b_off = load_int8(buf) & SCROLL_BUFFER_MASK; 4084 context->buf_b_off = load_int8(buf) & SCROLL_BUFFER_MASK;
4076 context->sprite_index = load_int8(buf); 4085 context->sprite_index = load_int8(buf);
4077 context->sprite_draws = load_int8(buf); 4086 context->sprite_draws = load_int8(buf);
4078 context->slot_counter = load_int8(buf); 4087 context->slot_counter = load_int8(buf);
4079 context->cur_slot = load_int8(buf); 4088 context->cur_slot = load_int8(buf);
4080 for (int i = 0; i < MAX_DRAWS; i++) 4089 if (version == 0) {
4081 { 4090 int cur_draw = 0;
4082 sprite_draw *draw = context->sprite_draw_list + i; 4091 for (int i = 0; i < MAX_SPRITES_LINE * 2; i++)
4083 draw->address = load_int16(buf); 4092 {
4084 draw->x_pos = load_int16(buf); 4093 if (cur_draw < MAX_SPRITES_LINE) {
4085 draw->pal_priority = load_int8(buf); 4094 sprite_draw *last = cur_draw ? context->sprite_draw_list + cur_draw - 1 : NULL;
4086 draw->h_flip = load_int8(buf); 4095 sprite_draw *draw = context->sprite_draw_list + cur_draw++;
4096 draw->address = load_int16(buf);
4097 draw->x_pos = load_int16(buf);
4098 draw->pal_priority = load_int8(buf);
4099 draw->h_flip = load_int8(buf);
4100 draw->width = 1;
4101 draw->height = 8;
4102
4103 if (last && last->width < 4 && last->h_flip == draw->h_flip && last->pal_priority == draw->pal_priority) {
4104 int adjust_x = draw->x_pos + draw->h_flip ? -8 : 8;
4105 int height = draw->address - last->address /4;
4106 if (last->x_pos == adjust_x && (
4107 (last->width > 1 && height == last->height) ||
4108 (last->width == 1 && (height == 8 || height == 16 || height == 24 || height == 32))
4109 )) {
4110 //current draw appears to be part of the same sprite as the last one, combine it
4111 cur_draw--;
4112 last->width++;
4113 }
4114 }
4115 } else {
4116 load_int16(buf);
4117 load_int16(buf);
4118 load_int8(buf);
4119 load_int8(buf);
4120 }
4121 }
4122 } else {
4123 for (int i = 0; i < MAX_SPRITES_LINE; i++)
4124 {
4125 sprite_draw *draw = context->sprite_draw_list + i;
4126 draw->address = load_int16(buf);
4127 draw->x_pos = load_int16(buf);
4128 draw->pal_priority = load_int8(buf);
4129 draw->h_flip = load_int8(buf);
4130 draw->width = load_int8(buf);
4131 draw->height = load_int8(buf);
4132 }
4087 } 4133 }
4088 for (int i = 0; i < MAX_SPRITES_LINE; i++) 4134 for (int i = 0; i < MAX_SPRITES_LINE; i++)
4089 { 4135 {
4090 sprite_info *info = context->sprite_info_list + i; 4136 sprite_info *info = context->sprite_info_list + i;
4091 info->size = load_int8(buf); 4137 info->size = load_int8(buf);