Files
jmelovich ae52676cfc M0: boilerplate skeleton builds with the system clang and launches as PPSA99350
Imported ps5-native-app-boilerplate (Makefile, tools, tooling, clean-room runtime
builder, CPU demo renderer). The compiler wrapper and build.sh fall back to the
host clang when clang-18 is absent (Arch ships clang 22; verified), ccache is
optional, and the large home-screen DDS/AT9 assets stay out of git. Identity:
PPSA99350 "Steam Remote Play". Submodules pinned: ihslib master 1881b9a,
protobuf-c v1.5.2, mbedtls v3.6.4, opus v1.5.2 (the mbedtls/opus revisions
ProsperoLight proved on the console). ProsperoLight's sceNet socket adapter,
entropy source, mbedtls config and VideoDec2/VideoOut/AGC link stubs are staged
under platform/ps5 and vendor/ps5 for M1/M2.

Tested: make, make deploy, shsrv launch; the demo screen renders on the TV.
2026-10-08 17:12:01 -07:00

82 lines
2.3 KiB
C++

/*
* ps5-native-app-boilerplate - Native application startup.
* Copyright (C) 2026 BlackBearReloaded
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Initializes the platform runtime, runs static constructors and main, and
* hands normal process termination back to the platform runtime.
*/
#include <cstddef>
#include <cstdint>
using Destructor = void (*)();
using Initializer = void (*)();
extern "C"
{
void _init_env(void *process_parameters);
int atexit(Destructor callback);
[[noreturn]] void exit(int status);
int application_main(int argc, char **argv, char **envp) __asm__("main");
extern Initializer __preinit_array_start[] __attribute__((weak));
extern Initializer __preinit_array_end[] __attribute__((weak));
extern Initializer __init_array_start[] __attribute__((weak));
extern Initializer __init_array_end[] __attribute__((weak));
extern Initializer __fini_array_start[] __attribute__((weak));
extern Initializer __fini_array_end[] __attribute__((weak));
}
namespace
{
void run_forward(Initializer *first, Initializer *last) noexcept
{
if (first == nullptr || last == nullptr)
return;
while (first != last)
(*first++)();
}
void run_reverse(Initializer *first, Initializer *last) noexcept
{
if (first == nullptr || last == nullptr)
return;
while (last != first)
(*--last)();
}
} // namespace
extern "C" __attribute__((weak)) void catchReturnFromMain(int status)
{
(void)status;
}
extern "C" void _init()
{
run_forward(__preinit_array_start, __preinit_array_end);
run_forward(__init_array_start, __init_array_end);
}
extern "C" void _fini()
{
run_reverse(__fini_array_start, __fini_array_end);
}
extern "C" [[noreturn]] __attribute__((visibility("default"))) void
_start(void *process_parameters, Destructor loader_teardown)
{
const int argc = *static_cast<const int *>(process_parameters);
auto *parameters = static_cast<std::uint8_t *>(process_parameters);
auto **argv = reinterpret_cast<char **>(parameters + sizeof(std::uint64_t));
_init_env(process_parameters);
if (loader_teardown != nullptr)
(void)atexit(loader_teardown);
(void)atexit(_fini);
_init();
const int status = application_main(argc, argv, nullptr);
catchReturnFromMain(status);
exit(status);
}