Skip to content

Instantly share code, notes, and snippets.

@spiiin
Created October 1, 2012 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spiiin/3814486 to your computer and use it in GitHub Desktop.
Save spiiin/3814486 to your computer and use it in GitHub Desktop.
Adventure Island 2 [NES] Map movement algorithm
ROM:B676 ; =============== S U B R O U T I N E =======================================
ROM:B676
ROM:B676
ROM:B676 gen_next_level: ; CODE XREF: ROM:B45Ep
ROM:B676 LDA #0
ROM:B678 STA byte_DB ; счетчик переходов по пройденным этапам (до 4х раз)
ROM:B67A LDA byte_D1 ; текущее значение уровня
ROM:B67C STA byte_DA ; DA = текущее смещение в мапе
ROM:B67E
ROM:B67E generate_next: ; CODE XREF: gen_next_level+76j
ROM:B67E LDA byte_E7 ; номер яйца + 6
ROM:B680 BNE begin_gen
ROM:B682 JMP ret_level ; возврат старого значения смещения уровня
ROM:B685 ; ---------------------------------------------------------------------------
ROM:B685
ROM:B685 begin_gen: ; CODE XREF: gen_next_level+Aj
ROM:B685 SEC
ROM:B686 SBC #6
ROM:B688 ASL A
ROM:B689 ASL A
ROM:B68A ASL A
ROM:B68B STA byte_D8 ; номер яйца * 8
ROM:B68D LDA #0
ROM:B68F STA byte_D9
ROM:B691
ROM:B691 get_next_ofs_rom: ; CODE XREF: gen_next_level+40j
ROM:B691 LDY byte_D8
ROM:B693 LDA $B721,Y
ROM:B696 STA byte_0 ; взять 1 из 8 байт рома
ROM:B698 LDA byte_DA
ROM:B69A CLC
ROM:B69B ADC byte_0
ROM:B69D STA byte_1 ; старое смещение в мапе + считанное смещение
ROM:B69F CMP #$20 ; ' ' ; если смещение слишком большое
ROM:B6A1 BCS change_ofs_proc
ROM:B6A3 TAX
ROM:B6A4 LDA $3E0,X
ROM:B6A7 CMP #$50 ; 'P' ; если уровень пуст или пройден
ROM:B6A9 BCS change_ofs_proc
ROM:B6AB JMP set_level
ROM:B6AE ; ---------------------------------------------------------------------------
ROM:B6AE
ROM:B6AE change_ofs_proc: ; CODE XREF: gen_next_level+2Bj
ROM:B6AE ; gen_next_level+33j
ROM:B6AE INC byte_D8
ROM:B6B0 INC byte_D9 ; счетчик смещения карты (до 8 смещений из одной зоны)
ROM:B6B2 LDA byte_D9
ROM:B6B4 CMP #8
ROM:B6B6 BNE get_next_ofs_rom
ROM:B6B8 INC byte_DB ; если ни один из 8 не подходит
ROM:B6BA LDA byte_DB ; увеличиваем счетчик DB [0..3]
ROM:B6BC CMP #4
ROM:B6BE BCC try_again ; следующая попытка рассчитать смещение из того же яйца
ROM:B6C0 JMP set_ofs_1f ; установка смещения в 1F и запись
ROM:B6C3 ; ---------------------------------------------------------------------------
ROM:B6C3
ROM:B6C3 try_again: ; CODE XREF: gen_next_level+48j
ROM:B6C3 LDA byte_D8
ROM:B6C5 SEC
ROM:B6C6 SBC #8
ROM:B6C8 STA byte_D8
ROM:B6CA LDA #0
ROM:B6CC STA byte_D9 ; вычитаем из индекса смещения 8 и зануляем счетчик
ROM:B6CC ; (берем предыдущее яйцо)
ROM:B6CE
ROM:B6CE try_again_cycle: ; CODE XREF: gen_next_level+81j
ROM:B6CE LDY byte_D8
ROM:B6D0 LDA $B721,Y
ROM:B6D3 STA byte_0 ; взяли байт из той же таблицы
ROM:B6D5 LDA byte_DA ; сложили с прошлым индексом в мапе
ROM:B6D7 CLC
ROM:B6D8 ADC byte_0
ROM:B6DA STA byte_1
ROM:B6DC CMP #$20 ; ' ' ; если смещение слишком большое
ROM:B6DE BCS inc_try_again
ROM:B6E0 TAX
ROM:B6E1 LDA $3E0,X
ROM:B6E4 CMP #$F0 ; 'Ё' ; если уровень уже пройден
ROM:B6E6 BNE inc_try_again
ROM:B6E8 LDA byte_1 ; переставили смещение в мапе на этот уровень и пробуем сделать переход с новой позиции
ROM:B6EA STA byte_DA ; смена текущей позиции в мапе и следующая итерация генератора
ROM:B6EC JMP generate_next ; номер яйца + 6
ROM:B6EF ; ---------------------------------------------------------------------------
ROM:B6EF
ROM:B6EF inc_try_again: ; CODE XREF: gen_next_level+68j
ROM:B6EF ; gen_next_level+70j
ROM:B6EF INC byte_D8
ROM:B6F1 INC byte_D9
ROM:B6F3 LDA byte_D9
ROM:B6F5 CMP #8 ; 8 раз
ROM:B6F7 BNE try_again_cycle
ROM:B6F9 JMP set_ofs_1f ; запись макс. смещения уровня
ROM:B6FC ; ---------------------------------------------------------------------------
ROM:B6FC
ROM:B6FC ret_level: ; CODE XREF: gen_next_level+Cj
ROM:B6FC ; gen_next_level+A8j
ROM:B6FC LDA byte_D1 ; возврат старого значения смещения уровня
ROM:B6FE STA byte_E6
ROM:B700 RTS
ROM:B701 ; ---------------------------------------------------------------------------
ROM:B701
ROM:B701 set_level: ; CODE XREF: gen_next_level+35j
ROM:B701 ; gen_next_level+9Dj
ROM:B701 LDA byte_1
ROM:B703 STA byte_E6 ; установка нового значения смещения уровня
ROM:B705 RTS
ROM:B706 ; ---------------------------------------------------------------------------
ROM:B706
ROM:B706 set_ofs_1f: ; CODE XREF: gen_next_level+4Aj
ROM:B706 ; gen_next_level+83j
ROM:B706 LDA #$1F ; запись макс. смещения уровня
ROM:B708 STA byte_1
ROM:B70A
ROM:B70A try_apply_ofs: ; CODE XREF: gen_next_level+A6j
ROM:B70A LDX byte_1
ROM:B70C LDA $3E0,X
ROM:B70F CMP #$50 ; 'P' ; если уровень не пройден и не пуст
ROM:B711 BCS dec_offset ; уменьшаем смещение
ROM:B713 JMP set_level
ROM:B716 ; ---------------------------------------------------------------------------
ROM:B716
ROM:B716 dec_offset: ; CODE XREF: gen_next_level+9Bj
ROM:B716 DEC byte_1 ; уменьшаем смещение
ROM:B718 LDA byte_1
ROM:B71A CMP #$FF
ROM:B71C BNE try_apply_ofs ; если смещение не предельное, пробуем применить его еще раз
ROM:B71E JMP ret_level ; иначе возвращаем старое значение уровня
ROM:B71E ; End of function gen_next_level
ROM:B71E
ROM:B71E ; ---------------------------------------------------------------------------
ROM:B721 .BYTE -8, -7, -9, 1, -1, 9, 7, 8; 0 ; смещения
ROM:B721 .BYTE -9, -8, -1, -7, 7, 1, 8, 9; 8
ROM:B721 .BYTE -1, -9, 7, -8, 8, -7, 9, 1; 16
ROM:B721 .BYTE 7, -1, 8, -9, 9, -8, 1, -7; 24
ROM:B721 .BYTE 8, 7, 9, -1, 1, -9, -7, -8; 32
ROM:B721 .BYTE 9, 8, 1, 7, -7, -1, -8, -9; 40
ROM:B721 .BYTE 1, 9, -7, 8, -8, 7, -9, -1; 48
ROM:B721 .BYTE -7, 1, -8, 9, -9, 8, -1, 7; 56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment