💾 Archived View for her.st › blog › developing-for-the-rg351mp.gmi captured on 2023-05-24 at 17:59:34. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
I have no idea what the factory shipped, I was afraid of anbernic-poisoning so I immediately went to flash ArkOS ... 3 times... unsuccessfully and then settled for 351elec @ https://351elec.de/.
elec was a new experience for me. Linux, yes, but everything runs as root, there are no users, no homes, not even a package manager. Getting dotnet and monogame up and running was quite the adventure.
Now, what can this thing do? Let's look at the hardware so we can get a rough idea about its capabilities.
The official Anbernic Store says its a 1.5ghz CPU, that however is a *lie*. It runs at 1.3ghz. I'll be taking a look at overclocking later, maybe I can make it true.
Alright, so we're dealing with an Ultra-Low-Power CPU from long-long-ago. The L2 cache is hilariously small, there's no L3 cache at all.
1GB of DDR3L RAM is not fast either and the GPU will share it with the CPU, making it even slower. Small cache, slow RAM, I'm predicting a memory bandwidth bottleneck. At least it can do SIMD, so we can vectorize our code. Now let's look at the GPU.
Further research shows it's running at 650 MHz, has two cores and can push 1,3 GPix/s, 980 MT/s or 21.4 GFLOPs.
Interestingly, ARM claims 4x MSAA has almost no performance overhead - we'll see about that!
Also surprisingly, it supports Vulkan!
So we're basically working with an original xbox in terms of performance - with some extra CPU cores and newer feature-sets. Sweet.
Anbernic was smart enough to use a low resolution screen, namely a 3.5", 640x480 @ 60hz IPS screen.
Most manufacturers would have slapped a 720p or 1080p screen on it just for marketing and cripple the rest of the hardware, but at 640x480, there aren't many pixels to push.
I want to add that the screen is super crisp. The resolution is more than enough for the size.
Suikoden, Pokemon, Earthbound, Batsugun, Alien Soldier, Advance Wars 2, Tekken 3.... I've already wasted a couple of hours writing this post, even at this moment, it's next to me playing some demo videos of random games as screensaver (which you can jump into by pressing start, launching the game that's currently playing, super cool!) begging me to pick it up or at least look at it.
Can't wait to play some more Destruction Derby later, but the dog will want out before I'm done writing. Ugh.
The primary reason for me to even buy this device has been to give me some additional motivation for creating games. I want to target the RG351 directly and make it my primary platform. I figured becoming a console game developer would be cool as it would impose a lot of hard limitations on me - not only in terms of performance, but also input methods and screen size.
elec is a readonly OS. Every reboot - it resets. Persistent storage is only possible in /storage. Which is the 2nd uSD card in the RG351MP. That's fine by me.
Since elec has no real shell, ships almost no libraries and has no terminal, we need to setup a couple of things like a script to launch our game and find/ship all the files required for the game to function. On MonoGame you need to ship libGL.so.1 and libEGL.so.1.
351elec is a 64bit OS and the RK3326 is an ARM CPU, that makes our dotnet command
dotnet publish -c release -r linux-arm64
but first we have to enable single file output.
csproj
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6</TargetFramework> <MonoGamePlatform>DesktopGL</MonoGamePlatform> <TieredCompilation>false</TieredCompilation> <PublishSingleFile>true</PublishSingleFile> <SelfContained>true</SelfContained> </PropertyGroup>
now we scp the contents of the publish folder and create our little launcher script
#!/bin/bash gamedir="/storage/roms/ports/test/" if [ -d "/opt/system/Tools/PortMaster/" ]; then controlfolder="/opt/system/Tools/PortMaster" elif [ -d "/opt/tools/PortMaster/" ]; then controlfolder="/opt/tools/PortMaster" elif [ -d "/roms/ports" ]; then controlfolder="/roms/ports/PortMaster" elif [ -d "/roms2/ports" ]; then controlfolder="/roms2/ports/PortMaster" else controlfolder="/storage/roms/ports/PortMaster" fi echo "Starting Pixel Engine (.net6, C#10, ECS) by https://her.st/" > /dev/tty0 source $controlfolder/control.txt source $controlfolder/tasksetter.sh export LIBGL_ES=31 export LIBGL_FB=4 export SDL_VIDEO_GL_DRIVER="$gamedir/libs/libGL.so.1" cd $gamedir $GPTOKEYB "Pixel" -c "./test.gptk" & $TASKSET ./Pixel > /dev/tty0 kill -9 $(pidof gptokeyb) printf "\033c" >> /dev/tty0
map.gptk:
back = esc start = enter a = enter b = up x = \" y = \" l1 = mouse_right l2 = mouse_right r1 = mouse_left r2 = mouse_left up = w down = s left = a right = d left_analog_up = up left_analog_down = down left_analog_left = left left_analog_right = right right_analog_up = mouse_movement_up right_analog_down = mouse_movement_down right_analog_left = mouse_movement_left right_analog_right = mouse_movement_right deadzone_triggers = 3000 mouse_scale = 8192 mouse_delay = 16
The "game" will now show up in 351elec and you'll be able to launch it.
That's as far as I got in a day. Documentation didn't exist so I had to reverse engineer other ports to figure out how to port >.>
I got my PixelGlue engine running, tomorrow I'll get inputs working properly...
For game development on the RG351MP, the architectural choice seems obvious -> ECS
We need to hit the cache or we cripple the GPU with increased memory bandwidth requirements from the CPU side. It will be essential to use all four cores as they're rather weak.
Vulkan goes without saying, however that's out of reach for me at this point. I lack the required skills.