Skip to content

Commit

Permalink
Allow disabling the time limit completely
Browse files Browse the repository at this point in the history
By setting `start_minutes_left` to -1 (or another negative number) the time limit can be disabled.
This also disables the in-game messages that report how much time is left every minute.
The elasped time is still kept track of, so that the shortest times will appear in the Hall of Fame (in ascending order, counting upwards from 0:00).
I changed the `rem_min` to a signed short integer to make this work.
(I wonder if `rem_min` was signed in the original DOS source... At least I suppose they did not count on large values, because they used a (signed) `%d` in the formatting string `%d MINUTES LEFT`)
  • Loading branch information
Falcury committed Sep 6, 2016
1 parent b138aef commit d63893f
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 4 deletions.
1 change: 1 addition & 0 deletions SDLPoP.ini
Expand Up @@ -161,6 +161,7 @@ fix_jump_through_wall_above_gate = false

[CustomGameplay]
; Starting minutes left. (default = 60)
; To disable the time limit completely, set this to -1.
;start_minutes_left = 60

; Starting number of ticks left in the first minute. (default = 719)
Expand Down
6 changes: 6 additions & 0 deletions src/config.h
Expand Up @@ -83,6 +83,12 @@ The authors of this program may be contacted at http://forum.princed.org
// Allow guard hitpoints not resetting to their default (maximum) value when re-entering the room
#define REMEMBER_GUARD_HP

// Enable completely disabling the time limit. To use this feature, set the starting time to -1.
// This also disables the in-game messages that report how much time is left every minute.
// The elasped time is still kept track of, so that the shortest times will appear in the Hall of Fame.
#define ALLOW_INFINITE_TIME


// Bugfixes:

// The mentioned tricks can be found here: http://www.popot.org/documentation.php?doc=Tricks
Expand Down
2 changes: 1 addition & 1 deletion src/data.h
Expand Up @@ -46,7 +46,7 @@ extern word resurrect_time;
// data:42B4
extern word dont_reset_time;
// data:4F7E
extern word rem_min;
extern short rem_min;
// data:4F82
extern word rem_tick;
// data:4608
Expand Down
21 changes: 19 additions & 2 deletions src/seg000.c
Expand Up @@ -335,7 +335,7 @@ int quick_load() {
screen_updates_suspended = 0;
request_screen_update();
screen_updates_suspended = 1;
word old_rem_min = rem_min;
short old_rem_min = rem_min;
word old_rem_tick = rem_tick;

ok = quick_process(process_load);
Expand All @@ -359,7 +359,9 @@ int quick_load() {
}
else {
if (rem_min == 6) rem_tick = 719; // crop to "5 minutes" exactly, if hitting the threshold in <1 minute
if (rem_min > 5) --rem_min;
if (rem_min > 5 /*be lenient, not much time left*/ || rem_min < 0 /*time runs 'forward' if < 0*/) {
--rem_min;
}
}

}
Expand Down Expand Up @@ -577,13 +579,28 @@ int __pascal far process_key() {
case SDL_SCANCODE_MINUS:
case SDL_SCANCODE_KP_MINUS: // '-' --> subtract time cheat
if (rem_min > 1) --rem_min;

#ifdef ALLOW_INFINITE_TIME
else if (rem_min < -1) ++rem_min; // if negative/infinite, time runs 'forward'
else if (rem_min == -1) rem_tick = 720; // resets the timer to 00:00:00
#endif

text_time_total = 0;
text_time_remaining = 0;
is_show_time = 1;
break;
case SDL_SCANCODE_EQUALS | WITH_SHIFT: // '+'
case SDL_SCANCODE_KP_PLUS: // '+' --> add time cheat

#ifdef ALLOW_INFINITE_TIME
if (rem_min < 0) { // if negative/infinite, time runs 'forward'
if (rem_min > INT16_MIN) --rem_min;
}
else ++rem_min;
#else
++rem_min;
#endif

text_time_total = 0;
text_time_remaining = 0;
is_show_time = 1;
Expand Down
15 changes: 15 additions & 0 deletions src/seg001.c
Expand Up @@ -724,7 +724,22 @@ void __pascal far show_hof() {
short index;
char time_text[12];
for (index = 0; index < hof_count; ++index) {

#ifdef ALLOW_INFINITE_TIME
int minutes, seconds;
if (hof[index].min > 0) {
minutes = hof[index].min - 1;
seconds = hof[index].tick / 12;
} else {
// negative minutes means time ran 'forward' from 0:00 upwards
minutes = abs(hof[index].min) - 1;
seconds = (719 - hof[index].tick) / 12;
}
snprintf(time_text, sizeof(time_text), "%d:%02d", minutes, seconds);
#else
snprintf(time_text, sizeof(time_text), "%d:%02d", hof[index].min - 1, hof[index].tick / 12);
#endif

show_hof_text(&hof_rects[index], -1, 0, hof[index].name);
show_hof_text(&hof_rects[index], 1, 0, time_text);
}
Expand Down
6 changes: 5 additions & 1 deletion src/seg003.c
Expand Up @@ -349,7 +349,11 @@ int __pascal far play_level_2() {
#ifdef USE_DEBUG_CHEATS
if (debug_cheats_enabled && is_timer_displayed) {
char timer_text[16];
snprintf(timer_text, 16, "%02d:%02d:%02d", rem_min - 1, rem_tick / 12, rem_tick % 12);
if (rem_min < 0) {
snprintf(timer_text, 16, "%02d:%02d:%02d", -(rem_min + 1), (719 - rem_tick) / 12, (719 - rem_tick) % 12);
} else {
snprintf(timer_text, 16, "%02d:%02d:%02d", rem_min - 1, rem_tick / 12, rem_tick % 12);
}
screen_updates_suspended = 1;
draw_rect(&timer_rect, color_0_black);
show_text(&timer_rect, -1, -1, timer_text);
Expand Down
9 changes: 9 additions & 0 deletions src/seg008.c
Expand Up @@ -1689,6 +1689,10 @@ void __pascal far show_time() {
#ifdef FREEZE_TIME_DURING_END_MUSIC
(!(options.enable_freeze_time_during_end_music && next_level != current_level)) &&
#endif
#ifdef ALLOW_INFINITE_TIME
// prevent overflow
(!(rem_min == INT16_MIN && rem_tick == 1)) &&
#endif
rem_min != 0 &&
(current_level < 13 || (current_level == 13 && leveldoor_open == 0)) &&
current_level < 15
Expand Down Expand Up @@ -1724,6 +1728,11 @@ void __pascal far show_time() {
}
display_text_bottom(sprintf_temp);
} else {

#ifdef ALLOW_INFINITE_TIME
if (rem_min == 0) // may also be negative, don't report "expired" in that case!
#endif

display_text_bottom("TIME HAS EXPIRED!");
}
is_show_time = 0;
Expand Down

1 comment on commit d63893f

@NagyD
Copy link
Owner

@NagyD NagyD commented on d63893f Sep 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if rem_min was signed in the original DOS source...

I guess it was:
In the disassembly, the cmp rem_min, <number> is followed by jle and jl for <= and < comparisons.
In x86 assembly, jle is the signed less-or-equal, while the unsigned version would be jbe (below-or-equal).

Probably most other variables that are currently declared as unsigned were signed instead, but there is no visible difference due to the way they are used. (Boolean variables are a good example of this.)

Please sign in to comment.