Vous êtes sur la page 1sur 6

Vita Programming Tutorial: Part 1 Hello, World

by wololo November 23, 2016

Not actually related to C programming on the Vita!

Note from Wololo: This tutorial on How to program homebrews for your PS Vita was initially published by /Talk member
thevitamaster, as part of our monthly tutorial contest. Thevitamaster won the August tutorial contest for the PS Vita (a $10
Amazon gift code) with this entry. You can find the original post here.

Hi guys,
welcome to part one of my new tutorial series on programming for the Vita, where we will be laying the groundwork for you to
develop your own homebrew / port games to the vita! Today we will be doing a graphical hello world with the unofficial VitaSDK
and vita2dlib.

Requirements:
Vita with Henkaku
********************************************************************************************************************
Unofficial VitaSDK and vita2dlib installed on a linux system (see my last tutorial)
********************************************************************************************************************
Local Area Network connectivity between Vita and linux system
********************************************************************************************************************
So, dont be scared but here comes a dump of code. Scroll a little bit down for the explanation.
Main.c

#include <psp2/display.h>

#include <psp2/moduleinfo.h>

#include <psp2/kernel/processmgr.h>

#include

PSP2_MODULE_INFO(0, 0, "HelloWorld");

int main() {

vita2d_pgf *pgf;

vita2d_init();

vita2d_set_clear_color(RGBA8(0, 0, 0, 255));
pgf = vita2d_load_default_pgf();

while(1){

vita2d_start_drawing();

vita2d_clear_screen();

vita2d_pgf_draw_text(pgf, 700, 30, RGBA8(0, 255, 0, 255), 1.0f, "Hello,


World!");

vita2d_end_drawing();

vita2d_swap_buffers();

vita2d_fini();

vita2d_free_pgf(pgf);

sceKernelExitProcess(0);

return 0;

Explanation of main.c (above):


First of all, lets look at the include directives (for example the #include <psp2/display.h> directive).
These include directives, also called preprocessor directives, because they are enumerated into files on a preparation pass,
basically just tell the C compiler to include (e.g. copy) the contents of this header file (display.h) into the file being compiled (our
file main.c in this case). With our Vita, also called an embedded linux device, we use these include directives to use functions
specific to some aspect of the hardware / software. For example, if we do #include <psp2/ctrl.h>, we want access to controller-
related functions, variables, enums (a new variable type documented in the header and defined in source), and so forth, so we
can for example do a bitwise AND (& in C) with our own subset variable of type SceCtrlData called pad.buttons and the
controller state of the UP directional button, which is called SCE_CTRL_UP.
********************************************************************************************************************
Now, before we dive into the skeletal function calls of a Vita program, we have to define how a function routine is created / defined
in C and also, how to then call it. So, lets assume we have a system capable of running assembled C code in a stable manner as
well as capable of printing printf() calls to the standard output, which is presumptuously a terminal. Heres how the creation and
calling of a function in the same file would work:
example.c:

#include

// Creation of function routine

int printdec(int decimal){

printf("%d", decimal);

return 0;

}
int main(){

// Function call

printdec(123);

return 0;

So, now we can see that function creation and function call always follow a pattern. The pattern for function creation is:

[variable type you want to return] [function name]([function arguments]){

[routine]

On the other hand, the pattern for function calling is:

[function name]([function arguments]);

Note the semicolon at the end of every function call, variable assignment, defintion, as this tells the C compiler that the
instruction ends there.
********************************************************************************************************************
Now we can look at the first skeletal function call in Vita program, namely

PSP2_MODULE_INFO(0, 0, "HelloWorld");

This function is defined in psp2/moduleinfo.h and, as you can see, it gives the Vita system some basic information on our
program, namely

1. The attribute (No idea what that is)


2. The version of your program
3. Your program name. This has a maximum length of 27 characters.

We pass this information in said order in the function arguments of PSP2_MODULE_INFO.


********************************************************************************************************************
Next up:

int main(){

In the C language, as opposed to say Python 2.7, every function call that should be executed has to be in the routine of the main()
function. So, basically, every function call we want to make, we put within the { curly braces following int main().
********************************************************************************************************************
Following, we have:

vita2d_pgf *pgf;

This variabble defintion basically creates a new pointer variable of type vita2d_pgf which we can assign to the start of a pgf file
with the appropriate function call.
********************************************************************************************************************

vita2d_init();
With that function call, we initialize the vita2d graphics engine.
********************************************************************************************************************

vita2d_set_clear_color(RGBA8(0, 0, 0, 255));

Woah, thats quite something to dissect, but well get it done.


So, first of all, we have the function call vita2d_set_clear_color() which sets the color the vita should display when the screen is
cleared of all to be rendered elements.
Inside that, as the colour argument, we have the RGBA8() macro, which is defined (well get to that in part 2) in vita2dlib.
Basically, this macro allows you to specify colours.
Here, we can specify the Red, Green, Blue and Alpha values, the max of every single value being 255, and the min 0.
The Red value specifies the amount of red, the Green value the amount of green and so on.
But what does the alpha value specify??
Well, that value specifies the opacity of the object, so how little transparency there is: 255 is no transparency and 0 is all
transparent.
********************************************************************************************************************

pgf = vita2d_load_default_pgf();

This is a variable assignment. Here, we assign the return value of vita2d_load_default_pgf() to the pointer pgf of type vita2d_pgf.
********************************************************************************************************************

while(1){

Here, we have an infinite while loop. We do this to draw the values all the time and not draw them once and then exit.
********************************************************************************************************************

vita2d_start_drawing();

Here, we tell the vita to start the rendering process in memory not allocated to the display.
[!Important]But, we wont see anything on the vita screen until we call vita2d_swap_buffers();[/!Important]
Because then, our instructions will be swapped to the vita memory allocated to the display and the display controller will then
execute the instructions.
********************************************************************************************************************

vita2d_clear_screen();

We set the vita screen to display all black.


Remember vita2d_set_clear_color() and RGBA8()?
********************************************************************************************************************

vita2d_pgf_draw_text(pgf, 700, 30, RGBA8(0, 255, 0, 255), 1.0f, "Hello World!");

So, this function call lets us draw text on the screen of the vita!
The arguments to the function are in following order:

1. Assigned pointer of type vita2d_pgf


2. X coordinate of start of text
3. Y coordinate of start of text
4. Colour value created with the RGBA8 macro
5. Value for the size of text of type float (e.g with decimal points)
6. String to display

To 3. and 4.: Both of these values must be of type int (e.g. no decimal points).
********************************************************************************************************************

vita2d_end_drawing();
End the creation of the graphical elements in memory; the memory can now be swapped.
********************************************************************************************************************

vita2d_swap_buffers();

Swap the new drawn memory with the old one.


********************************************************************************************************************

End the infinte while loop.


********************************************************************************************************************

vita2d_fini();

Start all the cleanup processes, etc. of the vita2d engine.


********************************************************************************************************************

vita2d_free_pgf(pgf);

Free the memory allocated to the pgf font.


********************************************************************************************************************

sceKernelExitProcess(0);

Exit the program using a function created in the unofficial VitaSDK.


********************************************************************************************************************

return 0;

Because our main function is of type int, we return the value 0.


This is standard programming practice in C.

Makefile:

TITLE_ID = VITA2DTST

TARGET = vita2dsample

OBJS = main.o

LIBS = -lvita2d -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub \

-lSceSysmodule_stub -lSceCtrl_stub -lScePgf_stub \

-lSceCommonDialog_stub -lfreetype -lpng -ljpeg -lz -lm -lc

PREFIX = arm-vita-eabi

CC = $(PREFIX)-gcc

CFLAGS = -Wl,-q -Wall -O3

ASFLAGS = $(CFLAGS)

all: $(TARGET).vpk

%.vpk: eboot.bin

vita-mksfoex -s TITLE_ID=$(TITLE_ID) "$(TARGET)" param.sfo


eboot.bin: $(TARGET).velf

vita-make-fself $< $@

%.velf: %.elf

vita-elf-create $< $@

$(TARGET).elf: $(OBJS)

$(CC) $(CFLAGS) $^ $(LIBS) -o $@

%.o: %.png

$(PREFIX)-ld -r -b binary -o $@ $^

clean:

@rm -rf $(TARGET).vpk $(TARGET).velf $(TARGET).elf $(OBJS) \

eboot.bin param.sfo

This just works.

Compilation of our Hello World program:


1. Copy the code of main.c and Makefile and put them in two seperate files with their equivalent names.
2. Open a terminal, change your directory to that of the two files and run:

make

Installation:
1. Open molecularshell on your vita and press select
2. Open a terminal and type:

cd ~

wget https://github.com/xyzz/Vita_Doom/releases/download/1.0/vitadoom.vpk

ftp [ip displayed on your vita] [port displayed on your vita] (without the brackets)

put ~/vitadoom.vpk /ux0:vitadoom.vpk

3. Press circle on your vita and navigate to ux0:, then press cross when the vitadoom.vpk file is highlighted
4. Press select again
5. Open a terminal and type:

ftp [ip displayed on your vita] [port displayed on your vita] (without the brackets)

put path/to/eboot.bin /ux0:app/DOOM00000/eboot.bin

put path/to/param.sfo /ux0:app/DOOM00000/sce_sys/param.sfo

6. Close molecularshell and open the Doom bubble


7. ???
8. Profit!!!

See you in the next part!

Vous aimerez peut-être aussi