Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ make
|newlib_heapsize_ctrl|VSDK00021|newlib's global heap size control example.|
|json|VSDK00022|json parsing example.|
|net_https|VSDK00023|https access example.|
|message_box|VSDK00024|Example on how to create a spawn a message box.|
|soloud|VSDK01337|Plays an audio file and Text To Speech.|
|common|-|Common functions for samples.|
|prx_simple|-|Minimal sample prx module.|
Expand Down
59 changes: 59 additions & 0 deletions message_box/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# You should only use Makefile-based build if you know what you're doing.
# For most vitasdk projects, CMake is a better choice. See CMakeLists.txt for an example.

PHONY := all package clean
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))

CC := arm-vita-eabi-gcc
CXX := arm-vita-eabi-g++
STRIP := arm-vita-eabi-strip

PROJECT_TITLE := message_box_sample
PROJECT_TITLEID := VSDK00024

PROJECT := message_box_sample
CFLAGS += -Wl,-q -I../common
CXXFLAGS += -Wl,-q -std=c++11 -I../common

SRC_C :=$(call rwildcard, src/, *.c)
SRC_CPP :=$(call rwildcard, src/, *.cpp)

OBJ_DIRS := $(addprefix out/, $(dir $(SRC_C:src/%.c=%.o))) $(addprefix out/, $(dir $(SRC_CPP:src/%.cpp=%.o)))
OBJS := $(addprefix out/, $(SRC_C:src/%.c=%.o)) $(addprefix out/, $(SRC_CPP:src/%.cpp=%.o))

# Needed by psvDebugScreenPrintf
LIBS += -lSceSysmodule_stub -lSceCommonDialog_stub -lSceAppUtil_stub -lSceGxm_stub -lSceDisplay_stub

all: package

package: $(PROJECT).vpk

$(PROJECT).vpk: eboot.bin param.sfo
vita-pack-vpk -s param.sfo -b eboot.bin \
$(PROJECT).vpk

eboot.bin: $(PROJECT).velf
vita-make-fself $(PROJECT).velf eboot.bin

param.sfo:
vita-mksfoex -s TITLE_ID="$(PROJECT_TITLEID)" "$(PROJECT_TITLE)" param.sfo

$(PROJECT).velf: $(PROJECT).elf
$(STRIP) -g $<
vita-elf-create $< $@

$(PROJECT).elf: $(OBJS)
$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@

$(OBJ_DIRS):
mkdir -p $@

out/%.o : src/%.cpp | $(OBJ_DIRS)
arm-vita-eabi-g++ -c $(CXXFLAGS) -o $@ $<

out/%.o : src/%.c | $(OBJ_DIRS)
arm-vita-eabi-gcc -c $(CFLAGS) -o $@ $<

clean:
rm -f $(PROJECT).velf $(PROJECT).elf $(PROJECT).vpk param.sfo eboot.bin $(OBJS)
rm -r $(abspath $(OBJ_DIRS))
173 changes: 173 additions & 0 deletions message_box/src/gxm_base.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <psp2/gxm.h>
#include <psp2/display.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/message_dialog.h>

#define VITA_GXM_SCREEN_WIDTH 960
#define VITA_GXM_SCREEN_HEIGHT 544
#define VITA_GXM_SCREEN_STRIDE 960
#define VITA_GXM_BUFFERS 3
#define VITA_GXM_PENDING_SWAPS 1


#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8

#define zero_memory(v) memset(&v, 0, sizeof(v))
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))


static unsigned int back_buffer_index_for_common_dialog = 0;
static unsigned int front_buffer_index_for_common_dialog = 0;

typedef struct
{
void *address;
unsigned char wait_vblank;
} VITA_GXM_DisplayData;


struct
{
VITA_GXM_DisplayData displayData;
SceGxmSyncObject *sync;
SceGxmColorSurface surf;
SceUID uid;
} buffer_for_common_dialog[VITA_GXM_BUFFERS];

void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
{
void *mem;

if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) {
size = ALIGN(size, 256 * 1024);
} else if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW) {
size = ALIGN(size, 1024 * 1024);
} else {
size = ALIGN(size, 4 * 1024);
}

*uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL);

if (*uid < 0) {
return NULL;
}

if (sceKernelGetMemBlockBase(*uid, &mem) < 0) {
return NULL;
}

if (sceGxmMapMemory(mem, size, attribs) < 0) {
return NULL;
}

return mem;
}

void vita_mem_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0) {
return;
}
sceGxmUnmapMemory(mem);
sceKernelFreeMemBlock(uid);
}


void gxm_minimal_term_for_common_dialog(void)
{
sceGxmTerminate();
}

static void display_callback(const void *callback_data)
{
SceDisplayFrameBuf framebuf;
const VITA_GXM_DisplayData *display_data = (const VITA_GXM_DisplayData *)callback_data;

memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));
framebuf.size = sizeof(SceDisplayFrameBuf);
framebuf.base = display_data->address;
framebuf.pitch = VITA_GXM_SCREEN_STRIDE;
framebuf.pixelformat = VITA_GXM_PIXEL_FORMAT;
framebuf.width = VITA_GXM_SCREEN_WIDTH;
framebuf.height = VITA_GXM_SCREEN_HEIGHT;
sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME);

if (display_data->wait_vblank) {
sceDisplayWaitVblankStart();
}
}



void gxm_minimal_init_for_common_dialog(void)
{
SceGxmInitializeParams initializeParams;
zero_memory(initializeParams);
initializeParams.flags = 0;
initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS;
initializeParams.displayQueueCallback = display_callback;
initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData);
initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
sceGxmInitialize(&initializeParams);
}


void gxm_init_for_common_dialog(void)
{
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) {
buffer_for_common_dialog[i].displayData.wait_vblank = true;
buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW,
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&buffer_for_common_dialog[i].uid);
sceGxmColorSurfaceInit(
&buffer_for_common_dialog[i].surf,
VITA_GXM_PIXEL_FORMAT,
SCE_GXM_COLOR_SURFACE_LINEAR,
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
VITA_GXM_SCREEN_WIDTH,
VITA_GXM_SCREEN_HEIGHT,
VITA_GXM_SCREEN_STRIDE,
buffer_for_common_dialog[i].displayData.address);
sceGxmSyncObjectCreate(&buffer_for_common_dialog[i].sync);
}
sceGxmDisplayQueueFinish();
}

void gxm_swap_for_common_dialog(void)
{
SceCommonDialogUpdateParam updateParam;
zero_memory(updateParam);
updateParam.renderTarget.colorFormat = VITA_GXM_PIXEL_FORMAT;
updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR;
updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH;
updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT;
updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE;

updateParam.renderTarget.colorSurfaceData = buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address;

updateParam.displaySyncObject = buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync;
memset(buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address, 0, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT);
sceCommonDialogUpdate(&updateParam);

sceGxmDisplayQueueAddEntry(buffer_for_common_dialog[front_buffer_index_for_common_dialog].sync, buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync, &buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData);
front_buffer_index_for_common_dialog = back_buffer_index_for_common_dialog;
back_buffer_index_for_common_dialog = (back_buffer_index_for_common_dialog + 1) % VITA_GXM_BUFFERS;
}

void gxm_term_for_common_dialog(void)
{
sceGxmDisplayQueueFinish();
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) {
vita_mem_free(buffer_for_common_dialog[i].uid);
sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
}
}
10 changes: 10 additions & 0 deletions message_box/src/gxm_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef GXM_BASE_H
#define GXM_BASE_H

void gxm_minimal_init_for_common_dialog(void);
void gxm_init_for_common_dialog(void);
void gxm_swap_for_common_dialog(void);
void gxm_term_for_common_dialog(void);
void gxm_minimal_term_for_common_dialog(void);

#endif
Loading