| Разработка и ромхакинг > Ромхакинг и программирование |
| [NES] Код эмулятора и код игры в одно целое. |
| (1/1) |
| teremochek:
Такая мысль. Хорошо-бы иметь исходный код игры с эмулятором, которые вместе компилируются в игру. К тому-же код игры сделать с заметой "BNE, BEQ и т.д." на If операторы. Как это сделал "Movax12". Затем модифицировать игру(ы), добавив в нее мультиплеер с большим количеством человек.(8-32). В иделе нужно иметь несколько популярных игр(аркад). Начать лучше с марио, т.к. в нем все разобрано.. Пока что я начал портировать HalfNes на BlitzMax. И Увяз, не получается. Не знаю может есть какой-нибудь хороший, простой эмулятор с открытым исходным код, который будет удобнее использовать. Пока, из тех эмулей, которые я смотрел... Каждый эмулятор, как загадка. Если бы вы только представляли, на сколько в них разный код и синтаксис и все остальное. Капитально возится с каждым придется, что-бы разобраться, как и где что работает. Добавлено позже: disassembly_pc = PC if PC>=8000 and PC<=8024 '... some code else current_inst:Byte = ReadRomByte() Opcodes( current_inst ) endif Вот таким вот примерно образом, перевести ассемблер рома в просто код. Частями, проверяя каждую. В идеале можно избавиться от счетчика команд и регистров. Таким образом можно будет добавлять любое количество кода, в любое место*. |
| Mr2:
teremochek, не живётся тебе спокойно... :lol: |
| JAM:
:facepalm: Пока ты всё это время пытаешься перевести ASM на NES в понятный код, я уже успел его более-менее выучить :lol: |
| yur:
teremochek, как твои успехи в изучении 6502 - может поделишья полезной инфой, а то на этом форуме принято у многих балаболить и мешать другим, мало того что мешают так ещё и обещают обнародовать доки с подробной инфой |
| teremochek:
--- Цитата: yur от 24 Февраль 2014, 11:59:14 ---teremochek, как твои успехи в изучении 6502 - может поделишья полезной инфой, а то на этом форуме принято у многих балаболить и мешать другим, мало того что мешают так ещё и обещают обнародовать доки с подробной инфой --- Конец цитаты --- Извиняюсь что не ответил сразу, но успехов нет. Портировать эмулятор я не осилил. Почитал книгу. "Игровые Приставки" Выпуск 21. Королев А.Г. Очень доволен. Всем советую, кто искал полезную информацию о устройстве NES,GB,SMD,PS. Хочется сказать что это как библия эмуляторщика) Что хочу сказать. Я понял почему сложно сделать более простой и понятный код из ассемблера. Дело в том CPU связан с PPU и APU. То есть несколько процессоров, которые должны быть синхронизированы. Нельзя сделать долгий или бесконечный цикл в CPU. Нужно иногда проверять что происходит в PPU и APU. В итоге получается рваный код. Вот приведу пример. Я Начал встраивать Ассемблер в CPU класс эмулятора (HalfNes). --- Код: --- if (PC >= 0x8000 && PC <= 0x8009) {// reset delayInterrupt(); interruptsDisabled = true; cycles += 2;//SEI 78 decimalModeFlag = false; cycles += 2; //CLD D8 PC=0x8002; lda(imm()); cycles += 2; //LDA A9 10 PC=0x8004; sta(abs()); cycles += 4; //STA 8D 00 20 PC=0x8007; ldx(imm()); cycles += 2; //LDX A2 FF S = X; cycles += 2; //TXS 9A PC=0x8009;//////////// PC++; //ram.read(PC++); } else if (PC >= 0x800A && PC <= 0x800E) {// VBlank1 lda(abs()); cycles += 4; // 00:800A:AD 02 20 LDA $2002 = #$50 PC=0x800D; isc(abs(Y, dummy.ALWAYS)); cycles += 7; // 00:800D:10 FB BPL _DO_WHILE_0001 } else if (PC >= 0x800F && PC <= 0x8013) {// VBlank2 lda(abs()); cycles += 4; // 00:800F:AD 02 20 LDA $2002 = #$50 PC=0x8013; isc(abs(Y, dummy.ALWAYS)); cycles += 7; // 00:8012:10 FB BPL _DO_WHILE_0002 _DO_EXIT___LOOP_ } else if (PC >= 0x8014 && PC <= 0x8017) { PC=0x8015; ldy(imm()); cycles += 2; // 00:8014:A0 FE LDY #$FE PC=0x8017; ldx(imm()); cycles += 2; // 00:8016:A2 05 LDX #$05 } else if (PC >= 0x8018 && PC <= 0x801E) {// WBootCheck //WBootCheck lda(abs(X, dummy.ONCARRY)); cycles += 4 + pb; // 00:8018:BD D7 07 LDA DisplayDigits TopScoreDisplay,X @ $07DC = #$00 PC=0x801C; cmp(A, imm()); cycles += 2; // 00:801B:C9 0A CMP #$0A PC=0x801E; branch(carryFlag); cycles += 2 + pb; // 00:801D:B0 0C BCS _END_IF_0002 coldboot } else if (PC >= 0x801F && PC <= 0x8021) { //IF_CODE_BLOCK_START_LABEL_0001: X--; X &= 0xFF; setflags(X); cycles += 2; // 00:801F:CA DEX PC=0x8021; isc(abs(Y, dummy.ALWAYS)); cycles += 7; // 00:8020:10 F6 BPL WBootCheck } else if (PC >= 0x8022 && PC <= 0x8028) {// _DO_EXIT___LOOP_CONTINUE_0003: lda(abs()); cycles += 4; // 00:8022:AD FF 07 LDA WarmBootValidation = #$A5 PC=0x8026; cmp(A, imm()); cycles += 2; // 00:8025:C9 A5 CMP #$A5 PC=0x8028; branch(!zeroFlag); cycles += 2 + pb; // 00:8027:D0 02 BNE _END_IF_0002 coldboot //IF_CODE_BLOCK_START_LABEL_0002: PC=0x802A; ldy(imm()); cycles += 2; // 00:8029:A0 D6 LDY #$D6 //coldboot: --- Конец кода --- Пока вот такая каша. Надеюсь получится что-то поинтереснее) |
| spiiin:
teremochek ты так задолбаешься переписывать по порядку код. лучше на луа переписывать произвольные части кода игры, которые тебе интересно подменять, есть примеры модификаций игр, марио того же, с новыми фишками: https://www.youtube.com/watch?v=-jbFjhBYCjg |
| Inspector_Popabol:
А я могу пользуясь случаем спросить про римейк The Guardian Legend? Будь няшей! |
| teremochek:
--- Цитата: spiiin от 04 Май 2014, 21:47:00 ---teremochek ты так задолбаешься переписывать по порядку код. лучше на луа переписывать произвольные части кода игры, которые тебе интересно подменять, есть примеры модификаций игр, марио того же, с новыми фишками: https://www.youtube.com/watch?v=-jbFjhBYCjg --- Конец цитаты --- Верно, но в моем случае есть плюс. Есть код эмулятора, который можно изменять(Ну память к примеру увеличить.) К тому-же не обязательно все по порядку переписывать. Разумеется частями. Просто в идеале хотелось бы иметь код полностью оторванный от рома. |
| Segaman:
Вот смотрю я на вас и понимаю: хватит с меня интернета на сегодня :) |
| teremochek:
Задача не очень простая. Делаю маленькую ошибку, и все глючит конкретно. Т.е. нужно каждую частичку тестировать. В марио, если на глас мерить, то порядка где-то 400 Методов. А главное что все уже дизассемблировано и в высокий уровень переведено. Остается анализировать, писать и тестировать. Добавлено позже: --- Цитата: Segaman от 05 Май 2014, 22:47:19 ---Вот смотрю я на вас и понимаю: хватит с меня интернета на сегодня :) --- Конец цитаты --- Вот такие замечания мне нравятся :) |
| JAM:
Жду через 50 лет супер-пупер крутой хак на Марио, где можно будет играть ввосьмером на доработаном эмуле =) |
| teremochek:
Два дня ковырялся, разобраться не мог, почему все так глючит. Оказалось в дебаггере был один ром, а в ява эмуляторе другой.(Адреса не совпадают.) --- Цитата: JAM от 06 Май 2014, 23:48:31 ---... можно будет играть ввосьмером ... --- Конец цитаты --- Мыслишь в интересном направлении :) |
| teremochek:
Вот покажу один рабочий метод. --- Код: ---public void _DrawFireball() { if (PC < 0xECEA){ Y = ram.wram[FBall_SprDataOffset + X]; ram.wram[Sprite_Y_Position + Y] = ram.wram[Fireball_Rel_YPos]; ram.wram[Sprite_X_Position + Y] = ram.wram[Fireball_Rel_XPos]; cycles += 22 + pb; } //DrawFirebar: A = ram.wram[FrameCounter]; lsrA(); lsrA(); ram.read(0xECF1+1 + 1); push(A); A &= 0x01; A ^= 0x64; A &= 0xff; ram.wram[0x0201 + Y] = A; ram.read(0xECF9+1 + 1); A = pop(); lsrA(); lsrA(); A = 0x02; if (carryFlag){ A |= ram.wram[0xC0]; A &= 0xff; cycles += 2; } ram.wram[0x0202 + Y] = A; PC=0xED06; rts(); cycles += 37; } --- Конец кода --- Получается примерно тоже что и дизассемблер "Movax13". Только в данном случае плюс - быстрая компиляция. Пока еще много вопросов и задач предстоит решить. Такой минус еще есть. Java в полно экранном режиме подлагивает. Проверю потом Экзешник. Может в нем лучше будет. |
| teremochek:
Покажу, как я пишу метод. JSR ImposeGravity вызов субрутины заменяем на метод _ImposeGravity() public void _ImposeGravity() { } Затем нужно добавить две детали. Оператор JSR() и выход из рутины RTS() { PC=0xB6CD + 1; jsr(0xbfd7); JSR() .... PC=0xB6CD + 3; rts(); RTS() } После этого пишу тело метода. Проверяю, если все работает нормально, то операторы JSR и RTS можно убрать. Пока хочу как можно больше избавиться от привязанности к счетчику команд PC. Еще мечтаю, как увеличить кол-во спрайтов. |
| perfect_genius:
Я так и не понял - что ты хочешь от игры? На какую игру какой мультиплеер? И дай ссыль на то, что сделал Movax12, пожалуйста. Я не в курсе. |
| teremochek:
У меня небольшой успех. Я импортировал в эмулятор HalfNes 40 функций отвечающие за Огненный шар в игре "Super Mario Bros". В коде я избавился от счетчика команд PC. Так-же я заменил branch переходы на IF, DO LOOP. Честно такой большой минус что - Дебаггера нет. Поэтому приходилось все в ручную тестировать. Устал искать, исправлять ошибки. Плюсы такие: Компилируется быстро, код можно вписывать куда угодно, практический без ограничения, под рукой исходный код эмулятора, который тоже можно изменять. Минусы: Эмуляция подлагивает иногда. (К моему удивлению лагать перестало, кода отключил звук.) |
| teremochek:
--- Цитата: SUPER_ROBOT от 28 Июнь 2014, 22:49:28 ---Я так и не понял - что ты хочешь от игры? На какую игру какой мультиплеер? И дай ссыль на то, что сделал Movax12, пожалуйста. Я не в курсе. --- Конец цитаты --- Извиняюсь, что не ответил. Мозги от вопросов расплавились.. От игры я хочу мультиплеер. Желательно на много игроков.(Как в CS, Quake и т.д.) Еще, к примеру, если увеличить число спрайтов, тогда можно сделать хак c двойными боссами"The Guardian Legend". Для простоты я выбрал "SMB", потому что на него уже сделали исходный код. Вообщем-то я его и преобразую, параллельно заглядывая в дизассемблер fceux. Что-бы не было ошибок. Да, и еще адреса нужны. Честно я не фанат SMB и не знаю что с ним такого сделать. Вероятно следующим шагом, попробую увеличить число Fireballs(Огненных Шариков). Не уверен, можно-ли это сделать, без увеличения числа спрайтов. А так по идее, нужно расширить память. И поменять адреса переменных. Вот ссылки на "Super Mario Brothers High Level Disassembly" http://www.romhacking.net/documents/635/ Топик на форуме http://forums.nesdev.com/viewtopic.php?f=2&t=9780 Для сравнения: Код 1 --- Код: --- ProcFireball_Bubble: lda PlayerStatus cmp #$02 bcc ProcAirBubbles lda A_B_Buttons and #B_Button beq ProcFireballs and PreviousA_B_Buttons bne ProcFireballs lda FireballCounter and #%00000001 tax lda Fireball_State,x bne ProcFireballs ldy Player_Y_HighPos dey bne ProcFireballs lda CrouchingFlag bne ProcFireballs lda Player_State cmp #$03 beq ProcFireballs lda #Sfx_Fireball sta Square1SoundQueue lda #$02 sta Fireball_State,x ldy PlayerAnimTimerSet sty FireballThrowingTimer dey sty PlayerAnimTimer inc FireballCounter . . . --- Конец кода --- Код 2 --- Код: ---.proc ProcFireball_Bubble if PlayerStatus <> #2 if A_B_Buttons & #BUTTON_B && not a & PreviousA_B_Buttons mb x := FireballCounter & #%00000001 if !Fireball_State[ x ] && y := Player_Y_HighPos - 1 == zero && !CrouchingFlag && Player_State <> #3 mb Square1SoundQueue := #SFX_Fireball mb Fireball_State[ x ] := #2 mb y, FireballThrowingTimer := PlayerAnimTimerSet mb PlayerAnimTimer := y - 1 inc FireballCounter if PlayerStatus <> #0 mb y, FireballThrowingTimer := PlayerAnimTimerSet mb PlayerAnimTimer := y - 1 mb a := #1 endif endif endif . . . --- Конец кода --- P.S. Jumanji Entertaiment System |
| Smoke:
Теремочек, лучше римейк гардиан легенд сделай. С графоном и плюшками |
| Навигация |
| Главная страница сообщений |