 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Sp3ct0r
Joined: 16 Apr 2008 Posts: 3
|
Posted: Thu Apr 17, 2008 11:15 am Post subject: Adhoc Receiving Data |
|
|
Hey, I'm creating an Adhoc compatible game for PSP using pspZorba's 3.xx compatible adhoc example. I've got it working right...however I am having trouble sending multiple variables. The PSP's are constantly sending and receiving data from each other, however when you send data, it must be all in a char, and when it is received, it is void type data. So I convert int to char, send it, the other PSP receives it, then converts char to int. This process only allows me to check 1 variable. And of course I need to check things like X, Y, state, current_animation, etc... So I think I need a way to put all these variables into a char array, send them, then receive them and be able to interpret each one as separate variables. I'm not quite sure how to do this...so if anyone can help me I would greatly appreciate it. Thanks. :P
| Code: | #include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspsdk.h>
#include <pspdisplay.h>
#include "ZBadhoc.h"
#include <oslib/oslib.h>
#include <string>
/* Define the module info section */
#define MY_HOMEBREW_MAJOR_VERSION 0
#define MY_HOMEBREW_MINOR_VERSION 42
//PSP_MODULE_USER
//PSP_MODULE_KERNEL
PSP_MODULE_INFO("SMBC", PSP_MODULE_USER, MY_HOMEBREW_MAJOR_VERSION, MY_HOMEBREW_MINOR_VERSION);
PSP_HEAP_SIZE_MAX();
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
OSL_IMAGE *player_img;
/**Ad-Hoc Only Variables**/
int sceInit(void);
int send; //Data Sent And Received
int receive;
int encore=1; //Adhoc Enabled
ZBremotePsp * pPsp; //Stores Mac Address Of Other PSP
int user; //Host = 1 Guest = 2
int init; //Mode Initiation Variable
char buffer[42+1];
char data[50];
int state = 1;
/**^^^^^^^^^^^^^^^^^^^^^**/
/**OSLIB STUFF**/
int initOSLib(){
oslInit(0);
oslInitGfx(OSL_PF_8888, 1);
oslInitAudio();
oslSetQuitOnLoadFailure(1);
oslSetKeyAutorepeatInit(40);
oslSetKeyAutorepeatInterval(10);
return 0;
}
int endOSLib(){
oslEndGfx();
osl_quit = 1;
return 0;
}
/**^^^^^^^^^^^**/
typedef struct {
int x,y;
int state;
OSL_IMAGE *img;
}Player1;
Player1 p1;
typedef struct {
int x,y;
int state;
OSL_IMAGE *img;
}Player2;
Player2 p2;
void LoadImages(), DrawImages();
//char to int function
bool string2int(char* digit, int& result) {
result = 0;
//--- Convert each digit char and add into result.
while (*digit >= '0' && *digit <='9') {
result = (result * 10) + (*digit - '0');
digit++;
}
//--- Check that there were no non-digits at end.
if (*digit != 0) {
return false;
}
return true;
}
int main( void)
{
scePowerSetClockFrequency(333, 333, 166); //Overclock to full potential
sceInit(); //set exit callback
pspDebugScreenInit();
sceKernelDelayThread(1000 * 1000); //1 Second Delay
//init everything
ZBadhoc::getSingleton();
SceCtrlData pad;
pspDebugScreenClear();
while(encore)
{
if (!user) //If The Player Hasn't Chosen To Host Or To Join
{
pspDebugScreenSetXY(0, 1); //Set Text X & Y
pspDebugScreenPrintf("To Host A Game Press []\n");
pspDebugScreenPrintf("To Join A Game Press /\\\n");
pspDebugScreenPrintf("To Quit Press ()");
}
//what button is pressed
sceDisplayWaitVblankStart();
sceCtrlReadBufferPositive(&pad, 1);
if(pad.Buttons & PSP_CTRL_SQUARE)
{
if (user != 1)
{
user = 1; //Set Player To Host
}
}
if(pad.Buttons & PSP_CTRL_TRIANGLE)
{
if (user != 2) {user = 2;} //Set Player To Guest
}
if(pad.Buttons & PSP_CTRL_CIRCLE) {encore = 0; init = 0; pPsp = 0; user = 0; continue;} //Quit
/**HOST**/
if (user == 1)
{
if (init == 0)
{
pPsp= ZBadhoc::getSingleton().selectAPsp(); //Select A PSP
receive = ZBadhoc::getSingleton().requestConnection(pPsp); //Request Connection
if( pPsp==NULL) {encore = 0; continue;} //If No PSP Is Chosen then Exit
initOSLib();
LoadImages(); //Load Images
init = 1; //End Initiation
}
if (init == 1) //Main Loop After Initiation-
{
/**Main Functions**/
DrawImages();
if (osl_keys->held.right) {p1.x+=4;}
if (osl_keys->held.left) {p1.x-=4;}
if (osl_keys->held.up) {p1.y--;}
if (osl_keys->held.down) {p1.y++;}
/**Ad-Hoc Functions**/
if (receive < 0) {continue;} //If No Signal, then Exit.
sprintf(data,"%i",p1.x); //convert int to char
send = ZBadhoc::getSingleton().sendData(pPsp,data,strlen(data));//send a messge to the other PSP
receive = ZBadhoc::getSingleton().receiveData( pPsp, buffer, 42); //receive data
if (receive > 0) {buffer[receive]=0; string2int(buffer,p2.x);} //convert char to int
receive = 0;
}
}
/**GUEST**/
if (user == 2)
{
if (init == 0)
{
pPsp = ZBadhoc::getSingleton().waitForConnection(); //Wait For Connection
if (pPsp == NULL) {continue;} //If No PSP Is Chosen Then Exit
initOSLib(); //Initiate Old School Library
LoadImages(); //Load Images
init = 1; //End Initiation
}
if (init == 1) //Main Loop After Initiation
{
/**Main Functions**/
DrawImages();
if (osl_keys->held.right) {p2.x+=4;}
if (osl_keys->held.left) {p2.x-=4;}
if (osl_keys->held.up) {p2.y--;}
if (osl_keys->held.down) {p2.y++;}
/**Ad-Hoc Functions**/
if (receive < 0) {continue;} //If No Signal, then Exit.
sprintf(data,"%i",p2.x); //int to char
send = ZBadhoc::getSingleton().sendData(pPsp,data,strlen(data));//send a messge to the other PSP
receive = ZBadhoc::getSingleton().receiveData( pPsp, buffer, 42); //Receive data
if (receive > 0) {buffer[receive]=0; string2int(buffer,p1.x);} //char to int
receive = 0;
}
}
}//end of main while
pspDebugScreenClear();
pspDebugScreenPrintf("Done.");
sceKernelSleepThread();
return 0;
}
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return (int)0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
int sceInit(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
void LoadImages()
{
p1.img = oslLoadImageFilePNG("img.png", OSL_IN_RAM,OSL_PF_5551);
p2.img = oslLoadImageFilePNG("img.png", OSL_IN_RAM,OSL_PF_5551);
}
void DrawImages()
{
oslStartDrawing(); //Start Drawing
oslCls(); //Clear Screen
oslReadKeys(); //Read Input Keys
if (user == 1) {oslDrawImageXY(p2.img,p2.x,p2.y); oslDrawImageXY(p1.img,p1.x,p1.y);}
if (user == 2) {oslDrawImageXY(p1.img,p1.x,p1.y); oslDrawImageXY(p2.img,p2.x,p2.y);}
oslEndDrawing(); //End Drawing
oslAudioVSync(); //Synchronize Audio
oslSyncFrame(); //Synchronize Screen
}
|
|
|
| Back to top |
|
 |
Smong
Joined: 04 Sep 2007 Posts: 82
|
Posted: Thu Apr 17, 2008 6:27 pm Post subject: |
|
|
It would have been helpful if you posted a link to get the pspZorba's adhoc sample, I managed to find ZBadhoc.h in a copy of PSPlorer (link).
This looks like the relevant part of the header.
| Code: | int sendData( ZBremotePsp *pPsp, const void *data, int lenData);// send data to pPsp
int receiveData( ZBremotePsp *pPsp, void *data, int maxLen, int debug=0);// receive data from pPsp |
Additionally buried in the .cpp, not in the .h file I found this:
| Code: | * @return: int
* 0< if error, otherwise the number of bytes that were read
* *************************************************************/
int ZBadhoc::receiveData( ZBremotePsp *pPsp, void *data, int maxLen, int debug) |
This is just a simple exercise in C/C++ programming. One way to deal with network comm's is to use packets, which are represented in code as structs. So here I'm sending the player 1 struct. You don't have to use char's the header file uses void* which can mean you are allowed to use any data type.
| Code: | //sending
sendData(pPsp, &p1, sizeof(Player1));
//receiving
receiveData(pPsp, &p1, sizeof(Player1)); |
However this is only good for testing. In reality you will have many different types of packet so you should receive into a temporary buffer and then determine what type the packet is before using it. Also you don't want to send pointers inside the packets, they won't work at the other end (such as images).
| Code: |
#define MAX_PACKET_LENGTH 500 // may need to increase this
#define PLAYER_PKT 1
#define OTHER_PKT 2
...
typedef struct {
int packettype;
} EmptyPacket;
typedef struct {
int packettype;
int x,y;
int state;
} PlayerPacket;
//sending
PlayerPacket ppkt;
ppkt.packettype = PLAYER_PKT;
ppkt.x = p1.x;
ppkt.y = p1.y;
ppkt.state = p1.state;
// old: sendData(pPsp, &p1, sizeof(PlayerPacket));
sendData(pPsp, &ppkt, sizeof(PlayerPacket)); // edit: fixed version
//receiving
char buf[MAX_PACKET_LENGTH];
int len;
EmptyPacket *pkt;
len = receiveData(pPsp, buf, MAX_PACKET_LENGTH);
pkt = (EmptyPacket*)buf;
if (pkt->packettype == PLAYER_PKT &&
len == sizeof(PlayerPacket))
{
// old: PlayerPacket ppkt = (PlayerPacket*)buf;
PlayerPacket *ppkt = (PlayerPacket*)buf; // edit: fixed version
p1.x = ppkt->x;
p1.y = ppkt->y;
p1.state = ppkt->state;
}
|
Edit:
Fixed the PlayerPacket ppkt/PlayerPacket *ppkt in the sample.
Also noticed another error! When sending,
| Code: | sendData(pPsp, &p1, sizeof(PlayerPacket)); // old version
sendData(pPsp, &ppkt, sizeof(PlayerPacket)); // fixed version |
_________________ (+[__]%)
Last edited by Smong on Thu Apr 17, 2008 10:02 pm; edited 1 time in total |
|
| Back to top |
|
 |
Sp3ct0r
Joined: 16 Apr 2008 Posts: 3
|
Posted: Thu Apr 17, 2008 7:29 pm Post subject: |
|
|
OMG YES!!! Tyvm Smong! :D I was able to send a packet perfectly!!! My only issue was that when i tried to use a temporary buffer to determine the packet type and stuff, it gave me these errors:
error: conversion from ‘PlayerPacket*’ to non-scalar type ‘PlayerPacket’ requested
error: base operand of ‘->’ has non-pointer type ‘PlayerPacket’
however when I just used
| Code: | //sending
sendData(pPsp, &p1, sizeof(Player1));
//receiving
receiveData(pPsp, &p1, sizeof(Player1)); |
It worked flawlessly. |
|
| Back to top |
|
 |
Smong
Joined: 04 Sep 2007 Posts: 82
|
Posted: Thu Apr 17, 2008 9:37 pm Post subject: |
|
|
| Quote: | | error: conversion from ‘PlayerPacket*’ to non-scalar type ‘PlayerPacket’ requested | You have to look at the hint. One has a * the other doesn't. Here's the fix:
| Code: | //old
PlayerPacket ppkt = (PlayerPacket*)buf;
//fixed
PlayerPacket *ppkt = (PlayerPacket*)buf;
|
And if anyone else is reading this thread I just found the adhoc code you were referring to here:
http://forums.ps2dev.org/viewtopic.php?p=67549#67549
It's not exactly identical to the PSPlorer version, but similar. _________________ (+[__]%) |
|
| Back to top |
|
 |
pspZorba
Joined: 22 Sep 2007 Posts: 156 Location: NY
|
Posted: Thu Apr 17, 2008 9:57 pm Post subject: |
|
|
the first thread was some tests I made to understand how it works. The other code (from PSPlorer) is just a little bit more recent. _________________ --pspZorba--
NO to K1.5 ! |
|
| Back to top |
|
 |
Smong
Joined: 04 Sep 2007 Posts: 82
|
Posted: Thu Apr 17, 2008 10:03 pm Post subject: |
|
|
Thanks for that clarification.
I went back and edited my original example and also fixed another bug I just noticed. _________________ (+[__]%) |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|