add image_display sample to pspsdk

fix for PR

renamed logo folder to image_display, renamed logo to image in source, changed image used, removed FW version from makefile, added header to source, added image_display to all samples makefile
This commit is contained in:
pyroesp
2023-05-28 05:04:50 +02:00
parent dbe0b6e03e
commit 0987b3602b
3 changed files with 229 additions and 0 deletions

View File

@@ -61,6 +61,7 @@ SAMPLES = \
power \
prx/prx_loader \
prx/testprx \
prx/image_display \
savedata/utility \
savedata/decrypt \
savedata/encrypt \

View File

@@ -0,0 +1,16 @@
TARGET = image_display
BUILD_PRX = 1
OBJS = main.o
INCDIR =
CFLAGS = -Os -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBS =
LIBDIR =
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build_prx.mak

View File

@@ -0,0 +1,212 @@
/*
* PSP Software Development Kit - https://github.com/pspdev
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* main.c - image display plugin example
*
* Copyright (c) 2023 pyroesp
*
*/
#include <pspkernel.h>
#include <pspdisplay.h>
#include <psptypes.h>
#include <psprtc.h>
PSP_MODULE_INFO("image display", PSP_MODULE_USER, 0, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
#define SCREEN_W 480
#define SCREEN_H 272
#define IMAGE_W 72
#define IMAGE_H 40
#define PIXEL_PER_BYTE 8
// monochrome 1 bit per pixel image
u8 image[] = {
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00
};
// main thread id
int thid;
// main running flag
int running;
// convert 0-359 degree value to u32 ABGR color
u32 color_Wheel(int degrees);
// main thread
int main_thread(SceSize args, void *argp){
u64 tick;
unsigned int* vram32;
int bufferwidth, pixelformat;
// wait for psp boot
sceKernelDelayThread(10 * 1000 * 1000);
// get psp ticks for pseudo randomness
sceRtcGetCurrentTick(&tick);
// set image start position from ticks
s16 image_x = tick % (SCREEN_W - IMAGE_W);
s16 image_y = tick % (SCREEN_H - IMAGE_H);
// set image movement from start position
s16 image_vx = (image_x & 1) ? -1 : 1;
s16 image_vy = (image_y & 1) ? -1 : 1;
// image color
u32 image_color = color_Wheel((int)((tick / 1000) % 360));
// main menu
while (running){
// check x collision
if ((image_x + image_vx) >= (SCREEN_W - IMAGE_W) || (image_x + image_vx) <= 0){
//change direction
image_vx = -image_vx;
// update tick value when changing direction
sceRtcGetCurrentTick(&tick);
// change color based on tick value
image_color = color_Wheel((int)((tick / 1000) % 360));
}
// check y collision
if ((image_y + image_vy) >= (SCREEN_H - IMAGE_H) || (image_y + image_vy) <= 0){
//change direction
image_vy = -image_vy;
// update tick value when changing direction
sceRtcGetCurrentTick(&tick);
// change color based on tick value
image_color = color_Wheel((int)((tick / 1000) % 360));
}
// move image
image_x += image_vx;
image_y += image_vy;
// get vram
int ret = sceDisplayGetFrameBuf((void*)&vram32, &bufferwidth, &pixelformat, PSP_DISPLAY_SETBUF_IMMEDIATE);
// works with both PSP_DISPLAY_SETBUF_NEXTFRAME and PSP_DISPLAY_SETBUF_IMMEDIATE
// check if return value from sceDisplayGetFrameBuf is valid
// check if vram32 is not NULL
// check if bufferwidth is not 0
if (ret == 0 && vram32 != NULL && bufferwidth != 0){
// draw image
for (int i = 0; i < IMAGE_H; i++){
for (int j = 0; j < IMAGE_W; j++){
// check if the pixel bit of the image at position 'j' is 1
if (image[(i * (IMAGE_W / PIXEL_PER_BYTE)) + j / PIXEL_PER_BYTE] & (1 << (PIXEL_PER_BYTE - 1 - (j % PIXEL_PER_BYTE)))){
// write image to vram
vram32[(image_y + i) * bufferwidth + (image_x + j)] = image_color;
}
}
}
}
// not checking return value and/or vram32 pointer will result in a crash when putting the PSP to sleep
// wait for vblank and allow for callbacks
if (sceDisplayWaitVblankStartCB() < 0)
break; // end of VSH ?
}
return sceKernelExitDeleteThread(0);
}
int module_start(SceSize args, void *argp){
running = 0;
// create and start main thread
thid = sceKernelCreateThread("image_display", main_thread, 0x10, 4*1024, PSP_THREAD_ATTR_USER, NULL);
if (thid >= 0){
running = 1;
sceKernelStartThread(thid, args, argp);
}
return 0;
}
int module_stop(SceSize args, void *argp){
// clean exit main thread
if (running){
running = 0;
SceUInt time = 200*1000;
int ret = sceKernelWaitThreadEnd(thid, &time);
if (ret < 0)
sceKernelTerminateDeleteThread(thid);
}
return 0;
}
// convert 0-359 degree value to u32 ABGR color
u32 color_Wheel(int degrees){
u8 red = 0, green = 0, blue = 0;
degrees = degrees % 360;
if (degrees < 120){
red = ((120 - degrees) * 255) / 120;
green = (degrees * 255) / 120;
blue = 0;
}else if (degrees < 240){
degrees -= 120;
red = 0;
green = ((120 - degrees) * 255) / 120;
blue = (degrees * 255) / 120;
}else{
degrees -= 240;
red = (degrees * 255) / 120;
green = 0;
blue = ((120 - degrees) * 255) / 120;
}
return (0xFF000000 | blue << 16 | green << 8 | red);
}