Skip to content

Add Overlay Support #46

Description

@nchapman

Feature Request: Overlay Support

Overview

Add PNG-based overlay support to minarch, allowing users to display bezels, scanlines, borders, and other graphical overlays during gameplay.

Implementation Details

File format: PNG images
Location: /Overlays/{CORE}/ directories (e.g., /Overlays/GBA/bezel.png)

Example directory structure:

/Overlays/
  GBA/
    gba-bezel.png
    scanlines.png
  GB/
    gameboy-frame.png
  NES/
    crt-effect.png

Features

  • 100% portable - Just needs PNG support (already in MinUI via SDL2_image)
  • Core-specific - Different overlays per emulator
  • Dynamic loading - Scans folder and populates menu at runtime
  • Toggle on/off - In-game menu option
  • None option - Always available to disable overlays

Implementation Tasks

Core overlay system (workspace/all/minarch/minarch.c):

  • Add overlay option to frontend config (FE_OPT_OVERLAY)
  • Implement dynamic overlay list population
  • Add "None" as first option in overlay list
  • Hook overlay selection to GFX_setOverlay() call

Platform API (workspace/all/common/api.h):

  • Define OVERLAYS_FOLDER path constant
  • Define GFX_setOverlay macro → PLAT_setOverlay
  • Document overlay rendering requirements

Per-platform implementation (workspace/*/platform/platform.c):

  • Implement PLAT_setOverlay(char* filename, char* core_tag)
  • Load PNG from /Overlays/{core_tag}/{filename}
  • Composite overlay over game rendering
  • Handle overlay disable (filename = "None")

Example implementation:

// In minarch.c initialization
char overlaypath[255];
snprintf(overlaypath, sizeof(overlaypath), "%s/%s", OVERLAYS_FOLDER, core.tag);
char** overlaylist = list_files_in_folder(overlaypath, &count, NULL);

// Add "None" as first option
char** newlist = malloc((count + 2) * sizeof(char*));
newlist[0] = strdup("None");
for (int i = 0; i < count; i++) {
    newlist[i + 1] = overlaylist[i];
}
newlist[count + 1] = NULL;

config.frontend.options[FE_OPT_OVERLAY].labels = newlist;
config.frontend.options[FE_OPT_OVERLAY].values = newlist;
config.frontend.options[FE_OPT_OVERLAY].count = count + 1;

Menu integration:

// Overlay selection callback
if (exactMatch(key, config.frontend.options[FE_OPT_OVERLAY].key)) {
    char** overlayList = config.frontend.options[FE_OPT_OVERLAY].values;
    if (value >= 0 && value < overlay_count) {
        GFX_setOverlay(overlayList[value], core.tag);
        overlay = value;
    }
}

Implementation Tasks Breakdown

Phase 1: Infrastructure

  • Add OVERLAYS_FOLDER constant to defines.h
  • Add GFX_setOverlay API to api.h
  • Create /Overlays/ directory in skeleton
  • Add per-console subdirectories

Phase 2: Core Integration

  • Add FE_OPT_OVERLAY to frontend options enum
  • Implement overlay list scanning on startup
  • Add overlay dropdown to in-game menu
  • Hook selection to GFX_setOverlay() call

Phase 3: Platform Rendering

  • Implement PLAT_setOverlay() for initial platform (tg5040 or miyoomini)
  • Test overlay compositing over game output
  • Verify performance impact
  • Add fallback/stub for platforms without overlay support

Phase 4: Polish

  • Handle overlay persistence in config
  • Add example overlays to repository
  • Document overlay creation guidelines (resolution, transparency)

Testing Checklist

  • Test overlay loading from /Overlays/{CORE}/ folders
  • Test "None" option disables overlay
  • Test switching overlays mid-game
  • Test overlay persistence across game sessions
  • Test with missing overlay folder (graceful degradation)
  • Test performance impact (especially on lower-end devices)
  • Test different overlay resolutions/formats

Platform Considerations

Rendering approach options:

  1. SDL2 surface compositing (simple, portable)
  2. OpenGL texture blend (fast, requires GL support)
  3. Framebuffer overlay (lowest overhead, platform-specific)

Start with SDL2 surface compositing for maximum portability.

Documentation

  • Document overlay creation guidelines
    • Recommended resolution per platform
    • Alpha channel usage
    • File naming conventions
  • Add example overlays (GB frame, GBA bezel, scanlines)
  • Link to overlay resources/communities

Example Overlays to Include

  • GB/GBC - Game Boy frame overlay
  • GBA - Bezel with visible screen area
  • NES - CRT scanline effect
  • Generic - Simple border templates

Portability: 100% - PNG support already available via SDL2_image
Complexity: Low-Medium - Requires per-platform rendering implementation
Priority: Medium - Nice quality-of-life feature

Reference: NextUI implementation (workspace/all/minarch/minarch.c:2241-2268)
Related: May want to combine with screen effect system for consistency

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions