C64 BTII: FILE0278460.PRG (CHAR DISK)
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
No problem.
Maybe it was done like I did in the attached file. I have decoded the combat engine and packed it back in the d64 file and added a file name 'combat'. Track 18 is very empty, so there is a lot of space for file names.
Now you have the disassembled combat engine and can go on to investigate the code.
Good luck!
Maybe it was done like I did in the attached file. I have decoded the combat engine and packed it back in the d64 file and added a file name 'combat'. Track 18 is very empty, so there is a lot of space for file names.
Now you have the disassembled combat engine and can go on to investigate the code.
Good luck!
- Attachments
-
- Bard's Tale II (Character Disk)_combat.rar
- (81.53 KiB) Downloaded 519 times
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
...
You know how I feel right now? I feel like I'm in 5th grade all over again, and I'm working hard on learning my multiplication tables...and here comes some guy in grade 8 and peers over my shoulder and says, "here let me help you with that", swipes my homework, and does it for me in 10 minutes, then hands it back to me and goes, "here ya go, hope you learned something", and then walks away.
That is more or less how I feel. Way to conpletely deflate me.
You know how I feel right now? I feel like I'm in 5th grade all over again, and I'm working hard on learning my multiplication tables...and here comes some guy in grade 8 and peers over my shoulder and says, "here let me help you with that", swipes my homework, and does it for me in 10 minutes, then hands it back to me and goes, "here ya go, hope you learned something", and then walks away.
That is more or less how I feel. Way to conpletely deflate me.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
Oh, sorry! That wasn't my intention. Just wanted to speed up the analysis of the combat engine. It will be faster analysed when two work on it.
And I didn't need 10min but some hours to build that file.
And I didn't need 10min but some hours to build that file.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
It's fine, I'll get over it.
I think I mentioned at some point or another that I want to write a 'construction set' for the BTII game engine. That's kind of my whole motivation for doing this.
I think I mentioned at some point or another that I want to write a 'construction set' for the BTII game engine. That's kind of my whole motivation for doing this.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
Battle pseudocode from the DOS version. The functions seem to be pretty similar between the C64/Apple versions and the DOS version so this might help a little.
Code: Select all
battle_init(){
saveActiveSongFlag;
saveActiveSongNumber;
// Initialize battle variables
songMissileDamageFlag = 0;
antiMagicBonus = 0;
partySongDamageBonus = 0;
partySongToHitBonus = 0;
songHealHp = 0;
party_extraAttacks = 0;
party_acBonus = 0;
// Convert song effects to battle effects
if (song is active) {
switch (activeSongNumber) {
case ArchersTune:
songMissileDamageFlag = 1;
case SpellSong:
antiMagicBonus = songBonus[dungeonLevel]
case MeleeMarch:
partySongDamageBonus = songBonus[dungeonLevel];
partySongToHitBonus = songBonus[dungeonLevel];
case ZanduvarCarack:
songHealHp = songBonus[dungeonLevel];
case RhymeOfDuotime:
party_extraAttacks = 1;
}
}
deactivateSong();
getOpponents();
printEncounter();
do {
updatePicture();
getPlayerOptions();
if (partyRan) {
// Not a function call. This code is inline and can be called from a few different places
// and I didn't want to clutter things up
cleanupAndReturn();
}
getTurnPriorities();
// Advance party
if (partyAdvances) {
foreach monsterGroup {
monsterGroup.distance--
if (monsterGroup.distance <= 1) {
monsterGroup.distance = 1
}
}
// Battle round loop
for (priority == 0xff; priority != 0; priority--) {
// Only check character actions when party is not advancing
if (!partyAdvances) {
foreach character {
characterTurn();
if (partyDied) {
return -1;
}
}
}
foreach monsterGroup {
foreach monster in group {
if (monster.priority == priority) {
monsterTurn();
if (partyDied) {
return -1;
}
}
}
}
}
partyDisbelieves();
if (partyDied) {
return -1;
}
if (monsterDisbelieveFlag) {
foreach character {
if character.isIllusion {
if savingThrow().Fails {
Print "Your foes see through your illusion"
// Interestingly, in the DOS version, nothing happens other than the message is printed
}
}
}
}
// Do post-round effects
doPoisonEffect();
doEquipmentEffects();
if (songHealHp != 0) {
foreach character {
if player.isNotDisabled {
character.Hp += songHealHp
if character.Hp > character.MaxHp {
character.Hp = character.MaxHp
}
}
}
postRoundCleanup();
// The logic around continuing is very convoluted. This is the best representation
// I can do.
if monsterGroups.AreEmpty() {
if party_active() {
if partyAttack {
Print "Do you wish to continue?"
getYesNo();
if (No) {
cleanupAndReturn();
}
}
}
}
}
}
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
Hi drifting, do you analyze the 8-bit version of the game too, or just the DOS version?
It seems that the DOS version is coded radically different, but then we know that the port from the 8-bit system wasn't all that spectacular.
Still, everything helps.
It seems that the DOS version is coded radically different, but then we know that the port from the 8-bit system wasn't all that spectacular.
Still, everything helps.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
I've done a bit with the 8 bit version. Mainly to fix the trap bug.
Coded radically different? Of course. They're completely different architectures. But they used mostly the same game logic between the ports. For example, the "monster to hit" code from Weber G's post viewtopic.php?p=7566#p7566. The DOS code is completely different but the logic is the same. The logic for the first bit of the BT2 function is this:
Code: Select all
Get character AC
Add target monster group's FEAR penalty to AC
If AC is greater than 1Fh then
set AC to 1Fh
Get monster ToHit value
Add a random amount
Add a monster group spell penalty
If monster ToHit is greater than AC then
Hit
The 1 & 2 ports were fine. Especially the Amiga version. BT3 was criminally bad.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
drifting wrote: ↑Fri Jan 08, 2021 3:08 amI've done a bit with the 8 bit version. Mainly to fix the trap bug.
Coded radically different? Of course. They're completely different architectures. But they used mostly the same game logic between the ports. For example, the "monster to hit" code from Weber G's post viewtopic.php?p=7566#p7566. The DOS code is completely different but the logic is the same. The logic for the first bit of the BT2 function is this:The DOS code follows the same logic. Knowing the logic ahead of time could make it easier to figure out.Code: Select all
Get character AC Add target monster group's FEAR penalty to AC If AC is greater than 1Fh then set AC to 1Fh Get monster ToHit value Add a random amount Add a monster group spell penalty If monster ToHit is greater than AC then Hit
The 1 & 2 ports were fine. Especially the Amiga version. BT3 was criminally bad.
So the line "If AC is greater than 1Fh then - set AC to 1Fh" is the logic for preventing AC from getting any better than L+, I presume?
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
So I encountered a curiousity here.
Consider:
Observe 825b to 8262; it looks to be a data field or table or somesuch in the middle of the executable code. Is this normal?
Consider:
Code: Select all
824c 43 a9 LDA #$ff
824d 15 ff
824e 6f 85 STA $ac
824f 46 ac
8250 48 a2 LDX #$06
8251 ec 06
8252 43 a9 LDA #$02
8253 e8 02
8254 77 9d STA $0390,x
8255 7a 90
8256 e9 03
8257 20 ca DEX
8258 fa 10 BPL $fa
8259 10 fa
825a 8a 60 RTS
825b eb 01
825c eb 01
825d e8 02
825e e8 02
825f e8 02
8260 e9 03
8261 e9 03
8262 ee 04
8263 43 a9 LDA #$00
8264 ea 00
8265 6f 85 STA $f0
8266 a1 f0
8267 4f a5 LDA $e1
8268 0b e1
8269 3a d0 BNE $10
826a fa 10
826b 48 a2 LDX #$00
826c ea 00
826d ca 20 JSR $0902
826e e8 02
826f e3 09
8270 4a a0 LDY #$14
8271 fe 14
8272 5b b1 LDA ($67),y
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
drifting, you are completely right. The DOS version with its texts could help a lot, since the logic behind seems to be similar to the C64 version.
I'm always wondering what's stored in the zeropage $F6/ $EA. Now I know it:
first lines of the C64 combat engine (finally with the knowing of $F6/ $EA):
Darendor, yes, sometines there are data flieds between the code:
I'm always wondering what's stored in the zeropage $F6/ $EA. Now I know it:
first lines of the C64 combat engine (finally with the knowing of $F6/ $EA):
Code: Select all
.C:9000 4C 09 90 JMP $9009 ;bard not singing: $D404 = 0; $D40B = 0; bard singing (1): $D404 = 20; $D40B = 20; bard singing (3): $D404 = 41; $D40B = 41
.C:9003 4C DD 9E JMP $9EDD
.C:9006 4C 05 A4 JMP $A405
.C:9009 20 93 08 JSR $0893 ;initialise for random number creation
.C:900c A5 F6 LDA $F6 ;$F6 (bard is singing 0/1) => A
.C:900e 85 EA STA $EA ;A => $EA (bard is singing 0/1)
.C:9010 20 14 09 JSR $0914 ;clear $F6 $D404 $D40B
.C:9013 20 DC 95 JSR $95DC ;identify which monsters are attacking (#, hit point creation)
.C:9016 20 D3 A7 JSR $A7D3 ;sort monster groups by distance
.C:9019 20 A6 9C JSR $9CA6 ;text output which monsters attack (encounter text)
.C:901c A9 00 LDA #$00 ;0 => A
.C:901e 85 4D STA $4D ;A => $4D
.C:9020 E6 C1 INC $C1 ;increase $C1
Code: Select all
.C:4063 90 F1 BCC $4056 ;Y < B8 => jump
.C:4065 E6 FA INC $FA ;increase $FA
.C:4067 A6 FA LDX $FA ;$FA => X
.C:4069 E0 78 CPX #$78
.C:406b 90 BA BCC $4027 ;X < 78h => jump
.C:406d CE 76 40 DEC $4076 ;decrease ######$4076
.C:4070 A0 0D LDY #$0D ;0D => Y
.C:4072 20 5F 1D JSR $1D5F
.C:4075 A9 00 LDA #$00 ;######$401A => A/ $406D
.C:4077 D0 AA BNE $4023 ;A <> 0 => jump
.C:4079 60 RTS
########## $407A - $4099
>C:407a 01 01 01 01 01 01 01 01 01 01 02 02 04 04 08 08 ................
>C:408a 08 08 08 08 08 08 08 08 08 08 04 04 02 02 01 01 ................
##############################################################################
###################################################################
########## clear text window
###################################################################
.C:409a 8E D1 40 STX $40D1 ;X => ######$40D1
.C:409d 8C D3 40 STY $40D3 ;Y => ######$40D3
.C:40a0 A2 18 LDX #$18 ;18 => x
.C:40a2 BD 00 B6 LDA $B600,X ;B600,X => A
.C:40a5 18 CLC
.C:40a6 69 80 ADC #$80 ;add 80h to A
.C:40a8 8D B8 40 STA $40B8 ;A => ######$40B8
.C:40ab BD 00 B7 LDA $B700,X ;B700,X => A
.C:40ae 69 00 ADC #$00 ;add 0 to A
.C:40b0 8D B9 40 STA $40B9 ;A => ######$40B9
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
How did you guys figure out what the code does and why/where?
I'm just curious. I haven't yet finished deciphering the file entirely yet, and am just wondering what you all look for.
Like for instance, this:
How did you know that was about the bard singing, and what does the "bard singing (1) mean vs bard singing (3)"? 2 different songs?
I'm just curious. I haven't yet finished deciphering the file entirely yet, and am just wondering what you all look for.
Like for instance, this:
Code: Select all
.C:9000 4C 09 90 JMP $9009 ;bard not singing: $D404 = 0; $D40B = 0; bard singing (1): $D404 = 20; $D40B = 20; bard singing (3): $D404 = 41; $D40B = 41
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
Which tool do you use? You don't have to decipher the code. There are tool which can do this in seconds. I didn't know this bard singing variables. But after I have taken a look at the DOS code from drifting, I tried it => let the bard sing, set a break point and check the variables and also the memory. That's all.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
I'm not using any tool besides DirMaster and 2 copies of NotePad.
What do you think of this: https://c64preservation.com/files/EaLoader.txt
It's a documentation about Electronic Arts' loader back in the day.
What do you think of this: https://c64preservation.com/files/EaLoader.txt
It's a documentation about Electronic Arts' loader back in the day.
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
You will have no success if you only use DirMaster. Please use Vice!
These are two different things. The loader in your link is, as far as I can see in short, the autoloader which starts a game.
But to load from disk, BT2 has it's own 'loader' which loads from disk to the RAM.
The latter is of interest for us.
Here is the 'heart' of the loader (load modus):
As you can see, it loads directly from $DD00 (serial interface CIA) to the buffer $FB3E.
These are two different things. The loader in your link is, as far as I can see in short, the autoloader which starts a game.
But to load from disk, BT2 has it's own 'loader' which loads from disk to the RAM.
The latter is of interest for us.
Here is the 'heart' of the loader (load modus):
Code: Select all
.C:fd87 20 CC FD JSR $FDCC
.C:fd8a 2C 00 DD BIT $DD00
.C:fd8d 50 FB BVC $FD8A
.C:fd8f 38 SEC
.C:fd90 A6 02 LDX $02
.C:fd92 AD 12 D0 LDA $D012
.C:fd95 E9 32 SBC #$32 ######6
.C:fd97 90 04 BCC $FD9D
.C:fd99 29 07 AND #$07
.C:fd9b F0 F5 BEQ $FD92
.C:fd9d 8E 00 DD STX $DD00
.C:fda0 8A TXA
.C:fda1 09 20 ORA #$20
.C:fda3 AA TAX
.C:fda4 EA NOP
.C:fda5 EA NOP
.C:fda6 A9 FF LDA #$FF ######7 ######8
.C:fda8 AD 00 DD LDA $DD00
.C:fdab 4A LSR A
.C:fdac 4A LSR A
.C:fdad EA NOP
.C:fdae 4D 00 DD EOR $DD00
.C:fdb1 4A LSR A
.C:fdb2 4A LSR A
.C:fdb3 EA NOP
.C:fdb4 24 80 BIT $80 #######9 #######10
.C:fdb6 4D 00 DD EOR $DD00
.C:fdb9 4A LSR A
.C:fdba 4A LSR A
.C:fdbb 45 02 EOR $02
.C:fdbd 4D 00 DD EOR $DD00
.C:fdc0 8E 00 DD STX $DD00
.C:fdc3 49 FF EOR #$FF
.C:fdc5 99 3E FB STA $FB3E,Y
.C:fdc8 C8 INY
.C:fdc9 D0 C4 BNE $FD8F
.C:fdcb 60 RTS
Re: C64 BTII: FILE0278460.PRG (CHAR DISK)
Well, that's one place that prevents it. Really anywhere in the code where the AC is updated, the same code runs. So if you put on a piece of armor, the AC is recalculated and the same code is run.