level_sp->header.DemoRandomSeed = tape.random_seed;
demo->length = 0;
+
for (i = 0; i < tape.length; i++)
{
int demo_action = map_key_RND_to_SP(tape.pos[i].action[0]);
int demo_repeat = tape.pos[i].delay;
+ int demo_entries = (demo_repeat + 15) / 16;
+
+ if (demo->length + demo_entries >= SP_MAX_TAPE_LEN)
+ {
+ Error(ERR_WARN, "tape truncated: size exceeds maximum SP demo size %d",
+ SP_MAX_TAPE_LEN);
+
+ break;
+ }
for (j = 0; j < demo_repeat / 16; j++)
demo->data[demo->length++] = 0xf0 | demo_action;
demo->data[demo->length++] = ((demo_repeat % 16 - 1) << 4) | demo_action;
}
- demo->data[demo->length++] = 0xff;
-
demo->is_available = TRUE;
}
return;
tape.level_nr = demo->level_nr; /* (currently not used) */
- tape.length = demo->length - 1; /* without "end of demo" byte */
tape.random_seed = level_sp->header.DemoRandomSeed;
TapeSetDateFromEpochSeconds(getFileTimestampEpochSeconds(filename));
- for (i = 0; i < demo->length - 1; i++)
+ tape.length = 0;
+ tape.pos[tape.length].delay = 0;
+
+ for (i = 0; i < demo->length; i++)
{
int demo_action = demo->data[i] & 0x0f;
int demo_repeat = (demo->data[i] & 0xf0) >> 4;
+ int tape_action = map_key_SP_to_RND(demo_action);
+ int tape_repeat = demo_repeat + 1;
+ int tape_entries = 1; // one new tape entry may be added
+
+ if (tape.length + tape_entries >= MAX_TAPE_LEN)
+ {
+ Error(ERR_WARN, "SP demo truncated: size exceeds maximum tape size %d",
+ MAX_TAPE_LEN);
+
+ break;
+ }
- tape.pos[i].action[0] = map_key_SP_to_RND(demo_action);
- tape.pos[i].delay = demo_repeat + 1;
+ if (tape.pos[tape.length].delay > 0) /* already stored action */
+ {
+ if (tape.pos[tape.length].action[0] != tape_action ||
+ tape.pos[tape.length].delay + tape_repeat >= 256)
+ {
+ tape.length++;
+ tape.pos[tape.length].delay = 0;
+ }
+ else
+ {
+ tape.pos[tape.length].delay += tape_repeat;
+ }
+ }
+
+ if (tape.pos[tape.length].delay == 0) /* store new action */
+ {
+ tape.pos[tape.length].action[0] = tape_action;
+ tape.pos[tape.length].delay = tape_repeat;
+ }
}
+ tape.length++;
+
tape.length_frames = GetTapeLengthFrames();
tape.length_seconds = GetTapeLengthSeconds();
}