Raspberry Pi cartridge from NES

  • Tutorial

Hello! This is a retro gaming console based on the Raspberry Pi. In the cartridge from the game console NES. An integrated screen can be used for the game. When outputting the same video via HDMI, it shows the image of the game cover, as well as the core temperature, see the photo. I suggest a little ponastalgic and read about the assembly and configuration of such a device. Carefully, further a lot of traffic and photos.

Nostalgia


In childhood, we, who are now over 25-35, loved to play consoles. Then there was no newfangled word of the console, so I will call them that. My acquaintance with consoles began with Dandy (clone NES). Super Mario Bros, Contra, Ducktales, Battletoads are just some of the hits of that time. Then the whole court was going to play with my friend in Sega (Sega Mega Drive), in such hits as Sonic, Ultimate Mortal Combat 3, Contra Hard Corps and more . And when the Play Station came out, I must say, she didn’t get to us right away, the Resident Evil series caused some truly frightening delight.


This picture helped me to wipe away a tear of nostalgia. I must say, I'm not the first who came up with the Raspberry Pi inserted into the case of the NES cartridge. Yes, this is not my device. And this cartridge is suitable for these purposes almost perfectly, it is small and beautiful. And inside a lot of space. Judge for yourself.


Inside a Raspberry Pi Zero, a USB hub, and a pair of extension cords. All sticks planted in the beef hot melt adhesive.

Assembly


I wanted to collect something the same or similar. The same cartridge was selected from NES. Other options are either very small or they don't look very good. As the fiery heart of a retro car made Raspberry Pi 3B. Were purchased on Ali, also, USB connectors with convenient leads for soldering. Here it is.


Oh yeah, you will repeat this project, do not take hit cartridges. There are so few of them left. Take something more common or less known. There is also an option to take a cartridge with Ali, but the original, it warms the soul. My 1986 release.

You will also need a special nes screwdriver screwdriver if the cartridge is screwed into three screws. There are also early versions of cartridges with five screws; they are unscrewed with a conventional flat-head screwdriver. I have just this.

From a cartridge with a stationery knife and a sheet from a hacksaw, all interfering parts are cut and sawed.


With the Raspberry Pi, protruding connectors were soldered. Experts say that you can do without a soldering station, if you first carefully disassemble the connectors with pliers, and then solder on one leg. All glued to the glue. Between connectors USB and raspberry laid insulator of non-melting plastic. Do not forget to connect the GND Raspberry Pi and the USB case of the USB connector (not shown in the picture above). Otherwise some joysticks will not work.


The last Retropie was installed on the raspberry . At first, Recalbox was standing , but I refused it, because it does not support the vibration of the joysticks on the Playstation 1 consoles. But I must say, the Recalbox is slightly more convenient in terms of what works out of the box and do not need to tune anything. In Retropie a lot of settings, you can customize infinitely. By this I liked him.
That's what happened. Connect any joysticks with xinput.



Screen


Appetite comes with eating. How about embed screen in a cartridge? To play or display the image of the game cover. Such a screen has been ordered . This is an 800 * 480 3.5 inch screen with a parallel DPI interface that uses almost all GPIO Raspberry Pi. It works for me in 120 Hz mode (but the render is still 60 Hz), the response is instant. The only negative is the 6-bit matrix. Only 262,144 colors. Although, in general, it is not particularly noticeable, judge for yourself.

Screenshot from the game Comix Zone (Clickable)

All the legs from the screen and the Raspberry Pi were soldered. The screen was soldered with two cables from an old IDE cable. Under the screen are installed mortgages in 5mm, it does not touch the bottom wall of the cartridge. Electrical tape is glued around the perimeter of the display so that there are no side lights. All glued to the glue. On the top cover, I cut through the window and glued a 2mm thick glass.


In order to start displaying the image on this screen, you need to fix the /boot/config.txt config . I recommend WinSCP program for Windows owners , which, when connecting to Raspberry Pi via SSH, gives the presentation of files as in Total commander'e. Very comfortably. Especially if you run it in shell mode sudo su - , which gives access to all files.

Unfortunately, when the DPI screen is on, video output via HDMI does not work. Therefore, I created two config files in the / boot / folder , one config_hdmi.txt , the second config_dpi.txt . In the config_hdmi.txt config , the resolution is 1080p60Hz and the overscan is removed. config_dpi.txt contains the DPI screen settings.

config_dpi.txt
# uncomment if you getno picture on HDMI for a default "safe" mode
#hdmi_safe=1
disable_overscan=1
# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1#hdmi_mode=1
# Sound output. Setto0orcommentfor autodetect, 1for DVI, 2to force HDMI.
#hdmi_drive=2
# Using /etc/modules is deprecated andno longer supported on4.4 kernel
# So manually enable audio
dtparam=audio=on
config_hdmi_boost=0
# force hdmi while the tv can take timebefore sending the signal on the hdmi output
hdmi_force_hotplug=1
# uncomment for composite PAL
#sdtv_mode=2
# uncomment for lirc-rpi
#dtoverlay=lirc-rpi#3.5 HD tft screen 800x480
dtoverlay=dpi24
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0#Banggood
framebuffer_width=800
framebuffer_height=480
dtparam=spi=off
dtparam=i2c_arm=off
enable_dpi_lcd=1
display_default_lcd=1
dpi_output_format=0x6f015
dpi_group=2
dpi_mode=87
hdmi_timings=480016162480004220001200460800006
display_rotate=3
# if you plug your tv at the same timeas your rpi and that the rpi switches from the hdmi or give a low resolution because tv had no enough timeto initialize it
boot_delay=3
# uncomment if you don't want the rainbow at startup
#disable_splash=1
# default CEC name
#cec_osd_name=recalbox
dtparam=spi=off
# Overclock
gpu_mem_256=128
gpu_mem_512=256
gpu_mem_1024=256
overscan_scale=1
gpu_mem=256
start_x=0
enable_uart=0
avoid_safe_mode=1
kernel=zImage

config_hdmi.txt
# For more options and information see# http://rpf.io/configtxt# Some settings may impact device functionality. See link above for details# uncomment if you get no picture on HDMI for a default "safe" mode#hdmi_safe=1# uncomment this if your display has a black border of unused pixels visible# and your display can output without overscan
disable_overscan=1# uncomment the following to adjust overscan. Use positive numbers if console# goes off screen, and negative if there is too much border#overscan_left=16#overscan_right=16#overscan_top=16#overscan_bottom=16# uncomment to force a console size. By default it will be display's size minus# overscan.#framebuffer_width=1280#framebuffer_height=720# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=1#1080p60fps
hdmi_mode=16# uncomment to force a HDMI mode rather than DVI. This can make audio work in# DMT (computer monitor) modes#hdmi_drive=2# uncomment to increase signal to HDMI, if you have interference, blanking, or# no display#config_hdmi_boost=4# uncomment for composite PAL#sdtv_mode=2#uncomment to overclock the arm. 700 MHz is the default.#arm_freq=800# Uncomment some or all of these to enable the optional hardware interfaces#dtparam=i2c_arm=on#dtparam=i2s=on
dtparam=spi=off
# Uncomment this to enable the lirc-rpi module#dtoverlay=lirc-rpi# Additional overlays and parameters are documented /boot/overlays/README# Enable audio (loads snd_bcm2835)
dtparam=audio=on
gpu_mem_256=128
gpu_mem_512=256
gpu_mem_1024=256
overscan_scale=1
gpu_mem=256
start_x=0
enable_uart=0


Switching configs will be our autoscript which is available on the network
\\ 192.168.x.xxx \ configs \ all \ autostart.sh or in the folder on the device /opt/retropie/configs/all/autostart.sh

autostart.sh
# Check to see if display is not connected
_NOHDMI=$(tvservice -n ) || true# Check to make sure it's not already in LCD mode
_ISLCD=$(tvservice -s | grep "LCD") || true# HDMI is connected - turn off backlight LCD
_HDMI=$(tvservice -s | grep "0x12000a") || trueif [ -z "$_NOHDMI" ]; thenif [ "$_ISLCD" ]; thenprintf"NO HDMI connected, LCD DPI display config already active\n"#do nothingelseprintf"NO HDMI connected, Switching to LCD DPI display\n"#change config to Hyperpixel and reboot since no display detected
    sudo cp /boot/config_dpi.txt /boot/config.txt
    sudo reboot now
  fielif [ "$_NOHDMI" ]; thenif [ "$_ISLCD" ]; thenprintf"HDMI is connected, but LCD DPI config is being used\n"#we need to switch to HDMI display config and reboot
    sudo cp /boot/config_hdmi.txt /boot/config.txt
    sudo reboot now
  elif [ "$_HDMI" ]; thenprintf"HDMI is connected, HDMI config detected, so turning off LCD BL\n"#we need to shut off the backlight on the Hyperpixel display since we aren't using it#don't panic, a reboot automatically resets this - it isn't a persistent value#also to do this the config.txt file needs to load the backlight module on startup#to control it even if you aren't loading the overlay driver for the display# this comment#echo 1 | sudo tee /sys/class/backlight/rpi_backlight/bl_powerelse#debugging catchall - shouldn't happen since we expect 0x12000a - but you never know...printf"HDMI is connected, HDMI config detected, your tv might not like 1920x1080 resolution\n"fielse#do nothing - based on previous if statements - you either have HDMI or you don't have it...printf"Debug catchall point - sorry I can't help you out - I haven't run into the error state yet!\n"fi
emulationstation #auto


A script was also written switchscreen.sh , which should be put in / home / pi / RetroPie / retropiemenu / . This script switches configs manually and is accessible from the main Retropie settings menu. After its launch, it is necessary to pull out the HDMI cable, otherwise after rebooting everything will switch back automatically. Do not forget to prescribe the script

chmod +x /home/pi/RetroPie/retropiemenu/switchscreen.sh

switchscreen.sh
#!/bin/bash# Check to see if display is dpi
_DPI=$(grep dpi /boot/config.txt) || trueif [ "$_DPI" ]; thenprintf"Switch to HDMI\n"
  sudo cp /boot/config_hdmi.txt /boot/config.txt
  sudo reboot now
elseprintf"Switch to DPI LCD\n"
  sudo cp /boot/config_dpi.txt /boot/config.txt
  sudo reboot now
fiexit 0


In autostart.sh , traces of code are visible, turning off the DPI screen backlight when HDMI is turned on. This script I copied on the Internet, so on our screen it does not work. It would be possible to be confused with transistors to turn off the power of the screen, but why, if we need to display a picture of the cover of the currently running game. You just need to figure out what DPI is.

Parallel Display Interface (DPI)


DPI, as was said, is a parallel interface for screens. Information on this interface one , two, and miscalculated . Well, now it will be here, in Russian.

All attempts to enable DPI by console commands during HDMI operation failed. Maybe doing something wrong. Plan B was adopted for implementation: display the image on a small screen, tugging programmatically by the legs of the GPIO.

DPI is characterized by the fact that one pixel is transmitted to the display in one clock signal clock. Since we have a 6-bit matrix, these are 18 pins for three colors, and also there are display enable pins (indicates a valid date), h_sync (sets the zero address of the horizontal line in the display controller), v_sync (sets the zero address of the vertical line in the display controller ). Data locking occurs on the falling edge of the clock signal. This is known if we decipher the line “dpi_output_format = 0x6f015” from our config_dpi.txt according to this terminology.

dpi_output_format
output_format          = (dpi_output_format >>  0) & 0xf;
rgb_order              = (dpi_output_format >>  4) & 0xf;
output_enable_mode     = (dpi_output_format >>  8) & 0x1;
invert_pixel_clock     = (dpi_output_format >>  9) & 0x1;
hsync_disable          = (dpi_output_format >> 12) & 0x1;
vsync_disable          = (dpi_output_format >> 13) & 0x1;
output_enable_disable  = (dpi_output_format >> 14) & 0x1;
hsync_polarity         = (dpi_output_format >> 16) & 0x1;
vsync_polarity         = (dpi_output_format >> 17) & 0x1;
output_enable_polarity = (dpi_output_format >> 18) & 0x1;
hsync_phase            = (dpi_output_format >> 20) & 0x1;
vsync_phase            = (dpi_output_format >> 21) & 0x1;
output_enable_phase    = (dpi_output_format >> 22) & 0x1;
output_format:
   1: DPI_OUTPUT_FORMAT_9BIT_666
   2: DPI_OUTPUT_FORMAT_16BIT_565_CFG1
   3: DPI_OUTPUT_FORMAT_16BIT_565_CFG2
   4: DPI_OUTPUT_FORMAT_16BIT_565_CFG3
   5: DPI_OUTPUT_FORMAT_18BIT_666_CFG1
   6: DPI_OUTPUT_FORMAT_18BIT_666_CFG2
   7: DPI_OUTPUT_FORMAT_24BIT_888
rgb_order:
   1: DPI_RGB_ORDER_RGB
   2: DPI_RGB_ORDER_BGR
   3: DPI_RGB_ORDER_GRB
   4: DPI_RGB_ORDER_BRG
output_enable_mode:
   0: DPI_OUTPUT_ENABLE_MODE_DATA_VALID
   1: DPI_OUTPUT_ENABLE_MODE_COMBINED_SYNCS
invert_pixel_clock:
   0: RGB Data changes on rising edge and is stable at falling edge
   1: RGB Data changes on falling edge and is stable at rising edge.
hsync/vsync/output_enable_polarity:
   0: default for HDMI mode
   1: inverted
hsync/vsync/oe phases:
   0: DPI_PHASE_POSEDGE
   1: DPI_PHASE_NEGEDGE




The sequence of bits is shown in the figure above. Each line starting with VSYNC has a full cycle of HSYNC line cycles. This is for one frame. Back and Front porch are the so-called indents of the display, which are in the memory of the controller, but they are not on the screen.

Now we will decode the string “hdmi_timings = 480 0 16 16 24 800 0 4 2 2 0 0 0 120 0 46080000 6” from our config_dpi.txt. There is nothing complicated here, just write down the parameters in order.


What GPIO legs are used to convey colors is shown in this picture. We have Mode 5. Attention, these are not legs in order, namely GPIO symbols! The remaining signals are Clock - GPIO 0, DE - GPIO 1, VSYNC - GPIO 2, HSYNC - GPIO 3.


A python was quickly installed, the necessary GPIO library and a hello script were written to at least color the screen blue. I also had cognitive dissonance, when Notepad ++ did not show indents on Windows where they were in nano, while doing line breaks did tabulation, not spaces. By the way, VSCode doesn’t find the same sin, how to fix it.

Python script
from gpiozero import LED
from time import sleep
sleep_time = 0.0
clock = LED(0)
de = LED(1)
vsync = LED(2)
hsync = LED(3)
red2 = LED(16)
red3 = LED(17)
red4 = LED(18)
red5 = LED(19)
red6 = LED(20)
red7 = LED(21)
green2 = LED(10)
green3 = LED(11)
green4 = LED(12)
green5 = LED(13)
green6 = LED(14)
green7 = LED(15)
blue2 = LED(4)
blue3 = LED(5)
blue4 = LED(6)
blue5 = LED(7)
blue6 = LED(8)
blue7 = LED(9)
defv_sync(frame):
    vsync.on()
    for n in range(frame):
        clock.on()
        #sleep(sleep_time)
        clock.off()
        #sleep(sleep_time)#print("vsync")
    vsync.off()
    passdefh_sync(frame):
    hsync.on()
    for n in range(frame):
        clock.on()
        #sleep(sleep_time)
        clock.off()
        #sleep(sleep_time)#print("hsync")
    hsync.off()
    passdefclc(frame):for n in range(frame):
        clock.on()
        #sleep(sleep_time)
        clock.off()
        #sleep(sleep_time)pass
red2.off()
red3.off()
red4.off()
red5.off()
red6.off()
red7.off()
green2.off()
green3.off()
green4.off()
green5.off()
green6.off()
green7.off()
blue2.on()
blue3.on()
blue4.on()
blue5.on()
blue6.on()
blue7.on()
clock.off()
de.off()
#de.on()
sleep(sleep_time)
v_sync(2)
clc(2)
for row in range(5):
    v_sync(2)
    # v_back_porch(2)
    clc(2)
    for column in range(800):
        h_sync(16)
        # h_back_porch(16)
        clc(16)
        # LCD column
        de.on()
        clc(480)
        de.off()
        # h_front_porch(24)
        clc(24)
    # v_front_porch(4)
    clc(4)
de.off()
red2.off()
red3.off()
red4.off()
red5.off()
red6.off()
red7.off()
green2.off()
green3.off()
green4.off()
green5.off()
green6.off()
green7.off()
blue2.off()
blue3.off()
blue4.off()
blue5.off()
blue6.off()
blue7.off()




Too me, Python. It was a surprise for me that the already rendered pixels disappear. Although what I was waiting for, it's obvious.

It was decided to rewrite everything in C. It works faster, approximately several frames per second. The screen is rippling like on old CRT monitors or radars. What you need. Retro! I put the code on github .


Access to GPIO is carried out directly through the SoC registers of the BCM2837 chip. Code examples took here .

It all started with a very tiny program, but now the display also shows the processor and memory usage in the form of small scroll bars. The temperature of the processor is drawn like this font.


To run the code, you need to copy the contents of the repository to the / home / pi / lcd_screen / folder (Who knows how to write the path relative to the binary, not the working folder in C under nix? Therefore, only in this folder) and run the following commands.

gcc ./lcd_screen/lcd.c -o ./lcd_screen/lcd
chmod +x ./lcd_screen/lcd

Or download the binary from releases immediately. To run, you need to type the following. SUDO is required to access GPIO.

sudo ./lcd_screen/lcd path/file.bmp usec_per_frame

Where “path / file.bmp” is the path to the image file, it works only with the BMP format, “usec_per_frame” is the delay between frames in microseconds in order not to load the processor in vain.

We automate the launch of our lcd program so that it displays the desired cover when the game is running. Of course, the built-in scraper is used to load the covers in Retropie.
Install the image converter. It will convert all formats to bmp, supported by the program. At the same time and resize, so that the images were full screen.

sudo apt-get install imagemagick

In the / opt / retropie / configs / all / directory, create two files: runcommand-onstart.sh and runcommand-onend.sh . Retropie automatically executes these scripts when loading / exiting any game. Do not forget to register chmod + x for each file.

runcommand-onstart.sh
#!/bin/sh

system="$1"
emulator="$2"
romname="$3"#with path#echo $system# LCD programm here: #find current config: dpi or hdmi
_DPI=$(grep dpi /boot/config.txt) || trueif ! [ "$_DPI" ]; #if hdmi then
  sudo killall lcd 
  # remove path
  filename=$(basename "$romname")
  # remove extension
  filename="${filename%.*}"# add image path
  file_png="/home/pi/.emulationstation/downloaded_images/$system/$filename-image.png"
  file_jpg="/home/pi/.emulationstation/downloaded_images/$system/$filename-image.jpg"#if system snes and n64 then rotate image 270 degreeif [ "$system" = "snes" ] || [ "$system" = "n64" ]
  theniftest -f "$file_png"; #fing filethen  
		convert "$file_png" -resize '800x480' -type TrueColor -alpha Remove -rotate 270 /home/pi/lcd_screen/work.bmp
	eliftest -f "$file_jpg"; 
	then 
		convert "$file_jpg" -resize '800x480' -type TrueColor -alpha Remove -rotate 270 /home/pi/lcd_screen/work.bmp 
	else
		convert "/opt/retropie/configs/$system/launching.png" -resize '480x800' -type TrueColor -alpha Remove -rotate 180 /home/pi/lcd_screen/work.bmp 	
	fielseiftest -f "$file_png"; 
	then  
		convert "$file_png" -resize '480x800' -type TrueColor -alpha Remove -rotate 180 /home/pi/lcd_screen/work.bmp
	eliftest -f "$file_jpg"; 
	then 
		convert "$file_jpg" -resize '480x800' -type TrueColor -alpha Remove -rotate 180 /home/pi/lcd_screen/work.bmp 
	else
		convert "/opt/retropie/configs/$system/launching.png" -resize '480x800' -type TrueColor -alpha Remove -rotate 180 /home/pi/lcd_screen/work.bmp 	
	fifi#launch my lcd project
  sudo /home/pi/lcd_screen/lcd /home/pi/lcd_screen/work.bmp 400000 &
 fi

runcommand-onend.sh
#!/bin/sh

_DPI=$(sudo grep dpi /boot/config.txt) || trueif ! [ "$_DPI" ]; 
then
  sudo killall lcd
  sudo /home/pi/lcd_screen/lcd /home/pi/lcd_screen/retropie.bmp 50000 &
#  cp /home/pi/lcd_screen/retropie.bmp /home/pi/lcd_screen/work.bmpfi


In the startup script, the presence of a DPI connection is first checked, then an image with jpeg or png formats is searched, rotated to the desired angle, its size is changed and converted to bmp format, then my program is launched with the required parameters.

Cooling


Raspberry Pi 3B is more powerful than Zero, and it needs good cooling. Especially in such a closed case. With a small radiator visible in the photo, after half an hour of playing on any emulator, the core temperature reached 80 degrees and trotting began.


A centrifugal fan of 40 * 30 * 10 mm was ordered, but before it arrived, I simply tried to cut a small plate of aluminum size 80 * 30 mm from 3 mm of aluminum. By that time I had dropped all the GPIO pins, so they no longer interfered with the installation of the plate. In addition, I also cut a piece of 20 * 10mm for contact with the chip and made a sandwich from the plates. It exceeded all my expectations, a maximum of 65 degrees on the core.


So it looks inside.



In the end, what


How is it played? Fine! With shouts, smashing gamepads, mutual reproaches. Just like sometime.

No delays and lags were noticed.

The screen, of course, is small, only three and a half inches. We spoiled smartphones with five inches, but you can play. The text is read, even small. I prefer HDMI.

You can come to a friend, play, portability allows. Related accessories: cables, cables, joysticks, charging take up more space than the console itself.

Sound


Unfortunately, the regular sound of the Raspberry Pi leaves much to be desired. PWM modulation with passive filtering is used as a sound system. Therefore, a USB DAC was purchased for PCM2704. Mostly because of its size.

There is a lack of sound output when playing on a small LCD screen, so a 3W microamplifier on the NS8002 was also bought and the speaker from the 8 ohm tablet was picked up.

USB DAC and NS8002



All this will fit under the LCD screen. Come, I will set.

Sawing Retropie


Build over. Here are some of the less interesting for entertaining reading features of the settings Retropie.

Shaders
Most of the consoles that Raspberry Pi can emulate have a resolution of 320x240 pixels. By today's standards it is very small. All games acquire pronounced pixelation on modern screens.


Создатели Retroarch, который входит в состав Retropie, озаботились этим вопросом и добавили поддержку шейдеров. Например, мне очень нравится предустановленный xbr-lv1-noblend.glslp. Он, буквально, вытягивает детали из картинки. См. ниже.

Скриншот из игры Castlevania: Symphony of the Night, советую в нее сыграть

Чтобы установить шейдер, зайдите в меню Retropie -> Configuration editor. Выберите Configure basic libretro emulator options, после выберите Configure default options for all libretro emulators. Затем установите Video Shader Enable в «true» и Video Shader File на желаемый шейдер. Установите также Video Smoth в «false», поскольку он только смазывает картинку. Можно даже выбрать что-то типа scanline шейдера, который эмитирует работу CRT телевизоров. Но это на любителя.


Отрисовка шейдеров довольно затратная операция. При разрешении равном и выше 720p на RPi 3B появляются довольно заметные подлагивания. Поэтому в этом же меню выберите Render resolution «800x600». Не волнуйтесь, если вы до этого делали изменения в файле /boot/config.txt, как в этой статье чуть выше, то разрешение экрана по кабелю HDMI будет 1080p, но эмулятор будет рендерить картинку в 800x600 и растягивать на весь экран. И делает он это не плохо. По крайне мере, с шейдером лучше, чем без него, да и рендер в 1080p бесполезен, поскольку видеоданные игры всё равно нарисованы для разрешения 320x240.

Setting the joysticks
Если у вас есть любой xinput геймпад (стандарт Micro$oft), он подойдет. Настраивается он при первом же запуске Retropie, либо через кнопку старт — Configure Input. Но и тут есть головная боль. Ушлые заокеанские ребята, чтобы не попадать на патентные судебные иски поменяли местами кнопки с A и B, X и Y.


Если у вас геймпад от xbox или аналогичный, то настраивать надо с перевернутыми кнопками, как на NES. Затем зайти в Retropie -> Retropie Setup, выбрать Configuration / tools, затем emulationstation, поставить в Swap A/B Buttons in ES «Swapped». Потом заново переконфигурируйте джойстик.

Также, мне не нравится, как разработчики Retropie распорядились кнопочным фондом. Где комбинация кнопок сделать скриншот? Зачем мне кнопка reset, если я на нее попадаю каждый раз? Где кнопки перемотки и ускорения времени?

Чтобы это исправить, нужно подредактировать файл с названием вашего джойстика в /opt/retropie/configs/all/retroarch-joypads/. Также он доступен по сети \\192.168.x.xxx\configs\all\retroarch-joypads\. После каждого обновления Retropie через апдейтер, нумерация привязки слетает, поэтому я не буду выкладывать весь конфиг. Напишу, что изменил лишь эти кнопки. Они выполняются при нажатии одновременно с Hotkey-м, обычно это кнопка с логотипом, посередине джойстика.

Button config
input_screenshot_btn = "0"
input_rewind_btn = "h0left"
input_hold_fast_forward_btn = "h0right"
input_state_slot_increase_btn = "h0up"
input_state_slot_decrease_btn = "h0down"


Здесь кнопка скриншотов назначена вместо reset. Fast forvard и rewind (перемотка назад) настроены на кнопки крестовины: вперед и назад. Кнопки крестовины вверх и вниз изменяют слот сохранения.

Rewind надо включить в конфиге /opt/retropie/configs/all/retroarch.cfg. Только не включайте Rewind на эмуляторе psx, всё начинает дико тормозить. Перемотка назад, по-умолчанию, отключена в конфиге psx.

Еще хочется добавить про Bluetooth. Сам я беспроводные джойстики не люблю и играю всегда с кабелем. Старая школа еще. Для любителей беспроводных джойстиков надо приобрести Bluetooth донгл и вставить в USB порт. Так будет лучше и никаких проблем не будет. Сам я не проверял, но знающие люди пишут.

Xboxdrv


Но и это еще не всё. В Retropie Setup в менеджере пакетов можно поставить различные порты, например Openttd, Doom или вообще DOS эмулятор Dosbox. Но управлять в них джойстиком не получится. Только клавиатурой и мышкой. Чтобы это исправить, нужно поставить в менеджере пакетов драйвер xboxdrv, который умеет эмулировать нажатия клавиатуры. Просто поставить из исходников, автозапуск делать не нужно, он не подходит под все джойстики.

Скрипт запуска напишем сами под наш геймпад. Добавим в /opt/retropie/configs/all/runcommand-onstart.sh следующие строки в конец файла.

runcommand-onstart.sh
# xboxdrv
sudo killall > /dev/null 2>&1 xboxdrv
if [ "$1" = "pc" ] || [ "$1" = "openttd" ] || [ "$1" = "doom" ] || [ "$1" = "kodi" ];
then
sudo /opt/retropie/supplementary/xboxdrv/bin/xboxdrv > /dev/shm/runcommand.log 2>&1 \
    --evdev /dev/input/event0 \
	--silent \
	--detach-kernel-driver \
	--force-feedback \
	--mimic-xpad \
	--trigger-as-button \
	--evdev-no-grab \
	--evdev-absmap ABS_X=x1,ABS_Y=y1,ABS_RX=x2,ABS_RY=y2,ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y \
	--evdev-keymap KEY_#304=a,KEY_#305=b,KEY_#307=x,KEY_#308=y,KEY_#312=lt,KEY_#313=rt,KEY_#310=lb,KEY_#311=rb,KEY_#317=tl,KEY_#318=tr,KEY_#314=back,KEY_#315=start,KEY_#316=guide \
	--axismap -Y1^deadzone:3000=Y1,-Y2^deadzone:3000=Y2 \
	--ui-axismap x2^deadzone:3000=KEY_LEFT:KEY_RIGHT,y2=KEY_UP:KEY_DOWN \
	--ui-axismap x1^deadzone:3000=REL_X:06,y1=REL_Y:06 \
	--ui-axismap dpad_x^deadzone:0=KEY_LEFT:KEY_RIGHT,dpad_y^deadzone:0=KEY_UP:KEY_DOWN \
	--ui-buttonmap rt=BTN_LEFT,lt=BTN_RIGHT,start=KEY_ENTER,back=KEY_ESC,tl=KEY_4,tr=KEY_5,lb=KEY_2,rb=KEY_3,a=KEY_SPACE,b=KEY_M,x=KEY_3,y=KEY_LEFTCTRL,guide=KEY_Y \
&
fi


Здесь $1 — наша целевая система, при которой запускается xboxdrv. Можно добавлять по аналогии. Строки --evdev-absmap --evdev-keymap отвечают за привязку осей и кнопок к вашему джойстику. Скрипт выше дан для контроллера Xbox One S. Чтобы узнать какая ось и кнопка соответствуют номеру или названию вашего джойстика, нужно в консоли набрать команду evtest. Заодно можно посмотреть какой event соответствует нашему джойстику. У меня это /dev/input/event0 который стоит в параметре --evdev.

Параметры --ui-axismap эмулируют оси мыши, а --ui-buttonmap кнопки клавиатуры. В данном примере курки — это кнопки мыши, левый стик — мышь, правый стик — курсорные клавиши. Старт, селект — enter и esc, соответственно. На остальные кнопки привязаны цифры клавиатуры. Задействовать крестовину под кнопки клавиатуры, к сожалению, не удалось. Почему-то на джойстике Xbox One S отказывается работать.

С таким конфигом отлично играются стратегии, наподобие Theme Hospital, OpenTTD и пр. Чуть хуже играется в шутеры, но вы можете создать аналогичные скрипты запуска под шутеры в этом же файле, меняя там параметр $1.

Чтобы обеспечить нормальную работу джойстика в emulationstation, нужно завершить xboxdrv после выхода из игры. Для этого в конец файла /opt/retropie/configs/all/runcommand-onend.sh добавляем следующее.

runcommand-onend.sh
sudo killall > /dev/null 2>&1 xboxdrv



If something went wrong when updating Retropie
Однажды, я запустил обновление Retropie и при распаковке ядра отвалился встроенный Wi-Fi. Устройство загружалось, но не реагировало ни на какие кнопки, в том числе на подключенной клавиатуре. SSH нет, так как нет Wi-Fi, на клавиатуру не реагирует, а SD карточку не достать…

Заметил, что клавиатура работает при загрузке. Понажимал много раз ctrl+c и, о, консоль! Но как теперь восстановить Wi-Fi? Интерфейс wlan0 отсутствовал от слова совсем. Запуск апдейтера не помог, поскольку он подтягивает файлы с интернета.

Первым делом в /opt/retropie/configs/all/autostart.sh закомментировал запуск emulationstation и перезагрузился. После перезапуска загружается консоль, клавиатура работает. Дальнейшее гугление, как вернуть wlan дало вот это. Команда переконфигурирует все установленные пакеты. Помогло.

sudo dpkg --configure -a


To make Retropie not look like a Linux station
При загрузке приставки мне не хочется смотреть на лог загрузки Linux. Он портит весь дух приставок девяностых.

Чтобы убрать лог загрузки Linux
Чтобы убрать лог загрузки Linux, нужно привести файл /boot/cmdline.txt к такому виду. Всё в одну строку.

cmdline.txt
dwc_otg.lpm_enable=0 console=tty3 root=PARTUUID=f2d3cb4f-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait loglevel=3 consoleblank=0 plymouth.enable=0 quiet vt.global_cursor_default=0 plymouth.enable=0 plymouth.ignore-serial-consoles splash


Кратко, конфиг убирает лого, выводит сообщения в другую консоль, убирает мигающий курсор.
Затем убираем весь текст в motd.

nano /etc/motd

Убираем автологин текст.

sudo nano /etc/systemd/system/autologin@.service

Нужно в этом файле изменить строку

ExecStart=-/sbin/agetty --autologin pi --noclear %I $TERM

На

ExecStart=-/sbin/agetty --skip-login --noclear --noissue --login-options "-f pi" %I $TERM

Более подробно про это написано здесь.

Также, при загрузке системы можно вывести свое фото — splashscreen. Можно и несколько, они будут сменять друг друга со временем. Нужно положить свои картинки в папку в сети \\192.168.x.xxx\splashscreens, и выбрать их в меню Retropie -> SPLASH SCREEN -> Append Splashscreen to list.

Мне, например, безумно нравится вот эта картинка.


Также в Retropie установлен runcommand, который при запуске игры выводит консольный обрезок с предложением нажатия клавиши. Этот экран можно заменить на милые картиночки игровых приставок.


Подробная инструкция, как это сделать, написана здесь.

What else can you do


Improve can be infinite. I will give a couple of links that you can do. Write more interesting things to add. Thanks for attention.


He is worth it.


Also popular now: