Simplified PSP network

This commit is contained in:
2026-07-16 22:55:47 -05:00
parent f16c80aa0f
commit d7982599d1
3 changed files with 62 additions and 151 deletions
+47 -132
View File
@@ -9,8 +9,11 @@
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
#include "display/displaysdl2.h"
#include "display/shader/shadergl.h"
#include "time/time.h"
// How long to wait for sceNetApctlConnect() to reach
// PSP_NET_APCTL_STATE_GOT_IP before giving up and reporting failure.
#define NETWORK_PSP_CONNECT_TIMEOUT 15.0f
errorret_t networkPSPInit() {
// Requests the PSP to load the network modules.
@@ -18,7 +21,7 @@ errorret_t networkPSPInit() {
ret = sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
if(ret < 0) errorThrow("Failed to init NET COMMON: 0x%08X", ret);
ret = sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
if(ret < 0) errorThrow("Failed to init NET INET: 0x%08X", ret);
@@ -54,129 +57,55 @@ errorret_t networkPSPInit() {
}
errorret_t networkPSPUpdate() {
int ret;
if(NETWORK.state == NETWORK_STATE_CONNECTING) {
switch(sceUtilityNetconfGetStatus()) {
case PSP_UTILITY_DIALOG_INIT:
break;
if(NETWORK.state != NETWORK_STATE_CONNECTING) errorOk();
case PSP_UTILITY_DIALOG_NONE:
NETWORK.state = NETWORK_STATE_DISCONNECTED;
errorThrow("PSP Netconf dialog disappeared without result");
break;
int apState = 0;
int ret = sceNetApctlGetState(&apState);
case PSP_UTILITY_DIALOG_VISIBLE:
// The dialog renders using whatever GL state we leave lying
// around, immediately before it draws - it doesn't set up its
// own blend/cull/depth/texture state from scratch. Match exactly
// what our own text rendering uses (displaySetState's
// BLEND-only flags, plus shaderUnlitSetMaterial's texture/color
// setup), otherwise its text/icons render missing while its
// untextured chrome still appears fine.
glDisable(GL_CULL_FACE);
errorChain(errorGLCheck());
glDisable(GL_DEPTH_TEST);
errorChain(errorGLCheck());
glEnable(GL_BLEND);
errorChain(errorGLCheck());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
errorChain(errorGLCheck());
if(ret < 0 || TIME.time >= NETWORK.platform.connectTimeoutAt) {
NETWORK.state = NETWORK_STATE_DISCONNECTED;
glEnable(GL_TEXTURE_2D);
errorChain(errorGLCheck());
glBindTexture(GL_TEXTURE_2D, TEXTURE_WHITE.id);
errorChain(errorGLCheck());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
errorChain(errorGLCheck());
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
errorChain(errorGLCheck());
SHADER_LEGACY.boundTextureId = TEXTURE_WHITE.id;
assertNotNull(
NETWORK.platform.onFailed,
"Network platform onFailed callback should be set."
);
// pspGL defers actually applying state to the GPU until the
// next real draw call - the calls above alone may be no-ops
// on hardware. Force a flush with a degenerate (zero-area, so
// nothing actually rasterizes) triangle.
const float_t degenerate[3 * 5] = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
};
const GLsizei stride = sizeof(float_t) * 5;
glVertexPointer(3, GL_FLOAT, stride, &degenerate[0]);
errorChain(errorGLCheck());
glTexCoordPointer(2, GL_FLOAT, stride, &degenerate[3]);
errorChain(errorGLCheck());
glDrawArrays(GL_TRIANGLES, 0, 3);
errorChain(errorGLCheck());
sceNetApctlDisconnect();
// 1 is mandatory?
ret = sceUtilityNetconfUpdate(1);
if(ret != 0) {
errorThrow("sceUtilityNetconfUpdate failed: 0x%08X", ret);
}
break;
case PSP_UTILITY_DIALOG_QUIT:
ret = sceUtilityNetconfShutdownStart();
if(ret != 0) {
errorThrow("sceUtilityNetconfShutdownStart failed: 0x%08X", ret);
}
break;
case PSP_UTILITY_DIALOG_FINISHED:
// Did we connect?
int apState = 0;
sceNetApctlGetState(&apState);
if(apState == PSP_NET_APCTL_STATE_GOT_IP) {
NETWORK.state = NETWORK_STATE_CONNECTED;
assertNotNull(
NETWORK.platform.onConnected,
"Network platform onConnected callback should be set."
);
NETWORK.platform.onConnected(NETWORK.platform.onConnectedUser);
} else {
NETWORK.state = NETWORK_STATE_DISCONNECTED;
assertNotNull(
NETWORK.platform.onFailed,
"Network platform onFailed callback should be set."
);
// Kill the PSP network stack.
errorret_t err = networkPSPTerm();
if(errorIsNotOk(err)) {
errorCatch(errorPrint(err));
}
errorret_t error = errorThrowImpl(
&NETWORK.errorState,
ERROR_NOT_OK,
__FILE__, __func__, __LINE__,
"Failed to connect to network"
);
NETWORK.platform.onFailed(error, NETWORK.platform.onConnectedUser);
}
break;
default:
errorThrow(
"Unknown PSP Netconf dialog status: %d", sceUtilityNetconfGetStatus()
);
errorret_t err = networkPSPTerm();
if(errorIsNotOk(err)) {
errorCatch(errorPrint(err));
}
errorret_t error = errorThrowImpl(
&NETWORK.errorState,
ERROR_NOT_OK,
__FILE__, __func__, __LINE__,
"Failed to connect to network"
);
NETWORK.platform.onFailed(error, NETWORK.platform.onConnectedUser);
errorOk();
}
if(apState == PSP_NET_APCTL_STATE_GOT_IP) {
NETWORK.state = NETWORK_STATE_CONNECTED;
assertNotNull(
NETWORK.platform.onConnected,
"Network platform onConnected callback should be set."
);
NETWORK.platform.onConnected(NETWORK.platform.onConnectedUser);
}
errorOk();
}
errorret_t networkPSPDispose() {
sceUtilityNetconfGetStatus();
errorCatch(errorPrint(networkPSPTerm()));
sceUtilityUnloadNetModule(PSP_NET_MODULE_HTTP);
sceUtilityUnloadNetModule(PSP_NET_MODULE_INET);
sceUtilityUnloadNetModule(PSP_NET_MODULE_COMMON);
errorOk();
}
@@ -214,30 +143,14 @@ void networkPSPRequestConnection(
ret = sceNetApctlInit(0x1800, 0x30);
assertTrue(ret >= 0, "Failed to init net apctl: 0x%08X");
// This is all related to getting the PSP online, refer to;
// https://github.com/joel16/CMFileManager-PSP/blob/00dab16c64cd48bf6452fc274a3b898d77c39a8d/app/source/net.cpp#L97
// since I follow this implementation closely.
memoryZero(&NETWORK.platform.dialogData, sizeof(NETWORK.platform.dialogData));
memoryZero(
&NETWORK.platform.dialogAdhoc, sizeof(NETWORK.platform.dialogAdhoc)
// Connect using the first saved connection profile - no dialog, no GU
// rendering involved. If this fails to even start (e.g. no profile
// exists), let networkPSPUpdate() report it the same way as any other
// connection failure on the very next frame, rather than crashing here.
ret = sceNetApctlConnect(1);
NETWORK.platform.connectTimeoutAt = (
ret >= 0 ? TIME.time + NETWORK_PSP_CONNECT_TIMEOUT : TIME.time
);
NETWORK.platform.dialogData.base.size = sizeof(pspUtilityNetconfData);
NETWORK.platform.dialogData.base.language = systemPSPGetLanguage();
NETWORK.platform.dialogData.base.buttonSwap =
systemPSPGetCrossButtonSetting();
NETWORK.platform.dialogData.base.graphicsThread = 17;
NETWORK.platform.dialogData.base.accessThread = 19;
NETWORK.platform.dialogData.base.fontThread = 18;
NETWORK.platform.dialogData.base.soundThread = 16;
NETWORK.platform.dialogData.action = PSP_NETCONF_ACTION_CONNECTAP;
NETWORK.platform.dialogData.adhocparam = (
&NETWORK.platform.dialogAdhoc
);
ret = sceUtilityNetconfInitStart(&NETWORK.platform.dialogData);
assertTrue(ret >= 0, "Failed to init netconf");
}
void networkPSPRequestDisconnection(
@@ -249,6 +162,8 @@ void networkPSPRequestDisconnection(
"Network host should be in a disconnecting state."
);
sceNetApctlDisconnect();
errorret_t err = networkPSPTerm();
if(errorIsNotOk(err)) {
errorCatch(errorPrint(err));
+15 -14
View File
@@ -8,13 +8,13 @@
#pragma once
#include "error/error.h"
#include "network/networkinfo.h"
#include "system/systempsp.h"
#include <psphttp.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspssl.h>
#include <pspnet_resolver.h>
#include <psputility_netmodules.h>
#include <psphttp.h>
// #define NETWORK_HTTP_PENDING_MAX 4
@@ -28,8 +28,9 @@
// #define NETWORK_PSP_AGENT "DuskEngine/1.0"
typedef struct {
pspUtilityNetconfData dialogData;
struct pspUtilityNetconfAdhoc dialogAdhoc;
// Deadline (TIME.time) for the current sceNetApctlConnect() attempt
// to reach PSP_NET_APCTL_STATE_GOT_IP before it's reported as failed.
float_t connectTimeoutAt;
// Used during establishing connection
void *onConnectedUser;
@@ -40,7 +41,7 @@ typedef struct {
/**
* Initializes the PSP Network manager. This will NOT do network connecting,
* only prep it for being able to connect in future.
*
*
* @return Error state (if any).
*/
errorret_t networkPSPInit();
@@ -48,7 +49,7 @@ errorret_t networkPSPInit();
/**
* Called each frame for handling PSP requests, basically this is where all
* communication between the HTTP thread and the main thread happens.
*
*
* @return Error state (if any).
*/
errorret_t networkPSPUpdate();
@@ -56,21 +57,22 @@ errorret_t networkPSPUpdate();
/**
* Disposes the PSP Network manager, this will clean all resources and, if the
* network is connected, it will disconnect it safely.
*
*
* @return Error state (if any).
*/
errorret_t networkPSPDispose();
/**
* Checks if the PSP network is connected.
*
*
* @return True if the PSP is connected to a network, false otherwise.
*/
bool_t networkPSPIsConnected();
/**
* Requests the PSP to connect to a network (Shows the Wi-Fi connected).
*
* Requests the PSP to connect to a network, using the first saved
* connection profile via sceNetApctlConnect() - no dialog is shown.
*
* @param onConnected Callback connected successfully.
* @param onFailed Callback if the connection failed.
* @param onDisconnect Callback when connection is lost.
@@ -85,7 +87,7 @@ void networkPSPRequestConnection(
/**
* Requests the PSP to disconnect from the network.
*
*
* @param onComplete Callback when disconnection is complete.
* @param user User data to pass to the callback.
*/
@@ -95,16 +97,15 @@ void networkPSPRequestDisconnection(
);
/**
* Disposes the PSP sce net libraries, doesn't unload the modules and won't
* term the dialog if it's active.
*
* Disposes the PSP sce net libraries, doesn't unload the modules.
*
* @return Error state (if any).
*/
errorret_t networkPSPTerm();
/**
* Gets the network information for the currently active network connection.
*
*
* @return Network information for the currently active network connection.
*/
networkinfo_t networkPSPGetInfo();
-5
View File
@@ -9,7 +9,6 @@
#include "input/input.h"
#include "util/string.h"
#include "assert/assert.h"
#include "network/network.h"
errorret_t systemInitPSP() {
// Bind ACCEPT and CANCEL binds.
@@ -46,10 +45,6 @@ errorret_t systemInitPSP() {
}
systemdialogtype_t systemGetActiveDialogTypePSP() {
if(NETWORK.state == NETWORK_STATE_CONNECTING) {
return SYSTEM_DIALOG_TYPE_TICK_BLOCKING;
}
return SYSTEM_DIALOG_TYPE_NONE;
}