• Please review our updated Terms and Rules here

MagiDuck, a DOS / CGA text mode game project

Apologies; you did not expressly state that. I'm not sure what gave me the impression. I guess I was shocked you were running an action game over a remote session and didn't think that the remote session was to blame for the response time or odd behavior.

Why paku-paku works over this and not magiduck? Likely because paku-paku updates very little on the screen, whereas magiduck repaints the entire screen as soon as the player causes scrolling. Maybe the full-screen updates were too much for the remote session to update at ~20fps.
 
I guess I was shocked you were running an action game over a remote session and didn't think that the remote session was to blame for the response time or odd behavior.

I suppose that it was silly for it not to occur to me that it might be a factor. But it's the first time I've ever encountered this sort of thing with VNC, specifically keypresses seemingly not being registered properly, not slow response time.

Why paku-paku works over this and not magiduck? Likely because paku-paku updates very little on the screen, whereas magiduck repaints the entire screen as soon as the player causes scrolling. Maybe the full-screen updates were too much for the remote session to update at ~20fps.

The keyboard problem in MagiDuck using VNC occurs at the title screen. It's bad enough that I can't even start the game.
 
But it's the first time I've ever encountered this sort of thing with VNC, specifically keypresses seemingly not being registered properly, not slow response time.

Glad to hear the cause was found.

The keyboard interrupt in Magi should be a pretty standard implementation. Of course if the frame rate drops very low for some reason, the interrupt would have time to register both the pressed and release states between two frames. Holding a key down for a long time and waiting for a response might give an idea if frame rate is the cause.

Now that I think about it, the native framerate of 24 fps is far too low for the routine to handle properly... It would need to be more intelligent about when a key can return to its released state.

It's using a WORD per key anyway, so maybe it could use the high byte for affirming that the key state was read by the game and it is ready to change to release.
 
Good to see a final release! Runs flawlessly on my IBM 5160- looks and plays very polished.

One "nice to have" feature for CGA would be the ability to shift the screen left and right as needed, i.e. increase/decrease the value in port 3D4h register 02. Helpful for people like me with cheap CRT TVs with no H-Position control, since by default everything is so off-center that the left edge of the picture is hidden under the bezel. (TSRs can and do fix this, but only for programs that set the video mode through the BIOS.)

Absolutely not necessary, mind you (I was able to work around it by hacking a different value into the binary); just pointing it out. :)
 
One "nice to have" feature for CGA would be the ability to shift the screen left and right as needed, i.e. increase/decrease the value in port 3D4h register 02.

Thanks! This sounds like a great idea. I started to work on it as a command line parameter, since it does seem like a pretty exotic tweak.

Would you have some sensible value range in mind for this? CGA documentation only mentions values for 320/640 modes but doesn't elaborate any further and I don't have the hardware to test it either.
 
It's using a WORD per key anyway, so maybe it could use the high byte for affirming that the key state was read by the game and it is ready to change to release.

That may be a fundemental different in why Paku Paku works and Magiduck doesn't. In PP keyups aren't actually used for the movement states. It's treated as a keyPRESS in that the most recent 'down' is used as the trigger for storing the NEXT direction to take if possible.

In your case I'd probably be tracking it as a trinary state, up, down, and pressed since last read. I was actually working on something similar before everything I was working on got put on hold due to health concerns.

What I was doing is on keydown setting 0xFF, but on keyup masking off everything but the sign bit. This way things like 'free movement' that should be "is the key down RIGHT NOW" can just test for non-zero and leave it alone, but for 'press' based actions like jump, shoot, or TYPING can test for any other bit (test 0x7F) and then clear everything but sign as an acknowledge.

Was even playing with letting some bits be set and others not as a way of saying "should this value be sent to a keyboard buffer or not" so I could use one ISR for all types of keyboard input -- state based, single press, buffered.
 
Would you have some sensible value range in mind for this? CGA documentation only mentions values for 320/640 modes but doesn't elaborate any further and I don't have the hardware to test it either.
Good thing you asked, because I never really bothered to check for the minimum/maximum sane values until now. :)

The general idea is that the HSync pulse always starts at a fixed location, somewhere beyond the right edge of the visible screen. The value in port 3D4h reg 2 represents how far the HSync is from the left edge of the active area. So decreasing the value 'pulls' the whole image closer to the HSync pulse (=shifts it to the right), and increasing it 'pushes' the image farther away (=shifts it to the left).

  • The default value is 2Dh (the unit is character clocks, so that value applies to 40-column text mode and all graphics modes. For 80-column text mode *only*, you double the value but as far as I can tell that doesn't apply to Magiduck).
  • On my TV the optimal value is 2Bh, or a right-shift of 2 character clocks (16 low-res pixels). I suspect that most other NTSC TV sets are the same or similar.
  • The largest sane value seems to be 2Eh, or just one more than the default. Any larger and my TV starts losing sync. I also had a look at Moon Patrol, which is one of those games that lets you shift the screen at will, and it doesn't go beyond 2Eh either.
  • As for the smallest sane value, I can actually decrease it all the way to 1 (and so does Moon Patrol) with no ill effects... other than the image moving so far to the right that it wraps around to the left and gets split in two. As comical as that looks, there's probably no practical value in going below 25h or so.
tl;dr: I'd say 25h--2Eh is a sensible range. Conveniently enough that's 10 possible values, so if you want a command-line argument you could map them to single decimal digits and people won't have to worry about arcane hex numbers. At least I think that's what I'll do with my aforementioned TSR.

BTW: this problem (and solution) would apply to PCjr and Tandy modes too, since those machines also have NTSC composite output and CRTC register 02 works the same way.
 
Last edited:
Back
Top