Keen Game Engine (for lack of a better name): VGA Keen DEMO

Here is where to post about the latest Commander Keen fangame or modification you've finished, a new website you've made, or another Keen-related creation.
User avatar
keenmaster486
Vorticon Elite
Posts: 542
Joined: Sun Mar 20, 2016 18:29
Location: Tranquility Base
Contact:

Keen Game Engine (for lack of a better name): VGA Keen DEMO

Post by keenmaster486 »

So I've been working on this project for about three months, but it's the spiritual successor to uncountable other iterations of this basic idea, which were never good enough for me to release. It's a basic game engine which loads the Keen graphics and tries to mimic the original Galaxy engine as faithfully as possible. It runs in VGA Mode 13h, 320x200x256.

It's called "Keen Game Engine 4" because believe it or not there were 3 other versions, completely rewritten every time, before this one. You do NOT want to see KGE 1, 2, or 3.

It's little more than a demo right now, as it's lacking most of the features of the Galaxy engine, but it's kind of interesting to look at. But now I'm wondering: with the release of the Keen Dreams code and the work done by the Atroxian realm team et al, has this project and others like it become obsolete? Or is there still a legitimate reason for something like this to exist? If there is I'll keep developing it, otherwise I guess I'll move to Dreams code.

One more thing: It's written in MS QuickBasic with the DirectQB library. Yes, I know that's been done before, but I thought to myself: I can do it better! The old one loads and runs really slow. Well, I got through with it and, lo and behold, it loads and runs really slow. But not too slow. You just have to crank DOSBox up to about 55000 cycles for it to run right, and it takes about 15-20 seconds to load, which I'm going to fix sometime. Right now it just has a "quick, lazy, and dirty" type loading routine. [UPDATE: this is fixed now. It now takes about a half second to load, and requires DOSBox to be about 30000 cycles to run at twice the fps of the first iteration :)]


Download link: https://drive.google.com/open?id=0Bwrva ... DlDQ0poWGs

List of features currently implemented:
-320x200 resolution at 256 colors (VGA mode 13h)
-Converts and loads Keen 4 tilesets and sprites
-Basic TED-style level editor with bare-bones features
-Mimics Keen 4 physics as well as it can
-Comes with graphics editor "KeenSprite" to edit sprites in its graphics format
-Runs in pure DOS
-Loads all graphics into EMS memory to leave a lot of base memory open
-Basic tile info routines, but it doesn't import anything from Keen so you have to manually set everything the first time you use a tile
-Bare-bones animation routines, set a tile to "animated" and it animates with the next three tiles
-Music: kvee's IMFPLAY, loads IMF type 0 files
-Digital sound effects (requires SB 2.0+)
-Neural stunner: basic bare-bones implementation
UPDATES:
-Adaptive tile refresh! Now it's 300% faster :p
-Doors (portals)
-Sloped (slightly jerky but they work)
-Item animations
-Good animation routines
-Horizontal platforms and switches

List of features yet to be implemented:
-Ledge-grabbing
-Gates
-Elevators


Issues:

Music: Right now it loads s3m files. There seems to be no converter to convert DRO or IMF files to S3M, though, so unless somebody feels like writing one I'm going to have to implement an IMF player or something. On a side note, it would be great if we could have a QB45 DRO player, so it would have OPL3 support too (we could make tunes in AT2 that way). [UPDATE: it now has IMFPLAY from kvee built in, so the music problem is pretty much solved.]

Timing: There's no timing in the program at all. You have to set DOSBox at 55000 cycles or thereabouts otherwise it will be too fast or too slow. This also means it speeds up when there are less tiles to draw. The reason I don't have timing routines is that the TIMER function in QB is totally messed up, and slows the program way down. When I try to use DQB's excellent DQBsetFrameRate and DQBframeReady functions, it messes the music up big time since it changes the PC timer 0. I really need either A) a new music routine that doesn't get messed up by DQBsetFrameRate, or B) a new QB timing routine that doesn't change the PC timer. [UPDATE: The timing works now! It automatically throttles the engine at 24 fps, no issues, and works with the music too]

Keen behavior: There are various issues with Keen's physics and behavior, such as that he can move around and jump while he's looking up or down. The impossible pogo trick is even more impossible. These are just bugs I have to fix. [UPDATE: I've fixed the physics a little. Feels much more like actual Keen now.]

Code: The code is not very well organized or commented. I just have to sit down and do some serious organizing and commenting! :o [UPDATE: Now the code is organized, but hasn't been commented yet :|]



The music files come from the demo S3M files that came with the QB s3m player, since I don't have a way to convert imf to s3m right now (I tried Camoto, it gave me a tempo incompatibility error - ?)

DISCLAIMER: This is a VERY "alpha", "demo", "unfinished", etc. release. It's not meant to be good, or even a real game engine YET.

So maybe this is not really necessary, but here it is: my first contribution to the Keen community, a completely useless and superfluous game engine. Hope you like it! :p
Last edited by keenmaster486 on Sun Aug 21, 2016 18:05, edited 5 times in total.
I flermmed the plootash just like you asked.
User avatar
Levellass
S-Triazine
Posts: 5265
Joined: Tue Sep 23, 2008 6:40

Post by Levellass »

*Drools*

Quick Basic... oh yes.


I remember seeing the last BASIC Keen, o I want the source so bad...
What you really need, not what you think you ought to want.
User avatar
Roobar
Vorticon Elite
Posts: 3267
Joined: Tue Jan 08, 2008 16:12
Contact:

Post by Roobar »

I like that when you jump and then turn on pogo, you jump even higher. Something like double jump. This should be a thing in a Keen game (mod) as a new move.
User avatar
keenmaster486
Vorticon Elite
Posts: 542
Joined: Sun Mar 20, 2016 18:29
Location: Tranquility Base
Contact:

Post by keenmaster486 »

wiivn wrote:I like that when you jump and then turn on pogo, you jump even higher. Something like double jump. This should be a thing in a Keen game (mod) as a new move.
Um, yeah ... (bobs head up and down really fast) I really did come up with that awesome feature all on my own! On purpose! It ISN'T a bug! Hee hee! So just credit me if you use it, okay? You can say "Thanks to keenmaster486's buggy program for giving me this idea".
I flermmed the plootash just like you asked.
User avatar
BlueGasMask
Vorticon Elite
Posts: 382
Joined: Tue Nov 20, 2007 9:56
Location: Wellington, New Zealand
Contact:

Post by BlueGasMask »

You could call it QBKeen, or ³K.
Image
User avatar
keenmaster486
Vorticon Elite
Posts: 542
Joined: Sun Mar 20, 2016 18:29
Location: Tranquility Base
Contact:

Post by keenmaster486 »

UPDATE: After a lot of work, the engine now has the following feature:

(cue fanfares)

Adaptive Tile Refresh!

So it runs on a 486DX-33 now instead of needing at least a Pentium/100. Which means you only have to crank DOSBox up to about 20000 cycles instead of 60000. That's a speed increase of 300% (I think) :p

Note: I implemented QB's crappy TIMER routine in this version. Which means the graphics are a little choppy right now because of how bad TIMER is. I have to get a better routine which doesn't change the PC timer 0! Any ideas? Well, if you want to fix that just copy KGE4OLD.CFG onto KGE4.CFG and it will revert to not using TIMER, except the speed will be dependent on the DOSBox cycles so you'll have to make it exact.

Now I'm wondering: Suppose that I got this thing 100% or 99% working, as a clone of the Galaxy engine. Suppose that it was suitable at that point for game development. Would anyone use it or be interested in it? Could we or would we make a Keen fangame with it? The only leg up it would have from lemm's Source Mod project is that it runs in 256-color VGA, which is what Galaxy was supposed to be. Perhaps it could be used to remake Galaxy in 256 colors! Or maybe that would be too much work for not enough reward... Anyone have thoughts on this?
I flermmed the plootash just like you asked.
User avatar
Roobar
Vorticon Elite
Posts: 3267
Joined: Tue Jan 08, 2008 16:12
Contact:

Post by Roobar »

I dunno. This is still QB. And it's too early to make something like this. I mean the physics are still not Keen's level accurate. You could try and make a demo showing the VGA capabilities though. IMKO VGA Keen should be a Windows native app rather than DOS to have any future.
User avatar
Levellass
S-Triazine
Posts: 5265
Joined: Tue Sep 23, 2008 6:40

Post by Levellass »

I'd be interested, but I'm too rusty to make much.
What you really need, not what you think you ought to want.
User avatar
kvee
Vortininja
Posts: 67
Joined: Sat Sep 26, 2015 11:17
Contact:

Re: Keen Game Engine (for lack of a better name): VGA Keen D

Post by kvee »

nice work!
keenmaster486 wrote:I'm going to have to implement an IMF player or something.
That's actually really easy, heh
User avatar
keenmaster486
Vorticon Elite
Posts: 542
Joined: Sun Mar 20, 2016 18:29
Location: Tranquility Base
Contact:

Post by keenmaster486 »

kvee wrote:nice work!
Thanks! :D
kvee wrote:That's actually really easy, heh
That is the impression I got after reading up on the IMF and DRO formats on the wiki. Here's the ideal thing: a QB45 DRO player, supporting OPL3 and easily concatenated into this program. I intend to write one, but I need all the help and advice I can get... have you any experience with this?
I flermmed the plootash just like you asked.
User avatar
kvee
Vortininja
Posts: 67
Joined: Sat Sep 26, 2015 11:17
Contact:

Post by kvee »

keenmaster486 wrote:have you any experience with this?
I wrote imfplay, so you could say that, yeah :]

this is a barebone version my older QBasic imfplay code, it's kinda garg and undocumented, but it works:

Code: Select all

CLS

DIM VRAM(256)

F$ = "imfs\k4t03.imf"

SPEED = 1193182 / 560

OUT &H43, &H36
OUT &H40, SPEED AND &HFF
OUT &H40, INT(SPEED / 256)

GOSUB CLEARP

OPEN F$ FOR BINARY ACCESS READ AS #1
IF EOF(1) GOTO ENDP
GET #1, 1, LENG%
LENG& = LENG%
IF LENG% = 0 THEN
  PRINT "type 0";
  START = 2
  LENG& = 2147483647
ELSE
  IF LENG& < 0 THEN LENG& = LENG& + 65536
  PRINT "type 1: "; LENG&;
END IF

'-------------
'- MAIN LOOP -
'-------------
FOR i = 3 + START TO LENG& STEP 4
  IF NOT EOF(1) THEN
    GOSUB READTIMER
    T1& = TIMERR&
    GET #1, i, R%
    IF EOF(1) GOTO ENDP
    GET #1, i + 1, V%
    IF EOF(1) GOTO ENDP
    GET #1, i + 2, D%
    D& = D%
    IF D& < 0 THEN D& = D& + 65536

    R% = R% AND &HFF
    V% = V% AND &HFF
    OUT &H388, R%
    OUT &H389, V%
    VRAM(R%) = V%
    LOCATE 25, 1
    PRINT USING "######"; D&;

    TOTALDELTA& = TOTALDELTA& + D&
    T2& = T1& + D&
    IF T2& > 65535 THEN
      WHILE TIMERR& > &H7FFF
      GOSUB READTIMER
      GOSUB INPUTP
      WEND
      T2& = T2& MOD 65536
    END IF
    WHILE TIMERR& < T2&
      GOSUB READTIMER
      GOSUB INPUTP
      LOCATE 25, 8
      PRINT USING "######"; T2& - TIMERR&;
    WEND

  ELSE
    EXIT FOR
  END IF

  IF CIN$ = CHR$(27) THEN EXIT FOR
NEXT i

CLOSE #1

ENDP:
  OUT &H43, &H36
  OUT &H40, &HFF
  OUT &H40, &HFF

  RESTORETIME& = INT((TOTALDELTA& * SPEED / 1193182) * (1193182 / 65536))
  GOSUB RESTORETIMER

  SYSTEM

'---------------
'- subroutines -
'---------------

CLEARP:
  V% = 0
  FOR R% = 0 TO &HF5
    OUT &H388, R%
    OUT &H389, V%
  NEXT R%

  R% = 1
  V% = 32
  OUT &H388, R%
  OUT &H389, V%
RETURN

INPUTP:
CIN$ = INKEY$
SELECT CASE CIN$
  CASE CHR$(27): GOTO ENDP
END SELECT
RETURN

READTIMER:
DEF SEG = 0
HIBYTE = PEEK(&H46D)
TIMERR& = PEEK(&H46C) + 256 * HIBYTE
RETURN

BACKUPTIMER:
DEF SEG = 0
TBKUP1 = PEEK(&H46C)
TBKUP2 = PEEK(&H46D)
TBKUP3 = PEEK(&H46E)
TBKUP4 = PEEK(&H46F)
TBKUP5 = PEEK(&H470)
RETURN

RESTORETIMER:
FOR TICKS& = 0 TO RESTORETIME&
TBKUP1 = (TBKUP1 + 1) MOD 256
IF TBKUP1 = 0 THEN
  TBKUP2 = (TBKUP2 + 1) MOD 256
  IF TBKUP2 = 0 THEN
    TBKUP3 = (TBKUP3 + 1) MOD 256
    IF TBKUP3 = 0 THEN
      TBKUP4 = (TBKUP4 + 1) MOD 256
      IF TBKUP4 = 0 THEN TBKUP5 = 1
    END IF
  END IF
END IF
NEXT TICKS&

DEF SEG = 0
POKE (&H46C), TBKUP1
POKE (&H46D), TBKUP2
POKE (&H46E), TBKUP3
POKE (&H46F), TBKUP4
POKE (&H470), TBKUP5
RETURN

If you can read C, I have the sources for the current version online, it supports DRO files as well: https://bitbucket.org/kvee/imfplay/src
User avatar
keenmaster486
Vorticon Elite
Posts: 542
Joined: Sun Mar 20, 2016 18:29
Location: Tranquility Base
Contact:

Post by keenmaster486 »

kvee wrote:I wrote imfplay, so you could say that, yeah :]
Aha... Aha! D'uh! (smacks forehead). Of course! And then you're also the guy whom I left a YouTube comment asking for the imfplay source 8) Yea! This is going great.

That code looks pretty easy to patch into my program, but if I converted that for-next main loop to some code that runs every time the game loop rolls around, would that cause timing issues? And what global variables are there that I should be declaring (I think I can find them all, but I just want to make sure)? Also, the timer 0 compatibility has been mitigated a little bit so that shouldn't be a problem yet, I don't think.

How hard can it be to convert this over to DRO and use OPL3? I can read C but that code looks way too long for me to translate (plus I have to keep the main QB program under 80K, right now it's about 60K)

Soon as I get my nose in my computer (later today or tomorrow maybe) I'll try this out! Thanks so much.
I flermmed the plootash just like you asked.
User avatar
kvee
Vortininja
Posts: 67
Joined: Sat Sep 26, 2015 11:17
Contact:

Post by kvee »

keenmaster486 wrote:And then you're also the guy whom I left a YouTube comment asking for the imfplay source 8) Yea! This is going great.
That was you? lol :D
Sorry for the delay, replying to you here made me realize you asked on YouTube :D
keenmaster486 wrote:...if I converted that for-next main loop to some code that runs every time the game loop rolls around, would that cause timing issues?
Assuming you have a stable time reference, you'd have to adjust all the times you read from the .IMF (they assume a 560Hz cycle) to match the game loop speed, that should work relatively well, with some barely noticeable jitter I think (most console game music engines run at 60Hz anyway and they work just fine, so methinks this should work).
The best would be to pre-parse the files, since it's probably the easiest to work with absolute times.
keenmaster486 wrote:And what global variables are there that I should be declaring (I think I can find them all, but I just want to make sure)?
Can't help you there, sorry. Stuff's really old and I haven't seen it in a loooong time. It'd be best if you tried and rewrote the player yourself, that way you can be sure.
keenmaster486 wrote:How hard can it be to convert this over to DRO and use OPL3?
Not that hard. There are two .DRO versions though, so keep that in mind. It'd not be a crime to support only the newer one imo. Other than that, change the timing from 560 to 1000 IIRC and you're fine.
OPL3 support is easy too, all register > 0x100 accesses go to a separate I/O address and that's pretty much it.
keenmaster486 wrote:Thanks so much.
np
User avatar
Levellass
S-Triazine
Posts: 5265
Joined: Tue Sep 23, 2008 6:40

Post by Levellass »

Well darn. There's something I could have used a few years ago. That's some nice coding right there.
What you really need, not what you think you ought to want.
User avatar
kvee
Vortininja
Posts: 67
Joined: Sat Sep 26, 2015 11:17
Contact:

Post by kvee »

Levellass wrote:Well darn. There's something I could have used a few years ago. That's some nice coding right there.
Hey, thanks! :]
Well the C version is infinitely better, the way I deal with timing here is kinda funny. And there should be a delay between OPL2 writes, as the datasheet says.

(also btw, when deleting the visuals, I've managed to remove

Code: Select all

GOSUB BACKUPTIMER
you should call it right after

Code: Select all

SPEED = 1193182 / 560
...sorry about that)
Post Reply