VSH Menu Plugin System Architecture in webMAN MOD: XMB Integration Explained

webMAN MOD integrates with the PlayStation 3 XMB by using the plugin_GetInterface NID to obtain pointers to the XMB plugin's XMM0 and XMB2 function tables, enabling direct execution of menu actions and UI notifications.

The aldostools/webman-mod project extends the PlayStation 3's native interface by leveraging the VSH (Virtual Shell) plugin system. Understanding the VSH Menu plugin system architecture is essential for developers seeking to modify XMB behavior, inject custom menu entries, or execute commands from web interfaces.

VSH Plugin Enumeration and Identification

The PlayStation 3 VSH identifies loaded plugins through a strict enumeration defined in vsh/xmb_plugin.h. Each plugin receives a unique integer identifier used throughout the system:

// vsh/xmb_plugin.h
enum plugins {
    system_plugin = 0x00,
    xmb_plugin    = 0x01,
    explore_plugin = 0x02,

};

The XMB plugin (xmb_plugin = 0x01) serves as the primary target for webMAN MOD integration. This plugin exports multiple interface tables—specifically XMM0, XMB2, and MOD0—that expose core functionality for menu manipulation and resource loading.

Obtaining Plugin Interfaces via NID Lookup

WebMAN MOD retrieves plugin function tables through the PAF (PlayStation Application Framework) interface mechanism. The macro plugin_GetInterface resolves to NID paf_23AFB290 in vsh/paf.h:

// vsh/paf.h
#define plugin_GetInterface paf_23AFB290

The standard acquisition pattern involves locating the plugin view handle, then requesting the specific interface version:

// Locate the XMB plugin view
int view = View_Find("xmb_plugin");

// Acquire core XMB functions (XMM0 interface)
xmb_plugin_xmm0 *xmm0_interface = 
    (xmb_plugin_xmm0 *)plugin_GetInterface(view, XMM0);

// Acquire UI helpers (XMB2 interface)
xmb_plugin_xmb2 *xmb2_interface = 
    (xmb_plugin_xmb2 *)plugin_GetInterface(view, XMB2);

Source: [vsh/paf.h](https://github.com/aldostools/webman-mod/blob/master/vsh/paf.h) defines the NID macro, while [vsh/xmb_plugin.h](https://github.com/aldostools/webman-mod/blob/master/vsh/xmb_plugin.h) contains the interface structures.

The XMM0 Interface: Core XMB Operations

The XMM0 interface provides low-level control over the XMB state machine. WebMAN MOD utilizes three critical function pointers from this table:

  • ExecuteAction (index 23): Executes textual XMB actions such as "copy:dev_hdd0" or launch commands. This function accepts a const char *action string and an integer mode parameter (0 for normal XMB, 1 for in-game XMB).
  • LoadPlugin3 (index 70): Loads a plugin by its enum ID (e.g., xmb_plugin) with signature LoadPlugin3(int id, void *arg, int mode).
  • ActivatePlugin (index 75): Activates a loaded plugin instance, required for transitioning between normal and in-game XMB contexts.

These functions enable webMAN MOD to trigger any XMB-compatible operation programmatically, including mounting games and navigating categories.

The XMB2 Interface: UI Notifications and Resources

While XMM0 handles state management, the XMB2 interface manages visual feedback and resource registration:

  • showMsg(const wchar_t *msg): Displays temporary bottom-screen notifications (e.g., "WebMAN MOD: Game mounted").
  • DoUnk28(const char *cmd): Parses low-level XMBML action strings for custom menu behaviors.
  • DoUnk30(void *cb, int *param): Registers callbacks for custom render plugins, used for overlays like video recording indicators.

Source: The complete structure definitions appear in [vsh/xmb_plugin.h](https://github.com/aldostools/webman-mod/blob/master/vsh/xmb_plugin.h).

Executing Web Commands Through the XMB Plugin

When webMAN MOD receives an HTTP command such as http://<ps3>/copy:dev_hdd0, the request flows through the VSH main interface function vshmain_AE35CF2D, declared in vsh/vshmain.h:

// vsh/vshmain.h
extern int32_t vshmain_AE35CF2D(char *, int);   // call_xmb_plugin

This dispatcher forwards the command to the XMB plugin's ExecuteAction method. The implementation pattern in include/init/html.h follows this sequence:

  1. Parse the URL into a command string (e.g., "copy:dev_hdd0").
  2. Determine the execution mode (0 for XMB, 1 for in-game).
  3. Invoke vshmain_AE35CF2D((char*)url, mode) to execute via XMM0.

Additionally, main.c initializes the plugin system by mapping required resources:

// main.c
map_vsh_resource(8, MAP_SELECTED, html_base_path, false);   // Maps xmb_plugin_normal.rco

Practical Implementation: Custom Menu Entries

The following pattern demonstrates how webMAN MOD adds custom entries and displays confirmation messages:

// 1. Acquire XMB2 interface for UI feedback
int view = View_Find("xmb_plugin");
xmb_plugin_xmb2 *xmb2 = 
    (xmb_plugin_xmb2 *)plugin_GetInterface(view, XMB2);

// 2. Display notification
xmb2->showMsg(L"WebMAN MOD: Custom entry added");

// 3. Map custom resource file
map_vsh_resource(8, MAP_SELECTED, 
                 "/dev_hdd0/xmlhost/custom.rco", false);

This sequence combines interface acquisition, user notification, and resource mapping—the three pillars of VSH Menu integration.

Key Source Files Reference

File Purpose
vsh/xmb_plugin.h Plugin enumeration and XMM0/XMB2 interface definitions
vsh/paf.h plugin_GetInterface NID macro (paf_23AFB290)
vsh/vshmain.h vshmain_AE35CF2D declaration for action dispatch
main.c Initial resource mapping and plugin initialization
include/feat/pkg_handler.h XMM0 interface usage examples
include/init/vsh.h Boilerplate for additional plugin interfaces

Summary

  • webMAN MOD extends the PS3 XMB by interfacing with the built-in xmb_plugin (ID 0x01) through the VSH plugin architecture.
  • Interface acquisition relies on plugin_GetInterface (NID paf_23AFB290) to retrieve XMM0 and XMB2 function tables.
  • XMM0 provides ExecuteAction, LoadPlugin3, and ActivatePlugin for core menu manipulation.
  • XMB2 offers showMsg and resource callbacks for UI notifications.
  • Command execution flows through vshmain_AE35CF2D, bridging HTTP requests to XMB actions.
  • Resource mapping via map_vsh_resource in main.c attaches custom RCO files to the plugin system.

Frequently Asked Questions

What is the XMM0 interface in webMAN MOD?

The XMM0 interface is a function table exported by the XMB plugin that provides core menu operations. According to the source code in vsh/xmb_plugin.h, it includes ExecuteAction (index 23) for running XMB commands, LoadPlugin3 (index 70) for loading plugins by ID, and ActivatePlugin (index 75) for switching between XMB contexts. WebMAN MOD obtains this interface via plugin_GetInterface to programmatically control the Cross-Media Bar.

How does webMAN MOD display notifications in the XMB?

WebMAN MOD displays notifications by obtaining the XMB2 interface and invoking the showMsg function. This interface method accepts a const wchar_t* string and renders a temporary message at the bottom of the screen. The implementation typically follows the pattern of calling View_Find("xmb_plugin"), retrieving the XMB2 interface pointer, and executing xmb2->showMsg(L"WebMAN MOD: Status message").

What role does vshmain_AE35CF2D play in the plugin architecture?

The function vshmain_AE35CF2D, declared in vsh/vshmain.h, serves as the dispatcher that forwards commands to the XMB plugin's ExecuteAction method. When webMAN MOD receives web commands via HTTP, it invokes this function with the command string and mode parameter (0 for normal XMB, 1 for in-game XMB). This allows remote commands to trigger native XMB actions without direct user interaction with the controller.

How are VSH plugins identified in the system?

VSH plugins are identified by integer constants defined in the plugins enumeration within vsh/xmb_plugin.h. The XMB plugin holds ID 0x01, while system_plugin is 0x00 and explore_plugin is 0x02. webMAN MOD uses these identifiers with LoadPlugin3 and ActivatePlugin to ensure the correct plugin modules are loaded and active before attempting to retrieve their exported interfaces.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →