Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Okimoka on December 23, 2016, 11:31:03 am

Title: Use "Pause" without stopping game
Post by: Okimoka on December 23, 2016, 11:31:03 am
Edit: I figured, since the z80 is single-threaded, this (using interrupts) is probably the only solution

Sorry, back with another one  :-\
A subroutine, which I will call inside my main game loop, should be executed with a delay of 1 second.
The subroutine may be called more than once in one execution of the main game loop, every loop will last ca. 0.01s.
Obviously, "Pause" doesn't work, because I want the main loop to continue running, and Pause seems to stop the entire program (the game should continue running).
My attempt at solving this was adding this timer to the main loop (I don't expect J to become larger than 256)
Code: [Select]
.Initially I and J are 0
I+1→I
If I=65535
 J+1→J
End
And then, every time I would want to call the subroutine, instead I would write the "time" (I,J) into the free space of a buffer (Buff(30)→GDB1)
(0th: I/256; 1st: I^256; 2nd: J)

So, for example, when I call the subroutine after 30min (180000s) of running time, "J" will be 2 (180000/65536) and "I" will be 48928 (180000^65536), which results in the timestamp:{191,32,2}. Because I want to execute it one second later, I will add 100 to the first value so I get {36,33,2}.
I don't expect more than 10 subroutine calls to "queue" at the same time, so the Buffer is of size 3*10, as I need 3 bytes of space to store the timestamp.
The main loop checks if there is a timestamp in the Buffer which equals the current time
Code: [Select]
For(A,0,10)
If ({GDB1+(A*3)}=I/256) and ({GDB1+(A*3)+1}=I^256) and ({GDB1+(A*3)+2}=J)
sub(DELAY)
0→{GDB1+(A*3)}:0→{GDB1+(A*3)+1}:0→{GDB1+(A*3)+2} .Clear space
End
End
Anyway, this is the only solution I could come up with.
This seems way too complicated for a simple task as delay, is there a better solution?



Title: Re: Use "Pause" without stopping game
Post by: E37 on December 24, 2016, 04:49:01 pm
Interrupts would probably solve the problem. They can trigger multiple times in a loop. The only problem is that they will probably occur more often than you want, so you will need a control variable. Here is some example code:
Code: [Select]
.TEST

fnInt(INTERRUPT,6)             //turns on interrupts and sets them to slowest speed
.Loop
While 1                             // the body of the main loop
3->I                                 // how many times you want the interrupt code to run per main loop (I chose 3)

.Some game code here

EndIf getKey(15)              //end of main loop
Return

Lbl INTERRUPT
ReturnIf C++^5??I-(=/=0) -> I =/=0    //return if the interrupt has occurred recently (It only runs every 5 times in this case - a higher number here means it runs less often) If it should run this time, decrease the number of times it needs to run in this loop or return if it is already 0
.Code that needs to run multiple times per loop
Return
That is my attempt to explain interrupts. If you are confused, try looking at a more in-depth tutorial.

Hope that helps!