News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Final Fantasy 1 Magic Upgrade Idea  (Read 16767 times)

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #60 on: June 01, 2017, 10:31:41 pm »
>.< When/Why did I add a second SEC? Weird...

How does this look?

Code: [Select]
    LDA ch_curhp, X     ; Load current HP low byte
    CLC
    ADC math_basedamage
    STA ch_curhp, X
    LDA ch_curhp+1, X
    ADC math_basedamage+1
    STA ch_curhp+1, X
    CMP ch_maxhp+1, X
    BCC @DrawRegenBoxes   
    LDA ch_curhp, X
    CMP ch_maxhp, X
    BCC @DrawRegenBoxes
    LDA ch_maxhp, X
    STA ch_curhp, X   
    LDA ch_maxhp+1, X           
    STA ch_curhp+1, X   

It seems to work... But now I'm 3 bytes over the limit. And I still didn't get to try to make it so that, if they don't NEED to regen health, it doesn't pop up the message. Which is something I should add to the enemy regen code, too...
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #61 on: June 02, 2017, 12:11:23 am »
That won't work.  You only compare the low bytes if the high bytes are exactly equal.  If the high bytes are not equal the low bytes need to be completely ignored.

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #62 on: June 03, 2017, 09:29:53 pm »
*sigh* Well, it's useless anyway, without extra space. So I'll put that on hold for a few weeks. I just wish I knew why I can't understand the necessary sequence. I keep thinking I get it, but soon as I "Get it" something else slips away.

Anyway... music is something I CAN focus on, so here's something I've been struggling with as well.

At the end of Music_DoScore...

@Code_F1_F2: I am fairly sure this should work... it works for @Code_Fx, right?

Code: [Select]
@Code_Fx:          ; here if $F0-F7, or $F9-FE
    CMP #$F9             ; if less than F9,
    BCC @Code_F0_F7      ; see if $F0-F7

      JSR Music_SetTempo       ; here if $F9-FE -- Tempo select
      JMP SkipMusicBit
      ;LDA #1
      ;JMP Music_DoScore_IncByA ; resume processing after incing by 1

  @Code_F0_F7:
CMP #$F0             ; if = $F0
BNE @Code_F1_F2      ; see if $F1 or $F2
  JSR Music_LoopCode2   ; this loop stuff works fine!
  JMP Music_DoScore   

    @Code_F1_F2:
CMP #$F3              ; if less than F3
BCC @Code_F3_F7
  JSR Music_Goto        ; it must be $F1-F2
        JMP Music_DoScore
     
  @Code_F3_F7:
    SkipMusicBit:
LDA #1 
JMP Music_DoScore_IncByA   ;  just skip over this byte and continue processing

The following code is based off what I thought would be a simple concept: to split a song's parts up, and basically do a JSR/RTS to them, which should save tons of space if a song has some repeated chords arranged in a loop-unfriendly way.

The way I decided to do this was to save a "return" point using the extra variables. F1 calls the code, F2 closes it. The return point is saved as the code right after the goto label following F1.

Code: [Select]
CONSTANTS:
CHAN_START        = $A0
CHAN_BYTES        = $14

VARIABLES:
ch_loop_marker = $10 ; works fine!
ch_return     = $11 ;+$12
ch_freespace  = $13 ;+$14? (or, since 00 counts as 1, is 14 the 00 of the next instrument?)

;DC to EF are empty for noise channel
     


Code: [Select]
Music_Goto:
    AND #$0F                ; get low bits
    ORA #$02                ; if 2 then goto the Return part
    BEQ @Return             ; otherwise its a 1, so use the following goto label to find the point in the song to start playing next--
   
    JSR @SaveReturnPoint    ; ...once we get the return point saved...
    JMP ResumeLoop          ; --which works the same way as resuming a loop! But is skipping to another spot entirely.   
       
    @Return:                ;
      LDA ch_return, X      ; load return pointers
      STA ch_scoreptr, X    ; save as channel and music pointers
      STA mu_scoreptr       ;
      LDA ch_return+1, X    ;
      STA ch_scoreptr+1, X  ;
      STA mu_scoreptr+1     ;
      JMP Music_DoScore     
   
    @SaveReturnPoint:
    LDY #3                  ; skip past the F1 code and the following GOTO label...
    LDA (mu_scoreptr), Y    ; get low byte of return-to address from the score
    STA ch_return, X        ; save as channel's return point (low)
    INY                     ; get the high byte
    LDA (mu_scoreptr), Y    ;
    STA ch_return+1, X      ; save as channel's return point (high)
    RTS                           

 ResumeLoop:
    LDY #1
    LDA (mu_scoreptr), Y    ; to resume the loop, get low byte of loop address from the score
    STA ch_scoreptr, X      ; record that as the new score pointer for the channel
    STA tmp                 ; store in tmp (don't change mu_scoreptr yet because we still need it
    INY                     ; to get the high byte)
    LDA (mu_scoreptr), Y
    STA ch_scoreptr+1, X    ; get high byte
    STA mu_scoreptr+1
    LDA tmp
    STA mu_scoreptr         ; then set low byte of mu_scoreptr previously tmp'd
    RTS                     ; channel is now pointing to loop address -- exit

An Alternate @SaveReturnPoint attempt, based off skipping a loop...
    @SaveReturnPoint:      
    LDA ch_scoreptr, X
    CLC
    ADC #3
    STA ch_return, X   
    LDA ch_scoreptr+1, X 
    ADC #0
    STA ch_return+1, X
    RTS

And the song I've been testing with... Triangle channel.

Code: [Select]
OVERWORLD3:
   .BYTE $F9 ; tempo ; does a triangle channel need an $F8 envelope speed command? (original game code seems to use them...)
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2_ALT
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2_ALT
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2
   .BYTE $D0
   .WORD OVERWORLD3
   
   OVERWORLD3_1:
   .BYTE $D9,$08,$48,$98,$48,$68,$98,$DA,$28,$D9,$98,$78,$B8,$DA,$48,$D9,$B8,$48,$78,$B8,$78
   .BYTE $08,$48,$78,$48,$28,$68,$B8,$68,$48,$78,$B8,$78,$DB,$B8,$D9,$28,$68,$28
   .BYTE $08,$48,$98,$48,$68,$98,$DA,$28,$D9,$98,$78,$B8,$DA,$48,$D9,$B8,$48,$78,$B8,$78
   .BYTE $F2
   OVERWORLD3_2:
   .BYTE $D9,$08,$48,$78,$48,$28,$68,$B8,$68,$48,$78,$B8,$78,$B4,$F2
   OVERWORLD3_2_ALT:
   .BYTE D9,$08,$48,$78,$48,$28,$68,$B8,$68,$48,$78,$B8,$78,$48,$B8,$DA,$48,$D9,$B8,$F2
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #63 on: June 03, 2017, 11:10:05 pm »
I just wish I knew why I can't understand the necessary sequence. I keep thinking I get it, but soon as I "Get it" something else slips away.

Yeah it can be frustrating.  Taking a break and moving to something else is probably a good idea.  Just don't get discouraged!!  =)

Quote
    @Code_F1_F2:
   CMP #$F3              ; if less than F3
   BCC @Code_F3_F7
     JSR Music_Goto        ; it must be $F1-F2
           JMP Music_DoScore
         
         
That all looks good.  Music_Goto will be called iff the byte is F1 or F2.

Quote
ch_freespace  = $13 ;+$14? (or, since 00 counts as 1, is 14 the 00 of the next instrument?)

$14 is the 0 of the next instrument.

With zero-based indexes, the length is 1 higher than the last index.  IE:  if you have a length of '5', that means your 5 elements are 0,1,2,3,4.

Quote
Music_Goto:
    AND #$0F                ; get low bits
    ORA #$02                ; if 2 then goto the Return part
You don't want ORA here.  Did you mean to AND with 2?  Because that would make more sense.  Also, if you're ANDing with 2, you don't need to AND with F.

Quote
    @Return:                ;
    ...
This code all looks fine.  It's just not running now because that ORA will never set the Z flag so you're never branching.


Quote
    @SaveReturnPoint:      
    LDY #3                  ; skip past the F1 code and the following GOTO label...
    LDA (mu_scoreptr), Y    ; get low byte of return-to address from the score

That LDA is not getting the low byte of the address -- it's getting the byte AT that address.

Your 'Alternaive' @SaveReturnPoint attempt is correct.

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #64 on: June 04, 2017, 12:37:34 am »
ACK! No ORA! That was a stupid "try something different" I did when nothing else was working (I know, I know! Bad...) I meant to turn it back into a CMP before I posted. AND $0F, CMP $02...

So, using the CMP $02 and the alternate @SaveReturnPoint ... why is it still wigging out?

I got it narrowed down to the fact that its every second musical note after a return that doesn't play.

Code: [Select]
   OVERWORLD3_1:
   .BYTE $D9,$06,$46,$96,$46,$66,$96,$DA,$26,$D9,$96,$76,$B6,$DA,$46,$D9,$B6,$46,$76,$B6,$76
   ;;;;;;;;;;;;;;;^^
   .BYTE $F0
   .WORD OVERWORLD3_1_END
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$D8,$B6,$D9,$26,$66,$26
   .BYTE $D1
   .WORD OVERWORLD3_1
   OVERWORLD3_1_END:
   .BYTE $F2
   OVERWORLD3_2:
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$B2,$F2
   ;;;;;;;;;;;^^
   OVERWORLD3_2_ALT:
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$46,$B6,$DA,$46,$D9,$B6,$F2
   ;;;;;;;;;;;^^

Those poor $46s... And it does only AFTER the first time the song starts playing, and it has nothing to do with my $F0 loop in there. Otherwise, the code works perfectly now!

Meanwhile I've been poking at some other things. I turned the annoying poison SFX into a noise channel "pfft" sound! Will that conflict if they walk on a damage tile, though? I also did... something to the Menu Error sound (trying to equip something you can't) and have accidentally made some fun randomization. But SQ2 still plays a beep. My goal with the SFX is to use the noise channel as much as possible, so its not turning off the music channel.

I was going to try to make the menu music disappear and keep playing the map's music, but without assembly, that hack is... scary. So I just disabled music in the party-line up screen; I always want a way to pause AND silence a game if I need to.
« Last Edit: June 14, 2017, 07:43:39 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #65 on: June 14, 2017, 08:17:17 pm »
I made lots and lots of space in Bank F to play with! I need a bit of help with this code, now...

I made it so most classes get a neat little thing they do when they land a critical hit. Bards will SLOW an enemy, Barbarians will STUN, Moon mages will CONFUSE, and Warrior mages add +4 to their own strength, since they start out puny like Black mages do. And Thieves will steal the amount of gold they dealt in damage.

I haven't tested the bard's code yet, but the Moon mage's CONFUSE ability is messing up. I got it working fine once, but if it tries to apply itself a second time, game freezes. This evil little thing here...

Code: [Select]
OnIRQ:                   ; IRQs point here, but the game doesn't use IRQs, so it's moot
@LoopForever:
    JMP @LoopForever     ; then loop forever! (or really until the NMI is triggered)

It seems once it tries to RTS with CritReturn, it doesn't know how to get back to Bank C or something?

The code starts in Bank C, then switches to F, with the proper imports and exports in place for everything...

Code: [Select]
   LDA battle_critsconnected
    BEQ :+                              ; if any criticals connected...
      LDA #BTLMSG_CRITICALHIT           ; print the Critical Hit!! combat message box
      JSR DrawBattleMessageCombatBox
      JSR RespondDelay
      JSR CritCheck

then over to Bank F...

Code: [Select]
CritCheck:
    LDA $6887
    BNE CritReturn
;    JSR OrbCount
;    LDA lut_OrbAccBoost, X          ; 0, 10, 20, 30, 40
;    LDX #100                        ;
;    JSR RandAX                      ;
;    CMP #75                         ; Player needs to roll 75 or over to do their special thing.
;    BCC CritReturn
   
    LDY #ch_class - ch_stats        ;
    LDA (btl_ob_charstat_ptr), Y    ; Check the class
    CMP #$01                        ; IF thief, goto CritSteal
    BEQ CritSteal                   
    CMP #$07                        ; IF thief, goto CritSteal
    BEQ CritSteal                   
    CMP #$02                        ; IF barbarian, goto CritStun
    BEQ CritStun
    CMP #$08                        ; IF barbarian, goto CritStun
    BEQ CritStun
    CMP #$03                        ; IF bard, goto CritWeaken
    BEQ CritSlow
    CMP #$09                        ; IF bard, goto CritWeaken
    BEQ CritSlow
    CMP #$05                        ; IF moon mage, goto CritConfuse
    BEQ CritConfuse
    CMP #$0B                        ; IF warrior mage, goto CritStrength
    BEQ CritStrength
      CritReturn:
    RTS
   
    CritStun:
    LDA #$01                        ; Load the byte for Dark/Blind weakness, which I'll count Confuse in
    JSR CheckEnemyResistance
    LDA #$10                        ; Stun ailment as used by STUN's effectivity in original game
    JSR CritAddAilment
    LDA #BTLMSG_PARALYZED
    JMP CritCheckPrint
       
    CritSlow:
    LDA btl_defender
    JSR PrepEntityPtr_Enemy         ; is this necessary?
    LDY #en_numhitsmult
    LDA (btl_entityptr_ibram), Y    ; hit multiplier from RAM stats
    STA btlmag_defender_numhitsmult
    DEC btlmag_defender_numhitsmult ; Decrease their hit multiplier
    BPL :+                         
;INC btlmag_defender_numhitsmult ; No reason to INC it again 'cos it doesn't get saved after a physical attack!
        RTS   
    STA (btl_entityptr_ibram), Y
 :  LDA #BTLMSG_LOSTINTELLIGENCE
    JMP CritCheckPrint
       
    CritConfuse:
    LDA #$08                        ; Load the byte for Dark/Blind weakness, which I'll count Confuse in
    JSR CheckEnemyResistance
    LDA #$80                        ; Confuse ailment as used by CONF's effectivity in original game
    JSR CritAddAilment
    LDA #BTLMSG_CONFUSED
    JMP CritCheckPrint
     
    CritStrength:                   ; Jigs tested and approved!
    LDA btl_attacker_strength   
    ADC #4
    BCC :+
      LDA #$FF
 : LDY #btlch_dmg
    STA (btl_ib_charstat_ptr), Y
    LDA #BTLMSG_ERASED              ; "Strength Up"
    JMP CritCheckPrint
   
    CritSteal:
    LDA tmp+6
    STA tmp
    LDA tmp+7
    STA tmp+1
    LDA #0                           
    STA tmp+2                       
    JSR AddGPToParty                 
    LDA #BTLMSG_WEAPONSSTRONGER   

    CritCheckPrint:   
    JSR DrawBattleMessageCombatBox   
    JSR RespondDelay
    RTS
 
  CheckEnemyResistance:
    STA tmp+6                       ; tmp+6 is now special attack's element
    LDA btl_defender_elemresist
    AND tmp+6
    BEQ :+                          ; if defender resists the special attack's element
      JMP CritReturn                ; cancel the whole special attack
     
  : RTS                             ; return to do the ailment
 
  CritAddAilment:
  PHA
    AND btl_defender_ailments    ; See if defender has this ailment already
    BEQ :+                       ; If yes...
      JMP CritReturn             ; cancel ... or just freeze the game!
 :   PLA
    ORA btl_defender_ailments    ; add to existing ailments
    STA btl_defender_ailments
    RTS

Apart from the error, I'm wondering if there's a better way to do the class CMPs. Can I combine them like AND sometimes lets you do with ailments?   CMP (#$01 | #$07) ?
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #66 on: June 14, 2017, 10:22:03 pm »
I apparently did not see your reply on the 3rd.  Whoooops.  I'll assume you got that sorted out by now and will just reply to your most recent post.


I haven't tested the bard's code yet, but the Moon mage's CONFUSE ability is messing up. I got it working fine once, but if it tries to apply itself a second time, game freezes. This evil little thing here... [OnIRQ]

Most likely cause of hitting OnIRQ is running into a BRK instruction which will jump to the IRQ vector.  And the only reason you'd run into a BRK is if you're jumping to something that isn't code.

Most likely cause of jumping to not-code is either expecting a specific bank to be swapped in when it isn't -- or having a corrupted stack on an RTS (ie:  an RTS that doesn't have a matching JSR).  Given how you don't seem to be doing any bankswapping in the code you posted, I'm going to assume the stack thing is your problem.

Some notes on your code:

- CritReturn is just an RTS... so there is never any reason to JMP to it.  JMPing to an RTS is the same as just doing an RTS directly, only it takes 2 extra bytes.  Branching to it would make sense because that's conditional -- but JMP makes no sense.

- CheckEnemyResistance doesn't do anything (it will always "succeed").  When you hit the BEQ, you'll either skip over the JMP and go straight to the RTS.  Or you'll JMP to CritReturn (which is just an RTS).  So either way, the only thing you're doing is just an RTS.  What you might be trying to do is a "double RTS", which is when you effectively go back two levels of JSRs instead of one.  This can be accomplished as below...
But note that I really don't recommend this unless you're VERY careful, as mangling the stack like this is a recipe for disaster if you don't know what you're doing.

Code: [Select]
  BEQ :+
    ; If they're resistant, double-RTS out of here and don't do anything
    ;  The two PLAs will pull one return address off the stack (effectively dropping the most
    ;  recent JSR), and then doing a normal RTS after that will go back to the JSR prior. 
    PLA
    PLA
: RTS


- CritAddAilment is mangling the stack, which is certainly the source of your crash.  Note that JSR/RTS and PHA/PLA share the same stack.  So once you PHA a value, you MUST NOT RTS until you've PLA'd it.  Otherwise, RTS will think the PHA'd value is part of its return address, which will cause it to jump back to random ass memory.
Code: [Select]
    PHA                         ; Stack now has a value that needs to be PLA'd before you can RTS
    AND btl_defender_ailments
    BEQ :+
      JMP CritReturn            ; This is an RTS, but you haven't PLA'd yet.. so CRASH
 :  PLA
    ORA btl_defender_ailments
    STA btl_defender_ailments
    RTS
   
- Although, there is no reason to be checking whether or not the enemy has the ailment before you give it to them.  Just give it to them again -- who cares?  $10 OR $10 is still $10.  ORing again won't cause a problem.  Unless you're trying to prevent a message from showing?



Quote
Apart from the error, I'm wondering if there's a better way to do the class CMPs. Can I combine them like AND sometimes lets you do with ailments?   CMP (#$01 | #$07) ?

Well, $01 OR $07 is just $07 ... so that won't work  ;P

One thing you might be able to do is make a jump table and use the class ID to index it.  But I don't think that'd save you any space, since you'd need 24 bytes for the table + at least another 15 or so to actually use the table.

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #67 on: June 15, 2017, 12:02:48 am »
I apparently did not see your reply on the 3rd.  Whoooops.  I'll assume you got that sorted out by now and will just reply to your most recent post.

Hah, actually I've been stumped. The post was full of rambling with every attempt I tried to fix it (I did fix some problem with how Music_DoScore was branching out to the different subroutines at least!), but in the end I just deleted everything but my last revelation, since that's all that matters. I have no idea what to do except to add a 1-length rest note before the other instruments start, and then add it into the first jump point. So it'll play the 1 length when the song first starts, the other instruments will get re-aligned, and every second note from then on is ignored--theoretically, that'll work. But not something I can do every time I want to use this code in other songs.

Hurrah! Thanks for the next lesson. :D It all makes sense now, and I think I made the changes that will work... Made everything a @ label and made branches and no more JSRs, so the only RTSing that goes on will go back just the once to before it all begins.

Quote
Unless you're trying to prevent a message from showing?

Yep, that's the plan. How's this look?
(Edit: Quick testing, while it works, doing confuse on a paralyzed enemy will print "Paralyzed"... so... gotta fix that somehow!)
(Edit again: I think I got it. Instead of checking the enemy's ailments, it'll check the class one last time.)

Code: [Select]
    @CritStun:
    LDA btl_defender_elemresist
    AND #$01
    BEQ :+                          ; if defender resists the special attack's element (stun: 01)
    RTS                             ; cancel specialty
  : LDA #$10                        ; Stun ailment as used by STUN's effectivity in original game
    JMP @CritAddAilment
               
    @CritConfuse:
    LDA btl_defender_elemresist
    AND #$08
    BEQ :+                          ; if defender resists the special attack's element (dark/confuse: 08)
    RTS                             ; cancel specialty
  : LDA #$80                        ; Confuse ailment as used by CONF's effectivity in original game
    JMP @CritAddAilment

    @CritAddAilment:
    PHA
    AND btl_defender_ailments    ; See if defender has this ailment already
    BEQ :+                       ; If yes...
       PLA                       ; fix the stack
       RTS                       ; cancel the specialty
 :  PLA
    ORA btl_defender_ailments    ; add to existing ailments
    STA btl_defender_ailments   
    LDA (btl_ob_charstat_ptr), Y
    CMP #$05                     ; is it still the moon mage's turn?
    BNE :+                       ; if not, go print Paralyzed, since it must be the barbarian's turn
       LDA #BTLMSG_CONFUSED     
       JMP @CritCheckPrint
 :  LDA #BTLMSG_PARALYZED
    JMP @CritCheckPrint

Next up: Make sure the Bard special crit attack works, then clean up the Cleric's ability: x2 crit chance against undead/were enemies!

June 15, 2017, 12:43:35 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Yeah, I think the bard one works! It doesn't bug out and it prints the message at least. I'll have to follow the debugger as it goes to make sure. (Also, OH MY GOODNESS I was using a version of Fceux from 2011 for some reason?? I updated it and now all my complains about the debugger earlier seem silly.)

For the cleric's specialty, starting in Bank C:

Code: [Select]
LDA btl_attacker_critrate   ; base crit chance of attacker's crit rate
    STA math_critchance
    JSR ClericCheck
Then in Bank F again:
Code: [Select]
ClericCheck:
    LDA $6887                       ; is it player attacking?
    BNE @return
    LDY #ch_class - ch_stats        ;
    LDA (btl_ob_charstat_ptr), Y    ; Check the class
    CMP #$00                        ; IF cleric
    BEQ :+                 
    CMP #$06                        ; If other cleric
    BNE @return
  : LDA btlmag_defender_category       
    AND #CATEGORY_UNDEAD+CATEGORY_WERE
    BEQ @return
    LDA btl_attacker_critrate
    ASL btl_attacker_critrate       ; *2 Crit chance against undead/cursed
    STA math_critchance
    @return:
    RTS

Or does that AND only work if they're both Undead and Were?
« Last Edit: June 15, 2017, 01:33:44 am by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #68 on: June 15, 2017, 09:30:05 am »
ugggghhh... I had a reply all typed out and then accidentally closed my window and lost it.

I'm not typing all that again right now.  Maybe I'll come back later.  Sorry.   :-[

RetroRain

  • Sr. Member
  • ****
  • Posts: 287
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #69 on: June 15, 2017, 12:24:23 pm »
ugggghhh... I had a reply all typed out and then accidentally closed my window and lost it.

I'm not typing all that again right now.  Maybe I'll come back later.  Sorry.   :-[

I HATE when that happens.  It's the worst thing ever.  That, or on some forums (one of the other forums I go to) has a timer.  If you wait too long to post, when you finally hit reply, you automatically get logged out, and then everything you typed is no longer there even if you hit the back button.

That's why I got into the habit of copying everything I'm typing in my post, to notepad, if I'm finding it's taking me a while to make that post.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #70 on: June 15, 2017, 12:43:13 pm »
That's why I got into the habit of copying everything I'm typing in my post, to notepad, if I'm finding it's taking me a while to make that post.

I was typing in notepad.  But I closed the tab thinking it was a different one (I have like a million tabs open at any given time).  =x

Here's the jist of my post:


I don't really understand the problem you're having with music.  The latest post seems incomplete, unless it's relying on info from earlier posts -- but given the size of this thread I'm not willing to scour the forums for all the relevant info.  If you can make a new reply that has all the relevant info that would be helpful.


The ailment code looks good.  If you want to shave a few bytes off, you can use the oft-overlooked "BIT" instruction, which effectively does an AND without modifying A... which means you won't have to PHA/PLA:

Code: [Select]
; This code...
PHA
AND btl_defender_ailments
BEQ :+
    PLA
    RTS
:
PLA

; ... could be replaced with this:
BIT btl_defender_ailments
BNE a_nearby_RTS


Your 2x crit chance code is broken:
Code: [Select]
    LDA btl_attacker_critrate       ; A = 1* Crit rate
    ASL btl_attacker_critrate       ; does not change A .. changes memory directly
    STA math_critchance             ; A is still 1* crit rate.. so you've effectively done nothing

If the crit rate has already been loaded into math_critchance, you can just ASL that value directly (don't need to use A):
Code: [Select]
    ASL math_critchance         ; double the crit rate.  No further code needed (unless you want to catch overflow)
   
    ; of course, with overflow, you could just roll the carry into the high byte:
    ROL math_critchance+1       ; roll carry into high byte (This assumes high byte is zero beforehand)


Quote
Or does that AND only work if they're both Undead and Were?

AND will work if they're EITHER undead or were (or both).

Remember how AND works:

Code: [Select]
0001 1000    <-  CATEGORY_UNDEAD + CATEGORY_WERE
xxxx xxxx    <-  defender category
=========
000x x000    <-  result of AND

That result will only be zero if BOTH of those 'x' bits were zero.  So if either (or both) are set, AND will be nonzero, and the Z flag will be cleared.



EDIT:

PS:  I'm leaving town for a family trip EARLY tomorrow morning and will be gone for 2 weeks.  I might be able to check on the forums at some point, but expect my replies from here on to be very slow.

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #71 on: June 15, 2017, 01:55:49 pm »
No worries! Sorry about your post, that happens to me a lot. Internet dies and I go hit post and then its gone...

Here's everything to do with the music bug, I think:

The part in Music_DoScore that checks for $F1 (save return point past the .word address, and goto the .word address) and $F2 (restore the return address and goto it). This part WAS broken, but it works now.
Code: [Select]
@Code_F1_F2:
CMP #$F3                ; if less than F3
BCS @Code_F3_F7
  JSR Music_Goto        ; here if $F1-F2
      JMP Music_DoScore   

The main code.
Code: [Select]
Music_Goto:
    CMP #$F2                ; if F2 then goto the Return part
    BEQ @Return             ; otherwise its an F1, so find the point in the song to start playing next--
   
    JSR @SaveReturnPoint    ; ...once we get the return point saved...
    JMP ResumeLoop          ; --which works the same way as resuming a loop! But is skipping to another spot entirely.
       
    @Return:                ;
      LDA ch_return, X      ; load return pointers
      STA ch_scoreptr, X    ; save as channel and music pointers
      STA mu_scoreptr       ;
      LDA ch_return+1, X    ;
      STA ch_scoreptr+1, X  ;
      STA mu_scoreptr+1     ;
      JMP Music_DoScore     
   
    @SaveReturnPoint:
    LDA ch_scoreptr, X
    CLC
    ADC #3
    STA ch_return, X        ; skip past the F1 and .WORD bytes
    LDA ch_scoreptr+1, X    ;
    ADC #0
    STA ch_return+1, X
    RTS

ResumeLoop, for reference:
Code: [Select]
ResumeLoop:
    LDY #1
    LDA (mu_scoreptr), Y    ; to resume the loop, get low byte of loop address from the score
    STA ch_scoreptr, X      ;  record that as the new score pointer for the channel
    STA tmp                 ; store in tmp (don't change mu_scoreptr yet because we still need it
    INY                     ;   to get the high byte)
    LDA (mu_scoreptr), Y
    STA ch_scoreptr+1, X    ; get high byte
    STA mu_scoreptr+1
    LDA tmp
    STA mu_scoreptr         ; then set low byte of mu_scoreptr previously tmp'd
    RTS                     ; channel is now pointing to loop address -- exit

The music score:
Code: [Select]
OVERWORLD3:
   .BYTE $FC
   OVERWORLD3_START:
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2_ALT
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2_ALT
   .BYTE $F1
   .WORD OVERWORLD3_1
   .BYTE $F1
   .WORD OVERWORLD3_2
   .BYTE $D0
   .WORD OVERWORLD3_START
   
   OVERWORLD3_1:
   .BYTE $D9,$06,$46,$96,$46,$66,$96,$DA,$26,$D9,$96,$76,$B6,$DA,$46,$D9,$B6,$46,$76,$B6,$76
   ;;;;;;;;;;;;;;;^^ Skips this note
   .BYTE $F0
   .WORD OVERWORLD3_1_END
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$D8,$B6,$D9,$26,$66,$26
   .BYTE $D1
   .WORD OVERWORLD3_1
   OVERWORLD3_1_END:
   .BYTE $F2
   OVERWORLD3_2:
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$B2,$F2
   ;;;;;;;;;;;^^ Skips this note
   OVERWORLD3_2_ALT:
   .BYTE $06,$46,$76,$46,$26,$66,$B6,$66,$46,$76,$B6,$76,$46,$B6,$DA,$46,$D9,$B6,$F2
   ;;;;;;;;;;;^^ Skips this note

The only problem now is that it skips the second note. Not the second byte of data in the score--just the played note.
The first time it hits OVERWORLD3_1, it plays the 06 and the 46 just fine. Then it goes to OVERWORLD3_2 and skips the 46, and so on. When it comes around again to OVERWORLD3_1, it skips the 46, not the 06 as you'd expect it to... At least, that's what I think I heard when I slowed it down and checked the recording against a piano version of the track.

Thanks for all your help so far, have a good vacation!
« Last Edit: June 15, 2017, 02:12:20 pm by Jiggers »
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

FCandChill

  • Hero Member
  • *****
  • Posts: 555
    • View Profile
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #72 on: June 15, 2017, 02:53:15 pm »
ugggghhh... I had a reply all typed out and then accidentally closed my window and lost it.

I'm not typing all that again right now.  Maybe I'll come back later.  Sorry.   :-[

You might want to look at into recovering lost files for the future: https://duckduckgo.com/html/?q=recover%20accidentally%20exited%20out%20files
« Last Edit: June 15, 2017, 03:00:37 pm by FCandChill »

Jiggers

  • Sr. Member
  • ****
  • Posts: 422
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy 1 Magic Upgrade Idea
« Reply #73 on: September 15, 2017, 05:20:48 am »
I should probably start a new thread for this project soon...

So the last month or... three, has it been? I've been poking around in Bank C, trying to make more room for my ideas. I have completely lost track of many changes I've made, but the big one is that I've managed to mostly consolidate how the game loads character and enemy stats. Rather than having different lists for loading a player's defense when using magic and when being attacked by an enemy, it uses the same chunk of code. Which is also more streamlined, using INY wherever possible, all the stats re-organized. $80 and $82 are used for the attacker, and $90 and $92 are used for the defender as much as possible. This also required lots of re-jiggering of variables, so maybe I screwed that up a lot.

I also slimmed up the way message boxes are drawn... I don't remember how I did that, though. I seem to have removed the ShowAltBattleMessage thing entirely.

And, for the most part, it works. There's just a few major bugs. :P

One, when using a weapon as an item, the character's name box doesn't get undrawn.

Two, casting healing magic on a player sometimes wigs out the whole thing, the sound effect plays higher and higher notes, black screen with garbled character sprites, game freezes. I think this has to do with healing over max HP.

Three, when healing magic doesn't do that, it doesn't effect the first character at ALL.

Four, the first and sometimes second character sometimes don't target the right enemy:
The first character will swing their weapon, but the enemy's name will be IMP or CHAOS or something else, and no "DoExplosionEffect" is triggered. Sometimes part of the battle screen behind the characters will have a chunk of it vanish. Sometimes the "DoExplosionEffect" IS triggered, but in a random spot on the screen. Sometimes they just normally target a different enemy.
The third and fourth characters always seem to hit their target just fine. The second character very rarely does... something that I can't remember and can't get them to replicate now. I THINK they attack, no explosion effect is drawn, but the enemy still vanishes after?

If I can fix these anomalies, I feel it will be worth it... I see 384 free bytes at the end of Bank C now!

My project so far, if anyone wants to help figure out what the heck I did. It is a mess.

https://drive.google.com/open?id=0B7rOlPhS8WdsVC1jZldwY05aQTg
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.