Dingoonity.org
Dingux (Dingoo Linux) => Development => Topic started by: DiegoSLTS on December 13, 2011, 04:46:54 pm
-
I used web.archive.org to recover some of the info on dingoo-wiki: http://web.archive.org/web/20100919034848/http://dingoowiki.com/index.php?title=Main_Page
I'm not sure how long that link will work, so I'll paste here everything on OpenDingux:Development:
Video
Frame Buffer
When setting a video mode, the legacy kernel will accept any requested resolution and color depth but regardless of what was asked it will return a 320x240x16bpp mode. This would break SDL's automatic color depth conversion since SDL would think no conversion was necessary. Elta's rootfs patches SDL to work around this issue. In OpenDingux, requests to the kernel for modes other than 320x240x16bpp will fail. If you're using SDL, you can ask SDL for 320x240x8bpp and SDL will automatically do the colorspace conversion for you. If you ask for a resolution other than 320x240, both the kernel and SDL will deny that request.
SDL has three surface modes:
- software surface: SDL_SWSURFACE
- hardware surface with single buffering: SDL_HWSURFACE
- hardware surface with double buffering: SDL_HWSURFACE | SDL_DOUBLEBUF
These modes are selected by passing the mentioned flags to SDL_SetVideoMode().
In the legacy kernel, software surface and hardware surface with single buffering work. However, single buffering means that any pixel drawn can immediately end up on the screen even if the current frame is not finished yet. As a result, any graphics that are painted in layers will end up flickering badly. This can be seen in the optional info bar at the top of the screen in psx4all, for example. Double buffering in the legacy kernel is broken so badly it will likely crash or hang the application that tries to use it.
In OpenDingux, all three modes work. Currently the page flip of double buffering is not properly synchronized yet, so there can be glitches, but they are relatively rare. Hardware surface with double buffering is the preferred mode since it has lower overhead than the software surface: one less buffer in memory and one less buffer to copy each frame, and does not suffer from the tearing and layer paint issues of the single buffered hardware surface.
If you want to access the frame buffer directly, make sure you always lock the surface before using the "pixels" pointer in the SDL_Surface struct. Also make sure you end a frame by calling SDL_Flip(), since that works for both software and hardware surfaces, while SDL_UpdateRect() only works for software surfaces.
Here is some stripped down example code:
SDL_Surface *surface = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
if (!surface) {
// ...error handling...
}
// ...other initialization code...
while (running) {
// ...stuff to do every frame...
if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
// ...access frame buffer directly through surface->pixels...
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
SDL_Flip(surface);
}
LCD Backlight
The intensity of the backlight can be controlled through sysfs:
# echo 120 > /sys/class/backlight/pwm-backlight/brightness
From the same brightness file you can also read the current value. The minimum brightness is 0 (off), the maximum can be read from the max_brightness file. The maximum is 255 under OpenDingux, but it's more portable to read it from the file.
Display Blanking
You can turn off the display by writing the string "1" to the blank file in sysfs:
# echo 1 > /sys/class/graphics/fb0/blank
To turn the display back on, write "0" to the same file.
Blanking not only turns off the backlight, it also powers down the LCD controller and suspends frame uploads to the LCD controller.
Audio (Empty on the archive)
Input (Empty on the archive)
The kernel header <linux/input.h> contains constants named KEY_* with the numbers used to identify keys in input events.
The key mappping for OpenDingux:
D-pad up KEY_UP
D-pad down KEY_DOWN
D-pad left KEY_LEFT
D-pad right KEY_RIGHT
A button KEY_LEFTCTRL
B button KEY_LEFTATL
X button KEY_SPACE
Y button KEY_LEFTSHIFT
Left shoulder KEY_TAB
Right shoulder KEY_BACKSPACE
START button KEY_ENTER
SELECT button KEY_ESC
power slider KEY_POWER
power hold KEY_PAUSE
Note that putting the power slider in hold position is a key down event and taking it out of the hold position is a key release event; this is different from a PC pause key where you'd do press+release to pause and press+release again to unpause.
CPU Frequency Control (Empty on the archive)
-----------
My older original post:
Hi, I'm trying to adapt FCEU320 0.3 to run in OpenDingux. It uses /dev/mem to get the input so I'm trying to switch to /dev/event0. The problem is I don't know what event code is generated when I press a button, is there a place (a page, a pdf) to see them? So far I've found that "A" has the code 29, "B" the code 56, and the "value" of the event is 1 or 0 if the button was pressed or released. But there are also events with code 0 and value 0, or code 129 (I think it's the power switch).
Are there some C or C++ source or header file with those codes? In FCE320 source there's a "minimal.h" with some constants for the /dev/mem method but they doesn't match the event0 codes.
Maybe it's easier with SDL events, but the code is really hard to follow and I'm trying to change small things.
I'm trying with FCEU320 0.3 because it's the only source I found for a NES emulator, so if anyone has the source of another NES emulator that worked on legacy dingux maybe I can try with it instead.
-
The kernel header <linux/input.h> contains constants named KEY_* with the numbers used to identify keys in input events.
The key mappping for OpenDingux:
D-pad up KEY_UP
D-pad down KEY_DOWN
D-pad left KEY_LEFT
D-pad right KEY_RIGHT
A button KEY_LEFTCTRL
B button KEY_LEFTATL
X button KEY_SPACE
Y button KEY_LEFTSHIFT
Left shoulder KEY_TAB
Right shoulder KEY_BACKSPACE
START button KEY_ENTER
SELECT button KEY_ESC
power slider KEY_POWER
power hold KEY_PAUSE
Note that putting the power slider in hold position is a key down event and taking it out of the hold position is a key release event; this is different from a PC pause key where you'd do press+release to pause and press+release again to unpause.
-
Thanks! I don't know how I missed them, of course they were in <linux/input.h>. I guess all the .h and .cpp of FCEU320 confused me :P.
-
I'm trying with FCEU320 0.3 because it's the only source I found for a NES emulator, so if anyone has the source of another NES emulator that worked on legacy dingux maybe I can try with it instead.
There's also nofrendo (source (http://www.baisoku.org/nofrendo-2.0pre1.zip)). It's very fast, but has a lower compatibility than fceu.
-
Me again, I've edited the title so I (and anyone) can ask questions about fixing legacy dingux apps to work on OpenDingux.
I know there was an article on the wiki with tips about this, but since it's down those tips are lost. I went to web.archive.org and found some info, but I'm not sure if there was more. I'll paste all I can find on the first post.
Also, I have a new question, now about sound. FCEU320 used OSS and accessed to /dev/dsp. I'm trying to use ALSA, but can't find the proper values of things... I get sound, but really bad sound, with a lot of noise and out off sync.
I found that there's an "OSS to ALSA" library but can't find it on OpenDingux. Is there one? Or is there a way to reuse oss code?
-
The "OSS to ALSA" wrapper library didn't perform good on the dingoo, we decided not to include it.
Instead, OpenDingux features the "libAO" library, which is very easy to use, and which can in its turn output audio using either OSS, ALSA, PulseAudio... You may want to try that lib, it's much easier than using ALSA directly.
The wiki did have a complete tutorial on how to modify a program to use libAO instead of OSS, I hope it's not been lost...
If you want to continue with ALSA, I know there's a good number of functions to call to initialize the hardware, maybe you're missing one of those calls.