-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
There are a number of bugfixes (and one subtle new feature) in v1.0b: - Spaceship parts are no longer lost if Keen dies in the level they were originally found in. This required a slightly more complicated patch, as multiple spaceship parts could be found in the same level. - Yorp statue messages about level locations are no-longer backwards. - The RNDKEEN1.BAT file now uses MS-DOS line endings, so will work on real MS-DOS machines. (DOSBox handled the UNIX newlines fine.) - The in-game random number generator is now seeded with a value derived from the randomiser seed. (This means that enemy behaviour, et al, is technically deterministic with the same seed now, but probably won't cause any player-visible changes.)
- Loading branch information
Showing
3 changed files
with
54 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ Commander Keen 1 Randomiser | |
=========================== | ||
|
||
Author: David Gow <[email protected]> | ||
Version: 1.0a | ||
Version: 1.0b | ||
Website: https://davidgow.net/keen/randomiser.html | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
@ECHO OFF | ||
COPY LEVEL81.CK1 RNDLV81.CK1 | ||
COPY LEVEL90.CK1 RNDLV90.CK1 | ||
RANDKEEN %1 %2 %3 %4 %5 %6 %7 %8 %9 | ||
CK1PATCH RNDKEEN1.PAT | ||
@ECHO OFF | ||
COPY LEVEL81.CK1 RNDLV81.CK1 | ||
COPY LEVEL90.CK1 RNDLV90.CK1 | ||
RANDKEEN %1 %2 %3 %4 %5 %6 %7 %8 %9 | ||
CK1PATCH RNDKEEN1.PAT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -557,6 +557,36 @@ void WriteMapHintToPatch(FILE *f, int oldMap, int newMap) | |
fprintf(f, "Level %d\nrests where\nlevel %d once\nwas...\n\n", newMap, oldMap); | ||
} | ||
|
||
void WritePerItemPatch(FILE *f, int level, int item) | ||
{ | ||
static int curPatchItem = 0; | ||
uint16_t offset = 0x4F68 + 11 * curPatchItem; | ||
if (item != K1_T_JOYSTICK && | ||
item != K1_T_BATTERY && | ||
item != K1_T_VACUUM && | ||
item != K1_T_EVERCLEAR) | ||
return; | ||
// Make sure we don't remove the spaceship parts from the | ||
// wrong levels. | ||
// cmp ax, (level) | ||
fprintf(f, "%%patch $%04X\t$3D $%04XW\n", offset, level); | ||
// jnz +6 | ||
fprintf(f, "\t\t$75 $06\n"); | ||
// mov (GameState.got_item), 0 | ||
if (item == K1_T_JOYSTICK) | ||
fprintf(f, "\t\t$C7 $06 $AA94W $0000W\n", level); | ||
else if (item == K1_T_BATTERY) | ||
fprintf(f, "\t\t$C7 $06 $AA9CW $0000W\n", level); | ||
else if (item == K1_T_VACUUM) | ||
fprintf(f, "\t\t$C7 $06 $AA94W $0000W\n", level); | ||
else if (item == K1_T_EVERCLEAR) | ||
fprintf(f, "\t\t$C7 $06 $AA94W $0000W\n", level); | ||
|
||
uint8_t end_off = 0x4FA0 - (offset + 13); | ||
fprintf(f, "\t\t$EB $%02x\n\n", end_off); | ||
curPatchItem++; | ||
} | ||
|
||
void WritePatchHeader(FILE *f) | ||
{ | ||
fprintf(f, "%%ext ck1\n"); | ||
|
@@ -571,6 +601,15 @@ void WritePatchHeader(FILE *f) | |
fprintf(f, "%%patch $0FA7\t$B8 $%04XW\n", (opt_seed >> 16) & 0xFFFF); | ||
fprintf(f, "\t\t$BA $%04XW\n", opt_seed & 0xFFFF); | ||
fprintf(f, "\t\t$90 $90 $90 $90 $90 $90\n\n"); | ||
|
||
// Base the game's random number seed off ours. | ||
uint8_t randomIndexByte = ((opt_seed >> 24) ^ (opt_seed >> 16) ^ (opt_seed >> 8) ^ opt_seed) & 0xFF; | ||
// push ax | ||
// mov ax, $00<seed> | ||
// mov [randomIndex], ax | ||
// pop ax | ||
// ret | ||
fprintf(f, "%%patch $C0AC $50 $B8 $%02X $00 $A1 $57 $51 $58 $C3\n\n"); | ||
|
||
if (opt_startPogo) | ||
fprintf(f, "%%patch $900E $01\n\n"); | ||
|
@@ -587,7 +626,7 @@ void WritePatchFooter(FILE *f) | |
void PrintBanner() | ||
{ | ||
printf("Keen 1 Randomiser\n"); | ||
printf("\tv1.00a\n"); | ||
printf("\tv1.00b\n"); | ||
printf("\tBy David Gow <[email protected]>\n\n"); | ||
} | ||
|
||
|
@@ -695,15 +734,18 @@ int main(int argc, char **argv) | |
K1_ShuffleEnemies(&vm); | ||
while (slotsPerLevel[level-1]--) | ||
{ | ||
int item = itemsPerSlot[curItemSlot]; | ||
// If we have the pogo at the start, or we have extra pogosticks, | ||
// don't generate hints for pogo stick locations. | ||
if (!(opt_startPogo || opt_extraPogo) || (itemsPerSlot[curItemSlot] != K1_T_POGOSTICK)) | ||
if (!(opt_startPogo || opt_extraPogo) || (item != K1_T_POGOSTICK)) | ||
{ | ||
WriteTileHintToPatch(patchFile, itemsPerSlot[curItemSlot], level); | ||
if (itemsPerSlot[curItemSlot] != K1_T_GREYSKY) | ||
WriteMapHintToPatch(patchFile, level, mapLocations[level-1]); | ||
WriteTileHintToPatch(patchFile, item, level); | ||
if (item != K1_T_GREYSKY) | ||
WriteMapHintToPatch(patchFile, mapLocations[level-1], level); | ||
} | ||
K1_SetSpecialItem(&vm, itemsPerSlot[curItemSlot++], slotsPerLevel[level-1]); | ||
K1_SetSpecialItem(&vm, item, slotsPerLevel[level-1]); | ||
WritePerItemPatch(patchFile, level, item); | ||
curItemSlot++; | ||
} | ||
sprintf(fname, "RNDLV%02d.CK1", level); | ||
f = fopen(fname, "wb"); | ||
|