Один добрый человек откликнулся на мой зов, помог с редактором карт в ROM~е.
Мне не до этого (Уже настоящая война пошла, а я тут в игрушки всё играл...), так что я просто выложу наработки, поскольку давно обещал. И пока закончу с этими делами.
http://www.emu-land.net/forum/index.php/topic,85072.msg1524987.html#msg1524987Ответы от
SharpnullДанные местности сжаты. Для получения адреса на сжатые данные использовал
http://chief-net.ru/forum/topic.php?forum=4&topic=76&postid=1609167083#1609167083, его программа для сжатия
http://chief-net.ru/forum/topic.php?forum=4&topic=76&postid=1609317116#1609317116. Для разжатия нужно указать адреса с $, потом выбрать ром и файл сохранения. Сжатие не пробовал.
Есть тип клетки, от этого зависит описание при наведении курсора (лес и т. п.), в RAM 27B0-2DEF, по 1 байту. Адреса в ROM с 65CE6 по 4 байта (Big-Endian).
Отображаемый блок (графика) в RAM 6DD4-7A53, по 2 байта. Адреса в ROM с 66F58. В ROM блок хранится по 1 байту и при загрузке конвертируется в 2 байта.
Адреса через Lua-скрипт ловил так. Тип клетки отображается перед экраном "How many players?". Блоки после "You are about to take the first step into battle.", я ловил запись в FF6DD4 и смотрел адреса, потому что потом сразу были другие распаковки данных.
Адреса (начальный - конечный) для типа и блока:
1. 650CC - 65347, 65CFE - 66128
2. 6534A - 6547B, 6612A - 662C9
3. 6547E - 655DC, 662CC - 6646B
4. 655DE - 65819, 6646E - 6679E
5. 6581C - 65AA9, 667A0 - 66C2C
6. 65AAC - 65CE3, 66C2E - 66F56
Не пробовал переносить данные, может кроме адреса потребуется ещё указать размер данных. Перенос потребуется, если сжатые данные будут больше по размеру.
Я в эту игру не играл, может вам нужно что-то ещё.
Попробовал распаковать все 12 сжатых блоков данных и новая программа от Марата не справилась со 2-м сценарием, старая сработала (
https://www.romhacking.net/utilities/1081/), но там нужно вырезать данные из рома. Придётся дописывать новую программу.
Ещё про сжатие. Вы можете расширить ром до 2МБ и сделать сжатие "без сжатия", тогда можно будет напрямую менять значения. 40*40*12 = 19200 байт для данных, + 19200/8 для FF через каждые 8 байт, ещё у каждого куска данных: 00 в конце и в начале 2 байта, которые не понял зачем. В любом случае, если сжимать случайные данные, то будет превышен размер в 1МБ данных, а пользователь может такого добиться, значит проще сразу распаковать данные и не придётся реализовывать сжатие в вашем редакторе, если только уже его не сделали. Ещё можно сэкономить память, если убрать алгоритм сжатия для этих данных, но придётся разбираться в коде.
Зря вы писали редактор в Excel, это неудобно для пользователей.
МОЙ ОТВЕТПока поразбираюсь ещё сам, но от запаковки-распаковки, конечно, хочется отказаться. ROM расширял уже, пусть будет 2 Мб.
Как "сообщить игре", что блок по указанному нами адресу уже будет не запакован? Там какой-то код где-то, или в типе сжатия блока в начале?
Сейчас немного болен, проснулся среди ночи, но не могу долго у компа сидеть, поэтому пока пишу кратко.
Идей, конечно, ещё очень много есть... Возможно, позже допишу.
Касательно карты ещё вот такое: при боях в городах отрисовывается местность города, она тоже где-то хранится. Найти - так сможем тогда и города свои рисовать.
Общий вопрос такой: какие есть хорошие отладчики, чтобы ловить нужные моменты в них?
ОТВЕТЯ посмотрел код и не нашёл использования флагов, там просто код, который выбирает адрес, распаковывает в один адрес RAM и копирует оттуда уже куда нужно.
Для типов клеток (не графика) с ROM $A644:
move.l #$00065CE2,A0 ; Адреса на данные по сценариям
move.l $00(A0,D0),-(SP) ; В D0 смещение сценария
pea $F9C0(A6) ; Куда распаковать
jsr ($00003360) ; Распаковка
pea ($0640) ; Сколько копировать
pea ($00FF27B0) ; Куда копировать
pea $F9C0(A6) ; Откуда копировать ($FFE968)
jsr ($00007FA4) ; Копировать
Я заменил и вроде работает прямое копирование:
move.l #$00065CE2,A0 ; Адреса на данные по сценариям
nop nop nop nop nop nop nop
pea ($0640) ; Сколько копировать
pea ($00FF27B0) ; Куда копировать
move.l $00(A0,D0),-(SP) ; Откуда копировать. В D0 смещение сценария
jsr ($00007FA4) ; Копировать
В роме нужно сделать изменения: A64A: 4E71 4E71 4E71 4E71 4E71 4E71 4E71, A662: 2F 30 08 00. Также указать адрес на несжатые данные с 65CE6. Зная начальные распакованные данные оригинала, вам не придётся реализовывать даже распаковку.
С распаковкой блоков графики чуть сложнее, там преобразование байтов в 2 байта (не знаю их смысл). Видимо нужно заменить код с ROM $A69A:
move.l #$00066F58,A0
move.l $00(A0,D0),-(SP)
pea $F9C0(A6)
jsr ($00003360)
На копирование в место распаковки:
move.l #$00066F58,A0
pea ($0640) ; Сколько копировать
pea $F9C0(A6) ; Куда копировать
move.l $00(A0,D0),-(SP) ; Откуда копировать. В D0 смещение сценария
jsr ($00007FA4) ; Копировать
Здесь не хватает места, нужно использовать ассемблер для выноса кода.
Я не следил, но не видел раньше упоминаний удобных как Mesen. DrMefisto делал модификацию для RetroArch с окном кода как в Gens r57shell и потом убрал его ради IDA, похоже все эксперты её используют. После Mesen хотелось похожего, но нет. Я давно улучшал GensKMod, но забросил и не дошёл до окна с кодом. В идеале думал взять код от сырого Mesen-S и прикрутить к BlastEm, но я не занимаюсь хаками для MD. Для поиска в RAM я использую BizHawk. Gens r57shell нужно дорабатывать (окно кода, HEX-редактор у меня тормозит эмуляцию [в Win10 после Win7 у меня окна заметно тормозят] и т. п.), а исходный код только от старой версии, но я его использую для разбора кода, также там Lua-скрипты. Для Sega CD и 32X я пару раз использовал MAME, он имеет универсальный отладчик, поэтому не очень удобный, но мне было достаточно, там можно указывать условие остановки на записи/чтении/выполнении инструкции. Exodus у меня плохо работал. У BlastEm консольный отладчик. Я вообще не видел чего-то удобного и самодостаточного как Mesen.Не думаю, что смогу особо помочь, я плохо знаю код M68K, только интуитивно.
На счёт программ от Марата. В новой версии указывать конец данных не нужно, только начало, программа высчитывает конец, потому что конец данных в алгоритме сжатия есть. А вот сжатие там не работает у меня. В любом случае, вы будете работать с несжатыми данными.
Опять мои вопросы:А например, как этот ВЫНОС сделать в разных вариантах? Есть, где прочитать?
У меня есть ещё места, которые нужно переделать с выносом кода.
Например, вот, нашёл в июле 2020 года, там ещё хуже:
03D3CE добавление самолётов после рейда в 10 от A4 (например, FF015E)
Вот здесь идёт обнуление самолётов к началу суток:
03C640 426A 0010 CLR.W $0010(A2)
Надо задействовать команду:
3578 0008 0010 move.w 8,$10(A2)
А она длиннее оригинальной.
Или использовать JSR/BSR и RTS, чтобы вернуться обратно. Или оба два раза JMP.
Вроде этого:
00037C 4EB9 0000 1D0A JSR $00001D0A
0003AC 4E75 RTS
Пустое место в коде начинается от 076400. Вписываем свой код по адресу 076400
Завершаем его RTS (4E75)
Код вызываем, например, по JSR: 4EB9 0007 6400
Осложнение: дополнительные вызовы и PEA в участке кода
А есть идеи и по дополнительному коду, например, разбомбить или заминировать мост, показать итоги боя, ввести свои формулы для расчётов, там уже вынос обязателен...
Продолжение от SharpnullКонкретно про вынос не знаю, но нам нужен прыжок, так что смотрите инструкции меняющие текущий PC. Вы сами написали и уже знаете про PEA, а я не подумал про проблему с PEA и move.l $00(A0,D0),-(SP): они изменяют стек как и JSR/BSR, поэтому вместо них подойдёт JMP или BRA.
В данном случае мы освободили место рядом (для коротких bra.b или bra.w) где тип клеток распаковывался, там я поставил ранее 7 * NOP (14 байт), можно добавить код туда примерно так (я не компилировал):
; Свободные 14 байт от типа клеток
A64A:
bra.b skip_new_code ; 2 байта
new_code:
pea ($0640) ; Сколько копировать. 4 байта
pea $F9C0(A6) ; Куда копировать. 4 байта
bra.w return_from_new_code ; 4 байта. Или bra.b - 2 байта + nop
skip_new_code:
A69A:
move.l #$00066F58,A0 ; Это было
bra.w new_code ; 4 байта. Или bra.b - 2 байта + nop
return_from_new_code:
move.l $00(A0,D0),-(SP) ; Откуда копировать. В D0 смещение сценария
jsr ($00007FA4) ; Копировать
Свободного места как раз хватает.