MacOS : Circus Linux update, SDL changes

Circus Linux is now looking really good :wink: The only bug is that the cursor
doesn’t stay hidden (Has this been seen on other platforms?).

I updated the .sit file (still in same location, see previous post). I made
a few mods to SDL to improve things. The mouse response went from lousy to
excellent by adding this code to poll instead of wait for mouse moved
events.

/* The main MacOS event handler */
static int Mac_HandleEvents(_THIS, int wait4it)
{
static Point old_mouse;
Point new_mouse;

UInt32 wait_time;
EventRecord event;
int posted;

/* Are we polling or not? */
if ( wait4it ) {
    wait_time = 2147483647;
} else {
    wait_time = 0;
}

// GetGlobalMouse (&new_mouse); // -dw- the Carbon way
new_mouse = LMGetMouseLocation ();
if ( (old_mouse.h != new_mouse.h) ||
     (old_mouse.v != new_mouse.v)   ) {

  old_mouse = new_mouse;
  
  GlobalToLocal(&new_mouse);
  
  posted = SDL_PrivateMouseMotion(0, 0, new_mouse.h, new_mouse.v);
  
  return(1);
}

I also changed the Delay function to be more accurate. Also, I have heard
that the Delay() call is not recommended.

void SDL_Delay(Uint32 ms)
{
UnsignedWide ms_init, ms_final;

ms_final.lo = 0;

Microseconds (&ms_init);
while ( (ms_final.lo - ms_init.lo) < 1000 * ms ) {

   SystemTask (); // maybe WaitNextEvent() here?
   
   Microseconds (&ms_final);
}

}

Any mistakes here?
Maybe I should have used UpTime() ?

Thanks,
Darrell

I also changed the Delay function to be more accurate. Also, I have heard
that the Delay() call is not recommended.

Matt Slot posted his fast and accurate timer code a while back. It looked
quite good, maybe you should use that instead? At least for SDL_GetTicks()
which is in sore need of replacement

I also changed the Delay function to be more accurate. Also, I have heard
that the Delay() call is not recommended.

Matt Slot posted his fast and accurate timer code a while back. It looked
quite good, maybe you should use that instead? At least for SDL_GetTicks()
which is in sore need of replacement

I tried Matt’s code, and it hung my Mac :frowning:

Here is my final implementation. I think microsecond is pretty darned fast,
except on old Macs. Circus Linux runs at a steady 33 fps now.

Uint32 SDL_GetTicks(void)
{
UnsignedWide ms;

Microseconds (&ms);

return ( ms.lo / 1000 );

}

void SDL_Delay(Uint32 ms)
{

UnsignedWide microsecs;
UInt32       stop;

Microseconds (&microsecs);

stop = microsecs.lo + (ms * 1000);

while ( stop > microsecs.lo ) {

   SystemTask ();
   
   Microseconds (&microsecs);
} 

}

Here is my final implementation. I think microsecond is pretty darned fast,

I did a little research, and your implementation won’t work if the
lo portion of the time value wraps.

Does this work? Is it fast enough?

#define kTwoPower32 (4294967296.0) /* 2^32 */

static double start_tick;

void SDL_StartTicks(void)
{
UnsignedWide us;

    Microseconds (&us);
    start_tick = (((double) us.hi) * kTwoPower32) + us.lo;

}

Uint32 SDL_GetTicks(void)
{
register double this_tick;
UnsignedWide us;

    Microseconds (&us);
    this_tick = (((double) us.hi) * kTwoPower32) + us.lo;

    return (Uint32)((this_tick-start_tick)/1000.0);

}

void SDL_Delay(Uint32 ms)
{
Uint32 stop, now;

    stop = SDL_GetTicks() + ms;
    do {
            SystemTask();

            now = SDL_GetTicks();

    } while ( stop > now );

}

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

In article <B5B0F7A3.C191%dwaliss1 at purdue.edu>, sdl at lokigames.com wrote:

I tried Matt’s code, and it hung my Mac :frowning:

I’ve posted several updates over the last couple months. As far as I know,
the currently posted code works fine. If you can try out the latest version
and let me know how it works – and I’ll help track down and fix any bugs
you find.

http://www.ambrosiasw.com/~fprefect/FastTimes.sit.bin

Matt–
/* Matt Slot, Bitwise Operator * One box, two box, yellow box, blue box *

In article <B5B0F7A3.C191%dwaliss1 at purdue.edu>, sdl at lokigames.com wrote:

I tried Matt’s code, and it hung my Mac :frowning:

I’ve posted several updates over the last couple months. As far as I know,
the currently posted code works fine. If you can try out the latest version
and let me know how it works – and I’ll help track down and fix any bugs
you find.

Thanks. I found that it hangs if I go past level 1 optimizations. Any fix?

FastTimes implementation of MacOS timing routines. It seems that somehow
SDL_StartTicks() and others where getting called before SDL_SYS_TimerInit()
was called (This is correct behavior?). If this happens, FastTimes will hang
the machine (can’t even drop into MacsBug!). I tested CircusLinux with this
code and it works fine.

#include <FastTimes.h>

static double start_tick;
static int is_fast_inited = 0;

void SDL_StartTicks(void)
{

// important to check or FastTime may hang machine!
if ( ! is_fast_inited )
        SDL_SYS_TimerInit();

    start_tick = FastMicroseconds();

}

Uint32 SDL_GetTicks(void)
{

    if ( ! is_fast_inited )
        SDL_SYS_TimerInit();
     
    return FastMilliseconds();

}

void SDL_Delay(Uint32 ms)
{
Uint32 stop, now;

    stop = SDL_GetTicks() + ms;
    do {
            SystemTask();

            now = SDL_GetTicks();

    } while ( stop > now );

}

int SDL_SYS_TimerInit(void)
{
FastInitialize ();
is_fast_inited = 1;

return(0);

}

In article <B5B24A2A.C1C4%dwaliss1 at purdue.edu>, sdl at lokigames.com wrote:

Thanks. I found that it hangs if I go past level 1 optimizations. Any fix?

That sounds like a compiler problem to me. What compiler/version/update are
you using? What hardware and system software does this happen on?

THanks–
/* Matt Slot, Bitwise Operator * One box, two box, yellow box, blue box *

That sounds like a compiler problem to me. What compiler/version/update are
you using? What hardware and system software does this happen on?

FastTimes.c doesn’t compile with MPW. Details sent to Matt Slot.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Thanks. I found that it hangs if I go past level 1 optimizations. Any fix?

That sounds like a compiler problem to me. What compiler/version/update are
you using? What hardware and system software does this happen on?

CodeWarrior C/C++ PPC Compiler 2.3.2 build 0075. I am running on 9.0.4 on
Beige G3/233 160 MB RAM, VM is off. It does this on the test project, have
you tried it? It hangs in this loop in FastInitialize() :

/* Wait for the beginning of the very next tick */
for(tick = MyLMGetTicks() + 1; tick > MyLMGetTicks(); );

Here is what the loop compiles into (Level 2 opt, Sched 750, Peephole) :

052A36D8: 8060016A lwz r3,0x0000016A
052A36DC: 3BA00000 li r29,0
052A36E0: 3B830001 addi r28,r3,1
052A36E4: 7C1C1810 subfc r0,r28,r3
052A36E8: 38000000 li r0,0
052A36EC: 7C1D0110 subfe r0,r29,r0
052A36F0: 7C1BD910 subfe r0,r27,r27
052A36F4: 7C0000D1 neg. r0,r0
052A36F8: 4082FFEC bne FastInitialize+0x130 ; $052A36E4

Funny thing is, that last bne doesn’t jump back to the first lwz! It jumps
back to subfc instruction! Obviously the cause of our troubles!

I think this problem recurs for this loop too:

/* Wait for the exact 60th tick to roll over */
while(tick + 60 > MyLMGetTicks());

Maybe some asm is needed?

Darrell Walisser wrote:

Funny thing is, that last bne doesn’t jump back to the first
lwz! It jumps back to subfc instruction! Obviously the cause
of our troubles!

I think this problem recurs for this loop too:

/* Wait for the exact 60th tick to roll over */
while(tick + 60 > MyLMGetTicks());

Sounds like the optimizer is assuming that “MyLMGetTicks” always returns the
same value (e.g. sqrt(2.0)). Try tagging “MyLMGetTicks” as volatile.

  • Randi

Regimental Command
Generic Armored Combat System
http://regcom.sourceforge.net

Randi J. Relander wrote:

Darrell Walisser wrote:

Funny thing is, that last bne doesn’t jump back to the
first lwz! It jumps back to subfc instruction! Obviously
the cause of our troubles!

I think this problem recurs for this loop too:

/* Wait for the exact 60th tick to roll over */
while(tick + 60 > MyLMGetTicks());

Sounds like the optimizer is assuming that “MyLMGetTicks” always returns
the
same value (e.g. sqrt(2.0)). Try tagging “MyLMGetTicks” as volatile.

Doh! The “sqrt” example was a bad one since it is an actual function. It
looks like (from the assembly output) that “MyLMGetTicks” is some sort of
macro accessing a hardcoded address (as follows?)

#define MyLMGetTicks (((long)0x0000016A))

which should be something like …

#define MyLMGetTicks (((volatile long)0x0000016A))

Typical optimizers will do what you are seeing with the first macro since
without the volatile qualifier they do not know that the memory address is
being modified by either hardware or an asynchronous interrupt. They read it
once and use the value over and over again.

  • Randi

Regimental Command
Generic Armored Combat System
http://regcom.sourceforge.net

#define MyLMGetTicks (((volatile long)0x0000016A))

Typical optimizers will do what you are seeing with the first macro since
without the volatile qualifier they do not know that the memory address is
being modified by either hardware or an asynchronous interrupt. They read it
once and use the value over and over again.

Thanks! That did the trick!

In article <B5B32D1F.C1E6%dwaliss1 at purdue.edu>, sdl at lokigames.com wrote:

CodeWarrior C/C++ PPC Compiler 2.3.2 build 0075. I am running on 9.0.4 on
Beige G3/233 160 MB RAM, VM is off. It does this on the test project, have
you tried it? It hangs in this loop in FastInitialize() :

/* Wait for the beginning of the very next tick */
for(tick = MyLMGetTicks() + 1; tick > MyLMGetTicks(); );

Yep, that looks like an optimizer bug – it’s assuming the memory location
for MyLMGetTicks() is constant. You can work around it by (a) replacing the
macro with the function TickCount() or (b) upgrading your copy of CWPro. I
only use the macro to access lowmem for speed.

Funny thing is, that last bne doesn’t jump back to the first lwz! It jumps
back to subfc instruction! Obviously the cause of our troubles!

The lwz is part of the for-loop prologue, the subfc is the test. Since the
loop is empty, it’s jumping back to “top” which is just the test.

Hope that helps!

Matt–
/* Matt Slot, Bitwise Operator * One box, two box, yellow box, blue box *