goodboy,нада смотреть на какой машине было сделано раньше.Цитата:
ZX Spectrum, Amstrad CPC, Commodore 64
Вид для печати
goodboy,нада смотреть на какой машине было сделано раньше.Цитата:
ZX Spectrum, Amstrad CPC, Commodore 64
Там есть вот такое место:
И сравни, например, с анимацией птицы:Код:; Data block at 77BE
anim_ball_resize:
DEFW spr_ball_normal
DEFW spr_empty_1
DEFW spr_empty_2
DEFW spr_empty_3
DEFW spr_empty_4
DEFW spr_empty_5
DEFW spr_empty_6
DEFW spr_empty_7
DEFW spr_big_ball
Я думаю, что мы сейчас делаем двойную работу. Многое из того, что вы написали с ivagor, мне уже было известно из кода. Давайте я закончу с дизассемблированием, выложу то, что получилось и мы потом вместе приступим к анализу кода. Это будет гораздо удобнее и быстрее. Я сейчас по ходу разбора переименовываю некоторые безликие цифровые метки, присваивая им осмысленные названия. И уже дальше, опираясь на эти названия, из контекста становится примерно понятно что значат соседние процедуры. Например:Код:; Анимация птицы
anim_bird:
DEFW spr_bird_1
DEFW spr_bird_2
DEFW spr_bird_3
DEFW spr_bird_4
DEFW spr_bird_3
DEFW spr_bird_2
DEFW spr_bird_1
DEFW spr_bird_5
DEFW spr_bird_1
DEFW spr_bird_2
DEFW spr_bird_3
Код:; Used by the routines at L927F and LB9E8.
L93F8:
LD HL,$0000
LD (L938A),HL
CALL draw_frame
LD HL,$BF00 ; Координаты окна (весь экран нижняя строка)
LD DE,win_full_screen_purple_ink
CALL fill_attrib
LD HL,$B708 ; Координаты окна
LD DE,win_1e_16_white_ink
CALL fill_attrib
LD HL,$4718 ; Адрес на экране
LD DE,spr_press_a
CALL print_sprite ; Press A
LD HL,$47C8 ; Адрес на экране
LD DE,spr_press_b
CALL print_sprite ; Press B
LD HL,hi_score_1up
LD DE,txt_score_1up+4
CALL copy_score
LD HL,hi_score_2up
LD DE,txt_score_2up+4
CALL copy_score
LD DE,txt_main_menu
LD B,$0F ; Количество строк в сообщении
CALL print_message
LD HL,(coord_ctrl_1up)
LD DE,spr_pointer_1
CALL print_sprite
LD HL,(coord_ctrl_2up)
LD DE,spr_pointer_2
CALL print_sprite
Код:; Data block at 9614
L9614:
DEFW txt_1_player
DEFW txt_controls
Ну что ж, теперь все компилируется и играет по адресу отличному от стандартного. Пробовал компилировать на 100 байт больше и на 100 байт меньше. Если на 100 байт меньше, то в таблице когда ввожу имя портится верхняя часть экрана. Скорее всего какой-то нижний буфер перехлестнул кодом. Потому что такого эффекта нет, если скомпилировать на +100 байт от стандартного адреса. Глубоко не тестировал - может там ещё что есть. Но сейчас анализировать код уже стало гораздо проще, так как я могу что-то менять, закомментировать какие-то участки кода, добавить своё и т.д.
Нашёл в игре неиспользуемый цветной спрайт. Кусок левой боковины. Мне показалось, что это дверь, как а Арканойде, для перехода на следующий раунд. Скорее всего это должно было выглядеть вот так:
https://pic.maxiol.com/thumbs2/15922....battydoor.png
Причём сейчас я эту "дверь" поместил не в графическом редакторе, а путём добавления нескольких строчек кода к исходнику :) Отладка в действии!
Да, правильная мысль! Сдвинул на 257 байт и эффект проявился в обоих сторонах. Не думаю, что это серьёзная проблема, равно или поздно найду в чём проблема, потому что сейчас в игре практически не осталось белых пятен :)
По мере разбора кода наталкиваюсь на интересные вещи. Например, игровое поле окружено бордюром. И бордюр шириной не 8 пикселей, а 9! Вначале рисуются спрайты толщиной 8 пикселей, а потом ещё отдельно по внутреннему краю дорисовывается несплошная линия толщиной в пиксель. Вот автор заморочился, чтобы всё было идеально!
Нашёл причину порчи таблицы! Почему-то я этот абсолютный адрес в тексте программы пропустил, хотя смотрел её вдоль и поперёк многократно.
Прикладываю версию Batty, скомпилированную по другом адресу (+257 байт от стандартного). Кому не лень потестируйте, пожалуйста, чтобы убедиться, что ничего не сломалось.
Нашёл в игре очень интересный звук, который автор в итоге так и не использовал нигде.
Сделал специальный снепшот, чтобы можно было его услышать. Для воспроизведения этого таинственного звука, в главном меню нужно нажать кнопку В - выбор управления для второго игрока. И вместо стандартного звука (как на кнопке А) вы услышите нечто другое :)
Ничего себе проект!!! Очень интересно. А какая конечная цель? Портирование на другой комп?
На всякий случай сообщаю, что дизассемблирование не бросил, а продолжаю копаться в программе. То, чтобы было сходу понятно давно уже разобрал. Сейчас работа замедлилась, потому что теперь в силу неочевидности и моего малого опыта работы с чужим кодом, приходится подолгу сидеть над каждой новой процедурой и переменной. Но дело потихоньку движется!
Ну, и так, для затравки могу немного рассказать про какие-то части игры.
То, что я в самом начале принял за декодирование и распаковку кода на самом деле оказалось подготовкой графики. Во-первых, в конце памяти строится таблица сдвигов. К этой таблице обращается процедура печати спрайтов для их вывода со сдвигом по горизонтали. Это относится к перемещению врагов, искр от взорвавшейся каретки, выпадающей цифры 400 и т.д. После этого идёт создание некоторых готовых спрайтов со сдвигом. В игре, сразу после её загрузки, есть пустые спрайты и эта процедура заполняет эти пустые спрайты сдвинутыми. Прежде всего это касается шарика - к стандартному спрайту добавляется ещё 7 сдвинутых спрайтов. И также ещё по одному сдвинутому спрайту добавляется к спрайтам каретки: стандартной, расширенной и к каретке с пулемётом. То есть подготавливаются самые используемые спрайты, а остальные сдвигаются по таблице в процессе их вывода на экран. И на последнем этапе подготовки графики часть спрайтов инвертируется. После этого управление передаётся игре по адресу #B9B1.
Странно автор подошёл к формированию уровней. Все свойства уровней раскиданы по коду, а некоторые свойства выбираются программно.
1. Кирпичи: их расположение и прочность практически единственная вещь, которую можно редактировать. Собственно, это и было обнаружено хакерами, которые выпускали Batty 2, Batty 3 и т.д. При этом в этих "продолжениях" всё остальное оставалось от оригинальной игры.
2. Магниты: их наличие на уровне, количество и расположение также можно редактировать. Однако без доступа к коду сделать это не очень просто и к тому же есть ограничения. Дело в том, что под описание магнитов на уровнях отведено разное место. В описании вначале идёт байт, указывающий сколько магнитов есть на уровне, и далее, если в первом байте не ноль, по два байта координат каждого магнита. Таким образом для описания магнитов первого уровня используется только один один байт (#00), а для второго уже три (#01, #XX, #YY). На уровнях 9, 13 и 14 используется по 4 магнита и, соответственно описание для каждого из них занимает по 9 байт. И так как описание каждого уровня имеет разный размер, в игре есть таблица расположения этих описаний. Как видите, не так-то просто это отредактировать по живому коду, особенно если захочется поместить магнитов больше, чем есть в игре..
3. Текстуры: всего есть 4 вида текстур и они последовательно чередуются по кругу от уровня к уровню. Таким образом назначить какую-то определённую текстуру уровню не представляется возможным. Причём, что интересно, текстура первого уровня находится в одном месте программы, а текстуры трёх других совсем в другом месте.Код:; Data block at 8E06
; Таблица магнитов для уровней
magnets:
DEFW magnet_level_03 ; Данные для первого уровня берутся из 3-го
DEFW magnet_level_02
DEFW magnet_level_03
DEFW magnet_level_04
DEFW magnet_level_05
DEFW magnet_level_06
DEFW magnet_level_07
DEFW magnet_level_08
DEFW magnet_level_09
DEFW magnet_level_10
DEFW magnet_level_11
DEFW magnet_level_12
DEFW magnet_level_13
DEFW magnet_level_14
DEFW magnet_level_15
DEFW magnet_level_15 ; Для чего-то продублирован 15-й уровень
; Data block at 8E26
; Первый байт - количество магнитов на уровне, далее по два байта их координаты
magnet_level_15:
DEFB $02,$4C,$82,$9C,$82
magnet_level_14:
DEFB $04,$8C,$24,$C4,$24,$8C,$64,$C4,$64
magnet_level_13:
DEFB $04,$10,$20,$D8,$20,$18,$6C,$D0,$6C
magnet_level_12:
DEFB $03,$74,$08,$20,$44,$C8,$44
magnet_level_11:
DEFB $02,$5C,$84,$8C,$84
magnet_level_10:
DEFB $01,$74,$44
magnet_level_09:
DEFB $04,$40,$3C,$A8,$3C,$54,$6C,$94,$6C
magnet_level_08:
DEFB $03,$74,$18,$4C,$74,$9C,$74
magnet_level_07:
DEFB $02,$30,$5C,$D8,$5C
magnet_level_06:
DEFB $03,$74,$10,$48,$73,$A0,$73
magnet_level_05:
DEFB $00
magnet_level_04:
DEFB $01,$74,$7C
magnet_level_03:
DEFB $00
magnet_level_02:
DEFB $01,$74,$2C
4. Враги: всего есть два вида врагов и они, также как и текстуры, просто чередуются от уровня к уровню.Код:; Routine at BE8B
;
; Used by the routine at LB9E8.
; Рисуем полный игровой экран со всеми элементами в буфере
game_screen_draw_to_buffer:
LD HL,spr_level_textures
LD A,(current_level_number_1up)
AND $03
ADD A,A
CALL hl_add_a
LD E,(HL)
INC HL
LD D,(HL)
LD (current_texture+1),DE ; Помещаем указатель на текстуру уровня