Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 568d50c

Browse files
committed
Initial commit
0 parents  commit 568d50c

20 files changed

+863
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*~
2+
build

LICENSE

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Copyright (c) 2024 Dov Grobgeld <[email protected]>
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDi
16+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Author
2+
3+
Dov Grobgeld
4+
5+
Last edited: 2024-09-10 Tue
6+
7+
# License
8+
9+
All files in this repository are licensed under the following BSD License. See ![LICENSE](./LICENSE)
10+
11+
# Intro
12+
13+
The R36S is a very powerful little handheld computer, that comes with the Linux based ArkOS Open Source operating system preinstalled. The system is built with emulation in mind, but as it is a standard Linux based system, it is quite straightforward to write native programs and games for it.
14+
15+
This repo will explore what is needed to program the system in C. Note that in addition, you can use almost any program that Linux supports and which has SDL bindings. E.g. C++, python, and zig.
16+
17+
# Connecting
18+
19+
In order to program the R36S you first need to connect to it from your computer by carrying out the folloiwing steps.
20+
21+
1. Connect Wifi dongle to the right hand usb port
22+
2. Navigate through EmulationStation (ES) to Options, and connect to your local Wifi, by choosing your SSID and entering your password.
23+
3. In the Options menu, choose "Enable remote services". This will only be needed the first time, as we will turn on this permanently. (See note about ssh connections below)
24+
4. After succesfully connecting, check the IP address you connected to through Options->Network Info
25+
5. On your PC, launch a ssh client and connect to the R36S
26+
6. Login with user:ark password:ark
27+
28+
You now have a Linux shell on your R36S!
29+
30+
# ssh
31+
32+
SSH standands for "Secure SHell" and it is as standard way for unix-like systems to communicate. Once you have turned on the "remote service" option, your R36S is running the SSH daemon, and is ready for remote connections from any ssh client.
33+
34+
There are a large veriety of ssh clients available for different systems. Though in principle it is possible to connect a keyboard to the R36S and program it directly, it is much more convienient to use a "real computer" with a keyboard and connect by ssh. There are lots of ssh clients and tools that for various operating systems.
35+
36+
Here is a list of some of them:
37+
38+
1. Command line ssh - This is the standard terminal connection
39+
2. putty - A client for Windows system
40+
3. termux - This is an android terminal emulator which contains an ssh client. If "all" you have is a android tablet with a keyboard, then you can use it to program the R36S.
41+
4. Microsoft Visual Code - There are several clients available as extensions. This especially useful when you program on the R36S, and through the extension you can use edit remote files and then, compile and run your programs straight from the editor.
42+
5. (emacs with tramp - This is what I use, but I have long ago stopped trying to persuade others to copy my old habits. :-) )
43+
44+
# Security and passwords
45+
46+
Note about security. By default ArkOS comes configured with default user/password ark/ark. Once you connect the first time you are strongly encouraged to change the password to something else by issuing the `passwd` command:
47+
48+
```
49+
ark@rg351mp:~$ passwd
50+
Changing password for ark.
51+
Current password:
52+
New password:
53+
```
54+
Note that when you are typing passwords at the shell, **there is no echo**, so you won't see neither the password you type nor any placeholders like "*".
55+
56+
## SSH keys
57+
58+
In addition to password based authentication, ssh allows public key based authentication, which will allow you to connect without needing to type your password. Describing how to set that up, is beyond the scope of this tutorial.
59+
60+
## scp
61+
62+
Scp stands for secure copy. It is convenient if you are editing the source files of your programs on your desktop and you can then copy them over to the R36S before you compile.
63+
64+
```
65+
scp hello-sdl2.c r36s:git/r36s-programming/cprog/hello-sdl2/
66+
```
67+
68+
# Git
69+
70+
git is a version control system. It is not strictly necessary for programming the R36S, but you do not want to work without it. It will allow you to backup and do source control of the program that you develop, and will also provide a convenient way of syncing the programs that you develop, between your R36S system and yor desktop.
71+
72+
# Preparing the system
73+
74+
Once you have connected the first time by your are working at the Linux prompt. We are now able to modify and setup the system to make it suitable for programming, initially for C and C++ .
75+
76+
Here are the steps that you need to do:
77+
78+
1. Automatically allow ssh connections without needing to turn it on through the ES menu:
79+
80+
```
81+
sudo systemctl enable sshd
82+
```
83+
2. Setup C and C++ environment. The arkos system comes with some of the system packages crippled, e.g. they are missing header files needed for C-compilation. The following command rectifies this as well as sets up additional system development packages that we need:
84+
```
85+
sudo apt-get install --reinstall libc6-dev libsdl2-dev linux-libc-dev g++ libstdc++-9-dev libsdl2-ttf-dev git python3 ninja-build cmake make python3
86+
```
87+
88+
3. We are now ready to compile our first C-program. To do so, first clone this repository by git
89+
```
90+
mkdir git && cd git
91+
git clone http://github.com/dov/r36s-programming
92+
```
93+
94+
4. You can now compile your first program from the command line
95+
96+
```
97+
cd cprog/hello-world
98+
mkdir build && cd build && cmake -GNinja ..
99+
ninja
100+
./hello-world
101+
```
102+
103+
This program writes "Hello world" to the console and quits.
104+
105+
5. If you are using Visual Studio Code on your host computer, install the "Remote - SSH" extension from the Visual Studio Market place. The first time you connect, visual studio will dowload the VS Code Server, and it will then allow you to edit files on the R36S.
106+
107+
(I tried installing the Microsoft C/C++ extension. However, I could not get this to work. I'd be happy if someone can explore this further).
108+
109+
# Graphics by SDL2
110+
111+
Our first hello world program was a command line program. But to write games, we want to have graphics. The R36S supports the standard graphics library SDL2. We can test compiling a SDL2 based c-program as follows:
112+
113+
```
114+
cd ~/git/r36-programming/cprog/hello-sdl2
115+
mkdir build && cd build && cmake -GNinja ..
116+
ninja
117+
./hello-sdl2
118+
```
119+
120+
This worked, somehow, but our program "collides" with the use of the screen by ES, because our program and ES are both running at the same time.
121+
122+
To fix this we can exit emulator system by Menu→Quit→Quit Emulationstation. This will turn the EmulationStation off, until next time you reboot the R36S.
123+
124+
If we now rerun ./hello-sdl2, we get only our colorful SDL on the screen:
125+
126+
![sdl-screenshot](images/sdl-screenshot.png)
127+
128+
# SDL2 specifics for the R36S
129+
130+
Even though the R36S is using a standard SDL, there are a few specifics that you need to be aware of:
131+
132+
1. The screen is 640x480 pixels. This is the only resolution that you can use.
133+
2. All the input controls are mapped as joystick buttons and axes. You can read the state of the joystick by the standard SDL2 joystick functions. In order to use the joystick you need to open it as follows in C:
134+
135+
```
136+
// Initialize SDL before everything else, so other SDL libraries can be safely initialized
137+
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 ) {
138+
printf("Error : failed to initialize SDL (%s).\n", SDL_GetError());
139+
return EXIT_FAILURE;
140+
}
141+
142+
// Check for joysticks
143+
if (SDL_NumJoysticks() < 1) {
144+
printf( "Warning: No joysticks connected!\n" );
145+
return EXIT_FAILURE;
146+
}
147+
else {
148+
// Load joystick
149+
gGameController = SDL_JoystickOpen( 0 );
150+
if (gGameController == NULL) {
151+
printf( "Warning: Unable to open game controller! SDL Error: %s\n", SDL_GetError() );
152+
return EXIT_FAILURE;
153+
}
154+
}
155+
156+
```
157+
158+
Once this is done, you can read the state of the joystick by the standard SDL2 joystick functions:
159+
160+
```
161+
while (SDL_PollEvent(&Event)) {
162+
switch (Event.type) {
163+
case SDL_JOYAXISMOTION:
164+
printf("axis = %d value = %d\n",
165+
Event.jaxis.axis, Event.jaxis.value);
166+
// Handle Joystick Motion
167+
break;
168+
case SDL_JOYBUTTONDOWN:
169+
printf("JoyButtonDown %d\n", Event.jbutton.button);
170+
break;
171+
case SDL_JOYBUTTONUP:
172+
printf("JoyButtonUp %d\n", Event.jbutton.button);
173+
break;
174+
}
175+
}
176+
```
177+
178+
# Mapping of the R36S controls
179+
180+
The following table show the mapping of the joystick buttons and axes to the R36S controls:
181+
182+
| Joy-Button | Description |
183+
|------------|-------------|
184+
| 0 | B |
185+
| 1 | A |
186+
| 2 | X |
187+
| 3 | Y |
188+
| 4 | L1 |
189+
| 5 | R1 |
190+
| 6 | L2 |
191+
| 7 | R2 |
192+
| 8 | D-Up |
193+
| 9 | D-Down |
194+
| 10 | D-Left |
195+
| 11 | D-Right |
196+
| 12 | Select |
197+
| 13 | Start |
198+
| 16 | Fn |
199+
200+
The axes are mapped as follows:
201+
202+
| Joy-Axis | Description |
203+
|----------|------------------------------------|
204+
| 0 | Left joystick - Left-Right motion |
205+
| 1 | Left joystick - Up-Down motion |
206+
| 2 | Right joystick - Left-Right motion |
207+
| 3 | Right joystick - Up-Down motion |
208+
209+
The program `print-joystick` will print the axes and buttons of the joystick to the console.
210+
211+
Press Fn+Start to exit the program.
212+
213+
# Installing into EmulationStation
214+
215+
It is possible to setup EmulationStation to support our native games. This is done by modifying the following files:
216+
217+
* `/etc/emulationstation/es_systems.cfg` - This file contains a list of our "emulators". We will add a new system "native" to this file.
218+
* `/etc/emulationstation/themes/es-theme-nes-box/` - Contains themes for the various emulators. We want to add a theme for our "native" system. If you are using another theme, you will want to modify the destination.
219+
220+
To simplify this, enter the `scripts` sub directery of this repository and run the script `install-native-emulator.sh` as follows:
221+
222+
```
223+
cd ~/git/r36-programming/scripts
224+
python3 install-native-emulator.py
225+
```
226+
227+
By default this script will reboot the R36S at the end. You may change this behavior, and other defaults, by setting the command line argument.
228+
229+
If all goes well you will now have a native menu in emulator station:
230+
231+
![es-native1](images/es-native1.jpg)
232+
233+
And if you enter it, you will see the c++ sdl program listed as a "game".
234+
235+
![es-native2](images/es-native2.jpg)
236+
237+
## Note about theme
238+
239+
The "native" theme images were created by me and are free to use and copy.
240+
241+
# Final thoughts
242+
243+
First of all, this repository, and this article is work in progress. I hope to expand it as time allows.
244+
245+
However, my intention was not to teach "everything". There are lots of material available on the net about Linux, SDL, git, game programming, and more. My intent was to try to put these into perspective with regards to the R36S.
246+
247+
Please let me know your feedback and comments!
248+
249+

binaries/hello-sdl2.exec

14.2 KB
Binary file not shown.

cprog/hello-sdl2/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
project(hello-world VERSION 1.0.0 LANGUAGES C)
4+
5+
add_executable(hello-sdl2
6+
hello-sdl2.c
7+
)
8+
9+
find_package(SDL2 REQUIRED)
10+
target_link_libraries(hello-sdl2 PRIVATE SDL2)
11+

cprog/hello-sdl2/hello-rect.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//======================================================================
2+
// A sdl2 program that draws a white window with a red circle.
3+
//
4+
// 2024-09-09 Mon
5+
// Dov Grobgeld <[email protected]>
6+
//----------------------------------------------------------------------
7+
8+
#include <SDL2/SDL.h>
9+
#include <stdio.h>
10+
#include <stdarg.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
14+
static void die(const char *fmt, ...)
15+
{
16+
va_list ap;
17+
va_start(ap,fmt);
18+
19+
vfprintf(stderr, fmt, ap);
20+
exit(-1);
21+
}
22+
23+
#define SCREEN_WIDTH 640
24+
#define SCREEN_HEIGHT 480
25+
26+
int main(int argc, char* argv[])
27+
{
28+
// Initialize SDL
29+
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
30+
die("SDLInit Error: %s\n", SDL_GetError());
31+
32+
// Create a window
33+
SDL_Window *win = SDL_CreateWindow("Hello, World!",
34+
SDL_WINDOWPOS_UNDEFINED,
35+
SDL_WINDOWPOS_UNDEFINED,
36+
SCREEN_WIDTH, SCREEN_HEIGHT,
37+
SDL_WINDOW_FOREIGN);
38+
39+
if (win == NULL)
40+
die("SDL_CreateWindow Error: %s\n", SDL_GetError());
41+
42+
// Create a renderer
43+
//SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
44+
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
45+
46+
// Setup t0 time using SDL
47+
Uint32 t0 = SDL_GetTicks();
48+
49+
if (ren == NULL)
50+
die("SDL_CreateRenderer Error: %s\n", SDL_GetError());
51+
52+
// Event loop
53+
SDL_bool quit = SDL_FALSE;
54+
while (!quit) {
55+
56+
// Poll for events with timeout of 100ms
57+
SDL_Event e = { .type=0 };
58+
SDL_WaitEventTimeout(&e, 10);
59+
60+
switch (e.type) {
61+
case SDL_QUIT:
62+
quit = SDL_TRUE;
63+
break;
64+
default:
65+
break;
66+
}
67+
68+
// Set draw the interface
69+
SDL_SetRenderDrawColor(ren, 0, 0, 255, 255);
70+
SDL_RenderClear(ren);
71+
72+
// Draw and animate
73+
SDL_Rect fillRect = { SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4,
74+
SCREEN_WIDTH/2, SCREEN_HEIGHT / 2 };
75+
SDL_RenderFillRect(ren, &fillRect);
76+
77+
SDL_RenderPresent(ren);
78+
79+
// Exit after 5 seconds
80+
if (elapsed > 10000)
81+
break;
82+
}
83+
84+
// Clean up
85+
SDL_DestroyRenderer(ren);
86+
SDL_DestroyWindow(win);
87+
SDL_Quit();
88+
89+
return 0;
90+
}

0 commit comments

Comments
 (0)