Fix IWD WiFi compatibility, restore glcore driver, improve sdl2text, and resolve DTS patch

- IWD: Fix SHA256 for version 3.10 (was downloading 3.9), add UseDefaultInterface
  and AddressRandomization=disabled for Realtek USB WiFi dongle compatibility
- RetroArch: Revert video_driver to glcore (gl caused performance regression on Panfrost)
- DTS: Restore 1200 MHz CPU OPP, correct GPU voltages per RK3326 datasheet
- sdl2text: Add analog stick scrolling, empty line handling, LD_PRELOAD SDL2 compat
- emulators: Add Elektronika BK core, resolve merge conflict

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Douglas Teles
2026-04-17 16:45:11 -03:00
parent 0278699ba8
commit 555711ca32
7 changed files with 132 additions and 37 deletions
@@ -1,5 +1,5 @@
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi 2026-04-02 16:22:14.377470397 -0300
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi 2026-04-02 16:22:14.378455687 -0300
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi 2026-04-03 13:23:49.793309412 -0300
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi 2026-04-03 13:24:16.188299986 -0300
@@ -20,6 +20,7 @@
#size-cells = <2>;
@@ -21,20 +21,17 @@
opp-microvolt = <950000 950000 1350000>;
clock-latency-ns = <40000>;
opp-suspend;
@@ -129,15 +131,16 @@
opp-microvolt = <1175000 1175000 1350000>;
clock-latency-ns = <40000>;
};
- opp-1200000000 {
- opp-hz = /bits/ 64 <1200000000>;
- opp-microvolt = <1300000 1300000 1350000>;
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <1350000 1350000 1350000>;
@@ -134,10 +136,16 @@
opp-microvolt = <1300000 1300000 1350000>;
clock-latency-ns = <40000>;
};
- opp-1296000000 {
- opp-hz = /bits/ 64 <1296000000>;
+ opp-1416000000 {
+ opp-hz = /bits/ 64 <1416000000>;
+ opp-microvolt = <1350000 1350000 1350000>;
+ clock-latency-ns = <40000>;
+ };
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
opp-microvolt = <1350000 1350000 1350000>;
@@ -43,7 +40,7 @@
};
};
@@ -348,6 +351,32 @@
@@ -348,6 +356,32 @@
};
};
@@ -76,7 +73,7 @@
pmugrf: syscon@ff010000 {
compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xff010000 0x0 0x1000>;
@@ -1065,22 +1094,14 @@
@@ -1065,22 +1099,14 @@
gpu_opp_table: opp-table-1 {
compatible = "operating-points-v2";
@@ -105,7 +102,7 @@
};
gpu: gpu@ff400000 {
@@ -1091,10 +1112,25 @@
@@ -1091,10 +1117,25 @@
<GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "job", "mmu", "gpu";
clocks = <&cru SCLK_GPU>;
@@ -24,6 +24,7 @@ EOF
else
# Show game guide if exists
if [ -f "/storage/.config/sdl2text/game_guide.path" ]; then
export LD_PRELOAD=/usr/lib/compat/libSDL2-2.0.so.0
GAME_GUIDE_PATH="$(cat /storage/.config/sdl2text/game_guide.path)"
/usr/bin/sdl2text "${GAME_GUIDE_PATH}"
else
@@ -141,8 +141,21 @@ struct LineTexture { SDL_Texture* tex; int w,h; };
std::vector<LineTexture> create_textures(SDL_Renderer* ren, TTF_Font* font, const std::vector<std::string>& wrapped, SDL_Color color) {
std::vector<LineTexture> textures;
for(auto &line:wrapped) {
// Handle empty lines
if(line.empty()) {
int lineHeight = TTF_FontHeight(font);
textures.push_back({nullptr, 0, lineHeight});
continue;
}
SDL_Surface* surf=TTF_RenderUTF8_Blended(font,line.c_str(),color);
if(!surf) continue;
if(!surf) {
// If render fails, still add a placeholder for the line height
int lineHeight = TTF_FontHeight(font);
textures.push_back({nullptr, 0, lineHeight});
continue;
}
SDL_Texture* tex=SDL_CreateTextureFromSurface(ren,surf);
textures.push_back({tex,surf->w,surf->h});
SDL_FreeSurface(surf);
@@ -191,15 +204,26 @@ int main(int argc,char* argv[]) {
SDL_GameController* pad=nullptr;
for(int i=0;i<SDL_NumJoysticks();i++) { if(SDL_IsGameController(i)) { pad=SDL_GameControllerOpen(i); if(pad) break; } }
// Wrap lines while preserving empty lines
std::vector<std::string> wrapped;
for(auto &line:lines) {
std::string clean=filter_invalid_chars(line,font);
auto chunks=wrap_line(clean,font,WINDOW_W-20);
wrapped.insert(wrapped.end(),chunks.begin(),chunks.end());
if(line.empty()) {
// Preserve empty lines
wrapped.push_back("");
} else {
std::string clean=filter_invalid_chars(line,font);
auto chunks=wrap_line(clean,font,WINDOW_W-20);
wrapped.insert(wrapped.end(),chunks.begin(),chunks.end());
}
}
auto textures=create_textures(ren,font,wrapped,white);
bool upPressed=false,downPressed=false,l1Pressed=false,r1Pressed=false,startPressed=false;
// Analog joystick axis state (left stick Y and right stick Y)
int16_t axisLeftY=0, axisRightY=0;
const int16_t AXIS_DEADZONE=8000;
const float AXIS_SCROLL_SCALE=0.002f; // pixels per frame at full deflection
bool running=true,showHelp=false;
SDL_Event e;
bool touchActive=false;
@@ -211,6 +235,11 @@ int main(int argc,char* argv[]) {
while(SDL_PollEvent(&e)) {
if(e.type==SDL_QUIT) { running=false; break; }
if(e.type==SDL_CONTROLLERAXISMOTION) {
if(e.caxis.axis==SDL_CONTROLLER_AXIS_LEFTY) axisLeftY = e.caxis.value;
if(e.caxis.axis==SDL_CONTROLLER_AXIS_RIGHTY) axisRightY = e.caxis.value;
}
if(e.type==SDL_CONTROLLERBUTTONDOWN) {
switch(e.cbutton.button) {
case SDL_CONTROLLER_BUTTON_DPAD_UP: upPressed=true; break;
@@ -220,16 +249,39 @@ int main(int argc,char* argv[]) {
case SDL_CONTROLLER_BUTTON_START: startPressed=true; break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
fontSize+=2; TTF_CloseFont(font); font=loadFont(fontSize); if(!font){fontSize-=2; font=loadFont(fontSize);}
// Re-wrap with new font size, preserving empty lines
wrapped.clear();
for(auto &line:lines) { std::string clean=filter_invalid_chars(line,font); auto chunks=wrap_line(clean,font,WINDOW_W-20); wrapped.insert(wrapped.end(),chunks.begin(),chunks.end()); }
for(auto &line:lines) {
if(line.empty()) {
wrapped.push_back("");
} else {
std::string clean=filter_invalid_chars(line,font);
auto chunks=wrap_line(clean,font,WINDOW_W-20);
wrapped.insert(wrapped.end(),chunks.begin(),chunks.end());
}
}
for(auto &lt:textures) if(lt.tex) SDL_DestroyTexture(lt.tex);
textures=create_textures(ren,font,wrapped,white); lineHeight=TTF_FontHeight(font); break;
textures=create_textures(ren,font,wrapped,white);
lineHeight=TTF_FontHeight(font);
break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
fontSize-=2; if(fontSize<8) fontSize=8; TTF_CloseFont(font); font=loadFont(fontSize); if(!font){fontSize+=2; font=loadFont(fontSize);}
// Re-wrap with new font size, preserving empty lines
wrapped.clear();
for(auto &line:lines) { std::string clean=filter_invalid_chars(line,font); auto chunks=wrap_line(clean,font,WINDOW_W-20); wrapped.insert(wrapped.end(),chunks.begin(),chunks.end()); }
for(auto &line:lines) {
if(line.empty()) {
wrapped.push_back("");
} else {
std::string clean=filter_invalid_chars(line,font);
auto chunks=wrap_line(clean,font,WINDOW_W-20);
wrapped.insert(wrapped.end(),chunks.begin(),chunks.end());
}
}
for(auto &lt:textures) if(lt.tex) SDL_DestroyTexture(lt.tex);
textures=create_textures(ren,font,wrapped,white); lineHeight=TTF_FontHeight(font); break;
textures=create_textures(ren,font,wrapped,white);
lineHeight=TTF_FontHeight(font);
break;
case SDL_CONTROLLER_BUTTON_A: running=false; break;
case SDL_CONTROLLER_BUTTON_B: running=false; break;
case SDL_CONTROLLER_BUTTON_BACK: showHelp=!showHelp; break;
}
@@ -250,39 +302,68 @@ int main(int argc,char* argv[]) {
if(e.type==SDL_FINGERUP) touchActive=false;
}
// Controller continuous scrolling
// D-pad continuous scrolling
if(upPressed) scroll_y-=SCROLL_SPEED;
if(downPressed) scroll_y+=SCROLL_SPEED;
if(l1Pressed) scroll_y-=SKIP_LINES*lineHeight;
if(r1Pressed) scroll_y+=SKIP_LINES*lineHeight;
// Analog joystick scrolling (left stick or right stick, whichever is deflected)
// Apply deadzone, then scale linearly to scroll pixels
auto applyAxis = [&](int16_t raw) {
if(raw > AXIS_DEADZONE)
scroll_y += (int)((raw - AXIS_DEADZONE) * AXIS_SCROLL_SCALE);
else if(raw < -AXIS_DEADZONE)
scroll_y += (int)((raw + AXIS_DEADZONE) * AXIS_SCROLL_SCALE);
};
applyAxis(axisLeftY);
applyAxis(axisRightY);
// Secret kill combo: L1 + START + SELECT
if(l1Pressed && startPressed && SDL_GameControllerGetButton(pad, SDL_CONTROLLER_BUTTON_BACK)) running=false;
// Clamp
int total_height=(int)textures.size()*lineHeight;
int total_height=0;
for(const auto& tex : textures) total_height += tex.h;
if(total_height<WINDOW_H) total_height=WINDOW_H;
if(scroll_y<0) scroll_y=0;
if(scroll_y>total_height-WINDOW_H) scroll_y=total_height-WINDOW_H;
// Render
SDL_SetRenderDrawColor(ren,0,0,0,255); SDL_RenderClear(ren);
int firstLine=scroll_y/lineHeight, offsetY=-(scroll_y%lineHeight);
// Find starting line based on scroll position
int firstLine=0;
int accumulatedHeight=0;
for(size_t i=0;i<textures.size();i++) {
if(accumulatedHeight + textures[i].h > scroll_y) {
firstLine=i;
break;
}
accumulatedHeight += textures[i].h;
}
int offsetY = - (scroll_y - accumulatedHeight);
for(size_t i=firstLine;i<textures.size() && offsetY<WINDOW_H;i++) {
if(textures[i].tex) { SDL_Rect dst={10,offsetY,textures[i].w,textures[i].h}; SDL_RenderCopy(ren,textures[i].tex,nullptr,&dst); }
offsetY+=textures[i].h;
if(textures[i].tex) {
SDL_Rect dst={10,offsetY,textures[i].w,textures[i].h};
SDL_RenderCopy(ren,textures[i].tex,nullptr,&dst);
}
offsetY += textures[i].h;
}
// Help overlay
if(showHelp) {
std::vector<std::string> helpLines={
"CONTROLS:",
"SELECT - Toggle This Help",
"SELECT - Toggle Help Screen",
"STICK UP/DOWN - Scroll Up / Down",
"DPAD UP/DOWN - Scroll Up / Down",
"L1/R1 - Skip Up / Down",
"DPAD LEFT/RIGHT - Dec / Inc Font Size",
"Touch Drag - Scroll Up / Down",
"B - Exit"
"DPAD LEFT/RIGHT - + / - Text Size",
"TOUCHSCREEN - Scroll Up / Down",
"A / B - Exit"
};
// Calculate box height based on content
@@ -340,8 +421,18 @@ int main(int argc,char* argv[]) {
// ---- Line Counter (bottom-right) ----
{
int currentLine = scroll_y / lineHeight + 1;
int totalLines = (int)textures.size();
// Calculate current line number based on scroll position
int currentLine = 1;
int accumulatedHeight = 0;
for(size_t i=0;i<textures.size();i++) {
if(accumulatedHeight + textures[i].h > scroll_y) {
currentLine = i + 1;
break;
}
accumulatedHeight += textures[i].h;
}
int totalLines = (int)textures.size();
if (currentLine < 1) currentLine = 1;
if (currentLine > totalLines) currentLine = totalLines;
@@ -734,7 +734,7 @@ video_context_driver = "wayland"
video_crop_overscan = "true"
video_ctx_scaling = "false"
video_disable_composition = "false"
video_driver = "gl"
video_driver = "glcore"
video_filter = ""
video_filter_dir = "~/.config/retroarch/filters/video"
video_font_enable = "true"
@@ -4,7 +4,7 @@
. ${ROOT}/packages/network/iwd/package.mk
PKG_VERSION="3.10"
PKG_SHA256="0cd7dc9b32b9d6809a4a5e5d063b5c5fd279f5ad3a0bf03d7799da66df5cad45"
PKG_SHA256="640bff22540e1714f71772a83123aff6f810b7eb9d7d6df1e10fb2695beb5115"
pre_configure_target() {
export LIBS="-lncurses -ltinfo"
@@ -2,6 +2,9 @@
[General]
EnableNetworkConfiguration=true
ControlPortOverNL80211=false
UseDefaultInterface=true
AddressRandomization=disabled
AddressRandomizationRange=full
[Network]
RoutePriorityOffset=200
@@ -9,6 +12,5 @@ RoutePriorityOffset=200
NameResolvingService=systemd
EnableIPv6=true
[Scan]
MaximumPeriodicScanInterval=30
@@ -362,6 +362,10 @@ makeinstall_target() {
add_emu_core ios touchhle touchhle-sa true
add_es_system ios
### Elektronika BK
add_emu_core bk retroarch bk true
add_es_system bk
### Nintendo Famicom
add_emu_core famicom retroarch nestopia true
add_emu_core famicom retroarch fceumm false