~ubuntu-branches/ubuntu/raring/vice/raring

« back to all changes in this revision

Viewing changes to src/vicii/vicii-sprites.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-03-31 00:37:15 UTC
  • mfrom: (1.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: james.westby@ubuntu.com-20090331003715-mzclchtl0dp7fcl0
Tags: upstream-2.1.dfsg
ImportĀ upstreamĀ versionĀ 2.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
#define X_OFFSET vicii.screen_leftborderwidth
51
51
 
52
 
#define SPRITE_EXPANDED_REPEAT_PIXELS_START(n) (0x11a + X_OFFSET + n * 0x10)
53
 
#define SPRITE_NORMAL_REPEAT_PIXELS_START(n) (0x132 + X_OFFSET + n * 0x10)
54
 
#define SPRITE_REPEAT_PIXELS_END(n) (0x157 + X_OFFSET + n * 0x10)
 
52
#define SPRITE_EXPANDED_REPEAT_PIXELS_START(n) (vicii.sprite_wrap_x < 0x200 ? \
 
53
                                               (0x11a + X_OFFSET + n * 0x10) :\
 
54
                                               (0x122 + X_OFFSET + n * 0x10))
 
55
 
 
56
#define SPRITE_NORMAL_REPEAT_PIXELS_START(n) (vicii.sprite_wrap_x < 0x200 ? \
 
57
                                             (0x132 + X_OFFSET + n * 0x10) :\
 
58
                                             (0x13a + X_OFFSET + n * 0x10))
 
59
 
 
60
#define SPRITE_REPEAT_PIXELS_END(n) (vicii.sprite_wrap_x < 0x200 ? \
 
61
                                    (0x157 + X_OFFSET + n * 0x10) :  \
 
62
                                    (0x15f + X_OFFSET + n * 0x10))
55
63
/* where the sprite pixels start repeating */
56
64
#define SPRITE_REPEAT_BEGIN(n) (SPRITE_REPEAT_PIXELS_END(n) - 0xc)
57
65
 
524
532
    int must_repeat_pixels = 0;
525
533
    DWORD repeat_pixel = 0;
526
534
    int i;
 
535
    int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
 
536
                            % vicii.sprite_wrap_x;
527
537
 
528
538
    sprmsk = sprite_doubling_table[(data_ptr[0] << 8) | data_ptr[1]];
529
539
 
530
 
    if (sprite_status->sprites[n].x > SPRITE_EXPANDED_REPEAT_PIXELS_START(n)
531
 
        && sprite_status->sprites[n].x < SPRITE_REPEAT_PIXELS_END(n)) {
 
540
    
 
541
    if (spritex_unwrapped > SPRITE_EXPANDED_REPEAT_PIXELS_START(n)
 
542
        && spritex_unwrapped < SPRITE_REPEAT_PIXELS_END(n)) {
532
543
        /* sprite #n repeats pixel SPRITE_REPEAT_BEGIN(n)-1 up to SPRITE_REPEAT_BEGIN(n)+6 */ 
533
544
        /* no display from SPRITE_REPEAT_BEGIN(n)+7 to SPRITE_REPEAT_BEGIN(n)+11           */
534
 
        size = SPRITE_REPEAT_BEGIN(n) - sprite_status->sprites[n].x;
 
545
        size = SPRITE_REPEAT_BEGIN(n) - spritex_unwrapped;
535
546
        must_repeat_pixels = (size > 0);
536
547
        if (size1 > size)
537
548
            size1 = size;
629
640
    int must_repeat_pixels = 0;
630
641
    DWORD repeat_pixel;
631
642
    int i;
 
643
    int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
 
644
                            % vicii.sprite_wrap_x;
632
645
 
633
646
    sprmsk = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2];
634
647
 
635
 
    if (sprite_status->sprites[n].x > SPRITE_NORMAL_REPEAT_PIXELS_START(n)
636
 
        && sprite_status->sprites[n].x < SPRITE_REPEAT_PIXELS_END(n)) {
 
648
    if (spritex_unwrapped > SPRITE_NORMAL_REPEAT_PIXELS_START(n)
 
649
        && spritex_unwrapped < SPRITE_REPEAT_PIXELS_END(n)) {
637
650
        /* sprite #n repeats pixel SPRITE_REPEAT_BEGIN(n)-1 up to SPRITE_REPEAT_BEGIN(n)+6 */ 
638
651
        /* no display from SPRITE_REPEAT_BEGIN(n)+7 to SPRITE_REPEAT_BEGIN(n)+11           */
639
 
        size = SPRITE_REPEAT_BEGIN(n) - sprite_status->sprites[n].x;
 
652
        size = SPRITE_REPEAT_BEGIN(n) - spritex_unwrapped;
640
653
        must_repeat_pixels = (size > 0);
641
654
 
642
655
        if (must_repeat_pixels) {
707
720
    BYTE cmsk = 0, sbit = 1 << n;
708
721
    BYTE data0, data1;
709
722
    int trim_size;
 
723
    int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
 
724
                            % vicii.sprite_wrap_x;
710
725
 
711
726
    mcsprmsk = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2];
712
727
    collmsk = ((((msk_ptr[1] << 24) | (msk_ptr[2] << 16)
740
755
        mcsprmsk &= ~(1 << (22 - (sprite_xs >> 1) + delayed_shift));
741
756
 
742
757
    /* Fixes for the "Repeated pixels" bug */
743
 
    if (sprite_status->sprites[n].x > SPRITE_EXPANDED_REPEAT_PIXELS_START(n)
744
 
        && sprite_status->sprites[n].x < SPRITE_REPEAT_PIXELS_END(n)) {
 
758
    if (spritex_unwrapped > SPRITE_EXPANDED_REPEAT_PIXELS_START(n)
 
759
        && spritex_unwrapped < SPRITE_REPEAT_PIXELS_END(n)) {
745
760
        /* sprite #n repeats pixel SPRITE_REPEAT_BEGIN(n)-1 up to SPRITE_REPEAT_BEGIN(n)+6 */ 
746
761
        /* no display from SPRITE_REPEAT_BEGIN(n)+7 to SPRITE_REPEAT_BEGIN(n)+11           */
747
 
        size = SPRITE_REPEAT_BEGIN(n) - sprite_status->sprites[n].x;
 
762
        size = SPRITE_REPEAT_BEGIN(n) - spritex_unwrapped;
748
763
        if (size < 0)
749
764
            size = 0;
750
765
        must_repeat_pixels = (size > 0);
861
876
    int delayed_shift;
862
877
    BYTE data0, data1, data2;
863
878
    int trim_size;
 
879
    int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
 
880
                            % vicii.sprite_wrap_x;
864
881
 
865
882
    mcsprmsk = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2];
866
883
    collmsk = ((((msk_ptr[0] << 24) | (msk_ptr[1] << 16)
891
908
             | mcsprtable[data2]);
892
909
    }
893
910
 
894
 
    if (sprite_status->sprites[n].x > SPRITE_NORMAL_REPEAT_PIXELS_START(n)
895
 
        && sprite_status->sprites[n].x < SPRITE_REPEAT_PIXELS_END(n)) {
 
911
    if (spritex_unwrapped > SPRITE_NORMAL_REPEAT_PIXELS_START(n)
 
912
        && spritex_unwrapped < SPRITE_REPEAT_PIXELS_END(n)) {
896
913
        /* sprite #n repeats pixel SPRITE_REPEAT_BEGIN(n)-1 up to SPRITE_REPEAT_BEGIN(n)+6 */ 
897
914
        /* no display from SPRITE_REPEAT_BEGIN(n)+7 to SPRITE_REPEAT_BEGIN(n)+11           */
898
 
        size = SPRITE_REPEAT_BEGIN(n) - sprite_status->sprites[n].x;
 
915
        size = SPRITE_REPEAT_BEGIN(n) - spritex_unwrapped;
899
916
        if (size < 0)
900
917
            size = 0;
901
918
        must_repeat_pixels = (size > 0);
1043
1060
 
1044
1061
        msk_ptr = gfx_msk_ptr
1045
1062
                  + (VICII_MAX_SPRITE_WIDTH + sprite_offset
1046
 
                    - VICII_RASTER_X(0) - vicii.raster.xsmooth) / 8;
 
1063
                    - VICII_RASTER_X(0) - vicii.raster.sprite_xsmooth) / 8;
1047
1064
        ptr = line_ptr + sprite_offset;
1048
1065
        lshift = (sprite_offset
1049
 
                 - vicii.raster.xsmooth) & 0x7;
 
1066
                 - vicii.raster.sprite_xsmooth) & 0x7;
1050
1067
        sptr = sprline - VICII_RASTER_X(0) + sprite_offset;
1051
1068
 
1052
1069
        if (sprite_status->sprites[n].multicolor)
1143
1160
 
1144
1161
/* Set the X coordinate of the `num'th sprite to `new_x'; the current
1145
1162
   vicii.raster X position is `raster_x'.  */
1146
 
/* FIXME: This is a beast and most probably not cycle exact */
1147
1163
void vicii_sprites_set_x_position(unsigned int num, int new_x, int raster_x)
1148
1164
{
1149
1165
    raster_sprite_t *sprite;
1150
1166
    int x_offset;
 
1167
    int last_pos;
 
1168
    int next_pos;
 
1169
    int change_pos;
1151
1170
 
1152
1171
    sprite = vicii.raster.sprite_status->sprites + num;
1153
1172
 
1154
 
    x_offset = vicii.screen_leftborderwidth - 24;
 
1173
    x_offset = vicii_sprite_offset();
 
1174
 
 
1175
    /* Handle spritegap in NTSC mode */
 
1176
    if (vicii.sprite_wrap_x > 0x200 && (unsigned int)new_x > 0x187)
 
1177
        new_x += (vicii.sprite_wrap_x - 0x200);
1155
1178
 
1156
1179
    new_x += x_offset;
1157
1180
 
 
1181
    /* transfer coordinates to a new timeline starting with memory fetch to
 
1182
       make calculation easier */
 
1183
    next_pos = (new_x - SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num)
 
1184
                    + vicii.sprite_wrap_x) % vicii.sprite_wrap_x;
 
1185
    last_pos = (sprite->x - SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num)
 
1186
                    + 2 * vicii.sprite_wrap_x) % vicii.sprite_wrap_x;
 
1187
    change_pos = (raster_x + 8 - SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num)
 
1188
                    + 2 * vicii.sprite_wrap_x) % vicii.sprite_wrap_x;
 
1189
 
 
1190
    /* disabled display is at the very end even on the transfered timeline */
 
1191
    if (sprite->x == vicii.sprite_wrap_x)
 
1192
        last_pos = vicii.sprite_wrap_x;
 
1193
 
1158
1194
    if (new_x >= vicii.sprite_wrap_x + VICII_RASTER_X(0)) {
1159
1195
        /* Sprites in the $1F8 - $1FF range are not visible at all and never
1160
1196
           cause collisions.  */
1161
 
        if (new_x >= 0x1f8 + x_offset)
 
1197
        if (new_x >= vicii.sprite_wrap_x + x_offset)
1162
1198
            new_x = vicii.sprite_wrap_x;
1163
1199
        else
1164
1200
            new_x -= vicii.sprite_wrap_x;
1165
1201
    }
1166
1202
 
1167
 
    if (new_x < sprite->x) {
1168
 
        if (raster_x + x_offset <= new_x
1169
 
            && sprite->x < (int)SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num))
 
1203
    if (next_pos < last_pos) {
 
1204
        if (change_pos <= next_pos)
1170
1205
        {
1171
 
            sprite->x = new_x;
 
1206
            if (raster_x + 8  > new_x) {
 
1207
                /* last line was already drawn */
 
1208
                raster_changes_sprites_add_int(&vicii.raster,
 
1209
                    SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num),
 
1210
                    &sprite->x, new_x);
 
1211
            } else {
 
1212
                sprite->x = new_x;
 
1213
            }
1172
1214
        } else {
1173
 
            if (raster_x + x_offset < sprite->x)
 
1215
            if (change_pos <= last_pos) {
 
1216
                /* too early to start at last_pos and too late to start
 
1217
                   at next_pos; disable display on this line */
1174
1218
                sprite->x = vicii.sprite_wrap_x;
 
1219
            } else {
 
1220
                /* display already started on last_pos, change on next fetch */
 
1221
                if (raster_x + 8  < new_x && sprite->x > raster_x + 8) {
 
1222
                    /* last line was already drawn */
 
1223
                    sprite->x = new_x;
 
1224
                } else {
 
1225
                    raster_changes_sprites_add_int(&vicii.raster,
 
1226
                        SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num),
 
1227
                        &sprite->x, new_x);
 
1228
                }
 
1229
            }
1175
1230
        }
1176
 
        raster_changes_next_line_add_int(&vicii.raster, &sprite->x, new_x);
1177
1231
    } else {
1178
 
        /* new_x >= sprite->x */
1179
 
        if (new_x >= (int)SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num)
1180
 
            && sprite->x < (int)SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num))
1181
 
        {
1182
 
            raster_changes_sprites_add_int(&vicii.raster,
1183
 
                                            raster_x, &sprite->x, new_x);
1184
 
        }
1185
 
        if (raster_x + x_offset < sprite->x
1186
 
            && sprite->x < (int)SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num))
1187
 
        {
1188
 
            sprite->x = new_x;
1189
 
        }
1190
 
        raster_changes_next_line_add_int(&vicii.raster, &sprite->x, new_x);
 
1232
        /* next_pos >= last_pos */
 
1233
        if (change_pos <= last_pos) {
 
1234
            if (raster_x + 8  > new_x) {
 
1235
                /* last line was already drawn */
 
1236
                raster_changes_sprites_add_int(&vicii.raster,
 
1237
                    SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num),
 
1238
                    &sprite->x, new_x);
 
1239
            } else {
 
1240
                sprite->x = new_x;
 
1241
            }
 
1242
        } else {
 
1243
            if (change_pos >= next_pos) {
 
1244
                if (raster_x + 8  < sprite->x && new_x > raster_x + 8) {
 
1245
                    /* last line was already drawn */
 
1246
                    sprite->x = new_x;
 
1247
                } else {
 
1248
                    /* display already started on last_pos, change on next fetch */
 
1249
                    raster_changes_sprites_add_int(&vicii.raster,
 
1250
                        SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num), &sprite->x, new_x);
 
1251
                }
 
1252
            }
 
1253
        }
1191
1254
    }
 
1255
    raster_changes_sprites_add_int(&vicii.raster,
 
1256
        SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num), &sprite->x, new_x);
1192
1257
}
1193
1258
 
1194
1259
void vicii_sprites_reset_xshift(void)
1221
1286
    lib_free(sprline);
1222
1287
}
1223
1288
 
 
1289
int vicii_sprite_offset(void)
 
1290
{
 
1291
    return vicii.screen_leftborderwidth - 24;
 
1292
}