[Coco] real-time mouse cursor
operator at coco3.com
Fri Jan 25 22:01:56 EST 2008
While I'm testing out Darren's alternate LOADM approach for doing MMU
switching, etc. I'm also working hard on a mouse/joystick cursor
routine that's "sort of" working.
I'm trying to keep up with a scanline counter by using IRQ and FIRQ
using both the vertical and horizontal syncs. IRQ resets the counter
to 0 while FIRQ increments a 16-bit counter. Simple enough. Ok,
with a lot of spaghetti code and stack blasting I'm now able to save
the cursor background, plot the new cursor (with masking), then
restore the background, to make the cursor appear solid at all times
during my running game.
This is actually working to some degree, which is why I'm determined
to figure out what's going wrong. What I'm seeing is the cursor
appears only for about the top 1/3rd of the screen (actually less),
and while it moves out of this range, up or down, you can see the
bottom of the cursor start to fade away (to the background image) and
the top portion of the cursor reduces in sprite lines as the cursor
moves away from the visible part of the screen I mentioned. In other
words, the cursor loses bottom lines as it moves out of the visible
range I'm obtaining.
My scheme is as follows:
In the FIRQ service code: If the current scanline = current mouse.y
value (sampled from the IRQ routine, every sync or every X number of
syncs to save CPU time), plot the cursor and immediately erase it
since the raster beam, according to when I started the drawing,
should be around that scanline, and erasing it should still leave the
cursor visible. No erasing should be noticed since I'm supposedly
doing it while the raster beam has passed the cursor's last scanline.
What I'm wondering is if all of the instructions needed to
save/draw/erase the cursor data, probably one or more VSYNCS have
happened which will clear the scanline counter and cause FIRQ to
think it's at the top again. Again, FIRQ only increments while IRQ
clears the scanline counter. This is the same idea behind
lightpens. I even built one years ago but it was very coarse even on
the 32x16 semigraphics screen. But it worked. I used a
photoresistor tied to a joystick button input, I think.
*Exactly* how many CPU cycles are in a video scanline, and how many
scanlines are on the "200-line GIME mode" ? This is really only 199
lines, btw. For proof, create a 320x200 image with a 1-pixel border
around the edges and then load it in Projector-3 or any of the other
graphics viewers. You probably won't see the bottom border line.
Also, does the GIME VBORD signal happen at the bottom of the screen
or the top border? I tried setting the first scanline to -25, -28,
-56 and various other values but then the cursor won't appear even
though it's still being drawn and erased. I can't put a delay after
the draw since FIRQ happens way to much and the code needs to be the
fastest possible. Even then, I'm seeing the main code slow down to
more than half speed. That's terrible.
IRQ controls when FIRQ plots the mouse
IRQ reads the mouse, but FIRQ can interrupt the code in the IRQ
service routine, no?
FIRQ compares mouse.y to the current scanline and exits if it's not
the same, otherwise plot and erase the cursor.
I guess need to determine how many scanlines have passed from the
time I start the background save and the cursor plot up until the
start of the background restore code.
I know there's other solutions to plotting a mouse cursor, and I'm
sure people will jump on this with their good and bad ideas, but in
order to plot a mouse cursor in real-time while the main code can
draw away on the screen, clear it, etc. without having any
corruption, I'm sure it has to be done when the scanline is equal to
or close to the mouse.y value, plus it has to be interrupt based so
that nothing else is going on when the cursor is plotted and erased
to the previous background.
More information about the Coco