Написал на ассемблере программку для идеального прохождения треков в игре Stepmania.
Если вы не знакомы с такой игрой - посмотрите видео ниже, и поймёте ее суть - нажимать на 4 клавиши в ритм с песней руками или ногами (на специальных ковриках/автоматах).
Весь код программы я описывать не буду, опишу только новые особенности Win API, с которыми мне пришлось иметь дело во время написания.
Для начала, вот несколько скриншотов программы и видео ее работы:
Каждый степчарт (файл с указанием, как должны лететь стрелки), хранится в SM-файлах. Некоторые степчарты могут храниться в формате dwi, но его поддержку я не делал, да и смысла нет, т.к. Stepmania все равно конвертирует их в SM и складывает в /Путь_к_Моим_Документам/StepMania CVS/Cache/Songs/. Оттуда и можно брать SM-файлы.
Программа читает SM, обрабатывает его, и проходит трек с идеальной точностью. Есть единственная задача - попасть точно на первую стрелку, т.к. программа сама не умеет определять, когда начинать играть. Но если даже попадание не совсем точное, его можно отрегулировать горячими клавишами по ходу игры.
Программа эмулирует нажатия клавиш которые бы нажимал человек (они настраиваются), поэтому во время игры окно Stepmania должно быть активным, а управление программой (вкл-выкл, корректировка) производится с помощью горячих клавиш, которые также настраиваются.
Можно задать некоторый уровень ошибок, тогда при игре будут некоторые отклонения от идеала, и будет казаться, что играет человек.
Программа способна обрабатывать любые SM-файлы, в том числе и с изменяющимся ритмом (BPM), со стопами (STOPS).
Теперь - немного технической части.
1. Эмуляция ввода.
Эмуляция нажатия клавиш производилась с помощью функции SendInput. Отмечу, что для того, чтобы ввод работал и в приложениях DirectX, которые используют DirectInput (а степмания и является таковой), необходимо отсылать не виртуальные коды клавиш, а скан-коды. Чтобы получить скан-код клавиши по виртуальному коду, необходимо воспользоваться функцией MapVirtualKey.
Есть еще функция keybd_event для эмуляции ввода с клавиатуры, но она устаревшая и является просто переходником к SendInput.
2. Немного о таймингах.
Так как тайминги в степмании очень точные, пришлось отказаться от таких функций, как Sleep, SleepEx, GetTickCount, SetTimer - все они поразительно неточные.
Осталось выбрать между QueryPerformanceCounter (вместе с QueryPerformanceFrequency), timeGetTime и ассемблерной командой ldtsc.
Первая функция является самой точной, как правило, ее точность составляет 1/3.5 мс, но она и самая медленная, а во-вторых, с ней возникают трудности на многоядерных процессорах или на ноутбуках при изменении режима энергосбережения.
Эта функция запрашивает состояние независимого счетчика со своей не зависящей от частоты процессора тактовой частотой, но на деле частота от процессора зависит, а на многоядерных системах этот счетчик может вернуть состояние для каждого ядра по отдельности случайным образом (для устранения таких проблем есть приемы, но они не идеальны).
С командой ldtsc примерно та же ситуация. Она возвращает текущий такт процессора в int64. Но частота процессора может динамически меняться, поэтому использовать эту команду не следует.
В итоге я остановился на timeGetTime, установив с помощью timeBeginPeriod ее разрешение в 1 мс (минимально возможное). Кроме того, Stepmania также использует данную функцию.
3. FPU
Работа с FPU (Floating Point Unit, математический сопроцессор) на ассемблере очень уныла и громоздка. К счастью, в пакете MASM32 есть отличная удобная библиотека FpuLib для выполнения различных вычислений, сравнений, преобразований с числами REAL10 и DWORD (10 и 4 байта соответственно).
Хелп по этой библиотеке лежит в том же MASM32 в папке help.
Ну вот и все заметки, которые я хотел оставить по коду. Если есть какие-либо вопросы, можете оставлять их в комментариях.
В архиве с программой и исходниками есть еще файл windows.asm - я использовал макросы оттуда для создания юникодовых строк на русском языке в приложении.
Скачать программу и исходники: ZIP
UPDATE 14.09.2015: Добавлена возможность загружать степчарты большего размера, с бОльшим количеством стопов и изменений BPM. Теперь загружаются чарты, где каждый такт разделен на 96 частей. Роллы (rolls) теперь поддерживаются минимально и работают как простое нажатие (раньше вообще пропускались).
UPDATE 06.06.2016: English version is now available (thanks Kaimi): sfuck_en
Sleep, SleepEx, GetTickCount, SetTimer – поразительно неточные.
Вот тут немного непонятно, на основании чего сделали такой вывод ?
Во-первых, в самом MSDN написано.
Про GetTickCount:
И про SetTimer:
И про Sleep(Ex):
SleepEx была самой точной из перечисленных Вами, но она не подошла чисто по алгоритму, так как задержки накапливались из-за различных операций с FPU и эмуляции ввода. Остальные функции имеют чересчур большие погрешности. Особенно SetTimer, особенно если он реализуется через WM_TIMER.
А вот для функции timeGetTime() есть возможность установить разрешение таймера в 1 мс с помощью timeBeginPeriod, что вполне приемлемо.
Разумеется, можно было бы использовать QueryPerformanceCounter/Frequency для получения значений с точностью до 1/3.5 мс или еще выше, но появится немало других проблем, да и надобности в такой точности нет.
Спасибо за объяснения, интересно.
Один вопрос: нафига? Чисто как практика кодинга?
Да
Автор! Название музыки!
DJ Mystik - Time To Say Goodbye
Excuse me but with some maps from these mistakes:
1) http://i59.tinypic.com/a44wah.png
2) http://i57.tinypic.com/w0oyts.png
3) http://i57.tinypic.com/1znmuy8.png
You could fix these errors? And a great hack, it's a shame to leave it :(
This software is very old, it'll be too difficult to support it now. By the way, these error texts are corrupted (this is the ANSI program, and error texts are in Russian, so they get corrupted when you launch the program in non-Russian Windows locale).
DX believe we can do a second version of this program?
Yes, of course you can do the second version. I believe in you, mate! :D
Excuse me, but I'm not very experienced codes XD, so was wondering if anyone could make a second version XD, then they need help with something, I'm there.
Please
As I remember, this program supports .sm files only, .dwi format is not supported. If you have problems when opening .sm file, could you upload it somewhere, so I'll be able to take a look at it?
No, the problem is not the file, because to run one stepfile need SM, therefore, only with some maps from these problems, only that the maps that give these errors are many :(.
Problems:
1) http://i59.tinypic.com/a44wah.png
2) http://i57.tinypic.com/w0oyts.png
3) http://i57.tinypic.com/1znmuy8.png
If you could solve everything would be grateful
1) sfuck.asm:1405 - Too big BPM number.
2) sfuck.asm:70 - Can't read info about 'stops'.
3) sfuck.asm:1244 - File format error.
And how you can fix these problems?
Read my comment above:
These problems can only occur when you load SM file. We can't fix them without having the file that causes them. So please provide these files to us, so we're able to see what's wrong.
This rar, there are various file some work and others do not, there are many, so I ask if you can see what's wrong.
Link: https://mega.nz/#!H1chmSqA!p6Iaio_NRJ2FtNrkpFe2Scx01isNEjQYs0dibHRwlWY
Try the new version (just uploaded it, use the same download link). It can now open larger stepcharts, with more BPM changes and stops. Rolls are now supported and work as usual presses (previous version has no support for rolls at all).
I thank you very warmly :)
How to use?
Yon English answer,please
Try this https://www.sendspace.com/file/hk1zrg it has English GUI
404
Works for me. Or you can use link from the article Update section
give me 5.0 cheats please:>
This probably will work with 5.0, too, as this cheat basically emulates keyboard input. You just have to set the keys correctly.
thanks
can use 5.0 ?
The program does not hook something or embed the code to the StepMania process, so yes, this should work with 5.0, too.
How to compile the program ? Can I do modifications to program such as make it read bigger files , change the visual style etc ?
You can compile the code using MASM32. Here you can find the package which can allow you to compile the code: https://kaimi.io/2009/08/%D0%BF%D0%B0%D0%BA%D0%B5%D1%82-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D0%B8-masm32/ (However, in Russian). As an option, you can download MASM32 and perform its full installation.
Of course, you can do any modifications you wish.
Вопрос, а будет ли поддержка 1.1х и больше? (скорость воспроизведения степчарта)
О какой скорости идет речь? Все ведь зависит от BPM, переменный BPM там поддерживается, как и остановки
Я имел в виду это
http://puu.sh/wnmmE/bab77314b0.png
Если это изменяет BPM трека, то нет, это не поддерживается, и вряд ли будет уже
Жалко
После какой то работы перестаёт работать (выбираю окно со stepmania на первую стрелку запускаю чит,а потом выбранное окно становится неактивным)