在PSP上画图



掌叔
2008-06-10 09:09:16

摘自:在PSP上画图
作者:vcbear

这几天把公司的事情忙的差不多了,于是继续我的PSP开发学习,呵呵。上次学会了PSP程序的运行框架以及简单的按键检测,下面就开始深入一点的学习了,这次是通过编程在PSP上画简单的图形,好了,不多说了,看下面的代码:
[code=c]
-- psptest.c

#include
#include
#include


#define SCREEN_WIDTH 480 // PSP屏幕宽
#define SCREEN_HEIGHT 272 // PSP屏幕高

#define SCAN_LINE_SIZE 512 // 最大屏幕宽有32个单位

#define ARGB(a, r, g, b) (a<<24|b<<16|g<<8|r) // 当屏幕设定为32bit一个像素时, 颜色的排列是ABGR, 即透明度, 蓝,绿, 红 设定该转换宏便于计算


// 程序名称和版本
PSP_MODULE_INFO("PSPGame", 0, 1, 1);

// optional
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);

#define printf pspDebugScreenPrintf

int done = 0;

u32* pVRAM = (u32*)(0x04000000+0x40000000); // 初始化VRAM,一定要OR 0x40000000才可使用



//------------------以下为退出线程的功能------------------------//
int exit_callback(int arg1, int arg2, void *common)
{
done = 1;
return 0;
}


int CallbackThread(SceSize args, void *argp)
{
int cbid;

cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);

sceKernelSleepThreadCB();

return 0;
}


int SetupCallbacks(void)
{
int thid = 0;

thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}

return thid;
}


//------------------以下为主函数中用到的用户函数------------------------
// 在指定位置画指定颜色的单像素点
void Plot(int x, int y, u32 color)
{
u32* p = pVRAM + y * SCAN_LINE_SIZE + x;
*p = color;
}


// 用指定颜色填充指定大小的矩形
void FillRect(int x, int y, int width, int height, u32 color)
{
// 取VRAM首地址
u32* p = pVRAM + y * SCAN_LINE_SIZE + x;
int i, j;
for (j=0;j
{
for (i=0;i// 先画横线
{
*(p+i) = color;
}
p += SCAN_LINE_SIZE; // 纵向下移一行
}
}



//加入一个截图功能,在按“home”键退出本程序时,自动在记忆卡根目录生成一个“screenshot.tga”的图片
void WriteByte(int fd, unsigned char data)
{
sceIoWrite(fd, &data, 1);
}


void ScreenShot()
{
const char tgaHeader[] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int width = SCREEN_WIDTH;
const int lineWidth = SCAN_LINE_SIZE;
const int height = SCREEN_HEIGHT;
unsigned char lineBuffer[width*4];
u32* vram = pVRAM;
int x, y;
int fd = sceIoOpen("ms0:/screenshot.tga", PSP_O_CREAT | PSP_O_TRUNC | PSP_O_WRONLY, 0777);
if (!fd) return;
sceIoWrite(fd, tgaHeader, sizeof(tgaHeader));
WriteByte(fd, width & 0xff);
WriteByte(fd, width >> 8);
WriteByte(fd, height & 0xff);
WriteByte(fd, height >> 8);
WriteByte(fd, 24);
WriteByte(fd, 0);
for (y = height - 1; y >= 0; y--) {
for (x = 0; x < width; x++) {
u32 color = vram[y * lineWidth + x];
unsigned char red = color & 0xff;
unsigned char green = (color >> 8) & 0xff;
unsigned char blue = (color >> 16) & 0xff;
lineBuffer[3*x] = blue;
lineBuffer[3*x+1] = green;
lineBuffer[3*x+2] = red;
}
sceIoWrite(fd, lineBuffer, width * 3);
}
sceIoClose(fd);
}


//------------------以下为主函数------------------------//
int main()
{
pspDebugScreenInit(); // do this so that we can use pspDebugScreenPrintf
SetupCallbacks();

// mode 0, pixel format: ABGR
sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT);


while (!done)
{
// plot some pixels
Plot(50, 20, ARGB(255,255,0,0)); // a red pixel
Plot(100, 20, ARGB(255,0,255,0)); // a green pixel
Plot(300, 20, ARGB(255,0,0,255)); // a blue pixel

// fill some color rectangles
FillRect(50, 100, 20, 20, ARGB(0,255,0,0)); // a red rectangle
FillRect(100, 150, 20, 20, ARGB(255,0,255,0)); // a green rectangle
FillRect(300, 200, 20, 20, ARGB(255,0,0,255)); // a blue rectangle

sceDisplayWaitVblankStart();
}

ScreenShot();

sceKernelExitGame();
return 0;
}



--makefile



TARGET = PSPTEST
OBJS = psptest.o

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

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = PSPTEST

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

好了!然后把PSP和电脑连接好,进入USB模式,用工具软件KXploit Tool 0.3 将生成的可执行文件拷入小P,以下是程序运行生成好的截图。
[attach]81[/attach]


zl308424
2009-01-05 00:08:50

太好了,找了很久关于画图的资料,谢谢了


ouou
2010-05-02 13:06:38

大虾,我EMAIL:954059307@QQ.COM,能不能把完整的代码发给我。谢谢。


ouou
2010-05-02 13:26:26

恩。我试了下,您发的头文件和void FillRect(int x, int y, int width, int height, u32 color)
函数不完整。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

以上的是头文件。
下面是完整的void FillRect(int x, int y, int width, int height, u32 color)函数

void FillRect(int x, int y, int width, int height, u32 color)
{
// 取VRAM首地址
u32* p = pVRAM + y * SCAN_LINE_SIZE + x;
int i, j;
for (j=0;j{
for (i=0;i {
*(p+i) = color;
}
p += SCAN_LINE_SIZE; // 纵向下移一行
}
}
再次向您表示感谢您发的代码。


mxd179
2010-07-28 15:47:00

受教了
小P还能当画板