RiptOPL DOCS

Theme Engine

A RiptOPL/OPL theme is a folder of images, fonts and one text file โ€” conf_theme.cfg โ€” that lays out the whole UI on a virtual 640ร—480 canvas. This page is the complete authoring reference: every block family, every element type, every property and value token the parser in src/themes.c actually understands, including this fork's Coverflow carousel and the two-layer overlay system. Nothing here is invented โ€” if a key isn't listed, the engine ignores it.

i Mental model
A theme is a flat, ordered list of elements. Each element has a type= and a handful of position/size properties. OPL draws them back-to-front in file order, scales the 640ร—480 canvas to the real video mode, and (with scaled=1) corrects for widescreen and the PS2's non-square pixels automatically. Anything a theme doesn't supply falls back to OPL's embedded default assets.

1 ยท File & folder structure

Themes live in the THM support folder. Each theme is its own sub-folder whose name must start with thm_; the loader strips that prefix to form the name you see in the theme picker. Inside the folder, all the artwork/fonts sit alongside a single conf_theme.cfg.

THM/
  thm_MyTheme/
    conf_theme.cfg      โ† the layout (this page)
    incebtion.png       โ† background, fonts, case art, screenshotsโ€ฆ (any names you reference)
    case.png
    myfont.ttf

RiptOPL also ships two built-in themes you can study as references without copying any files: the classic <OPL> theme and this fork's default <Coverflow> theme. Their sources are misc/conf_theme_OPL.cfg and misc/theme_coverflow.cfg in the repository โ€” both are reproduced and annotated lower down.

conf_theme.cfg is a plain key/value file with exactly two kinds of line:

# lines beginning with '#' are comments โ€” comment a whole block to disable it
bg_color=#182580          # a global property

main0:                    # an element block
    type=Background
    pattern=BG
i Block keys are flattened
Internally a block property foo under block main0 is read as the key main0_foo. You almost always write the indented form above, but knowing this explains the flat tables in ยง3โ€“ยง4 โ€” every "property" is just a <block>_<property> key.

2 ยท Block families & the contiguous-numbering rule

Element block names carry a family prefix plus an index โ€” e.g. main0, main1, appsMain2, vcdInfo3. Each family targets one screen/view. The base families are main<N> (the games list/menu page) and info<N> (the game info page). On top of those, this fork adds three per-slot override families. For every slot N the engine looks for the family's block; if it's absent it falls back down a fixed chain โ€” so you override only what differs and inherit the rest.

Family (main / info)Drawn onPer-slot fallback chain
main0โ€ฆ / info0โ€ฆThe games list / info โ€” the base layout(none โ€” this is the base)
appsMain0โ€ฆ / appsInfo0โ€ฆThe apps device list / infoโ†’ mainN / infoN
favsMain0โ€ฆ / favsInfo0โ€ฆThe Favourites tab list / infoโ†’ mainN / infoN
vcdMain0โ€ฆ / vcdInfo0โ€ฆA device's PS1 / VCD view (toggle with L3)main: โ†’ appsMainN โ†’ mainN ยท info: โ†’ infoN

The parser reads as many base main<N> blocks as you define, then for each slot 0โ€ฆN resolves every family against that chain. Practically:

โš  Contiguous-numbering rule
Blocks are read in order from 0 and the engine stops at the first gap. If you define main0, main1, main3 (skipping main2), then main3 is never read. When you delete a block, renumber the ones after it so there are no holes. The same applies inside each info* sequence. (A commented-out block counts as a deletion โ€” re-number around it.)
Why does a Background have to be element 0? The first element of a list must be the Background (the engine inserts a default plasma background if you forget). Likewise only the first ItemsList becomes the games list, the second the apps list, the third the Favourites list โ€” so order matters beyond just draw order. The PS1/VCD view reuses the games list, so it never needs its own ItemsList.

3 ยท Global properties

These go at the top of the file, outside any block.

Colours (#RRGGBB)

KeyApplies to
bg_colorPlasma / background tint
text_colorDefault element text colour
ui_text_colorUI text (menus, buttons, hints)
sel_text_colorSelected-item text colour

Colours are 8 bits per channel in hex; alpha is fixed internally (the parser sets it for you).

Fonts

KeyValueNotes
default_fontfont file pathThe theme's main font; falls back to the built-in font if the file is missing.
font1 โ€ฆ font15font file pathExtra fonts; each defaults to default_font if not set.
default_font_sizeint (px)Size for the default font (defaults to the system default if โ‰ค 0).
font1_size โ€ฆ font15_sizeint (px)Per-font sizes.

Reference a font from an element with font=N (0 = default). font1=builtin is not a real token: the parser builds the path <theme>/builtin, that file doesn't exist, so the load fails and the slot falls back to the embedded default font. The <Coverflow> theme relies on this file-not-found fallback (and for the built-in <Coverflow> the font keys aren't parsed at all, since font loading is skipped for buffer-loaded built-in themes).

Other global keys

KeyValueMeaning
use_default0 / 1Use OPL's embedded default assets for anything the theme omits (default 1).
use_real_height0 / 1Lay out against the real screen height instead of the virtual 480.
use_settings_bg0 / 1Load the theme's own settings_bg.png behind the settings menus instead of the plasma. Theme-supplied only โ€” there is no embedded default, so the built-in themes leave the plasma in place.
coverflow_cover_offsetint (clamped โˆ’1024โ€ฆ1024, default 0)Horizontal nudge for the Coverflow carousel (see ยง9).
i Not a real key
You may see plasma_blend_color= in the shipped theme_coverflow.cfg. The current parser does not read it โ€” the plasma blend uses bg_color. It's a harmless leftover; don't rely on it.

4 ยท Common element properties

Every element block starts with type=<ElementType> (see ยง5). Almost all of them also accept these positioning/appearance properties:

PropertyTypeNotes
xint or POS_MIDHorizontal position. Negative = measured from the right edge. POS_MID = horizontal centre.
yint or POS_MIDVertical position. Negative = measured from the bottom edge. POS_MID = vertical centre.
widthint or DIM_INFDIM_INF = full screen width.
heightint or DIM_INFDIM_INF = full screen height.
aligned0 / 10 = anchor top-left; 1 = centre the element on (x, y).
scaled0 / 10 = raw pixels; 1 = ratio-correct (handles widescreen + pixel aspect). Use 1 for images you want undistorted.
color#RRGGBBText/tint colour. Defaults to text_color.
font0 โ€ฆ 15Font index (see ยง3). Default 0.
reflection0 / 1Draw a mirrored, alpha-faded reflection beneath the element (used by Coverflow). Default 0.
reflection_offsetint (clamped โˆ’1024โ€ฆ1024)Shift the reflection vertically (e.g. to clear a case base).
enabled0 / 1Set 0 to skip the element without deleting the block. Default 1.

Value tokens: POS_MID and DIM_INF (above), and #RRGGBB for colours. Negative x/y anchor to the right/bottom edge โ€” let those and the tokens do the work instead of hard-coding resolution-specific numbers.

5 ยท Element types

Set with type=. Elements marked (item) redraw whenever you move the selection.

type=Renders
BackgroundFull-screen background. With pattern=BG it draws the plasma; with a default= image it draws that. Must be the first element of its list (auto-added if you omit it).
StaticImageA fixed image from default= (supports overlays).
StaticTextFixed text from value=.
AttributeText (item)Game metadata text โ€” see attribute= in ยง6.
GameCountText (item)The number of items in the current list.
GameImage (item)Dynamic art from pattern= (cover / screenshot / icon โ€ฆ) with a default= fallback.
AttributeImage (item)A badge image chosen by a game attribute โ€” see ยง6.
MenuIconThe current device/menu icon.
MenuTextThe current menu name, with left/right arrows when there are sibling menus.
ItemsList (item)The scrolling list of games/apps. First one = games list, second = apps, third = Favourites. Auto-added if omitted.
ItemIcon (item)A per-item icon element (a GameImage bound to the ICO cache).
ItemCover (item)The selected item's cover (a GameImage bound to the COV cache), with optional overlay.
ItemText (item)The selected item's startup filename.
HintTextButton hints for the list screen.
InfoHintTextButton hints for the info screen.
LoadingIconThe animated loading spinner (only one per theme).
BdmIndexThe block-device (BDM) mode indicator โ€” shows which mass device slot is active.
Coverflow (item)This fork: a centred cover-art carousel (see ยง9).

Text-element extras

PropertyUsed byNotes
valueStaticTextThe literal string to show.
attributeAttributeText, AttributeImageThe metadata key (ยง6).
displaytext0 = always show label + value; 1 = only when the value exists; 2 = value only (no label).
wraptext1 = word-wrap within width/height.
titleAttributeTextOverride the auto-localised label for the attribute.

List extras

PropertyUsed byNotes
decoratorItemsListA GameImage pattern name (e.g. ICO) to draw as a small per-row icon next to each entry.

6 ยท Image & overlay properties (incl. the two-layer system)

Image-type elements (StaticImage, GameImage, Background, AttributeImage, ItemCover, Coverflow) add these:

PropertyTypeNotes
defaultasset nameThe image to draw / fall back to (a built-in name from ยง8, or a file in the theme folder).
patterncache suffixFor dynamic art: COV (cover), SCR / SCR2 (screenshots), ICO (icon), BG (background), โ€ฆ
countintNumber of cache slots for pattern (the engine forces a minimum of 2 for COV).
overlayasset nameAn optional frame drawn around the image (a case / bezel). This is layer 1.
overlay_ulx, overlay_ulyintUpper-left corner of the inlaid art inside the overlay.
overlay_urx, overlay_uryintUpper-right corner.
overlay_llx, overlay_llyintLower-left corner.
overlay_lrx, overlay_lryintLower-right corner.
overlay2asset nameAn optional second overlay (layer 2) painted over overlay. It shares the element's position/size and takes no corners of its own.

The four overlay corners describe where the inner art sits within the overlay frame, in the element's own coordinate space (relative to width/height). They scale with the drawn element, so the cover window tracks the art at any size. Omitted corner keys default to 0.

i The two-layer overlay (RiptOPL)
The draw order is cover โ†’ overlay โ†’ overlay2. A single asymmetric frame would force the cover off-centre; splitting the frame into two layers over a centred cover avoids that shift. The fork's graphics use it as: the cover, then case (the transparent plastic / case frame, layer 1), then case_overlay (foliage / decoration, layer 2). Both layers are de-duplicated across every element that names the same asset, so re-using a layer costs no extra VRAM. overlay2 is drawn as a plain pixmap over the cover composite โ€” it never takes corner coordinates.

7 ยท attribute= values

AttributeText (metadata text)

For type=AttributeText, set attribute= to a metadata key. The label is auto-localised (override it with title=):

attribute=Shows
TitleGame title
GenreGenre
DeveloperDeveloper / publisher
ReleaseRelease date
DescriptionLong description (use wrap=1 + a width/height box)
#SizeInstall size โ€” the value is auto-suffixed with MiB

AttributeImage (badge chosen by the game's value)

For type=AttributeImage, set attribute= to one of the keys below. OPL reads the game's current value for that attribute; where the glyph comes from depends on the theme:

โš  Disk-theme filename order
The file is <value>_<attribute>, not <attribute>_<value> โ€” PS2DVD_#DiscType.png is correct, #DiscType_PS2DVD.png is never read. The # is a literal filename character, and the extension must be lower-case .png (the PS2 HDD's filesystem is case-sensitive). These badges are populated on every device โ€” USB/BDM, SMB, MMCE and the internal HDD/HDL (and their PS1/VCD lists).
attribute=AxisValue(s) OPL setsDisk-theme file
#SystemConsole (FR #49)PS1, PS2PS1_#System.png, PS2_#System.png
#MediaDisc typeCD, DVD (APP for homebrew)CD_#Media.png, DVD_#Media.png
#DiscTypeConsole + media (issue #49)PS1CD, PS2CD, PS2DVDPS1CD_#DiscType.png, PS2CD_#DiscType.png, PS2DVD_#DiscType.png
#FormatImage formatISO, ZSO, UL, ELF, HDL, VCDISO_#Format.png, โ€ฆ
Vmode / Aspect / Scan / Players / RatingCompatibility (value is the full glyph name)Vmode_ntsc, Aspect_w, Scan_480p, Players_2, Rating_3, โ€ฆ<value>_<attribute>.png
i #DiscType โ€” one disc glyph per kind
#System says PS1 vs PS2 and #Media says CD vs DVD, but PS1-CD and PS2-CD both report #Media=CD, so a single #Media glyph can't tell them apart. #DiscType (issue #49) collapses console + media into one token. There are no built-in #DiscType glyphs โ€” supply your own in the theme folder (PS1CD_#DiscType.png / PS2CD_#DiscType.png / PS2DVD_#DiscType.png) and give the element a contiguous mainN/infoN index (the parser stops at the first gap). FR #49 also surfaces #System/#Media on the main page, not just the info page.

8 ยท Built-in default= asset names

You can point default= or overlay= at any of OPL's embedded textures โ€” no file needed. (For a theme folder, a same-named file overrides the built-in.)

GroupNames
Covers / artcover, coverapp, disc, screen, screens (screenshot overlay), missing
Case overlayscase (shared frame, layer 1), case_overlay (layer 2, over case), apps_case (legacy apps-only frame)
Device iconsusb, mmce, hdd, eth, app, usb_bd, ilk_bd, m4s_bd, hdd_bd
BDM indicatorsIndex_0 โ€ฆ Index_4
Buttonscross, circle, triangle, square, left, right, select, start
Loading framesload0 โ€ฆ load7
Boot logologo, logo0 โ€ฆ logo6 (animated frames)
Backgroundsincebtion (default theme bg), ip
Format iconsELF, HDL, ISO, ZSO, UL
Media / consoleAPP, CD, DVD, PS1, PS2
Aspect / Scan / Vmode / Ratingthe badge sets listed in ยง7

settings_bg is theme-supplied only (no embedded default). Legacy Device_* indicators were removed in this fork โ€” use the device icons and Index_* above.

9 ยท The Coverflow element

type=Coverflow (this fork) renders the game/app list as a centred cover carousel with a reflection and slide animation. It behaves like a GameImage โ€” it uses the same COV cover cache and overlay/corner system โ€” but draws 3 or 5 covers fanned out around the selection. The first Coverflow element the parser sees flags the theme as "Coverflow active", which unlocks the live Coverflow Settings menu.

Per-theme properties (in conf_theme.cfg)

PropertyNotes
defaultFallback cover when a game's art is missing (e.g. cover, or coverapp for the apps list).
overlay + overlay_* cornersThe case art drawn around each cover (e.g. case). The corners place the cover inside the case window; the engine auto-centres the visible frame and keeps it aspect-correct in both 4:3 and 16:9.
overlay2The second case layer (e.g. case_overlay), drawn over each cover composite.
reflection1 to draw the mirrored reflection below each cover. Tune with reflection_offset.
x, y, width, heightCarousel position and per-cover size. width/height should match your case art's pixel size so the overlay corners line up; they also set the box aspect.
โš  Don't double-correct widescreen
The carousel applies the widescreen / pixel-aspect correction itself at draw time, exactly like the stock cover path. Author your covers' aspect via the element's width:height only โ€” never try to pre-stretch them. Games use a PS2-case portrait box (184ร—256); apps and PS1/VCD covers use a square box (184ร—184) to match their square art. Define a vcdMain Coverflow block to give PS1 covers their own square element; omit it and PS1 games reuse appsMain (see ยง2).

A minimal three-family Coverflow setup (the shape the fork's <Coverflow> theme uses):

main2:
    type=Coverflow
    default=cover
    reflection=1
    y=197
    width=184
    height=256        # portrait PS2 case
    overlay=case
    overlay2=case_overlay
    overlay_ulx=0    overlay_uly=0    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=256  overlay_lrx=184  overlay_lry=256
appsMain2:
    type=Coverflow
    default=coverapp
    reflection=1
    y=239
    width=184
    height=184        # square apps box
    overlay=case
    overlay2=case_overlay
    overlay_ulx=0    overlay_uly=0    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=184  overlay_lrx=184  overlay_lry=184
vcdMain2:
    type=Coverflow
    default=cover
    reflection=1
    y=239
    width=184
    height=184        # square PS1 jewel-case box
    overlay=case
    overlay2=case_overlay
    overlay_ulx=0    overlay_uly=0    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=184  overlay_lrx=184  overlay_lry=184

Global Coverflow tuning (NOT in the theme)

These live in settings_riptopl.cfg and are exposed in the Coverflow Settings menu (shown while a Coverflow theme is active). They apply to any Coverflow theme and are clamped on load:

Config keyValuesEffect
coverflow_count3 or 5Number of covers shown (anything else is forced to 3).
coverflow_scalepx (0โ€ฆ1000)How much the centre cover grows over the side covers.
coverflow_animms (0โ€ฆ5000)Slide-animation duration; 0 = instant, no animation.
coverflow_dim0 / 1Dim the non-centre covers.

The per-theme horizontal nudge coverflow_cover_offset is the one Coverflow knob that does live in the theme (a global key โ€” see ยง3). For the in-menu walkthrough of these settings, see Coverflow.

10 ยท Coordinates & scaling

Author on 640ร—480

All positions/sizes are written for a virtual 640ร—480 canvas. OPL scales that to the active video mode at draw time โ€” you never hard-code 480p vs. 1080i numbers.

Use scaled=1 for undistorted art

With scaled=1, image widths are corrected for widescreen and the PS2's non-square pixels, so a square stays square in both 4:3 and 16:9. Positions are not aspect-scaled, so layouts simply fill the wider screen naturally.

Anchor to edges, not pixels

Negative x/y anchor to the right/bottom edge; POS_MID centres; DIM_INF fills. Prefer these over magic numbers so a layout survives resolution changes.

11 ยท Worked examples

An info-page metadata label

info3:
    type=AttributeText
    attribute=Title       # the game's titleโ€ฆ
    color=#ffffff
    display=0             # 0 = always show "Title: "
    aligned=0            # anchor top-left at (x,y)
    x=33
    y=70

Switch display=2 to drop the "Title: " label and print the value alone; add wrap=1 with a width/height box for a long Description.

A framed cover with the two-layer case

main5:
    type=ItemCover         # selected game's cover, COV cache
    default=cover         # fallback when art is missing
    x=-128                # 128px in from the right edge
    y=240
    overlay=case          # layer 1: plastic case frame
    overlay2=case_overlay # layer 2: foliage/decoration, over the cover
    overlay_ulx=0    overlay_uly=0
    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=256   # cover window = full 184ร—256 of the frame
    overlay_lrx=184  overlay_lry=256

A screenshot with a bezel overlay

info14:
    type=GameImage
    pattern=SCR           # first screenshot cache
    default=screen
    x=189
    y=-150               # 150px up from the bottom
    scaled=1             # any non-zero = ratio-correct (same as 1)
    width=200
    height=150
    overlay=screens       # 1px inset bezel around the shot
    overlay_ulx=1    overlay_uly=1    overlay_urx=199  overlay_ury=1
    overlay_llx=1    overlay_lly=149  overlay_lrx=199  overlay_lry=149

12 ยท A complete, annotated sample theme

This is the shipped default <OPL> theme (misc/conf_theme_OPL.cfg), annotated. It is a full, valid conf_theme.cfg โ€” copy it into THM/thm_MyTheme/, edit, and you have a working theme. Note the contiguous numbering and the single appsMain5 override that swaps the games' portrait cover box for the apps' square one.

# โ”€โ”€ Global colours โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
bg_color=#182580          # plasma tint
sel_text_color=#ffffff    # selected list row
text_color=#324d9e        # default text
ui_text_color=#00FFFF     # menus / hints

# โ”€โ”€ Games LIST page (main*) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
main0:                    # element 0 MUST be the Background
    type=Background
    pattern=BG            # plasma background
main1:
    type=StaticImage
    default=incebtion     # embedded background art
    aligned=0
    scaled=0
    width=DIM_INF         # fill the screen
    height=DIM_INF
main2:
    type=StaticImage
    default=ip            # small corner image
    x=-132               # 132px in from the right
    y=20
    aligned=0
    width=16
    height=16
main3:
    type=MenuIcon         # current device icon
    x=0
    y=0
    aligned=0
    scaled=0
    width=DIM_INF
    height=DIM_INF
main4:
    type=ItemsList        # the scrolling game list (first ItemsList = games)
    x=30
    y=70
    aligned=0
    width=400
    height=350
main5:
    type=ItemCover        # selected cover, with the two-layer case frame
    default=cover
    x=-128
    y=240
    overlay=case          # layer 1 (plastic case)
    overlay2=case_overlay # layer 2 (over the cover)
    overlay_ulx=0    overlay_uly=0
    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=256   # portrait 184ร—256 window
    overlay_lrx=184  overlay_lry=256
appsMain5:                # APPS override of slot 5: square cover box
    type=ItemCover
    default=coverapp
    x=-128
    y=-198               # 198px up from the bottom
    overlay=case
    overlay2=case_overlay
    overlay_ulx=0    overlay_uly=0
    overlay_urx=184  overlay_ury=0
    overlay_llx=0    overlay_lly=185   # square 184ร—185 window
    overlay_lrx=184  overlay_lry=185
main6:
    type=LoadingIcon      # animated spinner (one per theme)
    x=-320
    y=-240
main7:
    type=BdmIndex         # active mass-device slot indicator
    x=7
    y=-35
    width=4
    height=32

# โ”€โ”€ Game INFO page (info*) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
info0:
    type=Background
    pattern=BG
info1:
    type=StaticImage
    default=incebtion
    aligned=0
    scaled=0
    width=DIM_INF
    height=DIM_INF
info2:
    type=StaticImage
    default=ip
    x=-132
    y=20
    aligned=0
    width=16
    height=16
info3:
    type=AttributeText    # Title:
    attribute=Title
    color=#ffffff
    display=0
    aligned=0
    x=33
    y=70
info4:
    type=AttributeText    # Developer:
    attribute=Developer
    color=#ffffff
    display=0
    aligned=0
    x=33
    y=89
info5:
    type=AttributeText    # Size: (auto-suffixed " MiB")
    attribute=#Size
    color=#ffffff
    display=0
    aligned=0
    x=33
    y=108
info6:
    type=AttributeText    # word-wrapped description box
    attribute=Description
    display=0
    color=#ffffff
    aligned=0
    x=33
    y=127
    width=590
    height=60
    wrap=1
info7:
    type=AttributeImage   # disc badge (CD/DVD/APP)
    attribute=#Media
    default=APP
    width=32
    height=16
    x=55
    y=-252
info8:
    type=AttributeImage   # format badge (ISO/ELF/โ€ฆ)
    attribute=#Format
    default=ELF
    width=32
    height=16
    x=86
    y=-252
info9:
    type=AttributeImage   # video-mode badge
    attribute=Vmode
    default=missing
    width=32
    height=16
    x=117
    y=-252
info10:
    type=AttributeImage   # aspect badge
    attribute=Aspect
    default=missing
    width=32
    height=16
    x=148
    y=-252
info11:
    type=AttributeImage   # scan-mode badge
    attribute=Scan
    default=missing
    width=32
    height=16
    x=179
    y=-252
info12:
    type=AttributeImage   # players badge
    attribute=Players
    default=missing
    width=32
    height=16
    x=210
    y=-252
info13:
    type=AttributeImage   # rating badge
    attribute=Rating
    default=no_Rating
    x=-76
    y=-252
    width=128
    height=16
info14:
    type=GameImage        # screenshot 1, with a 1px bezel overlay
    pattern=SCR
    default=screen
    x=189
    y=-150
    scaled=2              # any non-zero = ratio-correct (same as 1)
    width=200
    height=150
    overlay=screens
    overlay_ulx=1    overlay_uly=1    overlay_urx=199  overlay_ury=1
    overlay_llx=1    overlay_lly=149  overlay_lrx=199  overlay_lry=149
info15:
    type=GameImage        # screenshot 2
    pattern=SCR2
    default=screen
    x=-191
    y=-150
    width=200
    height=150
    overlay=screens
    overlay_ulx=1    overlay_uly=1    overlay_urx=199  overlay_ury=1
    overlay_llx=1    overlay_lly=149  overlay_lrx=199  overlay_lry=149

See also