Merge remote-tracking branch 'upstream/main' into quasifs

This commit is contained in:
Marek Ledworowski 2025-11-05 23:05:30 +01:00
commit e02fa1475c
28 changed files with 2489 additions and 84 deletions

View File

@ -461,6 +461,12 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/mouse/mouse.h
src/core/libraries/web_browser_dialog/webbrowserdialog.cpp
src/core/libraries/web_browser_dialog/webbrowserdialog.h
src/core/libraries/font/font.cpp
src/core/libraries/font/font.h
src/core/libraries/font/fontft.cpp
src/core/libraries/font/fontft.h
src/core/libraries/font/font_error.h
)
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h

View File

@ -40,28 +40,30 @@ namespace {
switch (mode) {
case FileAccessMode::Read:
return L"rb";
case FileAccessMode::Write:
return L"wb";
case FileAccessMode::Append:
return L"ab";
case FileAccessMode::Write:
case FileAccessMode::ReadWrite:
return L"r+b";
case FileAccessMode::ReadAppend:
return L"a+b";
case FileAccessMode::Create:
return L"wb";
}
break;
case FileType::TextFile:
switch (mode) {
case FileAccessMode::Read:
return L"r";
case FileAccessMode::Write:
return L"w";
case FileAccessMode::Append:
return L"a";
case FileAccessMode::Write:
case FileAccessMode::ReadWrite:
return L"r+";
case FileAccessMode::ReadAppend:
return L"a+";
case FileAccessMode::Create:
return L"w";
}
break;
}
@ -91,28 +93,30 @@ namespace {
switch (mode) {
case FileAccessMode::Read:
return "rb";
case FileAccessMode::Write:
return "wb";
case FileAccessMode::Append:
return "ab";
case FileAccessMode::Write:
case FileAccessMode::ReadWrite:
return "r+b";
case FileAccessMode::ReadAppend:
return "a+b";
case FileAccessMode::Create:
return "wb";
}
break;
case FileType::TextFile:
switch (mode) {
case FileAccessMode::Read:
return "r";
case FileAccessMode::Write:
return "w";
case FileAccessMode::Append:
return "a";
case FileAccessMode::Write:
case FileAccessMode::ReadWrite:
return "r+";
case FileAccessMode::ReadAppend:
return "a+";
case FileAccessMode::Create:
return "w";
}
break;
}

View File

@ -21,9 +21,8 @@ enum class FileAccessMode {
*/
Read = 1 << 0,
/**
* If the file at path exists, the existing contents of the file are erased.
* The empty file is then opened for writing.
* If the file at path does not exist, it creates and opens a new empty file for writing.
* If the file at path exists, it opens the file for writing.
* If the file at path does not exist, it fails to open the file.
*/
Write = 1 << 1,
/**
@ -42,6 +41,12 @@ enum class FileAccessMode {
* reading and appending.
*/
ReadAppend = Read | Append,
/**
* If the file at path exists, the existing contents of the file are erased.
* The empty file is then opened for writing.
* If the file at path does not exist, it creates and opens a new empty file for writing.
*/
Create = 1 << 3,
};
DECLARE_ENUM_FLAG_OPERATORS(FileAccessMode);
@ -102,6 +107,11 @@ public:
return file != nullptr;
}
bool IsWriteOnly() const {
return file_access_mode == FileAccessMode::Append ||
file_access_mode == FileAccessMode::Write;
}
uintptr_t GetFileMapping();
int Open(const std::filesystem::path& path, FileAccessMode mode,
@ -209,7 +219,7 @@ public:
}
static size_t WriteBytes(const std::filesystem::path path, const auto& data) {
IOFile out(path, FileAccessMode::Write);
IOFile out(path, FileAccessMode::Create);
return out.Write(data);
}
std::FILE* file = nullptr;

View File

@ -62,7 +62,7 @@ private:
class FileBackend {
public:
explicit FileBackend(const std::filesystem::path& filename, bool should_append = false)
: file{filename, should_append ? FS::FileAccessMode::Append : FS::FileAccessMode::Write,
: file{filename, should_append ? FS::FileAccessMode::Append : FS::FileAccessMode::Create,
FS::FileType::TextFile} {}
~FileBackend() = default;

View File

@ -140,6 +140,8 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, NpParty) \
SUB(Lib, Zlib) \
SUB(Lib, Hmd) \
SUB(Lib, Font) \
SUB(Lib, FontFt) \
SUB(Lib, HmdSetupDialog) \
SUB(Lib, SigninDialog) \
SUB(Lib, Camera) \

View File

@ -114,6 +114,8 @@ enum class Class : u8 {
Lib_CompanionHttpd, ///< The LibCompanionHttpd implementation.
Lib_CompanionUtil, ///< The LibCompanionUtil implementation.
Lib_VrTracker, ///< The LibSceVrTracker implementation.
Lib_Font, ///< The libSceFont implementation.
Lib_FontFt, ///< The libSceFontFt implementation.
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend

View File

@ -152,7 +152,7 @@ inline std::string RunDisassembler(const std::string& disassembler_cli, const T&
}
} else {
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Create);
file.Write(shader_code);
file.Close();

View File

@ -123,7 +123,7 @@ void FrameDumpViewer::Draw() {
const auto fname = fmt::format("{:%F %H-%M-%S} {}_{}_{}.bin", now_time,
magic_enum::enum_name(selected_queue_type),
selected_submit_num, selected_queue_num2);
Common::FS::IOFile file(fname, Common::FS::FileAccessMode::Write);
Common::FS::IOFile file(fname, Common::FS::FileAccessMode::Create);
const auto& data = frame_dump->queues[selected_cmd].data;
if (file.IsOpen()) {
DebugState.ShowDebugMessage(fmt::format("Dumping cmd as {}", fname));

View File

@ -99,7 +99,7 @@ bool PSF::Open(const std::vector<u8>& psf_buffer) {
}
bool PSF::Encode(const std::filesystem::path& filepath) const {
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Write);
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Create);
if (!file.IsOpen()) {
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Font {
struct OrbisFontTextCharacter {
// Other fields...
struct OrbisFontTextCharacter* next; // Pointer to the next node 0x00
struct OrbisFontTextCharacter* prev; // Pointer to the next node 0x08
void* textOrder; // Field at offset 0x10 (pointer to text order info)
u32 characterCode; // Field assumed at offset 0x28
u8 unkn_0x31; // Offset 0x31
u8 unkn_0x33; // Offset 0x33
u8 charType; // Field assumed at offset 0x39
u8 bidiLevel; // Field assumed at offset 0x3B stores the Bidi level
u8 formatFlags; // Field at offset 0x3D (stores format-related flags)
};
struct OrbisFontRenderSurface {
void* buffer;
s32 widthByte;
s8 pixelSizeByte;
u8 unkn_0xd;
u8 styleFlag;
u8 unkn_0xf;
s32 width, height;
u32 sc_x0;
u32 sc_y0;
u32 sc_x1;
u32 sc_y1;
void* unkn_28[3];
};
struct OrbisFontStyleFrame {
/*0x00*/ u16 magic; // Expected to be 0xF09
/*0x02*/ u16 flags;
/*0x04*/ s32 dpiX; // DPI scaling factor for width
/*0x08*/ s32 dpiY; // DPI scaling factor for height
/*0x0c*/ s32 scalingFlag; // Indicates whether scaling is enabled
/*0x10*/
/*0x14*/ float scaleWidth; // Width scaling factor
/*0x18*/ float scaleHeight; // Height scaling factor
/*0x1c*/ float weightXScale;
/*0x20*/ float weightYScale;
/*0x24*/ float slantRatio;
};
s32 PS4_SYSV_ABI sceFontAttachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontBindRenderer();
s32 PS4_SYSV_ABI sceFontCharacterGetBidiLevel(OrbisFontTextCharacter* textCharacter,
int* bidiLevel);
s32 PS4_SYSV_ABI sceFontCharacterGetSyllableStringState();
s32 PS4_SYSV_ABI sceFontCharacterGetTextFontCode();
s32 PS4_SYSV_ABI sceFontCharacterGetTextOrder(OrbisFontTextCharacter* textCharacter,
void** pTextOrder);
u32 PS4_SYSV_ABI sceFontCharacterLooksFormatCharacters(OrbisFontTextCharacter* textCharacter);
u32 PS4_SYSV_ABI sceFontCharacterLooksWhiteSpace(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextBack(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextNext(OrbisFontTextCharacter* textCharacter);
s32 PS4_SYSV_ABI sceFontCharactersRefersTextCodes();
s32 PS4_SYSV_ABI sceFontClearDeviceCache();
s32 PS4_SYSV_ABI sceFontCloseFont();
s32 PS4_SYSV_ABI sceFontControl();
s32 PS4_SYSV_ABI sceFontCreateGraphicsDevice();
s32 PS4_SYSV_ABI sceFontCreateGraphicsService();
s32 PS4_SYSV_ABI sceFontCreateGraphicsServiceWithEdition();
s32 PS4_SYSV_ABI sceFontCreateLibrary();
s32 PS4_SYSV_ABI sceFontCreateLibraryWithEdition();
s32 PS4_SYSV_ABI sceFontCreateRenderer();
s32 PS4_SYSV_ABI sceFontCreateRendererWithEdition();
s32 PS4_SYSV_ABI sceFontCreateString();
s32 PS4_SYSV_ABI sceFontCreateWords();
s32 PS4_SYSV_ABI sceFontCreateWritingLine();
s32 PS4_SYSV_ABI sceFontDefineAttribute();
s32 PS4_SYSV_ABI sceFontDeleteGlyph();
s32 PS4_SYSV_ABI sceFontDestroyGraphicsDevice();
s32 PS4_SYSV_ABI sceFontDestroyGraphicsService();
s32 PS4_SYSV_ABI sceFontDestroyLibrary();
s32 PS4_SYSV_ABI sceFontDestroyRenderer();
s32 PS4_SYSV_ABI sceFontDestroyString();
s32 PS4_SYSV_ABI sceFontDestroyWords();
s32 PS4_SYSV_ABI sceFontDestroyWritingLine();
s32 PS4_SYSV_ABI sceFontDettachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontGenerateCharGlyph();
s32 PS4_SYSV_ABI sceFontGetAttribute();
s32 PS4_SYSV_ABI sceFontGetCharGlyphCode();
s32 PS4_SYSV_ABI sceFontGetCharGlyphMetrics();
s32 PS4_SYSV_ABI sceFontGetEffectSlant();
s32 PS4_SYSV_ABI sceFontGetEffectWeight();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsCount();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsOutlineProfile();
s32 PS4_SYSV_ABI sceFontGetFontMetrics();
s32 PS4_SYSV_ABI sceFontGetFontResolution();
s32 PS4_SYSV_ABI sceFontGetFontStyleInformation();
s32 PS4_SYSV_ABI sceFontGetGlyphExpandBufferState();
s32 PS4_SYSV_ABI sceFontGetHorizontalLayout();
s32 PS4_SYSV_ABI sceFontGetKerning();
s32 PS4_SYSV_ABI sceFontGetLibrary();
s32 PS4_SYSV_ABI sceFontGetPixelResolution();
s32 PS4_SYSV_ABI sceFontGetRenderCharGlyphMetrics();
s32 PS4_SYSV_ABI sceFontGetRenderEffectSlant();
s32 PS4_SYSV_ABI sceFontGetRenderEffectWeight();
s32 PS4_SYSV_ABI sceFontGetRenderScaledKerning();
s32 PS4_SYSV_ABI sceFontGetRenderScalePixel();
s32 PS4_SYSV_ABI sceFontGetRenderScalePoint();
s32 PS4_SYSV_ABI sceFontGetResolutionDpi();
s32 PS4_SYSV_ABI sceFontGetScalePixel();
s32 PS4_SYSV_ABI sceFontGetScalePoint();
s32 PS4_SYSV_ABI sceFontGetScriptLanguage();
s32 PS4_SYSV_ABI sceFontGetTypographicDesign();
s32 PS4_SYSV_ABI sceFontGetVerticalLayout();
s32 PS4_SYSV_ABI sceFontGlyphDefineAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetGlyphForm();
s32 PS4_SYSV_ABI sceFontGlyphGetMetricsForm();
s32 PS4_SYSV_ABI sceFontGlyphGetScalePixel();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetrics();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalAdvance();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalX();
s32 PS4_SYSV_ABI sceFontGlyphRefersOutline();
s32 PS4_SYSV_ABI sceFontGlyphRenderImage();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageVertical();
s32 PS4_SYSV_ABI sceFontGraphicsBeginFrame();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingCancel();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingFinish();
s32 PS4_SYSV_ABI sceFontGraphicsEndFrame();
s32 PS4_SYSV_ABI sceFontGraphicsExchangeResource();
s32 PS4_SYSV_ABI sceFontGraphicsFillMethodInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetFillEffect();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsGetDeviceUsage();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInit();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitCircular();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitRoundish();
s32 PS4_SYSV_ABI sceFontGraphicsRelease();
s32 PS4_SYSV_ABI sceFontGraphicsRenderResource();
s32 PS4_SYSV_ABI sceFontGraphicsSetFramePolicy();
s32 PS4_SYSV_ABI sceFontGraphicsSetupClipping();
s32 PS4_SYSV_ABI sceFontGraphicsSetupColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsSetupHandleDefault();
s32 PS4_SYSV_ABI sceFontGraphicsSetupLocation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupPositioning();
s32 PS4_SYSV_ABI sceFontGraphicsSetupRotation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupScaling();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvas();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvasSequence();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesign();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesignResource();
s32 PS4_SYSV_ABI sceFontGraphicsStructureSurfaceTexture();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateClipping();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateLocation();
s32 PS4_SYSV_ABI sceFontGraphicsUpdatePositioning();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateRotation();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateScaling();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateShapeFill();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateShapeFillPlot();
s32 PS4_SYSV_ABI sceFontMemoryInit();
s32 PS4_SYSV_ABI sceFontMemoryTerm();
s32 PS4_SYSV_ABI sceFontOpenFontFile();
s32 PS4_SYSV_ABI sceFontOpenFontInstance();
s32 PS4_SYSV_ABI sceFontOpenFontMemory();
s32 PS4_SYSV_ABI sceFontOpenFontSet();
s32 PS4_SYSV_ABI sceFontRebindRenderer();
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImage();
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImageHorizontal();
s32 PS4_SYSV_ABI sceFontRenderCharGlyphImageVertical();
s32 PS4_SYSV_ABI sceFontRendererGetOutlineBufferSize();
s32 PS4_SYSV_ABI sceFontRendererResetOutlineBuffer();
s32 PS4_SYSV_ABI sceFontRendererSetOutlineBufferPolicy();
void PS4_SYSV_ABI sceFontRenderSurfaceInit(OrbisFontRenderSurface* renderSurface, void* buffer,
int bufWidthByte, int pixelSizeByte, int widthPixel,
int heightPixel);
void PS4_SYSV_ABI sceFontRenderSurfaceSetScissor(OrbisFontRenderSurface* renderSurface, int x0,
int y0, int w, int h);
s32 PS4_SYSV_ABI sceFontRenderSurfaceSetStyleFrame(OrbisFontRenderSurface* renderSurface,
OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontSetEffectSlant();
s32 PS4_SYSV_ABI sceFontSetEffectWeight();
s32 PS4_SYSV_ABI sceFontSetFontsOpenMode();
s32 PS4_SYSV_ABI sceFontSetResolutionDpi();
s32 PS4_SYSV_ABI sceFontSetScalePixel();
s32 PS4_SYSV_ABI sceFontSetScalePoint();
s32 PS4_SYSV_ABI sceFontSetScriptLanguage();
s32 PS4_SYSV_ABI sceFontSetTypographicDesign();
s32 PS4_SYSV_ABI sceFontSetupRenderEffectSlant();
s32 PS4_SYSV_ABI sceFontSetupRenderEffectWeight();
s32 PS4_SYSV_ABI sceFontSetupRenderScalePixel();
s32 PS4_SYSV_ABI sceFontSetupRenderScalePoint();
s32 PS4_SYSV_ABI sceFontStringGetTerminateCode();
s32 PS4_SYSV_ABI sceFontStringGetTerminateOrder();
s32 PS4_SYSV_ABI sceFontStringGetWritingForm();
s32 PS4_SYSV_ABI sceFontStringRefersRenderCharacters();
s32 PS4_SYSV_ABI sceFontStringRefersTextCharacters();
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectSlant(OrbisFontStyleFrame* styleFrame,
float* slantRatio);
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectWeight(OrbisFontStyleFrame* fontStyleFrame,
float* weightXScale, float* weightYScale,
uint32_t* mode);
s32 PS4_SYSV_ABI sceFontStyleFrameGetResolutionDpi();
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePixel(OrbisFontStyleFrame* styleFrame, float* w,
float* h);
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePoint();
s32 PS4_SYSV_ABI sceFontStyleFrameInit();
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectSlant();
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectWeight();
s32 PS4_SYSV_ABI sceFontStyleFrameSetResolutionDpi();
s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePixel();
s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePoint();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectSlant();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectWeight();
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetScale();
s32 PS4_SYSV_ABI sceFontSupportExternalFonts();
s32 PS4_SYSV_ABI sceFontSupportGlyphs();
s32 PS4_SYSV_ABI sceFontSupportSystemFonts();
s32 PS4_SYSV_ABI sceFontTextCodesStepBack();
s32 PS4_SYSV_ABI sceFontTextCodesStepNext();
s32 PS4_SYSV_ABI sceFontTextSourceInit();
s32 PS4_SYSV_ABI sceFontTextSourceRewind();
s32 PS4_SYSV_ABI sceFontTextSourceSetDefaultFont();
s32 PS4_SYSV_ABI sceFontTextSourceSetWritingForm();
s32 PS4_SYSV_ABI sceFontUnbindRenderer();
s32 PS4_SYSV_ABI sceFontWordsFindWordCharacters();
s32 PS4_SYSV_ABI sceFontWritingGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingInit();
s32 PS4_SYSV_ABI sceFontWritingLineClear();
s32 PS4_SYSV_ABI sceFontWritingLineGetOrderingSpace();
s32 PS4_SYSV_ABI sceFontWritingLineGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingLineRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingLineWritesOrder();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStepCharacter();
s32 PS4_SYSV_ABI sceFontWritingSetMaskInvisible();
s32 PS4_SYSV_ABI Func_00F4D778F1C88CB3();
s32 PS4_SYSV_ABI Func_03C650025FBB0DE7();
s32 PS4_SYSV_ABI Func_07EAB8A163B27E1A();
s32 PS4_SYSV_ABI Func_09408E88E4F97CE3();
s32 PS4_SYSV_ABI Func_09F92905ED82A814();
s32 PS4_SYSV_ABI Func_0D142CEE1AB21ABE();
s32 PS4_SYSV_ABI Func_14BD2E9E119C16F2();
s32 PS4_SYSV_ABI Func_1AC53C9EDEAE8D75();
s32 PS4_SYSV_ABI Func_1D401185D5E24C3D();
s32 PS4_SYSV_ABI Func_1E83CD20C2CC996F();
s32 PS4_SYSV_ABI Func_314B1F765B9FE78A();
s32 PS4_SYSV_ABI Func_350E6725FEDE29E1();
s32 PS4_SYSV_ABI Func_3DB773F0A604BF39();
s32 PS4_SYSV_ABI Func_4FF49DD21E311B1C();
s32 PS4_SYSV_ABI Func_526287664A493981();
s32 PS4_SYSV_ABI Func_55CA718DBC84A6E9();
s32 PS4_SYSV_ABI Func_563FC5F0706A8B4D();
s32 PS4_SYSV_ABI Func_569E2ECD34290F45();
s32 PS4_SYSV_ABI Func_5A04775B6BE47685();
s32 PS4_SYSV_ABI Func_5FD93BCAB6F79750();
s32 PS4_SYSV_ABI Func_62B5398F864BD3B4();
s32 PS4_SYSV_ABI Func_6F9010294D822367();
s32 PS4_SYSV_ABI Func_7757E947423A7A67();
s32 PS4_SYSV_ABI Func_7E06BA52077F54FA();
s32 PS4_SYSV_ABI Func_93B36DEA021311D6();
s32 PS4_SYSV_ABI Func_94B0891E7111598A();
s32 PS4_SYSV_ABI Func_9785C9128C2FE7CD();
s32 PS4_SYSV_ABI Func_97DFBC9B65FBC0E1();
s32 PS4_SYSV_ABI Func_ACD9717405D7D3CA();
s32 PS4_SYSV_ABI Func_B19A8AEC3FD4F16F();
s32 PS4_SYSV_ABI Func_C10F488AD7CF103D();
s32 PS4_SYSV_ABI Func_D0C8B5FF4A6826C7();
s32 PS4_SYSV_ABI Func_E48D3CD01C342A33();
s32 PS4_SYSV_ABI Func_EAC96B2186B71E14();
s32 PS4_SYSV_ABI Func_FE4788A96EF46256();
s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5();
void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Font

View File

@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/libraries/error_codes.h"
constexpr int ORBIS_FONT_ERROR_FATAL = 0x80460001;
constexpr int ORBIS_FONT_ERROR_INVALID_PARAMETER = 0x80460002;
constexpr int ORBIS_FONT_ERROR_INVALID_MEMORY = 0x80460003;
constexpr int ORBIS_FONT_ERROR_INVALID_LIBRARY = 0x80460004;
constexpr int ORBIS_FONT_ERROR_INVALID_FONT_HANDLE = 0x80460005;
constexpr int ORBIS_FONT_ERROR_INVALID_GLYPH = 0x80460006;
constexpr int ORBIS_FONT_ERROR_INVALID_RENDERER = 0x80460007;
constexpr int ORBIS_FONT_ERROR_INVALID_TEXT_SOURCE = 0x80460008;
constexpr int ORBIS_FONT_ERROR_INVALID_STRING = 0x80460009;
constexpr int ORBIS_FONT_ERROR_INVALID_WRITING = 0x8046000A;
constexpr int ORBIS_FONT_ERROR_INVALID_WORDS = 0x8046000B;
constexpr int ORBIS_FONT_ERROR_ALLOCATION_FAILED = 0x80460010;
constexpr int ORBIS_FONT_ERROR_FS_OPEN_FAILED = 0x80460011;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_LIBRARY = 0x80460018;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_FORMAT = 0x80460019;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_FUNCTION = 0x80460020;
constexpr int ORBIS_FONT_ERROR_ALREADY_SPECIFIED = 0x80460021;
constexpr int ORBIS_FONT_ERROR_ALREADY_ATTACHED = 0x80460022;
constexpr int ORBIS_FONT_ERROR_ALREADY_OPENED = 0x80460023;
constexpr int ORBIS_FONT_ERROR_NOT_ATTACHED_CACHE_BUFFER = 0x80460025;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_FONTSET = 0x80460031;
constexpr int ORBIS_FONT_ERROR_FONT_OPEN_MAX = 0x80460033;
constexpr int ORBIS_FONT_ERROR_FONT_OPEN_FAILED = 0x80460036;
constexpr int ORBIS_FONT_ERROR_FONT_CLOSE_FAILED = 0x80460037;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_TYPOGRAPHY = 0x80460040;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_CODE = 0x80460041;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_GLYPH = 0x80460042;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_SCRIPT = 0x80460043;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_LANGUAGE = 0x80460044;
constexpr int ORBIS_FONT_ERROR_NO_SUPPORT_SURFACE = 0x80460050;
constexpr int ORBIS_FONT_ERROR_UNSET_PARAMETER = 0x80460058;
constexpr int ORBIS_FONT_ERROR_FUNCTIONAL_LIMIT = 0x8046005C;
constexpr int ORBIS_FONT_ERROR_ALREADY_BOUND_RENDERER = 0x80460060;
constexpr int ORBIS_FONT_ERROR_NOT_BOUND_RENDERER = 0x80460061;
constexpr int ORBIS_FONT_ERROR_RENDERER_ALLOCATION_FAILED = 0x80460063;
constexpr int ORBIS_FONT_ERROR_RENDERER_ALLOCATION_LIMITED = 0x80460064;
constexpr int ORBIS_FONT_ERROR_RENDERER_RENDER_FAILED = 0x80460065;

View File

@ -0,0 +1,140 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/font/fontft.h"
#include "core/libraries/libs.h"
namespace Libraries::FontFt {
s32 PS4_SYSV_ABI sceFontFtInitAliases() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSetAliasFont() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSetAliasPath() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportBdf() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportCid() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportFontFormats() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportOpenType() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportOpenTypeOtf() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportOpenTypeTtf() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportPcf() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportPfr() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportSystemFonts() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportTrueType() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportTrueTypeGx() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportType1() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportType42() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtSupportWinFonts() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontFtTermAliases() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontSelectGlyphsFt() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontSelectLibraryFt() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontSelectRendererFt() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("e60aorDdpB8", "libSceFontFt", 1, "libSceFontFt", sceFontFtInitAliases);
LIB_FUNCTION("BxcmiMc3UaA", "libSceFontFt", 1, "libSceFontFt", sceFontFtSetAliasFont);
LIB_FUNCTION("MEWjebIzDEI", "libSceFontFt", 1, "libSceFontFt", sceFontFtSetAliasPath);
LIB_FUNCTION("ZcQL0iSjvFw", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportBdf);
LIB_FUNCTION("LADHEyFTxRQ", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportCid);
LIB_FUNCTION("+jqQjsancTs", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportFontFormats);
LIB_FUNCTION("oakL15-mBtc", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportOpenType);
LIB_FUNCTION("dcQeaDr8UJc", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportOpenTypeOtf);
LIB_FUNCTION("2KXS-HkZT3c", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportOpenTypeTtf);
LIB_FUNCTION("H0mJnhKwV-s", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportPcf);
LIB_FUNCTION("S2mw3sYplAI", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportPfr);
LIB_FUNCTION("+ehNXJPUyhk", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportSystemFonts);
LIB_FUNCTION("4BAhDLdrzUI", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportTrueType);
LIB_FUNCTION("Utlzbdf+g9o", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportTrueTypeGx);
LIB_FUNCTION("nAfQ6qaL1fU", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportType1);
LIB_FUNCTION("X9+pzrGtBus", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportType42);
LIB_FUNCTION("w0hI3xsK-hc", "libSceFontFt", 1, "libSceFontFt", sceFontFtSupportWinFonts);
LIB_FUNCTION("w5sfH9r8ZJ4", "libSceFontFt", 1, "libSceFontFt", sceFontFtTermAliases);
LIB_FUNCTION("ojW+VKl4Ehs", "libSceFontFt", 1, "libSceFontFt", sceFontSelectGlyphsFt);
LIB_FUNCTION("oM+XCzVG3oM", "libSceFontFt", 1, "libSceFontFt", sceFontSelectLibraryFt);
LIB_FUNCTION("Xx974EW-QFY", "libSceFontFt", 1, "libSceFontFt", sceFontSelectRendererFt);
};
} // namespace Libraries::FontFt

View File

@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::FontFt {
s32 PS4_SYSV_ABI sceFontFtInitAliases();
s32 PS4_SYSV_ABI sceFontFtSetAliasFont();
s32 PS4_SYSV_ABI sceFontFtSetAliasPath();
s32 PS4_SYSV_ABI sceFontFtSupportBdf();
s32 PS4_SYSV_ABI sceFontFtSupportCid();
s32 PS4_SYSV_ABI sceFontFtSupportFontFormats();
s32 PS4_SYSV_ABI sceFontFtSupportOpenType();
s32 PS4_SYSV_ABI sceFontFtSupportOpenTypeOtf();
s32 PS4_SYSV_ABI sceFontFtSupportOpenTypeTtf();
s32 PS4_SYSV_ABI sceFontFtSupportPcf();
s32 PS4_SYSV_ABI sceFontFtSupportPfr();
s32 PS4_SYSV_ABI sceFontFtSupportSystemFonts();
s32 PS4_SYSV_ABI sceFontFtSupportTrueType();
s32 PS4_SYSV_ABI sceFontFtSupportTrueTypeGx();
s32 PS4_SYSV_ABI sceFontFtSupportType1();
s32 PS4_SYSV_ABI sceFontFtSupportType42();
s32 PS4_SYSV_ABI sceFontFtSupportWinFonts();
s32 PS4_SYSV_ABI sceFontFtTermAliases();
s32 PS4_SYSV_ABI sceFontSelectGlyphsFt();
s32 PS4_SYSV_ABI sceFontSelectLibraryFt();
s32 PS4_SYSV_ABI sceFontSelectRendererFt();
void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::FontFt

View File

@ -465,11 +465,7 @@ s32 PS4_SYSV_ABI posix_rename(const char* from, const char* to) {
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto file = h->GetFile(src_path);
if (file) {
// We need to force ReadWrite if the file had Write access before
// Otherwise f.Open will clear the file contents.
auto access_mode = file->f.GetAccessMode() == Common::FS::FileAccessMode::Write
? Common::FS::FileAccessMode::ReadWrite
: file->f.GetAccessMode();
auto access_mode = file->f.GetAccessMode();
file->f.Close();
std::filesystem::remove(src_path);
file->f.Open(dst_path, access_mode);

View File

@ -9,6 +9,35 @@
namespace Libraries::Http {
static bool g_isHttpInitialized = true; // TODO temp always inited
void NormalizeAndAppendPath(char* dest, char* src) {
char* lastSlash;
u64 length;
lastSlash = strrchr(dest, '/');
if (lastSlash == NULL) {
length = strlen(dest);
dest[length] = '/';
dest[length + 1] = '\0';
} else {
lastSlash[1] = '\0';
}
if (*src == '/') {
dest[0] = '\0';
}
length = strnlen(dest, 0x3fff);
strncat(dest, src, 0x3fff - length);
return;
}
int HttpRequestInternal_Acquire(HttpRequestInternal** outRequest, u32 requestId) {
return 0; // TODO dummy
}
int HttpRequestInternal_Release(HttpRequestInternal* request) {
return 0; // TODO dummy
}
int PS4_SYSV_ABI sceHttpAbortRequest() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
@ -34,8 +63,9 @@ int PS4_SYSV_ABI sceHttpAddQuery() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpAddRequestHeader() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
int PS4_SYSV_ABI sceHttpAddRequestHeader(int id, const char* name, const char* value, s32 mode) {
LOG_ERROR(Lib_Http, "(STUBBED) called id= {} name = {} value = {} mode = {}", id,
std::string(name), std::string(value), mode);
return ORBIS_OK;
}
@ -84,8 +114,9 @@ int PS4_SYSV_ABI sceHttpCreateConnection() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpCreateConnectionWithURL() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
int PS4_SYSV_ABI sceHttpCreateConnectionWithURL(int tmplId, const char* url, bool enableKeepalive) {
LOG_ERROR(Lib_Http, "(STUBBED) called tmpid = {} url = {} enableKeepalive = {}", tmplId,
std::string(url), enableKeepalive ? 1 : 0);
return ORBIS_OK;
}
@ -104,8 +135,10 @@ int PS4_SYSV_ABI sceHttpCreateRequest2() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpCreateRequestWithURL() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
int PS4_SYSV_ABI sceHttpCreateRequestWithURL(int connId, s32 method, const char* url,
u64 contentLength) {
LOG_ERROR(Lib_Http, "(STUBBED) called connId = {} method = {} url={} contentLength={}", connId,
method, url, contentLength);
return ORBIS_OK;
}
@ -184,7 +217,7 @@ int PS4_SYSV_ABI sceHttpGetAcceptEncodingGZIPEnabled() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpGetAllResponseHeaders() {
int PS4_SYSV_ABI sceHttpGetAllResponseHeaders(int reqId, char** header, u64* headerSize) {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_FAIL;
}
@ -254,12 +287,42 @@ int PS4_SYSV_ABI sceHttpGetResponseContentLength() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpGetStatusCode() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
int PS4_SYSV_ABI sceHttpGetStatusCode(int reqId, int* statusCode) {
LOG_ERROR(Lib_Http, "(STUBBED) called reqId = {}", reqId);
#if 0
if (!g_isHttpInitialized)
return ORBIS_HTTP_ERROR_BEFORE_INIT;
if (statusCode == nullptr)
return ORBIS_HTTP_ERROR_INVALID_VALUE;
int ret = 0;
// Lookup HttpRequestInternal by reqId
HttpRequestInternal* request = nullptr;
ret = HttpRequestInternal_Acquire(&request, reqId);
if (ret < 0)
return ret;
request->m_mutex.lock();
if (request->state > 0x11) {
if (request->state == 0x16) {
ret = request->errorCode;
} else {
*statusCode = request->httpStatusCode;
ret = 0;
}
} else {
ret = ORBIS_HTTP_ERROR_BEFORE_SEND;
}
request->m_mutex.unlock();
HttpRequestInternal_Release(request);
return ret;
#else
return ORBIS_OK;
#endif
}
int PS4_SYSV_ABI sceHttpInit(int libnetMemId, int libsslCtxId, std::size_t poolSize) {
int PS4_SYSV_ABI sceHttpInit(int libnetMemId, int libsslCtxId, u64 poolSize) {
LOG_ERROR(Lib_Http, "(DUMMY) called libnetMemId = {} libsslCtxId = {} poolSize = {}",
libnetMemId, libsslCtxId, poolSize);
// return a value >1
@ -267,14 +330,104 @@ int PS4_SYSV_ABI sceHttpInit(int libnetMemId, int libsslCtxId, std::size_t poolS
return ++id;
}
int PS4_SYSV_ABI sceHttpParseResponseHeader() {
int PS4_SYSV_ABI sceHttpParseResponseHeader(const char* header, u64 headerLen, const char* fieldStr,
const char** fieldValue, u64* valueLen) {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpParseStatusLine() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceHttpParseStatusLine(const char* statusLine, u64 lineLen, int32_t* httpMajorVer,
int32_t* httpMinorVer, int32_t* responseCode,
const char** reasonPhrase, u64* phraseLen) {
if (!statusLine) {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
if (!httpMajorVer || !httpMinorVer || !responseCode || !reasonPhrase || !phraseLen) {
LOG_ERROR(Lib_Http, "Invalid value");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_VALUE;
}
*httpMajorVer = 0;
*httpMinorVer = 0;
if (lineLen < 8) {
LOG_ERROR(Lib_Http, "Linelen is smaller than 8");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
if (strncmp(statusLine, "HTTP/", 5) != 0) {
LOG_ERROR(Lib_Http, "statusLine doesn't start with HTTP/");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
u64 index = 5;
if (!isdigit(statusLine[index])) {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
while (isdigit(statusLine[index])) {
*httpMajorVer = *httpMajorVer * 10 + (statusLine[index] - '0');
index++;
}
if (statusLine[index] != '.') {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
index++;
if (!isdigit(statusLine[index])) {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
while (isdigit(statusLine[index])) {
*httpMinorVer = *httpMinorVer * 10 + (statusLine[index] - '0');
index++;
}
if (statusLine[index] != ' ') {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
index++;
// Validate and parse the 3-digit HTTP response code
if (lineLen - index < 3 || !isdigit(statusLine[index]) || !isdigit(statusLine[index + 1]) ||
!isdigit(statusLine[index + 2])) {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
*responseCode = (statusLine[index] - '0') * 100 + (statusLine[index + 1] - '0') * 10 +
(statusLine[index + 2] - '0');
index += 3;
if (statusLine[index] != ' ') {
LOG_ERROR(Lib_Http, "Invalid response");
return ORBIS_HTTP_ERROR_PARSE_HTTP_INVALID_RESPONSE;
}
index++;
// Set the reason phrase start position
*reasonPhrase = &statusLine[index];
u64 phraseStart = index;
while (index < lineLen && statusLine[index] != '\n') {
index++;
}
// Determine the length of the reason phrase, excluding trailing \r if present
if (index == phraseStart) {
*phraseLen = 0;
} else {
*phraseLen =
(statusLine[index - 1] == '\r') ? (index - phraseStart - 1) : (index - phraseStart);
}
// Return the number of bytes processed
return index + 1;
}
int PS4_SYSV_ABI sceHttpReadData() {
@ -317,8 +470,8 @@ int PS4_SYSV_ABI sceHttpsEnableOptionPrivate() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpSendRequest() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
int PS4_SYSV_ABI sceHttpSendRequest(int reqId, const void* postData, u64 size) {
LOG_ERROR(Lib_Http, "(STUBBED) called reqId = {} size = {}", reqId, size);
return ORBIS_OK;
}
@ -548,7 +701,8 @@ int PS4_SYSV_ABI sceHttpUnsetEpoll() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpUriBuild() {
int PS4_SYSV_ABI sceHttpUriBuild(char* out, u64* require, u64 prepare,
const OrbisHttpUriElement* srcElement, u32 option) {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
}
@ -563,13 +717,97 @@ int PS4_SYSV_ABI sceHttpUriEscape() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpUriMerge() {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceHttpUriMerge(char* mergedUrl, char* url, char* relativeUri, u64* require,
u64 prepare, u32 option) {
u64 requiredLength;
int returnValue;
u64 baseUrlLength;
u64 relativeUriLength;
u64 totalLength;
u64 combinedLength;
int parseResult;
u64 localSizeRelativeUri;
u64 localSizeBaseUrl;
OrbisHttpUriElement parsedUriElement;
if (option != 0 || url == NULL || relativeUri == NULL) {
LOG_ERROR(Lib_Http, "Invalid value");
return ORBIS_HTTP_ERROR_INVALID_VALUE;
}
returnValue = sceHttpUriParse(NULL, url, NULL, &localSizeBaseUrl, 0);
if (returnValue < 0) {
LOG_ERROR(Lib_Http, "returning {:#x}", returnValue);
return returnValue;
}
returnValue = sceHttpUriParse(NULL, relativeUri, NULL, &localSizeRelativeUri, 0);
if (returnValue < 0) {
LOG_ERROR(Lib_Http, "returning {:#x}", returnValue);
return returnValue;
}
baseUrlLength = strnlen(url, 0x3fff);
relativeUriLength = strnlen(relativeUri, 0x3fff);
requiredLength = localSizeBaseUrl + 2 + (relativeUriLength + baseUrlLength) * 2;
if (require) {
*require = requiredLength;
}
if (mergedUrl == NULL) {
return ORBIS_OK;
}
if (prepare < requiredLength) {
LOG_ERROR(Lib_Http, "Error Out of memory");
return ORBIS_HTTP_ERROR_OUT_OF_MEMORY;
}
totalLength = strnlen(url, 0x3fff);
baseUrlLength = strnlen(relativeUri, 0x3fff);
combinedLength = totalLength + 1 + baseUrlLength;
relativeUriLength = prepare - combinedLength;
returnValue =
sceHttpUriParse(&parsedUriElement, relativeUri, mergedUrl + totalLength + baseUrlLength + 1,
&localSizeRelativeUri, relativeUriLength);
if (returnValue < 0) {
LOG_ERROR(Lib_Http, "returning {:#x}", returnValue);
return returnValue;
}
if (parsedUriElement.scheme == NULL) {
strncpy(mergedUrl, relativeUri, requiredLength);
if (require) {
*require = strnlen(relativeUri, 0x3fff) + 1;
}
return ORBIS_OK;
}
returnValue =
sceHttpUriParse(&parsedUriElement, url, mergedUrl + totalLength + baseUrlLength + 1,
&localSizeBaseUrl, relativeUriLength);
if (returnValue < 0) {
LOG_ERROR(Lib_Http, "returning {:#x}", returnValue);
return returnValue;
}
combinedLength += localSizeBaseUrl;
strncpy(mergedUrl + combinedLength, parsedUriElement.path, prepare - combinedLength);
NormalizeAndAppendPath(mergedUrl + combinedLength, relativeUri);
returnValue = sceHttpUriBuild(mergedUrl, 0, ~(baseUrlLength + totalLength) + prepare,
&parsedUriElement, 0x3f);
if (returnValue >= 0) {
return ORBIS_OK;
} else {
LOG_ERROR(Lib_Http, "returning {:#x}", returnValue);
return returnValue;
}
}
int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, void* pool,
size_t* require, size_t prepare) {
u64* require, u64 prepare) {
LOG_INFO(Lib_Http, "srcUri = {}", std::string(srcUri));
if (!srcUri) {
LOG_ERROR(Lib_Http, "invalid url");
@ -586,10 +824,10 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
}
// Track the total required buffer size
size_t requiredSize = 0;
u64 requiredSize = 0;
// Parse the scheme (e.g., "http:", "https:", "file:")
size_t schemeLength = 0;
u64 schemeLength = 0;
while (srcUri[schemeLength] && srcUri[schemeLength] != ':') {
if (!isalnum(srcUri[schemeLength])) {
LOG_ERROR(Lib_Http, "invalid url");
@ -611,7 +849,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
requiredSize += schemeLength + 1;
// Move past the scheme and ':' character
size_t offset = schemeLength + 1;
u64 offset = schemeLength + 1;
// Check if "//" appears after the scheme
if (strncmp(srcUri + offset, "//", 2) == 0) {
@ -638,7 +876,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
// Parse the path (everything after the slashes)
char* pathStart = (char*)srcUri + offset;
size_t pathLength = 0;
u64 pathLength = 0;
while (pathStart[pathLength] && pathStart[pathLength] != '?' &&
pathStart[pathLength] != '#') {
pathLength++;
@ -689,7 +927,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
hostStart++;
}
size_t hostLength = 0;
u64 hostLength = 0;
while (hostStart[hostLength] && hostStart[hostLength] != '/' &&
hostStart[hostLength] != '?' && hostStart[hostLength] != ':') {
hostLength++;
@ -714,7 +952,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
// Parse the port (if present)
if (hostStart[hostLength] == ':') {
char* portStart = hostStart + hostLength + 1;
size_t portLength = 0;
u64 portLength = 0;
while (portStart[portLength] && isdigit(portStart[portLength])) {
portLength++;
}
@ -754,7 +992,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
// Parse the path (if present)
if (srcUri[offset] == '/') {
char* pathStart = (char*)srcUri + offset;
size_t pathLength = 0;
u64 pathLength = 0;
while (pathStart[pathLength] && pathStart[pathLength] != '?' &&
pathStart[pathLength] != '#') {
pathLength++;
@ -780,7 +1018,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
// Parse the query (if present)
if (srcUri[offset] == '?') {
char* queryStart = (char*)srcUri + offset + 1;
size_t queryLength = 0;
u64 queryLength = 0;
while (queryStart[queryLength] && queryStart[queryLength] != '#') {
queryLength++;
}
@ -805,7 +1043,7 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
// Parse the fragment (if present)
if (srcUri[offset] == '#') {
char* fragmentStart = (char*)srcUri + offset + 1;
size_t fragmentLength = 0;
u64 fragmentLength = 0;
while (fragmentStart[fragmentLength]) {
fragmentLength++;
}
@ -833,12 +1071,12 @@ int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, v
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize) {
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, u64 srcSize) {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, size_t* require, size_t prepare, const char* in) {
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const char* in) {
LOG_ERROR(Lib_Http, "(STUBBED) called");
return ORBIS_OK;
}

View File

@ -3,6 +3,7 @@
#pragma once
#include <mutex>
#include "common/types.h"
#include "core/libraries/network/ssl.h"
@ -25,6 +26,12 @@ struct OrbisHttpUriElement {
u8 reserved[10];
};
struct HttpRequestInternal {
int state; // +0x20
int errorCode; // +0x28
int httpStatusCode; // +0x20C
std::mutex m_mutex;
};
using OrbisHttpsCaList = Libraries::Ssl::OrbisSslCaList;
int PS4_SYSV_ABI sceHttpAbortRequest();
@ -32,7 +39,7 @@ int PS4_SYSV_ABI sceHttpAbortRequestForce();
int PS4_SYSV_ABI sceHttpAbortWaitRequest();
int PS4_SYSV_ABI sceHttpAddCookie();
int PS4_SYSV_ABI sceHttpAddQuery();
int PS4_SYSV_ABI sceHttpAddRequestHeader();
int PS4_SYSV_ABI sceHttpAddRequestHeader(int id, const char* name, const char* value, s32 mode);
int PS4_SYSV_ABI sceHttpAddRequestHeaderRaw();
int PS4_SYSV_ABI sceHttpAuthCacheExport();
int PS4_SYSV_ABI sceHttpAuthCacheFlush();
@ -42,11 +49,12 @@ int PS4_SYSV_ABI sceHttpCookieExport();
int PS4_SYSV_ABI sceHttpCookieFlush();
int PS4_SYSV_ABI sceHttpCookieImport();
int PS4_SYSV_ABI sceHttpCreateConnection();
int PS4_SYSV_ABI sceHttpCreateConnectionWithURL();
int PS4_SYSV_ABI sceHttpCreateConnectionWithURL(int tmplId, const char* url, bool enableKeepalive);
int PS4_SYSV_ABI sceHttpCreateEpoll();
int PS4_SYSV_ABI sceHttpCreateRequest();
int PS4_SYSV_ABI sceHttpCreateRequest2();
int PS4_SYSV_ABI sceHttpCreateRequestWithURL();
int PS4_SYSV_ABI sceHttpCreateRequestWithURL(int connId, s32 method, const char* url,
u64 contentLength);
int PS4_SYSV_ABI sceHttpCreateRequestWithURL2();
int PS4_SYSV_ABI sceHttpCreateTemplate();
int PS4_SYSV_ABI sceHttpDbgEnableProfile();
@ -62,7 +70,7 @@ int PS4_SYSV_ABI sceHttpDeleteRequest();
int PS4_SYSV_ABI sceHttpDeleteTemplate();
int PS4_SYSV_ABI sceHttpDestroyEpoll();
int PS4_SYSV_ABI sceHttpGetAcceptEncodingGZIPEnabled();
int PS4_SYSV_ABI sceHttpGetAllResponseHeaders();
int PS4_SYSV_ABI sceHttpGetAllResponseHeaders(int reqId, char** header, u64* headerSize);
int PS4_SYSV_ABI sceHttpGetAuthEnabled();
int PS4_SYSV_ABI sceHttpGetAutoRedirect();
int PS4_SYSV_ABI sceHttpGetConnectionStat();
@ -76,10 +84,13 @@ int PS4_SYSV_ABI sceHttpGetMemoryPoolStats();
int PS4_SYSV_ABI sceHttpGetNonblock();
int PS4_SYSV_ABI sceHttpGetRegisteredCtxIds();
int PS4_SYSV_ABI sceHttpGetResponseContentLength();
int PS4_SYSV_ABI sceHttpGetStatusCode();
int PS4_SYSV_ABI sceHttpInit(int libnetMemId, int libsslCtxId, std::size_t poolSize);
int PS4_SYSV_ABI sceHttpParseResponseHeader();
int PS4_SYSV_ABI sceHttpParseStatusLine();
int PS4_SYSV_ABI sceHttpGetStatusCode(int reqId, int* statusCode);
int PS4_SYSV_ABI sceHttpInit(int libnetMemId, int libsslCtxId, u64 poolSize);
int PS4_SYSV_ABI sceHttpParseResponseHeader(const char* header, u64 headerLen, const char* fieldStr,
const char** fieldValue, u64* valueLen);
int PS4_SYSV_ABI sceHttpParseStatusLine(const char* statusLine, u64 lineLen, int32_t* httpMajorVer,
int32_t* httpMinorVer, int32_t* responseCode,
const char** reasonPhrase, u64* phraseLen);
int PS4_SYSV_ABI sceHttpReadData();
int PS4_SYSV_ABI sceHttpRedirectCacheFlush();
int PS4_SYSV_ABI sceHttpRemoveRequestHeader();
@ -88,7 +99,7 @@ int PS4_SYSV_ABI sceHttpsDisableOption();
int PS4_SYSV_ABI sceHttpsDisableOptionPrivate();
int PS4_SYSV_ABI sceHttpsEnableOption();
int PS4_SYSV_ABI sceHttpsEnableOptionPrivate();
int PS4_SYSV_ABI sceHttpSendRequest();
int PS4_SYSV_ABI sceHttpSendRequest(int reqId, const void* postData, u64 size);
int PS4_SYSV_ABI sceHttpSetAcceptEncodingGZIPEnabled();
int PS4_SYSV_ABI sceHttpSetAuthEnabled();
int PS4_SYSV_ABI sceHttpSetAuthInfoCallback();
@ -134,14 +145,16 @@ int PS4_SYSV_ABI sceHttpTerm();
int PS4_SYSV_ABI sceHttpTryGetNonblock();
int PS4_SYSV_ABI sceHttpTrySetNonblock();
int PS4_SYSV_ABI sceHttpUnsetEpoll();
int PS4_SYSV_ABI sceHttpUriBuild();
int PS4_SYSV_ABI sceHttpUriBuild(char* out, u64* require, u64 prepare,
const OrbisHttpUriElement* srcElement, u32 option);
int PS4_SYSV_ABI sceHttpUriCopy();
int PS4_SYSV_ABI sceHttpUriEscape();
int PS4_SYSV_ABI sceHttpUriMerge();
int PS4_SYSV_ABI sceHttpUriMerge(char* mergedUrl, char* url, char* relativeUri, u64* require,
u64 prepare, u32 option);
int PS4_SYSV_ABI sceHttpUriParse(OrbisHttpUriElement* out, const char* srcUri, void* pool,
size_t* require, size_t prepare);
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, size_t srcSize);
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, size_t* require, size_t prepare, const char* in);
u64* require, u64 prepare);
int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, u64 srcSize);
int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const char* in);
int PS4_SYSV_ABI sceHttpWaitRequest();
void RegisterLib(Core::Loader::SymbolsResolver* sym);

View File

@ -1285,7 +1285,8 @@ u16 PS4_SYSV_ABI sceNetNtohs(u16 net16) {
int PS4_SYSV_ABI sceNetPoolCreate(const char* name, int size, int flags) {
LOG_ERROR(Lib_Net, "(DUMMY) name = {} size = {} flags = {} ", std::string(name), size, flags);
return ORBIS_OK;
static s32 id = 1;
return id++;
}
int PS4_SYSV_ABI sceNetPoolDestroy() {

View File

@ -185,7 +185,7 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor
}
if (!ignore_corrupt && !read_only) {
Common::FS::IOFile f(corrupt_file_path, Common::FS::FileAccessMode::Write);
Common::FS::IOFile f(corrupt_file_path, Common::FS::FileAccessMode::Create);
f.Close();
}

View File

@ -58,7 +58,7 @@ void PersistMemory(u32 slot_id, bool lock) {
while (n++ < 10) {
try {
IOFile f;
int r = f.Open(memoryPath, Common::FS::FileAccessMode::Write);
int r = f.Open(memoryPath, Common::FS::FileAccessMode::Create);
if (f.IsOpen()) {
f.WriteRaw<u8>(data.memory_cache.data(), data.memory_cache.size());
f.Close();
@ -150,7 +150,7 @@ void SetIcon(u32 slot_id, void* buf, size_t buf_size) {
fs::copy_file(src_icon, icon_path);
}
} else {
int fd = qfs->Operation.Open(icon_path, QUASI_O_WRONLY | QUASI_O_TRUNC);
int fd = qfs->Operation.Creat(icon_path);
qfs->Operation.Write(fd, buf, buf_size);
qfs->Operation.Close(fd);
}

View File

@ -1389,7 +1389,7 @@ Error PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint
}
try {
const Common::FS::IOFile file(path, Common::FS::FileAccessMode::Write);
const Common::FS::IOFile file(path, Common::FS::FileAccessMode::Create);
file.WriteRaw<u8>(icon->buf, std::min(icon->bufSize, icon->dataSize));
} catch (const fs::filesystem_error& e) {
LOG_ERROR(Lib_SaveData, "Failed to load icon: {}", e.what());

View File

@ -502,19 +502,19 @@ bool Elf::IsSharedLib() {
}
void Elf::ElfHeaderDebugDump(const std::filesystem::path& file_name) {
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write,
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create,
Common::FS::FileType::TextFile};
f.WriteString(ElfHeaderStr());
}
void Elf::SelfHeaderDebugDump(const std::filesystem::path& file_name) {
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write,
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create,
Common::FS::FileType::TextFile};
f.WriteString(SElfHeaderStr());
}
void Elf::SelfSegHeaderDebugDump(const std::filesystem::path& file_name) {
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write,
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create,
Common::FS::FileType::TextFile};
for (u16 i = 0; i < m_self.segment_count; i++) {
f.WriteString(SELFSegHeader(i));
@ -522,7 +522,7 @@ void Elf::SelfSegHeaderDebugDump(const std::filesystem::path& file_name) {
}
void Elf::PHeaderDebugDump(const std::filesystem::path& file_name) {
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write,
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create,
Common::FS::FileType::TextFile};
if (m_elf_header.e_phentsize > 0) {
for (u16 i = 0; i < m_elf_header.e_phnum; i++) {

View File

@ -32,7 +32,7 @@ const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolResolver& s) const {
}
void SymbolsResolver::DebugDump(const std::filesystem::path& file_name) {
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Write,
Common::FS::IOFile f{file_name, Common::FS::FileAccessMode::Create,
Common::FS::FileType::TextFile};
for (const auto& symbol : m_symbols) {
const auto ids = Common::SplitString(symbol.name, '#');

View File

@ -31,6 +31,8 @@
#include "core/file_format/trp.h"
#include "core/file_sys/fs.h"
#include "core/libraries/disc_map/disc_map.h"
#include "core/libraries/font/font.h"
#include "core/libraries/font/fontft.h"
#include "core/libraries/libc_internal/libc_internal.h"
#include "core/libraries/libs.h"
#include "core/libraries/ngs2/ngs2.h"
@ -621,8 +623,8 @@ void Emulator::LoadSystemModules(const std::string& game_serial) {
{"libSceJson2.sprx", nullptr},
{"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterLib},
{"libSceCesCs.sprx", nullptr},
{"libSceFont.sprx", nullptr},
{"libSceFontFt.sprx", nullptr},
{"libSceFont.sprx", &Libraries::Font::RegisterlibSceFont},
{"libSceFontFt.sprx", &Libraries::FontFt::RegisterlibSceFontFt},
{"libSceFreeTypeOt.sprx", nullptr}});
std::vector<std::filesystem::path> found_modules;

View File

@ -559,7 +559,7 @@ void Translator::EmitFetch(const GcnInst& inst) {
std::filesystem::create_directories(dump_dir);
}
const auto filename = fmt::format("vs_{:#018x}.fetch.bin", info.pgm_hash);
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
const auto file = IOFile{dump_dir / filename, FileAccessMode::Create};
file.WriteRaw<u8>(fetch_data->code, fetch_data->size);
}

View File

@ -39,7 +39,7 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code
std::filesystem::create_directories(dump_dir);
}
const auto filename = fmt::format("{}_{:#018x}.srtprogram.txt", info.stage, info.pgm_hash);
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write, FileType::TextFile};
const auto file = IOFile{dump_dir / filename, FileAccessMode::Create, FileType::TextFile};
u64 address = reinterpret_cast<u64>(code);
u64 code_end = address + codesize;

View File

@ -28,7 +28,7 @@ void DumpProgram(const Program& program, const Info& info, const std::string& ty
}
const auto ir_filename =
fmt::format("{}_{:#018x}.{}irprogram.txt", info.stage, info.pgm_hash, type);
const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Write, FileType::TextFile};
const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Create, FileType::TextFile};
size_t index{0};
std::map<const IR::Inst*, size_t> inst_to_index;
@ -46,7 +46,7 @@ void DumpProgram(const Program& program, const Info& info, const std::string& ty
const auto asl_filename = fmt::format("{}_{:#018x}.{}asl.txt", info.stage, info.pgm_hash, type);
const auto asl_file =
IOFile{dump_dir / asl_filename, FileAccessMode::Write, FileType::TextFile};
IOFile{dump_dir / asl_filename, FileAccessMode::Create, FileType::TextFile};
for (const auto& node : program.syntax_list) {
std::string s = IR::DumpASLNode(node, block_to_index, inst_to_index) + '\n';

View File

@ -632,7 +632,7 @@ void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stag
std::filesystem::create_directories(dump_dir);
}
const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext);
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
const auto file = IOFile{dump_dir / filename, FileAccessMode::Create};
file.WriteSpan(code);
}