Большая часть людей радуется, когда им удаётся вернуть к жизни старые вещи. Бесконечное стремление заново пережить опыт молодости ведёт нас путями, которые мы давно уже позабыли. А по дороге мы иногда сталкиваемся с забытыми воспоминаниями, вызывающими другие забытые воспоминания, позволяющие нам заново переживать счастливые моменты, о которых мы не думали годами, или даже десятилетиями. Кого-то обратно в старшие классы, к вечерним автопрогулкам с выкрученной на полную катушку громкостью радиоприёмника возвращает рёв двигателя Ford Windsor. Для тех, кто родился в 80-х и 90-х подобные воспоминания могут вызывать видеоигры. Кто может забыть первую встречу со скрепкой-помощником из Microsoft Office, элегантную музыку из Final Fantasy, или вверх-вверх-вниз-вниз-влево-вправо-влево-вправо-b-a-выбрать-начать?

Прогресс в технологии процессоров позволил нам заново провести время с нашими любимыми играми посредством эмуляторов – программ, эмулирующих процессоры старых компьютеров. Игры скачиваются с ROM-чипов в файлы. Эти файлы затем можно загрузить в эмулятор, и поиграть в игру так, будто бы вы играете в неё на оригинальной системе.


Внутренности NES Zapper

Технология – штука прекрасная. Она позволяет нам двигаться вперёд и делать сегодня то, что было невозможным вчера. Однако в некоторых случаях эта парадигма неверна. Один из них – это игровая приставка NES, Nintendo Entertainment System, и её контроллер в виде пистолета, Zapper. В своё время NES стала самой популярной игровой приставкой, и не зря. Инженеры, программисты и эксперты по аудио компании Nintendo сумели породить некоторые из лучших видеоигр, когда-либо созданных. К сожалению, в некоторые из этих игр нельзя играть на вашем любимом эмуляторе на Raspberry Pi, поскольку Zapper несовместим с современными цифровыми мониторами. Вряд ли кто может забыть, как весело было играть в «Утиную охоту» (Duck Hunt). Эта игра шла в комплекте со всеми системами NES, поэтому мы все играли в неё. Но связанная с нею ностальгия погребена из-за нерешённых технологических особенностей.

Скажу вам, как хакер хакеру – этого больше терпеть нельзя. Так что сначала мы разберёмся, как работает Zapper, и почему он не работает с цифровыми дисплеями. А потом мы подумаем, как его исправить.

Проблема


Пистолет Zapper – это просто фотоэлемент с переключателем. Когда спусковой крючок (переключатель) нажимается, NES проводит определённые манипуляции с экраном, чтобы понять, куда направлен пистолет. Какие именно – обсудим чуть позже. Но сначала нам необходимо понять, что они работают только на аналоговых телевизорах с ЭЛТ. Если вы подключите ваш эмулятор к такому телевизору, у вас не будет проблем. Проблема в том, что телевизоров с ЭЛТ уже ни у кого нет. У всех стоят цифровые телевизоры с плоским экраном и мониторы. При подключении к такому монитору игра не будет работать. Нам нужно понять, почему это так.

Развенчиваем мифы


По поводу того, откуда NES знает, куда направлен Zapper, есть много путаницы, даже среди людей, немного разбирающихся в электронике. Некоторые из них считают, и продолжают распространять этот миф, что NES считывает строчки развёртки с ЭЛТ. ЭЛТ рисует строки развёртки с верха до низа экрана через определённые промежутки времени. Сравнив время начала прорисовки и время, когда Zapper видит линию, NES может узнать, куда указывает Zapper. А поскольку современный монитор показывает все строки одновременно, подсчитать, куда именно указывает Zapper, нельзя никак. Возможно, что какие-то более старые пистолеты на фотоэлементах так и работали, но NES работает не так. Совсем.

Как работает NES Zapper


Система довольно хитроумная. При нажатии спускового крючка NES рисует сплошной чёрный кадр на ТВ. NES рисует 60 кадров в секунду, поэтому один кадр находится на экране примерно 0,0166, или 17 мс. В следующем кадре на месте утки появляется белый прямоугольник, и приставка опрашивает состояние фотоэлемента в пистолете. Выход фотодиода сильно отличается в зависимости от того, направлен ли он на чёрный экран или на белый прямоугольник. И всё это происходит за время демонстрации двух кадров, 34 мс. Человек едва это замечает. Следующий кадр снова рисует игровое поле, и вам засчитывается попадание или промах. Гениально!



«Но погодите, как эта система работает, когда на экране есть две цели?» Хороший вопрос. Инженеры NES справляются с этой проблемой, просто повторяя весь процесс. Первый кадр будет чёрный, за ним будет кадр с белым прямоугольником на месте одной цели и опрос фотоэлемента. Если на экране есть ещё одна цель, то третий кадр будет с прямоугольником вокруг второй цели. Все три кадра проходят примерно за полсекунды, поэтому у вас не будет возможности подстрелить сразу двух уток. Вы можете подстрелить только одну, и эта техника даёт NES знать, какую именно.

«Если NES просто опрашивает состояние фотоэлемента, могу я просто направить пистолет на яркий свет и каждый раз записывать себе попадание?» Ещё один хороший вопрос. Инженеры NES избавились от такого обмана, опрашивая состояние фотоэлемента ещё во время появления первого, чёрного кадра. Если фотоэлемент видит что-то, отличное от чёрного экрана, приставка засчитывает вам промах. Есть слухи о том, что в самых ранних версиях игры эту ошибку не исправляли, но пока что никто такого бага продемонстрировать не смог.



Другой взгляд на проблему


Теперь, зная, как работает Zapper, мы можем перейти к решению проблем с цифровым монитором. Если игра просто замеряет разницу между чёрным и белым, то пистолет должен прекрасно работать и на цифровых мониторах. Но он, очевидно, не работает. Некоторые утверждают, что фотоэлемент чувствителен к инфракрасному излучению ЭЛТ, а цифровой монитор не испускает инфракрасных лучей. Но посмотрите на этот ролик: Zapper прекрасно работает!


[В ролике показан модифицированный Zapper / прим. перев.]

Мы знаем, что строки развёртки тут ни при чём, и что Zapper может различать контраст между белым и чёрным на цифровом экране. Мы можем заключить, что наша проблема связана со временем. Судя по всему, ЭЛТ может выводить изображение гораздо быстрее цифрового коллеги. В NES жёстко зашита необходимость проверять наличие белого прямоугольника после 16 мс. Если ваш цифровой экране не в состоянии обрабатывать выход NES с достаточной скоростью, то приставка будет искать белый прямоугольник в то время, когда на экране ещё видна игра.

Выходное разрешение NES — 256 x 240 точек. Цифровому монитору необходимо масштабировать каждый кадр до рабочего разрешения. Этот процесс порождает задержку, которая может доходить до 70 мс, серьёзно превышая наш показатель в 16 мс.

Как это исправить


Это будет нелегко. Если цифровой монитор по своей природе слишком медленный, то единственным решением будет замедление NES.

Вариант 1: уменьшение тактовой частоты


Мы все слышали про разгон процессора через увеличение тактовой частоты. А что насчёт торможения? Можем ли мы замедлить время в процессоре NES, не разогнав его до ощутимой доли от скорости света? При этом необходимо, чтобы игра шла с нормальной скоростью, но при нажатии спускового крючка переключалась на замедленную работу и, по сути, увеличивала время задержки. Помните, что NES выводит чёрный экран на 16 мс, а затем рисует белый прямоугольник. Замедляя процессор, мы можем увеличить эту задержку и дать цифровому монитору время на реакцию.

Вариант 2: редактирование ROM


ROM можно редактировать только в шестнадцатеричном редакторе. Что, если бы мы изучили эмулятор и нашли, в каком месте задаётся величина задержки после нажатия спускового крючка? Мы могли бы просто сделать её больше, и надеяться, что ничего не сломали.

Вариант 3: ваш вариант


Теперь, когда вы знаете, как работает NES Zapper, и почему он не работает с современными цифровыми мониторами, вы уже на полпути к решению этой проблемы и освобождению ностальгии, которой лишила нас жестокая технологическая судьба. Что бы вы сделали, чтобы заставить Zapper работать с цифровым монитором и стать героем интернета?

Схема работы не такая уж и сложная – наверняка мы все вместе сможем придумать, как сделать так, чтобы Zapper перестал стрелять холостыми в нашем цифровом мире. Делитесь вашими решениями в комментариях.

Оригинал статьи

Комментарии (48)


  1. lingvo
    25.07.2018 15:41

    Здесь тоже можно делиться?
    Zapper постоянно отсылает в приставку состояние фотодиода или только когда приставка его спросит?


    1. kvazimoda24
      25.07.2018 15:46

      Недавно читал статью про этот пистолет. Там говорилось, что приставка по желанию может опросить датчик и без нажатия на курок. Подозреваю, что сам пистолет является совсем примитивным устройством, в котором стоит кнопка и фотодиод. Всё это напрямую подключается к приставке. А уж опрашивать или нет фотодиод и кнопку, и когда именно это делать решает программа в приставке.
      Понятное дело, что постоянно смотреть информацию с фотодиода программе из статьи (игра Утиная охота) не нужно. Да это и не имеет смысла, т.к. для анализа направления пришлось бы постоянно мигать экраном, что было бы неприятным для игрока.


  1. Ardanay
    25.07.2018 15:54
    +3

    А мне вот запрещали играть в игры пистолетом :) Потому что кинескоп садят.


    1. j_wayne
      25.07.2018 17:05

      И на цветном нельзя было играть в NES в принципе. Глаза сажает! :)


    1. tormozedison
      25.07.2018 20:35
      +4

      Не… Кинескоп, согласно тогдашнему мифу, садил сам факт игры, а не пистолет.
      Прототипом мифа был реальный факт неравномерного износа люминофора от статичных изображений.


  1. molchanoviv
    25.07.2018 16:29

    Имхо название кнопок select и start переводить не стоило.


  1. Roland_D
    25.07.2018 16:30

    Сильно подозреваю, что универсального решения тут быть не может, т.к. все мониторы будут обладать разным временем задержки. Это потребует индивидуальной калибровки под монитор самостоятельно игроком. Да и всегда ли это время задержки строго одинаково у одного и того же монитора?


  1. Nuwen
    25.07.2018 16:37

    Ещё в те времена обратил внимание на такое поведение приставки, кое-как подключенной к старенькому, плохо настраиваемому ламповому телевизору «Рассвет»: если при запущенной пистолетной игре водить стволом вверх-вниз, то помехи на экране, в виде обширного, более светлого участка изображения, смещаются вслед за тем, куда указывает пистолет. Таким образом можно увидеть то, в какую часть экрана направлен ствол — в верхнюю или нижнюю, но по горизонтали точка прицела не локализуется, потому что светлое поле просто ходит вверх и вниз, занимая всю горизонталь. Ну я и думал всегда, что пистолет просто постоянно опрашивается приставкой на предмет задержки принимаемого от кинескопа света строки, а в момент выстрела положение прицела просто уточняется ещё по горизонтали. Как-то же приставка знала о том, куда направлен пистолет, раз отправляла такие помехи. Уж не знаю теперь, в чём дело, может подключенный пистолет просто работал как дополнительная антенна для помех, и от её положения и зависели помехи, либо у меня был какой-то китайский клон NES/FAMICOM, который работал по отличному от описанного в статье принципу.


    1. Javian
      26.07.2018 13:19
      +2

      В других приставках использовались и более сложные методы, к примеру учитывающие то, что луч (в ЭЛТ-телевизорах) освещает только одну точку в каждый момент времени. Приставка заливала экран белым в момент нажатия и отсчитывала время до засветки фотодиода. Таким образом, направление можно было вычислить более точно, а количество мишеней определялось «радиусом поражения» пистолета. Эта схема, к примеру использовалась в SNES.

      habr.com/post/24274


      1. Nuwen
        26.07.2018 15:29
        +2

        Да, кстати, вспомнилось. В момент выстрела засвечивался весь экран, и никаких белых прямоугольников. Выходит, по крайней мере, на том китайском клоне, на котором я это заметил, метод был именно таким. И вот интересно, насколько я понимаю, в России большинство приставок было именно китайскими разношерстными клонами, а не Dendy, которая разумеется была таким же китайско-тайваньским клоном, но имела какие-то ещё характерные особенности. Например видеопроцессор в ней работал на частоте NTSC, однако видеовыход был PAL. Значит, информация из статьи актуальна, как минимум, не для всех.
        В глаза не видел "настоящей" Dendy, поэтому не знаю как там выглядели игры, зато перевидал с десяток разных китайских моделей, а в своё время стало откровением то, что оригинальный Famicom работал на частоте в 60Hz, а китайские клоны — на частоте 50Hz, что влияло на скорость игры и скорость и тональность звукового сопровождения. Оказывается, мы играли в заторможенную версию оригинальных игр, и те места, которые считали хардкорными, у американцев и японцев были вообще непроходимы. И даже игровая музыка была несколько динамичнее.


        1. Javian
          26.07.2018 16:41
          +2

          Еще отличия в контроллерах: «игровыми контроллерами Famicom, NES и Dendy, и чем же они отличаются в этом плане.», «Денди — это очень странная смесь NES и Famicom, PAL и NTSC»
          Там же в комментариях обсуждают ЖК и световой пистолет.
          habr.com/post/260749
          image

          К слову интересное дополнение о принципах работы пистолета:

          В ходе тестирования было выяснено, что сигнал с фотодиода поступает не постоянно, а только при резкой смене освещённости с темного на светлый. При этом, если в этот момент нажат курок — сигнал сильнее.

          Световой пистолет к Ардуино
          habr.com/post/141643


          1. Nuwen
            26.07.2018 16:48

            А у нас в Сибири была достаточно популярна вот эта:
            image
            Найди, как говорится, несколько отличий.


  1. Byteman
    25.07.2018 17:19

    Самый простой вариант — добавить перед началом игры калибровочный код, который будет смотреть задержку (в кадрах) между выдачей видео с консоли и детектом на экране. Однако, могут возникнуть проблемы с «умным» деинтерлейсом в телевизорах. Возможно, придется выводить квадрат не один кадр, а два (телевизор может запросто не отрисовать одиночный черный кадр, а просто «смешает» два соседних кадра; при выдаче двух последовательных кадров он будет обязан их отрисовать).


    1. lingvo
      25.07.2018 18:43

      Для начала стоит проверить видны ли эти два кадра на современном мониторе или нет. Для этого надо взять быструю камеру( или тот же айфон в режиме замедленной сьемки). Если кадры мелькают, можно продолжить исследование и попробовать обмануть цепь детектора эмулятором — черный/белый. Если и это заработает — определяться, где вводить задержки.


      1. Byteman
        26.07.2018 14:14
        +1

        Не факт. Картинка с композитного видеовхода всегда прогоняется через деинтерлейсер. Посмотрите, как демы с ZX Spectrum'а, где используется эффект gigascreen (переключение двух экранных областей с частотой 50гц), смотрятся на современных ТВ. Некоторые телики показывают честное мерцание, некоторые просто смешивают два кадра. Третьи принимают такой сигнал как черезстрочный и показывают один кадр на четных, другой — на нечетных строках растра. Поэтому я и написал, что (возможно) придётся квадрат выводить не один кадр («поле» в терминологии черезстрочного сигнала), а два, чтобы телик/монитор это дело отрисовал 100%.


  1. opanas
    25.07.2018 18:23

    Недавно на кикстартере пытались денег поднять на разработку, кстати, но неуспешно:
    www.kickstarter.com/projects/metsasta/modern-mallard


  1. robert_ayrapetyan
    25.07.2018 18:36

    Эээ, был уверен, что речь пойдет о другой утиной охоте (отечественного производства Электроника).


    1. tormozedison
      25.07.2018 20:32

      Это где вместо уток квадраты, что ли?


      1. robert_ayrapetyan
        25.07.2018 20:47

        Никаких квадратов, обычные утки. Конкретно эта версия называлась «Электроника ИМ-18».


        1. tormozedison
          25.07.2018 20:59

          А, такую тоже помню, там уток надо не стрелять, а ловить (ружьё в роли пылесоса?), как в «Ну, погоди».


          1. uu_69
            26.07.2018 15:09

            «Волк с яйцами»


  1. solariserj
    25.07.2018 20:11
    +2

    А есть ли разница на чб или цветном играешь? А то в моей молодости у нас был черно-белый горизонт, и не стрелял, хотя когда покупали то на цветном работал. Далее (не помню как) выяснилось что работает через футболку о_0 футболку просвечивало и по силуэту(темному пятну) можно было понять где утка. И игра приобрела командный характер один держит футболку перед телевизором, другой стреляет пистолетом, далее выяснилось что также работает через красную плёнку от обложки папки, и наконец наклеяли кусок этой красной обложки на пистолет и он начал стрелять. Но потом подвели порты которые расыпались, а починить не хватало навыков.


  1. hzs
    25.07.2018 21:30
    +4

    Тоже мне нашли проблему.
    Играешь на старом ЭЛТ телевизоре и не паришься, и соотношение сторон экрана правильное и красивое размытие пикселей и вообще ламповая картинка.
    Ну и аутентичность полная.


    1. tormozedison
      25.07.2018 22:55

      Это сейчас легко говорить. Все такие телевизоры когда-нибудь выдохнутся, и снятые с производства детали к ним купить будет всё труднее и труднее. Не скоро, но обязательно наступит момент, когда даже Музей советских игровых автоматов будет вынужден искать запчасти к трубочным мониторам своих экспонатов с миру по нитке, а в некоторые ставить ЖК-панели.


      1. hzs
        26.07.2018 05:19

        Тогда и будем решать проблемы, по мере их поступления.
        Думаю, лет 10 — 20 ещё можно будет найти ЭЛТ телевизоры в рабочем состоянии.


    1. Byteman
      26.07.2018 14:15
      +1

      А ещё круче найти кинескопный 60''+ проекционник 4:3 и играть на огромном экране :)


  1. juray
    26.07.2018 02:27
    +2

    По заголовку сначала было подумалось про какой-то ремейк самой игры.
    Типа такого:


    1. Lsh
      26.07.2018 14:53

      А было бы круто!


  1. juray
    26.07.2018 02:34
    +1

    По самой статье — что-то мне сомнительным показался пассаж про 70 мс задержку на масштабирование. Ведь это, получается, во всех играх вносит лаг, а 70 мс в динамических играх (шутерах, гонках) — довольно чувствительно уже.

    И еще про «60 кадров в секунду» — полукадров, вообще-то. Хотя сути это не меняет.


    1. Byteman
      26.07.2018 14:16
      +1

      у НЕСа прогрессивная развертка :) Поэтому там это именно кадры, чередования полей нет.


      1. juray
        26.07.2018 20:41

        но у телевизора-то чересстрочная.


        1. tormozedison
          26.07.2018 21:26

          Просто оба поля выглядят одинаково.


          1. Byteman
            26.07.2018 22:56

            Тогда это было бы 25fps/30fps, а NES (как и остальные консоли) даёт 50/60.


        1. Byteman
          26.07.2018 22:55

          Телевизор умеет выводить как чересстрочную 480i/576i (60Hz и 50Hz частотой полей соотв.), так и 240p/288p, когда у вас нет разбиения на четные и нечетные поля, и все поля выводятся на одном и том же месте (т.е. без мерцания, с промежутками между сканлайнами). Попробуйте найти хороший CRT-монитор а-ля Commodore 1084, и попробуйте туда вывести обычный телевизионный сигнал, скажем, с AV-выхода видеокамеры, и с любой игровой консоли. Сразу увидите разницу между прогрессивом (с уменьшенным в 2 раза вертикальным разрешением) и интерлейсом.


  1. Stalker_RED
    26.07.2018 02:38

    Есть слухи о том, что в самых ранних версиях игры эту ошибку не исправляли, но пока что никто такого бага продемонстрировать не смог.
    Это не зависело от картридджа?
    У меня был клон NES под названием сюбор
    (похожий, только в белом корпусе)
    image


    1. tommyangelo27
      26.07.2018 15:51

      У меня в какой-то из стрелялок (кажется про ковбоев) работало днем от окна.


  1. Anilexis
    26.07.2018 07:42

    А на проекторах как? У меня современный китайский клон NES с пистолетом подключен к проектору. Пистолет не работает(


    1. vesper-bot
      26.07.2018 10:04
      +1

      Проектор в качестве отображающего элемента имеет аналогичный цифровому дисплей и лампочку, которая, собственно, и проецирует его на экран. То есть или так же, или никак.


      1. Byteman
        26.07.2018 14:16

        Можно найти кинескопный проектор :)


  1. UncleJey
    26.07.2018 08:22
    -1

    Проблема давно известна. Как причины так и следствия. Так же известно что простого решения нет, что собственно в статье и написано. Зачем здесь эта статья?


  1. vesper-bot
    26.07.2018 10:03

    Я видел одну игру с пистолетом на Денди, которая куда хитрее опрашивала пистолет — вначале рисовала черный экран, потом везде белый, потом рисовала белый прямоугольник шириной где-то в 1/6 (по памяти) экрана, высотой в десятка два строк, на том уровне, куда был наведен пистолет, пробегавший по строке в последующих кадрах, и в нем как-то хитро рисовала спрайт выстрела, причем он иногда был и смещен в правильную, как мне казалось, сторону от середины прямоугольника по обеим осям. Вот эту, пожалуй, точно не реанимировать корректно.


  1. Byteman
    26.07.2018 14:18

    К слову, на Atari XE/XL/GS пистолет работает с точностью до пикселя — там действительно идёт синхронизация с развёрткой.


  1. sergix
    26.07.2018 14:37

    Тоже пытался возродить эту затею иным образом. На c# получая метку с экрана(Через веб камеру, она же есть у всех! Можно было положить начало целому циклу игр). Но скорости обработки при использовании стандартных библиотек не хватило Вопрос на стаке с полным описанием, как оно было


  1. Alexus819
    26.07.2018 15:04
    +3

    «Все три кадра проходят примерно за полсекунды» Хм… 6fps?
    мне кажется это не правда… скорее всего кто то перепутал 50мс и 500 мс


  1. iDm1
    26.07.2018 16:51
    +2

    Лучше доработать эмулятор. После каждого нажатия на спусковой крючок эмулятору требуется ставить эмуляцию игры на микропаузу и ожидать чёрного кадра от Zapper в течении максимально допустимой задержки, допустим те же 70 мс.
    Если эмулятор дожидается черного кадра, то возобновляет ход игры и она успешно регистрирует черный кадр и следующий за ним.
    Если по достижении 70 мс черный кадр не обнаружен, то эмуляция возобновляется по таймауту, но игра уже засчитает срелку промах из-за отсутствия черного кадра.

    В RetroArch (libretro) уже добавили разных «игр со временем», как то перемотку и более интересную «Run-Ahead to Reduce Latency», которая по сути выполняет несколько параллельных эмуляций игры с разными комбинациями ввода наперёд и выводит на экран тот вариант, который соответствует нажатиям игрока, таким образом убирая задержку ввода до минимально возможного значения в 1 кадр. Но для борьбы с задержкой Zapper данные функции не подходят.


  1. neco
    26.07.2018 21:12

    у меня вот есть вот такая штука: image

    и я думаю посмотреть как оно там всё устроенно…
    потому что меня сильно смущает высказывание про «зажержку 70мс»… и динамический вывод кадров…
    на жк-телевизоре (50lb670v) пистолет работает через раз… у него вроде развертка 200герц…
    надо собрать всё в кучу взять осциллограф и посмотреть что происходит…


    1. neco
      26.07.2018 21:18

      прошу прошения, не «развертка» а частота обновления 200 Гц
      и это както с 16мс не согласуется…
      я готов поверить что там просто сбивается синхронизация опроса денди с кадрами и не всегда попадает… но 70мс на масштабирование…


      1. Byteman
        26.07.2018 22:58

        Скорее там задержки на «дорисовку» недостающих кадров. На Филипсе есть игровой режим, помогал в играх вроде guitar hero (игра показывала нулевой лаг в режике калибровки), но я не пробовал этот режим с нинтендой и пистолетом проверять… Надо будет проверить на досуге.