Справочное руководство
S1 Hacking Studio использует Hivebrain's 2005 Disassembly с компилятором ASM68K. Оригинальный дизасембл был частично изменен для нужд программы, например, некоторые маппинги вынесены в файлы, некоторые данные переконвертированы из формата ASM в BIN. Дизасембл также был усовершенствован и дополнен, добавлено несколько макросов для удобства, добавлено много новых комментариев, множество лейбелов были названы смысловыми именами (до этого у них были имена loc_XXXX или sub_XXXX).
В оригинальный код игры были внесены некоторые изменения и усовершенствования. Сделано это, во-первых, для нужд S1 Hacking Studio, во-вторых, для улучшения самой игры.
В обновленный дизасембл S1HS добавилось 4 новых макроса. Все макросы теперь находятся в файле macro.asm.
Аргументы:
1 — адрес VRAM
2 — регистр или адрес, куда будет записан полученный код доступа
Макрос для получения доступа к VRAM на запись. Второй аргумент необязателен, если он не указан, то код доступа будет послан сразу в VDP Control Port (адрес $C00004). Вы также можете записать его в регистр или в RAM M68K, и получить доступ позже, послав содержимое регистра в $C00004.
Аргументы:
1 — код ошибки
2 — роутина для обработки ошибки
3 — если существует, прибавляет 2 к указателю стека
Специфический макрос для векторов ошибок, дабы сэкономить размер кода. Вам вряд ли понадобится этот макрос, так как большинство ошибок им уже обрабатывается. Так что забудьте о нем, как о страшном сне.
Аргументы:
1 — перечень кнопок
2 — адрес битового поля с состоянием кнопок
Эти два макроса проверяют нажаты ли или удерживаются заданные кнопки. Они призваны упростить жизнь и избавить кодеров от нужды постоянно проверять индексы и значения для нужных им кнопок. Все кнопки объявляются ввиде констант с их именами, так что в первом аргументе вы можете сразу писать их имена, например, C или Start. Если вам необходимо проверить несколько кнопок, просто перечислите их, разделяя знаками + или |, например: A+B+C.
Второй аргумент - битовое поле, которое нужно проверить. В нем-то и прописано, какие кнопки активны. В Sonic 1 предусмотрены два таких поля, которые в макросе определены именами Joypad и SonicControl. Первое всегда отображает состояние джойпада и обновляется постоянно. Второе отвечает за управление Соником, оно обычно просто дублирует кнопки джойпада. Однако, поле SonicControl отличается тем, что иногда способно блокироваться, и перестает получать нажатия кнопок с джойпада, например, если не нужно больше, чтобы игрок управлял Соником. В режиме демо-уровней, это поле также заблокировано и получает нажатия кнопок из записанных прохождений. Если вы пишете код для Соника, лучше всего вторым аргументом указывать SonicControl.
После выполнения макросов можно использовать условные переходы. BEQ переходит, если ни одна из заданных кнопок не нажата, BNE срабатывает, если хотя бы одна из перечисленных кнопок нажата:
tpress A+B+C,(SonicControl) ; нажаты ли A, B или C? beq.s XXXXXXX ; если нет, переходим
В зависимости от настроек S1HS требуется помимо файлов изменять или добавлять код в файле sonic1.asm, например, если в программе поставлен флажок на Spin Dash'е, требуется добавить его код в sonic1.asm.
Для этого был введен файл config.asm, описывающий часть выбранных в S1HS настроек, в зависимости от которых потом потребуется изменить код. В файле содержится список констант и переменных с определенным значениями. Они при компиляции кода будут влиять на то, какой код добавлять и изменять. Константы и переменные имеют вот такой формат:
Константа equ Значение Переменная = Значение
Условия, в зависимости от которых вставлять опредленный код описываются в самом же sonic1.asm с помощью директивы if.
if (условие) ; код, который нужно вставлять, если условие верно esle ; код, вставляемый если условие неверно endc
В других случаях, например с ударами боссов, условий не требуется, нужно только подставить в строку значение переменной, для этого вместо числа просто пишется значение переменной, например:
move.b #var_BHits_GHZ,$21(a0)
В дизасембле S1HS было аннотировано огромное количество кода и исправлены ошибки, неточные названия лейбелов и комментарии оригинального Hivebrain's 2005 Disassembly.
Вот пример плохо-комментированной суброутины в оригинальном дизасембле:
loc_177E6: move.b $3F(a0),d0 jsr (CalcSine).l asr.w #6,d0 add.w $38(a0),d0 move.w d0,$C(a0) move.w $30(a0),8(a0) addq.b #2,$3F(a0) cmpi.b #8,$25(a0) bcc.s locret_1784A tst.b $22(a0) bmi.s loc_1784C tst.b $20(a0) bne.s locret_1784A tst.b $3E(a0) bne.s Obj3D_ShipFlash move.b #$20,$3E(a0) ; set number of times for ship to flash move.w #$AC,d0 jsr (PlaySound_Special).l ; play boss damage sound Obj3D_ShipFlash: lea ($FFFFFB22).w,a1 ; load 2nd pallet, 2nd entry moveq #0,d0 ; move 0 (black) to d0 tst.w (a1) bne.s loc_1783C move.w #$EEE,d0 ; move 0EEE (white) to d0 loc_1783C: move.w d0,(a1) ; load colour stored in d0 subq.b #1,$3E(a0) bne.s locret_1784A move.b #$F,$20(a0) locret_1784A: rts
Эта же суброутина в обновленном дизасембле:
; This routine does the main ship stuff Obj3D_ShipProcess: ; Move ship slightly up and down during the flight move.b $3F(a0),d0 ; Y-amplitude jsr (CalcSine).l asr.w #6,d0 ; d0 contains sine add.w $38(a0),d0 ; add secondary Y-pos to d0 move.w d0,$C(a0) ; and we've got Y-pos with the amplitude move.w $30(a0),8(a0) addq.b #2,$3F(a0) ; reduce the amplitude ; Touch repsonse stuff cmpi.b #8,$25(a0) ; is routine more or equals to 8? bcc.s locret_1784A ; if yes, branch tst.b $22(a0) ; was boss defeated? bmi.s Obj3D_ShipGone ; if yes, branch tst.b $20(a0) ; is touch response zero? bne.s locret_1784A ; if not, branch tst.b $3E(a0) ; is flashes counter zero? bne.s Obj3D_ShipFlash ; if not, branch move.b #$20,$3E(a0) ; set number of times to flash move.w #$AC,d0 jsr (PlaySound_Special).l ; play boss damage sound Obj3D_ShipFlash: lea ($FFFFFB22).w,a1 ; load 2nd pallet, 2nd entry moveq #0,d0 ; move 0 (black) to d0 tst.w (a1) ; is colour in pallete black? bne.s loc_1783C ; if not, branch move.w #$EEE,d0 ; move 0EEE (white) to d0 loc_1783C: move.w d0,(a1) ; apply colour stored in d0 subq.b #1,$3E(a0) ; subtract 1 from flashes counter bne.s locret_1784A ; if flashes counter is not zero, branch move.b #$F,$20(a0) ; restore touch responsibility locret_1784A:
Вот лишь неполный список аннотированных роутин и блоков кода: