forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Adhoc Receiving Data

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Sp3ct0r



Joined: 16 Apr 2008
Posts: 3

PostPosted: Thu Apr 17, 2008 11:15 am    Post subject: Adhoc Receiving Data Reply with quote

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
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
Smong



Joined: 04 Sep 2007
Posts: 82

PostPosted: Thu Apr 17, 2008 6:27 pm    Post subject: Reply with quote

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
View user's profile Send private message
Sp3ct0r



Joined: 16 Apr 2008
Posts: 3

PostPosted: Thu Apr 17, 2008 7:29 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
Smong



Joined: 04 Sep 2007
Posts: 82

PostPosted: Thu Apr 17, 2008 9:37 pm    Post subject: Reply with quote

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
View user's profile Send private message
pspZorba



Joined: 22 Sep 2007
Posts: 156
Location: NY

PostPosted: Thu Apr 17, 2008 9:57 pm    Post subject: Reply with quote

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
View user's profile Send private message
Smong



Joined: 04 Sep 2007
Posts: 82

PostPosted: Thu Apr 17, 2008 10:03 pm    Post subject: Reply with quote

Thanks for that clarification.

I went back and edited my original example and also fixed another bug I just noticed.
_________________
(+[__]%)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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