Разработка и ромхакинг > Ромхакинг
[NES] Ассемблер перевести в понятный код
Ti_:
LDA не влияет на carry, поэтому иногда в коде CMP может и раньше быть - через строчку или даже несколько.
Вот примеры использования:
--- Код: ---BANK0:8C22 LDA Objects_X_speed,X
BANK0:8C25 CMP #$FF
BANK0:8C27 LDA #$18
BANK0:8C29 BCS loc_0_8C57
--- Конец кода ---
--- Код: ---BANK0:8951 LDA Level_ID
BANK0:8953 CMP #4
BANK0:8955 LDA bike_frames_ids - $38,Y
BANK0:8958 BCC loc_0_895D
BANK0:895A LDA bike_frames_ids2 - $38,Y
BANK0:895D
BANK0:895D loc_0_895D
BANK0:895D STA Obj_anim_frame,X
BANK0:8960 RTS
--- Конец кода ---
teremochek:
Посмотрел что есть в верху кода. Где все переменные.
В основном встречаются 3 типа:
1. numplayers .byt 0
Просто байтовая переменная, в конце которой стоит "0". Не знаю что он обозначает.
2. chrdest .word 0
Строковая переменная. Тоже вконце стоит "0".
3. velocity_bullet_x .dsb 24,0
dsb - Data Storage of Bytes, очевидно массив. Из 24 Байт. И опять "0".
numplayers : BYTE
chrdest : STRING
velocity_bullet_x : BYTE [ 24 ]
Попробовал перевести еще одну функцию.
Код.
--- Код: ---
l_player_width = local5
l_player_left_edge = local6
l_cur_bullet = local7
ProcessAllBullets:
JSR ProcessPlayerBullet
LDA #7
STA l_cur_bullet
LDY #0
LDX #0
NextEnemyBullet:
CLC ; loop 7 times
LDA velocity_bullet_x,y
ADC spr_buf(33,xcoo),x
STA spr_buf(33,xcoo),x ; sprite33..sprite39 (enemy bullets)
CLC
LDA spr_buf(33,ycoo),x ; if Y coordinate of bullet is 0
BNE skp018
STA spr_buf(33,xcoo),x ; reset X coordinate
BEQ DoneWithThisBullet
skp018: ADC #2
STA spr_buf(33,ycoo),x ; move enemy bullets down at 2pixels/vsync
INC PlayerDiedThisVsync
DEC PlayerDiedThisVsync ; test PlayerDiedThisVsync without modifying A
BNE DoneWithThisBullet
SEC
SBC #202 ; bulletY-202
CMP #5 ; bulletY-202 <=> 5?
BCC skp019
CMP #17 ; bulletY-202 <=> 17?
BCS DoneWithThisBullet
LDA player_x_pos
ADC #119
STA l_player_left_edge ; player_x_pos + 119 = left edge
LDA #11
STA l_player_width ; 11 = width
JMP skp020
skp019: LDA player_x_pos
ADC #122
STA l_player_left_edge ; player_x_pos + 122 = left edge
LDA #5
STA l_player_width ; 5 = width
skp020: SEC
LDA spr_buf(33,xcoo),x
SBC l_player_left_edge ; did it collide with the ship?
CMP l_player_width
BCS DoneWithThisBullet
LDA #1
STA PlayerDiedThisVsync
JSR StartPlayerDiedSound
LDA #0
STA spr_buf(33,ycoo),x
DoneWithThisBullet:
INY
INX
INX
INX
INX
DEC l_cur_bullet
BNE NextEnemyBullet
RTS
--- Конец кода ---
Избавляемся от загрузки, сохранения регистров.
--- Код: ---l_player_width = local5
l_player_left_edge = local6
l_cur_bullet = local7
Function ProcessAllBullets()
ProcessPlayerBullet()
l_cur_bullet = 7
y = 0
x = 0
# NextEnemyBullet ; loop 7 times
velocity_bullet_x[ y ] += spr_buf(33+x,xcoo)
spr_buf(33+x,xcoo) = velocity_bullet_x[ y ]
if spr_buf(33+x,xcoo) <> 0 Then GoTo skp018
spr_buf(33+x,xcoo) = 0
if spr_buf(33+x,xcoo) == 0 Then Goto DoneWithThisBullet
# skp018:
spr_buf(33+x,ycoo) +=2
If PlayerDiedThisVsync <> 0 Then Goto DoneWithThisBullet
spr_buf(33+x,ycoo) -= 202
If spr_buf(33+x,ycoo) - 5 < 0 Then Goto skp019 ;BCC
If spr_buf(33+x,ycoo) - 17 >= 0 Then Goto DoneWithThisBullet ;BCS
l_player_left_edge = player_x_pos + 119
l_player_width = 11
Goto skp020
# skp019
l_player_left_edge = player_x_pos + 122
l_player_width = 5
# skp020
spr_buf(33+x,xcoo) -= l_player_left_edge
if spr_buf(33+x,xcoo) - l_player_width >= 0 Then Goto DoneWithThisBullet
PlayerDiedThisVsync = 1
StartPlayerDiedSound()
spr_buf(33+x,ycoo) = 0
# DoneWithThisBullet
y +=1
x +=4
l_cur_bullet -=1
If l_cur_bullet <> 0 Then GoTo NextEnemyBullet
End Function
--- Конец кода ---
Избавляемся от меток.
--- Код: ---Function ProcessAllBullets()
ProcessPlayerBullet()
l_cur_bullet = 7
y = 0
x = 0
Do
velocity_bullet_x[ y ] += spr_buf(33+x,xcoo)
spr_buf(33+x,xcoo) = velocity_bullet_x[ y ]
if spr_buf(33+x,xcoo) <> 0
else
spr_buf(33+x,xcoo) = 0
if spr_buf(33+x,xcoo) == 0
y +=1
x +=4
l_cur_bullet -=1
If l_cur_bullet <> 0 Then Continue
endif
endif
spr_buf(33+x,ycoo) +=2
If PlayerDiedThisVsync <> 0
else
spr_buf(33+x,ycoo) -= 202
If spr_buf(33+x,ycoo) - 5 < 0
l_player_left_edge = player_x_pos + 122
l_player_width = 5
spr_buf(33+x,xcoo) -= l_player_left_edge
if spr_buf(33+x,xcoo) - l_player_width >= 0
else
PlayerDiedThisVsync = 1
StartPlayerDiedSound()
spr_buf(33+x,ycoo) = 0
endif
y +=1
x +=4
l_cur_bullet -=1
If l_cur_bullet <> 0 Then Continue
endif
If spr_buf(33+x,ycoo) - 17 >= 0
else
l_player_left_edge = player_x_pos + 119
l_player_width = 11
spr_buf(33+x,xcoo) -= l_player_left_edge
if spr_buf(33+x,xcoo) - l_player_width >= 0
else
PlayerDiedThisVsync = 1
StartPlayerDiedSound()
spr_buf(33+x,ycoo) = 0
endif
endif
endif
y +=1
x +=4
l_cur_bullet -=1
If l_cur_bullet <> 0 Then Continue
break
loop
End Function
--- Конец кода ---
Надо-бы подумать, как можно проверить работоспособность этих функции..
JAM:
А вот как ты их проверишь-то?
Массивы xcoo и ycoo, ты, допустим задал. А их адреса в роме?
--- Код: ---STA l_cur_bullet
--- Конец кода ---
Это даже без перевода на C работать не будет. В исходном коде был адрес, заменённый на переменную l_cur_bullet где-то в самом начале кода. Не указав его, куда прикажешь сохранять? Нельзя просто так выдрать из рома кусок кода с переменными, не расшифровав их. Вернее можно, но работать код не будет =)
teremochek:
--- Цитата: JAM от 06 Апреля 2013, 00:04:13 ---А вот как ты их проверишь-то?
Массивы xcoo и ycoo, ты, допустим задал. А их адреса в роме?
--- Конец цитаты ---
Не понимаю, зачем нужны их адреса.
За место спрайтов использовал квадраты.
Хочу разобраться, как Графику рома приделать.. (chr).
Вроде там 64 плитки. Вот только как именно они загружаются в память.. подряд, или в опр. порядке.
На худой конец можно скопировать из эмулятора буфер VRAM.
--- Цитата: JAM от 06 Апреля 2013, 00:04:13 ---
--- Код: ---STA l_cur_bullet
--- Конец кода ---
Это даже без перевода на C работать не будет. В исходном коде был адрес, заменённый на переменную l_cur_bullet где-то в самом начале кода. Не указав его, куда прикажешь сохранять? Нельзя просто так выдрать из рома кусок кода с переменными, не расшифровав их. Вернее можно, но работать код не будет =)
--- Конец цитаты ---
как написано перед функцией.
l_cur_bullet = local7
Вроде так можно делать, два имени у одной переменной. Если нельзя. То просто заменить все l_cur_bullet на local7.
Перевел еще две простенькие функции.
--- Код: ---IsPlayerMoving:
LDA PlayerDiedThisVsync
BNE ret18
JSR IsPlayerGoingLeft
LDA activejoykeys
AND #JOY_RIGHT
BEQ ret19
LDA player_x_pos
CMP #106 ; normalized 234
BEQ ret19
INC player_x_pos
ret19: RTS
;-------------------------------------------------------------------------------
IsPlayerGoingLeft:
LDA activejoykeys
AND #JOY_LEFT
BEQ ret19
LDA player_x_pos
CMP #<-106 ; clip player to no further left than -106 (normalized 22)
BEQ ret20
DEC player_x_pos
ret20: RTS
--- Конец кода ---
Перевод:
--- Код: ---Function IsPlayerMoving()
IF PlayerDiedThisVsync <> 0 Then Return ; BNE ret18
IsPlayerGoingLeft()
if activejoykeys AND #JOY_RIGHT == 0 Then Return
if player_x_pos == 106 Then Return ;BEQ 234 normalized
player_x_pos:+1
end function
;-------------------------------------------------------------------------------
Function IsPlayerGoingLeft()
if activejoykeys AND #JOY_LEFT == 0 Then Return
if player_x_pos == -106 Then Return ;(normalized 22)
player_x_pos:-1
end function
--- Конец кода ---
JAM:
--- Цитата: teremochek от 11 Апреля 2013, 10:01:38 --- if player_x_pos == 106 Then Return ;BEQ 234 normalized
--- Конец цитаты ---
Тогда уж не 106, а 262. Хотя ХЗ, там Hex в твоём коде или нет
teremochek:
(оффтоп)
Такая мысль пришла. Легче сделать видео, чем игру. Сначала записать видео на эмуляторе. А потом по верх него положить 3Д модели в Блендере.
s1nka:
teremochek, выглядит офигенно.
teremochek:
Сложность в том, что объекты в NES нарисованы в Ортографическом виде.
Но что-бы нам показать трехмерность нужен перспективный вид.
Такая мысли пришла, смоделировать объект в перспективном виде, но что-бы он выглядел так, как в ортографическом.
Это для игр типа Zelda. Где картинка статична, и перемещается лишь при переходе на другой экран.
Навигация
Перейти к полной версии