Skip to content

Commit aef92b3

Browse files
committed
README corrections
1 parent caa6cae commit aef92b3

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

README.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ Linux can provide all the pixel data shown on the screen (frame buffers) in devf
156156

157157
Instead of _RGBA32_, the GBA understands _RGB555_ (or _15bpp color_), which means 5 bits for red, 5 for green, and 5 for blue with no alpha channel. As it's a little-endian system, first one is red.
158158

159-
To draw those colors on the screen, it supports 3 [several bitmap modes](https://www.coranac.com/tonc/text/bitmaps.htm). For this project, I used _mode 4_, where each pixel is an 8-bit reference to a palette of 256 different 15bpp colors. The only consideration to have when using mode 4 is that VRAM doesn't support 8-bit writes, so you have to read first what's on the address to rewrite the complete halfword/word.
159+
To draw those colors on the screen, it supports 3 [different bitmap modes](https://www.coranac.com/tonc/text/bitmaps.htm). For this project, I used _mode 4_, where each pixel is an **8-bit** reference to a palette of **256** 15bpp colors. The only consideration to have when using mode 4 is that VRAM doesn't support 8-bit writes, so you have to read first what's on the address to rewrite the complete halfword/word.
160160

161161
<p align="center">
162162
<i>15bpp color representation</i>
@@ -165,12 +165,11 @@ To draw those colors on the screen, it supports 3 [several bitmap modes](https:/
165165
</p>
166166

167167
**Related code:**
168-
- [GBA deciding the draw cursor](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L153)
169168
- [GBA writing a pixel in mode 4](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/Utils.h#L30)
170169

171170
### Color quantization
172171

173-
So, the Raspberry Pi has to [quantize](https://en.wikipedia.org/wiki/Color_quantization) every frame to a 256 colors palette. In an initial iteration, I was using a quantization library that generated the most optimal palette for each frame. Though that's the best regarding image quality, it was too slow. The implemented solution ended up using a fixed palette ([this one](https://en.wikipedia.org/wiki/List_of_software_palettes#6-8-5_levels_RGB) in particular), and approximate every color to an 8-bit referencing palette's colors.
172+
So, the Raspberry Pi has to [quantize](https://en.wikipedia.org/wiki/Color_quantization) every frame to a 256 colors palette. In an initial iteration, I was using a quantization library that generated the most optimal palette for each frame. Though that's the best regarding image quality, it was too slow. The implemented solution ended up using a fixed palette ([this one](https://en.wikipedia.org/wiki/List_of_software_palettes#6-8-5_levels_RGB) in particular), and approximate every color to a byte referencing palette's colors.
174173

175174
<table border="0">
176175
<tr>
@@ -202,9 +201,9 @@ To approximate colors faster, when running the code for the first time, it creat
202201

203202
### Scaling
204203

205-
The frame buffer is _240x160_ but what's sent to the GBA is configurable, so if you prefer a killer frame rate over detail you can send _120x80_ and use the [mosaic effect](https://www.coranac.com/tonc/text/gfx.htm#sec-mos) to scale the image to fill the entire screen. Or, if you like old [CRT](https://en.wikipedia.org/wiki/Cathode-ray_tube)s, you could send _240x80_ and draw artificial scanlines between each actual line.
204+
The frame buffer is _240x160_ but what's sent to the GBA is configurable, so if you prefer a killer frame rate over detail you can send _120x80_ and use the [mosaic effect](https://www.coranac.com/tonc/text/gfx.htm#sec-mos) to scale the image so it fills the entire screen. Or, if you like old [CRT](https://en.wikipedia.org/wiki/Cathode-ray_tube)s, you could send _240x80_ and draw artificial scanlines between each actual line.
206205

207-
The Raspberry Pi discards each pixel that is not multiple of the drawing scale. For example, if you use a 2x width scale factor, it will discard odd pixels and the resulting width will be _120_ instead of _240_.
206+
The Raspberry Pi discards each pixel that is not a multiple of the drawing scale. For example, if you use a 2x width scale factor, it will discard odd pixels and the resulting width will be _120_ instead of _240_.
208207

209208
At the time of rendering, you have to take this into account because GBA's _mode 4_ expects a _240x160_ pixel matrix. If you give it less, you'd only fill a part of the screen.
210209

@@ -239,7 +238,7 @@ At the time of rendering, you have to take this into account because GBA's _mode
239238
**Related code:**
240239
- [RPI ignoring pixels](https://github.com/rodri042/gba-remote-play/blob/v0.9/raspi/src/GBARemotePlay.h#L279)
241240
- [GBA setting up mosaic](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L71)
242-
- [GBA deciding the draw cursor](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L153)
241+
- [GBA selecting the draw cursor](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L153)
243242

244243
### Image compression
245244

@@ -282,7 +281,7 @@ However, RLE doesn't always make things better: it can sometimes produce a longe
282281

283282
#### Trimming the diffs
284283

285-
For a render resolution of _120x80_, the bit array would be _120x80/8 = 1200bytes_. That's a lot to transfer every frame, so it only sends the part from the first '1' to the last '1', but of course in 32-bit packets.
284+
For a render resolution of _120x80_, the bit array would be _120x80/8 = 1200bytes_. That's a lot to transfer every frame, so it only sends the chunk from the first '1' to the last '1', but of course in 32-bit packets.
286285

287286
```
288287
v startPacket v endPacket
@@ -334,6 +333,7 @@ For every frame, the steps to run are:
334333
**Related code:**
335334
- [GBA Main loop](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L81)
336335
- [RPI Main loop](https://github.com/rodri042/gba-remote-play/blob/v0.9/raspi/src/GBARemotePlay.h#L42)
336+
- [Protocol](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/Protocol.h#L4)
337337

338338
### Metadata exchange
339339

@@ -349,7 +349,7 @@ In this step, the GBA sends its input and receives a _frame metadata_ packet:
349349
> audio flag: if 1, the frame includes an audio chunk
350350
```
351351

352-
As a sanity check, this transfer is done twice. The second time, each device sends the received packet on the first transfer. If it doesn't match => **Reset!**
352+
As a sanity check, this transfer is done twice. The second time, each device sends the received packet during the first transfer. If it doesn't match => **Reset!**
353353

354354
**Related code:**
355355
- [Metadata exchange on the GBA](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/_main.cpp#L104)
@@ -359,6 +359,9 @@ As a sanity check, this transfer is done twice. The second time, each device sen
359359

360360
For the audio, the GBA runs [a port](https://github.com/pinobatch/gsmplayer-gba) of the [GSM Full Rate](https://en.wikipedia.org/wiki/Full_Rate) audio codec. It expects 33-byte audio frames, but in order to survive frame drops, GSM frames are grouped into chunks, with its length defined by a build time constant called `AUDIO_CHUNK_SIZE`.
361361

362+
**Related code:**
363+
- [Audio chunk size constant](https://github.com/rodri042/gba-remote-play/blob/v0.9/gba/src/Protocol.h#L22)
364+
362365
### Reading system audio
363366

364367
On the Raspberry Pi side, we use [a virtual sound card](https://www.alsa-project.org/wiki/Matrix:Module-aloop) that is preinstalled on the system. When you start the module (`sudo modprobe snd-aloop`), two new sound devices appear (both for playing and recording).
@@ -382,7 +385,7 @@ On the Raspberry Pi side, we use [a virtual sound card](https://www.alsa-project
382385
</tr>
383386
</table>
384387

385-
How it works is that if some application plays sound on -for example- `hw:0,0,0` (card 0, device 0, substream 0), other application can record on `hw:0,1,0` and obtain that sound. The loopback cards have to be set as the default output on the system, so we can record whatever sound is running on the OS.
388+
How it works is that if some application plays sound on -for example- `hw:0,0,0` (card 0, device 0, substream 0), another application can record on `hw:0,1,0` and obtain that sound. The loopback cards have to be set as the default output on the system, so we can record whatever sound is running on the OS.
386389

387390
### Encoding GSM frames
388391

@@ -415,7 +418,7 @@ Since transferring a frame takes time, it can sometimes happen that more audio f
415418
<img src="https://user-images.githubusercontent.com/1631752/125158350-03f13880-e147-11eb-914d-cced48d84969.gif">
416419
</p>
417420

418-
To fix that, there's a [ioctl](https://man7.org/linux/man-pages/man2/ioctl.2.html) we can use (called [FIONREAD](https://docs.oracle.com/cd/E19683-01/806-6546/kermes8-28/index.html)) to retrieve the amount of queued bytes. To skip over those, we call the [splice](https://en.wikipedia.org/wiki/Splice_(system_call)) system call to redirect them to `/dev/null`.
421+
To fix that, there's an [ioctl](https://man7.org/linux/man-pages/man2/ioctl.2.html) we can use (called [FIONREAD](https://docs.oracle.com/cd/E19683-01/806-6546/kermes8-28/index.html)) to retrieve the amount of queued bytes. To skip over those, we call the [splice](https://en.wikipedia.org/wiki/Splice_(system_call)) system call to redirect them to `/dev/null`.
419422

420423
**Related code:**
421424
- [Skipping outdated bytes](https://github.com/rodri042/gba-remote-play/blob/v0.9/raspi/src/LoopbackAudio.h#L82)
@@ -509,7 +512,7 @@ Then, when you run `cat /proc/asound/modules` you should see:
509512

510513
Now run `sudo modprobe snd-aloop` and set **Loopback (Stereo Full Duplex)** as the default output audio device from the UI.
511514

512-
As a last step, edit the config file of GBA Remote Play (`config.cfg`) and increase `SPI_DELAY_MICROSECONDS` to `4`. **It won't work with the default delay!**
515+
As a last step, open the config file of GBA Remote Play (`config.cfg`) and make sure that `SPI_DELAY_MICROSECONDS` is `4`. **It won't work with smaller values!**
513516

514517
# Credits
515518

0 commit comments

Comments
 (0)