19 users online:  AmperSam, Angelito, anonimzwx,  Anorakun, Buzbee, CalHal, dotCoockie, GamesInTweed, GangsterJerby, GbreezeSunset, Jakeapus, jspolley, Luztruz, Morph Moth, PhantasyReal, PuffleDreemurr, Supertails,  Thomas, YouFailMe - Guests: 99 - Bots: 173
Users: 62,816 (2,619 active)
Latest user: jspolley

Integrated Speedrun Timer v1.2 by BlueToad

File Name: Integrated Speedrun Timer v1.2
Submitted: by BlueToad
Authors: BlueToad
Type: Level, Game Mode
Includes GFX: No
Includes Hijack: No
Featured: No
Description: This is an UberASM which draws a timer on the status bar, which counts for how much time you have been in the level. It will pause whenever the game freezes, is paused or when a message box is active. When the level is completed it will stop and change palette to denote that the level has ended. Requires Super Status Bar patch.

You can also disable the timer in upto 5 levels. This might be useful when you don't want the timer running in Yoshi's House, or during the intro message, for instance.

Uses 6 bytes of free RAM. Use it as level ASM or use it in Game Mode 14 to apply to all levels.

Requested by DoktorGroove.

Screenshot 1: Showing the timer itself.
Screenshots 2, 3, and 4: Timer stops and changes palette when a goal tape is touched, a palace switch is hit, or when a boss is defeated.
Screenshot 5: Timer freezes when animations and sprites are frozen.
Screenshot 6 and 7: Timer does not show up during No Yoshi intros.
Screenshot 8: When started from the midway point, the timer does not show up.

v1.1 update 9/8/2021: optimized a lot of the code, and made it use one less byte of free RAM.
v1.2 update 11/8/2021: optimized the code a bit more, and fixed a bug about the timer appearing in No Yoshi intros.
Tags: hud, speedrun, status bar, time, timer
We decided to remove it under the basis of lack of optimisation.

The first optimisation which could be done is the level check: Currently, the timer only allows you to make exceptions for up to five different levels (more specifically, sublevels, not translevels so you can't make an exception to a greater HUB area). A table is a better choice even if a bit more wasteful for a smaller amount of levels.

The second optimisation is the return parameter of freezecheck: You're using scratch RAM to denote whether to run the timer or not. The problem is that there is a better way in for m of the zero or carry flag and then immediately return from the routine should the timer not run or be displayed.

A third optimisation is the check of the midway flag:
LDX $13BF	; Index
LDA $1EA2,X	;Check midway touched.
STA $01
ORA #$40
CMP $01
STZ $00
+	;If touched, don't do anything.

Please use AND or BIT for that, using ORA and scratch RAM is plain overkill.

For the fourth and optimisation, I criticise the way on how you handle the timer:
	INC !FR1	;Increment correctly
	LDA #$04
	BEQ decback
	LDA #$09
	BEQ decback
	JMP cont

	LDA #$0A	; Check overflow for centisecond.
	CMP !FR1	
	BEQ centi
	JMP skip

	INC !FR2	; Check overflow for 10*centisecond.
	LDA #$0A
	CMP !FR2	
	BEQ deci
	JMP skip

	LDA #$0A	; Second
	CMP !FR3	
	BEQ sec
	JMP skip

	LDA #$06	; 10Second
	CMP !FR4	
	BEQ tensec
	JMP skip
	LDA #$0A	; Minute
	CMP !FR5	
	BEQ min
	JMP skip

	LDA #$0A	; 10Minute
	CMP !FR6	
	BEQ tenmin
	JMP skip

You use six bytes of freeRAM, one for each digit. The thing is that SMW only does this for the level timer (for some weird reason) but not for any other counter because not only are these easier to handle but these also save on freeRAM (and those which you have chosen are very often used). SMW provides a Hex2Dec routine at $00974C which allows you to convert the digits into a decimal representation.
For centiseconds, you can simply use the centiseconds as a frame counter (i.e. it counts from 0 to 59) but multiply the number by 99/59 which can be easily done with the multiplication and division registers.

Lastly, the position of the timer is hardcoded and can't be changed with a define. This essentially prevents most users from setting the timer at any position unless they know what they're doing and it also prevents them from changing the freeRAM destination of the status bar so they're stuck with the default LoROM address.

In addition, it would be nice if you made the resource SA-1 compatible which simply means in this case, stick a |!addr after every absolute WRAM access (i.e. $0000-$1FFF) and, as mentioned before, turn the status bar destination into a define so you can use the SA-1 freeRAM.