Make it so that the VFO screen shows the frequency with a consistent set
precision. Show the hundredths place in the full size font, then show
the thousandths and ten-thousandths place in font two steps smaller.
This way it's easier to scroll through frequencies and read where you are.
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Previously gfx_drawSymbol returned the glyph's {width, height} size
(propagated verbatim from gfx_printBuffer). This made it impossible to
chain consecutive symbol draws by reusing the return value as the next
start position.
Change the return value to the position immediately to the right of the
drawn symbol: {origin_x + xAdvance, start.y}. No existing caller used
the return value, so there are no behavioural regressions.
This is important to make it easier to show messaging icons in the top
bar in future commits.
Co-authored-by: GitHub Copilot <copilot@github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Add openrtx/src/core/graphics.c and openrtx/include/core/graphics.h
in scripts/clang_format.sh and apply the formatter. No functional
changes.
Co-authored-by: GitHub Copilot <copilot@github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Adds gfx_printBufferClipped: a variant of gfx_printBuffer that accepts
an explicit right-edge limit (max_x) and a vertical clip window
[clip_top_y, clip_bot_y]. Word-wrap fires when the next glyph would
exceed max_x. Pixels outside the clip window are suppressed without
affecting layout, so a negative start.y can be used to implement smooth
text scrolling.
gfx_printBuffer now delegates entirely to gfx_printBufferClipped with
clip_top_y=0 and clip_bot_y=CONFIG_SCREEN_HEIGHT-1. The old pixel guard
used strict > 0 comparisons, which excluded pixels at row 0 and column 0.
The new implementation renders those pixels; callers that relied on the
old exclusion will see a behaviour change.
Compared to a naive port of gfx_printBuffer, this implementation
addresses several correctness issues:
- Control characters '\n' and '\r' are checked before the glyph array
is indexed, avoiding undefined behaviour on fonts whose first codepoint
is at or above 0x20 (e.g. TomThumb, first=0x20), since '\n' (0x0A)
would produce a negative index.
- get_line_size uses <= instead of < when accumulating glyph widths so
that a glyph whose xAdvance exactly equals max_width is counted. The
render loop uses strict > to trigger wrap, so the old < mismatch caused
text_size.x to be under-reported by one glyph whenever a line was an
exact fit, and misplaced CENTER/RIGHT lines in that case.
- For TEXT_ALIGN_LEFT, line_size is recomputed on every '\n' before the
max_line_size comparison. Without this, max_line_size was stuck at the
first-line width for the entire call, so text_size.x was wrong whenever
a subsequent line was wider.
- saved_start_y is int16_t to match point_t.y, allowing correct
text_size.y computation when start.y is negative (scroll offset).
- text_size.y is computed as (start.y - saved_start_y) + line_h,
matching the sign fix introduced for gfx_printBuffer.
- Pixels above row 0 (py < 0) are suppressed before the uint16_t cast
passed to gfx_setPixel, preventing a silent wrap to a large row index.
- max_line_size tracks the widest line across all line breaks and wraps;
text_size.x reflects the widest line, not just the last.
Extend tests/unit/gfx_text.cpp with return-value tests covering:
single-line height, two-line height delta equals yAdvance, negative
start.y scroll offset, negative clip_top_y, exact-fit line width
(get_line_size <= boundary), max line width from a wider first line,
max line width from a wider second line (TEXT_ALIGN_LEFT regression),
glyph at clip_bot_y not skipped, and TEXT_ALIGN_RIGHT per-line reset.
Co-authored-by: GitHub Copilot <copilot@github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Refactor the static helper get_line_size to accept an explicit max_width
parameter instead of the hardcoded CONFIG_SCREEN_WIDTH cap. All three
call sites in gfx_printBuffer are updated to pass CONFIG_SCREEN_WIDTH,
preserving existing behaviour.
Add gfx_measureText: a pure-computation function that simulates the same
word-wrap pass as gfx_printBufferClipped (to be added next) without
touching the display. It returns the total pixel height of the laid-out
text block and accepts a char_count limit so callers can compute the
y-coordinate of an arbitrary cursor position for scroll-offset
calculations.
Add tests/unit/gfx_text.cpp and register the gfx_text_test executable in
meson.build. The test suite covers single-line strings, multi-line
strings via explicit newlines, char_count truncation, and word-wrap
height growth.
Co-authored-by: GitHub Copilot <copilot@github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Three bugs fixed in gfx_printBuffer:
1. Word-wrap was remeasuring line size from the start of the buffer
instead of from the current position, causing incorrect alignment on
wrapped lines. Pass &buf[i] to get_line_size and pass reset_x (not
start.x) to get_reset_x so the left margin is preserved across wraps.
2. The glyph array was indexed unconditionally before the '\n'/'\r'
check. For fonts whose first glyph is 0x20 (space), a newline
character (0x0A) produces a negative index, which is undefined
behaviour. Move the control-character check before the glyph lookup.
3. text_size.y was computed as (saved_start_y - start.y) + line_h.
Because start.y grows downward as lines are added, the subtraction
underflows for any multi-line string. Correct to
(start.y - saved_start_y) + line_h. Also change saved_start_y to
int16_t to match point_t.y.
Co-authored-by: GitHub Copilot <copilot@github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
The Linux emulator had no working audio output: the speaker endpoint had a
NULL driver (streams returned -ENODEV). This adds an SDL2 audio playback
driver for the output path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
On native (non-cross) builds, try codec2 resolution in this order:
1. pkg-config (homebrew, Nix, and other pkg-config-based installs)
2. Compiler's built-in find_library (libcodec2-dev on Debian/Ubuntu)
3. Subproject build from source (embedded fallback)
This fixes macOS homebrew builds without breaking Linux system package
installations that lack a .pc file but have the library on the search
path. The previous single find_library approach missed homebrew installs.
Also guard the audioDevice struct alignment change to only apply on
Darwin ARM64 where Apple's int64_t misbehaves with packed structs.
Other platforms retain the original __attribute__((packed)) to avoid
increasing memory usage on resource-constrained embedded targets.
Co-authored-by: opencode (https://opencode.ai)
Co-authored-by: OpenRTX Contributors
Pushing to a PR branch now cancels the previous in-progress run
instead of queueing a duplicate ~40 minute build. Runs on branches
(master included) are never cancelled. Also drop the unused
RADIO_TOOL_VERSION env var.
Signed-off-by: Vlastimil Slinták <slintak@uart.cz>
The image is the layer cache for the build workflow and goes stale
whenever the ubuntu:24.04 base image is updated upstream. Since the
last rebuild (May 26) the base moved (Jul 2), so every CI run now
rebuilds the full Miosix toolchain (~40 min) and is exposed to GNU
mirror outages. Also drop two unused env vars from this workflow.
Signed-off-by: Vlastimil Slinták <slintak@uart.cz>
The toolchain build cloned miosix-kernel HEAD, so upstream layout
changes could break CI at any time. Fetch a fixed SHA instead.
Fixes#469
Signed-off-by: Vlastimil Slinták <slintak@uart.cz>
The artifact renaming step interpolates the branch name into output
file names. A branch name containing a slash (e.g. fix/foo) makes mv
interpret it as a nonexistent directory path and the build job fails.
Seen on PR #489.
Signed-off-by: Vlastimil Slinták <slintak@uart.cz>
W25Qx_writePage released the SPI bus mutex without ever acquiring it,
leaving page programs unguarded on shared buses and unlocking a mutex
possibly held by another thread. The lock was lost in the extended
addressing refactor (404e8403).
Fixes#476
Signed-off-by: Vlastimil Slinták <slintak@uart.cz>
Make clang-format cheking all the files in the repository by default.
The shell script now contains a list of files and folders excluded from
the check, to be progressively reduced when these files are updated to
the new coding style.
Signed-off-by: Silvano Seva <silseva@fastwebnet.it>
fileSource_data() assigned dest from ctx->buffer but never wrote the
pointer back to the caller's *buf, leaving the consumer with the
original (uninitialized or stale) pointer it passed in. On the Linux
platform this meant baseband audio streamed from file sources was
silently dropped, breaking loopback and file-based baseband tests.
Set *buf = dest immediately after dest is initialized so the caller
always receives the valid buffer pointer.
Co-authored-by: GitHub Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Right now we depend on developers to know not to commit the meson
subproject wraplock file. Folks not familiar with meson may not realize
that this is essentially a build artifact, or LLM agents may mistakenly
commit this as an oversight.
Large meson codebases have ensured this in the past, such as
[gstreamer](https://github.com/GStreamer/gstreamer/blob/main/.gitignore#L47) having it in gitignore
or
[gtk](https://gitlab.gnome.org/GNOME/gtk/-/tree/main/subprojects?ref_type=heads)
intentionally not checking in the wraplock. Let's ensure the same for
us.
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Add the `.venv` directory to gitignore, as this is the
python-recommended directory name for virtual envs. This avoids having
developers mistakenly commit changes to include this directory.
Signed-off-by: Ryan Turner <ryan@turnrye.com>
Remove Xcode-specific #pragma directives, not recognized by GCC and
triggering the -Wunknown-pragma warning
Signed-off-by: Silvano Seva <silseva@fastwebnet.it>
Adapt voice prompts code to the new standard, where typedef before enum
and struct type is to be avoided unless really necessary.
For a rationale see:
https://docs.kernel.org/process/coding-style.html#typedefs
Signed-off-by: Silvano Seva <silseva@fastwebnet.it>