Разработка и ромхакинг > Ромхакинг и программирование
[NES] Battletoads / Battletoads & Double Dragon
<< < (2/12) > >>
feos:
Ключевой оказалась ячейка $16. В кадр 3527 именно на нее указывает $B7.

--- Код: ---$D347:B1 B7     LDA ($B7),Y @ $0016 = #$7F
--- Конец кода ---

Но в трейс логе я не нашел $4017 == #$7F, хотя именно оттуда (2 джой) это число рождается и пишется также в $2A и $2C, хотя в 4 объект оно берется не из них. Вообще, вот список адресов, принимающих значение из 2 джоя в ключевой кадр и меняющихся одинаково с изменением инпута 2 джоя:
$16, $2a, $2c, $4e, $1f8, $27d, $3c4.

А в адресе $16 значение #$7F образуется каким-то магическим путем. Ведь значение $4017 во всей этой субрутине равно #$FF!


--- Код: ---  $8683:20 78 8D  JSR $8D78                    A:90 X:00 Y:00 S:FD P:NVUBdIzc
    $8D78:A2 01     LDX #$01                     A:90 X:00 Y:00 S:FB P:NVUBdIzc
    $8D7A:8E 16 40  STX $4016 = #$FF             A:90 X:01 Y:00 S:FB P:nVUBdIzc
    $8D7D:CA        DEX                          A:90 X:01 Y:00 S:FB P:nVUBdIzc
    $8D7E:8E 16 40  STX $4016 = #$FF             A:90 X:00 Y:00 S:FB P:nVUBdIZc
    $8D81:A2 08     LDX #$08                     A:90 X:00 Y:00 S:FB P:nVUBdIZc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:90 X:08 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:08 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$30             A:20 X:08 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:08 Y:00 S:FB P:nVUBdIzc
    $8D8C:6A        ROR                          A:40 X:08 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$02             A:20 X:08 Y:00 S:FB P:nVUBdIzc
    $8D8F:CA        DEX                          A:20 X:08 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:20 X:07 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:20 X:07 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:07 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$60             A:20 X:07 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:07 Y:00 S:FB P:NVUBdIzc
    $8D8C:6A        ROR                          A:41 X:07 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$04             A:20 X:07 Y:00 S:FB P:nVUBdIzC
    $8D8F:CA        DEX                          A:20 X:07 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:20 X:06 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:20 X:06 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:06 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$C0             A:20 X:06 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:06 Y:00 S:FB P:NVUBdIzC
    $8D8C:6A        ROR                          A:41 X:06 Y:00 S:FB P:nVUBdIzC
    $8D8D:26 16     ROL $0016 = #$09             A:A0 X:06 Y:00 S:FB P:NVUBdIzC
    $8D8F:CA        DEX                          A:A0 X:06 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:A0 X:05 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:A0 X:05 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:05 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$80             A:20 X:05 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:05 Y:00 S:FB P:nVUBdIZC
    $8D8C:6A        ROR                          A:41 X:05 Y:00 S:FB P:nVUBdIzC
    $8D8D:26 16     ROL $0016 = #$13             A:A0 X:05 Y:00 S:FB P:NVUBdIzC
    $8D8F:CA        DEX                          A:A0 X:05 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:A0 X:04 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:A0 X:04 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:04 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$00             A:20 X:04 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:04 Y:00 S:FB P:nVUBdIZc
    $8D8C:6A        ROR                          A:41 X:04 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$27             A:20 X:04 Y:00 S:FB P:nVUBdIzC
    $8D8F:CA        DEX                          A:20 X:04 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:20 X:03 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:20 X:03 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:03 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$00             A:20 X:03 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:03 Y:00 S:FB P:nVUBdIZc
    $8D8C:6A        ROR                          A:41 X:03 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$4F             A:20 X:03 Y:00 S:FB P:nVUBdIzC
    $8D8F:CA        DEX                          A:20 X:03 Y:00 S:FB P:NVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:20 X:02 Y:00 S:FB P:nVUBdIzc
    $8D83:AD 16 40  LDA $4016 = #$FF             A:20 X:02 Y:00 S:FB P:nVUBdIzc
    $8D86:6A        ROR                          A:40 X:02 Y:00 S:FB P:nVUBdIzc
    $8D87:26 15     ROL $0015 = #$00             A:20 X:02 Y:00 S:FB P:nVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:20 X:02 Y:00 S:FB P:nVUBdIZc
    $8D8C:6A        ROR                          A:41 X:02 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$9F             A:20 X:02 Y:00 S:FB P:nVUBdIzC
    $8D8F:CA        DEX                          A:20 X:02 Y:00 S:FB P:nVUBdIzC
    $8D90:D0 F1     BNE $8D83                    A:20 X:01 Y:00 S:FB P:nVUBdIzC
    $8D83:AD 16 40  LDA $4016 = #$FF             A:20 X:01 Y:00 S:FB P:nVUBdIzC
    $8D86:6A        ROR                          A:40 X:01 Y:00 S:FB P:nVUBdIzC
    $8D87:26 15     ROL $0015 = #$00             A:A0 X:01 Y:00 S:FB P:NVUBdIzc
    $8D89:AD 17 40  LDA $4017 = #$FF             A:A0 X:01 Y:00 S:FB P:nVUBdIZc
    $8D8C:6A        ROR                          A:41 X:01 Y:00 S:FB P:nVUBdIzc
    $8D8D:26 16     ROL $0016 = #$3F             A:20 X:01 Y:00 S:FB P:nVUBdIzC
    $8D8F:CA        DEX                          A:20 X:01 Y:00 S:FB P:nVUBdIzc
    $8D90:D0 F1     BNE $8D83                    A:20 X:00 Y:00 S:FB P:nVUBdIZc
    $8D92:A5 15     LDA $0015 = #$00             A:20 X:00 Y:00 S:FB P:nVUBdIZc
    $8D94:AA        TAX                          A:00 X:00 Y:00 S:FB P:nVUBdIZc
    $8D95:45 29     EOR $0029 = #$10             A:00 X:00 Y:00 S:FB P:nVUBdIZc
    $8D97:86 29     STX $0029 = #$10             A:10 X:00 Y:00 S:FB P:nVUBdIzc
    $8D99:25 15     AND $0015 = #$00             A:10 X:00 Y:00 S:FB P:nVUBdIzc
    $8D9B:85 2B     STA $002B = #$10             A:00 X:00 Y:00 S:FB P:nVUBdIZc
    $8D9D:A5 16     LDA $0016 = #$7F             A:00 X:00 Y:00 S:FB P:nVUBdIZc
    $8D9F:AA        TAX                          A:7F X:00 Y:00 S:FB P:nVUBdIzc
    $8DA0:45 2A     EOR $002A = #$00             A:7F X:7F Y:00 S:FB P:nVUBdIzc
    $8DA2:86 2A     STX $002A = #$00             A:7F X:7F Y:00 S:FB P:nVUBdIzc
    $8DA4:25 16     AND $0016 = #$7F             A:7F X:7F Y:00 S:FB P:nVUBdIzc
    $8DA6:85 2C     STA $002C = #$00             A:7F X:7F Y:00 S:FB P:nVUBdIzc
    $8DA8:60        RTS                          A:7F X:7F Y:00 S:FB P:nVUBdIzc
  $8686:A4 10     LDY $0010 = #$03     
--- Конец кода ---

Вот весь лог от начала кадра 3527 до записи #$7F в $16.
http://pastebin.com/Guq1NCK1

Добавлено позже:
О, так ведь первый джой получается связан с ячейкой $15, а второй с $16!
Ti_:

--- Цитата: feos от 09 Август 2012, 19:37:42 ---Добавлено позже:
О, так ведь первый джой получается связан с ячейкой $15, а второй с $16!

--- Конец цитаты ---
Посмотри внимательно - в том логе что ты выложил она как раз и образуется командами ROL ($16)  - битовый сдвиг.
feos:
Да я вижу, просто не врубаюсь в саму суть этих последовательных ROL'ов а также, почему он не показывает значение джоя равным 7F. Можешь на пальцах объяснить, как в ячейке 16 образуется 7F?
Ti_:

--- Цитата: feos от 09 Август 2012, 20:24:19 ---Да я вижу, просто не врубаюсь в саму суть этих последовательных ROL'ов а также, почему он не показывает значение джоя равным 7F. Можешь на пальцах объяснить, как в ячейке 16 образуется 7F?

--- Конец цитаты ---
Ну это просто особенности команд. По каким-то соображениям создатели проца сделали добавление битов из статуса (флагов результатов операций) ко многим командам.  Ты наверно видел в коде NES операции ADC #0.  А нафига добавлять ничего...просто там еще может добавится бит из статус регистра. Поэтому в итоге добавится 1, а не 0.(если бит окажется =1).
С ROL точно также, там перед ней идет команда ROR.. поворот числа направо на 1бит. И если бит окажется 1 то и флаг результата в процессоре будет 1. (флаг carry)
А команда ROR наоборот двигает число влево, поэтому в него и запишется  значение этого флага.
На Сеговском проце такое же есть, только там для таких фич выделили отдельные вариации команд ADDX и roxl.
По этим же причинам они везде например при сложнении и пихают толи CLC (clear flag carry) толи SEC(set carry), дабы в значение не попало лишний бит.




Добавлено позже:
А ячеек несколько используется, потому что например опрос джойстиков создают не только на нажатие кнопки , а на нажатие и зажатие. (ну и мб даже отпускание кнопки бывает)
Поэтому четыре ячейки - 2 игрока -  и для каждого текущее нажатие кнопки считывается, и еще используется предыдущее. В одной ячейке будет значение в тот момент когда нажал, и в следующем кадре обнулится уже, а в другой ячейке будет хранится пока кнопку не отпустишь.
feos:
То есть...


--- Код: ---00000D99: AD1740 LDA $4017
00000D9C: 6A ROR A
00000D9D: 2616 ROL $16
--- Конец кода ---

Имеем число 0111 1111, загруженное в аккумулятор из джоя.
Делаем ROR. Получаем 1011 1111, да плюс 1 в carry флаге, так?
Потом обратно делаем ROL, то есть возвращаем 0111 1111 и пишем в ячейку $16 штоль?
А флаг потом просто для прыжков юзается?
Ti_:

--- Цитата: feos от 09 Август 2012, 21:07:49 ---Потом обратно делаем ROL, то есть возвращаем 0111 1111 и пишем в ячейку $16 штоль?
А флаг потом просто для прыжков юзается?

--- Конец цитаты ---
Нет мы не возвращаем, так как следом идущая ROL влияет только на ячейку памяти $16, а регистр A не трогает. И в эту ячейку записывает информацию из флага carry + сдвигает число.
Флагов много во-первых есть флаги C Z и другие + они образуются меняются от разных команд - конкретно надо смотреть в списке команд. Какие флаги меняет та или иная команда и каким образом, и какие учитывает при вычислениях.  http://www.emuverse.ru/wiki/MOS_Technology_6502/Система_команд;
Такой код тут использован потому что там из порта джойстика $4016 нельзя считать целиком все биты кнопок за 1 команду, поэтому приходится перекидывать по одному биту.
feos:
Дошло!!! Оно пуляет по 1 биту из джоя в $16 до тех пор, пока значение $16 не сравняется со значением джоя (то есть 8 раз), и потом выходит из субрутины!

А запоминание предыдущего инпута там необходимо, чтобы работало ускорение и несколько трюков связанных с ним:

--- Код: ---Нажали, отпустили, снова нажали ВПЕРЕД ->
Держим ВПЕРЕД - перс бежит;
Держим ПРЫЖОК - перс делает гипер-прыжок;
Держим ВВЕРХ или ВНИЗ рядом с лестницей - перс бежит по лестнице

--- Конец кода ---

Добавлено позже:
ПОСЛЕДНИЙ ВОПРОС на сегодня: откуда он берет, что именно в эти кадры надо увеличивать поинтер? Что я заметил - прямо перед рестартом он начинает автоматически КАЖДЫЙ КАДР увеличивать его на 11, за исключением лаговых кадров. Потом натыкается на #$7F и просто запускает конец. Команду увеличения поинтера я нашел, но когда он ее выполняет?
Добавлено позже:

Ну вот, разобрался. Он в начале уровня, или (что то же самое) на рестарте загружает необходимые объекты по очереди:
посреди лага загружаются жабы, потом после лага загружается точка рестарта, потом враги по очереди, и далее уровень идет своим чередом, загружая объекты когда надо.
Ti_:

--- Цитата: feos от 09 Август 2012, 21:37:02 ---ПОСЛЕДНИЙ ВОПРОС на сегодня: откуда он берет, что именно в эти кадры надо увеличивать поинтер? Что я заметил - прямо перед рестартом он начинает автоматически КАЖДЫЙ КАДР увеличивать его на 11, за исключением лаговых кадров. Потом натыкается на #$7F и просто запускает конец. Команду увеличения поинтера я нашел, но когда он ее выполняет?

--- Конец цитаты ---
Это происходит потому что чтение конфига не зациклено - он не будет выполнять проверку на чтение следующего объекта, если уже создал один, даже если объекты одинаковые и должны появится в одной точке. То есть вызов функции 'прочитать и проверить следующий объект' произойдет всего 1 раз за игровой 'цикл'. (jsr level_config_reading).  Если игра идет во все 60fps то и получается что создается каждый кадр.


Исключение - загрузка уровня. Там строчка jsr level_config_reading  продублирована. То есть загрузятся два объекта одновременно. (и это будут жабы игрока 1 и 2 , т.к. они всегда вначале уровней прописаны).

Следующий 'игровой цикл' - то есть набор функций где обрабатывается механика игры начнется только в следующем кадре. А до этого игра просто останавливается и ожидает прерывания на вывод графики. (Но в случае bt ещё и 'крутит рандом').  Если бы этого ожидания не было игра шла бы неравномерно и зависела от скорости процессора. Как например многие старые игры под DOS запускаемые на 1Ггц проце
Можешь скачать из темы хаков NES рипы конфигов уровней, там есть и куски кода подгрузки объекта.
[NES] Хаки на любой вкус
Roket:
Мега глюк в Battletoads Double Dragon . Пушка стреляет вторым игроком. :lol:
Yaranga:
Roket, дык она им не стреляет, она его весело подбивает своими пульками с разных точек, по-моему это никакой не глюк, так и задумывалось изначально...
Roket:
Yaranga, не, она именно им стреляет. Пули вылетают вместе с жёлтой жабой. Надо было всё-таки заснять это зрелище :?. Жаль сейв пересохранил. Потом как нарвусь ещё раз на этот глюк, то сделаю видео. ;)
Добавлено позже:
Вот. Так понятно, что она им на самом деле стреляет?
Ti_:

--- Цитата: Roket от 13 Август 2012, 13:00:19 ---Вот. Так понятно, что она им на самом деле стреляет?

--- Конец цитаты ---
Название рома - lomax hardcore - сдается это он что-то начудил. У него в контре такое было : http://www.youtube.com/watch?v=66LUH3k1rms
Roket:
Может быть кстати, что наш Ломака смог что-то не то опять сломать. :? Ну в общем в такой хак играть с особой осторожностью. ^_^
feos:
ЭТО РЕАЛЬНО ЕСТЬ В ИГРЕ!

http://www.youtube.com/watch?v=lZdXwwfI_3Y#t=150s

Скорее всего нао ударить пушку в тот самый момент когда она стреляет. Должен получиться лаг, и в атрибут этой пули пропишитеся 0x82, 8 означает, что она несет обьъект, 2 - что этот объект во 2 слоте. Надо дебажить это место, неужели совсем никакого бэкапа не осталось??? Мувик? Что угодно!
Ti_:

--- Цитата: feos от 13 Август 2012, 18:21:44 ---ЭТО РЕАЛЬНО ЕСТЬ В ИГРЕ!

http://www.youtube.com/watch?v=lZdXwwfI_3Y#t=150s

Скорее всего нао ударить пушку в тот самый момент когда она стреляет. Должен получиться лаг, и в атрибут этой пули пропишитеся 0x82, 8 означает, что она несет обьъект, 2 - что этот объект во 2 слоте. Надо дебажить это место, неужели совсем никакого бэкапа не осталось??? Мувик? Что угодно!

--- Конец цитаты ---
Ну если тот косяк со счетчиком объектов, сбивающемся в результате лага и они в БТ&ДД забыли испправить, тогда думаю это еще не последний глюк.  Надо бы глянуть

Добавлено позже:
Посмотрел - там почти тоже самое, только вместо $1A  - $1B.   И в джойстиках она же походу.
feos:
Естественно не последний!

http://www.youtube.com/watch?v=fmgDazOOxTY
http://www.youtube.com/watch?v=NJQjIMq46C0#t=28s

Ты еще глянь видео с предыдущего поста, там на шадоу боссе ГЕНЕРИТСЯ динамит! А также он хватает обоих персов сразу. Я уже не говорю про анимацию сгорания от удара палкой.
Roket:

--- Цитата ---Скорее всего нао ударить пушку в тот самый момент когда она стреляет. Должен получиться лаг, и в атрибут этой пули пропишитеся 0x82, 8 означает, что она несет обьъект, 2 - что этот объект во 2 слоте. Надо дебажить это место, неужели совсем никакого бэкапа не осталось??? Мувик? Что угодно!
--- Конец цитаты ---
Я так и сделал. Ударил именно жёлтой жабой самую первую попавшуюся пушку- Жаба сначала упала вместе с ней а потом исчезла и стала появляться в виде снарядов. Но в видео она умерла. А в моём случае нет.
 Мувик не сделал, так как занимался не выяснением глюков, а хакингом. ;) Потом я ж сказал нарвусь ещё раз, то сделаю. Тут видишь ещё и выясняется, что это глюк разработчиков, значит зря мы гнали на Ломакса. Впрочем вся серия боевых жаб на нес у них такая. :lol:
Добавлено позже:

--- Цитата ---Ты еще глянь видео с предыдущего поста, там на шадоу боссе ГЕНЕРИТСЯ динамит! А также он хватает обоих персов сразу. Я уже не говорю про анимацию сгорания от удара палкой.
--- Конец цитаты ---
Шедоу Босс отдельная тема. Там если не пройти отрезок когда он появляется, он тоже начнёт глючить, не сразу атаковать, с бажной графикой и прочими премудростями.
feos:

--- Цитата: Roket ---Шедоу Босс отдельная тема. Там если не пройти отрезок когда он появляется, он тоже начнёт глючить, не сразу атаковать, с бажной графикой и прочими премудростями.
--- Конец цитаты ---

Ну тут без мувика я тебя вообщ не отпущу!
Roket:

--- Цитата ---Ну тут без мувика я тебя вообщ не отпущу!
--- Конец цитаты ---
Ты сам можешь это проверить. Дойди до него и как только он появится оставляй игрока в том месте, где он будет появлять и лупи его -он ничего не сделает. Тут главное держать его на том мизерном расстоянии, пока он не попал на свою арену.
Меня сильно эти глюки не волнуют, он меня только раздражают. <_<
feos:
Ок. А насчет пули, ты камеру бил когда она уже выехала? Ее же можно лупануть когда она только зарождается, и она сразу исчезнет. А если дашь выехать, то рогами по ней не попадешь, перс автоматически прицепляется к пушке.
Навигация
Главная страница сообщений
Следующая страница
Предыдущая страница

Перейти к полной версии