Welcome Press #01
31 декабря 1995

Справочник программиста - в поисках вечной жизни.

<b>Справочник программиста</b> - в поисках вечной жизни.
      
      
      
      
      
      

CopyRight (c) 1992-95 by Max Iwamoto/Code Busters


    Начало  этому  описанию  было  положено в тот
момент, когда одному из нас пришла в голову мысль
сделать   игру,   которую  мы  не  могли  пройти,
безжизненной.  Эта  мысль увенчалась успехом, что
дало  импульс  для  попытки сделать безжизненными
другие  игры  и вплотную заняться их устройством,
спецификой.    В   итобе   нами   были   вынесены
практические приемы  работы с играми (под работой
над    игрой   здесь (и  далее)   подразумевается
стремление  сделать  эту  игру  бессмертной). Эти
приёмы  были  разделены  на пять групп, которые и
представлены далее.
    Всё    нижесказанное   было   опробовано   на
компьютерах  MSX2  и  ZX-Spectrum  с  применением
таких программ как: Debugger, Mons4, STS3.3 и др.
Данная  версия  статьи рассчитана ислючительно на
пользователей ZX-Spectrum.
    Настоящее     руководство    рассчитано    на
пользователей,   практически   не  имеющих   даже
минимального  опыта  работы на Ассемблере Z80, но
знающих его основные команды.
    Предлагаем  на  Ваше  рассмотрение  несколько
методов  с помощью которых нам удалось переделать
не одну сотню игр.
           
   
                   МЕТОД 1
                   ───────
           ПРИШЕДШИЙ В ГОЛОВУ САМ СОБОЙ  


    Попытаться   поискать   ячейку,   в   которой
хранится  количество  жизней  и  увеличить их(при
этом  надо  иметь  ввиду,  что  в некоторых играх
число  жизней, выводимых на экран, на 1, а бывает
даже и на 2, меньше,  чем  загружается),  и  ещё,
никигда  не  ставьте  255  жизней, т.к., если Вам
вдруг  добавят  жизнь,  то  счётчик жизней станет
равным   0  и  наступит  Game  Over.  Чаще  всего
занесение   происходит   через  аккумулятор(далее
Acc):

#6000: 3E 03     A,#03        ;жизни в Acc
#6002: 32 00 C0  LD (#C000),A ;Acc в ячейку #C000

    Измените   число   по   адресу   #6001,  если
количество  жизней  в  игре  увеличилось,  значит
ячейка  (#C000) содержит количество жизней. Кроме
занесения  через аккумулятор существует множество
других, вот некоторые из них:

#6000: 21 00 C0    LD HL,#C000   ; #C000 в HL
#6003: 36 03       LD (HL),#03   ; жизни в #C000

    В  данном случае ячейка с которой нужно далее
работать - (#C000).
    Некоторые  фирмы  пошли более хитрыми путями.
Они  используют  ещё  несколько способов загрузки
жизней в ячейки:

#6000: 21 03 00  LD HL,#0003  ;загрузить 3 в HL
#6003: 7D        LD A,L       ;в Acc из L
#6004: 32 00 C0  LD (#C000),A ;Acc в ячейку #C000


#6000: 21 03 00  LD HL,#0003   ;загрузить 3 в HL
#6003: 22 00 C0  LD (#C000),HL ;HL в ячейку #C000

    Вместо  HL  могут  использоваться DE, BC, IX,
IY,  но  для нас главное найти ячейку, содержащую
жизни. Если ячейка найдена, то необходимо перейти
к  этапу  поиска  вычитания  жизни,  т.к. если мы
просто  увеличим  значение  в нужной ячейке может
так случиться,что даже большого количества жизней
не  хватит  для прохождения игры. Поиск вычитания
жизни рассмотрим на примере игры BUGGY RANGER:

   У нас имеется 3 жизни. Находим:

#B9EB: 3E 03     A,#03        ;жизни в Acc
#B9ED: 32 38 A9  LD (#A938),A ;Acc в ячейку #A938

   Ищем обращения к ячейке (#A938). Находим:

#B959: 21 38 A9  LD HL,#A938   ;
#B95C: 35        DEC (HL)      ; вычитание жизней

    После  того  как  мы  убираем DEC (HL) (#00 в
#B95C)  игра становится бессмертной, но пройти ее
практически    невозможно,    так   так   энергия
вычитается  слишком  быстро.  Поэтому мы начинаем
искать,  что  заносится  в ячейки рядом с ячейкой
жизни, т.е. (A9??):

#B9FF: 3E FF     A,#FF        ;энергия в Acc
#BA01: 32 39 A9  LD (#A939),A ;Acc в ячейку #A939

   Далее находим:

#C72C: 3A 39 A9  LD A,(#A939) ;энергию в Acc
#C72F: 95        SUB L        ;вычитание Acc
#C730: 32 39 A9  LD (#A939),A ;Acc в ячейку энер-
#C733: B7        OR A         ;гии  выставление
#C734: CA 38 C7  JP Z,#C738   ;флагов  переход,
                              ;если 0
#C737: C9        RET          ;возврат, если не 0
#C738: AF        XOR A        ;Обнуление
#C739: 32 39 A9  LD (#A939),A ;ячейки энергии
#C73C: C3 59 B9  JP #B959     ;переход  на проце-
                              ;дуру вычитания
                              ;жизни

    Аналогично можно обнаружить топливо и оружие:
ячейки  (A93A)  и (A941). Их вычитание аналогично
вычитанию жизней.
   
    Следующий  способ  заключается  в  том, что в
ячейку  помещается  не  само  число,  а ASCII код
этого числа. Например, если в игрушке 3 жизни, то
в  соответствующую  ячейку будет помещено не 3, а
#33,  то есть код цифры 3. Соответсвенно и жизней
в  данной игрушке не может быть больше 9, а также
проверка  осуществляется  не на 0, а на ASCII код
код 0, т.е. на #30. Очень любил использовать этот
способ  Bob  Pape, который написал R-TYPE, DRAGON
BREED, TUSKER. Возьмем для примера TUSKER:

    В  этой  игре  3  жизни.  Поэтому мы начинаем
искать  занесение  3 в Acc, но ничего не находим.
Далее  начинаем искать занесение ASCII кода числа
3 - #33. Находим:

#94D4: 3E 33     A,#33        ;жизни в Acc
#94D6: 32 21 FE  LD (#FE21),A ;Acc в ячейку #FE21

    Теперь начинаем искать обращения к
ячейке (#FЕ21):

#96E0: 3A 21 FE  LD A,(#FE21)
#96E3: 3D        DEC A        
#96E4: 32 21 FE  LD (#FE21),A 
#96E7: FE 30     CP #30        
#96E9: CA 01 84  JP Z,#8401

    DEC   A   у   нас  вызывает  подозрения,  они
усиливаются, когда  мы  видим CP #30 (проверка на
код числа 0). Теперь по адресу #96Е3 ставим #00 и
запускаем программу.
   
    И  напоследок  самый  хитрый и наиболее редко
встречаемый  способ.  Данные  о  жизни,  энергии,
номере этапа хранятся в теле программы, а на свои
адреса  пересылаются  командой  LDIR. Более того,
чаще   всего   они  хранятся  после  подпрограммы
пересылки!

#6000: 21 0C 60  LD HL,#600C  ; Источник
#6003: 11 00 C0  LD DE,#C000  ; Приемщик
#6006: 01 03 00  LD BC,#0003  ; сколько переслать
#6009: ED BO     LDIR         ; переслать 3 байта
#600B: C9        RET          ; с #600C на #C000
#600C: 03        INC BC       ; пересылаемые
#600D: 01 12 00  LD BC,#0012  ; данные
   
    В  данном  случае  ячейка, где следует искать
жизни  -  это  (#C000).  В (#C001) хранится номер
этапа, а в (#C002) количество энергии игрока.

    Но существует еще один тип игр. Это игры, где
участвует  несколько  игроков. В них всё делается
через  индексную  адрессацию, т.е.  для вычитания
жизней  обоих  игроков используется  одна и та же
подпрограмма.  Но,  если  игра представляет собой
драки ( например  Street   Fighter),   то   убрав
процедуру   вычитания   энергии (или  жизней)  Вы
сделаете   бессмертными   обоих  игроков  и  игра
потеряет  смысл. В этом случае необходимо убирать
не  команду  вычитания,  а  обращение к процедуре
вычитания для одного из игроков.
    
    Нужно    сказать    ещё    об   одной   часто
встречающейся  ошибке.  Если в игрушке количество
каких-то  предметов  одинаково,  то  занесение  в
ячейки  часто  находится  в одном и том же месте.
Например,  в  игре  Saigon  Combat  Unit  1 число
жизней  ровно  числу гранат и занесение находится
рядом:

#A823: 3E 04       A,#04         ;число 4 в Acc
#A825: 32 20 B0    LD (#B020),A  ;в ячейку жизней
#A828: 32 21 B0    LD (#B021),A  ;в ячейку гранат


    Но   на  самом  деле  самое  жестокое,  когда
создатели   игры  предусматривают,  что  их  игру
кто-то  будет  обессмерчивать. Например, это было
сделано  в  игре EQUINOX. Жизни в нем отключаются
довольно   просто,   но   если  Вы  переназначите
клавиатуру  перед игрой или Вам не хватит времени
для  прохождения уровня, то начав игру сначала Вы
увидите,   что   жизни   вычитаются.  Если  такое
происходит,  то  нужно  поискать  занесение  кода
команды  вычитания  в  память. В данном случае мы
находим:


#7006: 3E 35     A,#35        ;код команды
                              ;DEC (HL)
#7008: 32 B1 9B  LD (#9BB1),A ;А по адресу #9BB1,
                             ;как раз и находится
                             ;вычитание жизней!!!
   
    Поэтому,  если  поставить,  #00 вместо #35 по
адресу    #7007,   то   игра   станет   абсолютно
бесконечной.

   
                   МЕТОД 2
                   ───────
             ПОИСК ПРОВЕРКИ НА НОЛЬ  


    Если  первый способ не привел к положительным
результатам,  то следует искать проверку ячеек на
ноль,   убирать  ее  и  смотреть,  что  из  этого
получится. Далее я приведу некоторые из возможных
вариантов:

#6000: 3A 00 C0   LD A,(#C000) ;в Acc из (#C000)
#6003: B7         OR A         ;установить флажки
#6004: CA 00 80   JP Z,#8000   ;перейти, если A=0
     
    Уберите переход по адресу #6004 и посмотрите,
что  произойдёт. Если на экране число жизней = 0,
а  надпись  Game Over ещё не появилась, то значит
ячейка  жизней в данном случае - (#C000). Поиском
вычитания можно и не заниматься, т.к. Game Over и
так  никогда  не  наступит, но нужно помнить, что
проверка на 0 может быть и в нескольких местах.

   Рассмотрим еще несколько примеров:

#6000: 21 00 C0    LD HL,#C000 ;#C000 в HL
#6003: A6          AND (HL)    ;установить флажки
#6004: CA 00 80    JP Z,#8000  ;перейти, если 0

   Уберите переход по адресу #6004.

#6000: 3A 00 C0   LD A,(#C000) ;в Acc из (#C000)
#6003: D6 00      SUB #00      ;установить флажки
#6005: CA 00 80   JP Z,#8000   ;перейти, если A=0

    Уберите  переход по адресу #6005. Очень часто
вместо  SUB  #00  встречается  SUB  #01  и  таким
образом  убиваются  сразу  2  зайца  - вычитается
жизнь и проверяется равенство нулю. В этом случае
необходимо  поставить  SUB  #00  вместо SUB #01 и
жизнь станет вечной.

   
                   МЕТОД 3
                   ───────
            ПОИСК УМЕНЬШЕНИЯ ЖИЗНЕЙ  


    Также   можно  искать  вычитания  каких  либо
ячеек,  среди  них  может  оказаться  и вычитание
жизни.   Вычитание   может   производится  любыми
командами  вычитания, например: DEC N, SUB N, где
N  -  A,  B, C, D, E, H, L, (IX+??), (IY+??), HL,
DE, BC. Но бывают и более извращённые методы:

#6000: 2A 00 C0  LD HL,(#C000);в HL из памяти
#6003: 11 01 00  LD DE,#0001  ;сколько отнимать
#6006: ED 52     SBC HL,DE    ;уменьшить HL на DE
#6008: 7C        LD A,H       ;а не 0 ли у нас
#6009: 5B        OR L         ;в HL ?
#600A: CA 00 80  JP Z,#8000   ;если 0, то
                              ;Game Over
#600D: 22 00 C0  LD (#C000),HL;а иначе продолжим.

    Необходимо  поставить  #00 по адресу #6004. А
некоторые делают еще необычней:

#6000: 3E FF     LD A,#FF     ; жизни в L, #FF
                              ; в Acc
#6003: 85        ADD A,L      ; увеличить L на
                              ; A=-1
#6004: 32 00 C0  LD (#C000),A ; возвратить Acc
                              ; в (#C000)
    В данном случае можно поставить #00 по адресу
#6001 или по адресу #6002.
    

                   МЕТОД 4
                   ───────
         ИСПОЛЬЗОВАНИЕ ОСОБЕННОСТЕЙ ИГРЫ  


    Во  многих играх происходит добавление жизней
за  что-либо, значит можно найти их добавление. А
если мы знаем, что жизней не может быть больше N,
то  можно найти проверку на это число, определить
ячейку  из которой оно берётся и перейти к методу
1, например:

#6000: 3A 00 C0  LD A,(#C000) ;в Acc из (#C000)
#6003: FE 09     CP #09       ;проверка = 9
#6005: CA 00 80  JP Z,#8000   ;уйти, если = 9

    Ячейка  к  которой следует искать обращение -
(#C000).
   
    Часто  число жизней (номер оружия, выстрелы и
т.п.)  изображается  цифрами. Можно найти место в
программе,   где   они   печатаются.   Рассмотрим
несколько возможных вариантов:

#6000: 7E        LD A,(HL) ;загрузить в A из (HL)
#6001: D6 01     SUB #01     ;уменьшить Acc на 1
#6003: 27        DAA         ;десятичная корреция
#6004: CD ?? ??  CALL PRINT  ;вызов процедуры
                             ;печати
#6000: 7E        LD A,(HL) ;загрузить в A из (HL)
#6001: C6 30     ADD A,#30   ;добавить #30 к Acc
#6003: CD ?? ??  CALL PRINT  ;вызов процедуры
                             ;печати

    Во  втором  примере  мы добавляем #30 к Acc и
получаем  число  равное  ASCII коду этого числа и
печатаем  как обычное текстовое сообщение. В этом
случае нужно искать число, находящееся в HL.

    Смысл  следующего метода состоит в нахождении
места, где печатается надпись Game Over(или любая
другая,   которая  свидетельствует  об  окончании
игры).  Вполне  вероятно,  что  где-нибудь  рядом
находится  проверка  какой-либо  ячейки  на ноль.
Если этого нет, то продолжайте поиск.


                   МЕТОД 5
                   ───────

   
    Это  метод так называемой шоковой терапии или
метод  "научного  тыка"  с  успехом  используемый
нашей наукой в течении 73 лет. Он применяется для
копания  игр,  в  которых  абсолютно  не  за  что
зацепиться.   Чаще   это   игры   с   графическим
показателем  жизни.  Этот  метод  основывается на
вашей   интуиции   и   заключается   в   создании
искусственной  зацепки:  вы "едите" в МОНИТОРЕ по
листингу  игры  и  опираясь на интуицию изменяете
определенные  участки  программы,  отвечающие, по
Вашему мнению, за жизни, попытки, вещи и т.п.

 
    Необходимо   заметить,  что  выше приведенные
адреса  и примеры чисто условны. В Вашей игре эти
адреса   модут  быть  другими,  более  того:  эти
примеры  могут  переплетаться в самых причудливых
комбинациях.



                     *  *  *


Все права на публикацию данной статьи принадлежат
фирме `WELCOME', Санкт-Петербург, 1996 год.



Другие статьи номера:

Turbo Assembler 3.0 - полное описание.

Вопросы и ответы.

Конкурс - конкурс на лучший "boot" года.

Новости - новости от фирмы WELCOME.

Новости - обзор компьютерной прессы.

Объявления - обьявление к господам программистам.

От редакции.

Путеводитель - вступление.

Путеводитель - игра Academy (Академия).

Путеводитель - игра Last Battle (Последняя битва)

Путеводитель - игра Lords of Midnights (Повелители Полуночи)

Путеводитель - игра Stiflip & Company (Стиффлип и компания).

Путеводитель - игра Where Time Stood Still (Там, где время замерло).

Спекутрум изнутри - логические элементы.

Справочник программиста - в поисках вечной жизни.

Справочник программиста - точки входа в TR-DOS.

Справочник - вступление.

Старший брат - CD-ROM

Фотоскоп - фотографии читателей.

Юмор - судьба резидента, или паутина над страной.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
С миру по биту - о содеражнии раздела.
Linezip
Музыка - Лиpический номеp с пластинки HARD DAYS NIGHT (солист- П.Маккаpтни).
Профессиональный подход - Алгоритмы построения и прохождения Лабиринтов.
От авторов - "Читайте наше издание и ваша Spectrum'овская душа будет кристально чистой."

В этот день...   21 ноября