Friday, October 11, 2013

Petit Computer Journal #20


IdleLoop


I'm going to do something different this time around. Usually I would make a new program, illustrating a new concept. However, this time, I won't be doing something new and exciting. I'll be doing something that is old and boring: idle loop.

What is idle loop? Well, you know the main loop on the program that goes like this:


  1. @MAINLOOP
  2. 'get player input
  3. 'process player input
  4. GOTO @MAINLOOP


That's it. Idle loop is so called because if the player has no input, it'll just wait around doing nothing. In other words, being idle.

So, you're probably wondering why I want to show that here. Shouldn't that process be known to everybody? Yes, it should. But not to everybody. Just like loop, there are various situations that you have to watch out for. For example, where would you want to put the @INIT function?

INIT function deals with initial state of the program. This is where default values come into play. Also, I like to put in @QUIT function, where the program does clean up when it exits. I don't put it in all my programs, especially simple ones, but for completeness, I want my programs to clean up after itself. It's just good programming practice.

So, the structure would be


  1. Global settings, DIM, and such
  2. INIT function
  3. MAIN function
  4. END/QUIT/CLEANUP function


There is a difference between Global Settings and INIT. In Global Settings, you allocate memory to the variables, and load any static resource needed. Fortunately, Petit Computer takes care most of it for you. Very little needed to be here. Some programming language requires you to load modules/libraries here as well.

INIT function deals with initializing the variables to start-up state. That means loading any custom screens if any. Backgrounds, Icons, and the like. This function gets called whenever the player quit to the title screen. It basically start fresh. If you have game states then you load that separately from this function. And yes, you want to have that special loading function, so you can override default graphics and provide the player with custom sprites and skin.

QUIT function basically says good-bye. There's not much here for Petit Computer. If you don't need anything, just leave it out, or just put out a good-bye message to the player.

The MAIN function will handle several types of cases:


  1. Infinite Loop
  2. Loop with Timer
  3. Loop with VSYNC
  4. Loop with Player input (wait)
  5. Loop with Player input (no wait)
  6. Loop with Player input + background process
  7. Loop with Player input + multi-thread


1. Infinite Loop


The first case is the simplest. You want the program to run forever, like in showing demo.


  1. @LOOP
  2. ?"Hello World"
  3. GOTO @LOOP


2. Loop with Timer


Sometimes, you want to have the program run for a certain length of time. Say, like a Timer. You can do it like this:


  1. 'TIMER PROGRAM BY HARRY HARDJONO
  2. SPSET 1,156,0,0,0,0
  3. SPOFS 1,-50,-50
  4. SPANIM 1,4,15
  5. SPSCALE 1,200

  6. @INIT
  7. CLS
  8. ?"HOW MANY SECONDS?"
  9. INPUT T
  10. IF 0>=T GOTO @END
  11. SPOFS 1,0,48,0
  12. SPOFS 1,224,48,T*60

  13. @LOOP
  14. IF (SPCHK(1) AND 1)==0 GOTO @END
  15. BEEP 28:WAIT 60
  16. GOTO @LOOP

  17. @END
  18. ?"TIME'S UP!"
  19. SPCLR 1
  20. BEEP 50
  21. WAIT 300


And that's it. The code before the INIT creates and sets the sprite. INIT is used to send the sprite across the screen, timed according to T variable. The loop then simply waits for the sprite to stop moving, and gave a "ding" sound when it's done. Also, sprite clean up is done at the END.


3. Loop with Player input (wait)


Let's modify the program a bit. We want to have a player input, and we want it to wait for each input. Let's say A to start the timer, B to set the timer, and X to end the program.


  1. @INIT
  2. CLS
  3. ?"HOW MANY SECONDS?"
  4. INPUT T
  5. IF 0>=T GOTO @END
  6. ?"A STARTS TIMER"
  7. ?"B SETS NEW TIME"
  8. ?"X EXIT"

  9. @LOOP
  10. VSYNC 1:B=BTRIG()
  11. IF (B AND 16) GOTO @TICK
  12. IF (B AND 32) GOTO @INIT
  13. IF (B AND 64) GOTO @END
  14. GOTO @LOOP
  15. @TICK
  16. SPOFS 1,0,48,0
  17. SPOFS 1,224,48,T*60
  18. @TOCK
  19. LOCATE 0,4:SPREAD(1),X,Y:?"TIME LEFT: ";FLOOR((224-X)*T/224);"   "
  20. IF (SPCHK(1) AND 1) THEN BEEP 28:WAIT 60:GOTO @TOCK
  21. ?"TIME'S UP!":SPOFS 1,-50,-50:BEEP 50
  22. GOTO @LOOP

  23. @END
  24. ?"GOODBYE!"
  25. SPCLR 1:WAIT 300


If you notice, there's TICK and TOCK. Normally, I would put these on separate subroutine, but since I'm showing you how to do LOOP while waiting for user input, I simply group it all at once. Does it look like spaghetti code to you?

4. Loop with Player input (no wait)


Let's do one more improvement, and this time, we're going to do player input without waiting. Let's implement a PAUSE button. The truth is, it's very simple. Petit Computer, by default, does not wait for user input.

Here, we simply check if the sprite is moving. If so, then we stop it. Else, we start it.


  1. 'TIMER PROGRAM BY HARRY HARDJONO
  2. SPSET 1,156,0,0,0,0
  3. SPOFS 1,-50,-50
  4. SPANIM 1,4,15
  5. SPSCALE 1,200

  6. @INIT
  7. CLS
  8. ?"HOW MANY SECONDS?"
  9. INPUT T
  10. IF 0>=T GOTO @END
  11. ?"A STARTS TIMER"
  12. ?"B SETS NEW TIME"
  13. ?"X EXIT"
  14. ?"Y PAUSE"

  15. @LOOP
  16. VSYNC 1:B=BTRIG()
  17. IF (B AND 16) GOTO @TICK
  18. IF (B AND 32) GOTO @INIT
  19. IF (B AND 64) GOTO @END
  20. GOTO @LOOP
  21. @TICK
  22. SPOFS 1,0,48,0
  23. SPOFS 1,224,48,T*60
  24. @TOCK
  25. LOCATE 0,8:SPREAD(1),X,Y:?"TIME LEFT: ";FLOOR((224-X)*T/224);"   "
  26. IF (BUTTON(0) AND 128) GOTO @PAUSE
  27. IF (SPCHK(1) AND 1) THEN BEEP 28:WAIT 60:GOTO @TOCK
  28. ?"TIME'S UP!":SPOFS 1,-50,-50:BEEP 50
  29. GOTO @LOOP

  30. @PAUSE
  31. IF (SPCHK(1) AND 1) THEN SPOFS 1,X,Y,0 
  32. IF (BUTTON(0) AND 16) THEN SPOFS 1,224,48,FLOOR((224-X)*T/224)*60:GOTO @TOCK
  33. IF (BUTTON(0) AND 32) GOTO @INIT
  34. IF (BUTTON(0) AND 64) GOTO @END
  35. GOTO @PAUSE

  36. @END
  37. ?"GOODBYE!"
  38. SPCLR 1:WAIT 300



Simple as that. We simply use the variable values from TIME LEFT to stop the sprite where it stands, and starts it in according to TIME LEFT. There's a trick here, that we use BUTTON(0) instead of BTRIG. We do that because of WAIT 60 that we have will cause BTRIG signal to get lost. BUTTON(0) will read the input continuously. Press A to restart the timer.

Petit Computer Programming can be so easy! Next, we'll examine loops with background processes.

No comments:

Post a Comment