Skip to content

Mewgenics (PPSA37318) 01.121.220: The game asked for a system function that is not supported yet: oB2fB… #11477

Closed

Description

@XatiX

What happens

The game asked for a system function that is not supported yet: oB2fBhW84tQ

Title, test or build step

Mewgenics (PPSA37318) 01.121.220

AnyPS5 commit

AnyPS5 toolkit anyplay-a126804, launcher 0.3.0

System

Windows 10 Pro 26H2 (build 26300.9711), NVIDIA GeForce RTX 5080 (driver 617.42 (32.0.16.1742))

Steps to reproduce

Started Mewgenics from the AnyPlay Launcher.
Settings: all at their defaults.

Log

C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceNpUniversalDataSystem.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceAgcDriver.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceVideoOut.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceKeyboard.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceAgc.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceUserService.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceSystemService.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libScePad.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceSysmodule.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceImeDialog.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceSaveData.native.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceSaveDataDialog.native.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceCommonDialog.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceMouse.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceNpManager.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceNet.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceNetCtl.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceWebBrowserDialog.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceSsl.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceHttp2.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceNpWebApi2.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceJson2.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceRtc.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceHttp.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libSceLibcInternal.prx
C:\Games\PS5\.AnyPS5\Games\PPSA37318-e397b7\libs\libc.prx
GetLastError: 127 - The specified procedure could not be found.
[anyps5-launcher] end 2026-10-26T16:21:12Z the game crashed (exception 0xC0000139 = 0xC0000139)

What was checked

No response

Activity

  1. MarcZX10 commented on Oct 26, 2026

    @MarcZX10
    Contributor

    Could you add the full resolver diagnostic that names the PRX and unresolved NID (including a few lines immediately before the GetLastError: 127 entry)? The issue gives the NID text but not which loaded library imports it, and GetLastError alone cannot distinguish which unresolved import caused the launch failure. Please also note whether the failure happens on every launch with the listed build; that will help confirm the smallest reproduction. I do not see an exact open PR or duplicate issue from the identifier/title search so far.

  2. XatiX commented on Oct 26, 2026

    @XatiX
    Author

    Sorry was trying out this anyplay toolkit auto report.

    Actual failures here -
    FAIL: unresolved ELF import oB2fBhW84tQ from libSceMouse.prx
    FAIL: unresolved ELF import stCCyzJJyM0 from libSceMouse.prx
    FAIL: unresolved ELF import If6YTBcYAbc from libSceMouse.prx

    Also happens in main commit ea42f4f

  3. MarcZX10 commented on Oct 26, 2026

    @MarcZX10
    Contributor

    Thanks, that identifies the failing library and the full import set. I checked the three NIDs with the repository’s tools/nid_names.py database and recomputed the names’ NIDs; they map exactly to sceMouseSetAbsoluteVirtualScreenSize (oB2fBhW84tQ), sceMouseSetAbsoluteHighPrecisionMode (stCCyzJJyM0) and sceMouseReadAbsolutePosition (If6YTBcYAbc). None of those names is currently present in libSceMouse, and I found no open or closed PR for them. This confirms distinct missing imports, but the NID mapping alone does not establish their argument layouts or behavior. If you can share the title’s call sites/import metadata or a reliable SDK/console reference for these three APIs, that would let a follow-up implement the correct ABI instead of guessing.

  4. MarcZX10 commented on Oct 26, 2026

    @MarcZX10
    Contributor

    Follow-up: open PR #11482 adds the three missing libSceMouse exports as import-resolution stubs and records their ABI/behavior as unknown. XatiX reports in that PR that, with the change, Mewgenics gets past import resolution but then aborts when sceMouseSetAbsoluteVirtualScreenSize is called, because the stub throws. Their disassembly notes for the call sites are in this PR comment. This addresses the unresolved-import symptom but does not yet establish or implement mouse API behavior.

  5. zaryabzip commented on Oct 29, 2026

    @zaryabzip
    Contributor

    @BunnyFl @edubox Mewgenics (PPSA37318) now resolves its imports (#11482 merged). It aborts at mouse init because sceMouseSetAbsoluteVirtualScreenSize throws. I'd like to implement the three absolute calls, but no emulator has them. Could either of you read them in libSceMouse.sprx (13.42, or the 11.00 dump)?

    From XatiX's call sites, the title calls SetAbsoluteVirtualScreenSize(handle, 3) and SetAbsoluteHighPrecisionMode(handle, 1). It then calls ReadAbsolutePosition(handle, buf, 1), reads the result as a count, and reads x/y as u16 at +0x10/+0x12.

    What I'd need for each call:

    1. Argument list. What the screen-size value selects (is 3 a resolution enum, and what are the other values?) and what high-precision mode changes (the scale of x/y?).
    2. Checks and error codes: before sceMouseInit, an unknown or closed handle, out-of-range values, a null buffer, and a count of 0 or above the limit.
    3. For ReadAbsolutePosition:
      • the record size and layout, and which fields it writes;
      • how the count relates to the request (does it return samples or 1?);
      • whether it depends on sceMouseResetAbsolutePosition, which here only validates because the host reports relative motion.

    Disassembly-only is fine. With that I can map the host pointer onto the virtual screen and get the title past mouse init.

  6. BunnyFl commented on Oct 29, 2026

    @BunnyFl
    Contributor

    @zaryabzip @edubox firmware 13.42 libSceMouse.sprx, read from the disassembly and checked with a PC run of the module (its exports called natively).

    • The driver ioctls were stubbed: open returns a handle, and the read ioctl returns samples I built from the field offsets the library reads.
    • So the checks, the state changes and the record writes below are the library's own code. The driver side was not measured: what samples a real mouse produces, how many come back per read, and what each sample field means. The field names below are my inferences.
    • Three runs gave identical output, except one logged pointer value.
    • Everything here is the single-handle path. Opening with a non-NULL param whose bit 0 is set, at SDK ≥ 0x2000000, links a second slot whose samples Read merges. I didn't follow that path.

    Error codes, with AnyPS5's MOUSE_ERROR_* names: INVALID_ARG 0x80DF0001, INVALID_HANDLE 0x80DF0003, NOT_INITIALIZED 0x80DF0005.

    1. Arguments

    sceMouseSetAbsoluteVirtualScreenSize(handle, size): size is an index.

    size virtual screen
    0 1280×720
    1 1920×1080, the value after sceMouseOpen
    2 2560×1440
    3 3840×2160

    Changing the size rescales the stored position: x × new width / old width, and the same for y, truncated. In the run, (1000, 500) at size 1 became (2000, 1000) at size 3, then (666, 333) at size 0.

    sceMouseSetAbsoluteHighPrecisionMode(handle, mode) stores the low byte of mode: 0x1234 was stored as 0x34, and 0x100 as 0, which is off. Per the disassembly, Read treats any non-zero stored value as on. The mode does not change the coordinate range; the same clamp code runs either way, per the disassembly. It changes how each motion delta moves the stored position. Each sample carries a value at +0x24 that looks like the pointer speed (s, clamped to 0–8).

    • Off: integer steps, applied to each axis separately.
      • s = 4: the delta is unchanged.
      • s = 0–3: the delta is halved, rounding toward zero, when its magnitude exceeds 1, 3, 7 and 15 respectively.
      • s = 5–6: doubled, and s = 7–8: quadrupled, when the magnitude exceeds 1 (odd s) or 0 (even s).
    • On: a curve on the vector length. The move is truncated toward zero, and the signed fraction is kept for the next read. Neither Reset nor SetSize clears that fraction.
      • At s = 4, one sample of dx (dy 0) from a zero fraction gave a total of 0.57 for dx 1 (x unchanged, 0.57 kept), 1.28 for dx 2, 10.62 for dx 10, 32.62 for dx 20 and 247.54 for dx 100.
      • s = 0 gives 0.1× and s = 8 gives 2× the s = 4 values.
      • Samples whose speed field is 1–3 or 5–7 do not move the pointer at all, because their multipliers in the module's table (at 0x47c0) are 0.
    m = sqrt(dx*dx + dy*dy)            (0 -> no move)
    v = m * 120 / 420
    f = piecewise linear in v through (0, 0) (0.4300079345703125, 1.0702667236328125)
        (1.25, 4.140625) (3.8600006103515625, 18.984375) (40, 443.75), last segment extended past 40
    scale = f * mul[s] * 96 / 120 / m,   mul = {0.1, 0, 0, 0, 1, 0, 0, 0, 2}
    t = dx * scale + remainder_x;  step = trunc(t);  remainder_x = t - step;  x = clamp(x + step)   (y the same)
    

    Per the disassembly, sceMouseSetPointerSpeed (0–8) and sceMouseSetHandType (0–1) only send ioctls 0x800C4844 and 0x800C4843 to the driver, so I infer that the speed and hand values in each sample come back from the driver. The library does not show a default speed.

    2. Checks, in the order they run

    call checks
    SetAbsoluteVirtualScreenSize NOT_INITIALIZED; size > 3 as unsigned (−1 too) → INVALID_ARG; handle → INVALID_HANDLE
    SetAbsoluteHighPrecisionMode NOT_INITIALIZED; handle; no value check
    ResetAbsolutePosition NOT_INITIALIZED; handle; x ≥ width or y ≥ height of the current size → INVALID_ARG (x and y are u16: 0x10005 becomes 5)
    ReadAbsolutePosition NOT_INITIALIZED; buffer NULL or num outside 1–64 → INVALID_ARG; handle
    • Before sceMouseInit all four return NOT_INITIALIZED, whatever the arguments.
    • An unknown handle returns INVALID_HANDLE. So does a closed one: I ran that for Reset after sceMouseClose, and the other three calls use the same lookup.
    • A bad value with a bad handle returns INVALID_ARG from SetSize and Read, but INVALID_HANDLE from Reset.

    3. ReadAbsolutePosition(handle, buf, num)

    Each record is 40 bytes:

    offset field
    +0x00 u64 copied from sample +0x00 (looks like a timestamp)
    +0x08 u8 1
    +0x09–0x0B not written
    +0x0C u32 buttons: bits 0 and 1 swapped when the sample's hand value is 1, bit 31 set when a flag byte in the sample is non-zero
    +0x10 / +0x12 u16 x / y after this sample's motion, clamped to 0..width−1 / 0..height−1
    +0x14 / +0x18 s32, each from a signed byte in the sample (per the disassembly, sceMouseRead writes the same two values at +0x18 / +0x1C)
    +0x1C–0x27 not written
    • Count: the return value is the number of records written, at most num.
      • The library takes the last num samples in the driver's order, and the motion of any earlier ones is dropped. With num 1 and three samples of dx 1, 2, 4, x moved by 4.
      • It then keeps only samples whose type byte (+0x10) is 1 and whose +0x14 bit 0 is clear. Samples it rejects are dropped along with their motion. Because the window is cut before this filter, a read can return fewer than num even when older valid samples exist.
      • Each record carries the position after its own sample. With three samples of dx 1, 2, 4 from x = 100 and num 3, the records held 101, 103 and 107.
      • The request passes num to the driver, so the library does not show whether a real driver ever returns more than num.
    • No samples:
      • If the driver's status word is 0, the call writes one zeroed record (x = y = 0, and +0x08 = 0 rather than 1) and returns 1.
      • If the status word is non-zero, it returns 0 and leaves the buffer untouched.
      • When the status word differs from the stored one, or a status-0 read with no samples cleared the stored one, the library resets its sceMouseRead-side state. That does not touch the absolute x/y, size, mode or fraction. The word looks like a connection id; that is an inference.
    • Reset: yes, Read depends on sceMouseResetAbsolutePosition.
      • Read adds each delta to the stored x/y, and Reset sets that stored x/y.
      • sceMouseOpen starts it at (0, 0), so without a Reset the pointer starts in the top-left corner.
      • On main, Reset checks a fixed 1920×1080 and stores nothing. The firmware checks the current size and stores x/y.

    AI-assisted: yes (Claude Code)

  7. XatiX commented on Oct 29, 2026

    @XatiX
    Author

    Implementation of the absolute-position exports from the 13.42 analysis above (issuecomment-6502712241). I can't open a PR at the moment, so anyone can raise it or change it: one commit on main bb04a4f1ea, XatiX/AnyPS5@a4fd1f5 (branch fix/mouse-absolute-position, diff against main).

    What it does

    • sceMouseSetAbsoluteVirtualScreenSize(handle, size): sizes 0–3 (720p, 1080p default, 1440p, 2160p), size > 3 unsigned → INVALID_ARG before the handle check, and the stored position is rescaled with truncation.
    • sceMouseSetAbsoluteHighPrecisionMode(handle, mode): stores the low byte; any non-zero value turns the mode on.
    • sceMouseResetAbsolutePosition: now stores x/y and checks them against the current size, not a fixed 1920×1080.
    • sceMouseReadAbsolutePosition(handle, buf, num): checks in the firmware order, 40-byte records (u16 x/y at +0x10/+0x12, wheel/tilt at +0x14/+0x18; +0x09–0x0B and +0x1C–0x27 left untouched), the last-num window, the no-sample cases (0 while connected, one zeroed record while disconnected), the integer speed steps and the high-precision curve with its kept fraction. sceMouseOpen resets the position to (0, 0) and the size to 1.

    Host choices (the driver side wasn't measured; listed in docs/dev/debt/libSceMouse.md)

    • Each SDL motion event is one sample, and the queue is shared with sceMouseRead.
    • When more samples are queued than num, adjacent connected samples with the same buttons share one record. Each still moves the position through the curve on its own, and the record sums their wheel and tilt.
    • The absolute path uses the host's unscaled relative counts. sceMouseRead keeps the window-to-guest delta scale.
    • Pointer speed 4 and hand type 0, since sceMouseSetPointerSpeed/sceMouseSetHandType are still stubs. The bit 31 flag and the second open slot aren't modelled.

    Tested

    • mouse_input, video_out_mouse and pad_keyboard_mouse pass. tests/Mouse.cpp uses the comment's numbers: (1000, 500) → (2000, 1000) → (666, 333), records 101/103/107, and the high-precision curve with its kept fraction (dx 1 ×2 → +1, dx 10 → 10, dx 100 → 248).
    • tools/check_conventions.py passes, and tools/pr_overlap.py finds no overlap.
    • Mewgenics (PPSA37318 01.121.220), Windows 11, physical mouse: it gets past mouse init, and the cursor moves and clicks through the menus to the first battle. An earlier version that summed one frame's samples before the curve and applied the window scale (×2.59 at 3840×2160 in a 1484-wide window) made the cursor far too fast. With per-sample motion and unscaled counts it feels right.
    • The first battle (tutorialbasic.lvl) then aborts with the AGC refusal that fix(agc): save the guest bytes of results that become pending over a surface that is no longer fully write-watched #7048 addresses ("storing storage image results pending over memory outside the write watch without the guest bytes saved before them"), unrelated to the mouse.

    AI-assisted: yes (Claude Code)

  8. zaryabzip commented on Oct 29, 2026

    @zaryabzip
    Contributor

    @BunnyFl Thank you, that covered everything. #12958 implements the three calls and a storing sceMouseResetAbsolutePosition from your run, and the curve reproduces your measured totals. @XatiX, if you can try Mewgenics on #12958 (it's stacked on #9982), that would show what the title does next. I couldn't run the title here.

  9. XatiX commented on Oct 29, 2026

    @XatiX
    Author

    11. @BunnyFl Thank you, that covered everything. #12958 implements the three calls and a storing sceMouseResetAbsolutePosition from your run, and the curve reproduces your measured totals. @XatiX, if you can try Mewgenics on #12958 (it's stacked on #9982), that would show what the title does next. I couldn't run the title here.

    Just posted own but i'll try your PR first and compare.

  10. zaryabzip commented on Oct 29, 2026

    @zaryabzip
    Contributor

    @XatiX Thanks, our versions crossed. Yours gets two things right that #12958 doesn't, and you've run the title:

    1. Each sample goes through the curve separately. feat(libSceMouse): implement the absolute position calls as firmware 13.42 does #12958 is stacked on fix(libSceMouse): sum consecutive motion into the newest unread report #9982, which merges consecutive motion reports before a read, so in high-precision mode it would apply the curve to the sum. The curve grows faster than linear, so that moves the cursor too far. That's the too-fast effect you saw.
    2. It uses the host's unscaled counts. feat(libSceMouse): implement the absolute position calls as firmware 13.42 does #12958 takes the window-scaled deltas sceMouseRead gets.

    Either way works for me:

    Which do you prefer? Until you say, I'll leave #12958 as it is.

  11. XatiX commented on Oct 29, 2026

    @XatiX
    Author

    @XatiX Thanks, our versions crossed. Yours gets two things right that #12958 doesn't, and you've run the title:

    1. Each sample goes through the curve separately. feat(libSceMouse): implement the absolute position calls as firmware 13.42 does #12958 is stacked on fix(libSceMouse): sum consecutive motion into the newest unread report #9982, which merges consecutive motion reports before a read, so in high-precision mode it would apply the curve to the sum. The curve grows faster than linear, so that moves the cursor too far. That's the too-fast effect you saw.
    2. It uses the host's unscaled counts. feat(libSceMouse): implement the absolute position calls as firmware 13.42 does #12958 takes the window-scaled deltas sceMouseRead gets.

    Either way works for me:

    Which do you prefer? Until you say, I'll leave #12958 as it is.

    Feel free to keep your PR open. I'm still waiting on my first PR to be merged and already have a followup to open after.
    If you're happy could swap to my commit as it fixes the mouse being too fast.

  12. zaryabzip commented on Oct 29, 2026

    @zaryabzip
    Contributor

    @XatiX Thanks, I'll keep #12958 and fix it along your lines, with credit in the debt entry and description:

    • The absolute path keeps its own per-event queue with the unscaled counts, so fix(libSceMouse): sum consecutive motion into the newest unread report #9982's merging no longer feeds the curve.
    • A read drains every pending sample. Same-button samples share a record when there are more than num, but each sample still moves the pointer, and the last num records are kept.
    • A test drives MouseInput at a 2× presentation scale, to show sceMouseRead gets the scaled delta while the absolute position moves by the raw count.

    It's running on Windows and WSL2 now, and goes up once it passes. Good luck with your PRs.

  13. XatiX commented on Nov 2, 2026

    @XatiX
    Author

    #12958 now merged.
    Closing issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions