The camera catches up
A camera that snaps to the player is unwatchable, so games ease: every frame, move some fraction of the remaining distance. The fraction is always a power of two, because the alternative is a call to __divsi3, and then the result is clamped so the view never runs off the edge of the level.
The distance to close is a subtraction, and it is negative every time the player moves left or up. That matters more than it looks, because C's / and >> do different things to a negative number. / truncates toward zero; >> rounds toward negative infinity. On a machine with no divider, the compiler implements the first by biasing the value before shifting:
0 add r0, r1
2 cmp r0, #0
4 bge 8 ~>
6 add r0, #31
8 ~>asr r0, #5
10 bx lr
The same expression written with a shift skips all of that:
0 add r0, r1
2 asr r0, #5
4 bx lr
And on unsigned values the question does not arise, so even a / compiles to a single instruction:
0 add r0, r1
2 lsr r0, #5
4 bx lr
Three spellings, three lengths, and the middle one differs from the first by one whenever the value is negative and not an exact multiple of 32. On a camera that shows up as behaviour: while the remaining distance is negative and smaller than the divisor, the shift still moves the view one unit a frame, and the divide truncates that step to zero and parks the view short of its target.
Your target eases twice, and only one of the two pays for the bias. Check every asr for a cmp/add pair leading into it before you decide what the source said, because the two axes were not written the same way and you have to reproduce both.
Your task
Write func_0842b7f8 to reproduce the target assembly.