├── .gitattributes ├── .gitignore ├── KEEN4-6 ├── CK_DEF.H ├── CK_DEMO.C ├── CK_GAME.C ├── CK_KEEN.C ├── CK_KEEN2.C ├── CK_MAIN.C ├── CK_PLAY.C ├── CK_STATE.C ├── CK_TEXT.C ├── ID_CA.C ├── ID_CA.H ├── ID_IN.C ├── ID_IN.H ├── ID_MM.C ├── ID_MM.H ├── ID_RF.C ├── ID_RF.H ├── ID_RF_A.ASM ├── ID_SD.C ├── ID_SD.H ├── ID_US.H ├── ID_US_1.C ├── ID_US_2.C ├── ID_US_A.ASM ├── ID_VW.C ├── ID_VW.H ├── ID_VW_A.ASM ├── ID_VW_AC.ASM ├── ID_VW_AE.ASM ├── ID_VW_AT.ASM ├── KEEN4 │ ├── AUDIOCK4.H │ ├── GFXE_CK4.EQU │ ├── GFXE_CK4.H │ ├── ID_ASM.EQU │ ├── ID_HEADS.H │ ├── K4_ACT1.C │ ├── K4_ACT2.C │ ├── K4_ACT3.C │ ├── K4_DEF.H │ └── K4_SPEC.C ├── KEEN4C.DSK ├── KEEN4C.PRJ ├── KEEN4C │ ├── GFXC_CK4.EQU │ ├── GFXC_CK4.H │ ├── ID_ASM.EQU │ └── ID_HEADS.H ├── KEEN4E.DSK ├── KEEN4E.PRJ ├── KEEN4M.DSK ├── KEEN4M.PRJ ├── KEEN4M │ └── ID_HEADS.H ├── KEEN4T.DSK ├── KEEN4T.PRJ ├── KEEN4T │ ├── GFXT_CK4.EQU │ ├── GFXT_CK4.H │ ├── ID_ASM.EQU │ └── ID_HEADS.H ├── UNZX0.ASM └── static │ ├── AUDIOHED.CK4 │ ├── CGAHEAD.CK4 │ ├── EGAHEAD.CK4 │ ├── INTROSCN.CK4 │ ├── MAKEOBJ.EXE │ ├── MAPHEAD.CK4 │ ├── TGAHEAD.CK4 │ ├── make.bat │ └── makeobj.c ├── KEEN4C.BAT ├── KEEN4E.BAT ├── KEEN4M.BAT ├── KEEN4T.BAT ├── LICENSE ├── README.md ├── cleanup.bat ├── keen4t.png └── music ├── KICKPANT.TND ├── OASIS.TND ├── SHADOWS.TND ├── TOOHOT.TND ├── VEGGIES.TND └── WONDER.TND /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.C text eol=crlf 3 | *.H text eol=crlf 4 | *.ASM text eol=crlf 5 | *.EQU text eol=crlf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /BC20 2 | /BC30 3 | /BC31 4 | 5 | /KEEN4-6/*.SYM 6 | 7 | /KEEN4-6/KEEN4/*.OBJ 8 | 9 | /KEEN4-6/KEEN4/OBJ 10 | /KEEN4-6/KEEN4C/OBJ 11 | /KEEN4-6/KEEN4M/OBJ 12 | /KEEN4-6/KEEN4T/OBJ 13 | -------------------------------------------------------------------------------- /KEEN4-6/CK_DEF.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is loosely based on: 9 | * Keen Dreams Source Code 10 | * Copyright (C) 2014 Javier M. Chavez 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | #ifndef __CK_DEF__ 28 | #define __CK_DEF__ 29 | 30 | #include 31 | #include 32 | 33 | #include "ID_HEADS.H" 34 | 35 | /* 36 | ============================================================================= 37 | 38 | GLOBAL CONSTANTS & MACROS 39 | 40 | ============================================================================= 41 | */ 42 | 43 | #define GAMELEVELS 25 44 | 45 | #define CONVERT_GLOBAL_TO_TILE(x) ((x)>>(G_T_SHIFT)) 46 | #define CONVERT_TILE_TO_GLOBAL(x) ((x)<<(G_T_SHIFT)) 47 | #define CONVERT_GLOBAL_TO_PIXEL(x) ((x)>>(G_P_SHIFT)) 48 | #define CONVERT_PIXEL_TO_GLOBAL(x) ((x)<<(G_P_SHIFT)) 49 | 50 | #define ARRAYLENGTH(x) (sizeof(x)/sizeof(*(x))) 51 | 52 | #define PLATFORMBLOCK 31 53 | #define DIRARROWSTART 91 54 | #define DIRARROWEND (DIRARROWSTART+arrow_None) 55 | 56 | /* 57 | ============================================================================= 58 | 59 | GLOBAL TYPES 60 | 61 | ============================================================================= 62 | */ 63 | 64 | //SDL-style integer types - just to make future SDL ports easier 65 | typedef unsigned int Uint16; 66 | typedef signed int Sint16; 67 | typedef unsigned char Uint8; 68 | typedef signed char Sint8; 69 | typedef unsigned long Uint32; 70 | typedef signed long Sint32; 71 | //Note: only the game code (CK_*.C, K?_*.C) uses these! 72 | 73 | //some compile-time checks to make sure the ints have the correct size 74 | #if (sizeof(Uint16) != 2) 75 | #error 'Uint16' has wrong size 76 | #elif (sizeof(Sint16) != 2) 77 | #error 'Sint16' has wrong size 78 | #elif (sizeof(Uint8) != 1) 79 | #error 'Uint8' has wrong size 80 | #elif (sizeof(Sint8) != 1) 81 | #error 'Sint8' has wrong size 82 | #elif (sizeof(Uint32) != 4) 83 | #error 'Uint32' has wrong size 84 | #elif (sizeof(Sint32) != 4) 85 | #error 'Sint32' has wrong size 86 | #endif 87 | 88 | typedef enum { 89 | arrow_North, // 0 90 | arrow_East, // 1 91 | arrow_South, // 2 92 | arrow_West, // 3 93 | arrow_NorthEast, // 4 94 | arrow_SouthEast, // 5 95 | arrow_SouthWest, // 6 96 | arrow_NorthWest, // 7 97 | arrow_None // 8 98 | } arrowdirtype; 99 | 100 | typedef enum { 101 | ex_stillplaying, // 0 102 | ex_died, // 1 103 | ex_completed, // 2 104 | ex_rescued, // 3, only in Keen 4 105 | ex_warped, // 4 106 | ex_resetgame, // 5 107 | ex_loadedgame, // 6 108 | ex_foot, // 7, only in Keen 4 109 | ex_abortgame, // 8 110 | ex_sandwich, // 9, only in Keen 6 111 | ex_hook, // 10, only in Keen 6 112 | ex_card, // 11, only in Keen 6 113 | ex_molly, // 12, only in Keen 6 114 | ex_portout, // 13, only in Keen 5 115 | ex_fusebroke, // 14, only in Keen 5 116 | ex_qedbroke, // 15, only in Keen 5 117 | NUMEXITTYPES 118 | } exittype; 119 | 120 | typedef enum 121 | { 122 | INTILE_NOTHING, // 0 123 | INTILE_POLE, // 1 124 | INTILE_DOOR, // 2 125 | INTILE_DEADLY, // 3 126 | INTILE_DROP, // 4 127 | INTILE_SWITCH0, // 5 128 | INTILE_SWITCH1, // 6 129 | INTILE_GEMSOCKET0, // 7 130 | INTILE_GEMSOCKET1, // 8 131 | INTILE_GEMSOCKET2, // 9 132 | INTILE_GEMSOCKET3, // 10 133 | INTILE_SHORESOUTH, // 11 134 | INTILE_SHOREWEST, // 12 135 | INTILE_SHORENORTH, // 13 136 | INTILE_SHOREEAST, // 14 137 | INTILE_BRIDGESWITCH, // 15 138 | INTILE_MOON, // 16 139 | INTILE_DIRARROW, // 17 (not used in the code, but assigned to tiles in Keen 5 & 6) 140 | INTILE_BRIDGE, // 18 141 | INTILE_FORCEFIELD, // 19 142 | INTILE_TELEPORT, // 20 143 | INTILE_BONUS100, // 21 144 | INTILE_BONUS200, // 22 145 | INTILE_BONUS500, // 23 146 | INTILE_BONUS1000, // 24 147 | INTILE_BONUS2000, // 25 148 | INTILE_BONUS5000, // 26 149 | INTILE_EXTRALIFE, // 27 150 | INTILE_AMMO, // 28 151 | INTILE_29, // 29 (never used) 152 | INTILE_FORCEFIELDEND, // 30 153 | INTILE_AMPTONCOMPUTER, // 31 154 | INTILE_KEYCARDDOOR, // 32 155 | INTILE_ELEVATORLEFT, // 33 156 | INTILE_ELEVATORRIGHT, // 34 157 | 158 | INTILE_FOREGROUND = 0x80 159 | } intiletype; 160 | 161 | #define INTILE_TYPEMASK (INTILE_FOREGROUND-1) 162 | 163 | typedef enum 164 | { 165 | nothing, // 0 166 | inertobj, // 1 167 | keenobj, // 2 168 | stunshotobj, // 3 169 | #if defined KEEN4 170 | bonusobj, // 4 171 | slugobj, // 5 172 | oracleobj, // 6 173 | classtype_7, // 7, never used 174 | eggobj, // 8 175 | madmushroomobj, // 9 176 | arachnutobj, // 10 177 | skypestobj, // 11 178 | wormouthobj, // 12 179 | thundercloudobj, // 13 180 | berkeloidobj, // 14 181 | bounderobj, // 15 182 | inchwormobj, // 16 183 | footobj, // 17 184 | lickobj, // 18 185 | mimrockobj, // 19 186 | platformobj, // 20 187 | dopefishobj, // 21 188 | schoolfishobj, // 22 189 | pixieobj, // 23 190 | lindseyobj, // 24 191 | lightningobj, // 25 192 | treasureeaterobj,// 26 193 | eggbirdobj, // 27 194 | classtype_28, // 28, never used 195 | classtype_29, // 29, never used 196 | scubaobj, // 30 197 | mshotobj, // 31 198 | mineobj, // 32 199 | stunnedobj, // 33 200 | flagobj, // 34 201 | #elif defined KEEN5 202 | mshotobj, // 4 203 | bonusobj, // 5 204 | platformobj, // 6 205 | stunnedobj, // 7 206 | flagobj, // 8 207 | sparkyobj, // 9 208 | mineobj, // 10 209 | slicestarobj, // 11 210 | roboredobj, // 12 211 | spirogripobj, // 13 212 | amptonobj, // 14 213 | cannonobj, // 15 214 | volteobj, // 16 215 | shelleyobj, // 17, never used 216 | spindredobj, // 18 217 | shikadimasterobj,// 19 218 | shikadiobj, // 20 219 | petobj, // 21 220 | spherefulobj, // 22 221 | scottieobj, // 23 222 | teleporterobj, // 24 223 | qedobj, // 25 224 | #elif defined KEEN6 225 | mshotobj, // 4 226 | bonusobj, // 5 227 | platformobj, // 6 228 | bloogobj, // 7 229 | bloogletobj, // 8 230 | classtype_9, // 9, never used 231 | fleexobj, // 10 232 | classtype_11, // 11, never used 233 | mollyobj, // 12 234 | babobbaobj, // 13 235 | bobbaobj, // 14 236 | classtype_15, // 15 237 | nospikeobj, // 16 238 | gikobj, // 17 239 | cannonobj, // 18 240 | orbatrixobj, // 19 241 | bipobj, // 20 242 | flectobj, // 21 243 | blorbobj, // 22 244 | ceilickobj, // 23 245 | blooguardobj, // 24 246 | stunnedobj, // 25 247 | bipshipobj, // 26 248 | sandwichobj, // 27 249 | hookobj, // 28 250 | passcardobj, // 29 251 | grabbiterobj, // 30 252 | rocketobj, // 31 253 | grapplespotobj, // 32 254 | satelliteobj, // 33 255 | satellitestopobj,// 34 256 | flagobj, // 35 257 | #endif 258 | NUMCLASSTYPES 259 | } classtype; 260 | 261 | typedef struct statestruct 262 | { 263 | Sint16 leftshapenum, rightshapenum; 264 | enum {step,slide,think,stepthink,slidethink} progress; 265 | boolean skippable; 266 | boolean pushtofloor; 267 | Sint16 tictime; 268 | Sint16 xmove; 269 | Sint16 ymove; 270 | void (*think) (struct objstruct*); 271 | void (*contact) (struct objstruct*, struct objstruct*); 272 | void (*react) (struct objstruct*); 273 | struct statestruct *nextstate; 274 | } statetype; 275 | 276 | typedef struct objstruct 277 | { 278 | classtype obclass; 279 | enum {ac_no, ac_yes, ac_always, ac_removable} active; 280 | boolean needtoreact; 281 | enum {cl_noclip, cl_midclip, cl_fullclip} needtoclip; 282 | Uint16 nothink; 283 | Uint16 x, y; 284 | Sint16 xdir, ydir; 285 | Sint16 xmove, ymove; 286 | Sint16 xspeed, yspeed; 287 | Sint16 ticcount; 288 | statetype *state; 289 | Uint16 shapenum; 290 | Uint16 priority; 291 | Uint16 left, top, right, bottom, midx; 292 | Uint16 tileleft, tiletop, tileright, tilebottom, tilemidx; 293 | Sint16 hitnorth, hiteast, hitsouth, hitwest; 294 | Sint16 temp1, temp2, temp3, temp4; 295 | void *sprite; 296 | struct objstruct *next, *prev; 297 | } objtype; 298 | 299 | typedef struct 300 | { 301 | Uint16 worldx, worldy; 302 | boolean leveldone[GAMELEVELS]; 303 | Sint32 score, nextextra; 304 | Sint16 ammo, drops; 305 | #if defined KEEN4 306 | Sint16 wetsuit; 307 | Sint16 rescued; 308 | #elif defined KEEN5 309 | boolean keycard; 310 | Sint16 destroyed; // never used 311 | Sint16 numfuses; 312 | #elif defined KEEN6 313 | Sint16 sandwichstate, hookstate, passcardstate, rocketstate; 314 | #endif 315 | Sint16 keys[4]; 316 | Sint16 mapon; 317 | Sint16 lives; 318 | Sint16 difficulty; 319 | objtype *riding; 320 | } gametype; 321 | 322 | /* 323 | ============================================================================= 324 | 325 | CK_MAIN DEFINITIONS 326 | 327 | ============================================================================= 328 | */ 329 | 330 | extern char str[80], str2[20]; 331 | extern boolean storedemo; 332 | 333 | Uint16 SizeText(char *text); 334 | 335 | /* 336 | ============================================================================= 337 | 338 | CK_DEMO DEFINITIONS 339 | 340 | ============================================================================= 341 | */ 342 | 343 | extern boolean scorescreenkludge; 344 | 345 | void CheckLastScan(void); 346 | #if GRMODE == EGAGR 347 | void Terminator(void); 348 | void StarWars(void); 349 | #endif 350 | void ShowTitle(void); 351 | #if GRMODE == CGAGR || GRMODE == TGAGR 352 | void ShowCredits(void); 353 | #endif 354 | void RunDemo(Sint16 num); 355 | void DrawHighScores(void); 356 | void CheckHighScore(Sint32 score, Sint16 completed); 357 | void ShowHighScores(void); 358 | 359 | /* 360 | ============================================================================= 361 | 362 | CK_GAME DEFINITIONS 363 | 364 | ============================================================================= 365 | */ 366 | 367 | void FreeGraphics(void); 368 | void NewGame(void); 369 | boolean SaveTheGame(Sint16 handle); 370 | boolean LoadTheGame(Sint16 handle); 371 | void ResetGame(void); 372 | void SetupGameLevel(boolean loadnow); 373 | void DialogDraw(char *title, Uint16 numcache); 374 | void DialogUpdate(void); 375 | void DialogFinish(void); 376 | void StartDemoRecord(void); 377 | void EndDemoRecord(void); 378 | void GameLoop(void); 379 | void HandleDeath(void); 380 | 381 | /* 382 | ============================================================================= 383 | 384 | CK_PLAY DEFINITIONS 385 | 386 | ============================================================================= 387 | */ 388 | 389 | extern boolean jumpcheat, godmode, keenkilled; 390 | extern exittype playstate; 391 | extern gametype gamestate; 392 | extern objtype *new, *player, *scoreobj; 393 | extern Uint16 originxtilemax, originytilemax; 394 | extern ControlInfo c; 395 | extern Sint16 invincible; 396 | extern boolean oldshooting, showscorebox; 397 | extern boolean debugok; 398 | extern boolean jumpbutton, jumpheld, pogobutton, pogoheld, firebutton, fireheld, upheld; 399 | 400 | 401 | void CenterActor(objtype *ob); 402 | void WorldScrollScreen(objtype *ob); 403 | void InitObjArray(void); 404 | void GetNewObj(boolean usedummy); 405 | void RemoveObj(objtype *ob); 406 | void GivePoints(Uint16 points); 407 | void StopMusic(void); 408 | void StartMusic(Uint16 num); 409 | void PlayLoop(void); 410 | 411 | /* 412 | ============================================================================= 413 | 414 | CK_TEXT DEFINITIONS 415 | 416 | ============================================================================= 417 | */ 418 | 419 | void HelpScreens(void); 420 | void FinaleLayout(void); 421 | 422 | /* 423 | ============================================================================= 424 | 425 | CK_STATE DEFINITIONS 426 | 427 | ============================================================================= 428 | */ 429 | 430 | extern Sint16 wallclip[8][16]; 431 | 432 | extern Sint16 xtry; 433 | extern Sint16 ytry; 434 | extern boolean playerkludgeclipcancel; 435 | 436 | void MoveObjVert(objtype *ob, Sint16 ymove); 437 | void MoveObjHoriz(objtype *ob, Sint16 xmove); 438 | void PlayerBottomKludge(objtype *ob); 439 | void PlayerTopKludge(objtype *ob); 440 | void ClipToEnds(objtype *ob); 441 | void ClipToSides(objtype *ob); 442 | boolean CheckPosition(objtype *ob); 443 | boolean StatePositionOk(objtype *ob, statetype *state); 444 | 445 | #ifdef KEEN5 446 | void CalcBounds(objtype *ob); 447 | #endif 448 | 449 | void ClipToWalls(objtype *ob); 450 | void FullClipToWalls(objtype *ob); 451 | void PushObj(objtype *ob); 452 | void ClipToSpriteSide(objtype *push, objtype *solid); 453 | void ClipToSpriteTop(objtype *push, objtype *solid); 454 | void ClipToSprite(objtype *push, objtype *solid, boolean squish); 455 | Sint16 DoActor(objtype *ob, Sint16 numtics); 456 | void StateMachine(objtype *ob); 457 | void NewState(objtype *ob, statetype *state); 458 | void ChangeState(objtype *ob, statetype *state); 459 | boolean OnScreen(objtype *ob); 460 | void DoGravity(objtype *ob); 461 | void DoWeakGravity(objtype *ob); 462 | void DoTinyGravity(objtype *ob); 463 | void AccelerateX(objtype *ob, Sint16 dir, Sint16 maxspeed); 464 | void AccelerateXv(objtype *ob, Sint16 dir, Sint16 maxspeed); 465 | void AccelerateY(objtype *ob, Sint16 dir, Sint16 maxspeed); 466 | void FrictionX(objtype *ob); 467 | void FrictionY(objtype *ob); 468 | void StunObj(objtype *ob, objtype *shot, statetype *stunstate); 469 | void T_Projectile(objtype *ob); 470 | void T_WeakProjectile(objtype *ob); 471 | void ProjectileThink1(objtype *ob); 472 | void T_Velocity(objtype *ob); 473 | void SetReactThink(objtype *ob); 474 | void T_Stunned(objtype *ob); 475 | void C_Lethal(objtype *ob, objtype *hit); 476 | void R_Draw(objtype *ob); 477 | void R_Walk(objtype *ob); 478 | void R_WalkNormal(objtype *ob); 479 | void BadState(void); 480 | void R_Stunned(objtype *ob); 481 | 482 | extern statetype sc_deadstate; 483 | extern statetype sc_badstate; 484 | 485 | /* 486 | ============================================================================= 487 | 488 | CK_KEEN DEFINITIONS 489 | 490 | ============================================================================= 491 | */ 492 | 493 | #ifndef KEEN4 494 | extern arrowdirtype arrowflip[]; 495 | #endif 496 | 497 | extern statetype s_keenstand; 498 | extern statetype s_keenpauselook; 499 | extern statetype s_keenwait1; 500 | extern statetype s_keenwait2; 501 | extern statetype s_keenwait3; 502 | extern statetype s_keenwait4; 503 | extern statetype s_keenwait5; 504 | extern statetype s_keenwait6; 505 | extern statetype s_keenmoon1; 506 | extern statetype s_keenmoon2; 507 | extern statetype s_keenmoon3; 508 | extern statetype s_keenread; 509 | extern statetype s_keenread2; 510 | extern statetype s_keenread3; 511 | extern statetype s_keenread4; 512 | extern statetype s_keenread5; 513 | extern statetype s_keenread6; 514 | extern statetype s_keenread7; 515 | extern statetype s_keenstopread; 516 | extern statetype s_keenstopread2; 517 | extern statetype s_keenstopread3; 518 | extern statetype s_keenlookup; 519 | extern statetype s_keenlookup2; 520 | extern statetype s_keenlookdown; 521 | extern statetype s_keenlookdown2; 522 | extern statetype s_keenlookdown3; 523 | extern statetype s_keenlookdown4; 524 | extern statetype s_keendrop; 525 | extern statetype s_keendead; 526 | extern statetype s_keendie1; 527 | extern statetype s_keendie2; 528 | #ifdef KEEN4 529 | extern statetype s_keensuitdie1; 530 | extern statetype s_keensuitdie2; 531 | #endif 532 | extern statetype s_keenshoot1; 533 | extern statetype s_keenshoot2; 534 | extern statetype s_keenshootup1; 535 | extern statetype s_keenshootup2; 536 | extern statetype s_keenswitch; 537 | extern statetype s_keenswitch2; 538 | extern statetype s_keenkey; 539 | extern statetype s_keenlineup; 540 | extern statetype s_keenenter1; 541 | extern statetype s_keenenter2; 542 | extern statetype s_keenenter3; 543 | extern statetype s_keenenter4; 544 | extern statetype s_keenenter5; 545 | extern statetype s_keenpole; 546 | extern statetype s_keenclimb1; 547 | extern statetype s_keenclimb2; 548 | extern statetype s_keenclimb3; 549 | extern statetype s_keenslide1; 550 | extern statetype s_keenslide2; 551 | extern statetype s_keenslide3; 552 | extern statetype s_keenslide4; 553 | extern statetype s_keenpoleshoot1; 554 | extern statetype s_keenpoleshoot2; 555 | extern statetype s_keenpoleshootup1; 556 | extern statetype s_keenpoleshootup2; 557 | extern statetype s_keenpoleshootdown1; 558 | extern statetype s_keenpoleshootdown2; 559 | extern statetype s_keenwalk1; 560 | extern statetype s_keenwalk2; 561 | extern statetype s_keenwalk3; 562 | extern statetype s_keenwalk4; 563 | extern statetype s_keenpogodown; 564 | extern statetype s_keenpogo; 565 | extern statetype s_keenpogo2; 566 | extern statetype s_keenjump1; 567 | extern statetype s_keenjump2; 568 | extern statetype s_keenjump3; 569 | extern statetype s_keenjump4; 570 | extern statetype s_keenairshoot1; 571 | extern statetype s_keenairshoot2; 572 | extern statetype s_keenairshoot3; 573 | extern statetype s_keenairshootup1; 574 | extern statetype s_keenairshootup2; 575 | extern statetype s_keenairshootup3; 576 | extern statetype s_keenairshootdown1; 577 | extern statetype s_keenairshootdown2; 578 | extern statetype s_keenairshootdown3; 579 | extern statetype s_keenholdon; 580 | extern statetype s_keenholdon2; 581 | extern statetype s_keenclimbup; 582 | extern statetype s_keenclimbup2; 583 | extern statetype s_keenclimbup3; 584 | extern statetype s_keenclimbup4; 585 | extern statetype s_keenclimbup5; 586 | 587 | extern Sint16 slopespeed[8]; 588 | extern Sint16 polexspeed[3]; 589 | 590 | extern Sint16 shotsinclip[4]; 591 | extern Sint16 bonussound[]; 592 | extern Sint16 bonuspoints[]; 593 | extern Sint16 bonussprite[]; 594 | 595 | extern Uint16 zeromap; 596 | 597 | extern Sint16 jumptime; 598 | extern Sint32 leavepoletime; 599 | extern Sint16 moonok; 600 | 601 | void SpawnKeen(Sint16 x, Sint16 y, Sint16 dir); 602 | boolean CheckGrabPole(objtype *ob); 603 | boolean CheckEnterHouse(objtype *ob); 604 | void WalkSound1(objtype *ob); 605 | void WalkSound2(objtype *ob); 606 | void KeenStandThink(objtype *ob); 607 | void KeenPauseThink(objtype *ob); 608 | void KeenReadThink(objtype *ob); 609 | void KeenLookUpThink(objtype *ob); 610 | void KeenLookDownThink(objtype *ob); 611 | void KeenWalkThink(objtype *ob); 612 | void T_LineUp(objtype *ob); 613 | void KeenEnterThink(objtype *ob); 614 | void KeenSwitchThink(objtype *ob); 615 | void KeenKeyThink(objtype *ob); 616 | void KeenAirThink(objtype *ob); 617 | void KeenBounceThink(objtype *ob); 618 | void KeenPogoThink(objtype *ob); 619 | void PoleActions(objtype *ob); 620 | void KeenPoleThink(objtype *ob); 621 | void KeenClimbThink(objtype *ob); 622 | void KeenDropThink(objtype *ob); 623 | void KeenDropDownThink(objtype *ob); 624 | void KeenHoldThink(objtype *ob); 625 | void KeenShootThink(objtype *ob); 626 | void T_PullUp1(objtype *ob); 627 | void T_PullUp2(objtype *ob); 628 | void T_PullUp3(objtype *ob); 629 | void T_PulledUp(objtype *ob); 630 | void KeenDieThink(objtype *ob); 631 | void KillKeen(void); 632 | void KeenContact(objtype *ob, objtype *hit); 633 | void KeenPosContact(objtype *ob, objtype *hit); 634 | void HandleRiding(objtype *ob); 635 | void TileBonus(Uint16 x, Uint16 y, Uint16 bonus); 636 | void GiveDrop(Uint16 x, Uint16 y); 637 | void CheckInTiles(objtype *ob); 638 | void KeenSimpleReact(objtype *ob); 639 | void KeenStandReact(objtype *ob); 640 | void KeenWalkReact(objtype *ob); 641 | void KeenAirReact(objtype *ob); 642 | void KeenPogoReact(objtype *ob); 643 | void KeenPoleReact(objtype *ob); 644 | 645 | 646 | /* 647 | ============================================================================= 648 | 649 | CK_KEEN2 DEFINITIONS 650 | 651 | ============================================================================= 652 | */ 653 | 654 | extern statetype s_score; 655 | extern statetype s_demo; 656 | void SpawnScore(void); 657 | void UpdateScore(objtype *ob); 658 | void DrawDemoPlaque(objtype *ob); 659 | 660 | extern statetype s_worldkeen; 661 | extern statetype s_worldkeenwave1; 662 | extern statetype s_worldkeenwave2; 663 | extern statetype s_worldkeenwave3; 664 | extern statetype s_worldkeenwave4; 665 | extern statetype s_worldkeenwave5; 666 | extern statetype s_worldkeenwalk; 667 | void SpawnWorldKeen(Sint16 x, Sint16 y); 668 | #ifdef KEEN5 669 | void SpawnWorldKeenPort(Uint16 tileX, Uint16 tileY); 670 | #endif 671 | void CheckEnterLevel(objtype *ob); 672 | void T_KeenWorld(objtype *ob); 673 | void T_KeenWorldWalk(objtype *ob); 674 | void CheckWorldInTiles(objtype *ob); 675 | 676 | #ifdef KEEN4 677 | extern statetype s_keenonfoot1; 678 | extern statetype s_keenonfoot2; 679 | extern statetype s_worldswim; 680 | void T_FootFly(objtype *ob); 681 | void T_KeenWorldSwim(objtype *ob); 682 | #endif 683 | 684 | #ifdef KEEN5 685 | extern statetype s_worldelevate; 686 | void T_Elevate(objtype *ob); 687 | #endif 688 | 689 | extern statetype s_flagwave1; 690 | extern statetype s_flagwave2; 691 | extern statetype s_flagwave3; 692 | extern statetype s_flagwave4; 693 | void SpawnFlag(Sint16 x, Sint16 y); 694 | 695 | #ifndef KEEN5 696 | extern statetype s_throwflag0; 697 | extern statetype s_throwflag1; 698 | extern statetype s_throwflag2; 699 | extern statetype s_throwflag3; 700 | extern statetype s_throwflag4; 701 | extern statetype s_throwflag5; 702 | extern statetype s_throwflag6; 703 | void SpawnThrowFlag(Sint16 x, Sint16 y); 704 | void TossThink(objtype *ob); 705 | void PathThink(objtype *ob); 706 | void FlagAlign(objtype *ob); 707 | #endif 708 | 709 | extern statetype s_stunray1; 710 | extern statetype s_stunray2; 711 | extern statetype s_stunray3; 712 | extern statetype s_stunray4; 713 | extern statetype s_stunhit; 714 | extern statetype s_stunhit2; 715 | void SpawnShot(Uint16 x, Uint16 y, Direction dir); 716 | void ExplodeShot(objtype *ob); 717 | void T_Shot(objtype *ob); 718 | void R_Shot(objtype *ob); 719 | 720 | extern statetype s_door1; 721 | extern statetype s_door2; 722 | extern statetype s_door3; 723 | void DoorOpen(objtype *ob); 724 | 725 | #ifdef KEEN5 726 | extern statetype s_carddoor; 727 | void CardDoorOpen(objtype *ob); 728 | #endif 729 | 730 | /* 731 | ============================================================================= 732 | 733 | OTHER DEFINITIONS 734 | 735 | ============================================================================= 736 | */ 737 | 738 | #if defined KEEN4 739 | #include "K4_DEF.H" 740 | #elif defined KEEN5 741 | #include "K5_DEF.H" 742 | #elif defined KEEN6 743 | #include "K6_DEF.H" 744 | #endif 745 | 746 | #endif -------------------------------------------------------------------------------- /KEEN4-6/CK_MAIN.C: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is loosely based on: 9 | * Keen Dreams Source Code 10 | * Copyright (C) 2014 Javier M. Chavez 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // CK_MAIN.C 28 | /* 29 | ============================================================================= 30 | 31 | COMMANDER KEEN 32 | 33 | An Id Software production 34 | 35 | ============================================================================= 36 | */ 37 | 38 | #include "CK_DEF.H" 39 | 40 | /* 41 | ============================================================================= 42 | 43 | GLOBAL VARIABLES 44 | 45 | ============================================================================= 46 | */ 47 | 48 | boolean tedlevel; 49 | Uint16 tedlevelnum; 50 | 51 | char str[80], str2[20]; 52 | boolean storedemo, jerk; 53 | 54 | /* 55 | ============================================================================= 56 | 57 | LOCAL VARIABLES 58 | 59 | ============================================================================= 60 | */ 61 | 62 | //=========================================================================== 63 | 64 | /* 65 | ===================== 66 | = 67 | = SizeText 68 | = 69 | = Calculates height of a string that contains line breaks 70 | = 71 | ===================== 72 | */ 73 | 74 | Uint16 SizeText(char *text) 75 | { 76 | register char *ptr; 77 | char c; 78 | Uint16 w, h; 79 | char strbuf[80]; 80 | Uint16 height = 0; 81 | 82 | ptr = &strbuf[0]; 83 | while ((c=*(text++)) != '\0') 84 | { 85 | *(ptr++) = c; 86 | if (c == '\n' || !*text) 87 | { 88 | USL_MeasureString(strbuf, &w, &h); // BUG: strbuf may not have a terminating '\0' at the end! 89 | height += h; 90 | ptr = &strbuf[0]; 91 | } 92 | } 93 | return height; 94 | } 95 | 96 | //=========================================================================== 97 | 98 | /* 99 | ========================== 100 | = 101 | = ShutdownId 102 | = 103 | = Shuts down all ID_?? managers 104 | = 105 | ========================== 106 | */ 107 | 108 | void ShutdownId(void) 109 | { 110 | US_Shutdown(); 111 | SD_Shutdown(); 112 | IN_Shutdown(); 113 | RF_Shutdown(); 114 | VW_Shutdown(); 115 | CA_Shutdown(); 116 | MM_Shutdown(); 117 | } 118 | 119 | 120 | //=========================================================================== 121 | 122 | /* 123 | ========================== 124 | = 125 | = InitGame 126 | = 127 | = Load a few things right away 128 | = 129 | ========================== 130 | */ 131 | 132 | void InitGame(void) 133 | { 134 | static char *ParmStrings[] = {"JERK", ""}; 135 | 136 | Uint16 segstart,seglength; 137 | Sint16 i; 138 | 139 | // Note: The value of the jerk variable is replaced with the value 140 | // read from the config file during US_Startup, which means the 141 | // JERK parameter has absolutely no effect if a valid config file 142 | // exists. The parameter check should be moved to some place after 143 | // US_Startup to make it work reliably. 144 | 145 | for (i=1; i < _argc; i++) 146 | { 147 | if (US_CheckParm(_argv[i], ParmStrings) == 0) 148 | { 149 | jerk = true; 150 | } 151 | } 152 | 153 | US_TextScreen(); 154 | 155 | MM_Startup(); 156 | VW_Startup(); 157 | RF_Startup(); 158 | IN_Startup(); 159 | SD_Startup(); 160 | US_Startup(); 161 | 162 | US_UpdateTextScreen(); 163 | 164 | CA_Startup(); 165 | US_Setup(); 166 | 167 | US_SetLoadSaveHooks(&LoadTheGame, &SaveTheGame, &ResetGame); 168 | drawcachebox = DialogDraw; 169 | updatecachebox = DialogUpdate; 170 | finishcachebox = DialogFinish; 171 | 172 | // 173 | // load in and lock down some basic chunks 174 | // 175 | 176 | CA_ClearMarks(); 177 | 178 | CA_MarkGrChunk(STARTFONT); 179 | CA_MarkGrChunk(STARTTILE8); 180 | CA_MarkGrChunk(STARTTILE8M); 181 | #if GRMODE == EGAGR 182 | CA_MarkGrChunk(CORDPICM); 183 | CA_MarkGrChunk(METALPOLEPICM); 184 | #endif 185 | 186 | CA_CacheMarks(NULL); 187 | 188 | MM_SetLock(&grsegs[STARTFONT], true); 189 | MM_SetLock(&grsegs[STARTTILE8], true); 190 | MM_SetLock(&grsegs[STARTTILE8M], true); 191 | #if GRMODE == EGAGR 192 | MM_SetLock(&grsegs[CORDPICM], true); 193 | MM_SetLock(&grsegs[METALPOLEPICM], true); 194 | #endif 195 | 196 | fontcolor = WHITE; 197 | 198 | US_FinishTextScreen(); 199 | 200 | // 201 | // reclaim the memory from the linked in text screen 202 | // 203 | segstart = FP_SEG(&introscn); 204 | seglength = 4000/16; 205 | if (FP_OFF(&introscn)) 206 | { 207 | segstart++; 208 | seglength--; 209 | } 210 | MM_UseSpace (segstart,seglength); 211 | mminfo.mainmem += 4000; 212 | 213 | VW_SetScreenMode(GRMODE); 214 | #if GRMODE == CGAGR 215 | VW_ColorBorder(BROWN); 216 | #elif GRMODE == EGAGR || GRMODE == TGAGR 217 | VW_ColorBorder(CYAN); 218 | #endif 219 | } 220 | 221 | //=========================================================================== 222 | 223 | /* 224 | ========================== 225 | = 226 | = Quit 227 | = 228 | ========================== 229 | */ 230 | 231 | void Quit(char *error) 232 | { 233 | Uint16 finscreen; 234 | 235 | if (!error) 236 | { 237 | CA_SetAllPurge(); 238 | CA_CacheGrChunk(ORDERSCREEN); 239 | finscreen = (Uint16)grsegs[ORDERSCREEN]; 240 | } 241 | 242 | // BUG: VW_ClearVideo may brick the system if screenseg is 0 243 | // (i.e. VW_SetScreenMode has not been executed) - this may 244 | // happen if the code runs into an error during InitGame 245 | // (EMS/XMS errors, files not found etc.) 246 | VW_ClearVideo(); 247 | VW_SetLineWidth(40); 248 | 249 | ShutdownId(); 250 | if (error && *error) 251 | { 252 | puts(error); 253 | if (tedlevel) 254 | { 255 | getch(); 256 | execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL); 257 | } 258 | else if (US_ParmPresent("windows")) 259 | { 260 | bioskey(0); 261 | } 262 | exit(1); 263 | } 264 | 265 | if (!NoWait) 266 | { 267 | movedata(finscreen, 7, 0xB800, 0, 4000); 268 | gotoxy(1, 24); 269 | if (US_ParmPresent("windows")) 270 | { 271 | bioskey(0); 272 | } 273 | } 274 | 275 | exit(0); 276 | } 277 | 278 | //=========================================================================== 279 | 280 | /* 281 | ================== 282 | = 283 | = TEDDeath 284 | = 285 | ================== 286 | */ 287 | 288 | void TEDDeath(void) 289 | { 290 | ShutdownId(); 291 | execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL); 292 | // BUG: should call exit(1); here in case starting TED5 fails 293 | } 294 | 295 | //=========================================================================== 296 | 297 | /* 298 | ===================== 299 | = 300 | = DemoLoop 301 | = 302 | ===================== 303 | */ 304 | 305 | void DemoLoop(void) 306 | { 307 | static char *ParmStrings[] = {"easy", "normal", "hard", ""}; 308 | 309 | register Sint16 i, state; 310 | Sint16 level; 311 | 312 | // 313 | // check for launch from ted 314 | // 315 | if (tedlevel) 316 | { 317 | NewGame(); 318 | CA_LoadAllSounds(); 319 | gamestate.mapon = tedlevelnum; 320 | restartgame = gd_Normal; 321 | for (i = 1;i < _argc;i++) 322 | { 323 | if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1) 324 | continue; 325 | 326 | restartgame = level+gd_Easy; 327 | break; 328 | } 329 | GameLoop(); 330 | TEDDeath(); 331 | } 332 | 333 | // 334 | // demo loop 335 | // 336 | state = 0; 337 | playstate = ex_stillplaying; 338 | while (1) 339 | { 340 | switch (state++) 341 | { 342 | case 0: 343 | #if GRMODE == CGAGR || GRMODE == TGAGR 344 | ShowTitle(); 345 | #elif GRMODE == EGAGR 346 | if (nopan) 347 | { 348 | ShowTitle(); 349 | } 350 | else 351 | { 352 | Terminator(); 353 | } 354 | #endif 355 | break; 356 | 357 | case 1: 358 | RunDemo(0); 359 | break; 360 | 361 | case 2: 362 | #if GRMODE == CGAGR || GRMODE == TGAGR 363 | ShowCredits(); 364 | #elif GRMODE == EGAGR 365 | StarWars(); 366 | #endif 367 | break; 368 | 369 | case 3: 370 | RunDemo(1); 371 | break; 372 | 373 | case 4: 374 | ShowHighScores(); 375 | break; 376 | 377 | case 5: 378 | RunDemo(2); 379 | break; 380 | 381 | case 6: 382 | state = 0; 383 | RunDemo(3); 384 | break; 385 | } 386 | 387 | while (playstate == ex_resetgame || playstate == ex_loadedgame) 388 | { 389 | GameLoop(); 390 | ShowHighScores(); 391 | if (playstate == ex_resetgame || playstate == ex_loadedgame) 392 | { 393 | continue; // don't show title screen, go directly to GameLoop(); 394 | } 395 | ShowTitle(); 396 | } 397 | } 398 | } 399 | 400 | //=========================================================================== 401 | 402 | 403 | 404 | /* 405 | ========================== 406 | = 407 | = main 408 | = 409 | ========================== 410 | */ 411 | 412 | void main(void) 413 | { 414 | if (US_ParmPresent("DEMO")) 415 | storedemo = true; 416 | 417 | InitGame(); 418 | 419 | if (NoWait || tedlevel) 420 | debugok = true; 421 | 422 | DemoLoop(); 423 | Quit("Demo loop exited???"); 424 | } -------------------------------------------------------------------------------- /KEEN4-6/CK_TEXT.C: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Wolfenstein 3-D Source Code 10 | * Copyright (C) 1992 id Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | #include "CK_DEF.H" 28 | 29 | /* 30 | ============================================================================= 31 | 32 | TEXT FORMATTING COMMANDS 33 | ------------------------ 34 | ^C Change text color 35 | ^E[enter] End of layout (all pages) 36 | ^G,,[enter] Draw a graphic and push margins 37 | ^P[enter] start new page, must be the first chars in a layout 38 | ^L,[ENTER] Locate to a specific spot, x in pixels, y in lines 39 | 40 | ============================================================================= 41 | */ 42 | 43 | /* 44 | ============================================================================= 45 | 46 | LOCAL CONSTANTS 47 | 48 | ============================================================================= 49 | */ 50 | 51 | #if GRMODE == CGAGR 52 | #ifdef KEEN5 53 | #define BACKCOLOR 2 // CGA magenta 54 | #else 55 | #define BACKCOLOR WHITE 56 | #endif 57 | #elif GRMODE == EGAGR || GRMODE == TGAGR 58 | #define BACKCOLOR RED 59 | #endif 60 | 61 | #define WORDLIMIT 80 62 | #define FONTHEIGHT 10 63 | #define TOPMARGIN 10 64 | #define BOTTOMMARGIN 10 65 | #define LEFTMARGIN 10 66 | #define RIGHTMARGIN 10 67 | #define PICMARGIN 8 68 | #define SPACEWIDTH 7 69 | #define TEXTROWS ((200-TOPMARGIN-BOTTOMMARGIN)/FONTHEIGHT) 70 | #define SCREENPIXWIDTH 320 71 | #define SCREENMID (SCREENPIXWIDTH/2) 72 | 73 | /* 74 | ============================================================================= 75 | 76 | LOCAL VARIABLES 77 | 78 | ============================================================================= 79 | */ 80 | 81 | Sint16 pagenum,numpages; 82 | Uint16 leftmargin[TEXTROWS],rightmargin[TEXTROWS]; 83 | char far *text; 84 | Uint16 rowon; 85 | Sint16 picx,picy,picnum,picdelay; 86 | boolean layoutdone; 87 | 88 | Sint16 helpmenupos; 89 | 90 | //=========================================================================== 91 | 92 | /* 93 | ===================== 94 | = 95 | = RipToEOL 96 | = 97 | ===================== 98 | */ 99 | 100 | void RipToEOL(void) 101 | { 102 | while (*text++ != '\n'); 103 | } 104 | 105 | 106 | /* 107 | ===================== 108 | = 109 | = ParseNumber 110 | = 111 | ===================== 112 | */ 113 | 114 | Sint16 ParseNumber(void) 115 | { 116 | char c, buffer[80]; 117 | char *bufptr; 118 | 119 | // 120 | // scan until a number is found 121 | // 122 | c = *text; 123 | while (c < '0' || c > '9') 124 | c = *++text; 125 | 126 | // 127 | // copy the number out 128 | // 129 | bufptr = buffer; 130 | do 131 | { 132 | *bufptr = c; 133 | bufptr++; 134 | text++; 135 | c = *text; 136 | } while (c >= '0' && c <= '9'); 137 | *bufptr = 0; 138 | 139 | return atoi(buffer); 140 | } 141 | 142 | 143 | /* 144 | ===================== 145 | = 146 | = ParsePicCommand 147 | = 148 | = Call with text pointing just after a ^P 149 | = Upon exit text points to the start of next line 150 | = 151 | ===================== 152 | */ 153 | 154 | void ParsePicCommand(void) 155 | { 156 | picy = ParseNumber(); 157 | picx = ParseNumber(); 158 | picnum = ParseNumber(); 159 | RipToEOL(); 160 | } 161 | 162 | void ParseTimedCommand(void) 163 | { 164 | picy = ParseNumber(); 165 | picx = ParseNumber(); 166 | picnum = ParseNumber(); 167 | picdelay = ParseNumber(); 168 | RipToEOL(); 169 | } 170 | 171 | /* 172 | ===================== 173 | = 174 | = TimedPicCommand 175 | = 176 | = Call with text pointing just after a ^P 177 | = Upon exit text points to the start of next line 178 | = 179 | ===================== 180 | */ 181 | 182 | void TimedPicCommand(void) 183 | { 184 | ParseTimedCommand(); 185 | 186 | // 187 | // update the screen, and wait for time delay 188 | // 189 | #if GRMODE == CGAGR 190 | VW_UpdateScreen(); 191 | #elif GRMODE == TGAGR 192 | VW_UpdateScreen(); 193 | VW_TGABottomUpdate(); 194 | #elif GRMODE == EGAGR 195 | VW_WaitVBL(1); 196 | VW_ScreenToScreen(bufferofs, displayofs, 40, 200); 197 | #endif 198 | 199 | // 200 | // wait for time 201 | // 202 | TimeCount = 0; 203 | while (picdelay > TimeCount) 204 | ; 205 | 206 | // 207 | // draw pic 208 | // 209 | VWB_DrawPic(picx & ~7, picy, picnum); 210 | } 211 | 212 | 213 | /* 214 | ===================== 215 | = 216 | = HandleCommand 217 | = 218 | ===================== 219 | */ 220 | 221 | void HandleCommand(void) 222 | { 223 | Sint16 i,margin,top,bottom; 224 | Sint16 picwidth,picheight,picmid; 225 | 226 | switch (toupper(*(++text))) 227 | { 228 | case 'B': 229 | picy = ParseNumber(); 230 | picx = ParseNumber(); 231 | picwidth = ParseNumber(); 232 | picheight = ParseNumber(); 233 | VWB_Bar(picx, picy, picwidth, picheight, BACKCOLOR); 234 | RipToEOL(); 235 | break; 236 | 237 | case 'P': // ^P is start of next page, ^E is end of file 238 | case 'E': 239 | layoutdone = true; 240 | text--; 241 | break; 242 | 243 | case 'C': // ^c changes text color 244 | i = toupper(*(++text)); 245 | if (i >= '0' && i <= '9') 246 | { 247 | fontcolor = i + 0 - '0'; 248 | } 249 | else if (i >= 'A' && i <= 'F') 250 | { 251 | fontcolor = i + 10 - 'A'; 252 | } 253 | #if GRMODE == CGAGR 254 | { 255 | static Sint16 colormap[16] = {2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}; 256 | // Note: This mapping is a bit problematic for Keen 5 CGA, 257 | // since some colors get mapped to CGA magenta, which is 258 | // used as the background color in that version. Luckily 259 | // those colors aren't used in the Keen 5 texts anyway. 260 | 261 | fontcolor = colormap[fontcolor]; 262 | } 263 | #endif 264 | fontcolor ^= BACKCOLOR; 265 | text++; 266 | break; 267 | 268 | case 'L': 269 | py = ParseNumber(); 270 | rowon = (py - 10)/10; 271 | py = rowon * 10 + 10; 272 | px = ParseNumber(); 273 | while (*(text++) != '\n') // scan to end of line 274 | ; 275 | break; 276 | 277 | case 'T': // ^Tyyy,xxx,ppp,ttt waits ttt tics, then draws pic 278 | TimedPicCommand(); 279 | break; 280 | 281 | case 'G': // ^Gyyy,xxx,ppp draws graphic 282 | ParsePicCommand(); 283 | VWB_DrawPic(picx & ~7, picy, picnum); 284 | picwidth = pictable[picnum-STARTPICS].width * BYTEPIXELS; 285 | picheight = pictable[picnum-STARTPICS].height; 286 | picmid = picx + picwidth/2; 287 | // 288 | // adjust margins 289 | // 290 | if (picmid > SCREENMID) 291 | { 292 | margin = picx-PICMARGIN; // new right margin 293 | } 294 | else 295 | { 296 | margin = picx+picwidth+PICMARGIN; // new left margin 297 | } 298 | top = (picy-TOPMARGIN)/FONTHEIGHT; 299 | if (top < 0) 300 | { 301 | top = 0; 302 | } 303 | bottom = (picy+picheight-TOPMARGIN)/FONTHEIGHT; 304 | if (bottom >= TEXTROWS) 305 | { 306 | bottom = TEXTROWS-1; 307 | } 308 | 309 | for (i=top; i<=bottom; i++) 310 | { 311 | if (picmid > SCREENMID) 312 | { 313 | rightmargin[i] = margin; 314 | } 315 | else 316 | { 317 | leftmargin[i] = margin; 318 | } 319 | } 320 | 321 | // 322 | // adjust this line if needed 323 | // 324 | if (leftmargin[rowon] > px) 325 | { 326 | px = leftmargin[rowon]; 327 | } 328 | break; 329 | } 330 | } 331 | 332 | 333 | /* 334 | ===================== 335 | = 336 | = NewLine 337 | = 338 | ===================== 339 | */ 340 | 341 | void NewLine(void) 342 | { 343 | char c; 344 | 345 | if (++rowon == TEXTROWS) 346 | { 347 | // 348 | // overflowed the page, so skip until next page break 349 | // 350 | layoutdone = true; 351 | do 352 | { 353 | if (*text == '^') 354 | { 355 | c = toupper(text[1]); 356 | if (c == 'E' || c == 'P') 357 | { 358 | layoutdone = true; 359 | return; 360 | } 361 | } 362 | text++; 363 | } while (1); 364 | } 365 | px = leftmargin[rowon]; 366 | py += FONTHEIGHT; 367 | } 368 | 369 | 370 | /* 371 | ===================== 372 | = 373 | = HandleCtrls 374 | = 375 | ===================== 376 | */ 377 | 378 | void HandleCtrls(void) 379 | { 380 | char c; 381 | 382 | c = *(text++); // get the character and advance 383 | 384 | if (c == '\n') 385 | { 386 | NewLine(); 387 | return; 388 | } 389 | } 390 | 391 | /* 392 | ===================== 393 | = 394 | = HandleWord 395 | = 396 | ===================== 397 | */ 398 | 399 | void HandleWord(void) 400 | { 401 | Uint16 wwidth, wheight, newpos, wordindex; 402 | char word[WORDLIMIT]; 403 | 404 | // 405 | // copy the next word into [word] 406 | // 407 | word[0] = *(text++); 408 | wordindex = 1; 409 | while (*text > ' ') 410 | { 411 | word[wordindex] = *(text++); 412 | if (++wordindex == WORDLIMIT) 413 | { 414 | Quit("PageLayout: Word limit exceeded"); 415 | } 416 | } 417 | word[wordindex] = 0; // stick a null at end for C 418 | 419 | // 420 | // see if it fits on this line 421 | // 422 | VW_MeasurePropString(word, &wwidth, &wheight); 423 | 424 | while (rightmargin[rowon] < px+wwidth) 425 | { 426 | NewLine(); 427 | if (layoutdone) 428 | { 429 | return; // overflowed page 430 | } 431 | } 432 | 433 | // 434 | // print it 435 | // 436 | newpos = px+wwidth; 437 | VWB_DrawPropString(word); 438 | px = newpos; 439 | 440 | // 441 | // suck up any extra spaces 442 | // 443 | while (*text == ' ') 444 | { 445 | px += SPACEWIDTH; 446 | text++; 447 | } 448 | } 449 | 450 | /* 451 | ===================== 452 | = 453 | = PageLayout 454 | = 455 | = Clears the screen, draws the pics on the page, and word wraps the text. 456 | = Returns a pointer to the terminating command 457 | = 458 | ===================== 459 | */ 460 | 461 | void PageLayout(boolean shownumber) 462 | { 463 | Sint16 oldcolor, i; 464 | char c; 465 | 466 | oldcolor = fontcolor; 467 | 468 | #if GRMODE == CGAGR 469 | fontcolor = BLACK^BACKCOLOR; 470 | #elif GRMODE == EGAGR || GRMODE == TGAGR 471 | fontcolor = YELLOW^BACKCOLOR; 472 | #endif 473 | 474 | // 475 | // clear the screen 476 | // 477 | VWB_Bar(0, 0, 320, 200, BACKCOLOR); 478 | #ifndef KEEN6 479 | VWB_DrawPic( 0, 0, H_TOPWINDOWPIC); 480 | VWB_DrawPic( 0, 8, H_LEFTWINDOWPIC); 481 | VWB_DrawPic(312, 8, H_RIGHTWINDOWPIC); 482 | if (shownumber) 483 | { 484 | VWB_DrawPic(8, 176, H_BOTTOMINFOPIC); 485 | } 486 | else 487 | { 488 | VWB_DrawPic(8, 192, H_BOTTOMWINDOWPIC); 489 | } 490 | #endif 491 | 492 | for (i=0; i 3) 693 | { 694 | helpmenupos = 3; 695 | } 696 | #else 697 | else if (helpmenupos > 4) 698 | { 699 | helpmenupos = 4; 700 | } 701 | #endif 702 | VWB_DrawPic(48, 24*helpmenupos+48, H_HANDPIC); 703 | VW_UpdateScreen(); 704 | #if GRMODE == TGAGR 705 | VW_TGABottomUpdate(); 706 | #endif 707 | VWB_Bar(48, 24*helpmenupos+48, 39, 24, BACKCOLOR); 708 | IN_ReadControl(0, &control); 709 | IN_ReadCursor(&cursor); 710 | if (LastScan) 711 | { 712 | key = LastScan; 713 | IN_ClearKeysDown(); 714 | switch (key) 715 | { 716 | case sc_UpArrow: 717 | helpmenupos--; 718 | break; 719 | case sc_DownArrow: 720 | helpmenupos++; 721 | break; 722 | case sc_Enter: 723 | return helpmenupos; 724 | case sc_Escape: 725 | return -1; 726 | } 727 | } 728 | ydelta += cursor.y; 729 | if (cursor.button0 || cursor.button1 || control.button0 || control.button1) 730 | { 731 | return helpmenupos; 732 | } 733 | if (ydelta < -40) 734 | { 735 | ydelta += 40; 736 | helpmenupos--; 737 | } 738 | else if (ydelta > 40) 739 | { 740 | ydelta -= 40; 741 | helpmenupos++; 742 | } 743 | } while (1); 744 | } 745 | 746 | /* 747 | ================= 748 | = 749 | = HelpScreens 750 | = 751 | ================= 752 | */ 753 | void HelpScreens(void) 754 | { 755 | static Uint16 layouttable[5] = 756 | { 757 | T_HELPART, 758 | T_CONTRART, 759 | T_STORYART, 760 | #ifndef GOODTIMES 761 | T_ORDERART, 762 | #endif 763 | T_IDART 764 | }; 765 | 766 | Uint16 olddisplayofs, oldbufferofs, oldfontnumber, temp; 767 | Sint16 pos; 768 | boolean newpage; 769 | 770 | oldfontnumber = fontnumber; 771 | olddisplayofs = displayofs; 772 | oldbufferofs = bufferofs; 773 | fontnumber = 0; 774 | 775 | #if GRMODE == EGAGR 776 | EGAMAPMASK(15); 777 | #endif 778 | 779 | CA_UpLevel(); 780 | CA_SetGrPurge(); 781 | 782 | #if GRMODE == EGAGR 783 | RF_FixOfs(); 784 | bufferofs = 0; 785 | displayofs = 0x8000; 786 | VW_SetScreen(displayofs, 0); 787 | #endif 788 | 789 | #ifdef KEEN5 790 | StartMusic(19); 791 | #endif 792 | 793 | do 794 | { 795 | pos = HelpMenu(); 796 | 797 | if (pos == -1) 798 | { 799 | CA_DownLevel(); 800 | IN_ClearKeysDown(); 801 | bufferofs = oldbufferofs; 802 | displayofs = olddisplayofs; 803 | fontnumber = oldfontnumber; 804 | RF_FixOfs(); 805 | #ifdef KEEN5 806 | StopMusic(); // Note: it's safer to call StopMusic BEFORE CA_DownLevel 807 | #endif 808 | return; 809 | } 810 | 811 | pos = layouttable[pos]; 812 | CA_CacheGrChunk(pos); 813 | text = grsegs[pos]; 814 | CacheLayoutGraphics(); 815 | 816 | newpage = true; 817 | do 818 | { 819 | if (newpage) 820 | { 821 | newpage = false; 822 | PageLayout(true); 823 | #if GRMODE == CGAGR 824 | VW_UpdateScreen(); 825 | #elif GRMODE == TGAGR 826 | VW_UpdateScreen(); 827 | VW_TGABottomUpdate(); 828 | #elif GRMODE == EGAGR 829 | VW_SetScreen(bufferofs, 0); 830 | temp = displayofs; 831 | displayofs = bufferofs; 832 | bufferofs = temp; 833 | #endif 834 | } 835 | 836 | LastScan = 0; 837 | while (!LastScan); 838 | 839 | switch (LastScan) 840 | { 841 | case sc_UpArrow: 842 | case sc_LeftArrow: 843 | case sc_PgUp: 844 | if (pagenum > 1) 845 | { 846 | BackPage(); 847 | BackPage(); 848 | newpage = true; 849 | } 850 | break; 851 | case sc_DownArrow: 852 | case sc_RightArrow: 853 | case sc_PgDn: 854 | if (pagenum < numpages) 855 | { 856 | newpage = true; 857 | } 858 | break; 859 | } 860 | } while (LastScan != sc_Escape); 861 | 862 | MM_FreePtr(&grsegs[pos]); 863 | IN_ClearKeysDown(); 864 | } while (true); 865 | } 866 | 867 | #endif 868 | 869 | //=========================================================================== 870 | 871 | /* 872 | ================= 873 | = 874 | = FinaleLayout 875 | = 876 | ================= 877 | */ 878 | void FinaleLayout(void) 879 | { 880 | char _seg *textseg; 881 | Sint16 i; 882 | 883 | RF_FixOfs(); 884 | CA_UpLevel(); 885 | CA_SetGrPurge(); 886 | CA_CacheGrChunk(H_FLASHARROW2PIC); 887 | CA_CacheGrChunk(H_FLASHARROW1PIC); 888 | 889 | #ifdef KEEN5 890 | if (gamestate.leveldone[13] == ex_fusebroke) 891 | { 892 | CA_CacheGrChunk(T_ENDART2); 893 | textseg = grsegs[T_ENDART2]; 894 | } 895 | else 896 | { 897 | CA_CacheGrChunk(T_ENDART); 898 | textseg = grsegs[T_ENDART]; 899 | } 900 | #else 901 | CA_CacheGrChunk(T_ENDART); 902 | textseg = grsegs[T_ENDART]; 903 | #endif 904 | 905 | text = textseg; 906 | CacheLayoutGraphics(); 907 | 908 | StartMusic(ENDINGMUSIC); 909 | 910 | while (pagenum < numpages) 911 | { 912 | PageLayout(false); 913 | IN_ClearKeysDown(); 914 | #if GRMODE == CGAGR 915 | VW_UpdateScreen(); 916 | #elif GRMODE == TGAGR 917 | VW_UpdateScreen(); 918 | VW_TGABottomUpdate(); 919 | #elif GRMODE == EGAGR 920 | VW_SetScreen(bufferofs, 0); 921 | #endif 922 | 923 | do 924 | { 925 | VWB_DrawPic(296, 184, H_FLASHARROW1PIC); 926 | #if GRMODE == CGAGR 927 | VW_UpdateScreen(); 928 | #elif GRMODE == TGAGR 929 | VW_UpdateScreen(); 930 | VW_TGABottomUpdate(); 931 | #endif 932 | for (i=0; i> ?? = tile 53 | #define G_P_SHIFT 4 // global >> ?? = pixels 54 | 55 | #if GRMODE == EGAGR || GRMODE == CGAGR 56 | #define SCREENTILESWIDE 20 57 | #define SCREENTILESHIGH 13 58 | #elif GRMODE == TGAGR 59 | #define SCREENTILESWIDE 20 60 | #define SCREENTILESHIGH 11 61 | #endif 62 | 63 | #define PORTTILESWIDE (SCREENTILESWIDE+1) // all drawing takes place inside a 64 | #define PORTTILESHIGH (SCREENTILESHIGH+1) // non displayed port of this size 65 | 66 | #define UPDATEWIDE (PORTTILESWIDE+1) 67 | #define UPDATEHIGH PORTTILESHIGH 68 | 69 | /* 70 | ============================================================================= 71 | 72 | PUBLIC VARIABLES 73 | 74 | ============================================================================= 75 | */ 76 | 77 | 78 | extern boolean compatibility; // crippled refresh for weirdo SVGAs 79 | 80 | extern unsigned tics; 81 | extern long lasttimecount; 82 | 83 | extern unsigned originxglobal,originyglobal; 84 | extern unsigned originxtile,originytile; 85 | 86 | extern unsigned mapwidth,mapheight; 87 | 88 | extern unsigned mapbwidthtable[MAXMAPHEIGHT]; 89 | 90 | extern unsigned originxmin,originxmax,originymin,originymax; 91 | 92 | extern unsigned masterofs; 93 | 94 | // 95 | // the floating update window is also used by the view manager for 96 | // double buffer tracking 97 | // 98 | 99 | extern byte *updateptr; // current start of update window 100 | 101 | #if GRMODE == CGAGR || GRMODE == TGAGR 102 | extern byte *baseupdateptr; 103 | #endif 104 | 105 | extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH]; 106 | extern unsigned updatemapofs[UPDATEWIDE*UPDATEHIGH]; 107 | extern unsigned uwidthtable[UPDATEHIGH]; // lookup instead of multiply 108 | 109 | #define UPDATETERMINATE 0x0301 110 | 111 | /* 112 | ============================================================================= 113 | 114 | PUBLIC FUNCTIONS 115 | 116 | ============================================================================= 117 | */ 118 | 119 | void RF_Startup (void); 120 | void RF_Shutdown (void); 121 | 122 | void RF_FixOfs (void); 123 | void RF_NewMap (void); 124 | void RF_MarkTileGraphics (void); 125 | void RF_InitAnimList (void); 126 | void RF_SetScrollBlockHorizontal (int y); 127 | void RF_SetScrollBlockVertical (int x); 128 | void RF_NewPosition (unsigned x, unsigned y); 129 | void RF_Scroll (int x, int y); 130 | 131 | void RF_MapToMap (unsigned srcx, unsigned srcy, 132 | unsigned destx, unsigned desty, 133 | unsigned width, unsigned height); 134 | void RF_MemToMap (unsigned far *source, unsigned plane, 135 | unsigned destx, unsigned desty, 136 | unsigned width, unsigned height); 137 | 138 | void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly, 139 | unsigned spritenumber, int priority); 140 | void RF_RemoveSprite (void **user); 141 | 142 | void RF_Refresh (void); 143 | void RF_ForceRefresh (void); 144 | void RF_SetRefreshHook (void (*func) (void) ); 145 | 146 | #if GRMODE == EGAGR 147 | unsigned RF_FindFreeBuffer (void); 148 | #endif 149 | -------------------------------------------------------------------------------- /KEEN4-6/ID_RF_A.ASM: -------------------------------------------------------------------------------- 1 | ; Commander Keen 4 Tandy Version Source Code 2 | ; Copyright (C) 2021-2022 Frenkel Smeijers 3 | ; 4 | ; This file is primarily based on: 5 | ; Catacomb 3-D Source Code 6 | ; Copyright (C) 1993-2014 Flat Rock Software 7 | ; 8 | ; This program is free software; you can redistribute it and/or modify 9 | ; it under the terms of the GNU General Public License as published by 10 | ; the Free Software Foundation; either version 2 of the License, or 11 | ; (at your option) any later version. 12 | ; 13 | ; This program is distributed in the hope that it will be useful, 14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ; GNU General Public License for more details. 17 | ; 18 | ; You should have received a copy of the GNU General Public License along 19 | ; with this program; if not, write to the Free Software Foundation, Inc., 20 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | 22 | ; ID_RF_A.ASM 23 | 24 | IDEAL 25 | MODEL MEDIUM,C 26 | 27 | INCLUDE "ID_ASM.EQU" 28 | 29 | ;============================================================================ 30 | 31 | IFE GRMODE-EGAGR 32 | TILESWIDE = 21 33 | TILESHIGH = 14 34 | ENDIF 35 | 36 | IFE GRMODE-CGAGR 37 | TILESWIDE = 21 38 | TILESHIGH = 14 39 | ENDIF 40 | 41 | IFE GRMODE-TGAGR 42 | TILESWIDE = 21 43 | TILESHIGH = 12 44 | ENDIF 45 | 46 | UPDATESIZE = (TILESWIDE+1)*TILESHIGH+1 47 | 48 | DATASEG 49 | 50 | EXTRN screenseg:WORD 51 | EXTRN updateptr:WORD 52 | EXTRN updatestart:WORD 53 | EXTRN masterofs:WORD ;start of master tile port 54 | EXTRN bufferofs:WORD ;start of current buffer port 55 | EXTRN grsegs:WORD 56 | EXTRN mapsegs:WORD 57 | EXTRN originmap:WORD 58 | EXTRN updatemapofs:WORD 59 | EXTRN tinf:WORD ;seg pointer to map header and tile info 60 | EXTRN blockstarts:WORD ;offsets from bufferofs for each update block 61 | 62 | planemask db ? 63 | planenum db ? 64 | 65 | CODESEG 66 | 67 | screenstartcs dw ? ;in code segment for accessibility 68 | 69 | 70 | 71 | 72 | IFE GRMODE-TGAGR 73 | ;============================================================================ 74 | ; 75 | ; TGA refresh routines 76 | ; 77 | ;============================================================================ 78 | 79 | TILEWIDTH = 8 80 | 81 | ;================= 82 | ; 83 | ; RFL_NewTile 84 | ; 85 | ; Draws a composit two plane tile to the master screen and sets the update 86 | ; spot to 1 in both update pages, forcing the tile to be copied to the 87 | ; view pages the next two refreshes 88 | ; 89 | ; Called to draw newly scrolled on strips and animating tiles 90 | ; 91 | ;================= 92 | 93 | PROC RFL_NewTile updateoffset:WORD 94 | PUBLIC RFL_NewTile 95 | USES SI,DI 96 | 97 | ; 98 | ; mark both update lists at this spot 99 | ; 100 | mov di,[updateoffset] 101 | 102 | mov bx,[updateptr] ;start of update matrix 103 | mov [BYTE bx+di],1 104 | 105 | mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line 106 | 107 | ; 108 | ; set di to the location in screenseg to draw the tile 109 | ; 110 | shl di,1 111 | mov si,[updatemapofs+di] ;offset in map from origin 112 | add si,[originmap] 113 | mov di,[blockstarts+di] ;screen location for tile 114 | add di,[masterofs] 115 | 116 | ; 117 | ; set BX to the foreground tile number and SI to the background number 118 | ; If either BX or SI = 0xFFFF, the tile does not need to be masked together 119 | ; as one of the planes totally eclipses the other 120 | ; 121 | mov es,[mapsegs+2] ;foreground plane 122 | mov bx,[es:si] 123 | mov es,[mapsegs] ;background plane 124 | mov si,[es:si] 125 | 126 | mov es,[screenseg] 127 | 128 | or bx,bx 129 | jz @@singletile 130 | jmp @@maskeddraw ;draw both together 131 | 132 | ;============= 133 | ; 134 | ; Draw single background tile from main memory 135 | ; 136 | ;============= 137 | 138 | @@singletile: 139 | shl si,1 140 | mov ds,[grsegs+STARTTILE16*2+si] 141 | 142 | xor si,si ;block is segment aligned 143 | 144 | REPT 15 145 | movsw 146 | movsw 147 | movsw 148 | movsw 149 | add di,dx 150 | ENDM 151 | movsw 152 | movsw 153 | movsw 154 | movsw 155 | 156 | mov ax,ss 157 | mov ds,ax ;restore turbo's data segment 158 | ret 159 | 160 | 161 | ;========= 162 | ; 163 | ; Draw a masked tile combo 164 | ; Interupts are disabled and the stack segment is reassigned 165 | ; 166 | ;========= 167 | @@maskeddraw: 168 | cli ; don't allow ints when SS is set 169 | shl bx,1 170 | mov ss,[grsegs+STARTTILE16M*2+bx] 171 | shl si,1 172 | mov ds,[grsegs+STARTTILE16*2+si] 173 | 174 | xor si,si ;first word of tile data 175 | 176 | REPT 16 177 | mov ax,[si] ;background tile 178 | and ax,[ss:si] ;mask 179 | or ax,[ss:si+128] ;masked data 180 | stosw 181 | mov ax,[si+2] ;background tile 182 | and ax,[ss:si+2] ;mask 183 | or ax,[ss:si+128+2] ;masked data 184 | stosw 185 | mov ax,[si+4] ;background tile 186 | and ax,[ss:si+4] ;mask 187 | or ax,[ss:si+128+4] ;masked data 188 | stosw 189 | mov ax,[si+6] ;background tile 190 | and ax,[ss:si+6] ;mask 191 | or ax,[ss:si+128+6] ;masked data 192 | stosw 193 | add si,8 194 | add di,dx 195 | ENDM 196 | 197 | mov ax,@DATA 198 | mov ss,ax 199 | sti 200 | mov ds,ax 201 | ret 202 | ENDP 203 | 204 | ENDIF 205 | 206 | 207 | 208 | IFE GRMODE-CGAGR 209 | ;============================================================================ 210 | ; 211 | ; CGA refresh routines 212 | ; 213 | ;============================================================================ 214 | 215 | TILEWIDTH = 4 216 | 217 | ;================= 218 | ; 219 | ; RFL_NewTile 220 | ; 221 | ; Draws a composit two plane tile to the master screen and sets the update 222 | ; spot to 1 in both update pages, forcing the tile to be copied to the 223 | ; view pages the next two refreshes 224 | ; 225 | ; Called to draw newly scrolled on strips and animating tiles 226 | ; 227 | ;================= 228 | 229 | PROC RFL_NewTile updateoffset:WORD 230 | PUBLIC RFL_NewTile 231 | USES SI,DI 232 | 233 | ; 234 | ; mark both update lists at this spot 235 | ; 236 | mov di,[updateoffset] 237 | 238 | mov bx,[updateptr] ;start of update matrix 239 | mov [BYTE bx+di],1 240 | 241 | mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line 242 | 243 | ; 244 | ; set di to the location in screenseg to draw the tile 245 | ; 246 | shl di,1 247 | mov si,[updatemapofs+di] ;offset in map from origin 248 | add si,[originmap] 249 | mov di,[blockstarts+di] ;screen location for tile 250 | add di,[masterofs] 251 | 252 | ; 253 | ; set BX to the foreground tile number and SI to the background number 254 | ; If either BX or SI = 0xFFFF, the tile does not need to be masked together 255 | ; as one of the planes totally eclipses the other 256 | ; 257 | mov es,[mapsegs+2] ;foreground plane 258 | mov bx,[es:si] 259 | mov es,[mapsegs] ;background plane 260 | mov si,[es:si] 261 | 262 | mov es,[screenseg] 263 | 264 | or bx,bx 265 | jz @@singletile 266 | jmp @@maskeddraw ;draw both together 267 | 268 | ;============= 269 | ; 270 | ; Draw single background tile from main memory 271 | ; 272 | ;============= 273 | 274 | @@singletile: 275 | shl si,1 276 | mov ds,[grsegs+STARTTILE16*2+si] 277 | 278 | xor si,si ;block is segment aligned 279 | 280 | REPT 15 281 | movsw 282 | movsw 283 | add di,dx 284 | ENDM 285 | movsw 286 | movsw 287 | 288 | mov ax,ss 289 | mov ds,ax ;restore turbo's data segment 290 | ret 291 | 292 | 293 | ;========= 294 | ; 295 | ; Draw a masked tile combo 296 | ; Interupts are disabled and the stack segment is reassigned 297 | ; 298 | ;========= 299 | @@maskeddraw: 300 | cli ; don't allow ints when SS is set 301 | shl bx,1 302 | mov ss,[grsegs+STARTTILE16M*2+bx] 303 | shl si,1 304 | mov ds,[grsegs+STARTTILE16*2+si] 305 | 306 | xor si,si ;first word of tile data 307 | 308 | REPT 16 309 | mov ax,[si] ;background tile 310 | and ax,[ss:si] ;mask 311 | or ax,[ss:si+64] ;masked data 312 | stosw 313 | mov ax,[si+2] ;background tile 314 | and ax,[ss:si+2] ;mask 315 | or ax,[ss:si+66] ;masked data 316 | stosw 317 | add si,4 318 | add di,dx 319 | ENDM 320 | 321 | mov ax,@DATA 322 | mov ss,ax 323 | sti 324 | mov ds,ax 325 | ret 326 | ENDP 327 | 328 | ENDIF 329 | 330 | 331 | 332 | IFE GRMODE-EGAGR 333 | ;=========================================================================== 334 | ; 335 | ; EGA refresh routines 336 | ; 337 | ;=========================================================================== 338 | 339 | TILEWIDTH = 2 340 | 341 | ;================= 342 | ; 343 | ; RFL_NewTile 344 | ; 345 | ; Draws a composit two plane tile to the master screen and sets the update 346 | ; spot to 1 in both update pages, forcing the tile to be copied to the 347 | ; view pages the next two refreshes 348 | ; 349 | ; Called to draw newly scrolled on strips and animating tiles 350 | ; 351 | ; Assumes write mode 0 352 | ; 353 | ;================= 354 | 355 | PROC RFL_NewTile updateoffset:WORD 356 | PUBLIC RFL_NewTile 357 | USES SI,DI 358 | 359 | ; 360 | ; mark both update lists at this spot 361 | ; 362 | mov di,[updateoffset] 363 | 364 | mov bx,[updatestart] ;page 0 pointer 365 | mov [BYTE bx+di],1 366 | mov bx,[updatestart+2] ;page 1 pointer 367 | mov [BYTE bx+di],1 368 | 369 | ; 370 | ; set screenstartcs to the location in screenseg to draw the tile 371 | ; 372 | shl di,1 373 | mov si,[updatemapofs+di] ;offset in map from origin 374 | add si,[originmap] 375 | mov di,[blockstarts+di] ;screen location for tile 376 | add di,[masterofs] 377 | mov [cs:screenstartcs],di 378 | 379 | ; 380 | ; set BX to the foreground tile number and SI to the background number 381 | ; If either BX or SI = 0xFFFF, the tile does not need to be masked together 382 | ; as one of the planes totally eclipses the other 383 | ; 384 | mov es,[mapsegs+2] ;foreground plane 385 | mov bx,[es:si] 386 | mov es,[mapsegs] ;background plane 387 | mov si,[es:si] 388 | 389 | mov es,[screenseg] 390 | mov dx,SC_INDEX ;for stepping through map mask planes 391 | 392 | or bx,bx 393 | jz @@singletile 394 | jmp @@maskeddraw ;draw both together 395 | 396 | ;========= 397 | ; 398 | ; No foreground tile, so draw a single background tile. 399 | ; 400 | ;========= 401 | @@singletile: 402 | 403 | mov bx,SCREENWIDTH-2 ;add to get to start of next line 404 | shl si,1 405 | 406 | mov ax,[cs:screenstartcs] 407 | mov ds,[grsegs+STARTTILE16*2+si] 408 | 409 | xor si,si ;block is segment aligned 410 | 411 | mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0 412 | 413 | mov cx,4 ;draw four planes 414 | @@planeloop: 415 | mov dx,SC_INDEX 416 | WORDOUT 417 | 418 | mov di,[cs:screenstartcs] ;start at same place in all planes 419 | 420 | REPT 15 421 | movsw 422 | add di,bx 423 | ENDM 424 | movsw 425 | 426 | shl ah,1 ;shift plane mask over for next plane 427 | loop @@planeloop 428 | 429 | mov ax,ss 430 | mov ds,ax ;restore turbo's data segment 431 | ret 432 | 433 | 434 | ;========= 435 | ; 436 | ; Draw a masked tile combo 437 | ; Interupts are disabled and the stack segment is reassigned 438 | ; 439 | ;========= 440 | @@maskeddraw: 441 | cli ; don't allow ints when SS is set 442 | shl bx,1 443 | mov ss,[grsegs+STARTTILE16M*2+bx] 444 | shl si,1 445 | mov ds,[grsegs+STARTTILE16*2+si] 446 | 447 | xor si,si ;first word of tile data 448 | 449 | mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0 450 | 451 | mov di,[cs:screenstartcs] 452 | @@planeloopm: 453 | WORDOUT 454 | tileofs = 0 455 | lineoffset = 0 456 | REPT 16 457 | mov bx,[si+tileofs] ;background tile 458 | and bx,[ss:tileofs] ;mask 459 | or bx,[ss:si+tileofs+32] ;masked data 460 | mov [es:di+lineoffset],bx 461 | tileofs = tileofs + 2 462 | lineoffset = lineoffset + SCREENWIDTH 463 | ENDM 464 | add si,32 465 | shl ah,1 ;shift plane mask over for next plane 466 | cmp ah,10000b 467 | je @@done ;drawn all four planes 468 | jmp @@planeloopm 469 | 470 | @@done: 471 | mov ax,@DATA 472 | mov ss,ax 473 | sti 474 | mov ds,ax 475 | ret 476 | ENDP 477 | 478 | ENDIF 479 | 480 | 481 | ;============================================================================ 482 | ; 483 | ; reasonably common refresh routines 484 | ; 485 | ;============================================================================ 486 | 487 | 488 | ;================= 489 | ; 490 | ; RFL_UpdateTiles 491 | ; 492 | ; Scans through the update matrix pointed to by updateptr, looking for 1s. 493 | ; A 1 represents a tile that needs to be copied from the master screen to the 494 | ; current screen (a new row or an animated tiled). If more than one adjacent 495 | ; tile in a horizontal row needs to be copied, they will be copied as a group. 496 | ; 497 | ; Assumes write mode 1 498 | ; 499 | ;================= 500 | 501 | 502 | ; AX 0/1 for scasb, temp for segment register transfers 503 | ; BX width for block copies 504 | ; CX REP counter 505 | ; DX line width deltas 506 | ; SI source for copies 507 | ; DI scas dest / movsb dest 508 | ; BP pointer to UPDATETERMINATE 509 | ; 510 | ; DS 511 | ; ES 512 | ; SS 513 | 514 | PROC RFL_UpdateTiles 515 | PUBLIC RFL_UpdateTiles 516 | USES SI,DI,BP 517 | 518 | jmp SHORT @@realstart 519 | @@done: 520 | ; 521 | ; all tiles have been scanned 522 | ; 523 | ret 524 | 525 | @@realstart: 526 | mov di,[updateptr] 527 | mov bp,(TILESWIDE+1)*TILESHIGH+1 528 | add bp,di ; when di = bx, all tiles have been scanned 529 | push di 530 | mov cx,-1 ; definately scan the entire thing 531 | 532 | ; 533 | ; scan for a 1 in the update list, meaning a tile needs to be copied 534 | ; from the master screen to the current screen 535 | ; 536 | @@findtile: 537 | pop di ; place to continue scaning from 538 | mov ax,ss 539 | mov es,ax ; search in the data segment 540 | mov ds,ax 541 | mov al,1 542 | repne scasb 543 | cmp di,bp 544 | je @@done 545 | 546 | cmp [BYTE di],al 547 | jne @@singletile 548 | jmp @@tileblock 549 | 550 | ;============ 551 | ; 552 | ; copy a single tile 553 | ; 554 | ;============ 555 | EVEN 556 | @@singletile: 557 | inc di ; we know the next tile is nothing 558 | push di ; save off the spot being scanned 559 | sub di,[updateptr] 560 | shl di,1 561 | mov di,[blockstarts-4+di] ; start of tile location on screen 562 | mov si,di 563 | add di,[bufferofs] ; dest in current screen 564 | add si,[masterofs] ; source in master screen 565 | 566 | mov dx,SCREENWIDTH-TILEWIDTH 567 | mov ax,[screenseg] 568 | mov ds,ax 569 | mov es,ax 570 | 571 | ;-------------------------- 572 | 573 | IFE GRMODE-CGAGR 574 | 575 | REPT 15 576 | movsw 577 | movsw 578 | add si,dx 579 | add di,dx 580 | ENDM 581 | movsw 582 | movsw 583 | 584 | ENDIF 585 | 586 | ;-------------------------- 587 | 588 | IFE GRMODE-TGAGR 589 | 590 | REPT 15 591 | movsw 592 | movsw 593 | movsw 594 | movsw 595 | add si,dx 596 | add di,dx 597 | ENDM 598 | movsw 599 | movsw 600 | movsw 601 | movsw 602 | 603 | ENDIF 604 | 605 | ;-------------------------- 606 | 607 | IFE GRMODE-EGAGR 608 | 609 | REPT 15 610 | movsb 611 | movsb 612 | add si,dx 613 | add di,dx 614 | ENDM 615 | movsb 616 | movsb 617 | 618 | ENDIF 619 | 620 | ;-------------------------- 621 | 622 | jmp @@findtile 623 | 624 | ;============ 625 | ; 626 | ; more than one tile in a row needs to be updated, so do it as a group 627 | ; 628 | ;============ 629 | EVEN 630 | @@tileblock: 631 | mov dx,di ; hold starting position + 1 in dx 632 | inc di ; we know the next tile also gets updated 633 | repe scasb ; see how many more in a row 634 | push di ; save off the spot being scanned 635 | 636 | mov bx,di 637 | sub bx,dx ; number of tiles in a row 638 | shl bx,1 ; number of bytes / row 639 | IFE GRMODE-TGAGR 640 | shl bx,1 641 | ENDIF 642 | 643 | mov di,dx ; lookup position of start tile 644 | sub di,[updateptr] 645 | shl di,1 646 | mov di,[blockstarts-2+di] ; start of tile location 647 | mov si,di 648 | add di,[bufferofs] ; dest in current screen 649 | add si,[masterofs] ; source in master screen 650 | 651 | mov dx,SCREENWIDTH 652 | sub dx,bx ; offset to next line on screen 653 | IFE GRMODE-CGAGR 654 | sub dx,bx ; bx is words wide in CGA tiles 655 | ENDIF 656 | IFE GRMODE-TGAGR 657 | sub dx,bx 658 | ENDIF 659 | 660 | mov ax,[screenseg] 661 | mov ds,ax 662 | mov es,ax 663 | 664 | REPT 15 665 | mov cx,bx 666 | IFE GRMODE-CGAGR 667 | rep movsw 668 | ENDIF 669 | IFE GRMODE-TGAGR 670 | rep movsw 671 | ENDIF 672 | IFE GRMODE-EGAGR 673 | rep movsb 674 | ENDIF 675 | add si,dx 676 | add di,dx 677 | ENDM 678 | mov cx,bx 679 | IFE GRMODE-CGAGR 680 | rep movsw 681 | ENDIF 682 | IFE GRMODE-TGAGR 683 | rep movsw 684 | ENDIF 685 | IFE GRMODE-EGAGR 686 | rep movsb 687 | ENDIF 688 | 689 | dec cx ; was 0 from last rep movsb, now $ffff for scasb 690 | jmp @@findtile 691 | 692 | ENDP 693 | 694 | 695 | ;============================================================================ 696 | 697 | 698 | ;================= 699 | ; 700 | ; RFL_MaskForegroundTiles 701 | ; 702 | ; Scan through update looking for 3's. If the foreground tile there is a 703 | ; masked foreground tile, draw it to the screen 704 | ; 705 | ;================= 706 | 707 | PROC RFL_MaskForegroundTiles 708 | PUBLIC RFL_MaskForegroundTiles 709 | USES SI,DI,BP 710 | jmp SHORT @@realstart 711 | @@done: 712 | ; 713 | ; all tiles have been scanned 714 | ; 715 | ret 716 | 717 | @@realstart: 718 | mov di,[updateptr] 719 | mov bp,(TILESWIDE+1)*TILESHIGH+2 720 | add bp,di ; when di = bx, all tiles have been scanned 721 | push di 722 | mov cx,-1 ; definately scan the entire thing 723 | ; 724 | ; scan for a 3 in the update list 725 | ; 726 | @@findtile: 727 | mov ax,ss 728 | mov es,ax ; scan in the data segment 729 | mov al,3 730 | pop di ; place to continue scaning from 731 | repne scasb 732 | cmp di,bp 733 | je @@done 734 | 735 | ;============ 736 | ; 737 | ; found a tile, see if it needs to be masked on 738 | ; 739 | ;============ 740 | 741 | push di 742 | 743 | sub di,[updateptr] 744 | shl di,1 745 | mov si,[updatemapofs-2+di] ; offset from originmap 746 | add si,[originmap] 747 | 748 | mov es,[mapsegs+2] ; foreground map plane segment 749 | mov si,[es:si] ; foreground tile number 750 | 751 | or si,si 752 | jz @@findtile ; 0 = no foreground tile 753 | 754 | mov bx,si 755 | add bx,INTILE ;INTILE tile info table 756 | mov es,[tinf] 757 | test [BYTE PTR es:bx],80h ;high bit = masked tile 758 | jz @@findtile 759 | 760 | ;------------------- 761 | 762 | IFE GRMODE-TGAGR 763 | ;================= 764 | ; 765 | ; mask the tile TGA 766 | ; 767 | ;================= 768 | 769 | mov di,[blockstarts-2+di] 770 | add di,[bufferofs] 771 | mov es,[screenseg] 772 | shl si,1 773 | mov ds,[grsegs+STARTTILE16M*2+si] 774 | 775 | mov bx,128 ;data starts 128 bytes after mask 776 | 777 | xor si,si 778 | 779 | lineoffset = 0 780 | REPT 16 781 | mov ax,[es:di+lineoffset] ;background 782 | and ax,[si] ;mask 783 | or ax,[si+bx] ;masked data 784 | mov [es:di+lineoffset],ax ;background 785 | inc si 786 | inc si 787 | mov ax,[es:di+lineoffset+2] ;background 788 | and ax,[si] ;mask 789 | or ax,[si+bx] ;masked data 790 | mov [es:di+lineoffset+2],ax ;background 791 | inc si 792 | inc si 793 | mov ax,[es:di+lineoffset+4] ;background 794 | and ax,[si] ;mask 795 | or ax,[si+bx] ;masked data 796 | mov [es:di+lineoffset+4],ax ;background 797 | inc si 798 | inc si 799 | mov ax,[es:di+lineoffset+6] ;background 800 | and ax,[si] ;mask 801 | or ax,[si+bx] ;masked data 802 | mov [es:di+lineoffset+6],ax ;background 803 | inc si 804 | inc si 805 | lineoffset = lineoffset + SCREENWIDTH 806 | ENDM 807 | ENDIF 808 | 809 | ;------------------- 810 | 811 | IFE GRMODE-CGAGR 812 | ;================= 813 | ; 814 | ; mask the tile CGA 815 | ; 816 | ;================= 817 | 818 | mov di,[blockstarts-2+di] 819 | add di,[bufferofs] 820 | mov es,[screenseg] 821 | shl si,1 822 | mov ds,[grsegs+STARTTILE16M*2+si] 823 | 824 | mov bx,64 ;data starts 64 bytes after mask 825 | 826 | xor si,si 827 | 828 | lineoffset = 0 829 | REPT 16 830 | mov ax,[es:di+lineoffset] ;background 831 | and ax,[si] ;mask 832 | or ax,[si+bx] ;masked data 833 | mov [es:di+lineoffset],ax ;background 834 | inc si 835 | inc si 836 | mov ax,[es:di+lineoffset+2] ;background 837 | and ax,[si] ;mask 838 | or ax,[si+bx] ;masked data 839 | mov [es:di+lineoffset+2],ax ;background 840 | inc si 841 | inc si 842 | lineoffset = lineoffset + SCREENWIDTH 843 | ENDM 844 | ENDIF 845 | 846 | ;------------------- 847 | 848 | IFE GRMODE-EGAGR 849 | ;================= 850 | ; 851 | ; mask the tile 852 | ; 853 | ;================= 854 | 855 | mov [BYTE planemask],1 856 | mov [BYTE planenum],0 857 | 858 | mov di,[blockstarts-2+di] 859 | add di,[bufferofs] 860 | mov [cs:screenstartcs],di 861 | mov es,[screenseg] 862 | shl si,1 863 | mov ds,[grsegs+STARTTILE16M*2+si] 864 | 865 | mov bx,32 ;data starts 32 bytes after mask 866 | 867 | @@planeloopm: 868 | mov dx,SC_INDEX 869 | mov al,SC_MAPMASK 870 | mov ah,[ss:planemask] 871 | WORDOUT 872 | mov dx,GC_INDEX 873 | mov al,GC_READMAP 874 | mov ah,[ss:planenum] 875 | WORDOUT 876 | 877 | xor si,si 878 | mov di,[cs:screenstartcs] 879 | lineoffset = 0 880 | REPT 16 881 | mov cx,[es:di+lineoffset] ;background 882 | and cx,[si] ;mask 883 | or cx,[si+bx] ;masked data 884 | inc si 885 | inc si 886 | mov [es:di+lineoffset],cx 887 | lineoffset = lineoffset + SCREENWIDTH 888 | ENDM 889 | add bx,32 ;the mask is now further away 890 | inc [ss:planenum] 891 | shl [ss:planemask],1 ;shift plane mask over for next plane 892 | cmp [ss:planemask],10000b ;done all four planes? 893 | je @@drawn ;drawn all four planes 894 | jmp @@planeloopm 895 | 896 | @@drawn: 897 | ENDIF 898 | 899 | ;------------------- 900 | 901 | mov ax,ss 902 | mov ds,ax 903 | mov cx,-1 ;definately scan the entire thing 904 | 905 | jmp @@findtile 906 | 907 | ENDP 908 | 909 | 910 | END 911 | 912 | -------------------------------------------------------------------------------- /KEEN4-6/ID_SD.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // 28 | // ID Engine 29 | // ID_SD.h - Sound Manager Header 30 | // v1.0d1 31 | // By Jason Blochowiak 32 | // 33 | 34 | #ifndef __TYPES__ 35 | #include "ID_Types.h" 36 | #endif 37 | 38 | #ifndef __ID_SD__ 39 | #define __ID_SD__ 40 | 41 | #ifdef __DEBUG__ 42 | #define __DEBUG_SoundMgr__ 43 | #endif 44 | 45 | #define TickBase 70 // 70Hz per tick - used as a base for timer 0 46 | 47 | typedef enum { 48 | sdm_Off, 49 | sdm_PC,sdm_AdLib, 50 | } SDMode; 51 | typedef enum { 52 | smm_Off,smm_AdLib,smm_Tandy 53 | } SMMode; 54 | 55 | #if 1 56 | typedef struct 57 | { 58 | word length, 59 | values[1]; 60 | } MusicGroup; 61 | #else 62 | typedef struct 63 | { 64 | word flags, 65 | count, 66 | offsets[1]; 67 | } MusicGroup; 68 | #endif 69 | 70 | 71 | // Global variables 72 | extern boolean AdLibPresent, 73 | QuietFX; 74 | extern SDMode SoundMode; 75 | extern SMMode MusicMode; 76 | extern longword TimeCount; // Global time in ticks 77 | 78 | // Function prototypes 79 | extern void SD_Startup(void), 80 | SD_Shutdown(void), 81 | SD_Default(boolean gotit,SDMode sd,SMMode sm), 82 | SD_PlaySound(soundnames sound), 83 | SD_StopSound(void), 84 | SD_WaitSoundDone(void), 85 | SD_StartMusic(MusicGroup far *music), 86 | SD_MusicOn(void), 87 | SD_MusicOff(void), 88 | SD_SetSoundMode(SDMode mode), 89 | SD_SetMusicMode(SMMode mode); 90 | extern word SD_SoundPlaying(void); 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /KEEN4-6/ID_US.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // 28 | // ID Engine 29 | // ID_US.h - Header file for the User Manager 30 | // v1.0d1 31 | // By Jason Blochowiak 32 | // 33 | 34 | #ifndef __TYPES__ 35 | #include "ID_Types.h" 36 | #endif 37 | 38 | #ifndef __ID_US__ 39 | #define __ID_US__ 40 | 41 | #ifdef __DEBUG__ 42 | #define __DEBUG_UserMgr__ 43 | #endif 44 | 45 | //#define HELPTEXTLINKED 46 | 47 | #define MaxX 320 48 | #define MaxY 200 49 | 50 | #define MaxHighName 57 51 | #define MaxScores 8 52 | typedef struct 53 | { 54 | char name[MaxHighName + 1]; 55 | long score; 56 | word completed; 57 | } HighScore; 58 | 59 | #define MaxGameName 32 60 | #define MaxSaveGames 6 61 | typedef struct 62 | { 63 | char signature[4]; 64 | word *oldtest; 65 | boolean present; 66 | char name[MaxGameName + 1]; 67 | } SaveGame; 68 | 69 | #define MaxString 128 // Maximum input string size 70 | 71 | typedef struct 72 | { 73 | int x,y, 74 | w,h, 75 | px,py; 76 | } WindowRec; // Record used to save & restore screen windows 77 | 78 | typedef enum 79 | { 80 | gd_Continue, 81 | gd_Easy, 82 | gd_Normal, 83 | gd_Hard 84 | } GameDiff; 85 | 86 | // Hack import for TED launch support 87 | extern boolean tedlevel; 88 | extern word tedlevelnum; 89 | extern void TEDDeath(void); 90 | 91 | extern boolean ingame, // Set by game code if a game is in progress 92 | abortgame, // Set if a game load failed 93 | loadedgame, // Set if the current game was loaded 94 | #ifdef KEEN6 95 | checkpassed, 96 | #endif 97 | NoWait, 98 | HighScoresDirty; 99 | extern GameDiff restartgame; // Normally gd_Continue, else starts game 100 | extern word PrintX,PrintY; // Current printing location in the window 101 | extern word WindowX,WindowY,// Current location of window 102 | WindowW,WindowH;// Current size of window 103 | 104 | extern void (*USL_MeasureString)(char far *,word *,word *), 105 | (*USL_DrawString)(char far *); 106 | 107 | extern boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int); 108 | extern void (*USL_ResetGame)(void); 109 | extern SaveGame Games[MaxSaveGames]; 110 | extern HighScore Scores[]; 111 | 112 | extern void US_Startup(void), 113 | US_Setup(void), 114 | US_Shutdown(void), 115 | US_InitRndT(boolean randomize), 116 | US_SetLoadSaveHooks(boolean (*load)(int), 117 | boolean (*save)(int), 118 | void (*reset)(void)), 119 | US_TextScreen(void), 120 | US_UpdateTextScreen(void), 121 | US_FinishTextScreen(void), 122 | US_ControlPanel(void), 123 | US_CenterWindow(word,word), 124 | USL_SetPrintRoutines(void (*measure)(char far *,word *,word *), 125 | void (*print)(char far *)), 126 | US_PrintCentered(char *s), 127 | US_CPrint(char *s), 128 | US_Print(char *s), 129 | US_PrintUnsigned(longword n), 130 | US_PrintSigned(long n); 131 | extern boolean US_LineInput(int x,int y,char *buf,char *def,boolean escok, 132 | int maxchars,int maxwidth); 133 | extern int US_CheckParm(char *parm,char **strings), 134 | US_RndT(void); 135 | 136 | extern boolean US_ParmPresent(char *arg); 137 | 138 | char *USL_GiveSaveName(word game); 139 | #endif 140 | -------------------------------------------------------------------------------- /KEEN4-6/ID_US_A.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | IDEAL 19 | MODEL MEDIUM,C 20 | 21 | ; Assembly portion of the User Mgr. This is just John Carmack's table 22 | ; driven pseudo-random number generator, and we put it in the User Mgr 23 | ; because we couldn't figure out where it should go 24 | 25 | 26 | ;============================================================================ 27 | ; 28 | ; RANDOM ROUTINES 29 | ; 30 | ;============================================================================ 31 | 32 | FARDATA 33 | 34 | rndindex dw ? 35 | 36 | rndtable db 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66 37 | db 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36 38 | db 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188 39 | db 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224 40 | db 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242 41 | db 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0 42 | db 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235 43 | db 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113 44 | db 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75 45 | db 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196 46 | db 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113 47 | db 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241 48 | db 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224 49 | db 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95 50 | db 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226 51 | db 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36 52 | db 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106 53 | db 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136 54 | db 120, 163, 236, 249 55 | 56 | 57 | CODESEG 58 | 59 | LastRnd dw ? 60 | 61 | ;================================================= 62 | ; 63 | ; void US_InitRndT (boolean randomize) 64 | ; Init table based RND generator 65 | ; if randomize is false, the counter is set to 0 66 | ; 67 | ;================================================= 68 | 69 | PROC US_InitRndT randomize:word 70 | uses si,di 71 | public US_InitRndT 72 | 73 | mov ax,SEG rndtable 74 | mov es,ax 75 | mov ax,[randomize] 76 | or ax,ax 77 | jne @@timeit ;if randomize is true, really random 78 | 79 | mov dx,0 ;set to a definite value 80 | jmp @@setit 81 | 82 | @@timeit: 83 | mov ah,2ch 84 | int 21h ;GetSystemTime 85 | and dx,0ffh 86 | 87 | @@setit: 88 | mov [es:rndindex],dx 89 | ret 90 | 91 | ENDP 92 | 93 | ;================================================= 94 | ; 95 | ; int US_RndT (void) 96 | ; Return a random # between 0-255 97 | ; Exit : AX = value 98 | ; 99 | ;================================================= 100 | PROC US_RndT 101 | public US_RndT 102 | 103 | mov ax,SEG rndtable 104 | mov es,ax 105 | mov bx,[es:rndindex] 106 | inc bx 107 | and bx,0ffh 108 | mov [es:rndindex],bx 109 | mov al,[es:rndtable+BX] 110 | xor ah,ah 111 | 112 | ret 113 | 114 | ENDP 115 | 116 | END 117 | 118 | -------------------------------------------------------------------------------- /KEEN4-6/ID_VW.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // ID_VW.H 28 | 29 | #ifndef __TYPES__ 30 | #include "ID_TYPES.H" 31 | #endif 32 | 33 | #ifndef __ID_MM__ 34 | #include "ID_MM.H" 35 | #endif 36 | 37 | #ifndef __ID_GLOB__ 38 | #include "ID_GLOB.H" 39 | #endif 40 | 41 | #define __ID_VW__ 42 | 43 | //=========================================================================== 44 | 45 | #define G_P_SHIFT 4 // global >> ?? = pixels 46 | 47 | #define CHARHEIGHT 8 48 | 49 | #if GRMODE == EGAGR 50 | #define SCREENWIDTH 64 51 | #define VIRTUALHEIGHT 300 52 | #define CHARWIDTH 1 53 | #define TILEWIDTH 2 54 | #define BYTEPIXELS 8 55 | #define PLANES 5 56 | #endif 57 | 58 | #if GRMODE == TGAGR 59 | #define SCREENWIDTH 170 60 | #define VIRTUALHEIGHT 200 61 | #define CHARWIDTH 4 62 | #define TILEWIDTH 8 63 | #define BYTEPIXELS 2 64 | #define PLANES 2 65 | #endif 66 | 67 | #if GRMODE == CGAGR 68 | #define SCREENWIDTH 128 69 | #define VIRTUALHEIGHT 300 70 | #define CHARWIDTH 2 71 | #define TILEWIDTH 4 72 | #define BYTEPIXELS 4 73 | #define PLANES 2 74 | #endif 75 | 76 | 77 | 78 | #if GRMODE == CGAGR || GRMODE == TGAGR 79 | #define MAXSHIFTS 1 80 | #elif GRMODE == EGAGR 81 | #define MAXSHIFTS 4 82 | #endif 83 | 84 | #if GRMODE == CGAGR 85 | 86 | #define WHITE 3 // graphics mode independant colors 87 | #define BLACK 0 88 | #define FIRSTCOLOR 1 89 | #define SECONDCOLOR 2 90 | #define F_WHITE 0 // for XOR font drawing 91 | #define F_BLACK 3 92 | #define F_FIRSTCOLOR 2 93 | #define F_SECONDCOLOR 1 94 | 95 | #elif GRMODE == EGAGR || GRMODE == TGAGR 96 | 97 | #define WHITE 15 // graphics mode independant colors 98 | #define BLACK 0 99 | #define FIRSTCOLOR 1 100 | #define SECONDCOLOR 12 101 | #define F_WHITE 0 // for XOR font drawing 102 | #define F_BLACK 15 103 | #define F_FIRSTCOLOR 14 104 | #define F_SECONDCOLOR 3 105 | 106 | #endif 107 | 108 | #if GRMODE == EGAGR 109 | #define SCREENXMASK (~7) 110 | #define SCREENXDIV (8) 111 | #endif 112 | 113 | #if GRMODE == TGAGR 114 | #define SCREENXMASK (~7) 115 | #define SCREENXDIV (2) 116 | #endif 117 | 118 | #if GRMODE == CGAGR 119 | #define SCREENXMASK (~3) 120 | #define SCREENXDIV (4) 121 | #endif 122 | 123 | //=========================================================================== 124 | 125 | 126 | #define SC_INDEX 0x3C4 127 | #define SC_RESET 0 128 | #define SC_CLOCK 1 129 | #define SC_MAPMASK 2 130 | #define SC_CHARMAP 3 131 | #define SC_MEMMODE 4 132 | 133 | #define CRTC_INDEX 0x3D4 134 | #define CRTC_H_TOTAL 0 135 | #define CRTC_H_DISPEND 1 136 | #define CRTC_H_BLANK 2 137 | #define CRTC_H_ENDBLANK 3 138 | #define CRTC_H_RETRACE 4 139 | #define CRTC_H_ENDRETRACE 5 140 | #define CRTC_V_TOTAL 6 141 | #define CRTC_OVERFLOW 7 142 | #define CRTC_ROWSCAN 8 143 | #define CRTC_MAXSCANLINE 9 144 | #define CRTC_CURSORSTART 10 145 | #define CRTC_CURSOREND 11 146 | #define CRTC_STARTHIGH 12 147 | #define CRTC_STARTLOW 13 148 | #define CRTC_CURSORHIGH 14 149 | #define CRTC_CURSORLOW 15 150 | #define CRTC_V_RETRACE 16 151 | #define CRTC_V_ENDRETRACE 17 152 | #define CRTC_V_DISPEND 18 153 | #define CRTC_OFFSET 19 154 | #define CRTC_UNDERLINE 20 155 | #define CRTC_V_BLANK 21 156 | #define CRTC_V_ENDBLANK 22 157 | #define CRTC_MODE 23 158 | #define CRTC_LINECOMPARE 24 159 | 160 | 161 | #define GC_INDEX 0x3CE 162 | #define GC_SETRESET 0 163 | #define GC_ENABLESETRESET 1 164 | #define GC_COLORCOMPARE 2 165 | #define GC_DATAROTATE 3 166 | #define GC_READMAP 4 167 | #define GC_MODE 5 168 | #define GC_MISCELLANEOUS 6 169 | #define GC_COLORDONTCARE 7 170 | #define GC_BITMASK 8 171 | 172 | #define ATR_INDEX 0x3c0 173 | #define ATR_MODE 16 174 | #define ATR_OVERSCAN 17 175 | #define ATR_COLORPLANEENABLE 18 176 | #define ATR_PELPAN 19 177 | #define ATR_COLORSELECT 20 178 | 179 | #define STATUS_REGISTER_1 0x3da 180 | 181 | //=========================================================================== 182 | 183 | typedef struct 184 | { 185 | int width, 186 | height, 187 | orgx,orgy, 188 | xl,yl,xh,yh, 189 | shifts; 190 | } spritetabletype; 191 | 192 | typedef struct 193 | { 194 | unsigned sourceoffset[MAXSHIFTS]; 195 | unsigned planesize[MAXSHIFTS]; 196 | unsigned width[MAXSHIFTS]; 197 | byte data[]; 198 | } spritetype; // the memptr for each sprite points to this 199 | 200 | typedef struct 201 | { 202 | int width,height; 203 | } pictabletype; 204 | 205 | 206 | typedef struct 207 | { 208 | int height; 209 | int location[256]; 210 | char width[256]; 211 | } fontstruct; 212 | 213 | 214 | //=========================================================================== 215 | 216 | extern unsigned bufferofs; // hidden port to draw to before displaying 217 | extern unsigned displayofs; // origin of port on visable screen 218 | extern unsigned pansx,pansy; // panning adjustments inside port in screen 219 | extern unsigned panadjust; // panx adjusted by screen resolution 220 | 221 | extern unsigned screenseg; // 0xa000 or the 64k floating screen segment 222 | 223 | extern unsigned linewidth; 224 | extern unsigned ylookup[VIRTUALHEIGHT]; 225 | 226 | extern boolean screenfaded; 227 | extern char colors[4][17]; // palettes for fades 228 | 229 | extern pictabletype _seg *pictable; 230 | extern pictabletype _seg *picmtable; 231 | extern spritetabletype _seg *spritetable; 232 | 233 | extern unsigned fontnumber; // 0 based font number for drawing 234 | extern int px,py; 235 | extern byte pdrawmode,fontcolor; 236 | 237 | extern int bordercolor; 238 | extern boolean nopan; 239 | 240 | // 241 | // asm globals 242 | // 243 | 244 | extern unsigned *shifttabletable[8]; 245 | extern unsigned bufferwidth,bufferheight; // used by font drawing stuff 246 | 247 | #if GRMODE == TGAGR 248 | extern unsigned char colorbyte[16]; 249 | #endif 250 | 251 | 252 | //=========================================================================== 253 | 254 | 255 | void VW_Startup (void); 256 | void VW_Shutdown (void); 257 | 258 | // 259 | // EGA hardware routines 260 | // 261 | 262 | #define EGAWRITEMODE(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_MODE+256*x;out dx,ax;sti;} 263 | #define EGABITMASK(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_BITMASK+256*x;out dx,ax;sti;} 264 | #define EGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov ax,SC_MAPMASK+x*256;out dx,ax;sti;} 265 | #define EGAREADMAP(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_READMAP+x*256;out dx,ax;sti;} 266 | 267 | void VW_SetLineWidth(int width); 268 | void VW_SetScreen (unsigned CRTC, unsigned pelpan); 269 | 270 | void VW_SetScreenMode (int grmode); 271 | void VW_ClearVideo (void); 272 | void VW_ClearVideoBottom (void); 273 | void VW_WaitVBL (int number); 274 | 275 | void VW_ColorBorder (int color); 276 | void VW_SetDefaultColors(void); 277 | void VW_FadeOut(void); 278 | void VW_FadeIn(void); 279 | 280 | // 281 | // block primitives 282 | // 283 | 284 | void VW_MaskBlock(memptr segm,unsigned ofs,unsigned dest, 285 | unsigned wide,unsigned height,unsigned planesize); 286 | void VW_MaskBlockClipped(memptr segm,unsigned ofs,unsigned dest, 287 | unsigned wide,unsigned height,unsigned planesize,unsigned spritewidthdelta); 288 | void VW_ScreenToScreen(unsigned source,unsigned dest,unsigned width,unsigned height); 289 | 290 | 291 | // 292 | // block addressable routines 293 | // 294 | 295 | void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum); 296 | #if GRMODE == EGAGR 297 | void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum); 298 | #endif 299 | 300 | // 301 | // pixel addressable routines 302 | // 303 | void VW_MeasurePropString (char far *string, word *width, word *height); 304 | 305 | #if GRMODE == EGAGR 306 | void VW_Plot(unsigned x, unsigned y, unsigned color); 307 | #endif 308 | void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color); 309 | void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height, 310 | unsigned color); 311 | 312 | //=========================================================================== 313 | 314 | // 315 | // Double buffer management routines 316 | // 317 | 318 | void VW_InitDoubleBuffer (void); 319 | void VW_FixRefreshBuffer (void); 320 | void VW_UpdateScreen (void); 321 | #if GRMODE == CGAGR 322 | void VW_CGAFullUpdate (void); 323 | #elif GRMODE == TGAGR 324 | void VW_TGAFullUpdate (void); 325 | void VW_TGABottomUpdate (void); 326 | #endif 327 | 328 | // 329 | // mode independant routines 330 | // coordinates in pixels, rounded to best screen res 331 | // regions marked in double buffer 332 | // 333 | 334 | void VWB_DrawTile8 (int x, int y, int tile); 335 | void VWB_DrawTile8M (int x, int y, int tile); 336 | void VWB_DrawPic (int x, int y, int chunknum); 337 | void VWB_DrawMPic(int x, int y, int chunknum); 338 | void VWB_Bar (int x, int y, int width, int height, int color); 339 | 340 | void VWB_DrawPropString (char far *string); 341 | void VWB_DrawSprite (int x, int y, int chunknum); 342 | void VWB_Hlin (int x1, int x2, int y, int color); 343 | void VWB_Vlin (int y1, int y2, int x, int color); 344 | 345 | //=========================================================================== 346 | -------------------------------------------------------------------------------- /KEEN4-6/ID_VW_A.ASM: -------------------------------------------------------------------------------- 1 | ; Commander Keen 4 Tandy Version Source Code 2 | ; Copyright (C) 2021-2022 Frenkel Smeijers 3 | ; 4 | ; This file is primarily based on: 5 | ; Catacomb 3-D Source Code 6 | ; Copyright (C) 1993-2014 Flat Rock Software 7 | ; 8 | ; This program is free software; you can redistribute it and/or modify 9 | ; it under the terms of the GNU General Public License as published by 10 | ; the Free Software Foundation; either version 2 of the License, or 11 | ; (at your option) any later version. 12 | ; 13 | ; This program is distributed in the hope that it will be useful, 14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ; GNU General Public License for more details. 17 | ; 18 | ; You should have received a copy of the GNU General Public License along 19 | ; with this program; if not, write to the Free Software Foundation, Inc., 20 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | 22 | ; ID_VW_A.ASM 23 | 24 | IDEAL 25 | MODEL MEDIUM,C 26 | 27 | INCLUDE "ID_ASM.EQU" 28 | 29 | WAITFORVBL = 1 ; setting to 0 causes setscreen and waitvbl 30 | ; to skip waiting for VBL (for timing things) 31 | 32 | ;============================================================================ 33 | 34 | DATASEG 35 | 36 | EXTRN screenseg :WORD 37 | EXTRN drawofs :WORD 38 | EXTRN bufferofs :WORD 39 | EXTRN displayofs :WORD 40 | EXTRN drawofs :WORD 41 | EXTRN panadjust :WORD 42 | EXTRN ylookup :WORD 43 | EXTRN linewidth :WORD 44 | EXTRN grsegs :WORD 45 | EXTRN updateptr :WORD 46 | EXTRN blockstarts :WORD ;offsets from drawofs for each update block 47 | EXTRN fontspace :WORD 48 | EXTRN fontnumber :WORD 49 | 50 | 51 | planemask db ? 52 | planenum db ? 53 | screendest dw ? 54 | linedelta dw ? 55 | 56 | LABEL shiftdata0 WORD 57 | dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 58 | dw 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 59 | dw 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41 60 | dw 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 61 | dw 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69 62 | dw 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 63 | dw 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 64 | dw 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111 65 | dw 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125 66 | dw 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139 67 | dw 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153 68 | dw 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167 69 | dw 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181 70 | dw 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195 71 | dw 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209 72 | dw 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 73 | dw 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237 74 | dw 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251 75 | dw 252, 253, 254, 255 76 | 77 | LABEL shiftdata1 WORD 78 | dw 0,32768, 1,32769, 2,32770, 3,32771, 4,32772, 5,32773, 6,32774 79 | dw 7,32775, 8,32776, 9,32777, 10,32778, 11,32779, 12,32780, 13,32781 80 | dw 14,32782, 15,32783, 16,32784, 17,32785, 18,32786, 19,32787, 20,32788 81 | dw 21,32789, 22,32790, 23,32791, 24,32792, 25,32793, 26,32794, 27,32795 82 | dw 28,32796, 29,32797, 30,32798, 31,32799, 32,32800, 33,32801, 34,32802 83 | dw 35,32803, 36,32804, 37,32805, 38,32806, 39,32807, 40,32808, 41,32809 84 | dw 42,32810, 43,32811, 44,32812, 45,32813, 46,32814, 47,32815, 48,32816 85 | dw 49,32817, 50,32818, 51,32819, 52,32820, 53,32821, 54,32822, 55,32823 86 | dw 56,32824, 57,32825, 58,32826, 59,32827, 60,32828, 61,32829, 62,32830 87 | dw 63,32831, 64,32832, 65,32833, 66,32834, 67,32835, 68,32836, 69,32837 88 | dw 70,32838, 71,32839, 72,32840, 73,32841, 74,32842, 75,32843, 76,32844 89 | dw 77,32845, 78,32846, 79,32847, 80,32848, 81,32849, 82,32850, 83,32851 90 | dw 84,32852, 85,32853, 86,32854, 87,32855, 88,32856, 89,32857, 90,32858 91 | dw 91,32859, 92,32860, 93,32861, 94,32862, 95,32863, 96,32864, 97,32865 92 | dw 98,32866, 99,32867, 100,32868, 101,32869, 102,32870, 103,32871, 104,32872 93 | dw 105,32873, 106,32874, 107,32875, 108,32876, 109,32877, 110,32878, 111,32879 94 | dw 112,32880, 113,32881, 114,32882, 115,32883, 116,32884, 117,32885, 118,32886 95 | dw 119,32887, 120,32888, 121,32889, 122,32890, 123,32891, 124,32892, 125,32893 96 | dw 126,32894, 127,32895 97 | 98 | LABEL shiftdata2 WORD 99 | dw 0,16384,32768,49152, 1,16385,32769,49153, 2,16386,32770,49154, 3,16387 100 | dw 32771,49155, 4,16388,32772,49156, 5,16389,32773,49157, 6,16390,32774,49158 101 | dw 7,16391,32775,49159, 8,16392,32776,49160, 9,16393,32777,49161, 10,16394 102 | dw 32778,49162, 11,16395,32779,49163, 12,16396,32780,49164, 13,16397,32781,49165 103 | dw 14,16398,32782,49166, 15,16399,32783,49167, 16,16400,32784,49168, 17,16401 104 | dw 32785,49169, 18,16402,32786,49170, 19,16403,32787,49171, 20,16404,32788,49172 105 | dw 21,16405,32789,49173, 22,16406,32790,49174, 23,16407,32791,49175, 24,16408 106 | dw 32792,49176, 25,16409,32793,49177, 26,16410,32794,49178, 27,16411,32795,49179 107 | dw 28,16412,32796,49180, 29,16413,32797,49181, 30,16414,32798,49182, 31,16415 108 | dw 32799,49183, 32,16416,32800,49184, 33,16417,32801,49185, 34,16418,32802,49186 109 | dw 35,16419,32803,49187, 36,16420,32804,49188, 37,16421,32805,49189, 38,16422 110 | dw 32806,49190, 39,16423,32807,49191, 40,16424,32808,49192, 41,16425,32809,49193 111 | dw 42,16426,32810,49194, 43,16427,32811,49195, 44,16428,32812,49196, 45,16429 112 | dw 32813,49197, 46,16430,32814,49198, 47,16431,32815,49199, 48,16432,32816,49200 113 | dw 49,16433,32817,49201, 50,16434,32818,49202, 51,16435,32819,49203, 52,16436 114 | dw 32820,49204, 53,16437,32821,49205, 54,16438,32822,49206, 55,16439,32823,49207 115 | dw 56,16440,32824,49208, 57,16441,32825,49209, 58,16442,32826,49210, 59,16443 116 | dw 32827,49211, 60,16444,32828,49212, 61,16445,32829,49213, 62,16446,32830,49214 117 | dw 63,16447,32831,49215 118 | 119 | LABEL shiftdata3 WORD 120 | dw 0, 8192,16384,24576,32768,40960,49152,57344, 1, 8193,16385,24577,32769,40961 121 | dw 49153,57345, 2, 8194,16386,24578,32770,40962,49154,57346, 3, 8195,16387,24579 122 | dw 32771,40963,49155,57347, 4, 8196,16388,24580,32772,40964,49156,57348, 5, 8197 123 | dw 16389,24581,32773,40965,49157,57349, 6, 8198,16390,24582,32774,40966,49158,57350 124 | dw 7, 8199,16391,24583,32775,40967,49159,57351, 8, 8200,16392,24584,32776,40968 125 | dw 49160,57352, 9, 8201,16393,24585,32777,40969,49161,57353, 10, 8202,16394,24586 126 | dw 32778,40970,49162,57354, 11, 8203,16395,24587,32779,40971,49163,57355, 12, 8204 127 | dw 16396,24588,32780,40972,49164,57356, 13, 8205,16397,24589,32781,40973,49165,57357 128 | dw 14, 8206,16398,24590,32782,40974,49166,57358, 15, 8207,16399,24591,32783,40975 129 | dw 49167,57359, 16, 8208,16400,24592,32784,40976,49168,57360, 17, 8209,16401,24593 130 | dw 32785,40977,49169,57361, 18, 8210,16402,24594,32786,40978,49170,57362, 19, 8211 131 | dw 16403,24595,32787,40979,49171,57363, 20, 8212,16404,24596,32788,40980,49172,57364 132 | dw 21, 8213,16405,24597,32789,40981,49173,57365, 22, 8214,16406,24598,32790,40982 133 | dw 49174,57366, 23, 8215,16407,24599,32791,40983,49175,57367, 24, 8216,16408,24600 134 | dw 32792,40984,49176,57368, 25, 8217,16409,24601,32793,40985,49177,57369, 26, 8218 135 | dw 16410,24602,32794,40986,49178,57370, 27, 8219,16411,24603,32795,40987,49179,57371 136 | dw 28, 8220,16412,24604,32796,40988,49180,57372, 29, 8221,16413,24605,32797,40989 137 | dw 49181,57373, 30, 8222,16414,24606,32798,40990,49182,57374, 31, 8223,16415,24607 138 | dw 32799,40991,49183,57375 139 | 140 | LABEL shiftdata4 WORD 141 | dw 0, 4096, 8192,12288,16384,20480,24576,28672,32768,36864,40960,45056,49152,53248 142 | dw 57344,61440, 1, 4097, 8193,12289,16385,20481,24577,28673,32769,36865,40961,45057 143 | dw 49153,53249,57345,61441, 2, 4098, 8194,12290,16386,20482,24578,28674,32770,36866 144 | dw 40962,45058,49154,53250,57346,61442, 3, 4099, 8195,12291,16387,20483,24579,28675 145 | dw 32771,36867,40963,45059,49155,53251,57347,61443, 4, 4100, 8196,12292,16388,20484 146 | dw 24580,28676,32772,36868,40964,45060,49156,53252,57348,61444, 5, 4101, 8197,12293 147 | dw 16389,20485,24581,28677,32773,36869,40965,45061,49157,53253,57349,61445, 6, 4102 148 | dw 8198,12294,16390,20486,24582,28678,32774,36870,40966,45062,49158,53254,57350,61446 149 | dw 7, 4103, 8199,12295,16391,20487,24583,28679,32775,36871,40967,45063,49159,53255 150 | dw 57351,61447, 8, 4104, 8200,12296,16392,20488,24584,28680,32776,36872,40968,45064 151 | dw 49160,53256,57352,61448, 9, 4105, 8201,12297,16393,20489,24585,28681,32777,36873 152 | dw 40969,45065,49161,53257,57353,61449, 10, 4106, 8202,12298,16394,20490,24586,28682 153 | dw 32778,36874,40970,45066,49162,53258,57354,61450, 11, 4107, 8203,12299,16395,20491 154 | dw 24587,28683,32779,36875,40971,45067,49163,53259,57355,61451, 12, 4108, 8204,12300 155 | dw 16396,20492,24588,28684,32780,36876,40972,45068,49164,53260,57356,61452, 13, 4109 156 | dw 8205,12301,16397,20493,24589,28685,32781,36877,40973,45069,49165,53261,57357,61453 157 | dw 14, 4110, 8206,12302,16398,20494,24590,28686,32782,36878,40974,45070,49166,53262 158 | dw 57358,61454, 15, 4111, 8207,12303,16399,20495,24591,28687,32783,36879,40975,45071 159 | dw 49167,53263,57359,61455 160 | 161 | LABEL shiftdata5 WORD 162 | dw 0, 2048, 4096, 6144, 8192,10240,12288,14336,16384,18432,20480,22528,24576,26624 163 | dw 28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152,51200,53248,55296 164 | dw 57344,59392,61440,63488, 1, 2049, 4097, 6145, 8193,10241,12289,14337,16385,18433 165 | dw 20481,22529,24577,26625,28673,30721,32769,34817,36865,38913,40961,43009,45057,47105 166 | dw 49153,51201,53249,55297,57345,59393,61441,63489, 2, 2050, 4098, 6146, 8194,10242 167 | dw 12290,14338,16386,18434,20482,22530,24578,26626,28674,30722,32770,34818,36866,38914 168 | dw 40962,43010,45058,47106,49154,51202,53250,55298,57346,59394,61442,63490, 3, 2051 169 | dw 4099, 6147, 8195,10243,12291,14339,16387,18435,20483,22531,24579,26627,28675,30723 170 | dw 32771,34819,36867,38915,40963,43011,45059,47107,49155,51203,53251,55299,57347,59395 171 | dw 61443,63491, 4, 2052, 4100, 6148, 8196,10244,12292,14340,16388,18436,20484,22532 172 | dw 24580,26628,28676,30724,32772,34820,36868,38916,40964,43012,45060,47108,49156,51204 173 | dw 53252,55300,57348,59396,61444,63492, 5, 2053, 4101, 6149, 8197,10245,12293,14341 174 | dw 16389,18437,20485,22533,24581,26629,28677,30725,32773,34821,36869,38917,40965,43013 175 | dw 45061,47109,49157,51205,53253,55301,57349,59397,61445,63493, 6, 2054, 4102, 6150 176 | dw 8198,10246,12294,14342,16390,18438,20486,22534,24582,26630,28678,30726,32774,34822 177 | dw 36870,38918,40966,43014,45062,47110,49158,51206,53254,55302,57350,59398,61446,63494 178 | dw 7, 2055, 4103, 6151, 8199,10247,12295,14343,16391,18439,20487,22535,24583,26631 179 | dw 28679,30727,32775,34823,36871,38919,40967,43015,45063,47111,49159,51207,53255,55303 180 | dw 57351,59399,61447,63495 181 | 182 | LABEL shiftdata6 WORD 183 | dw 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,10240,11264,12288,13312 184 | dw 14336,15360,16384,17408,18432,19456,20480,21504,22528,23552,24576,25600,26624,27648 185 | dw 28672,29696,30720,31744,32768,33792,34816,35840,36864,37888,38912,39936,40960,41984 186 | dw 43008,44032,45056,46080,47104,48128,49152,50176,51200,52224,53248,54272,55296,56320 187 | dw 57344,58368,59392,60416,61440,62464,63488,64512, 1, 1025, 2049, 3073, 4097, 5121 188 | dw 6145, 7169, 8193, 9217,10241,11265,12289,13313,14337,15361,16385,17409,18433,19457 189 | dw 20481,21505,22529,23553,24577,25601,26625,27649,28673,29697,30721,31745,32769,33793 190 | dw 34817,35841,36865,37889,38913,39937,40961,41985,43009,44033,45057,46081,47105,48129 191 | dw 49153,50177,51201,52225,53249,54273,55297,56321,57345,58369,59393,60417,61441,62465 192 | dw 63489,64513, 2, 1026, 2050, 3074, 4098, 5122, 6146, 7170, 8194, 9218,10242,11266 193 | dw 12290,13314,14338,15362,16386,17410,18434,19458,20482,21506,22530,23554,24578,25602 194 | dw 26626,27650,28674,29698,30722,31746,32770,33794,34818,35842,36866,37890,38914,39938 195 | dw 40962,41986,43010,44034,45058,46082,47106,48130,49154,50178,51202,52226,53250,54274 196 | dw 55298,56322,57346,58370,59394,60418,61442,62466,63490,64514, 3, 1027, 2051, 3075 197 | dw 4099, 5123, 6147, 7171, 8195, 9219,10243,11267,12291,13315,14339,15363,16387,17411 198 | dw 18435,19459,20483,21507,22531,23555,24579,25603,26627,27651,28675,29699,30723,31747 199 | dw 32771,33795,34819,35843,36867,37891,38915,39939,40963,41987,43011,44035,45059,46083 200 | dw 47107,48131,49155,50179,51203,52227,53251,54275,55299,56323,57347,58371,59395,60419 201 | dw 61443,62467,63491,64515 202 | 203 | LABEL shiftdata7 WORD 204 | dw 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656 205 | dw 7168, 7680, 8192, 8704, 9216, 9728,10240,10752,11264,11776,12288,12800,13312,13824 206 | dw 14336,14848,15360,15872,16384,16896,17408,17920,18432,18944,19456,19968,20480,20992 207 | dw 21504,22016,22528,23040,23552,24064,24576,25088,25600,26112,26624,27136,27648,28160 208 | dw 28672,29184,29696,30208,30720,31232,31744,32256,32768,33280,33792,34304,34816,35328 209 | dw 35840,36352,36864,37376,37888,38400,38912,39424,39936,40448,40960,41472,41984,42496 210 | dw 43008,43520,44032,44544,45056,45568,46080,46592,47104,47616,48128,48640,49152,49664 211 | dw 50176,50688,51200,51712,52224,52736,53248,53760,54272,54784,55296,55808,56320,56832 212 | dw 57344,57856,58368,58880,59392,59904,60416,60928,61440,61952,62464,62976,63488,64000 213 | dw 64512,65024, 1, 513, 1025, 1537, 2049, 2561, 3073, 3585, 4097, 4609, 5121, 5633 214 | dw 6145, 6657, 7169, 7681, 8193, 8705, 9217, 9729,10241,10753,11265,11777,12289,12801 215 | dw 13313,13825,14337,14849,15361,15873,16385,16897,17409,17921,18433,18945,19457,19969 216 | dw 20481,20993,21505,22017,22529,23041,23553,24065,24577,25089,25601,26113,26625,27137 217 | dw 27649,28161,28673,29185,29697,30209,30721,31233,31745,32257,32769,33281,33793,34305 218 | dw 34817,35329,35841,36353,36865,37377,37889,38401,38913,39425,39937,40449,40961,41473 219 | dw 41985,42497,43009,43521,44033,44545,45057,45569,46081,46593,47105,47617,48129,48641 220 | dw 49153,49665,50177,50689,51201,51713,52225,52737,53249,53761,54273,54785,55297,55809 221 | dw 56321,56833,57345,57857,58369,58881,59393,59905,60417,60929,61441,61953,62465,62977 222 | dw 63489,64001,64513,65025 223 | 224 | shifttabletable dw shiftdata0,shiftdata1,shiftdata2,shiftdata3 225 | dw shiftdata4,shiftdata5,shiftdata6,shiftdata7 226 | 227 | PUBLIC shifttabletable 228 | 229 | 230 | ;============================================================================ 231 | 232 | CODESEG 233 | 234 | IFE GRMODE-CGAGR 235 | INCLUDE "ID_VW_AC.ASM" 236 | ENDIF 237 | 238 | IFE GRMODE-EGAGR 239 | INCLUDE "ID_VW_AE.ASM" 240 | ENDIF 241 | 242 | IFE GRMODE-TGAGR 243 | INCLUDE "ID_VW_AT.ASM" 244 | ENDIF 245 | 246 | ;============================================================================ 247 | ; 248 | ; MISC VIDEO ROUTINES 249 | ; 250 | ;============================================================================ 251 | 252 | ;======== 253 | ; 254 | ; VW_WaitVBL (int number) 255 | ; 256 | ;======== 257 | 258 | PROC VW_WaitVBL number:WORD 259 | PUBLIC VW_WaitVBL 260 | 261 | if WAITFORVBL ; skip wait if profiling 262 | 263 | mov dx,STATUS_REGISTER_1 264 | 265 | mov cx,[number] 266 | 267 | waitvbl1: 268 | in al,dx 269 | test al,00001000b ;look for vbl 270 | jnz waitvbl1 271 | 272 | waitvbl2: 273 | in al,dx 274 | test al,00001000b ;look for vbl 275 | jz waitvbl2 276 | 277 | loop waitvbl1 278 | 279 | endif 280 | 281 | ret 282 | 283 | ENDP 284 | 285 | 286 | END 287 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4/AUDIOCK4.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021 Frenkel Smeijers 3 | * 4 | * Reconstructed Commander Keen 4-6 Source Code 5 | * Copyright (C) 2021 K1n9_Duk3 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, write to the Free Software Foundation, Inc., 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | */ 21 | 22 | #ifndef __AUDIO_H__ 23 | #define __AUDIO_H__ 24 | 25 | //#include "VERSION.H" 26 | 27 | ///////////////////////////////////////////////// 28 | // 29 | // MUSE Header for .CK4 30 | // 31 | ///////////////////////////////////////////////// 32 | 33 | #define NUMSOUNDS LASTSOUND 34 | #define NUMMUSICSONGS LASTMUSIC 35 | #define NUMSNDCHUNKS ((3*LASTSOUND)+(2*NUMMUSICSONGS)) 36 | 37 | // 38 | // Sound names & indexes 39 | // 40 | typedef enum { 41 | SND_WORLDWALK1, 42 | SND_WORLDWALK2, 43 | SND_JUMP, 44 | SND_LAND, 45 | SND_KEENFIRE, 46 | SND_WORMOUTHATTACK, 47 | SND_6, 48 | SND_POGOBOUNCE, 49 | SND_GETPOINTS, 50 | SND_GETAMMO, 51 | SND_GETWATER, 52 | SND_11, 53 | SND_ENTERLEVEL, 54 | SND_LEVELDONE, 55 | SND_NOWAY, 56 | SND_HELMETHIT, 57 | SND_BOUNCE2, 58 | SND_EXTRAKEEN, 59 | SND_OPENDOOR, 60 | SND_GETKEY, 61 | SND_PLUMMET, 62 | SND_USESWITCH, 63 | SND_SQUISH, 64 | SND_KEENDEAD, 65 | SND_24, 66 | SND_SHOTEXPLODE, 67 | SND_SWIM1, 68 | SND_SWIM2, 69 | SND_BOUNCE1, 70 | SND_EATBONUS, 71 | SND_TREASUREEATERVANISH, 72 | SND_LINDSEY, 73 | SND_LICKATTACK, 74 | SND_BERKELOIDATTACK, 75 | SND_SHOWSTATUS, 76 | SND_HIDESTATUS, 77 | SND_BLUB, 78 | SND_MINEEXPLODE, 79 | SND_SPRITEFIRE, 80 | SND_THUNDER, 81 | SND_FIREBALLLAND, 82 | SND_SHOOTDART, 83 | SND_BURP, 84 | SND_FLAGSPIN, 85 | SND_FLAGLAND, 86 | SND_MAKEFOOT, 87 | SND_SLUGPOO, 88 | KEENPADDLESND, 89 | BALLBOUNCESND, 90 | COMPPADDLESND, 91 | COMPSCOREDSND, 92 | KEENSCOREDSND, 93 | LASTSOUND 94 | } soundnames; 95 | 96 | #if LASTSOUND != 52 97 | #error bad sound enum! 98 | #endif 99 | 100 | #define NOWAYSND SND_NOWAY 101 | 102 | // 103 | // Base offsets 104 | // 105 | #define STARTPCSOUNDS 0 106 | #define STARTADLIBSOUNDS (STARTPCSOUNDS+NUMSOUNDS) 107 | #define STARTDIGISOUNDS (STARTADLIBSOUNDS+NUMSOUNDS) 108 | #define STARTADLIBMUSIC (STARTDIGISOUNDS+NUMSOUNDS) 109 | #define STARTTANDYMUSIC (STARTADLIBMUSIC+NUMMUSICSONGS) 110 | 111 | // 112 | // Music names & indexes 113 | // 114 | typedef enum { 115 | SHADOWS_MUS, 116 | VEGGIES_MUS, 117 | TOOHOT_MUS, 118 | OASIS_MUS, 119 | KICKPANT_MUS, 120 | WONDER_MUS, 121 | LASTMUSIC 122 | } musicnames; 123 | 124 | ///////////////////////////////////////////////// 125 | // 126 | // Thanks for playing with MUSE! 127 | // 128 | ///////////////////////////////////////////////// 129 | 130 | #endif -------------------------------------------------------------------------------- /KEEN4-6/KEEN4/GFXE_CK4.EQU: -------------------------------------------------------------------------------- 1 | ;===================================== 2 | ; 3 | ; Graphics .EQU file for .CK4 4 | ; not IGRAB-ed :) 5 | ; 6 | ;===================================== 7 | 8 | ;INCLUDE "VERSION.EQU" 9 | 10 | ; 11 | ; Amount of each data item 12 | ; 13 | NUMFONT = 3 14 | NUMFONTM = 0 15 | NUMPICM = 3 16 | NUMTILE8 = 108 17 | NUMTILE8M = 36 18 | NUMTILE32 = 0 19 | NUMTILE32M = 0 20 | 21 | ; 22 | ; Amount of each item in episode 4 23 | ; 24 | NUMPICS = 115 25 | NUMSPRITES = 397 26 | NUMTILE16 = 1296 27 | NUMTILE16M = 2916 28 | NUMEXTERN = 16 29 | 30 | 31 | ; 32 | ; File offsets for data items 33 | ; 34 | STRUCTPIC = 0 35 | STRUCTPICM = 1 36 | STRUCTSPRITE = 2 37 | 38 | STARTFONT = 3 39 | STARTFONTM = (STARTFONT+NUMFONT) 40 | STARTPICS = (STARTFONTM+NUMFONTM) 41 | STARTPICM = (STARTPICS+NUMPICS) 42 | STARTSPRITES = (STARTPICM+NUMPICM) 43 | STARTTILE8 = (STARTSPRITES+NUMSPRITES) 44 | STARTTILE8M = (STARTTILE8+1) 45 | STARTTILE16 = (STARTTILE8M+1) 46 | STARTTILE16M = (STARTTILE16+NUMTILE16) 47 | STARTTILE32 = (STARTTILE16M+NUMTILE16M) 48 | STARTTILE32M = (STARTTILE32+NUMTILE32) 49 | STARTEXTERN = (STARTTILE32M+NUMTILE32M) 50 | 51 | NUMCHUNKS = (STARTEXTERN+NUMEXTERN) 52 | 53 | ; 54 | ; Thank you for using IGRAB! 55 | ; 56 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4/ID_ASM.EQU: -------------------------------------------------------------------------------- 1 | ; 2 | ; Equates for all .ASM files 3 | ; 4 | 5 | ;---------------------------------------------------------------------------- 6 | 7 | INCLUDE "GFXE_CK4.EQU" 8 | 9 | ;---------------------------------------------------------------------------- 10 | 11 | CGAGR = 1 12 | EGAGR = 2 13 | TGAGR = 9 14 | 15 | GRMODE = EGAGR 16 | PROFILE = 0 ; 1=keep stats on tile drawing 17 | 18 | SC_INDEX = 03C4h 19 | SC_RESET = 0 20 | SC_CLOCK = 1 21 | SC_MAPMASK = 2 22 | SC_CHARMAP = 3 23 | SC_MEMMODE = 4 24 | 25 | CRTC_INDEX = 03D4h 26 | CRTC_H_TOTAL = 0 27 | CRTC_H_DISPEND = 1 28 | CRTC_H_BLANK = 2 29 | CRTC_H_ENDBLANK = 3 30 | CRTC_H_RETRACE = 4 31 | CRTC_H_ENDRETRACE = 5 32 | CRTC_V_TOTAL = 6 33 | CRTC_OVERFLOW = 7 34 | CRTC_ROWSCAN = 8 35 | CRTC_MAXSCANLINE = 9 36 | CRTC_CURSORSTART = 10 37 | CRTC_CURSOREND = 11 38 | CRTC_STARTHIGH = 12 39 | CRTC_STARTLOW = 13 40 | CRTC_CURSORHIGH = 14 41 | CRTC_CURSORLOW = 15 42 | CRTC_V_RETRACE = 16 43 | CRTC_V_ENDRETRACE = 17 44 | CRTC_V_DISPEND = 18 45 | CRTC_OFFSET = 19 46 | CRTC_UNDERLINE = 20 47 | CRTC_V_BLANK = 21 48 | CRTC_V_ENDBLANK = 22 49 | CRTC_MODE = 23 50 | CRTC_LINECOMPARE = 24 51 | 52 | 53 | GC_INDEX = 03CEh 54 | GC_SETRESET = 0 55 | GC_ENABLESETRESET = 1 56 | GC_COLORCOMPARE = 2 57 | GC_DATAROTATE = 3 58 | GC_READMAP = 4 59 | GC_MODE = 5 60 | GC_MISCELLANEOUS = 6 61 | GC_COLORDONTCARE = 7 62 | GC_BITMASK = 8 63 | 64 | ATR_INDEX = 03c0h 65 | ATR_MODE = 16 66 | ATR_OVERSCAN = 17 67 | ATR_COLORPLANEENABLE = 18 68 | ATR_PELPAN = 19 69 | ATR_COLORSELECT = 20 70 | 71 | STATUS_REGISTER_1 = 03dah 72 | 73 | 74 | MACRO WORDOUT 75 | out dx,ax 76 | ENDM 77 | 78 | if 0 79 | 80 | MACRO WORDOUT 81 | out dx,al 82 | inc dx 83 | xchg al,ah 84 | out dx,al 85 | dec dx 86 | xchg al,ah 87 | ENDM 88 | 89 | endif 90 | 91 | UPDATEWIDE = 22 92 | UPDATEHIGH = 14 93 | 94 | ; 95 | ; tile info offsets from segment tinf 96 | ; 97 | 98 | ANIM = 402 99 | SPEED = (ANIM+NUMTILE16) 100 | 101 | NORTHWALL = (SPEED+NUMTILE16) 102 | EASTWALL = (NORTHWALL+NUMTILE16M) 103 | SOUTHWALL = (EASTWALL+NUMTILE16M) 104 | WESTWALL = (SOUTHWALL+NUMTILE16M) 105 | MANIM = (WESTWALL+NUMTILE16M) 106 | INTILE = (MANIM+NUMTILE16M) 107 | MSPEED = (INTILE+NUMTILE16M) 108 | 109 | 110 | SCREENWIDTH = 64 111 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4/ID_HEADS.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // ID_GLOB.H 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define __ID_GLOB__ 44 | 45 | //-------------------------------------------------------------------------- 46 | 47 | #define KEEN 48 | #define KEEN4 49 | 50 | #define EXTENSION "CK4" 51 | 52 | extern char far introscn; 53 | 54 | #include "GFXE_CK4.H" 55 | #include "AUDIOCK4.H" 56 | 57 | //-------------------------------------------------------------------------- 58 | 59 | #define TEXTGR 0 60 | #define CGAGR 1 61 | #define EGAGR 2 62 | 63 | #define GRMODE EGAGR 64 | 65 | #define GREXT "EGA" 66 | 67 | //#define PROFILE 68 | 69 | // 70 | // ID Engine 71 | // Types.h - Generic types, #defines, etc. 72 | // v1.0d1 73 | // 74 | 75 | #ifndef __TYPES__ 76 | #define __TYPES__ 77 | 78 | typedef enum {false,true} boolean; 79 | typedef unsigned char byte; 80 | typedef unsigned int word; 81 | typedef unsigned long longword; 82 | typedef byte * Ptr; 83 | 84 | typedef struct 85 | { 86 | int x,y; 87 | } Point; 88 | typedef struct 89 | { 90 | Point ul,lr; 91 | } Rect; 92 | 93 | #define nil ((void *)0) 94 | 95 | #endif 96 | 97 | #include "ID_MM.H" 98 | #include "ID_CA.H" 99 | #include "ID_VW.H" 100 | #include "ID_RF.H" 101 | #include "ID_IN.H" 102 | #include "ID_SD.H" 103 | #include "ID_US.H" 104 | 105 | 106 | void Quit (char *error); // defined in user program 107 | 108 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4/K4_DEF.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is loosely based on: 9 | * Keen Dreams Source Code 10 | * Copyright (C) 2014 Javier M. Chavez 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | #ifndef __K4_DEF__ 28 | #define __K4_DEF__ 29 | 30 | /* 31 | ============================================================================= 32 | 33 | GLOBAL CONSTANTS 34 | 35 | ============================================================================= 36 | */ 37 | 38 | #define STARPALETTE {0, 1, 2, 3, 4, 16, 6, 7, 31, 31, 31, 31, 31, 31, 31, 31, 0} 39 | #define INTROPALETTE {0, 24, 24, 7, 1, 1, 1, 1, 17, 17, 17, 17, 19, 19, 19, 19, 0} 40 | #define SHRINKPALETTE {0, 24, 24, 7, 1, 1, 1, 1, 17, 17, 17, 17, 19, 19, 19, 24, 0} 41 | 42 | #define HIGHSCORE_LEFT 24 43 | #define HIGHSCORE_TOP 51 44 | #define HIGHSCORE_RIGHT 296 45 | #define HIGHSCORE_MAP 19 46 | 47 | #define STATUS_PRESSKEY_X 160 48 | 49 | #define WORLDMAPNAME "Shadowlands" 50 | #define DROPSNAME "DROPS" 51 | 52 | #define STARWARSMUSIC 12 53 | #define ENDINGMUSIC 7 54 | 55 | // levels in this range can NOT be re-entered (BWB level should be > MAXDONELEVEL) 56 | #define MINDONELEVEL 1 57 | #define MAXDONELEVEL 17 58 | 59 | #define INACTIVATEDIST 4 60 | 61 | /* 62 | ============================================================================= 63 | 64 | K4_SPEC DEFINITIONS 65 | 66 | ============================================================================= 67 | */ 68 | 69 | extern char far swtext[]; 70 | extern char far *levelnames[GAMELEVELS]; 71 | extern char far *levelenter[GAMELEVELS]; 72 | 73 | void ScanInfoPlane(void); 74 | void PrincessLindsey(void); 75 | void RescueJanitor(void); 76 | void CantSwim(void); 77 | void GotScuba(void); 78 | void RescuedMember(void); 79 | 80 | extern statetype s_keenswimslow1; 81 | extern statetype s_keenswimslow2; 82 | extern statetype s_kbubble1; 83 | extern statetype s_kbubble2; 84 | extern statetype s_kbubble3; 85 | extern statetype s_kbubble4; 86 | void SpawnSwimKeen(Sint16 x, Sint16 y); 87 | void SpawnKbubble(objtype *ob); 88 | void T_KeenSwimSlow(objtype *ob); 89 | void C_KeenSwim(objtype *ob, objtype *hit); 90 | void R_KeenSwim(objtype *ob); 91 | 92 | /* 93 | ============================================================================= 94 | 95 | K4_ACT1 DEFINITIONS 96 | 97 | ============================================================================= 98 | */ 99 | 100 | extern statetype s_miragia0; 101 | extern statetype s_miragia1; 102 | extern statetype s_miragia2; 103 | extern statetype s_miragia3; 104 | extern statetype s_miragia4; 105 | extern statetype s_miragia5; 106 | extern statetype s_miragia6; 107 | extern statetype s_miragia7; 108 | void SpawnMiragia(Sint16 x, Sint16 y); 109 | void T_Miragia0(objtype *ob); 110 | void T_Miragia1(objtype *ob); 111 | void T_Miragia2(objtype *ob); 112 | void T_Miragia3(objtype *ob); 113 | void T_Miragia4(objtype *ob); 114 | void T_Miragia5(objtype *ob); 115 | void T_Miragia6(objtype *ob); 116 | void T_Miragia7(objtype *ob); 117 | 118 | extern statetype s_bonus1; 119 | extern statetype s_bonus2; 120 | extern statetype s_bonusrise; 121 | extern statetype s_splash1; 122 | extern statetype s_splash2; 123 | extern statetype s_splash3; 124 | extern Uint16 bonusshape[]; 125 | void SpawnBonus(Sint16 x, Sint16 y, Sint16 type); 126 | void SpawnSplash(Sint16 x, Sint16 y); 127 | void T_Bonus(objtype *ob); 128 | 129 | extern statetype s_councilwalk1; 130 | extern statetype s_councilwalk2; 131 | extern statetype s_councilstand; 132 | void SpawnCouncil(Sint16 x, Sint16 y); 133 | void T_Council(objtype *ob); 134 | 135 | extern statetype s_slugwalk1; 136 | extern statetype s_slugwalk2; 137 | extern statetype s_slugpiss1; 138 | extern statetype s_slugstun; 139 | extern statetype s_slugstunalt; 140 | extern statetype s_slugslime; 141 | extern statetype s_slugslime2; 142 | void SpawnSlug(Sint16 x, Sint16 y); 143 | void T_Slug(objtype *ob); 144 | void T_SlugPiss(objtype *ob); 145 | void C_Slug(objtype *ob, objtype *hit); 146 | 147 | extern statetype s_mushroom1; 148 | extern statetype s_mushroom2; 149 | void SpawnMadMushroom(Sint16 x, Sint16 y); 150 | void T_Mushroom(objtype *ob); 151 | void C_Mushroom(objtype *ob, objtype *hit); 152 | void R_Mushroom(objtype *ob); 153 | 154 | extern statetype s_egg; 155 | extern statetype s_eggbroke; 156 | extern statetype s_eggchip1; 157 | extern statetype s_eggchip2; 158 | extern statetype s_eggchip3; 159 | extern statetype s_eggbirdpause; 160 | extern statetype s_eggbirdwalk1; 161 | extern statetype s_eggbirdwalk2; 162 | extern statetype s_eggbirdwalk3; 163 | extern statetype s_eggbirdwalk4; 164 | extern statetype s_eggbirdfly1; 165 | extern statetype s_eggbirdfly2; 166 | extern statetype s_eggbirdfly3; 167 | extern statetype s_eggbirdfly4; 168 | extern statetype s_eggbirdstun; 169 | extern statetype s_eggbirdstun2; 170 | extern statetype s_eggbirdstun3; 171 | extern statetype s_eggbirdstun4; 172 | extern statetype s_eggbirdstun5; 173 | void SpawnEggbird(Sint16 x, Sint16 y); 174 | void T_EggUnstun(objtype *ob); 175 | void SpawnEggbirdOut(Sint16 x, Sint16 y); 176 | void C_Egg(objtype *ob, objtype *hit); 177 | void T_Eggbird(objtype *ob); 178 | void T_EggbirdFly(objtype *ob); 179 | void C_Eggbird(objtype *ob, objtype *hit); 180 | void C_EggbirdStun(objtype *ob, objtype *hit); 181 | void R_Eggbird(objtype *ob); 182 | void R_Chip(objtype *ob); 183 | void R_Eggbirdfly(objtype *ob); 184 | 185 | extern statetype s_arach1; 186 | extern statetype s_arach2; 187 | extern statetype s_arach3; 188 | extern statetype s_arach4; 189 | extern statetype s_arachstun; 190 | extern statetype s_arachstun2; 191 | extern statetype s_arachstun3; 192 | extern statetype s_arachstun4; 193 | extern statetype s_arachstun5; 194 | void SpawnArachnut(Sint16 x, Sint16 y); 195 | void T_Arach(objtype *ob); 196 | void C_Arach(objtype *ob, objtype *hit); 197 | void C_ArachStun(objtype *ob, objtype *hit); 198 | 199 | extern statetype s_pestfly1; 200 | extern statetype s_pestfly2; 201 | extern statetype s_squashedpest; 202 | extern statetype s_pestrest1; 203 | extern statetype s_pestrest2; 204 | extern statetype s_pestrest3; 205 | extern statetype s_pestrest4; 206 | extern statetype s_pestrest5; 207 | extern statetype s_pestrest6; 208 | extern statetype s_pestrest7; 209 | extern statetype s_pestrest8; 210 | extern statetype s_pestrest9; 211 | extern statetype s_pestrest10; 212 | extern statetype s_pestrest11; 213 | extern statetype s_pestrest12; 214 | extern statetype s_pestrest13; 215 | extern statetype s_pestrest14; 216 | extern statetype s_pestrest15; 217 | extern statetype s_pestrest16; 218 | extern statetype s_pestrest17; 219 | void SpawnSkypest(Sint16 x, Sint16 y); 220 | void T_PestFly(objtype *ob); 221 | void C_PestFly(objtype *ob, objtype *hit); 222 | void C_Squashable(objtype *ob, objtype *hit); 223 | void T_PestRest(objtype *ob); 224 | void R_Pest(objtype *ob); 225 | 226 | /* 227 | ============================================================================= 228 | 229 | K4_ACT2 DEFINITIONS 230 | 231 | ============================================================================= 232 | */ 233 | 234 | extern statetype s_worm; 235 | extern statetype s_wormpeek1; 236 | extern statetype s_wormpeek2; 237 | extern statetype s_wormpeek3; 238 | extern statetype s_wormpeek4; 239 | extern statetype s_wormpeek5; 240 | extern statetype s_wormpeek6; 241 | extern statetype s_wormpeek7; 242 | extern statetype s_wormpeek8; 243 | extern statetype s_wormbite1; 244 | extern statetype s_wormbite2; 245 | extern statetype s_wormbite3; 246 | extern statetype s_wormbite4; 247 | extern statetype s_wormbite5; 248 | extern statetype s_wormstun; 249 | void SpawnWormMouth(Sint16 x, Sint16 y); 250 | void T_WormLookRight(objtype *ob); 251 | void T_WormLook(objtype *ob); 252 | void T_WormLookLeft(objtype *ob); 253 | void T_Worm(objtype *ob); 254 | void C_Worm(objtype *ob, objtype *hit); 255 | void C_WormKill(objtype *ob, objtype *hit); 256 | 257 | extern statetype s_cloudsleep; 258 | extern statetype s_cloudwake; 259 | extern statetype s_cloud; 260 | extern statetype s_cloudalign; 261 | extern statetype s_cloudcharge; 262 | extern statetype s_cloudattack1; 263 | extern statetype s_cloudattack2; 264 | extern statetype s_cloudattack3; 265 | extern statetype s_cloudattack4; 266 | extern statetype s_cloudattack5; 267 | extern statetype s_cloudattack6; 268 | extern statetype s_cloudattack7; 269 | extern statetype s_cloudattack8; 270 | extern statetype s_cloudattack9; 271 | extern statetype s_bolt1; 272 | extern statetype s_bolt2; 273 | extern statetype s_bolt3; 274 | extern statetype s_bolt4; 275 | extern statetype s_bolt5; 276 | extern statetype s_bolt6; 277 | void SpawnCloudster(Sint16 x, Sint16 y); 278 | void T_Cloud(objtype *ob); 279 | void T_CloudAlign(objtype *ob); 280 | void R_Cloud(objtype *ob); 281 | void T_CloudShoot(objtype *ob); 282 | void C_CloudSleep(objtype *ob, objtype *hit); 283 | 284 | extern statetype s_berkefloat1; 285 | extern statetype s_berkefloat2; 286 | extern statetype s_berkefloat3; 287 | extern statetype s_berkefloat4; 288 | extern statetype s_berkethrow1; 289 | extern statetype s_berkethrow2; 290 | extern statetype s_berkethrow3; 291 | extern statetype s_berkethrow4; 292 | extern statetype s_berkethrow5; 293 | extern statetype s_berkethrow6; 294 | extern statetype s_berkethrow7; 295 | extern statetype s_berkethrow8; 296 | extern statetype s_berkethrow9; 297 | extern statetype s_berkethrow10; 298 | extern statetype s_berkethrow11; 299 | extern statetype s_berkethrow12; 300 | extern statetype s_fire1; 301 | extern statetype s_fire2; 302 | extern statetype s_fireland1; 303 | extern statetype s_fireland2; 304 | extern statetype s_fireland3; 305 | extern statetype s_fireland4; 306 | extern statetype s_fireland5; 307 | extern statetype s_fireland6; 308 | extern statetype s_fireland7; 309 | extern statetype s_fireland8; 310 | extern statetype s_fireland9; 311 | void SpawnBerkeloid(Sint16 x, Sint16 y); 312 | void BerkeThink(objtype *ob); 313 | void BerkeThrowThink(objtype *ob); 314 | void BerkeThrowDone(objtype *ob); 315 | void C_Berke(objtype *ob, objtype *hit); 316 | void FireReact(objtype *ob); 317 | void BerkeDrawReact(objtype *ob); 318 | void BerkeWalkReact(objtype *ob); 319 | 320 | extern statetype s_footsmoke1; 321 | extern statetype s_footsmoke2; 322 | extern statetype s_footsmoke3; 323 | extern statetype s_footsmoke4; 324 | extern statetype s_inch1; 325 | extern statetype s_inch2; 326 | extern statetype s_footwait; 327 | void SpawnInchworm(Sint16 x, Sint16 y); 328 | void SpawnFoot(Sint16 x, Sint16 y); 329 | void InchThink(objtype *ob); 330 | void InchContact(objtype *ob, objtype *hit); 331 | void FootContact(objtype *ob, objtype *hit); 332 | 333 | extern statetype s_bounderup1; 334 | extern statetype s_bounderup2; 335 | extern statetype s_bounderside1; 336 | extern statetype s_bounderside2; 337 | extern statetype s_bounderstun; 338 | extern statetype s_bounderstun2; 339 | void SpawnBounder(Sint16 x, Sint16 y); 340 | void C_Bounder(objtype *ob, objtype *hit); 341 | void R_Bounder(objtype *ob); 342 | 343 | extern statetype s_lick1; 344 | extern statetype s_lick2; 345 | extern statetype s_lick3; 346 | extern statetype s_lick4; 347 | extern statetype s_licklick1; 348 | extern statetype s_licklick2; 349 | extern statetype s_licklick3; 350 | extern statetype s_licklick4; 351 | extern statetype s_licklick5; 352 | extern statetype s_licklick6; 353 | extern statetype s_licklick7; 354 | extern statetype s_licklick8; 355 | extern statetype s_lickstun; 356 | extern statetype s_lickstun2; 357 | void SpawnLick(Sint16 x, Sint16 y); 358 | void LickJumpThink(objtype *ob); 359 | void LickContact(objtype *ob, objtype *hit); 360 | void LickKillContact(objtype *ob, objtype *hit); 361 | void LickAirReact(objtype *ob); 362 | 363 | extern statetype s_platform; 364 | void SpawnPlatform(Sint16 x, Sint16 y, Sint16 dir); 365 | void T_Platform(objtype *ob); 366 | void R_Platform(objtype *ob); 367 | 368 | extern statetype s_dropplatsit; 369 | extern statetype s_dropplatfall; 370 | extern statetype s_dropplatrise; 371 | void SpawnDropPlat(Sint16 x, Sint16 y); 372 | void T_DropPlatSit(objtype *ob); 373 | void T_DropPlatFall(objtype *ob); 374 | void T_DropPlatRise(objtype *ob); 375 | 376 | /* 377 | ============================================================================= 378 | 379 | K4_ACT3 DEFINITIONS 380 | 381 | ============================================================================= 382 | */ 383 | 384 | extern statetype s_eaterstand1; 385 | extern statetype s_eaterstand2; 386 | extern statetype s_eatertport1; 387 | extern statetype s_eatertport2; 388 | extern statetype s_eatertport3; 389 | extern statetype s_eatertport4; 390 | extern statetype s_eatertport5; 391 | extern statetype s_eatertport6; 392 | extern statetype s_eatertport7; 393 | extern statetype s_eatertport8; 394 | extern statetype s_eaterjump1; 395 | extern statetype s_eaterjump2; 396 | extern statetype s_eaterjump3; 397 | extern statetype s_eaterjump4; 398 | extern statetype s_eaterstun; 399 | extern statetype s_eaterstun2; 400 | extern statetype s_eatenbonus1; 401 | extern statetype s_eatenbonus2; 402 | extern statetype s_eatenbonus3; 403 | extern statetype s_eatenbonus4; 404 | void SpawnEater(Sint16 x, Sint16 y); 405 | void T_EaterJump(objtype *ob); 406 | void T_EaterTeleport(objtype *ob); 407 | void C_Eater(objtype *ob, objtype *hit); 408 | void EaterInTile(objtype *ob); 409 | void R_EaterAir(objtype *ob); 410 | 411 | extern statetype s_mimrock; 412 | extern statetype s_mimsneak1; 413 | extern statetype s_mimsneak2; 414 | extern statetype s_mimsneak3; 415 | extern statetype s_mimsneak4; 416 | extern statetype s_mimsneak5; 417 | extern statetype s_mimsneak6; 418 | extern statetype s_mimbonk1; 419 | extern statetype s_mimbonk2; 420 | extern statetype s_mimbonk3; 421 | extern statetype s_mimbounce; 422 | extern statetype s_mimstun; 423 | extern statetype s_mimstun2; 424 | void SpawnMimrock(Sint16 x, Sint16 y); 425 | void T_MimrockWait(objtype *ob); 426 | void T_MimrockSneak(objtype *ob); 427 | void C_Mimrock(objtype *ob, objtype *hit); 428 | void C_MimLethal(objtype *ob, objtype *hit); 429 | void R_MimAir(objtype *ob); 430 | void R_MimBounce(objtype *ob); 431 | 432 | extern statetype s_dopefish1; 433 | extern statetype s_dopefish2; 434 | extern statetype s_dopeattack; 435 | extern statetype s_dopeeat; 436 | extern statetype s_dopeburp1; 437 | extern statetype s_dopeburp2; 438 | extern statetype s_dopereturn; 439 | extern statetype s_dopefood; 440 | extern statetype s_keendopefood; 441 | extern statetype s_keendieslow; 442 | extern statetype s_bubble1; 443 | extern statetype s_bubble2; 444 | extern statetype s_bubble3; 445 | extern statetype s_bubble4; 446 | void SpawnDopefish(Sint16 x, Sint16 y); 447 | void T_EatenKeen(objtype *ob); 448 | void T_Dope(objtype *ob); 449 | void T_DopeHunt(objtype *ob); 450 | void T_DopeReturn(objtype *ob); 451 | void T_Burp(objtype *ob); 452 | void T_Bubble(objtype *ob); 453 | void C_Dope(objtype *ob, objtype *hit); 454 | void R_Fish(objtype *ob); 455 | 456 | extern statetype s_schoolfish1; 457 | extern statetype s_schoolfish2; 458 | void SpawnSchoolfish(Sint16 x, Sint16 y); 459 | void T_SchoolFish(objtype *ob); 460 | 461 | extern statetype s_pixie; 462 | extern statetype s_pixielook; 463 | extern statetype s_pixieshoot; 464 | extern statetype s_pixieshoot2; 465 | extern statetype s_pixiefire1; 466 | extern statetype s_pixiefire2; 467 | extern statetype s_pixiefire3; 468 | extern statetype s_pixiefire4; 469 | void SpawnPixie(Sint16 x, Sint16 y); 470 | void T_Pixie(objtype *ob); 471 | void T_PixieCheck(objtype *ob); 472 | void T_PixieShoot(objtype *ob); 473 | void R_Mshot(objtype *ob); 474 | 475 | extern statetype s_mine; 476 | extern statetype s_mineboom1; 477 | extern statetype s_mineboom2; 478 | void SpawnMine(Sint16 x, Sint16 y, Sint16 dir); 479 | void C_Mine(objtype *ob, objtype *hit); 480 | 481 | extern statetype s_lindsey1; 482 | extern statetype s_lindsey2; 483 | extern statetype s_lindsey3; 484 | extern statetype s_lindsey4; 485 | void SpawnLindsey(Sint16 x, Sint16 y); 486 | void T_Lindsey(objtype *ob); 487 | 488 | extern statetype s_dartthrower; 489 | extern statetype s_dart1; 490 | extern statetype s_dart2; 491 | extern statetype s_dartup1; 492 | extern statetype s_dartup2; 493 | extern statetype s_dartdown1; 494 | extern statetype s_dartdown2; 495 | void SpawnDartShooter(Sint16 x, Sint16 y, Sint16 dir); 496 | void T_DartShoot(objtype *ob); 497 | 498 | extern statetype s_scuba; 499 | void SpawnScuba(Sint16 x, Sint16 y); 500 | void C_Scuba(objtype *ob, objtype *hit); 501 | 502 | #endif -------------------------------------------------------------------------------- /KEEN4-6/KEEN4C.DSK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4C.DSK -------------------------------------------------------------------------------- /KEEN4-6/KEEN4C.PRJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4C.PRJ -------------------------------------------------------------------------------- /KEEN4-6/KEEN4C/GFXC_CK4.EQU: -------------------------------------------------------------------------------- 1 | ;===================================== 2 | ; 3 | ; Graphics .EQU file for .CK4 4 | ; not IGRAB-ed :) 5 | ; 6 | ;===================================== 7 | 8 | ;INCLUDE "VERSION.EQU" 9 | 10 | ; 11 | ; Amount of each data item 12 | ; 13 | NUMFONT = 2 14 | NUMFONTM = 0 15 | NUMPICM = 3 16 | NUMTILE8 = 108 17 | NUMTILE8M = 36 18 | NUMTILE32 = 0 19 | NUMTILE32M = 0 20 | 21 | ; 22 | ; Amount of each item in episode 4 23 | ; 24 | NUMPICS = 116 25 | NUMSPRITES = 397 26 | NUMTILE16 = 1296 27 | NUMTILE16M = 2916 28 | NUMEXTERN = 16 29 | 30 | 31 | ; 32 | ; File offsets for data items 33 | ; 34 | STRUCTPIC = 0 35 | STRUCTPICM = 1 36 | STRUCTSPRITE = 2 37 | 38 | STARTFONT = 3 39 | STARTFONTM = (STARTFONT+NUMFONT) 40 | STARTPICS = (STARTFONTM+NUMFONTM) 41 | STARTPICM = (STARTPICS+NUMPICS) 42 | STARTSPRITES = (STARTPICM+NUMPICM) 43 | STARTTILE8 = (STARTSPRITES+NUMSPRITES) 44 | STARTTILE8M = (STARTTILE8+1) 45 | STARTTILE16 = (STARTTILE8M+1) 46 | STARTTILE16M = (STARTTILE16+NUMTILE16) 47 | STARTTILE32 = (STARTTILE16M+NUMTILE16M) 48 | STARTTILE32M = (STARTTILE32+NUMTILE32) 49 | STARTEXTERN = (STARTTILE32M+NUMTILE32M) 50 | 51 | NUMCHUNKS = (STARTEXTERN+NUMEXTERN) 52 | 53 | ; 54 | ; Thank you for using IGRAB! 55 | ; 56 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4C/ID_ASM.EQU: -------------------------------------------------------------------------------- 1 | ; 2 | ; Equates for all .ASM files 3 | ; 4 | 5 | ;---------------------------------------------------------------------------- 6 | 7 | INCLUDE "GFXC_CK4.EQU" 8 | 9 | ;---------------------------------------------------------------------------- 10 | 11 | CGAGR = 1 12 | EGAGR = 2 13 | TGAGR = 9 14 | 15 | GRMODE = CGAGR 16 | PROFILE = 0 ; 1=keep stats on tile drawing 17 | 18 | SC_INDEX = 03C4h 19 | SC_RESET = 0 20 | SC_CLOCK = 1 21 | SC_MAPMASK = 2 22 | SC_CHARMAP = 3 23 | SC_MEMMODE = 4 24 | 25 | CRTC_INDEX = 03D4h 26 | CRTC_H_TOTAL = 0 27 | CRTC_H_DISPEND = 1 28 | CRTC_H_BLANK = 2 29 | CRTC_H_ENDBLANK = 3 30 | CRTC_H_RETRACE = 4 31 | CRTC_H_ENDRETRACE = 5 32 | CRTC_V_TOTAL = 6 33 | CRTC_OVERFLOW = 7 34 | CRTC_ROWSCAN = 8 35 | CRTC_MAXSCANLINE = 9 36 | CRTC_CURSORSTART = 10 37 | CRTC_CURSOREND = 11 38 | CRTC_STARTHIGH = 12 39 | CRTC_STARTLOW = 13 40 | CRTC_CURSORHIGH = 14 41 | CRTC_CURSORLOW = 15 42 | CRTC_V_RETRACE = 16 43 | CRTC_V_ENDRETRACE = 17 44 | CRTC_V_DISPEND = 18 45 | CRTC_OFFSET = 19 46 | CRTC_UNDERLINE = 20 47 | CRTC_V_BLANK = 21 48 | CRTC_V_ENDBLANK = 22 49 | CRTC_MODE = 23 50 | CRTC_LINECOMPARE = 24 51 | 52 | 53 | GC_INDEX = 03CEh 54 | GC_SETRESET = 0 55 | GC_ENABLESETRESET = 1 56 | GC_COLORCOMPARE = 2 57 | GC_DATAROTATE = 3 58 | GC_READMAP = 4 59 | GC_MODE = 5 60 | GC_MISCELLANEOUS = 6 61 | GC_COLORDONTCARE = 7 62 | GC_BITMASK = 8 63 | 64 | ATR_INDEX = 03c0h 65 | ATR_MODE = 16 66 | ATR_OVERSCAN = 17 67 | ATR_COLORPLANEENABLE = 18 68 | ATR_PELPAN = 19 69 | ATR_COLORSELECT = 20 70 | 71 | STATUS_REGISTER_1 = 03dah 72 | 73 | 74 | MACRO WORDOUT 75 | out dx,ax 76 | ENDM 77 | 78 | if 0 79 | 80 | MACRO WORDOUT 81 | out dx,al 82 | inc dx 83 | xchg al,ah 84 | out dx,al 85 | dec dx 86 | xchg al,ah 87 | ENDM 88 | 89 | endif 90 | 91 | UPDATEWIDE = 22 92 | UPDATEHIGH = 14 93 | 94 | ; 95 | ; tile info offsets from segment tinf 96 | ; 97 | 98 | SPEED = 402 99 | ANIM = (SPEED+NUMTILE16) 100 | 101 | NORTHWALL = (ANIM+NUMTILE16) 102 | EASTWALL = (NORTHWALL+NUMTILE16M) 103 | SOUTHWALL = (EASTWALL+NUMTILE16M) 104 | WESTWALL = (SOUTHWALL+NUMTILE16M) 105 | MANIM = (WESTWALL+NUMTILE16M) 106 | INTILE = (MANIM+NUMTILE16M) 107 | MSPEED = (INTILE+NUMTILE16M) 108 | 109 | 110 | SCREENWIDTH = 128 111 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4C/ID_HEADS.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // ID_GLOB.H 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define __ID_GLOB__ 44 | 45 | //-------------------------------------------------------------------------- 46 | 47 | #define KEEN 48 | #define KEEN4 49 | 50 | #define EXTENSION "CK4" 51 | 52 | extern char far introscn; 53 | 54 | #include "GFXC_CK4.H" 55 | #include "AUDIOCK4.H" 56 | 57 | //-------------------------------------------------------------------------- 58 | 59 | #define TEXTGR 0 60 | #define CGAGR 1 61 | #define EGAGR 2 62 | 63 | #define GRMODE CGAGR 64 | 65 | #define GREXT "CGA" 66 | 67 | //#define PROFILE 68 | 69 | // 70 | // ID Engine 71 | // Types.h - Generic types, #defines, etc. 72 | // v1.0d1 73 | // 74 | 75 | #ifndef __TYPES__ 76 | #define __TYPES__ 77 | 78 | typedef enum {false,true} boolean; 79 | typedef unsigned char byte; 80 | typedef unsigned int word; 81 | typedef unsigned long longword; 82 | typedef byte * Ptr; 83 | 84 | typedef struct 85 | { 86 | int x,y; 87 | } Point; 88 | typedef struct 89 | { 90 | Point ul,lr; 91 | } Rect; 92 | 93 | #define nil ((void *)0) 94 | 95 | #endif 96 | 97 | #include "ID_MM.H" 98 | #include "ID_CA.H" 99 | #include "ID_VW.H" 100 | #include "ID_RF.H" 101 | #include "ID_IN.H" 102 | #include "ID_SD.H" 103 | #include "ID_US.H" 104 | 105 | 106 | void Quit (char *error); // defined in user program 107 | 108 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4E.DSK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4E.DSK -------------------------------------------------------------------------------- /KEEN4-6/KEEN4E.PRJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4E.PRJ -------------------------------------------------------------------------------- /KEEN4-6/KEEN4M.DSK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4M.DSK -------------------------------------------------------------------------------- /KEEN4-6/KEEN4M.PRJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4M.PRJ -------------------------------------------------------------------------------- /KEEN4-6/KEEN4M/ID_HEADS.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // ID_GLOB.H 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define __ID_GLOB__ 44 | 45 | //-------------------------------------------------------------------------- 46 | 47 | #define KEEN 48 | #define KEEN4 49 | 50 | #define EXTENSION "CK4" 51 | 52 | extern char far introscn; 53 | 54 | #include "GFXT_CK4.H" 55 | #include "AUDIOCK4.H" 56 | 57 | //-------------------------------------------------------------------------- 58 | 59 | #define TEXTGR 0 60 | #define CGAGR 1 61 | #define EGAGR 2 62 | #define TGAGR 9 63 | 64 | #define GRMODE TGAGR 65 | 66 | #define GREXT "TGA" 67 | 68 | #define MCGA 69 | 70 | //#define PROFILE 71 | 72 | // 73 | // ID Engine 74 | // Types.h - Generic types, #defines, etc. 75 | // v1.0d1 76 | // 77 | 78 | #ifndef __TYPES__ 79 | #define __TYPES__ 80 | 81 | typedef enum {false,true} boolean; 82 | typedef unsigned char byte; 83 | typedef unsigned int word; 84 | typedef unsigned long longword; 85 | typedef byte * Ptr; 86 | 87 | typedef struct 88 | { 89 | int x,y; 90 | } Point; 91 | 92 | #define nil ((void *)0) 93 | 94 | #endif 95 | 96 | #include "ID_MM.H" 97 | #include "ID_CA.H" 98 | #include "ID_VW.H" 99 | #include "ID_RF.H" 100 | #include "ID_IN.H" 101 | #include "ID_SD.H" 102 | #include "ID_US.H" 103 | 104 | 105 | void Quit (char *error); // defined in user program 106 | 107 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4T.DSK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4T.DSK -------------------------------------------------------------------------------- /KEEN4-6/KEEN4T.PRJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/KEEN4T.PRJ -------------------------------------------------------------------------------- /KEEN4-6/KEEN4T/GFXT_CK4.EQU: -------------------------------------------------------------------------------- 1 | ;===================================== 2 | ; 3 | ; Graphics .EQU file for .CK4 4 | ; not IGRAB-ed :) 5 | ; 6 | ;===================================== 7 | 8 | ;INCLUDE "VERSION.EQU" 9 | 10 | ; 11 | ; Amount of each data item 12 | ; 13 | NUMFONT = 3 14 | NUMFONTM = 0 15 | NUMPICM = 3 16 | NUMTILE8 = 108 17 | NUMTILE8M = 36 18 | NUMTILE32 = 0 19 | NUMTILE32M = 0 20 | 21 | ; 22 | ; Amount of each item in episode 4 23 | ; 24 | NUMPICS = 115 25 | NUMSPRITES = 397 26 | NUMTILE16 = 1296 27 | NUMTILE16M = 2916 28 | NUMEXTERN = 16 29 | 30 | 31 | ; 32 | ; File offsets for data items 33 | ; 34 | STRUCTPIC = 0 35 | STRUCTPICM = 1 36 | STRUCTSPRITE = 2 37 | 38 | STARTFONT = 3 39 | STARTFONTM = (STARTFONT+NUMFONT) 40 | STARTPICS = (STARTFONTM+NUMFONTM) 41 | STARTPICM = (STARTPICS+NUMPICS) 42 | STARTSPRITES = (STARTPICM+NUMPICM) 43 | STARTTILE8 = (STARTSPRITES+NUMSPRITES) 44 | STARTTILE8M = (STARTTILE8+1) 45 | STARTTILE16 = (STARTTILE8M+1) 46 | STARTTILE16M = (STARTTILE16+NUMTILE16) 47 | STARTTILE32 = (STARTTILE16M+NUMTILE16M) 48 | STARTTILE32M = (STARTTILE32+NUMTILE32) 49 | STARTEXTERN = (STARTTILE32M+NUMTILE32M) 50 | 51 | NUMCHUNKS = (STARTEXTERN+NUMEXTERN) 52 | 53 | ; 54 | ; Thank you for using IGRAB! 55 | ; 56 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4T/ID_ASM.EQU: -------------------------------------------------------------------------------- 1 | ; 2 | ; Equates for all .ASM files 3 | ; 4 | 5 | ;---------------------------------------------------------------------------- 6 | 7 | INCLUDE "GFXT_CK4.EQU" 8 | 9 | ;---------------------------------------------------------------------------- 10 | 11 | CGAGR = 1 12 | EGAGR = 2 13 | TGAGR = 9 14 | 15 | GRMODE = TGAGR 16 | PROFILE = 0 ; 1=keep stats on tile drawing 17 | 18 | SC_INDEX = 03C4h 19 | SC_RESET = 0 20 | SC_CLOCK = 1 21 | SC_MAPMASK = 2 22 | SC_CHARMAP = 3 23 | SC_MEMMODE = 4 24 | 25 | CRTC_INDEX = 03D4h 26 | CRTC_H_TOTAL = 0 27 | CRTC_H_DISPEND = 1 28 | CRTC_H_BLANK = 2 29 | CRTC_H_ENDBLANK = 3 30 | CRTC_H_RETRACE = 4 31 | CRTC_H_ENDRETRACE = 5 32 | CRTC_V_TOTAL = 6 33 | CRTC_OVERFLOW = 7 34 | CRTC_ROWSCAN = 8 35 | CRTC_MAXSCANLINE = 9 36 | CRTC_CURSORSTART = 10 37 | CRTC_CURSOREND = 11 38 | CRTC_STARTHIGH = 12 39 | CRTC_STARTLOW = 13 40 | CRTC_CURSORHIGH = 14 41 | CRTC_CURSORLOW = 15 42 | CRTC_V_RETRACE = 16 43 | CRTC_V_ENDRETRACE = 17 44 | CRTC_V_DISPEND = 18 45 | CRTC_OFFSET = 19 46 | CRTC_UNDERLINE = 20 47 | CRTC_V_BLANK = 21 48 | CRTC_V_ENDBLANK = 22 49 | CRTC_MODE = 23 50 | CRTC_LINECOMPARE = 24 51 | 52 | 53 | GC_INDEX = 03CEh 54 | GC_SETRESET = 0 55 | GC_ENABLESETRESET = 1 56 | GC_COLORCOMPARE = 2 57 | GC_DATAROTATE = 3 58 | GC_READMAP = 4 59 | GC_MODE = 5 60 | GC_MISCELLANEOUS = 6 61 | GC_COLORDONTCARE = 7 62 | GC_BITMASK = 8 63 | 64 | ATR_INDEX = 03c0h 65 | ATR_MODE = 16 66 | ATR_OVERSCAN = 17 67 | ATR_COLORPLANEENABLE = 18 68 | ATR_PELPAN = 19 69 | ATR_COLORSELECT = 20 70 | 71 | STATUS_REGISTER_1 = 03dah 72 | 73 | 74 | MACRO WORDOUT 75 | out dx,ax 76 | ENDM 77 | 78 | if 0 79 | 80 | MACRO WORDOUT 81 | out dx,al 82 | inc dx 83 | xchg al,ah 84 | out dx,al 85 | dec dx 86 | xchg al,ah 87 | ENDM 88 | 89 | endif 90 | 91 | UPDATEWIDE = 22 92 | UPDATEHIGH = 12 93 | 94 | ; 95 | ; tile info offsets from segment tinf 96 | ; 97 | 98 | SPEED = 402 99 | ANIM = (SPEED+NUMTILE16) 100 | 101 | NORTHWALL = (ANIM+NUMTILE16) 102 | EASTWALL = (NORTHWALL+NUMTILE16M) 103 | SOUTHWALL = (EASTWALL+NUMTILE16M) 104 | WESTWALL = (SOUTHWALL+NUMTILE16M) 105 | MANIM = (WESTWALL+NUMTILE16M) 106 | INTILE = (MANIM+NUMTILE16M) 107 | MSPEED = (INTILE+NUMTILE16M) 108 | 109 | 110 | SCREENWIDTH = 170 111 | -------------------------------------------------------------------------------- /KEEN4-6/KEEN4T/ID_HEADS.H: -------------------------------------------------------------------------------- 1 | /* Commander Keen 4 Tandy Version Source Code 2 | * Copyright (C) 2021-2022 Frenkel Smeijers 3 | * 4 | * This file is primarily based on: 5 | * Reconstructed Commander Keen 4-6 Source Code 6 | * Copyright (C) 2021 K1n9_Duk3 7 | * 8 | * This file is primarily based on: 9 | * Catacomb 3-D Source Code 10 | * Copyright (C) 1993-2014 Flat Rock Software 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with this program; if not, write to the Free Software Foundation, Inc., 24 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | */ 26 | 27 | // ID_GLOB.H 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define __ID_GLOB__ 44 | 45 | //-------------------------------------------------------------------------- 46 | 47 | #define KEEN 48 | #define KEEN4 49 | 50 | #define EXTENSION "CK4" 51 | 52 | extern char far introscn; 53 | 54 | #include "GFXT_CK4.H" 55 | #include "AUDIOCK4.H" 56 | 57 | //-------------------------------------------------------------------------- 58 | 59 | #define TEXTGR 0 60 | #define CGAGR 1 61 | #define EGAGR 2 62 | #define TGAGR 9 63 | 64 | #define GRMODE TGAGR 65 | 66 | #define GREXT "TGA" 67 | 68 | #define TANDY 69 | 70 | //#define PROFILE 71 | 72 | // 73 | // ID Engine 74 | // Types.h - Generic types, #defines, etc. 75 | // v1.0d1 76 | // 77 | 78 | #ifndef __TYPES__ 79 | #define __TYPES__ 80 | 81 | typedef enum {false,true} boolean; 82 | typedef unsigned char byte; 83 | typedef unsigned int word; 84 | typedef unsigned long longword; 85 | typedef byte * Ptr; 86 | 87 | typedef struct 88 | { 89 | int x,y; 90 | } Point; 91 | 92 | #define nil ((void *)0) 93 | 94 | #endif 95 | 96 | #include "ID_MM.H" 97 | #include "ID_CA.H" 98 | #include "ID_VW.H" 99 | #include "ID_RF.H" 100 | #include "ID_IN.H" 101 | #include "ID_SD.H" 102 | #include "ID_US.H" 103 | 104 | 105 | void Quit (char *error); // defined in user program 106 | 107 | -------------------------------------------------------------------------------- /KEEN4-6/UNZX0.ASM: -------------------------------------------------------------------------------- 1 | ; Commander Keen 4 Tandy Version Source Code 2 | ; Copyright (C) 2021 Frenkel Smeijers 3 | ; 4 | ; This file is primarily based on: 5 | ; unzx0_8088.S - ZX0 decompressor for 8088 - 81 bytes - NASM 6 | ; 7 | ; inputs: 8 | ; * ds:si: start of compressed data 9 | ; * es:di: start of decompression buffer 10 | ; 11 | ; Copyright (C) 2021 Emmanuel Marty 12 | ; ZX0 compression (c) 2021 Einar Saukas, https://github.com/einar-saukas/ZX0 13 | ; 14 | ; This software is provided 'as-is', without any express or implied 15 | ; warranty. In no event will the authors be held liable for any damages 16 | ; arising from the use of this software. 17 | ; 18 | ; Permission is granted to anyone to use this software for any purpose, 19 | ; including commercial applications, and to alter it and redistribute it 20 | ; freely, subject to the following restrictions: 21 | ; 22 | ; 1. The origin of this software must not be misrepresented; you must not 23 | ; claim that you wrote the original software. If you use this software 24 | ; in a product, an acknowledgment in the product documentation would be 25 | ; appreciated but is not required. 26 | ; 2. Altered source versions must be plainly marked as such, and must not be 27 | ; misrepresented as being the original software. 28 | ; 3. This notice may not be removed or altered from any source distribution. 29 | 30 | IDEAL 31 | P8086 32 | MODEL SMALL,C 33 | 34 | CODESEG 35 | 36 | PUBLIC zx0_decompress 37 | 38 | PROC zx0_decompress NEAR 39 | 40 | zx0_decompress_start: 41 | cld ; make string operations go forward 42 | mov al,080H ; initialize empty bit queue 43 | ; plus bit to roll into carry 44 | xor dx,dx ; initialize rep-offset to 1 45 | dec dx 46 | 47 | @@literals: 48 | call @@get_elias ; read number of literals to copy 49 | rep movsb ; copy literal bytes 50 | 51 | add al,al ; shift bit queue, and high bit into carry 52 | jc @@get_offset ; if 1: read offset, if 0: rep-match 53 | 54 | call @@get_elias ; read rep-match length (starts at 1) 55 | 56 | @@copy_match: 57 | push ds ; save ds:si (current pointer to compressed data) 58 | push si 59 | 60 | push es 61 | pop ds 62 | mov si,di ; point to destination in es:di + offset in dx 63 | add si,dx 64 | rep movsb ; copy matched bytes 65 | 66 | pop si ; restore ds:si 67 | pop ds 68 | 69 | add al,al ; read 'literal or match' bit 70 | jnc @@literals ; if 0: go copy literals 71 | 72 | @@get_offset: 73 | mov cl,0feh ; initialize value to FEh 74 | call @@elias_loop ; read high byte of match offset 75 | inc cl ; obtain negative offset high byte 76 | je @@done ; exit if EOD marker 77 | 78 | mov dh,cl ; transfer negative high byte into dh 79 | mov cx,1 ; initialize match length value to 1 80 | mov dl,[si] ; read low byte of offset + 1 bit of len 81 | inc si 82 | stc ; set high bit that is shifted into bit 15 83 | rcr dx,1 ; shift len bit into carry/offset in place 84 | jc @@got_offs ; if len bit is set, no need for more 85 | call @@elias_bt ; read rest of elias-encoded match length 86 | @@got_offs: 87 | inc cx ; fix match length 88 | jmp short @@copy_match ; go copy match 89 | 90 | @@get_elias: 91 | mov cx,1 ; initialize value to 1 92 | @@elias_loop: 93 | add al,al ; shift bit queue, and high bit into carry 94 | jnz @@got_bit ; queue not empty, bits remain 95 | lodsb ; read 8 new bits 96 | adc al,al ; shift bit queue, and high bit into carry 97 | @@got_bit: 98 | jc @@got_elias ; done if control bit is 1 99 | @@elias_bt: 100 | add al,al ; read data bit 101 | adc cx,cx ; shift into cx 102 | jmp short @@elias_loop ; keep reading 103 | 104 | @@got_elias: 105 | ret 106 | @@done: 107 | retf 108 | 109 | ENDP zx0_decompress 110 | 111 | ENDS 112 | 113 | END 114 | -------------------------------------------------------------------------------- /KEEN4-6/static/AUDIOHED.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/AUDIOHED.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/CGAHEAD.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/CGAHEAD.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/EGAHEAD.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/EGAHEAD.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/INTROSCN.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/INTROSCN.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/MAKEOBJ.EXE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/MAKEOBJ.EXE -------------------------------------------------------------------------------- /KEEN4-6/static/MAPHEAD.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/MAPHEAD.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/TGAHEAD.CK4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/KEEN4-6/static/TGAHEAD.CK4 -------------------------------------------------------------------------------- /KEEN4-6/static/make.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem bcc makeobj.c 3 | 4 | rem makeobj c AUDIODCT.CK4 ..\keen4\ck4adict.obj _audiodict 5 | makeobj f AUDIOHED.CK4 ..\keen4\ck4ahead.obj _AudioHeader _audiohead 6 | makeobj f EGAHEAD.CK4 ..\keen4\ck4ehead.obj EGA_grafixheader _EGAhead 7 | makeobj f CGAHEAD.CK4 ..\keen4\ck4chead.obj CGA_grafixheader _CGAhead 8 | makeobj f TGAHEAD.CK4 ..\keen4\ck4thead.obj TGA_grafixheader _TGAhead 9 | makeobj f MAPHEAD.CK4 ..\keen4\ck4mhead.obj MapHeader _maphead 10 | makeobj f INTROSCN.CK4 ..\keen4\ck4intro.obj _introscn 11 | -------------------------------------------------------------------------------- /KEEN4-6/static/makeobj.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** makeobj.c 3 | ** 4 | **--------------------------------------------------------------------------- 5 | ** Copyright 2014 Braden Obrzut 6 | ** All rights reserved. 7 | ** 8 | ** Redistribution and use in source and binary forms, with or without 9 | ** modification, are permitted provided that the following conditions 10 | ** are met: 11 | ** 12 | ** 1. Redistributions of source code must retain the above copyright 13 | ** notice, this list of conditions and the following disclaimer. 14 | ** 2. Redistributions in binary form must reproduce the above copyright 15 | ** notice, this list of conditions and the following disclaimer in the 16 | ** documentation and/or other materials provided with the distribution. 17 | ** 3. The name of the author may not be used to endorse or promote products 18 | ** derived from this software without specific prior written permission. 19 | ** 20 | ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | **--------------------------------------------------------------------------- 31 | ** 32 | ** This is a throwaway program to create OMF object files for DOS. It also 33 | ** extracts the object files. It should be compatible with MakeOBJ by John 34 | ** Romero except where we calculate the checksum correctly. 35 | ** 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #pragma pack(1) 45 | typedef struct 46 | { 47 | unsigned char type; 48 | unsigned short len; 49 | } SegHeader; 50 | 51 | typedef struct 52 | { 53 | unsigned short len; 54 | unsigned char name; 55 | unsigned char classname; 56 | unsigned char overlayname; 57 | } SegDef; 58 | #pragma pack() 59 | 60 | const char* ReadFile(const char* fn, int *size) 61 | { 62 | char* out; 63 | 64 | FILE* f = fopen(fn, "rb"); 65 | fseek(f, 0, SEEK_END); 66 | *size = ftell(f); 67 | out = (char*)malloc(*size); 68 | fseek(f, 0, SEEK_SET); 69 | 70 | fread(out, *size, 1, f); 71 | 72 | fclose(f); 73 | 74 | return out; 75 | } 76 | 77 | void WriteFile(const char* fn, const char *data, int size) 78 | { 79 | FILE* f = fopen(fn, "wb"); 80 | fwrite(data, size, 1, f); 81 | fclose(f); 82 | } 83 | 84 | void Extract(const char* infn) 85 | { 86 | const char* in; 87 | const char* start; 88 | const char* p; 89 | char outfn[16]; 90 | char str[256]; 91 | char *outdata; 92 | int outsize; 93 | int insize; 94 | SegHeader head; 95 | 96 | outdata = NULL; 97 | 98 | start = in = ReadFile(infn, &insize); 99 | 100 | while(in < start + insize) 101 | { 102 | head = *(SegHeader*)in; 103 | 104 | switch(head.type) 105 | { 106 | case 0x80: /* THEADR */ 107 | memcpy(outfn, in+4, in[3]); 108 | outfn[in[3]] = 0; 109 | printf("Output: %s\n", outfn); 110 | { 111 | int i; 112 | for(i = 0;i < 16;++i) 113 | { 114 | if(outfn[i] == ' ') 115 | outfn[i] = 0; 116 | } 117 | } 118 | break; 119 | case 0x88: /* COMENT */ 120 | switch(in[3]) 121 | { 122 | case 0: 123 | memcpy(str, in+5, head.len-2); 124 | str[head.len-3] = 0; 125 | printf("Comment: %s\n", str); 126 | break; 127 | default: 128 | printf("Unknown comment type %X @ %x ignored.\n", (unsigned char)in[3], (unsigned int)(in - start)); 129 | break; 130 | } 131 | break; 132 | case 0x96: /* LNAMES */ 133 | p = in+3; 134 | while(p < in+head.len+2) 135 | { 136 | memcpy(str, p+1, (unsigned char)*p); 137 | str[(unsigned char)*p] = 0; 138 | printf("Name: %s\n", str); 139 | 140 | p += (unsigned char)*p+1; 141 | } 142 | break; 143 | case 0x98: /* SEGDEF */ 144 | { 145 | SegDef *sd; 146 | 147 | sd = *(in+3) ? (SegDef*)(in+4) : (SegDef*)(in+7); 148 | printf("Segment Length: %d\n", sd->len); 149 | 150 | outdata = (char*)malloc(sd->len); 151 | outsize = sd->len; 152 | break; 153 | } 154 | case 0x90: /* PUBDEF */ 155 | p = in+5; 156 | if(in[5] == 0) 157 | p += 2; 158 | while(p < in+head.len+2) 159 | { 160 | memcpy(str, p+1, (unsigned char)*p); 161 | str[(unsigned char)*p] = 0; 162 | printf("Public Name: %s\n", str); 163 | 164 | p += (unsigned char)*p+4; 165 | } 166 | break; 167 | case 0xA0: /* LEDATA */ 168 | printf("Writing data at %d (%d)\n", *(unsigned short*)(in+4), head.len-4); 169 | memcpy(outdata+*(unsigned short*)(in+4), in+6, head.len-4); 170 | break; 171 | case 0x8A: /* MODEND */ 172 | /* Ignore */ 173 | break; 174 | default: 175 | printf("Unknown header type %X @ %x ignored.\n", head.type, (unsigned int)(in - start)); 176 | break; 177 | } 178 | 179 | in += 3 + head.len; 180 | } 181 | 182 | WriteFile(outfn, outdata, outsize); 183 | 184 | free((char*)start); 185 | free(outdata); 186 | } 187 | 188 | void CheckSum(char *s, unsigned short len) 189 | { 190 | int sum; 191 | 192 | len += 3; 193 | 194 | sum = 0; 195 | while(len > 1) 196 | { 197 | sum += *(unsigned char*)s; 198 | ++s; 199 | --len; 200 | } 201 | *s = (unsigned char)(0x100-(sum&0xFF)); 202 | } 203 | 204 | void MakeDataObj(const char* infn, const char* outfn, const char* segname, const char* symname, int altmode) 205 | { 206 | #define Flush() fwrite(d.buf, d.head.len+3, 1, f) 207 | union 208 | { 209 | char buf[4096]; 210 | SegHeader head; 211 | } d; 212 | int i; 213 | FILE *f; 214 | int insize; 215 | const char *in; 216 | const char *infn_stripped = strrchr(infn, '/'); 217 | if(strrchr(infn, '\\') > infn_stripped) 218 | infn_stripped = strrchr(infn, '\\'); 219 | if(infn_stripped == NULL) 220 | infn_stripped = infn; 221 | else 222 | ++infn_stripped; 223 | 224 | f = fopen(outfn, "wb"); 225 | 226 | in = ReadFile(infn, &insize); 227 | 228 | d.head.type = 0x80; 229 | d.head.len = 14; 230 | d.buf[3] = 12; 231 | if(d.buf[3] > 12) 232 | d.buf[3] = 12; 233 | sprintf(&d.buf[4], "%-12s", infn_stripped); 234 | for(i = 0;i < strlen(infn_stripped) && i < 12;++i) 235 | d.buf[4+i] = toupper(d.buf[4+i]); 236 | /* CheckSum(d.buf, d.head.len); */ 237 | d.buf[17] = 0; /* For some reason this one isn't checksummed by MakeOBJ */ 238 | Flush(); 239 | 240 | d.head.type = 0x88; 241 | d.head.len = 15; 242 | d.buf[3] = 0; 243 | d.buf[4] = 0; 244 | /* We're not really MakeOBJ v1.1, but to allow us to verify with md5sums */ 245 | memcpy(&d.buf[5], "MakeOBJ v1.1", 12); 246 | CheckSum(d.buf, d.head.len); 247 | Flush(); 248 | 249 | d.head.type = 0x96; 250 | d.head.len = strlen(infn_stripped)+40; 251 | d.buf[3] = 6; 252 | memcpy(&d.buf[4], "DGROUP", 6); 253 | d.buf[10] = 5; 254 | memcpy(&d.buf[11], "_DATA", 5); 255 | d.buf[16] = 4; 256 | memcpy(&d.buf[17], "DATA", 4); 257 | d.buf[21] = 0; 258 | d.buf[22] = 5; 259 | memcpy(&d.buf[23], "_TEXT", 5); 260 | d.buf[28] = 4; 261 | memcpy(&d.buf[29], "CODE", 4); 262 | d.buf[33] = 8; 263 | memcpy(&d.buf[34], "FAR_DATA", 8); 264 | if(!segname) 265 | { 266 | if(!altmode) 267 | { 268 | d.buf[42] = strlen(infn_stripped)-1; 269 | for(i = 0;i < strlen(infn_stripped)-4;++i) 270 | { 271 | if(i == 0) 272 | d.buf[43] = toupper(infn_stripped[0]); 273 | else 274 | d.buf[43+i] = tolower(infn_stripped[i]); 275 | } 276 | memcpy(&d.buf[43+i], "Seg", 3); 277 | } 278 | else 279 | { 280 | d.head.len = 40; 281 | } 282 | } 283 | else 284 | { 285 | d.head.len = strlen(segname)+41; 286 | d.buf[42] = strlen(segname); 287 | strcpy(&d.buf[43], segname); 288 | } 289 | CheckSum(d.buf, d.head.len); 290 | Flush(); 291 | 292 | d.head.type = 0x98; 293 | d.head.len = 7; 294 | *(unsigned short*)(d.buf+4) = insize; 295 | if(altmode == 0) 296 | { 297 | d.buf[3] = (char)((unsigned char)0x60); 298 | d.buf[6] = 8; 299 | d.buf[7] = 7; 300 | d.buf[8] = 4; 301 | } 302 | else 303 | { 304 | d.buf[3] = (char)((unsigned char)0x48); 305 | d.buf[6] = 2; 306 | d.buf[7] = 3; 307 | d.buf[8] = 4; 308 | } 309 | CheckSum(d.buf, d.head.len); 310 | Flush(); 311 | 312 | if(altmode) 313 | { 314 | d.head.type = 0x9A; 315 | d.head.len = 4; 316 | d.buf[3] = 1; 317 | d.buf[4] = (char)((unsigned char)0xFF); 318 | d.buf[5] = 1; 319 | CheckSum(d.buf, d.head.len); 320 | Flush(); 321 | } 322 | 323 | d.head.type = 0x90; 324 | d.head.len = strlen(infn_stripped)+4; 325 | d.buf[3] = 1; 326 | d.buf[4] = 1; 327 | if(!symname) 328 | { 329 | d.buf[5] = strlen(infn_stripped)-3; 330 | d.buf[6] = '_'; 331 | for(i = 0;i < strlen(infn_stripped)-4;++i) 332 | d.buf[7+i] = tolower(infn_stripped[i]); 333 | } 334 | else 335 | { 336 | d.head.len = strlen(symname)+7; 337 | d.buf[5] = strlen(symname); 338 | strcpy(&d.buf[6], symname); 339 | i = strlen(symname)-1; 340 | } 341 | d.buf[7+i] = 0; 342 | d.buf[8+i] = 0; 343 | d.buf[9+i] = 0; 344 | /* This checksum is calculated wrong in MakeOBJ, although I don't know in what way. */ 345 | CheckSum(d.buf, d.head.len); 346 | Flush(); 347 | 348 | #define LEDATA_LEN 1024 349 | for(i = 0;i < insize;i += LEDATA_LEN) 350 | { 351 | d.head.type = 0xA0; 352 | d.head.len = insize - i > LEDATA_LEN ? LEDATA_LEN+4 : insize - i + 4; 353 | d.buf[3] = 1; 354 | *(unsigned short*)(d.buf+4) = i; 355 | memcpy(&d.buf[6], &in[i], d.head.len-4); 356 | CheckSum(d.buf, d.head.len); 357 | Flush(); 358 | } 359 | 360 | d.head.type = 0x8A; 361 | d.head.len = 2; 362 | d.buf[3] = 0; 363 | d.buf[4] = 0; 364 | CheckSum(d.buf, d.head.len); 365 | Flush(); 366 | 367 | fclose(f); 368 | free((char*)in); 369 | } 370 | 371 | void DumpData(const char* infn, const char* outfn, int skip) 372 | { 373 | FILE *f; 374 | int i; 375 | int insize; 376 | char symname[9]; 377 | const char *in; 378 | const char *infn_stripped = strrchr(infn, '/'); 379 | if(strrchr(infn, '\\') > infn_stripped) 380 | infn_stripped = strrchr(infn, '\\'); 381 | if(infn_stripped == NULL) 382 | infn_stripped = infn; 383 | else 384 | ++infn_stripped; 385 | 386 | f = fopen(outfn, "wb"); 387 | 388 | memset(symname, 0, 9); 389 | memcpy(symname, infn_stripped, strlen(infn_stripped)-4); 390 | fprintf(f, "char far %s[] ={\r\n", symname); 391 | 392 | in = ReadFile(infn, &insize); 393 | 394 | for(i = skip;i < insize;++i) 395 | { 396 | fprintf(f, "%d", (unsigned char)in[i]); 397 | if(i != insize-1) 398 | fprintf(f, ",\r\n"); 399 | } 400 | fprintf(f, " };\r\n"); 401 | 402 | fclose(f); 403 | free((char*)in); 404 | } 405 | 406 | int main(int argc, char* argv[]) 407 | { 408 | if(argc < 3) 409 | { 410 | printf("Converts file to OMF.\nUseage:\n ./makeobj [fx] ...\n"); 411 | return 0; 412 | } 413 | 414 | switch(argv[1][0]) 415 | { 416 | case 'c': 417 | if(argc < 4) 418 | { 419 | printf("Need an output location. (Extra parms: [])\n"); 420 | return 0; 421 | } 422 | else 423 | { 424 | const char *symname = NULL; 425 | if(argc >= 5) 426 | symname = argv[4]; 427 | MakeDataObj(argv[2], argv[3], NULL, symname, 1); 428 | } 429 | break; 430 | default: 431 | case 'f': 432 | if(argc < 4) 433 | { 434 | printf("Need an output location. (Extra parms: [ ])\n"); 435 | return 0; 436 | } 437 | else 438 | { 439 | const char *segname = NULL, *symname = NULL; 440 | if(argc >= 6) 441 | { 442 | segname = argv[4]; 443 | symname = argv[5]; 444 | } 445 | MakeDataObj(argv[2], argv[3], segname, symname, 0); 446 | } 447 | break; 448 | case 'x': 449 | Extract(argv[2]); 450 | break; 451 | case 's': 452 | if(argc < 4) 453 | { 454 | printf("Need an output location. (Extra parms: [])\n"); 455 | return 0; 456 | } 457 | else 458 | { 459 | int skip = 0; 460 | if(argc >= 5) 461 | { 462 | skip = atoi(argv[4]); 463 | } 464 | DumpData(argv[2], argv[3], skip); 465 | } 466 | break; 467 | break; 468 | } 469 | return 0; 470 | } 471 | -------------------------------------------------------------------------------- /KEEN4C.BAT: -------------------------------------------------------------------------------- 1 | SET PATH=C:\BC30\BIN;%PATH% 2 | cd KEEN4-6 3 | BC KEEN4C.PRJ 4 | cd .. -------------------------------------------------------------------------------- /KEEN4E.BAT: -------------------------------------------------------------------------------- 1 | SET PATH=C:\BC30\BIN;%PATH% 2 | cd KEEN4-6 3 | BC KEEN4E.PRJ 4 | cd .. -------------------------------------------------------------------------------- /KEEN4M.BAT: -------------------------------------------------------------------------------- 1 | SET PATH=C:\BC30\BIN;%PATH% 2 | cd KEEN4-6 3 | BC KEEN4M.PRJ 4 | cd .. -------------------------------------------------------------------------------- /KEEN4T.BAT: -------------------------------------------------------------------------------- 1 | SET PATH=C:\BC30\BIN;%PATH% 2 | cd KEEN4-6 3 | BC KEEN4T.PRJ 4 | cd .. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Commander Keen 4 Tandy 320x200 16 color source code port 2 | ![Commander Keen 4 Tandy 320x200 16 color source code port](keen4t.png?raw=true) 3 | 4 | Download the game [here](https://github.com/FrenkelS/keensource456tandy/releases). 5 | 6 | This is a Tandy 320x200 16 color version of Commander Keen 4. 7 | It includes Tandy music. 8 | There's also a version for MCGA with smooth palette fading. 9 | And EGA and CGA versions that feature the same Tandy music. 10 | The EGA version also has smooth palette fading when a VGA card is detected. 11 | 12 | If the graphics get corrupted in the Tandy version while playing one or two levels, like in [this video](https://youtu.be/zyuhOdDRiHk?t=6211), 13 | you don't have enough video memory allocated. This version of the game needs 32k of video memory. 14 | The amount of video memory can be changed in the BIOS. 15 | It can also be altered by using [ADJMEM](https://www.classicdosgames.com/tutorials/grafix/chapter4.html). 16 | Before running `KEEN4T.EXE`, run `ADJMEM -16` to increase the amount of video memory by 16k. 17 | There's always at least 16k of video memory allocated, so increasing it by 16k gives you the required amount of 32k of video memory. 18 | 19 | The score box is disabled by default. The game runs faster this way. 20 | Pressing Backspace enables the score box. 21 | 22 | If you can create executables that are byte for byte 100% identical 23 | to the Keen 4 v1.4 EGA and CGA executables with K1n9_Duk3's reconstructed Commander Keen 4-6 source code, you can probably also compile this code. 24 | 25 | ## Special Thanks 26 | * [id Software](https://idsoftware.com) for creating Commander Keen. 27 | 28 | * [K1n9_Duk3](https://k1n9duk3.shikadi.net) for reconstructing the original Keen 4-6 source code. 29 | 30 | * [Einar Saukas](https://github.com/einar-saukas) and [Emmanuel Marty](https://github.com/emmanuel-marty) for [ZX0](https://github.com/emmanuel-marty/unzx0_x86). 31 | I had to replace the original Huffman compression with something that produces smaller files, otherwise the game wouldn't fit on a 720 kB floppy disk. 32 | 33 | * [ModdingWiki](https://moddingwiki.shikadi.net) for information about the Commander Keen file formats. -------------------------------------------------------------------------------- /cleanup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del KEEN4-6\KEEN4\OBJ\*.obj 3 | del KEEN4-6\KEEN4C\OBJ\*.obj 4 | del KEEN4-6\KEEN4M\OBJ\*.obj 5 | del KEEN4-6\KEEN4T\OBJ\*.obj 6 | -------------------------------------------------------------------------------- /keen4t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/keen4t.png -------------------------------------------------------------------------------- /music/KICKPANT.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/KICKPANT.TND -------------------------------------------------------------------------------- /music/OASIS.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/OASIS.TND -------------------------------------------------------------------------------- /music/SHADOWS.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/SHADOWS.TND -------------------------------------------------------------------------------- /music/TOOHOT.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/TOOHOT.TND -------------------------------------------------------------------------------- /music/VEGGIES.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/VEGGIES.TND -------------------------------------------------------------------------------- /music/WONDER.TND: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrenkelS/keensource456tandy/0d4c5a5ed3d228b967e9ae1f2e02fdabd80af22a/music/WONDER.TND --------------------------------------------------------------------------------