Skip to content

Commit 63b37fe

Browse files
committed
webMAN MOD 1.47.47h
- Bumped version to "h" - Fixed bug building XML filled with nulls at the end of the file - Refactored wm_proxy: moved mount functions to mount.h - wm_proxy: Added direct mount of PS2 Classics and PS1 with cuesheet - Updated README.md for wm_proxy
1 parent 73c562c commit 63b37fe

18 files changed

+382
-188
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

_Projects_/wm_proxy/README.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,27 @@ The plugin receives the web command through the `module_action` parameter from t
2121
a GET request is constructed and the http request is sent to webMAN's web server using the
2222
loopback IP address 127.0.0.1 on port 80.
2323

24-
If webMAN's web server is not running, the message "webMAN not ready!" is displayed.
25-
24+
If webMAN's web server is not running, the proxy tries to mount the file using Cobra commands.
25+
Only certain file types are supported. Other the message "webMAN not ready!" is displayed.
26+
27+
Type file types that can be mounted directly by the proxy:
28+
- Games if JB folder format (GAMES and GAMEZ)
29+
- PS3ISO (non-split)
30+
- PS2ISO (non-split)
31+
- PS2 Classics
32+
- PSXISO
33+
- BDISO
34+
- DVDISO
35+
- ROMS
36+
37+
Type file types that CANNOT be mounted directly by the proxy are:
38+
- Remote network files (ps3netsrv)
39+
- External ISO stored in exFAT / NTFS /ext2/3/4
40+
- multi-part ISOs
41+
- PSPISO
42+
- GAMEI
43+
- Auto-CONFIG for PS2ISO and PS2 Classics
44+
- PS2 Cue/CCD and PS1 CCD cuesheets are not supported
2645

2746
## Credits
2847

_Projects_/wm_proxy/cobra/cobra.c

+16-12
Original file line numberDiff line numberDiff line change
@@ -864,38 +864,42 @@ int cobra_mount_bd_disc_image(char *files[], unsigned int num)
864864
return sys_storage_ext_mount_bd_discfile(num, files);
865865
}
866866

867-
static void init_tracks(int num_tracks, ScsiTrackDescriptor *scsi_tracks)
867+
static void init_tracks(int num_tracks, TrackDef *tracks, ScsiTrackDescriptor *scsi_tracks)
868868
{
869869
memset(scsi_tracks, 0, num_tracks * sizeof(ScsiTrackDescriptor));
870870

871871
for (int i = 0; i < num_tracks; i++)
872872
{
873-
scsi_tracks[i].adr_control = i ? 0x10 : 0x14;
873+
scsi_tracks[i].adr_control = (tracks[i].is_audio) ? 0x10 : 0x14;
874874
scsi_tracks[i].track_number = i + 1;
875-
scsi_tracks[i].track_start_addr = 0;
875+
scsi_tracks[i].track_start_addr = tracks[i].lba;
876876
}
877877
}
878878

879-
int cobra_mount_psx_disc_image(char *file)
879+
int cobra_mount_psx_disc_image(char *file, TrackDef *tracks, unsigned int num_tracks)
880880
{
881881
if (!file) return EINVAL;
882882

883-
ScsiTrackDescriptor scsi_tracks[1];
884-
init_tracks(1, scsi_tracks);
883+
num_tracks = RANGE(num_tracks, 1, MAX_TRACKS);
885884

886-
return sys_storage_ext_mount_psx_discfile(file, 1, scsi_tracks);
885+
ScsiTrackDescriptor scsi_tracks[num_tracks];
886+
init_tracks(num_tracks, tracks, scsi_tracks);
887+
888+
return sys_storage_ext_mount_psx_discfile(file, num_tracks, scsi_tracks);
887889
}
888890

889-
int cobra_mount_ps2_disc_image(char *files[], int num)
891+
int cobra_mount_ps2_disc_image(char *files[], int num, TrackDef *tracks, unsigned int num_tracks)
890892
{
891-
if (!files) return EINVAL;
893+
if (!files || !tracks) return EINVAL;
894+
895+
num_tracks = RANGE(num_tracks, 1, MAX_TRACKS);
892896

893-
ScsiTrackDescriptor scsi_tracks[1];
894-
init_tracks(1, scsi_tracks);
897+
ScsiTrackDescriptor scsi_tracks[num_tracks];
898+
init_tracks(num_tracks, tracks, scsi_tracks);
895899

896900
num = RANGE(num, 1, 32);
897901

898-
return sys_storage_ext_mount_ps2_discfile(num, files, 1, scsi_tracks);
902+
return sys_storage_ext_mount_ps2_discfile(num, files, num_tracks, scsi_tracks);
899903
}
900904

901905
int cobra_umount_disc_image(void)

_Projects_/wm_proxy/cobra/cobra.h

+14-18
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ enum DiscEmu
2222
EMU_GAMEI, // not a DiscEmu
2323
};
2424

25-
#ifdef COBRA_ONLY
26-
2725
enum DiscType
2826
{
2927
DISC_TYPE_NONE, /* No disc inserted */
@@ -132,7 +130,7 @@ typedef struct
132130
u8 reserved1 : 7;
133131
} __attribute__((packed)) DiscPhysInfo;
134132
*/
135-
133+
/*
136134
typedef struct
137135
{
138136
u16 size;
@@ -161,7 +159,7 @@ typedef struct
161159
u8 auto_earth; // deprecated
162160
u8 auto_dev_blind; // 1 = Allow auto-mount /dev_blind | 0 = Does not allow auto-mount /dev_blind
163161
} __attribute__((packed)) CobraConfig;
164-
162+
*/
165163

166164
/*
167165
* Inits the cobra library. Call this function before any other
@@ -228,7 +226,7 @@ int cobra_get_disc_type(unsigned int *real_disctype, unsigned int *effective_dis
228226
*
229227
* Remarks: call this function only when necessary, e.g. when you detect a disc change.
230228
*/
231-
int cobra_disc_auth(void);
229+
//int cobra_disc_auth(void);
232230

233231

234232
/*
@@ -370,7 +368,7 @@ int cobra_mount_bd_disc_image(char *files[], unsigned int num);
370368
* See readme about how to properly mount an iso and specific details about psx.
371369
*/
372370
//int cobra_mount_psx_disc_image_iso(char *file, TrackDef *tracks, unsigned int num_tracks);
373-
int cobra_mount_psx_disc_image(char *file);
371+
int cobra_mount_psx_disc_image(char *file, TrackDef *tracks, unsigned int num_tracks);
374372

375373

376374
/*
@@ -395,7 +393,7 @@ int cobra_mount_psx_disc_image(char *file);
395393
*
396394
* See readme about how to properly mount an iso.
397395
*/
398-
int cobra_mount_ps2_disc_image(char *files[], int num);
396+
int cobra_mount_ps2_disc_image(char *files[], int num, TrackDef *tracks, unsigned int num_tracks);
399397

400398

401399
/*
@@ -633,7 +631,7 @@ int cobra_map_game(const char *path, const char *title_id, int use_app_home);
633631
* Upon success, the file in icon_save_path will have the psp icon and the icon of psp launcher is mapped to it.
634632
* This function allocates temporally a 512 KB buffer, so at least that memory should be available
635633
*/
636-
int cobra_set_psp_umd(char *path, char *umd_root, char *icon_save_path);
634+
//int cobra_set_psp_umd(char *path, char *umd_root, char *icon_save_path);
637635

638636
/*
639637
* Sets the umd iso for psp emulation and sets the apropiated emulation parameters.
@@ -673,7 +671,7 @@ int cobra_set_psp_umd(char *path, char *umd_root, char *icon_save_path);
673671
*
674672
* Additional info: the function succeeds even if there is no psp iso set.
675673
*/
676-
int cobra_unset_psp_umd(void);
674+
//int cobra_unset_psp_umd(void);
677675

678676

679677
/*
@@ -697,7 +695,7 @@ int cobra_unset_psp_umd(void);
697695
* >= 0 -> the emu type, one of PS2EmuType
698696
* Other -> error from the kernel
699697
*/
700-
int cobra_get_ps2_emu_type(void);
698+
//int cobra_get_ps2_emu_type(void);
701699

702700

703701
/*
@@ -711,7 +709,7 @@ int cobra_get_ps2_emu_type(void);
711709
* ENOSYS -> not in cobra
712710
*/
713711
//int cobra_get_version(u16 *cobra_version, u16 *ps3_version);
714-
int sys_get_version2(u16 *version);
712+
//int sys_get_version2(u16 *version);
715713

716714
/*
717715
* Reads the cobra configuration from RAM cache.
@@ -725,7 +723,7 @@ int sys_get_version2(u16 *version);
725723
*
726724
* Additional info: this function succeeds regardless of cobra device being present or not.
727725
*/
728-
int cobra_read_config(CobraConfig *cfg);
726+
//int cobra_read_config(CobraConfig *cfg);
729727

730728

731729
/*
@@ -739,7 +737,7 @@ int cobra_read_config(CobraConfig *cfg);
739737
*
740738
* Additional info: currently, none of the config fields requires a ps3 reboot to be effective.
741739
*/
742-
int cobra_write_config(CobraConfig *cfg);
740+
//int cobra_write_config(CobraConfig *cfg);
743741

744742

745743
/*
@@ -787,7 +785,7 @@ int cobra_write_config(CobraConfig *cfg);
787785
* EKRESOURCE -> a module is already loaded at that slot
788786
* Other -> error from kernel (invalid prx, etc)
789787
*/
790-
int cobra_load_vsh_plugin(unsigned int slot, const char *path, void *arg, u32 arg_size);
788+
//int cobra_load_vsh_plugin(unsigned int slot, const char *path, void *arg, u32 arg_size);
791789

792790

793791
/*
@@ -801,9 +799,9 @@ int cobra_load_vsh_plugin(unsigned int slot, const char *path, void *arg, u32 ar
801799
* EINVAL -> invalid slot
802800
* ENOENT -> there is no module loaded in that slot.
803801
*/
804-
int cobra_unload_vsh_plugin(unsigned int slot);
802+
//int cobra_unload_vsh_plugin(unsigned int slot);
805803

806-
void map_app_home(const char *path);
804+
//void map_app_home(const char *path);
807805

808806
#define MAX_TRACKS 98 // game with most tracks (97) is SLUS-01208 - Sabrina the Teenage Witch: A Twitch in Time!
809807

@@ -812,5 +810,3 @@ void map_app_home(const char *path);
812810
#endif
813811

814812
#endif /* _COBRA_H */
815-
816-
#endif //#ifdef COBRA_ONLY

_Projects_/wm_proxy/cue_file.h

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#define NONE -1
2+
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
3+
#define MAX_LINE_LEN 640 // html games
4+
5+
extern char *stdc_73EAE03D(const char *s, int c); // strrchr()
6+
char* strrchr(const char *s, int c) {if(!s) return NULL; return stdc_73EAE03D(s, c);}
7+
8+
static int parse_lba(const char *templn, int ret_value)
9+
{
10+
char *time = strrchr(templn, ' '); if(!time) return ret_value;
11+
char tcode[10]; // mm:ss:ff
12+
13+
memcpy(tcode, time + 1, 8); tcode[8] = '\0';
14+
if(tcode[2]!=':' || tcode[5]!=':') return ret_value;
15+
16+
unsigned int tmin, tsec, tfrm;
17+
tmin = (tcode[0] & 0x0F)*10 + (tcode[1] & 0x0F); // 0-98
18+
tsec = (tcode[3] & 0x0F)*10 + (tcode[4] & 0x0F); // 0-59
19+
tfrm = (tcode[6] & 0x0F)*10 + (tcode[7] & 0x0F); // 0-74
20+
21+
return ((((tmin * 60) + tsec) * 75) + tfrm); // msf_to_lba
22+
}
23+
24+
static int get_line(char *templn, const char *cue_buf, const int buf_size, const int start)
25+
{
26+
int l = 0;
27+
int len = MIN(buf_size, MAX_LINE_LEN);
28+
29+
int lp = start;
30+
bool eol = false;
31+
32+
for(; lp < buf_size; lp++)
33+
{
34+
if(!cue_buf[lp]) break;
35+
36+
if(cue_buf[lp] != '\n' && cue_buf[lp] != '\r')
37+
{
38+
if(eol) break;
39+
if(l < len) templn[l++] = cue_buf[lp];
40+
}
41+
else
42+
eol = true;
43+
}
44+
45+
templn[l] = '\0';
46+
47+
if(l) return lp;
48+
49+
return NONE;
50+
}
51+
52+
static unsigned int parse_cue(char *templn, const char *cue_buf, const int cue_size, TrackDef *tracks)
53+
{
54+
if(!cue_buf || !templn || !tracks) return 1; // default 1 track
55+
56+
unsigned int num_tracks = 0;
57+
58+
tracks[0].lba = 0;
59+
tracks[0].is_audio = 0;
60+
61+
if(cue_size > 16)
62+
{
63+
int lba, lp = 0, off = 0, len;
64+
65+
int pregap = 0;
66+
67+
while(lp < cue_size)
68+
{
69+
lp = get_line(templn, cue_buf, cue_size, lp);
70+
71+
if(lp < 1) break;
72+
if(*templn == NULL) continue;
73+
74+
lba = NONE;
75+
76+
//if(strstr(templn, "INDEX 1=")) lba = get_valuen32(templn, "INDEX 1="); else // ccd frames
77+
if(strstr(templn, "INDEX 01") || strstr(templn, "INDEX 1 "))
78+
{
79+
len = lba = parse_lba(templn, -1); // cue msf
80+
if((lba < off) || !num_tracks)
81+
lba = off + pregap; // INDEX 01 is a track length, instead of lba in msf
82+
else
83+
len = 0; // INDEX 01 is absolute LBA in MSF
84+
off = lba + len;
85+
}
86+
87+
if(lba < 0) continue;
88+
89+
if(num_tracks)
90+
{
91+
tracks[num_tracks].lba = lba;
92+
tracks[num_tracks].is_audio = 1;
93+
}
94+
95+
pregap = 150; // (2 * 75) -> 2 secs * 75 frames/sec
96+
97+
num_tracks++; if(num_tracks >= MAX_TRACKS) break;
98+
}
99+
}
100+
101+
if(!num_tracks) num_tracks++;
102+
103+
return num_tracks;
104+
}
105+
106+
static int read_cue(char *path, TrackDef *tracks)
107+
{
108+
char cue_buf[4096];
109+
u64 cue_size = 0;
110+
111+
int fd;
112+
if(cellFsOpen(path, CELL_FS_O_RDONLY, &fd, NULL, 0) == CELL_FS_SUCCEEDED)
113+
{
114+
if(cellFsRead(fd, (void *)cue_buf, 4096, &cue_size) != CELL_FS_SUCCEEDED) cue_size = 0;
115+
cellFsClose(fd);
116+
117+
return parse_cue(path, cue_buf, cue_size, tracks);
118+
}
119+
else
120+
return 0;
121+
}

0 commit comments

Comments
 (0)