Перейти к содержимому

Мимо проходящий

Пользователи
  • Публикации

    18
  • Зарегистрирован

  • Посещение

Все публикации пользователя Мимо проходящий

  1. Отредактируй Objects.cfg: в разделе [objects] произведи замены: 11=[%z,0:"11"] на 11=[%z,0:"11",2:"11"] 50=[%z,4:"50"] на 50=[%z,4:"50",2:"50"]
  2. Теоретически мост с шестнадцатью брёвнами можно получить, присвоив объекту подтип $10 (16). Но в S1LE для считывания и редактирования длины моста используются только первые четыре бита подтипа. Открой файл Objects.cfg и перейди к объекту 11. Замени все "%b0123" на "%b01234". Это задействует пятый бит, что позволит увеличить максимальную длину моста с 15 до 31 (в действительности -- до 16, т.к. более длинные мосты генерируются игрой с ошибками).
  3. Price5115, у тебя изменены третий и четвёртый тайлы, а также с седьмого по десятый. В S1LE приблизься до любого тайла, кнопками Z/X поменяй номер на 003, приблизься до точек и отредактируй.
  4. Попробуй тогда удалить код проверки зоны, первые 5 строк той же самой процедуры. В итоге должно стать так: Sonic_Loops: move.w $C(a0),d0 lsr.w #1,d0 andi.w #$380,d0 move.b 8(a0),d1 и т.д...
  5. Dr_Robotnik, к сожалению, программа не работает с файлом SourceCode\misc\loopnums.bin. Тебе придётся отредактировать его вручную. Открой файл любым Hex-редактором. Первые четыре байта отвечают за зону GHZ, вторые четыре - за LZ, третьи четыре - за MZ, и т. д. Структура этих байтов такова: первые два - это номера чанков с петлями, вторые два - номера чанков с туннелями. Например, для первой зоны значения байтов: B5 7F 1F 20 B5 - это 35 чанк (надо отнять 80). При прохождении по 35 чанку вниз головой, этот чанк меняется на СЛЕДУЮЩИЙ, 36-ой, такой же, как 35-ый, только с другими коллизиями. 7F - второй чанк с петлёй не задан. 1F - номер первого чанка с туннелем. 20 - номер второго чанка с туннелем. Кроме того, чтобы добавить петлю в Marble Zone, придётся внести изменения в исходный код. Открой sonic1.asm, перейди к процедуре Sonic_Loops: и добавь в её начало следующее: cmpi.b #2,($FFFFFE10).w ; is level MZ ? beq.s loc_13926 ; if yes, branch Теперь, помимо GHZ и SLZ, на петли и туннели будет проверяться и MZ.
  6. Almaz, ты не понял, сеговский процессор не занимается поворотом спрайтов. Спрайты уже сгенерированы и находятся внутри РОМа. Motorola 68K просто подгружает их из РОМа по мере необходимости. Хотя твоя идея хороша. Вначале я так и планировал – каждый кадр поворачивать Соника на определённый угол при помощи подпрограммы – но потом, прикинув, сколько вычислительных операций придётся делать процессору, отказался от этой затеи.
  7. Всем известно, что SonED 2, входящий в комплект S1HS, не совсем удобен в работе, а в некоторых случаях даже даёт сбои. Посему предлагаю вам свою альтернативу. S1LE (Sonic 1 Level Editor) - многофункциональный редактор уровней для игры Sonic The Hedgehog (Sega Genesis). Несомненные плюсы редактора: • интуитивный минимизированный интерфейс • полноценный зуминг • отражение изменений в режиме реального времени • поддержка горячих клавиш • запуск уровня в эмуляторе одним нажатием клавиши Программа позволяет: • редактировать чанки, блоки и тайлы (в том числе циклические) • осуществлять расстановку объектов и Соника на уровне • расширять границы камеры и устанавливать уровень воды • редактировать специальные этапы Некоторые известные минусы: S1LE.rar Как установить сиё чудо. Просто кидаете папку S1LE в папку S1HS. Внимание! Лучше устанавливать содержимое поверх ЧИСТОЙ копии S1HS. Продукт распространяется по принципу "как есть", поэтому я не несу ответственности за порчу или потерю любых ваших данных. Надеюсь, моя программа окажется полезной.
  8. Как известно, Соник в режиме бега или ходьбы может поворачиваться на углы в 0, 45, 90 и 135 градусов. Мне стало любопытно: что, если увеличить количество углов наклона в несколько раз, добавив промежуточные? Для этого я написал специальную программу, которая загружает спрайты горизонтального бега/ходьбы и поворачивает их на углы, кратные 11,25º. Каждое полученное изображение разбивается на тайлы, последние сохраняются в файл. Одновременно с этим генерируются нужные маппинги и dplc. Наглядная демонстрация работы программы: Результат: Соник стал поворачиваться более плавно на подъёмах, спусках и петлях. Особенно эффект заметен на холмах зоны Marble Zone. Интересно также смотрится, как Соник пытается в воздухе вернуться в вертикальное положение, будучи в горизонтальном. Для этого в первом акте Spring Yard Zone ударьтесь о первую пружину. s1smtd.rar
  9. Всему виной колючка с подтипом $13 (обведена окружностью). Замени на $10. Но это ещё не всё: глубоко внизу, за пределами карты уровня, находится ещё одна такая же колючка. SonED'ом её не достать, попробуй воспользоваться Hex-редактором. Рекомендую WinHex. Открой в нём файл "SourceCode\objpos\ghz3.bin", найди значение "0B9015403613", выдели и удали (кнопкой Delete).
  10. Мой хак. http://webfile.ru/6546352
  11. Интересно. Наверняка работа над просчётом динамически изменяющихся границ отняла немало времени. Чётко сделано.
  12. Закомментировать - значит поставить точку с запятой ПЕРЕД нужной командой. Вот так: bsr.w Sonic_Water То есть, теперь это не команда прыжка на Sonic_Water, а просто текст, который компилятор просто проигнорирует и не станет превращать в машинный код. Фактически, комментирование команды аналогично её удалению. А вот следующий код: bsr.w Sonic_Water ;not water in lz ничего не изменит. Комментарием считается текст, начинающийся с ";" и заканчивающийся последним символом строки. Первая часть строки, команда "bsr.w Sonic_Water", будет успешно обработана компилятором и переведена в машинный код, а вот вторая часть, следующая за точкой с запятой, проигнорируется.
  13. Открываешь sonic.asm в блокноте, ставишь курсор в начало документа, нажимаешь Ctrl+F, вписываешь "#1,($FFFFFE10).w" в поисковую строку, жмёшь "найти далее". Поисковик перенесёт курсор на инструкцию "cmpi.b #1,($FFFFFE10).w". После неё идёт что-то вроде "bne.s XXX" или "bne.w XXX", где bne - условный переход по ссылке XXX в случае, если уровень не LZ. Меняешь bne.w на jmp. Продолжаешь поиск и проделываешь всё то же самое ещё 7 раз (всего 8 раз). Дальше поиск продолжится в разделе "объекты", его не трогаем. Последнее: переходишь по ссылке "loc_12C7E:" и комментируешь команду "bsr.w Sonic_Water", поставив перед ней точку с запятой. Готово. Воды нет. Правда, движение на уровне LZ становится немного обрывистым; не знаю, с чем это связано, особо не углублялся в эту тему. Но эмпирически оптимальное решение можно всегда найти.
  14. Решение задачи с комодом:
  15. Как в Sonic1 записать собственный демонстрационный ролик. К счастью, в оригинальном роме уже есть подпрограмма записи демо-роликов (MoveDemo_Record). Нужно всего лишь слегка подправить уже имеющийся код. 1. Первым делом переходим к MoveSonicInDemo и комментируем команду "rts" таким образом: MoveSonicInDemo: tst.w ($FFFFFFF0).w ; is demo mode on? bne.s MoveDemo_On ; if yes, branch ;rts Теперь если демо-режим не включён, выхода из подпрограммы не будет, процессор перейдёт в секцию MoveDemo_Record; 2. Первую же команду секции MoveDemo_Record "lea ($80000).l,a1" меняем на "lea ($FFFFA000).l,a1" Здесь мы устанавливаем адрес, куда будет записываться наш ролик. Адрес $80000 указывает на то, что запись будет производиться в РОМ, однако это невозможно, поскольку само понятие ROM'а (Read Only Memory) говорит о невозможности проведения такой акции. Выбора нет - остаётся ОЗУ. Самое подходящее место для этого, я считаю, - блок памяти $FFFFA000-$FFFFA3FF. Места размером в $400 байт нам вполне достаточно. Это место зарезервировано для двух последних чанков (под номерами $51 и $52), которые традиционно пусты и не используются. Временно пожертвуем ими. 3. Теперь переходим в подпрограмму Joypad_Read и сразу после "or.b d1,d0" вставляем четыре строчки: move.b d0,d2 rol.b #1,d2 and.b ($FFFFFFF1).l, d2 bne.b Joypad_Read_Rts Шестью строчками ниже прямо перед "rts" вставляем вот это: Joypad_Read_Rts: Это необходимо для подключения обработки события Joypad|Press в демо-режиме. Отныне JumpDash, HomingAttack и другие функции, использующее это событие, будут записываться корректно. Код готов. Переходим непосредственно к тому, для чего и создавалась данная статья, - к записи видео. Для начала скачиваем эмулятор Gens KMod: http://www.romhackin.../utilities/301/ Компилируем наш хак и запускаем в эмуляторе. Переходим к первому уровню (Green Hill Zone, Act 1), начинаем играть. Как только начнётся отсчёт времени и активизируется управление Соником, программа автоматически начнёт запись нашего демо-ролика в оперативную память. Не спешите зажимать клавиши раньше времени, иначе видео рассинхронизируется. У нас в запасе имеется 30 секунд, после чего demo-режим отключится, и включится режим SegaScreen. За полминуты можно пройти чуть ли не весь первый уровень. По истечении 30 секунд ставим игру на паузу. Теперь нам необходимо вырезать получившееся видео и вставить в наш хак. Для этого в эмуляторе переходим по команде CPU => Debug => Genesis => Genesis - 68K, и в появившемся окне нажимаем кнопку DUMP RAM. Сохраняем дамп (s1built_68K.ram) на диск и открываем его с помощью любого Hex-редактора, например WinHex. Параллельно в том же редакторе открываем файл demodata/i_ghz.bin. В файле s1built_68K.ram переходим по смещению 0000A000. Начиная с этого оффсета, записан нужный нам ролик. Формат данных таков: 1 байт на состояние зажатых кнопок, 1 байт на задержку (в кадрах), т.е. на любое одно изменение состояния джойстика требуется 2 байта. Вначале будут идти шестнадцатеричные числа, отличные от нуля, но изредка включающие нули. Чуть ниже будут идти уже сплошные нули. Так вот, нам нужен участок данных от 0000A000 до начала появления сплошных нулей. Выделяем этот блок и копируем в буфер обмена. Будет лучше, если мы заденем лишние нули, но последнюю строку выделим целиком. Например, на рисунке выше лучше выделить участок от 0000A000 до 0000A08F. Открываем i_ghz.bin и перезаписываем его, вставив из буфера новые данные (в WinHex: устанавливаем курсор на позицию 0 и Ctrl+B или Правка -> Данные буфера -> Запись). Ничего страшного, если вписываемые данные по объёму будут больше, чем исходный файл: если программа спросит разрешение на расширение места, согласитесь. Сохраните i_ghz.bin. Снова откомпилируйте ром, запустите и наслаждайтесь проделанной работой. Этот трюк можно проделать и с уровнями Marble Zone, Spring Yard Zone, Special Stage (демо-записи хранятся в файлах i_mz.bin, i_syz.bin, i_ss.bin соответственно). Для быстрого перехода к этим уровням воспользуйтесь кодом выбора уровня. Если вы хотите записать, к примеру зону Star Light, то можно отредактировать список воспроизводимых уровней (файл misc\dm_ord1.bin). Количество воспроизводимых уровней задаётся в секции loc_33E4: в инструкции "cmpi.w #4,($FFFFFFF2).w" поменяйте четвёрку, если необходимо. Время воспроизведения задаётся в секции Level_Demo: в инструкции "move.w #1800,($FFFFF614).w" число 1800 показывает количество кадров (1800 кадров - 30 секунд). Отключить запись demo можно, раскомментировав команду "rts" в MoveSonicInDemo. Надеюсь, мой гайд окажется полезным.
  16. Всем отписавшимся отвечаю. Я не претендую на авторство, этот код целиком и полностью принадлежит Владу. Присваивать его себе я не собирался. Выложив код в открытый доступ, я, таким образом, преследовал цель "наказать" автора за его "наглость" в кавычках. Меня, как программиста, очень задели его слова о том, что составить такой код, якобы, никто не в силах. Я воспринял это как вызов. Я задался целью, пусть и не сам, пусть методом взлома, но написать эту фичу. Если бы я хотел выдать код за свой, я мог бы изменить его до неузнаваемости: мог бы изменить регистры, участки памяти, структуру. Я не стал этого делать. Я специально оставил всё как есть, чтобы vladikcomper смог узнать своё детище. Влад, надеюсь, ты не обижаешься на меня. В конце концов, настало время сказать НЯ.
  17. Это был ответ vladikcomper'у на его заявление "Совершенно очевидно, что в России код Хоминга в ближайшее время никто не составит". На отладку хака Megahack Ultra и написание кода ушло всего три дня.
  18. Как добавить в Sonic 1 самонаводящуюся атаку. Прежде чем испробовать эту особенность Соника, настоятельно рекомендую потереть старый JumpDash от vladikcomper'а. Если он у вас, конечно, стоит. Переходим по ссылке Obj01_MdJump2. В самое её начало вписываем это: bsr.w Sonic_JumpDash Далее, в любое свободное место вставляем следующий код. Я лично вставил его после Sonic_JumpHeight. Для этого найдите строчку «; End of function Sonic_JumpHeight». Сразу после нее вставьте новый код: Sonic_JumpDash: cmpi.b #$02,($FFFFFFEB).w ; if STATE == HOMING beq.s Sonic_JD_ChkFramesCount ; checking frames tpress A+B+C,(SonicControl) ; if A, B or C pressed bne.s Sonic_JD_Init ; then initialize rts Sonic_JD_ChkFramesCount: subq.b #01,$001F(a0) ; decrement count of remained frames bne.s Sonic_JD_ExecHoming ; if frames > 0, execute homing clr.b ($FFFFFFEB).w ; if not, then not rts Sonic_JD_ExecHoming: move.w $003A(a0),a1 ; get address of object move.w $000C(a1),d1 ; get Y-pos of object sub.w $000C(a0),d1 ; get deltaY move.w $0008(a1),d2 ; get X-pos of object sub.w $0008(a0),d2 ; get deltaX jsr CalcAngle.l ; calculate Angle (A) jsr CalcSine.l ; get sin & cos of Angle (A) move.w #$00001000,d3 ; set homing speed (HS) muls.w d3,d0 ; get X-velocity (sin(A)*HS) muls.w d3,d1 ; get Y-velocity (cos(A)*HS) asr.l #8, d0 ; X-velocity / 256 asr.l #8, d1 ; Y-velocity / 256 move.w d1,$0012(a0) ; SET Y-velocity move.w d0,$0010(a0) ; SET X-velocity move.w d0,$0014(a0) ; SET Ground-velocity rts Sonic_JD_Init: lea ($FFFFD800).w,a1 ; set address of Objects move.w #$005F,d6 ; set max count of Objects for checking moveq #$FFFFFFFF,d3 ; set minimal distanсe from Object to Sonic Sonic_JD_CheckObject: tst.b $01(a1) ; check1 bpl.w Sonic_JD_NextObject tst.b $20(a1) ; check2 bne.w Sonic_JD_GoodObject Sonic_JD_NextObject: lea $0040(a1),a1 ; select next Object block dbf d6, Sonic_JD_CheckObject ; repeat until reach last Object cmpi.l #$00006400, d3 ; check distance from Sonic to closest Object bhi.w Sonic_JD_ExecJumpDash ; if too far, execute JumpDash Sonic_JD_InitHoming: move.b #$3C,$001F(a0) ; set count of frames for Homing Attack move.b #$02,($FFFFFFEB).w ; current STATE = HOMING move.w #$00BC,d0 ; select JD sound jmp (PlaySound_Special).l ; play JD sound Sonic_JD_GoodObject: lea Sonic_JD_ObjectsDB,a2 ; get address of Objects' database move.b (a1),d0 ; get number of current Object Sonic_JD_IsObjectInTheDB: cmp.b (a2)+,d0 ; if object number is there in the database beq.b Sonic_JD_GetDX ; if yes, calculate DX bhi.b Sonic_JD_IsObjectInTheDB ; else, repeat bra.w Sonic_JD_NextObject Sonic_JD_GetDX: move.w $0008(a1),d1 ; get X-position of Object sub.w $0008(a0),d1 ; minus X-position of Sonic bpl.b Sonic_JD_ObjectToTheRight Sonic_JD_ObjectToTheLeft: btst #0, $0022(a0) ; if Sonic looks left beq.w Sonic_JD_NextObject ; if not, go to the next Object bra.b Sonic_JD_GetDY Sonic_JD_ObjectToTheRight: btst #0,$0022(a0) ; if Sonic looks right bne.w Sonic_JD_NextObject ; if not, go to the next Object Sonic_JD_GetDY: move.w $000C(a1),d2 ; get Y-position of Object sub.w $000C(a0),d2 ; minus Y-position of Sonic Sonic_JD_ChkClosestObject: muls.w d1,d1 ; DX^2 muls.w d2,d2 ; DY^2 add.l d1,d2 ; DX^2+DY^2 cmp.l d3,d2 ; compare distanсes bcc.w Sonic_JD_NextObject Sonic_JD_SetClosestObject: move.l d2,d3 ; set current Object as closest move.w a1,$003A(a0) ; set current Object for Homing Attack bra.w Sonic_JD_NextObject ; database of valid objects to do homing attack with ; numbers MUST BE in ascending order Sonic_JD_ObjectsDB: dc.l $1E1F2226, $2B2C2D40, $42435055, $6078FF00 Sonic_JD_ExecJumpDash: tst.b ($FFFFFFEB).w ;if STATE == JUMPDASH bne.w Sonic_JD_Rts ; if not, branch move.b #$01,($FFFFFFEB).w ; current STATE = JUMPDASH move.w #$0A00,d0 ; set X-velocity to $A00 btst #6,$22(a0) ; is Sonic underwater? beq.w Sonic_JD_ChkShoes move.w #$0600,d0 ; if underwater, set X-velocity to $60 Sonic_JD_ChkShoes: tst.b ($FFFFFE2E).w ; does Sonic have speed shoes? beq.w Sonic_JD_ChkOrientation ; addi.w #$0200,d0 ; set speed to $C00 or $800 if underwater Sonic_JD_ChkOrientation: btst #0,$0022(a0) ; where Sonic looks to? beq.w Sonic_JD_SetSpeed; if not to right, then neg.w d0 ; reverse X-velocity Sonic_JD_SetSpeed: move.w d0,$0010(a0) ; SET X-velocity move.w d0,$0014(a0) ; SET Ground-velocity move.w #$0000,$0012(a0) ; SET Y-velocity move.w #$00BC,d0 ; select JD sound jsr (PlaySound_Special).l ; play JD sound Sonic_JD_Rts: rts Sonic_JD_StopHoming: cmpi.b #$02, ($FFFFFFEB).w ; if STATE == JUMPDASH bne Sonic_JD_StopHoming_Rts ; if not, branch clr.b ($FFFFFFEB).w ; STATE = NORMAL move.w #$FA10,d0 ; set Y-velocity to -5F0 btst #6,$22(a0) ; is Sonic underwater? beq Sonic_JD_StopHoming_ChkShoes move.w #$FCE0,d0 ; if underwater, set X-velocity to -320 Sonic_JD_StopHoming_ChkShoes: tst.b ($FFFFFE2E).w ; does Sonic have speed shoes? beq Sonic_JD_StopHoming_SetSpeed move.w #$F9E0,d0 ; set X-velocity to -620 Sonic_JD_StopHoming_SetSpeed: move.w #$0000,$0010(a0) ; SET X-velocity move.w d0,$0012(a0) ; SET Y-velocity Sonic_JD_StopHoming_Rts: rts В секции Sonic_ResetOnFloor в самое начало добавляем: clr.b ($FFFFFFEB).w ; STATE = NORMAL Далее переходим к loc_1AF1E и после "addq.b #2,$24(a1)" вписываем: jmp Sonic_JD_StopHoming И, наконец, в секции loc_1AF9C после "bsr.w AddPoints" вставляем: jsr Sonic_JD_StopHoming Откомпилируйте и проверьте - работает! Каждый кадр, покамест ёжик крутится в воздухе, процессор непроизвольно переходит по нашей ссылке, в который вписан практически весь сценарий выполнения усовершенствованного JumpDash'а. Первой миссией нашей программы становится поиск объектов, удовлетворяющих следующим требованиям: 1) объект входит в список целей, разрешённых для выполнения самонаводящейся атаки. Этот пункт можно отредактировать, изменив байты в следующем участке нашего кода: Sonic_JD_ObjectsDB: dc.l $1E1F2226, $2B2C2D40, $42435055, $6078FF00 Здесь 1E, 1F, 22, 26, 2B, 2C и т.д. - это т.н. номера объектов, характеризующие вид объекта. К примеру 22 - это летающие осы. Какой номер что означает можно узнать из программы SonED2. По умолчанию установлено 14 объектов. Вы можете увеличить их количество добавлением новых dc.l, dc.w, dc.b - как угодно, на ваше усмотрение. Последний байт (00) ни в коем случае не менять. Программа должна знать, где закончить. ВНИМАНИЕ! Байты должны идти в строго возрастающем порядке. 2) объект находится в поле зрения Ёжика, а не за ним. Далее находится расстояние от Соника до объекта (точнее, квадрат расстояния) и сравнивается с кратчайшим расстоянием, таким образом вычисляется ближайший к герою объект. Если таких объектов поблизости нет, выполняется старый добрый JampDash. В противном случае записываем адрес объекта-цели в память и каждый кадр будем менять положение Соника по отношению к врагу в сторону сближения, чтобы в конце концов уничтожить последнего. Это и есть самонаводящаяся атака. Сближение по умолчанию производится в течение 31 кадра, после чего эта особенность отключается. Тем не менее, этого достаточно, чтобы провести молниеносную атаку. При столкновении с целью или препятствием, самонаводящаяся атака также отключается. Надеюсь, мой гайд окажется полезным.
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×