Handling Files on PS2
Handling Files on PS2
I was creating a very simple SDL program that tries to load a png file and show it, but then it hit me: looks like PS2 filesystem is not so easy that using picture = IMG_Load("./img.png"); works :-P
So, it seems like I have to somehow use mass: (I'm running the code form a USB pendrive) or semething like that...
Are there any instructions or tutorials for begginers on this filesystem behavior?
Thanks in advance.
So, it seems like I have to somehow use mass: (I'm running the code form a USB pendrive) or semething like that...
Are there any instructions or tutorials for begginers on this filesystem behavior?
Thanks in advance.
The prefix you are refering to is the device string. When accessing files you prefix the filename with the devices string to tell the PS2 which device you want load the file from. This makes it much simpler to access files on different devices, as you always use the same functions.
For instance when access files on your PC when using PS2Link, you use the "host:" prefix, eg. "host:file.txt". The way this works is that you load a device driver (module/IRX) on the IOP and it adds the device string to the file system. This is your interface to the files on the device.
The only devices which are loaded by default are "cdrom0:" (CD/DVD drive access) and "rom0:" (access to BIOS files). Which are both read only.
- PS2Link adds "host:" (read and write).
- The "rom0:MCMAN" module add "mc0:" and "mc1:", memory card 1 and 2 respectively (read and write).
- The usb_mass.irx adds "mass:" which gives you access to the USB mass storage devices such as pendrive/usbsticks (read and write).
- The HDD IRXs in PS2SDK add "hdd0:" support (read and write).
There might be more devies, these are just the ones I can remember off the top of my head.
You just need to load the correct IRX (and any IRXs it is dependent on in the correct order) and you can then access files on the device.
For instance when access files on your PC when using PS2Link, you use the "host:" prefix, eg. "host:file.txt". The way this works is that you load a device driver (module/IRX) on the IOP and it adds the device string to the file system. This is your interface to the files on the device.
The only devices which are loaded by default are "cdrom0:" (CD/DVD drive access) and "rom0:" (access to BIOS files). Which are both read only.
- PS2Link adds "host:" (read and write).
- The "rom0:MCMAN" module add "mc0:" and "mc1:", memory card 1 and 2 respectively (read and write).
- The usb_mass.irx adds "mass:" which gives you access to the USB mass storage devices such as pendrive/usbsticks (read and write).
- The HDD IRXs in PS2SDK add "hdd0:" support (read and write).
There might be more devies, these are just the ones I can remember off the top of my head.
You just need to load the correct IRX (and any IRXs it is dependent on in the correct order) and you can then access files on the device.
IRX are just IOP Relocatable eXecutable or just programs for the IOP :-)
There is some in depth IRX information available here:
http://ps2dev.org/ps2/Tutorials/TUTORIA ... _Processor
There is some in depth IRX information available here:
http://ps2dev.org/ps2/Tutorials/TUTORIA ... _Processor
Just another quick question:
I noticed in most examples that there is a kind of order for loading IRX. For example, first the ones from BIOS, then the ones from memory card (as mass). In this case you need to place the irx files in your memory card, right?
So, how some standalone programs such as uLaunchELF and Doom can run, and read files from the mass even without having a CD or Memory Cards inserted? Is there a way to embed, or statiacly link the IRX files?
PS: Sorry if this was already answered, I searched a lot before posting :)
I noticed in most examples that there is a kind of order for loading IRX. For example, first the ones from BIOS, then the ones from memory card (as mass). In this case you need to place the irx files in your memory card, right?
So, how some standalone programs such as uLaunchELF and Doom can run, and read files from the mass even without having a CD or Memory Cards inserted? Is there a way to embed, or statiacly link the IRX files?
PS: Sorry if this was already answered, I searched a lot before posting :)
try checking how ulaunchelf does this, since it has integrated usb driver (but it can use external one, as well). everything is packed together into a single executable.So, how some standalone programs such as uLaunchELF and Doom can run, and read files from the mass even without having a CD or Memory Cards inserted? Is there a way to embed, or statiacly link the IRX files?
as far as mc/dvd/cd access goes - when ps2 bios runs an application, required cd and mc modules are most likely already loaded and active. application either relies on them, or loads its own replacement modules off those media.
Yes, I'm trying, but ps2dev.org is down, so I can't see the code right now.
But searching on the net, I found they just placed the soruce code of the usb irx driver into their code. This is the hard way IMHO.
But the doom port has, for example, integrated the wad file into the elf somehow, so it probally can be done also for the IRX binary.
But searching on the net, I found they just placed the soruce code of the usb irx driver into their code. This is the hard way IMHO.
But the doom port has, for example, integrated the wad file into the elf somehow, so it probally can be done also for the IRX binary.
-
- Posts: 202
- Joined: Wed Aug 09, 2006 1:00 am
You define a rule to convert the irx module into a data buffer in assembly or C using bin2s or bin2c for embedding into the project. The command is:
For example, using iomanX.irx, you would add iomanX_irx.o to your EE_OBJS variable in your makefile.
Add this rule to your makefile as well:Alternatively, using bin2c, the rule would be:This will give you a .s or .c file containing the iomanX.irx buffer called iomanX_irx and a global integer for the size of it called size_iomanX_irx.
Then in the source file where you load modules you would have:And in the function that you load the module:This is how uLE does it, except they use a void type for the symbol names.
The explanation is a little explicit but it might help other people who want to do the same :D.
Code: Select all
bin2s <infile> <outfile> <symbol>
Add this rule to your makefile as well:
Code: Select all
iomanX_irx.s:
bin2s $(PS2SDK)/iop/irx/iomanX.irx iomanX_irx.s iomanX_irx
Code: Select all
iomanX_irx.c:
bin2c $(PS2SDK)/iop/irx/iomanX.irx iomanX_irx.c iomanX_irx
Then in the source file where you load modules you would have:
Code: Select all
extern char iomanX_irx;
extern int size_iomanX_irx;
Code: Select all
int ret;
ret = SifExecModuleBuffer(&iomanX_irx, size_iomanX_irx, 0, NULL, &ret);
The explanation is a little explicit but it might help other people who want to do the same :D.
Yes, great to have all the info in one place.
Thanks a lot ragnarok :)
This shold solve my distribution problems, so I now can start developing SDL apps for PS2 without major problems. Just need to test image and ttf loading later tonight and I'm done. It was a while since I had this fun developing, HTML/Javascript/PHP just drain your energies after a while ;)
Thanks a lot ragnarok :)
This shold solve my distribution problems, so I now can start developing SDL apps for PS2 without major problems. Just need to test image and ttf loading later tonight and I'm done. It was a while since I had this fun developing, HTML/Javascript/PHP just drain your energies after a while ;)
For some reason I can't load files from mass, from mc0 it seems to work fine, exept SDL IMG_Load does not work giving a "Can't seek data" error, but this is expecting as memory card probally does not support seek.
Here is my code, image.c
ps2_modules.h:
Any help is accepted :)
Here is my code, image.c
Code: Select all
/* Simple program: Loop, watching keystrokes
Note that you need to call SDL_PollEvent() or SDL_WaitEvent() to
pump the event loop and catch keystrokes.
*/
#include "ps2_modules.h"
#include <SDL.h>
#include <SDL/SDL_image.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
#define DEPTH 32
int main(int argc, char* argv[])
{
SDL_Surface *screen;
SDL_Surface *picture;
SDL_Rect pictureLocation;
SDL_Event event;
int keypress = 0;
//int h=0;
SifResetIop();
init_scr();
scr_printf("Hello, world!\n");
// init IOP modules
loadMinimal();
pictureLocation.x = 0;
pictureLocation.y = 0;
picture = IMG_Load("mass:sles11_3.JPG");
if (!picture) {
scr_printf("IMG_Load 1: %s\n", IMG_GetError());
picture = IMG_Load("mc0:sles11_3.JPG");
if (!picture) {
scr_printf("IMG_Load 2: %s\n", IMG_GetError());
} else {
scr_printf("IMG_Load 2: OK\n");
}
while (1) {}
} else {
if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_HWSURFACE))) {
SDL_Quit();
return 1;
}
while(!keypress) {
//DrawScreen(screen,h++);
SDL_BlitSurface(picture, NULL, screen, &pictureLocation);
if (!picture) {
//SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 255, 0));
}
SDL_Flip(screen);
//SDL_Delay(500);
while(SDL_PollEvent(&event)) {
switch (event.type)
{
case SDL_QUIT:
keypress = 1;
break;
case SDL_KEYDOWN:
keypress = 1;
break;
}
}
}
SDL_Quit();
}
return 0;
}
Code: Select all
#ifndef __PS2SDK_1_1__
#include <stdio.h>
#endif
#include <tamtypes.h>
#include <sifrpc.h>
#include <kernel.h>
#include <loadfile.h>
#include <fileio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <debug.h>
#include <iopcontrol.h>
void loadMinimal() {
int ret;
ret = SifLoadModule("rom0:SIO2MAN", 0, NULL);
ret = SifLoadModule("rom0:MCMAN", 0, NULL);
if (ret < 0) {
scr_printf("Error '%d' loading module rom0:MCMAN\n", ret);
} else {
scr_printf("Module rom0:MCMAN loaded\n");
}
ret = SifLoadModule("rom0:MCSERV", 0, NULL);
ret = SifLoadModule("rom0:PADMAN", 0, NULL);
ret = SifLoadModule("rom0:IOMAN", 0, NULL);
//mcInit(MC_TYPE_MC);
ret = SifLoadModule("mc0:usbd.irx", 0, NULL);
if (ret < 0) {
scr_printf("Error '%d' loading module mc0:usbd.irx\n", ret);
} else {
scr_printf("Module mc0:usbd.irx loaded\n");
}
}
Tip for anyone looking here in the future, IMG_load does not work, it seems like there is a bug or hardware/software restrictions with fseek, so use this instead:
Now I'm going to look what to do to avoid this fseek bug when doing a fopen operation...
PS: Already got a image to show in the screem very fun!
Code: Select all
SDL_RWops *rwop;
SDL_Surface *img;
char filename[50];
sprintf(filename, "mass:/myfile.png");
rwop=SDL_RWFromFile(filename, "rb");
if (!rwop) {
PRINTOUT("Error in build_pallete: '%s' file not found\n", filename);
}
img=IMG_LoadPNG_RW(rwop);
PS: Already got a image to show in the screem very fun!
More information/bugs:
SDL_HWSURFACE crashes when using SDL_CreateRGBSurface, use SDL_SWSURFACE instead and it will work.
SDL_SetColorKey does not seem to be working.
Already compiled my basic code and solved almost all problems (the colorkey transparency will really give me problems), now I'm going to add joystick code to move sprites in the screen. :)
SDL_HWSURFACE crashes when using SDL_CreateRGBSurface, use SDL_SWSURFACE instead and it will work.
SDL_SetColorKey does not seem to be working.
Already compiled my basic code and solved almost all problems (the colorkey transparency will really give me problems), now I'm going to add joystick code to move sprites in the screen. :)
-
- Posts: 202
- Joined: Wed Aug 09, 2006 1:00 am
ps2sdk has had a few bugs with fseek. The last bug, hopefully, was fixed in revision 1509. From looking at SDL's source, it's probably fseek returning -1 on seeking offset 0 and/or ftell returning the wrong offset, too, which was fixed in revision 1509 as well. I don't see anything else that would be wrong. The crt0.s was also modified recently so that argument parsing would work and ps2sdk's libc would be initialized properly. The latest revision should work just fine, :D.
EDIT: Just after posting, found resetIOP seems to fix the problem.
Thanks ragnarok, updating the SDK and recompiling all my libs really helped a lot.
But I believe I found a real and nasty bug:
When loading SIO2MAN using ret = SifLoadModule("rom0:SIO2MAN", 0, NULL); and also loading Joystick in SDL by using SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) the screen goes black, no matter what.
Sadly I no not have a ps2link, so debugging this is uout of my hands :-(
Is there a alternative to SIO2MAN? I need it to fopen and mass to load some image files :-(
I searched doom sdl port and noticed it does not load those Bios modules, but still did not had the time to see what they are doing.
Thanks ragnarok, updating the SDK and recompiling all my libs really helped a lot.
But I believe I found a real and nasty bug:
When loading SIO2MAN using ret = SifLoadModule("rom0:SIO2MAN", 0, NULL); and also loading Joystick in SDL by using SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) the screen goes black, no matter what.
Sadly I no not have a ps2link, so debugging this is uout of my hands :-(
Is there a alternative to SIO2MAN? I need it to fopen and mass to load some image files :-(
I searched doom sdl port and noticed it does not load those Bios modules, but still did not had the time to see what they are doing.
Theres the freesio2.irx from the ps2sdk that can be used as a replacement.protomank wrote:
Is there a alternative to SIO2MAN? I need it to fopen and mass to load some image files :-(
I searched doom sdl port and noticed it does not load those Bios modules, but still did not had the time to see what they are doing.
Then there´s the xsio2man from the bios. maybe that one is needed to avoid the bug. I´m a beginner in ps2 programming so I´m not sure of the differences between the 2 but I think the xsio2man is the newer module
Doom does load the modules but I have no idea where the code is that loads it. Cosmito said the SDL does the initializing but I couldn´t find where.
Cosmito or Lukasz will have to answer that question.
bye
Yes, I just tested it after a break to play god of war (because I was programming for more than 6 hours when I realized, heheheh) and worked, just changed all rom drivers/irx to X, and worked like a charm.
Transparency I got fixed by using it in the png files itselves, instead of opening and trying to set it in SDL.
Joystick was a bit trick because most of the examples I found using events just did not worked, now using SDL_JoystickUpdate+SDL_JoystickGetButton it works fine, I made a rectangle grow when pessing the square button :D
[ok, this is silly, but I'm proud of it]
Next step is to use SDL_ttf so debugging the program will be WAY easier, and setting a subversion to store the code so other people can use or research.
At the pace things are going, looks like I'll have to start working on the level editor and got some free graphics soon.
Transparency I got fixed by using it in the png files itselves, instead of opening and trying to set it in SDL.
Joystick was a bit trick because most of the examples I found using events just did not worked, now using SDL_JoystickUpdate+SDL_JoystickGetButton it works fine, I made a rectangle grow when pessing the square button :D
[ok, this is silly, but I'm proud of it]
Next step is to use SDL_ttf so debugging the program will be WAY easier, and setting a subversion to store the code so other people can use or research.
At the pace things are going, looks like I'll have to start working on the level editor and got some free graphics soon.
Sorry I only saw your post now :Sprotomank wrote:EDIT: Just after posting, found resetIOP seems to fix the problem.
Thanks ragnarok, updating the SDK and recompiling all my libs really helped a lot.
But I believe I found a real and nasty bug:
When loading SIO2MAN using ret = SifLoadModule("rom0:SIO2MAN", 0, NULL); and also loading Joystick in SDL by using SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) the screen goes black, no matter what.
Sadly I no not have a ps2link, so debugging this is uout of my hands :-(
Is there a alternative to SIO2MAN? I need it to fopen and mass to load some image files :-(
I searched doom sdl port and noticed it does not load those Bios modules, but still did not had the time to see what they are doing.
For loading stuff from mass: you need to load the usbd.irx and usbhdfsd.irx IOP modules. From the ps2doom sources you can see how to embbed these modules into source files and so including them into the ELF file. the
Code: Select all
// USB mass support
SifExecModuleBuffer(usbd, size_usbd, 0, NULL, &ret);
SifExecModuleBuffer(usbhdfsd, size_usbhdfsd, 0, NULL, &ret);
Yes that would be handy, at least for me as I'm starting using SDL at the PS2 and I'd prefer not to go through the same issues as you did.protomank wrote:Next step is to use SDL_ttf so debugging the program will be WAY easier, and setting a subversion to store the code so other people can use or research.
Currently there's a Patch Submissions section but if you're out of free time to create the patches, you might consider publish the mod sources to a free svn service like assembla.com (or google code although it's more suitable for complete projects and it forces you to pick a software license).