50
50
#define X_OFFSET vicii.screen_leftborderwidth
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))
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))
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)
524
532
int must_repeat_pixels = 0;
525
533
DWORD repeat_pixel = 0;
535
int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
536
% vicii.sprite_wrap_x;
528
538
sprmsk = sprite_doubling_table[(data_ptr[0] << 8) | data_ptr[1]];
530
if (sprite_status->sprites[n].x > SPRITE_EXPANDED_REPEAT_PIXELS_START(n)
531
&& sprite_status->sprites[n].x < SPRITE_REPEAT_PIXELS_END(n)) {
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)
629
640
int must_repeat_pixels = 0;
630
641
DWORD repeat_pixel;
643
int spritex_unwrapped = (sprite_status->sprites[n].x + vicii.sprite_wrap_x)
644
% vicii.sprite_wrap_x;
633
646
sprmsk = (data_ptr[0] << 16) | (data_ptr[1] << 8) | data_ptr[2];
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);
642
655
if (must_repeat_pixels) {
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)
1149
1165
raster_sprite_t *sprite;
1152
1171
sprite = vicii.raster.sprite_status->sprites + num;
1154
x_offset = vicii.screen_leftborderwidth - 24;
1173
x_offset = vicii_sprite_offset();
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);
1156
1179
new_x += x_offset;
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;
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;
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;
1164
1200
new_x -= vicii.sprite_wrap_x;
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)
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),
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;
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 */
1225
raster_changes_sprites_add_int(&vicii.raster,
1226
SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num),
1176
raster_changes_next_line_add_int(&vicii.raster, &sprite->x, new_x);
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))
1182
raster_changes_sprites_add_int(&vicii.raster,
1183
raster_x, &sprite->x, new_x);
1185
if (raster_x + x_offset < sprite->x
1186
&& sprite->x < (int)SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num))
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),
1243
if (change_pos >= next_pos) {
1244
if (raster_x + 8 < sprite->x && new_x > raster_x + 8) {
1245
/* last line was already drawn */
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);
1255
raster_changes_sprites_add_int(&vicii.raster,
1256
SPRITE_DISPLAY_IMMEDIATE_DATA_FETCHED(num), &sprite->x, new_x);
1194
1259
void vicii_sprites_reset_xshift(void)