main.c
Code: Select all
#include <pspdisplay.h>
#include <pspctrl.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspgu.h>
#include <stdio.h>
#include "graphics.h"
int main()
{
char buffer[200];
BITMAP* image;
pspDebugScreenInit();
initGraphics();
sprintf(buffer, "title.pcx");
image = load_pcx(buffer,0);
if (!image)
{
//Image load failed
printf("Image load failed!\n");
}
else
{
int x = 0;
int y = 0;
sceDisplayWaitVblankStart();
blitImageToScreen(0,0,300,200,image,x,y);
flipScreen();
}
sceKernelSleepThread();
return 0;
}
Code: Select all
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <pspdisplay.h>
#include <psputils.h>
#include <pspgu.h>
#include "graphics.h"
Color* g_vram_base = (Color*) (0x40000000 | 0x04000000);
#define IS_ALPHA(color) (((color)&0xff000000)==0xff000000?0:1)
#define FRAMEBUFFER_SIZE (PSP_LINE_SIZE*SCREEN_HEIGHT*4)
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
BITMAP* screen = NULL;
BITMAP* buffer = NULL;
typedef struct
{
unsigned short u, v;
short x, y, z;
} Vertex;
extern u8 msx[];
unsigned int __attribute__((aligned(16))) list[262144];
static int dispBufferNumber;
static int initialized = 0;
static int getNextPower2(int width)
{
int b = width;
int n;
for (n = 0; b != 0; n++) b >>= 1;
b = 1 << n;
if (b == 2 * width) b >>= 1;
return b;
}
Color* getVramDrawBuffer()
{
Color* vram = (Color*) g_vram_base;
if (dispBufferNumber == 0) vram += FRAMEBUFFER_SIZE / sizeof(Color);
return vram;
}
Color* getVramDisplayBuffer()
{
Color* vram = (Color*) g_vram_base;
if (dispBufferNumber == 1) vram += FRAMEBUFFER_SIZE / sizeof(Color);
return vram;
}
BITMAP *load_pcx(const char* filename,PALETTE pal)
{
FILE *df;
unsigned long offset =4;
int w = 0,h = 0;
int c,i,j,numRepeat;
unsigned char xMin,yMin,xMax,yMax;
unsigned char *line,*pixData = NULL,*palData;
BITMAP* pcx = (BITMAP*) malloc(sizeof(BITMAP));
if (!pcx) return NULL;
if ((df = fopen(filename, "rb")) == NULL) return NULL;
rewind(df);
fgetc(df);
fgetc(df);
fgetc(df);
fgetc(df);
xMin = fgetc(df); xMin |= fgetc(df) << 8;
yMin = fgetc(df); yMin |= fgetc(df) << 8;
xMax = fgetc(df); xMax |= fgetc(df) << 8;
yMax = fgetc(df); yMax |= fgetc(df) << 8;
pcx->imageWidth = xMax - xMin + 1;
pcx->imageHeight = yMax - yMin + 1;
offset+=53;
offset+=60;
line = (unsigned char*)malloc(w*h);
fseek(df, 128, SEEK_SET);
pcx = create_bitmap(w,h);
for (i = 0;i < (w*h);i++)
{
c = getc(df);
if (c > 0xbf)
{
numRepeat = 0x3f & c;
c = getc(df);
for (j = 0;j < numRepeat;j++)
{
pixData[i++] = c;
}
}
else
pixData[i++] = c;
fflush(stdout);
}
palData = (unsigned char*)malloc(768);
fseek(df, -769, SEEK_END);
c = getc(df);
for (i = 0; i < 768; i++)
{
c = getc(df);
palData[i] = c;
}
free(line);
fclose(df);
return pcx;
}
void blitImageToImage(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy, BITMAP* destination)
{
Color* destinationData = &destination->data[destination->textureWidth * dy + dx];
int destinationSkipX = destination->textureWidth - width;
Color* sourceData = &source->data[source->textureWidth * sy + sx];
int sourceSkipX = source->textureWidth - width;
int x, y;
for (y = 0; y < height; y++, destinationData += destinationSkipX, sourceData += sourceSkipX) {
for (x = 0; x < width; x++, destinationData++, sourceData++) {
*destinationData = *sourceData;
}
}
}
void blitImageToScreen(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy)
{
if (!initialized) return;
Color* vram = getVramDrawBuffer();
sceKernelDcacheWritebackInvalidateAll();
guStart();
sceGuCopyImage(GU_PSM_8888, sx, sy, width, height, source->textureWidth, source->data, dx, dy, PSP_LINE_SIZE, vram);
sceGuFinish();
sceGuSync(0,0);
}
void blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)
{
if (dest->data==getVramDisplayBuffer())
{
blitImageToScreen(source_x,source_y,width,height,source,dest_x,dest_y);
}
else
{
blitImageToImage(source_x,source_y,width,height,source,dest_x,dest_y,dest);
}
}
void blitAlphaImageToImage(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy, BITMAP* destination)
{
// TODO Blend!
Color* destinationData = &destination->data[destination->textureWidth * dy + dx];
int destinationSkipX = destination->textureWidth - width;
Color* sourceData = &source->data[source->textureWidth * sy + sx];
int sourceSkipX = source->textureWidth - width;
int x, y;
for (y = 0; y < height; y++, destinationData += destinationSkipX, sourceData += sourceSkipX) {
for (x = 0; x < width; x++, destinationData++, sourceData++) {
Color color = *sourceData;
if (!IS_ALPHA(color)) *destinationData = color;
}
}
}
void blitAlphaImageToScreen(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy)
{
if (!initialized) return;
sceKernelDcacheWritebackInvalidateAll();
guStart();
sceGuTexImage(0, source->textureWidth, source->textureHeight, source->textureWidth, (void*) source->data);
float u = 1.0f / ((float)source->textureWidth);
float v = 1.0f / ((float)source->textureHeight);
sceGuTexScale(u, v);
int j = 0;
while (j < width) {
Vertex* vertices = (Vertex*) sceGuGetMemory(2 * sizeof(Vertex));
int sliceWidth = 64;
if (j + sliceWidth > width) sliceWidth = width - j;
vertices[0].u = sx + j;
vertices[0].v = sy;
vertices[0].x = dx + j;
vertices[0].y = dy;
vertices[0].z = 0;
vertices[1].u = sx + j + sliceWidth;
vertices[1].v = sy + height;
vertices[1].x = dx + j + sliceWidth;
vertices[1].y = dy + height;
vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices);
j += sliceWidth;
}
sceGuFinish();
sceGuSync(0, 0);
}
BITMAP* create_bitmap(int width, int height)
{
BITMAP* image = (BITMAP*) malloc(sizeof(BITMAP));
if (!image) return NULL;
image->imageWidth = width;
image->imageHeight = height;
image->textureWidth = getNextPower2(width);
image->textureHeight = getNextPower2(height);
image->data = (Color*) memalign(16, image->textureWidth * image->textureHeight * sizeof(Color));
if (!image->data) return NULL;
memset(image->data, 0, image->textureWidth * image->textureHeight * sizeof(Color));
return image;
}
void destroy_bitmap(BITMAP* image)
{
free(image->data);
free(image);
}
void clearImage(Color color, BITMAP* image)
{
int i;
int size = image->textureWidth * image->textureHeight;
Color* data = image->data;
for (i = 0; i < size; i++, data++) *data = color;
}
void clearScreen(Color color)
{
if (!initialized) return;
guStart();
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuFinish();
sceGuSync(0, 0);
}
void clear_to_color(BITMAP *bitmap,Color color)
{
if (bitmap->data==getVramDisplayBuffer())
{
clearScreen(color);
}
else
{
clearImage(color,bitmap);
}
}
void fillImageRect(Color color, int x0, int y0, int width, int height, BITMAP* image)
{
int skipX = image->textureWidth - width;
int x, y;
Color* data = image->data + x0 + y0 * image->textureWidth;
for (y = 0; y < height; y++, data += skipX) {
for (x = 0; x < width; x++, data++) *data = color;
}
}
void fillScreenRect(Color color, int x0, int y0, int width, int height)
{
if (!initialized) return;
int skipX = PSP_LINE_SIZE - width;
int x, y;
Color* data = getVramDrawBuffer() + x0 + y0 * PSP_LINE_SIZE;
for (y = 0; y < height; y++, data += skipX) {
for (x = 0; x < width; x++, data++) *data = color;
}
}
void rectfill(BITMAP *bmp,int x1, int y1, int x2, int y2, Color color)
{
int width,height;
width=x1-x2;
height=y1-y2;
if (bmp->data==getVramDisplayBuffer())
{
fillScreenRect(color,x1,y1,width,height);
}
else
{
fillImageRect(color,x1,y1,width,height,bmp);
}
}
void putPixelScreen(Color color, int x, int y)
{
Color* vram = getVramDrawBuffer();
vram[PSP_LINE_SIZE * y + x] = color;
}
void putPixelImage(Color color, int x, int y, BITMAP* image)
{
image->data[x + y * image->textureWidth] = color;
}
void putpixel(BITMAP *bmp, int x, int y, Color color)
{
if (bmp->data==getVramDisplayBuffer())
{
putPixelScreen(color,x,y);
}
else
{
putPixelImage(color,x,y,bmp);
}
}
Color getPixelScreen(int x, int y)
{
Color* vram = getVramDrawBuffer();
return vram[PSP_LINE_SIZE * y + x];
}
Color getPixelImage(int x, int y, BITMAP* image)
{
return image->data[x + y * image->textureWidth];
}
void getpixel(BITMAP *bmp, int x, int y)
{
if (bmp->data==getVramDisplayBuffer())
{
getPixelScreen(x,y);
}
else
{
getPixelImage(x,y,bmp);
}
}
void printTextScreen(int x, int y, const char* text, u32 color)
{
int c, i, j, l;
u8 *font;
Color *vram_ptr;
Color *vram;
if (!initialized) return;
for (c = 0; c < strlen(text); c++) {
if (x < 0 || x + 8 > SCREEN_WIDTH || y < 0 || y + 8 > SCREEN_HEIGHT) break;
char ch = text[c];
vram = getVramDrawBuffer() + x + y * PSP_LINE_SIZE;
font = &msx[ (int)ch * 8];
for (i = l = 0; i < 8; i++, l += 8, font++) {
vram_ptr = vram;
for (j = 0; j < 8; j++) {
if ((*font & (128 >> j))) *vram_ptr = color;
vram_ptr++;
}
vram += PSP_LINE_SIZE;
}
x += 8;
}
}
void printTextImage(int x, int y, const char* text, u32 color, BITMAP* image)
{
int c, i, j, l;
u8 *font;
Color *data_ptr;
Color *data;
if (!initialized) return;
for (c = 0; c < strlen(text); c++) {
if (x < 0 || x + 8 > image->imageWidth || y < 0 || y + 8 > image->imageHeight) break;
char ch = text[c];
data = image->data + x + y * image->textureWidth;
font = &msx[ (int)ch * 8];
for (i = l = 0; i < 8; i++, l += 8, font++) {
data_ptr = data;
for (j = 0; j < 8; j++) {
if ((*font & (128 >> j))) *data_ptr = color;
data_ptr++;
}
data += image->textureWidth;
}
x += 8;
}
}
void saveImage(const char* filename, Color* data, int width, int height, int lineSize, int saveAlpha)
{
}
//int save_bitmap(const char *filename, BITMAP *bmp,const RGB *pal)
//{
// if (bmp->data==getVramDisplayBuffer())
// {
// return saveImage(filename,getVramDisplayBuffer(),SCREEN_WIDTH,SCREEN_HEIGHT,PSP_LINE_SIZE,0);
// }
// else
// {
// return saveImage(filename,bmp->data,bmp->imageWidth,bmp->imageHeight,bmp->textureWidth,0);
// }
//}
void flipScreen()
{
if (!initialized) return;
sceGuSwapBuffers();
dispBufferNumber ^= 1;
}
static void drawLine(int x0, int y0, int x1, int y1, int color, Color* destination, int width)
{
int dy = y1 - y0;
int dx = x1 - x0;
int stepx, stepy;
if (dy < 0) { dy = -dy; stepy = -width; } else { stepy = width; }
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
dy <<= 1;
dx <<= 1;
y0 *= width;
y1 *= width;
destination[x0+y0] = color;
if (dx > dy) {
int fraction = dy - (dx >> 1);
while (x0 != x1) {
if (fraction >= 0) {
y0 += stepy;
fraction -= dx;
}
x0 += stepx;
fraction += dy;
destination[x0+y0] = color;
}
} else {
int fraction = dx - (dy >> 1);
while (y0 != y1) {
if (fraction >= 0) {
x0 += stepx;
fraction -= dy;
}
y0 += stepy;
fraction += dx;
destination[x0+y0] = color;
}
}
}
void drawLineScreen(int x0, int y0, int x1, int y1, Color color)
{
drawLine(x0, y0, x1, y1, color, getVramDrawBuffer(), PSP_LINE_SIZE);
}
void drawLineImage(int x0, int y0, int x1, int y1, Color color, BITMAP* image)
{
drawLine(x0, y0, x1, y1, color, image->data, image->textureWidth);
}
void line(BITMAP *bmp, int x1, int y1, int x2, int y2, Color color)
{
if (bmp->data==getVramDisplayBuffer())
{
drawLineScreen(x1,y1,x2,y2,color);
}
else
{
drawLineImage(x1,y1,x2,y2,color,bmp);
}
}
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (4) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
void initGraphics()
{
dispBufferNumber = 0;
sceGuInit();
guStart();
sceGuDrawBuffer(GU_PSM_8888, (void*)FRAMEBUFFER_SIZE, PSP_LINE_SIZE);
sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void*)0, PSP_LINE_SIZE);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
sceGuDepthBuffer((void*) (FRAMEBUFFER_SIZE*2), PSP_LINE_SIZE);
sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2));
sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuDepthRange(0xc350, 0x2710);
sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuAlphaFunc(GU_GREATER, 0, 0xff);
sceGuEnable(GU_ALPHA_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuEnable(GU_CLIP_PLANES);
sceGuTexMode(GU_PSM_8888, 0, 0, 0);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
sceGuAmbientColor(0xffffffff);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
initialized = 1;
}
void disableGraphics()
{
initialized = 0;
}
void guStart()
{
sceGuStart(GU_DIRECT, list);
}
Code: Select all
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include <psptypes.h>
#define PSP_LINE_SIZE 512
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
//extern u32* g_vram_base;
#define GFX_TEXT 0
#define GFX_DIRECTX_WIN 1
#define GFX_DIRECTX_ACCEL 2
#define GFX_DIRECTX_SOFT 3
#define DRAW_MODE_COPY_PATTERN 0
#define DRAW_MODE_SOLID 1
#define FONT unsigned char
typedef u32 Color;
#define A(color) ((u8)(color >> 24 & 0xFF))
#define B(color) ((u8)(color >> 16 & 0xFF))
#define G(color) ((u8)(color >> 8 & 0xFF))
#define R(color) ((u8)(color & 0xFF))
#define makecol(r,g,b) ((r)|((g)<<8)|((b)<<16))
typedef struct RGB
{
unsigned char r, g, b;
unsigned char filler;
} RGB;
typedef RGB PALETTE[256];
//typedef Color PALETTE[256];
typedef struct
{
int textureWidth; // the real width of data, 2^n with n>=0
int textureHeight; // the real height of data, 2^n with n>=0
int imageWidth; // the image width
int imageHeight;
Color* data;
} BITMAP;
typedef struct
{
Color* pal;
int nbc;
int w,h;
int x,y;
int chche_idx;
int cache_hits;
int size;
unsigned char* buf;
} RLE_SPRITE;
typedef struct
{
int w,h,x,y;
} RECT;
//#define PALETTE unsigned char
extern BITMAP* screen;
//extern PALLETE black_palette;
extern FONT* font;
extern BITMAP* load_pcx(const char* filename,PALETTE pal);
extern void blitImageToImage(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy, BITMAP* destination);
extern void blitImageToScreen(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy);
extern void blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
extern void blitAlphaImageToImage(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy, BITMAP* destination);
extern void blitAlphaImageToScreen(int sx, int sy, int width, int height, BITMAP* source, int dx, int dy);
extern BITMAP* create_bitmap(int width, int height);
extern void destroy_bitmap(BITMAP* image);
extern void clearImage(Color color, BITMAP* image);
extern void clearScreen(Color color);
extern void clear_to_color(BITMAP *bitmap,Color color);
extern void fillImageRect(Color color, int x0, int y0, int width, int height, BITMAP* image);
extern void fillScreenRect(Color color, int x0, int y0, int width, int height);
extern void rectfill(BITMAP *bmp,int x1, int y1, int x2, int y2, Color color);
extern void putPixelScreen(Color color, int x, int y);
extern void putPixelImage(Color color, int x, int y, BITMAP* image);
extern void putpixel(BITMAP *bmp, int x, int y, Color color);
extern Color getPixelScreen(int x, int y);
extern Color getPixelImage(int x, int y, BITMAP* image);
extern void getpixel(BITMAP *bmp, int x, int y);
extern void printTextScreen(int x, int y, const char* text, u32 color);
extern void printTextImage(int x, int y, const char* text, u32 color, BITMAP* image);
extern void saveImage(const char* filename, Color* data, int width, int height, int lineSize, int saveAlpha);
//extern int save_bitmap(const char *filename, BITMAP *bmp,const RGB *pal);
extern void flipScreen();
extern void initGraphics();
extern void disableGraphics();
void drawLineScreen(int x0, int y0, int x1, int y1, Color color);
extern void drawLineImage(int x0, int y0, int x1, int y1, Color color, BITMAP* image);
extern void line(BITMAP *bmp, int x1, int y1, int x2, int y2, Color color);
extern Color* getVramDrawBuffer();
extern Color* getVramDisplayBuffer();
extern void guStart();
#endif
//BITMAP *screen;
//screen->imageWidth=SCREEN_W;
//screen->imageHeight=SCEEN_H;
//screen->textureWidth=1;
//screen->textureHeight=PSP_LINE_SIZE;
//screen->data=getVramDisplayBuffer();
//BITMAP *buffer;
//buffer->imageWidth=SCREEN_W;
//buffer->imageHeight=SCEEN_H;
//buffer->textureWidth=1;
//buffer->textureHeight=PSP_LINE_SIZE;
//buffer->data=getVramDrawBuffer();