Skip to content
Merged
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 src/samples/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ SAMPLES = \
gu/morph \
gu/morphskin \
gu/ortho \
gu/pixelmask \
gu/reflection \
gu/rendertarget \
gu/scissor \
Expand Down
1 change: 1 addition & 0 deletions src/samples/Makefile.samples
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SAMPLES = \
gu/morphskin \
gu/mipmapping \
gu/ortho \
gu/pixelmask \
gu/reflection \
gu/rendertarget \
gu/scissor \
Expand Down
19 changes: 19 additions & 0 deletions src/samples/gu/pixelmask/Makefile.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
TARGET = pixelmask
OBJS = pixelmask.o ../common/callbacks.o

INCDIR =
CFLAGS = -Wall -O2
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LDFLAGS =
LIBS = -lpspgu

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = PixelMask Sample

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


165 changes: 165 additions & 0 deletions src/samples/gu/pixelmask/pixelmask.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* PSP Software Development Kit - https://github.com/pspdev
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* PixelMask sample - Demonstrates sceGuPixelMask channel write-masking
*/

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include <pspctrl.h>
#include <pspgu.h>
#include <psprtc.h>

#include "../common/callbacks.h"

PSP_MODULE_INFO("PixelMask Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);

static unsigned int __attribute__((aligned(16))) list[1024];

#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)

#define COLOR_BLACK 0x00000000

typedef struct PixelMaskMode
{
const char *description;
unsigned int mask;
} PixelMaskMode;

#define TEXTURE_FORMAT GU_PSM_8888
// In mask 0xAABBGGRR: 1-bits prevent writes to that bit, 0-bits allow writes.
// Keep AA=0x00 so alpha writes remain enabled for all modes in this sample.
static const PixelMaskMode modes[] = {
{"Mask 0x00000000: All channels writable", 0x00000000},
{"Mask 0x0000FFFF: Only Blue (+Alpha) writable", 0x0000FFFF}, // R=0xFF, G=0xFF, B=0x00, A=0x00
{"Mask 0x00FF00FF: Only Green (+Alpha) writable", 0x00FF00FF}, // R=0xFF, G=0x00, B=0xFF, A=0x00
{"Mask 0x00FFFF00: Only Red (+Alpha) writable", 0x00FFFF00}, // R=0x00, G=0xFF, B=0xFF, A=0x00
};

// GU_PSM_8888, 8x8. Where the 2 first columns are red and the 2 last columns are green.
static uint32_t __attribute__((aligned(16))) pixels[64] = {
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFF,
};

struct Vertex
{
short u, v;
short x, y, z;
};

void blit()
{
struct Vertex *vertices = (struct Vertex *)sceGuGetMemory(2 * sizeof(struct Vertex));

vertices[0].u = 0;
vertices[0].v = 0;
vertices[0].x = 0;
vertices[0].y = 0;
vertices[0].z = 0;

vertices[1].u = 8;
vertices[1].v = 8;
vertices[1].x = SCR_WIDTH;
vertices[1].y = SCR_HEIGHT;
vertices[1].z = 0;

sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices);
}

int main(int argc, char *argv[])
{
int mode_index = 0;
int frame_counter = 0;
int drawFormat = GU_PSM_5650;

pspDebugScreenInit();
setupCallbacks();

// Setup GU

void *fbp0 = guGetStaticVramBuffer(BUF_WIDTH, SCR_HEIGHT, drawFormat);
void *fbp1 = guGetStaticVramBuffer(BUF_WIDTH, SCR_HEIGHT, drawFormat);

sceGuInit();

sceGuStart(GU_DIRECT, list);
sceGuDrawBuffer(drawFormat, fbp0, BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, fbp1, BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH / 2), 2048 - (SCR_HEIGHT / 2));
sceGuViewport(2048, 2048, SCR_WIDTH, SCR_HEIGHT);
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuEnable(GU_TEXTURE_2D);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);

sceGuTexMode(TEXTURE_FORMAT, 0, 0, 0);
sceGuTexImage(0, 8, 8, 8, pixels);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); // don't get influenced by any vertex colors
sceGuTexFilter(GU_NEAREST, GU_NEAREST); // point-filtered sampling

sceGuFinish();
sceGuSync(GU_SYNC_FINISH, GU_SYNC_WHAT_DONE);

sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);

sceKernelDcacheWritebackAll();

pspDebugScreenInitEx(fbp0, drawFormat, 1);

while (running())
{
sceGuStart(GU_DIRECT, list);

sceGuClearColor(COLOR_BLACK);
sceGuClear(GU_COLOR_BUFFER_BIT);

// Apply current pixel mask and draw color bars
sceGuPixelMask(modes[mode_index].mask);
blit();
sceGuPixelMask(0);

sceGuFinish();
sceGuSync(GU_SYNC_FINISH, GU_SYNC_WHAT_DONE);

// HUD text
pspDebugScreenSetOffset((int)fbp0);
pspDebugScreenSetXY(0, 0);
pspDebugScreenPrintf("sceGuPixelMask demo\n");
pspDebugScreenPrintf("%s\n", modes[mode_index].description);

sceDisplayWaitVblankStart();
fbp0 = sceGuSwapBuffers();

// Rotate mode every ~2 seconds (assuming ~60 FPS)
frame_counter++;
if (frame_counter >= 120)
{
frame_counter = 0;
mode_index = (mode_index + 1) % (sizeof(modes) / sizeof(modes[0]));
}
}

sceGuTerm();

sceKernelExitGame();
return 0;
}