Thursday, July 30, 2020

Basics on the code PART 12

In today's entry we were going to read and compile the prx_loader and the prx_simple, which is about the PRX or Playstation Relocatable Executable. Those are about plugin creation (start and stop modules).

For that goal, you can also look into https://tai.henkaku.xyz/ . And also recommended to read about the SceDisplay  (handles management of the framebuffers), and the SceKernelModulemgr (is in charge of loading both user modules and kernel modules)

However, after reading the sample and trying to compile it (for a whole day with breaks), receiving some errors, warnings and whatnot (yes we check other samples to see if the sdk was gone or something, and we tried to solve some of them). We have decide it to just speak about the failure and let that sample appart.

Explanations: Why let it appart? Are you giving up? Are you doing the same with future similar failures? No, we are not giving up, we let that appart because it is about plugins and we don't need that currently. We can go back there in the future when need it, and we have the taihenkaku web for a more clarified way to do them (also we can figure them out with actual plugins if we need to).

Note: While trying to solve the problems, we look other resources and the other big SDK for the vita. Those are the cbps web (currently with an error 523, Origin is unreachable), and the dolce sdk forum a.k.a cbps forum.

Note 2: The vita sdk and the dolce sdk will be appart in time, but currently (as one is a fork from the other) they have the same samples (they only have different cmakelists to differentiate one sdk name with the other). This is useful to know if we want to make a transition or something (more deep knowledge in the sdk will be used when creating the main project of the blog).

Note 3: It must be stated, that the errors found may or may not be caused by us or by the samples' coding.


Having said that, we want to give a brief overview with 2 images of the compiling:

First we tried to read, understand and compile the prx_loader sample. It gaves us, several errors:

   - Lot of them where undeclared functions
     (caused by the lack of a/some include/s, which should be in one of the header files already included).

prx_loader compiling errors

And Then, we decided to compile the prx_simple as it uses the loader as base and goes further.
That means it should give similar errors and/or we can use it to solve some of them. This one gave less errors, nonetheless it gave them:

   - The first time it gave us only three.

prx_simple with 3 compiling errors


 - we reduced them to two adding one include,  #include <psp2/display.h>

prx_simple with 2 compiling errors





 - After this, it seemed easy to solve (giving types to those variables)
   We look in other files what where their types and added them.

prx_simple with errors on the link part


 - Yet again, although it compiled the first part, it gave us more errors, this time, on the link part.
   Knowing this is mostly kernel related we didn't want to take any risk and stop after more fruitless investigation.

Samples common files & code PART 1

We have seen many code samples about the ps vita's handlement of inputs. and some more about how to show info on screen. Although there are still a few samples with functions unseen, in this entry we are going to review some of the basics. To do this we are going to use some samples we have not seen before, because they would have been overlapped with others samples needlessly.

Note: they may be overlapped with others, but that does not mean they are less important. Many people may have started with them instead.

The specific samples we are going to use for review are:

    common: Common functions for samples.
    debug_print: A minimal debug print sample.
    debugscreen: Debug text printing sample.
    pretty_livearea: A minimal hello world sample with example livearea styling and features.

Note: As we did with the first sample entry, we are going to review the files primarily.

Without further ado, let's start!


SAMPLE "common"

// headers and functions for the screen output. Data formats, and its memory control.
 debugScreen.h
 debugScreen.c

//Like the name says it has the font properties at low-level.
 debugScreenFont.builder.html
 debugScreen_custom.h
 debugScreenFont.c


SAMPLE "debug_print"

 // it basically shows you a printf like the hello_world sample, but with more details (foreground/background colors)
 // to make your debugging more appealing with colors in your printed messages.
 main.c


SAMPLE "debugscreen"

 //  test functions to check stuff on the vita, it has a lot of info about what is shown on screen.
 main.c

SAMPLE "pretty_live area"

// it has the same code as in the hello_world sample. But here you have other 2 images, to know how to make your homebrew more atractive.


-----------

Some screenshots from the samples running on the vita:

pretty_live area

debug_print

debugscreen


And that's all for this entry.

Tuesday, July 28, 2020

Basics on the code PART 11

In this entry we will see how the vita generates sounds. This could be useful when we want warnings or similar things to have sound.

Note: The VM we were using was setup without enough space and "broke", so we will be using another one with ubuntu 20 from now on. The reason of the firmware change is explained in this entry. If your machine have enough space, it is not required to change it.

To help us to understand the functions of this sample, we have to use the vitasdk documentation, for this specific sample we will use the audio section. Also, the the audioout header section.


SAMPLE "audio"

audio: Simple audio wave generator.


#include <stdint.h>
#include <math.h>

#include <psp2/ctrl.h>
#include <psp2/audioout.h>
#include <psp2/kernel/processmgr.h>

#include "debugScreen.h"

// functions to control the frequency changes
#define countof(A) sizeof(A)/sizeof(*A)
#define MIN(A,B) ((A)<(B)?(A):(B))
#define MAX(A,B) ((A)>(B)?(A):(B))

#define printf psvDebugScreenPrintf

// frequency function and its variables based on the button input to change accordingly
double gen_sqr(double p){return p>.5?-1.:1.;}
double gen_tri(double p){return p*2;}
double gen_nul(double p){return 0.;}
double gen_sin(double p){return sin(2*M_PI*p);}

typedef double (*wav_gen)(double);

// audio wave generetator function
void wave_set(int16_t*buffer, size_t size,  wav_gen generator){
    for (size_t smpl = 0; smpl < size; ++smpl)
        buffer[smpl] = 0x7FFF*generator((float)smpl/(float)size);
}

// main program

int main(void) {
    psvDebugScreenInit();


// audio and wave variables during the execution
    int freqs[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000};
    int size = 256;
    int freq = 8;
    int mode = SCE_AUDIO_OUT_MODE_MONO;
    int vol = SCE_AUDIO_VOLUME_0DB;


// current running wave variable
    int port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_BGM, size, freqs[freq], mode);
    sceAudioOutSetVolume(port, SCE_AUDIO_VOLUME_FLAG_L_CH |SCE_AUDIO_VOLUME_FLAG_R_CH, (int[]){vol,vol});


// wave data and its control functions based on the input button in execution time
    int16_t wave_buf[SCE_AUDIO_MAX_LEN]={0};
    wav_gen gen=gen_nul;
    SceCtrlData ctrl_peek, ctrl_press;
    do{
        ctrl_press = ctrl_peek;
        sceCtrlPeekBufferPositive(0, &ctrl_peek, 1);
        ctrl_press.buttons = ctrl_peek.buttons & ~ctrl_press.buttons;

        if(ctrl_press.buttons == SCE_CTRL_CIRCLE)
            gen=gen_sin;
        if(ctrl_press.buttons == SCE_CTRL_SQUARE)
            gen=gen_sqr;
        if(ctrl_press.buttons == SCE_CTRL_TRIANGLE)
            gen=gen_tri;
        if(ctrl_press.buttons == SCE_CTRL_CROSS)
            gen=gen_nul;
        if(ctrl_press.buttons & (SCE_CTRL_CROSS|SCE_CTRL_TRIANGLE|SCE_CTRL_SQUARE|SCE_CTRL_CIRCLE))
            wave_set(wave_buf,size,gen);
          
        if(ctrl_press.buttons == SCE_CTRL_RIGHT)
            freq = MIN(countof(freqs)-1, freq+1);
        if(ctrl_press.buttons == SCE_CTRL_LEFT)
            freq = MAX(0, freq-1);
        if(ctrl_press.buttons == SCE_CTRL_RTRIGGER)
            size = MIN(SCE_AUDIO_MAX_LEN,size+1000);
        if(ctrl_press.buttons == SCE_CTRL_LTRIGGER)
            size = MAX(SCE_AUDIO_MIN_LEN,size-1000);
        if(ctrl_press.buttons & (SCE_CTRL_RIGHT|SCE_CTRL_LEFT|SCE_CTRL_LTRIGGER|SCE_CTRL_RTRIGGER)){
            sceAudioOutSetConfig(port, size, freqs[freq], mode);
            wave_set(wave_buf,size,gen);
        }

        if(ctrl_press.buttons == SCE_CTRL_UP)
            vol = MIN(vol+1024,SCE_AUDIO_VOLUME_0DB);
        if(ctrl_press.buttons == SCE_CTRL_DOWN)
            vol = MAX(vol-1024,0);
        if(ctrl_press.buttons & (SCE_CTRL_UP|SCE_CTRL_DOWN))
            sceAudioOutSetVolume(port, SCE_AUDIO_VOLUME_FLAG_L_CH |SCE_AUDIO_VOLUME_FLAG_R_CH, (int[]){vol,vol});

        sceAudioOutOutput(port, wave_buf);
        printf("freq:%-5i size:%-5i vol:%-5i  wave:{%+6i..%+6i..%6i..%+6i }\r",
                freqs[freq], size, vol, wave_buf[0*size/4], wave_buf[1*size/4], wave_buf[2*size/4], wave_buf[3*size/4]);//\e[H
    }while(ctrl_press.buttons != SCE_CTRL_START); // // sample loop for testing until start button is pressed


    sceAudioOutReleasePort(port);
    sceKernelExitProcess(0);
    return 0;
}


-----------

Some screenshots from the sample running on the vita:

Basic screen before any input

Wave stopped (after being running)

One posible running wave

And that's all for this sample.

Sunday, July 26, 2020

Basics on the code PART 10

Today we are going to read the sample about the ps vita's camera features

To help us to understand the functions we have to use the vitasdk documentation, for this specific sample we will use the camera section.

SAMPLE "camera"

camera: Demonstration of camera features.


#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/display.h>
#include <psp2/ctrl.h>
#include <psp2/camera.h>
#include <psp2/kernel/processmgr.h>

// screen memory allocation variables
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
#define DISPLAY_WIDTH 640
#define DISPLAY_HEIGHT 368

// main program

int main(void){
    void* base;

// memory allocation for the camera buffer
    SceUID memblock = sceKernelAllocMemBlock("camera", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, 256 * 1024 * 5, NULL);
    sceKernelGetMemBlockBase(memblock, &base);

    SceDisplayFrameBuf dbuf = { sizeof(SceDisplayFrameBuf), base, DISPLAY_WIDTH, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT};


    int cur_res = 1;// 1-8 (maybe more)
    int cur_cam = 0;//front:0, back:1
    int cur_fps = 6;
    int cur_fmt = 5;

// set sample mode
    sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);
    SceCtrlData ctrl_peek;SceCtrlData ctrl_press;

// basics options variables about the data info of the pictures
    do{
        int cur_sat=0,cur_rev=0,cur_efx=0,cur_iso=0,cur_zom=10,cur_nim=0,cur_wbl=0;
        size_t res_table[][2] = {{0,0},{640,480},{320,240},{160,120},{352,288},{176,144},{480,272},{640,360},{640,360}};
        size_t fps_table[] = {3,5,7,10,15,20,30};
        sceCameraOpen(cur_cam, &(SceCameraInfo){
            .size = sizeof(SceCameraInfo),
            .format = cur_fmt,//422_TO_ABGR
            .resolution = cur_res,
            .framerate = fps_table[cur_fps],
            .sizeIBase = 4*res_table[cur_res][0]*res_table[cur_res][1],
            .pitch     = 4*(DISPLAY_WIDTH-res_table[cur_res][0]),
            .pIBase = base,
        });


        sceCameraStart(cur_cam); // start the camera

        // setting camera features and commanidng buttons
        do{
            ctrl_press = ctrl_peek;
            sceCtrlPeekBufferPositive(0, &ctrl_peek, 1);
            ctrl_press.buttons = ctrl_peek.buttons & ~ctrl_press.buttons;
           
            sceCameraSetBrightness(cur_cam, ctrl_press.rx);
            sceCameraSetContrast(cur_cam, ctrl_press.ry-100);
            sceCameraSetEV(cur_cam, (ctrl_press.lx-128)/7);//-20...20
            sceCameraSetGain(cur_cam, (ctrl_press.ly<100)?ctrl_press.ly/6:0);//0..16 //don't seem to work
            if(ctrl_press.buttons & SCE_CTRL_TRIANGLE)
                sceCameraSetSaturation(cur_cam,   cur_sat=((cur_sat+5)%45));
            if(ctrl_press.buttons & SCE_CTRL_CIRCLE)
                sceCameraSetReverse(cur_cam,      cur_rev=((cur_rev+1)%4));
            if(ctrl_press.buttons & SCE_CTRL_CROSS)
                sceCameraSetISO(cur_cam,(int[]){1,100,200,400}[cur_iso=((cur_iso+1)%4)]);
            if(ctrl_press.buttons & SCE_CTRL_SQUARE)
                sceCameraSetEffect(cur_cam,       cur_efx=((cur_efx+1)%7));
            if(ctrl_press.buttons & SCE_CTRL_LTRIGGER)
                sceCameraSetWhiteBalance(cur_cam, cur_wbl=((cur_wbl+1)%4));
            if(ctrl_press.buttons & SCE_CTRL_RTRIGGER)
                sceCameraSetNightmode(cur_cam,    cur_nim=((cur_nim+1)%4));
            if(ctrl_press.buttons & SCE_CTRL_SELECT)
                sceCameraSetZoom(cur_cam,         cur_zom=((cur_zom+1)%41));

            /* TODO: find more button combo to trigg :
                sceCameraSetAntiFlicker(int cur_cam, int mode);
                sceCameraSetBacklight(int cur_cam, int mode);
            */

//
            if(sceCameraIsActive(cur_cam)>0){
                SceCameraRead read = {sizeof(SceCameraRead),0/*<Blocking*/};
                sceCameraRead(cur_cam, &read);
                sceDisplaySetFrameBuf(&dbuf, SCE_DISPLAY_SETBUF_NEXTFRAME);
            }

// actual testing functions and comunicating the commands to the console
        }while(!(ctrl_press.buttons & (SCE_CTRL_UP|SCE_CTRL_DOWN|SCE_CTRL_LEFT|SCE_CTRL_RIGHT|SCE_CTRL_START)));
        sceCameraStop(cur_cam);
        sceCameraClose(cur_cam);
        if(ctrl_press.buttons & SCE_CTRL_UP)
            cur_res=(cur_res+1)%ARRAYSIZE(res_table);
        if(ctrl_press.buttons & SCE_CTRL_DOWN)
            cur_cam=(cur_cam+1)%2;
        if(ctrl_press.buttons & SCE_CTRL_LEFT)
            cur_fps=(cur_fps+1)%ARRAYSIZE(fps_table);
        //may overflow the drawbuffer => TODO:reallocate drawbuff on format change
        //if(ctrl_press.buttons & SCE_CTRL_RIGHT)
        //    cur_fmt=(cur_fmt+1)%9;

    }while(!(ctrl_press.buttons & SCE_CTRL_START));  // sample loop for testing until start button is pressed

    sceKernelFreeMemBlock(memblock); // free the used memory block
    sceKernelExitProcess(0); // close the vita proccess runing, usually close the app
    return 0;
}


-----------

Some screenshots from the sample running on the vita:


Daily mode

Negative mode

Negative + mirror mode (180 degree rotation)

Yellow filter

Pink filter

Rear screen in the corner, with front screen frozen





And that's all for this sample.

Monday, July 20, 2020

Basics on the code PART 9

Today we are going to read the sample about the touch screens (frontal and rear pannel) of the vita.

To help us to understand the functions we have to use the vitasdk documentation, for this specific sample we will use the touch section.  

Note: there seems to be some functions that are based on previous versions of the SDK, but they are with the newer ones, so we'll try to join the explanations unless other requirements arise.

SAMPLE "touch"

touch: A minimal touch sample.


#include <psp2/kernel/processmgr.h>
#include <psp2/touch.h>

#include <stdio.h>
#include <string.h>

#include "debugScreen.h"

#define printf psvDebugScreenPrintf

/* TODO: why touch[port].report[i].force is always at 128 ? */

// main program

int main(int argc, char *argv[]) {
    psvDebugScreenInit();  // needed for the prints to show on the vita screen.


// as in other samples, here is written the stop condition for the sample

    printf("swipe to the bottom with 1 finger to stop\n");
    /* should use SCE_TOUCH_SAMPLING_STATE_START instead of 1 but old SDK have an invalid values */
    sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, 1);
    sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, 1);
    sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT);
    sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK);
   
    SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM];
    SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM];



// and here on, it is the loop for the testing and parameters

    while (1) {

        memcpy(touch_old, touch, sizeof(touch_old));
        printf("\e[0;5H");

        int port,i;
        /* sample both back and front surfaces */
        for(port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++){

//  shows the screen coordinates where you are pressing,
// and saves the result on screen until new coordinates are created

            sceTouchPeek(port, &touch[port], 1);
            printf("%s",((const char*[]){"FRONT","BACK "})[port]);
            /* print every touch coordinates on that surface */
            for(i = 0; i < SCE_TOUCH_MAX_REPORT; i++)
                printf("\e[9%im%4i:%-4i ", (i < touch[port].reportNum)? 7:0,
                       touch[port].report[i].x,touch[port].report[i].y);
            printf("\n");
        }

// stop condition for the loop to exit
/* in real test, this coordinates are too specific and is difficult to sweep in the right position*/

        if ( (touch[SCE_TOUCH_PORT_FRONT].reportNum == 1)
          && (touch_old[SCE_TOUCH_PORT_FRONT].reportNum == 1)
          && (touch[SCE_TOUCH_PORT_FRONT].report[0].y >= 1000)
          && (touch_old[SCE_TOUCH_PORT_FRONT].report[0].y < 1000))
        break;
    }


    sceKernelExitProcess(0);
    return 0;
}


-----------

Some screenshots from the sample running on the vita:

Starting coordinates


One finger pressing the rear pannel

Two fingers pressing the front pannel


Two fingers pressing the rear pannel

Six fingers presing the front channel

And that's all for this sample.

Sunday, July 19, 2020

Basics on the code PART 8

Today we are going to see the motion sensor sample, which is about the ps vita's orientation, speed, magnetometer...

To understand the functions we have to use the vitasdk documentation, for this specific sample we will use the motion section

Reminder: the threshold is the magnitude or intensity that must be exceeded for a certain reaction, phenomenon, result, or condition to occur or be manifested.

SAMPLE "motion"

motion: Prints accelerometer data.


#include <stdio.h>
#include <stdbool.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/ctrl.h>
#include <psp2/motion.h>

#include "debugScreen.h"

#define printf psvDebugScreenPrintf


// main program

int main(){
    psvDebugScreenInit();         // needed for the prints to show on the vita screen.  
   
    SceCtrlData ctrl;                   // used to read the buttons (used when options are offered in the sample)

    float threshold;                     // used to have a base number for the sensor data to be displayed   
 
    bool is_sampling=false;       // used to know if we are sampling the data or not


// loop for sampling

    while(1){

// control questions to set up the sampling and to quit

        sceCtrlReadBufferPositive(0, &ctrl, 1);
        printf("\e[60;35HPress Start to quit\n");
        if(ctrl.buttons & SCE_CTRL_START)
            break;
        printf("\e[H");/*reset the cursor position to 0,0*/
       
        printf("Sampling:%3s (X:ON, O:OFF)\n",is_sampling?"ON":"OFF");
        if((ctrl.buttons & SCE_CTRL_CROSS) && !is_sampling)
            is_sampling=(sceMotionStartSampling()==0);
        if((ctrl.buttons & SCE_CTRL_CIRCLE) && is_sampling)
            is_sampling=(sceMotionStopSampling()!=0);

        printf("Deadband:%3s ([]: ON, /\\:OFF)\n",sceMotionGetDeadband()?"ON":"OFF");
        if(ctrl.buttons & SCE_CTRL_SQUARE)
            sceMotionSetDeadband(1);
        if(ctrl.buttons & SCE_CTRL_TRIANGLE)
            sceMotionSetDeadband(0);

        threshold = sceMotionGetAngleThreshold();
        printf("AngleThreshold:%+1.3f (Up:+=0.1,Down:-=0.1)\n",threshold);
        if(ctrl.buttons & SCE_CTRL_UP)
            sceMotionSetAngleThreshold(threshold+0.1f);
        if(ctrl.buttons & SCE_CTRL_DOWN)
            sceMotionSetAngleThreshold(threshold-0.1f);

        printf("TiltCorrection:%i (RIGHT:ON, LEFT:OFF)\n",sceMotionGetTiltCorrection());
        if(ctrl.buttons & SCE_CTRL_LEFT)
            sceMotionSetTiltCorrection(0);
        if(ctrl.buttons & SCE_CTRL_RIGHT)
            sceMotionSetTiltCorrection(1);

        printf("\n");
        /* no need to further if we are not sampling */
        if(!is_sampling)
            continue;
           
/* Here we read all the data from the motion sensor in the vita and use printf to display it on the screen */


        printf("Magnetometer:%3s (L:ON, R:OFF)\n",sceMotionGetMagnetometerState()?"ON":"OFF");
        if(ctrl.buttons & SCE_CTRL_LTRIGGER)
            sceMotionMagnetometerOn();
        if(ctrl.buttons & SCE_CTRL_RTRIGGER)
            sceMotionMagnetometerOff();

        printf("\nPress Select to calibrate as Origin\n");
        if(ctrl.buttons & SCE_CTRL_SELECT)
            sceMotionReset();

        SceMotionState state;
        sceMotionGetState(&state);
        printf("Acceleration <x:%+1.3f y:%+1.3f z:%+1.3f>     \n",state.acceleration.x, state.acceleration.y, state.acceleration.z);
        printf("Ang.Velocity <x:%+1.3f y:%+1.3f z:%+1.3f>     \n",state.angularVelocity.x, state.angularVelocity.y, state.angularVelocity.z);
        printf("Orientation  <x:%+1.3f y:%+1.3f z:%+1.3f>     \n",state.basicOrientation.x, state.basicOrientation.y, state.basicOrientation.z);
        printf("Device       <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.deviceQuat.x, state.deviceQuat.y, state.deviceQuat.z, state.deviceQuat.w);
        printf("Rotation.X   <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.rotationMatrix.x.x, state.rotationMatrix.x.y, state.rotationMatrix.x.z, state.rotationMatrix.x.w);
        printf("Rotation.Y   <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.rotationMatrix.y.x, state.rotationMatrix.y.y, state.rotationMatrix.y.z, state.rotationMatrix.y.w);
        printf("Rotation.Z   <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.rotationMatrix.z.x, state.rotationMatrix.z.y, state.rotationMatrix.z.z, state.rotationMatrix.z.w);
        printf("Rotation.W   <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.rotationMatrix.w.x, state.rotationMatrix.w.y, state.rotationMatrix.w.z, state.rotationMatrix.w.w);
        printf("NedMatrix.X  <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.nedMatrix.x.x, state.nedMatrix.x.y, state.nedMatrix.x.z, state.nedMatrix.x.w);
        printf("NedMatrix.Y  <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.nedMatrix.y.x, state.nedMatrix.y.y, state.nedMatrix.y.z, state.nedMatrix.y.w);
        printf("NedMatrix.Z  <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.nedMatrix.z.x, state.nedMatrix.z.y, state.nedMatrix.z.z, state.nedMatrix.z.w);
        printf("NedMatrix.W  <x:%+1.3f y:%+1.3f z:%+1.3f w:%+1.3f>\n",state.nedMatrix.w.x, state.nedMatrix.w.y, state.nedMatrix.w.z, state.nedMatrix.w.w);
       
        printf("\n");
       
        SceMotionSensorState sensor;
        sceMotionGetSensorState(&sensor, 1);
        printf("SensorCounter:%i                \n",sensor.counter);
        printf("accelerometer<x:%+1.3f y:%+1.3f z:%+1.3f>   \n",sensor.accelerometer.x, sensor.accelerometer.y, sensor.accelerometer.z);

        SceFVector3 basicOrientation;
        sceMotionGetBasicOrientation(&basicOrientation);
        printf("basicOrient. <x:%+1.3f y:%+1.3f z:%+1.3f>   \n",basicOrientation.x, basicOrientation.y, basicOrientation.z);
       
        /*        sceMotionRotateYaw(float radians);*/
    }


    sceKernelExitProcess(0);  // close the vita proccess runing, usually close the app
    return 0;
}


-----------

Some screenshots from the sample running on the vita:

Sampling Off

Sampling On



And that's all for this sample.

Friday, July 17, 2020

Basics on the code PART 7

This sample is about the time clock on the vita.

Note: for those who didn't know, rtc stands for Real-Time-Clock


As always, we are going to use as reference the vitasdk documentation, being vitasdk rtc.h the particular section for today. Also, you can read about the rtc header from the linux man rtc.h.

Note: this entry is very simple, you only need to read the functions in the prints to see what is doing. Besides, we haven't said it before but, with the printf we should start getting used to the different print formats

Note 2: there is a TODO on this sample, we are skiping it. However, doing it, would be a good practice.

SAMPLE "rtc"

 rtc: A minimal RTC sample.

#include <psp2/kernel/processmgr.h>
#include <psp2/rtc.h>

#include "debugScreen.h"

#define printf psvDebugScreenPrintf

// main program

int main(int argc, char *argv[]) {
    psvDebugScreenInit();  // needed for the prints to show on the vita screen.

    SceDateTime time;
    sceRtcGetCurrentClock(&time, 13);
    printf("Phoenix Island Time:%04d/%02d/%02d %02d:%02d:%02d:%i\n",
        sceRtcGetYear(&time),
        sceRtcGetMonth(&time),
        sceRtcGetDay(&time),
        sceRtcGetHour(&time),
        sceRtcGetMinute(&time),
        sceRtcGetSecond(&time),
        sceRtcGetMicrosecond(&time));

    sceRtcGetCurrentClockLocalTime(&time);
    printf("Your Local Time:%04d/%02d/%02d %02d:%02d:%02d:%i Valid:%i\n",
        sceRtcGetYear(&time),
        sceRtcGetMonth(&time),
        sceRtcGetDay(&time),
        sceRtcGetHour(&time),
        sceRtcGetMinute(&time),
        sceRtcGetSecond(&time),
        sceRtcGetMicrosecond(&time),
        sceRtcCheckValid(&time));

    printf("We are the %ith days of the week (Sun:0)\n",
           sceRtcGetDayOfWeek(sceRtcGetYear(&time), sceRtcGetMonth(&time), sceRtcGetDay(&time)));
    printf("They are %i days this month and this %s a lap year\n",
        sceRtcGetDaysInMonth(sceRtcGetYear(&time), sceRtcGetMonth(&time)),
        sceRtcIsLeapYear(sceRtcGetYear(&time))?"is":"is not");

    printf("Tick Resolution = %i\n", sceRtcGetTickResolution());

    SceRtcTick current, network, utc, local;
   
    printf("     Current %s:%llu\n", sceRtcGetCurrentTick       (&current      )?"FAIL":"", current.tick);
    printf("     Network %s:%llu\n", sceRtcGetCurrentNetworkTick(&network      )?"FAIL":"", network.tick);
    printf("     Loc2UTC %s:%llu\n", sceRtcConvertLocalTimeToUtc(&current, &utc)?"FAIL":"", utc.tick);
    printf("     UTC2Loc %s:%llu\n", sceRtcConvertUtcToLocalTime(&utc, &local  )?"FAIL":"", local.tick);
    printf("     Loc %c UTC\n","<=>"[sceRtcCompareTick(&current, &utc)+1]);
    printf("     UTC %c Loc\n","<=>"[sceRtcCompareTick(&utc, &current)+1]);
    printf("     UTC %c UTC\n","<=>"[sceRtcCompareTick(&utc, &utc    )+1]);
   
    SceRtcTick add1000, us1000, sec120, min120, hour48, days32, week64, month13, year1000;
    printf("      T+1000 %s:%llu\n", sceRtcTickAddTicks       (&add1000, &current, 1000)?"FAIL":"", add1000.tick);
    printf("     Us+1000 %s:%llu\n", sceRtcTickAddMicroseconds(&us1000,  &current, 1000)?"FAIL":"", us1000.tick);
    printf("      S+120  %s:%llu\n", sceRtcTickAddSeconds     (&sec120,  &current,  120)?"FAIL":"", sec120.tick);
    printf("      M+120  %s:%llu\n", sceRtcTickAddMinutes     (&min120,  &current,  120)?"FAIL":"", min120.tick);
    printf("      H+48   %s:%llu\n", sceRtcTickAddHours       (&hour48,  &current,   48)?"FAIL":"", hour48.tick);
    printf("      D+32   %s:%llu\n", sceRtcTickAddDays        (&days32,  &current,   32)?"FAIL":"", days32.tick);
    printf("      W+64   %s:%llu\n", sceRtcTickAddWeeks       (&week64,  &current,   64)?"FAIL":"", week64.tick);
    printf("      M+13   %s:%llu\n", sceRtcTickAddMonths      (&month13, &current,   13)?"FAIL":"", month13.tick);
    printf("      Y+1000 %s:%llu\n", sceRtcTickAddYears       (&year1000,&current, 1000)?"FAIL":"", year1000.tick);

    char rfc3339_loc[128], rfc3339_12[128], rfc2822_loc[128], rfc2822_12[128];
    printf("RFC3339local %s:%s\n", sceRtcFormatRFC3339LocalTime(rfc3339_loc,&utc      )?"FAIL":"", rfc3339_loc);
    printf("RFC3339 + 2  %s:%s\n", sceRtcFormatRFC3339         (rfc3339_12, &utc, -120)?"FAIL":"", rfc3339_12);
    printf("RFC2822local %s:%s\n", sceRtcFormatRFC2822LocalTime(rfc2822_loc,&utc      )?"FAIL":"", rfc2822_loc);
    printf("RFC2822 - 2  %s:%s\n", sceRtcFormatRFC2822         (rfc2822_12, &utc, +120)?"FAIL":"", rfc2822_12);
   
    const char*rfc_ex1 = "2002-10-02T10:00:00-05:00";
    const char*rfc_ex2 = "2002-10-02T15:00:00Z";
    const char*rfc_ex3 = "2002-10-02T15:00:00.05Z";
    SceRtcTick parse_ex1, parse_ex2, parse_ex3;
    printf("RFC3339_1    %s:%-26s->%llu\n", sceRtcParseRFC3339(&parse_ex1, rfc_ex1)?"FAIL":"", rfc_ex1, parse_ex1.tick);
    printf("RFC3339_2    %s:%-26s->%llu\n", sceRtcParseRFC3339(&parse_ex2, rfc_ex2)?"FAIL":"", rfc_ex2, parse_ex2.tick);
    printf("RFC3339_3    %s:%-26s->%llu\n", sceRtcParseRFC3339(&parse_ex3, rfc_ex3)?"FAIL":"", rfc_ex3, parse_ex3.tick);

    const char*datetime_ex1 = "2002-10-02T10:00:00-05:00";
    const char*datetime_ex2 = "2002-10-02T15:00:00Z";
    const char*datetime_ex3 = "2002-10-02T15:00:00.05Z";
    SceRtcTick parsedDate_ex1, parsedDate_ex2, parsedDate_ex3;
    printf("datetime_1   %s:%-26s->%llu\n",sceRtcParseDateTime(&parsedDate_ex1, datetime_ex1)?"FAIL":"", datetime_ex1, parsedDate_ex1);
    printf("datetime_2   %s:%-26s->%llu\n",sceRtcParseDateTime(&parsedDate_ex2, datetime_ex2)?"FAIL":"", datetime_ex2, parsedDate_ex2);
    printf("datetime_3   %s:%-26s->%llu\n",sceRtcParseDateTime(&parsedDate_ex3, datetime_ex3)?"FAIL":"", datetime_ex3, parsedDate_ex3);

    /* TODO (aka not implemented in the sample)

    sceRtcSetTime_t(&time, time_t iTime);
    sceRtcSetTime64_t(&time, SceUInt64 ullTime);
    sceRtcGetTime_t(const &time, time_t *piTime);
    sceRtcGetTime64_t(const &time, SceUInt64 *pullTime);
    sceRtcSetDosTime(&time, unsigned int uiDosTime);
    sceRtcGetDosTime(const &time, unsigned int *puiDosTime);
    sceRtcSetWin32FileTime(&time, SceUInt64 ulWin32Time);
    sceRtcGetWin32FileTime(const &time, SceUInt64 *ulWin32Time);
    sceRtcSetTick(&time, const &tick);
    sceRtcGetTick(const &time, &tick);
    */

    int i=60;
    while(i-->0){
/* This use in fact two separate operators, -- and >.
The conditional's code decrements i,
while returning i's original (not decremented) value,
and then compares the original value with 0 using the > operator */
        printf("This sample will close in %2i seconds\r", i);   // use the i value as a timer to close the sample
        sceKernelDelayThread(1000*1000);
    }

    sceKernelExitProcess(0); // close the vita proccess runing, usually close the app
    return 0;
}

-----------

Screenshot from the sample running on the vita:




And that's all for this sample

Thursday, July 16, 2020

Basics on the code PART 6

This entry is about managing the data on the system power.

As always, to understand the functions, we should read the vitasdk documentation, particularly the power section.

To understand this sample, we have to know that the power info of the console is given through reading a thread,
that is going to be an endless callback for info from the viewer perspective. This works like any game or program that seem "halt" until you make an action. You only need to see 2 things:
- the thread with the info inside as variables, in a constant refresh on screen.
- the loop that keeps your system waiting for an input (interrupt programming), and lets you (in this case) end the loop, and exit the program.


SAMPLE "power"

power: A minimal power sample.


#include <stdio.h>
#include <string.h>

#include <psp2/ctrl.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/power.h>
#include <psp2/rtc.h>

#include "debugScreen.h"

/* Define printf, just to make typing easier */
#define printf psvDebugScreenPrintf


/* Power Callback - Runs when anything related do with power happens;
     e.g. pressed power button, sleep, etc. */
int powerCallback(int notifyId, int notifyCount, int powerInfo, void *common) {

    // doesn't work without a file handle open...?
    FILE *fd = fopen("ux0:data/test_power_cb.txt", "w");

// get the time from the console
    SceDateTime time;
    sceRtcGetCurrentClockLocalTime(&time);

    printf("%04d/%02d/%02d %02d:%02d:%02d:%05d notifyId %i, notifyCount %i, powerInfo 0x%08X\n",
        sceRtcGetYear(&time), sceRtcGetMonth(&time), sceRtcGetDay(&time),
        sceRtcGetHour(&time), sceRtcGetMinute(&time), sceRtcGetSecond(&time), sceRtcGetMicrosecond(&time),
        notifyId, notifyCount, powerInfo);

    fclose(fd);
}

/* Our thread to handle any callbacks. */
int CallbackThread(SceSize args, void *argp) {
    // create and register a callback in this thread.
    int cbid;
    cbid = sceKernelCreateCallback("Power Callback", 0, powerCallback, NULL);
    int registered = scePowerRegisterCallback(cbid);

    printf("\e[16;0H Callback registered id: %i  registered: %i.\n\n", cbid, registered);

    // this thread only handles callbacks.
    // so delay it forever, but handle callbacks.
    while (1) {
        sceKernelDelayThreadCB(10 * 1000 * 1000);
    }

    return registered;
}

/* Sets up the callback thread and returns its thread id */
int setupCallbacks(void) {
    int thid = 0;

    // The main thread does not handle callbacks, so we need to make one to handle them.
    thid = sceKernelCreateThread("callbackThread", CallbackThread, 0x10000100, 0x10000, 0, 0, NULL);
    if (thid >= 0)
        sceKernelStartThread(thid, 0, 0);

    printf("\e[15;0H Thread created %i\n.", thid);
    return thid;
}

/* main routine */
int main(int argc, char *argv[])
{   
    SceCtrlData pad;
    int i = 0;
    int batteryLifeTime = 0;

    psvDebugScreenInit();
   

// show the info on screen with values obtained from functions inside the printf

    printf("PS Vita Power Sample v0.1\n\n");

    printf("External power: %s\n", scePowerIsPowerOnline()? "yes" : "no ");
    printf("Low charge: %s\n", scePowerIsLowBattery()? "yes" : "no ");
    printf("Charging: %s\n", scePowerIsBatteryCharging()? "yes" : "no ");
    printf("Battery life percent: %d%%\n", scePowerGetBatteryLifePercent());
    batteryLifeTime = scePowerGetBatteryLifeTime();
    printf("Battery life time: (%02dh%02dm)\n", batteryLifeTime/60, batteryLifeTime-(batteryLifeTime/60*60));
    printf("Clock frequency of the ARM: %d mHz\n", scePowerGetArmClockFrequency());
    printf("Clock frequency of the BUS: %d mHz\n", scePowerGetBusClockFrequency());
    printf("Clock frequency of the GPU: %d mHz\n", scePowerGetGpuClockFrequency());

    printf("\n\nExperiment by sleeping vita and turning back on. Press start to exit. \n");
    setupCallbacks();


// looping for reading inputs, as any other program do, to know the user actions

    while (1)
    {
        memset(&pad, 0, sizeof(pad));
        sceCtrlPeekBufferPositive(0, &pad, 1);
        
        if (pad.buttons & SCE_CTRL_START) // stops the loop if the user press the start button
            break;
    }

    sceKernelExitProcess(0); 
// close the vita proccess runing, usually close the app

    return 0;
}


-----------

Screenshot from the sample running on the vita:




And that's all for this sample

Wednesday, July 15, 2020

Basics on the code PART 5

This entry is about the input method editor (IME). This will give us the power to make screen dialog windows with user input answers.

To understand the functions, we have to use the dialog section in the vitasdk documentation. for this particular sample, we will use specificly this user section.

SAMPLE "ime"

ime: Graphical dialog sample.

#include <string.h>
#include <stdbool.h>

#include <psp2/types.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/message_dialog.h>
#include <psp2/ime_dialog.h>
#include <psp2/display.h>
#include <psp2/apputil.h>
#include <psp2/gxm.h>
#include <psp2/kernel/sysmem.h>


// screen constants
#define ALIGN(x, a)    (((x) + ((a) - 1)) & ~((a) - 1))
#define DISPLAY_WIDTH            960
#define DISPLAY_HEIGHT            544
#define DISPLAY_STRIDE_IN_PIXELS    1024
#define DISPLAY_BUFFER_COUNT        2
#define DISPLAY_MAX_PENDING_SWAPS    1




// dialog window structure
typedef struct{
    void*data;
    SceGxmSyncObject*sync;
    SceGxmColorSurface surf;
    SceUID uid;
}displayBuffer;

// variables for the text box
unsigned int backBufferIndex = 0;
unsigned int frontBufferIndex = 0;
/* could be converted as struct displayBuffer[] */
displayBuffer dbuf[DISPLAY_BUFFER_COUNT];

// memory allocation for the window object
void *dram_alloc(unsigned int size, SceUID *uid){
    void *mem;
    *uid = sceKernelAllocMemBlock("gpu_mem", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, ALIGN(size,256*1024), NULL);
    sceKernelGetMemBlockBase(*uid, &mem);
    sceGxmMapMemory(mem, ALIGN(size,256*1024), SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
    return mem;
}

//
VSync (to match the graphics processor's frames with the refresh rate of the monitor to fix any syncing issues)
void gxm_vsync_cb(const void *callback_data){
    sceDisplaySetFrameBuf(&(SceDisplayFrameBuf){sizeof(SceDisplayFrameBuf),
        *((void **)callback_data),DISPLAY_STRIDE_IN_PIXELS, 0,
        DISPLAY_WIDTH,DISPLAY_HEIGHT}, SCE_DISPLAY_SETBUF_NEXTFRAME);
}

// gxm (Graphics eXpansion Modules) initialization
void gxm_init(){
    sceGxmInitialize(&(SceGxmInitializeParams){0,DISPLAY_MAX_PENDING_SWAPS,gxm_vsync_cb,sizeof(void *),SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE});
    unsigned int i;
    for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
        dbuf[i].data = dram_alloc(4*DISPLAY_STRIDE_IN_PIXELS*DISPLAY_HEIGHT, &dbuf[i].uid);
 
// applying gxm     sceGxmColorSurfaceInit(&dbuf[i].surf,SCE_GXM_COLOR_FORMAT_A8B8G8R8,SCE_GXM_COLOR_SURFACE_LINEAR,SCE_GXM_COLOR_SURFACE_SCALE_NONE,SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,DISPLAY_WIDTH,DISPLAY_HEIGHT,DISPLAY_STRIDE_IN_PIXELS,dbuf[i].data);
        sceGxmSyncObjectCreate(&dbuf[i].sync);
    }
}
void gxm_swap(){
    sceGxmPadHeartbeat(&dbuf[backBufferIndex].surf, dbuf[backBufferIndex].sync);
    sceGxmDisplayQueueAddEntry(dbuf[frontBufferIndex].sync, dbuf[backBufferIndex].sync, &dbuf[backBufferIndex].data);
    frontBufferIndex = backBufferIndex;
    backBufferIndex = (backBufferIndex + 1) % DISPLAY_BUFFER_COUNT;
}
void gxm_term(){
    sceGxmTerminate();

// freeing memory
    for (int i=0; i<DISPLAY_BUFFER_COUNT; ++i)
        sceKernelFreeMemBlock(dbuf[i].uid);
}


// main program
int main(int argc, const char *argv[]) {

// declare and init the actual dialog window with its parameters
    uint16_t input[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
    SceImeDialogParam param;
    int shown_dial = 0; // var to keep the main loop , the display of  the keyboard
    bool said_yes = false; // var to keep looping (waiting) until the user says yes

    sceAppUtilInit(&(SceAppUtilInitParam){}, &(SceAppUtilBootParam){});
    sceCommonDialogSetConfigParam(&(SceCommonDialogConfigParam){});

   // initialize the gxm
    gxm_init();


   // keep the dialog windows open until the user answers "yes" in the text box
    while (!said_yes) {
        //clear current screen buffer
        memset(dbuf[backBufferIndex].data,0xff000000,DISPLAY_HEIGHT*DISPLAY_STRIDE_IN_PIXELS*4);

// parameters of the text and boxes of the window

      if (!shown_dial) {
            sceImeDialogParamInit(&param);

            param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH;
            param.languagesForced = SCE_TRUE;
            param.type = SCE_IME_DIALOG_TEXTBOX_MODE_DEFAULT;
            param.option = 0;
            param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_DEFAULT;

            param.title = u"say yes!"; // var with the text displayed to the user above the bracket to write

            param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH;

            param.initialText = u"nah"; // dafault text in the bracket for user input

            param.inputTextBuffer = input; // buffer to store the user input

            shown_dial = sceImeDialogInit(&param) > 0;
        }

    // get the input answers, and update (terminate or refresh) the dialog
        if (sceImeDialogGetStatus() == SCE_COMMON_DIALOG_STATUS_FINISHED) {
            SceImeDialogResult result={};      
            sceImeDialogGetResult(&result);

            uint16_t*last_input = (result.button == SCE_IME_DIALOG_BUTTON_ENTER) ? input:u"";

            said_yes=!memcmp(last_input,u"yes",4*sizeof(u' ')); // check if the answer is "yes"

            sceImeDialogTerm();
            shown_dial = 0;/*< to respawn sceImeDialogInit on next loop */
        }
    
        // show the user's input in the text box
        sceCommonDialogUpdate(&(SceCommonDialogUpdateParam){{
            NULL,dbuf[backBufferIndex].data,0,0,
            DISPLAY_WIDTH,DISPLAY_HEIGHT,DISPLAY_STRIDE_IN_PIXELS},
            dbuf[backBufferIndex].sync});

        gxm_swap();
        sceDisplayWaitVblankStart(); //
Wait for vertical blank start (a.k.a. Refreshing), should avoid blinking
    }


    gxm_term();
    sceKernelExitProcess(0); 
// close the vita proccess runing, usually close the app
    return 0;
}



-----------

Screenshot from the sample running on the vita:




And that's all for this sample.

Tuesday, July 14, 2020

Basiscs on the code PART 4

This entry is about the sld2 sample. As the name suggests, it uses the sld2 library.

The sample deeps in drawing pictures in the screen (rendering), specificly a red rectangle as its name implies.

To understand the functions, we have to use the vitasdk documentation, for this specific sample we will use the graphics section. In addition, we need to use the sdl2 wiki.

Note: Again, the sample doesn't use any specific function from the vita, appart from the "includes" and "defines" to be executed. However, we think it is useful to have the vitasdk documentation stated here as well.

Note 2: For those who need this, it uses the RGB color code, you can find the different codes here.


 SAMPLE "sdl/redrectangle"

redrectangle: Example SDL rendering.


// this time the code is pretty forward and you can see some features of the vita graphics so, we will put a small number of comments here.

#include <psp2/kernel/processmgr.h>
#include <SDL2/SDL.h>

//Screen dimension constants
enum {
  SCREEN_WIDTH  = 960,
  SCREEN_HEIGHT = 544
};

// Part from the sdl library to declare constant and variables

SDL_Window    * gWindow   = NULL;
SDL_Renderer  * gRenderer = NULL;

SDL_Rect fillRect = { SCREEN_WIDTH  / 4,
              SCREEN_HEIGHT / 4,
              SCREEN_WIDTH  / 2,
              SCREEN_HEIGHT / 2
};


// main program

int main(int argc, char *argv[])
{

// sdl init and checking if has had any error

  if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
      return -1;

// creating the rectangle and checking if has been any errors

  if ((gWindow = SDL_CreateWindow( "RedRectangle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN)) == NULL)
    return -1;

// rendering the figures and again checking errors

  if ((gRenderer = SDL_CreateRenderer( gWindow, -1, 0)) == NULL)
      return -1;

// actually drawing the figures and colors in the screen

  SDL_SetRenderDrawColor( gRenderer, 255,0,0,255);
  SDL_RenderFillRect( gRenderer, &fillRect );
  SDL_RenderPresent( gRenderer );

  SDL_Delay(4000);

// cleaning the memory

  SDL_DestroyRenderer( gRenderer );
  SDL_DestroyWindow( gWindow );
  gWindow = NULL;
  gRenderer = NULL;
 
// exiting

  SDL_Quit(); // close the sdl
  sceKernelExitProcess(0); // close the vita proccess runing, usually close the app
  return 0;
}

-----------

Screenshot from the sample running on the vita:





And that's all for this sample.

Monday, July 13, 2020

Basiscs on the code PART 3

We have seen samples for screen printing and for button control, is time to see the sample to read an audio file.

This sample use the soLoud engine. It doesn't use any specific function from the vita, appart from the "includes" and "defines" to be executed. However, we think it is useful to have the vitasdk documentation stated here anyways.

SAMPLE "soloud" 

soloud: Plays an audio file and Text To Speech.


This sample has a few things new, in reference to the previous ones:

It has an audio file music.ogg, this is obviously the audio file we're going to be reading; and it has a c++ (.cpp) file as main.

Note: there are not enough significant syntax differences between c and c++ to make difficult the understanding of the file, so we are going to keep everything as is (in that matter) for the moment.


// headers and other required files which need to be linked for the homebrew to work

#include <stdint.h>
#include <math.h>

#include <psp2/ctrl.h>
#include <psp2/audioout.h>
#include <psp2/kernel/processmgr.h>

#include "debugScreen.h"

#include "soloud.h"
#include "soloud_wav.h"
#include "soloud_speech.h"


// Part from the soLoud engine to declare variables

SoLoud::Soloud gSoloud; // SoLoud engine
SoLoud::Wav gWave;      // One wave file


// definition of some future used functions

#define printf psvDebugScreenPrintf

// main program

int main(void) {

    psvDebugScreenInit();  // needed for the prints to show on the vita screen.

    printf("soloud demo\n");

    gSoloud.init(); // Initialize SoLoud
    printf("init\n");


   // example from an audio file

    gWave.load("app0:/music.ogg"); // Load a wave from the game datapath
                                                     // Key note: It is worth to remember this datapath "app0:/" for future uses.
    printf("load\n");

    gSoloud.play(gWave); // Play the wave


    /* example from a text (in this case, the text is harcoded as a variable).
      [According to soloud samples, you should be able to read from the console and,
       the console reading is a file reading in unix] */

    SoLoud::Speech sp;       // declares a text soLoud variable
    sp.setText("Hello world.  You will be assimilated.");      // the engine reads the text to
    gSoloud.play(sp);         // play it as an audio
    printf("play\n");

/* this was not in the sample but after seeing it in soLoud examples we think it is a good practice.*/

// clean up soLoud
 soloud.deinit();


// back to the sample's code ...

    while (1) {
        sceKernelDelayThread(1000 * 1000);
    }


    sceKernelExitProcess(0); // close the vita proccess runing, usually close the app
    return 0;
}


-----------

Some screenshots from the sample running on the vita:




And that's all for this sample.

Sunday, July 12, 2020

Basics on the code PART 2

Today we are going to review our second sample, which is going to be "ctrl". Because it is about the console keypad and remote controller status, a.k.a. Buttons.

In this sample, the only difference with the "hello_world" one, is the main.c file, that is why are only focusing on that.

The goal of this sample is knowing the functions that control the buttons of the console, which are going to be very important if we want to make our app interactive.

To understand the functions we have to read the vitasdk documentation, for this specific sample we will use the control section

SAMPLE "ctrl"

 ctrl: A minimal controller (button) sample.

// headers and other required files which need to be linked for the homebrew to work

#include <stdio.h>
#include <psp2/kernel/processmgr.h>

#include <psp2/ctrl.h>

#include "debugScreen.h"

#define printf psvDebugScreenPrintf

// main program

int main(int argc, char *argv[]) {

    psvDebugScreenInit();  // needed for the prints to show on the vita screen.

    printf("input test\n");

    printf("press Select+Start+L+R to stop\n");

    /* to enable analog sampling */
    sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);  // Set the controller mode.
  
    SceCtrlData ctrl; // Returned controller data.

    const char* btn_label[]={"SELECT ","","","START ",
        "UP ","RIGHT ","DOWN ","LEFT ","L ","R ","","",
        "TRIANGLE ","CIRCLE ","CROSS ","SQUARE "};
    do{
        sceCtrlPeekBufferPositive(0, &ctrl, 1); // Get the controller state information (polling, positive logic).
        printf("Buttons:%08X == ", ctrl.buttons);
        int i;
        for(i=0; i < sizeof(btn_label)/sizeof(*btn_label); i++){
            printf("\e[9%im%s",(ctrl.buttons & (1<<i)) ? 7 : 0, btn_label[i]);
        }
        printf("\e[m Stick:[%3i:%3i][%3i:%3i]\r", ctrl.lx,ctrl.ly, ctrl.rx,ctrl.ry); // print analogue stick values

    }while(ctrl.buttons != (SCE_CTRL_START | SCE_CTRL_SELECT | SCE_CTRL_LTRIGGER | SCE_CTRL_RTRIGGER) );   // as the printed line at the begining says, it defines a way to exit from the input mode


    sceKernelExitProcess(0);  // close the vita proccess runing, usually close the app

    return 0;
}

-----------

Some screenshots from the sample running on the vita:

No button pressed

Down button pressed

Start and Up button pressed

Triangle button pressed



And that's all for this sample.