Print This Post StepFucker — проходим треки в степмании на АААА

Воскресенье, 20. Сентябрь 2009
Раздел: Assembler, автор:

Написал на ассемблере программку для идеального прохождения треков в игре 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

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 30 к “StepFucker — проходим треки в степмании на АААА”

  1. Sleep, SleepEx, GetTickCount, SetTimer – поразительно неточные.
    Вот тут немного непонятно, на основании чего сделали такой вывод ?

    [Ответить]

    dx:

    Во-первых, в самом MSDN написано.
    Про GetTickCount:

    The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds

    И про SetTimer:

    Because a timer's accuracy depends on the system clock rate and how often the application retrieves messages from the message queue, the time-out value is only approximate.

    И про Sleep(Ex):

    To increase the accuracy of the sleep interval, call the timeGetDevCaps function to determine the supported minimum timer resolution and the timeBeginPeriod function to set the timer resolution to its minimum. Use caution when calling timeBeginPeriod, as frequent calls can significantly affect the system clock, system power usage, and the scheduler. If you call timeBeginPeriod, call it one time early in the application and be sure to call the timeEndPeriod function at the very end of the application.

    SleepEx была самой точной из перечисленных Вами, но она не подошла чисто по алгоритму, так как задержки накапливались из-за различных операций с FPU и эмуляции ввода. Остальные функции имеют чересчур большие погрешности. Особенно SetTimer, особенно если он реализуется через WM_TIMER.

    А вот для функции timeGetTime() есть возможность установить разрешение таймера в 1 мс с помощью timeBeginPeriod, что вполне приемлемо.

    Разумеется, можно было бы использовать QueryPerformanceCounter/Frequency для получения значений с точностью до 1/3.5 мс или еще выше, но появится немало других проблем, да и надобности в такой точности нет.

    [Ответить]

  2. Спасибо за объяснения, интересно.

    [Ответить]


  3. Tim :

    Один вопрос: нафига? Чисто как практика кодинга?

    [Ответить]

    dx:

    Да

    [Ответить]


  4. asd :

    Автор! Название музыки!

    [Ответить]

    Kaimi:

    DJ Mystik - Time To Say Goodbye

    [Ответить]


  5. Jambon :

    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 :(

    [Ответить]

    dx:

    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).

    [Ответить]

    Jambon:

    DX believe we can do a second version of this program?

    [Ответить]

    dx:

    Yes, of course you can do the second version. I believe in you, mate! :D


  6. Jambon :

    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.

    [Ответить]

    Jambon:

    Please

    [Ответить]

    dx:

    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?

    [Ответить]

    Jambon:

    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

    Kaimi:

    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.


  7. Jambon :

    And how you can fix these problems?

    [Ответить]

    dx:

    Read my comment above:

    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?

    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.

    [Ответить]

    Jambon:

    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

    [Ответить]

    dx:

    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).


  8. Jambon :

    I thank you very warmly :)

    [Ответить]

  9. How to use?
    Yon English answer,please

    [Ответить]

    Kaimi:

    Try this https://www.sendspace.com/file/hk1zrg it has English GUI

    [Ответить]

    رئيس الحزب الشيوعي الصيني:

    404

    [Ответить]

    Kaimi:

    Works for me. Or you can use link from the article Update section

    رئيس الحزب الشيوعي الصيني:

    thanks

    رئيس الحزب الشيوعي الصيني:

    can use 5.0 ?

    dx:

    The program does not hook something or embed the code to the StepMania process, so yes, this should work with 5.0, too.


  10. ENERGY :

    How to compile the program ? Can I do modifications to program such as make it read bigger files , change the visual style etc ?

    [Ответить]

    dx:

    You can compile the code using MASM32. Here you can find the package which can allow you to compile the code: /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.

    [Ответить]


Оставьте ваш комментарий