Files
pspsdk/src/samples/gu/lines/lines.c
2025-05-01 20:31:37 +02:00

205 lines
4.5 KiB
C

/*
* PSP Software Development Kit - https://github.com/pspdev
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* Copyright (c) 2005 Jesper Svennevid
*/
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <pspgu.h>
#include "../common/callbacks.h"
PSP_MODULE_INFO("Lines Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
static unsigned int __attribute__((aligned(16))) list[262144];
struct Vertex
{
float x,y,z;
};
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
unsigned int colors[8] =
{
0xffff0000,
0xffff00ff,
0xff0000ff,
0xff00ffff,
0xff00ff00,
0xffffff00,
0xffffffff,
0xff00ffff
};
#define NUM_LINES 12
#define NUM_VERTICES 8
#define SPEED 4.0f
#define FADE_SPEED 0.015f;
struct Vertex lines[NUM_LINES][NUM_VERTICES];
unsigned int curr_line = 0;
struct Vertex position[8];
struct Vertex direction[8];
float fade = 0;
unsigned int color_index = 0;
int main(int argc, char* argv[])
{
unsigned int i;
setupCallbacks();
// initialize lines
memset(lines,0,sizeof(lines));
srand(time(0));
for (i = 0; i < NUM_VERTICES; ++i)
{
position[i].x = (((float)rand())/RAND_MAX) * (SCR_WIDTH-1);
position[i].y = (((float)rand())/RAND_MAX) * (SCR_HEIGHT-1);
direction[i].x = (((float)rand())/(RAND_MAX/2)-1.0f) * SPEED;
direction[i].y = (((float)rand())/(RAND_MAX/2)-1.0f) * SPEED;
}
// setup GU
void* fbp0 = guGetStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* fbp1 = guGetStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* zbp = guGetStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444);
sceGuInit();
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH);
sceGuDepthBuffer(zbp,BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(65535,0);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuFinish();
sceGuSync(GU_SYNC_FINISH, GU_SYNC_WHAT_DONE);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
// run sample
while(running())
{
unsigned int i,j;
unsigned int result;
// update lines
for (i = 0; i < NUM_VERTICES; ++i)
{
position[i].x += direction[i].x;
position[i].y += direction[i].y;
if (position[i].x < 0)
{
position[i].x = 0;
direction[i].x = (((float)rand())/RAND_MAX) * SPEED;
direction[i].y += 0.1f * (direction[i].y / fabsf(direction[i].y));
}
else if (position[i].x >= SCR_WIDTH)
{
position[i].x = (SCR_WIDTH-1);
direction[i].x = -(((float)rand())/RAND_MAX) * SPEED;
direction[i].y += 0.1f * (direction[i].y / fabsf(direction[i].y));
}
if (position[i].y < 0)
{
position[i].y = 0;
direction[i].x += 0.1f * (direction[i].x / fabsf(direction[i].x));
direction[i].y = (0.1f+((float)rand())/RAND_MAX) * SPEED;
}
else if (position[i].y >= SCR_HEIGHT)
{
position[i].y = (SCR_HEIGHT-1);
direction[i].x += 0.1f * (direction[i].x / fabsf(direction[i].x));
direction[i].y = -(0.1f+((float)rand())/RAND_MAX) * SPEED;
}
lines[curr_line][i].x = position[i].x;
lines[curr_line][i].y = position[i].y;
}
curr_line = (curr_line+1) % NUM_LINES;
fade += FADE_SPEED;
if (fade >= 1.0f)
{
fade -= 1.0f;
color_index = (color_index+1) & 7;
}
sceGuStart(GU_DIRECT,list);
// clear screen
sceGuClearColor(0);
sceGuClear(GU_COLOR_BUFFER_BIT);
// render lines
result = 0;
for (i = 0; i < 4; ++i)
{
int ca = (colors[color_index] >> (i*8)) & 0xff;
int cb = (colors[(color_index+1)&7] >> (i*8)) & 0xff;
result |= ((unsigned char)(ca + (cb-ca) * fade)) << (i*8);
}
sceGuColor(result);
for (i = 0; i < NUM_LINES; ++i)
{
// we make local copies of the line into the main buffer here, so we don't have to flush the cache
struct Vertex* vertices = sceGuGetMemory((NUM_VERTICES+1) * sizeof(struct Vertex));
// create a lineloop
for (j = 0; j < NUM_VERTICES; ++j)
vertices[j] = lines[i][j];
vertices[NUM_VERTICES] = lines[i][0];
sceGuDrawArray(GU_LINE_STRIP,GU_VERTEX_32BITF|GU_TRANSFORM_2D,(NUM_VERTICES+1),0,vertices);
}
// wait for next frame
sceGuFinish();
sceGuSync(GU_SYNC_FINISH, GU_SYNC_WHAT_DONE);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
sceGuTerm();
sceKernelExitGame();
return 0;
}