Code: Select all
// main.c
//This code is just a skeleton for your own programs
// This code was created by Jeff Molofee '99 (ported to Linux/GLUT by Richard Campbell '99)
//
// If you've found this code useful, please let me know.
//
// Visit me at www.demonews.com/hosted/nehe
// (email Richard Campbell at [email protected])
//
// this was modified to work on PSP by Edorul ([email protected])
// Many Thanks to jared bruni ([email protected]) for is
// MasterPiece3D port to PSP : it gave me a good sample and not
// the least a working makefile !
// important notes : - all modified portion of code from cygwin version
// of Nehe tutorial are marked with @@@
// Used keys :
// START = exit
#include <stdlib.h> // needed in order to have "exit" function @@@
#include <stdio.h>
#include <jpeglib.h>
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
/* The number of our GLUT window */
int window;
int page;
int loading;
unsigned int tex[1];
void loadJPEG(char *filename)
{
int i, y, rowsRead;
unsigned char* m_data;
unsigned char** rowPtr;
if(loading == 0)
{
loading = 1;
glDeleteTextures(1, &tex[0]);
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
FILE* infile;
if ((infile = fopen(filename, "rb")) == NULL)
{
exit(0);
}
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
y = cinfo.image_height;
m_data = (unsigned char *) malloc(sizeof(unsigned char)*512*512*3);
rowPtr = (unsigned char**) malloc(sizeof(unsigned char*)*y);
for (i = 0; i < y; i++)
{
rowPtr[i] = &(m_data[i*512*3]);
}
jpeg_start_decompress(&cinfo);
rowsRead = cinfo.output_height - 1;
while (cinfo.output_scanline < cinfo.output_height)
{
rowsRead -= jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], 1);
}
free(rowPtr);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex[0]);
glBindTexture(GL_TEXTURE_2D, tex[0]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 512 , 512, 0, GL_RGB, GL_UNSIGNED_BYTE, m_data);
free(m_data);
loading = 0;
}
}
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
{
loading = 0;
page = 1;
loadJPEG("01.jpg");
glClearColor(0.0f, 1.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
// gluPerspective(45.0f,(float)Width/(float)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Prevent A Divide By Zero If The Window Is Too Small
Height=1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// gluPerspective(45.0f,(float)Width/(float)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* The main drawing function. */
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, tex[0]);
glTranslatef(0.0, 0.0, -1.0);
glBegin(GL_QUADS);
float x_d = (512 - 480) / 512.0;
float y_d = (512 - 272) / 512.0;
glTexCoord2f(0.0, 0.0);
glVertex3d(-1.0, -1.0, 0.5);
glTexCoord2d(1 - x_d, 0.0);
glVertex3d(1.0, -1.0, 0.5);
glTexCoord2d(1 - x_d, 1 - y_d);
glVertex3d(1.0, 1.0, 0.5);
glTexCoord2d(0.0, 1 - y_d);
glVertex3d(-1.0, 1.0, 0.5);
glEnd();
glutSwapBuffers();
}
/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
switch (key) {
case 'd': /* delta, triangle */
break;
case 'o': /* round */
break;
case 'q': /* square*/
break;
case 'x': /* cross */
break;
case 'n': /* key with the music note */
break;
case 's': /* select */
break;
case 'a': /* startbutton */ /* If START is pressed, kill everything. */
/* exit the program...normal termination. */
exit(0);
default:
;
}
}
/* The function called whenever a key is released. */
void keyReleased(unsigned char key, int x, int y)
{
switch (key) {
case 'd': /* delta, triangle */
break;
case 'o': /* round */
break;
case 'q': /* square*/
break;
case 'x': /* cross */
break;
case 'n': /* key with the music note */
break;
case 's': /* select */
break;
case 'a': /* startbutton */
break;
default:
;
}
}
/* The function called whenever a special key is pressed. */
void specialKeyPressed(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP: // pad arrow up
break;
case GLUT_KEY_DOWN: // pad arrow down
break;
case GLUT_KEY_LEFT: // pad arrow left
break;
case GLUT_KEY_RIGHT: // pad arrow right
break;
case GLUT_KEY_HOME: // home
break;
default:
break;
}
}
/* The function called whenever a special key is released. */
void specialKeyReleased(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP: // pad arrow up
break;
case GLUT_KEY_DOWN: // pad arrow down
break;
case GLUT_KEY_LEFT: // pad arrow left
if(page > 1)
{
char nazwa[20];
page--;
sprintf(nazwa, "%.2i.jpg", page);
loadJPEG(nazwa); }
break;
case GLUT_KEY_RIGHT: // pad arrow right
if(page < 10)
{
char nazwa[20];
page++;
sprintf(nazwa, "%.2i.jpg", page);
loadJPEG(nazwa);
}
break;
case GLUT_KEY_HOME: // home
break;
default:
break;
}
}
/* The function called whenever the joystick is moved. */
void joystickMoved (unsigned int buttonMask, int x, int y, int z)
{
if (abs(x) > 150) // dead zone
{
// use x value
}
if (abs(y) > 150) // dead zone
{
// use y value
}
}
/* The function called whenever the triggers are pressed. */
void triggerHandle (int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON) { // left trigger...
if (state == GLUT_DOWN) { // ...is pressed
}
if (state == GLUT_UP) { // ...is released
}
}
if (button == GLUT_RIGHT_BUTTON) { // right trigger...
if (state == GLUT_DOWN) { // ...is pressed
}
if (state == GLUT_DOWN) { // ...is released
}
}
}
/* main function */
int main(int argc, char **argv)
{
/* Initialize GLUT state - glut will take any command line arguments that pertain to it or
X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
glutInit(&argc, argv);
/* Select type of Display mode:
Double buffer
RGBA color
Alpha components supported
Depth buffer */
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
/* get a 640 x 480 window */
glutInitWindowSize(480, 272);
/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);
/* Open a window */
window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99");
/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawGLScene);
/* Even if there are no events, redraw our gl scene. */
glutIdleFunc(&DrawGLScene);
/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);
/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
/* Register the function called when the keyboard is released. */
glutKeyboardUpFunc(&keyReleased);
/* Register the function called when special keys (arrows, page down, etc) are pressed. */
glutSpecialFunc(&specialKeyPressed);
/* Register the function called when special keys (arrows, page down, etc) are released. */
glutSpecialUpFunc(&specialKeyReleased);
/* Register the function called when joystick is moved. */
glutJoystickFunc(&joystickMoved, 0); // 0 = Joystick polling interval in milliseconds
/* Register the function called when Trigger_left or Trigger_right is pressed */
glutMouseFunc(&triggerHandle);
/* Initialize our window. */
InitGL(480, 272);
/* Start Event Processing Engine */
glutMainLoop();
return (0);
}
Code: Select all
TARGET = lesson1
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
PSPBIN = $(PSPSDK)/../bin
CFLAGS += -I$(PSPSDK)/../include -fsingle-precision-constant -g -Wall -O2
LIBS += -lglut -lGLU -lGL -lm -lc -lpsputility -lpspdebug -lpspge -lpspdisplay -lpspctrl -lpspsdk -lpspvfpu -lpsplibc -lpspuser -lpspkernel -lpsprtc -lpsppower -lstdc++ -ljpeg
LDFLAGS += -DMODULE_NAME="lesson1" psp-setup.c
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = LESSON1
# PSP_EBOOT_ICON = hero.png
# PSP_EBOOT_PIC1 = bg.png
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Code: Select all
// psp-setup.c
/**
* This file handles all the PSP-specific kernel setup and exit stuff.
*
* Is there some general interest for this file, so that we can place it
* somewhere in the compiler toolchain include path?
*
* Usage: Simply add
* -DMODULE_NAME="your-module-name" psp-setup.c
* to the LFLAGS or LDFLAGS of your project, so that this file is
* compiled in when gcc collects and links the final ELF binary.
*
* Options:
* -DMODULE_NAME="name" -- set the name (default NONAME)
* -DMODULE_ATTR=0 -- module attributes (default 0)
* -DVERSION_MAJOR=1 -- version 1.x (default 1)
* -DVERSION_MINOR=0 -- version x.0 (default 0)
*
* Note: The linker flags and library lists need to be placed after this
* entry on the LFLAG or LDFLAGS command line, otherwise gcc won't
* be able to to resolve all symbols.
*/
#include <pspkerneltypes.h>
#include <pspuser.h>
#if !defined(MODULE_NAME)
#define MODULE_NAME NONAME
#endif
#if !defined(MODULE_VERSION_MAJOR)
#define MODULE_VERSION_MAJOR 1
#endif
#if !defined(MODULE_VERSION_MINOR)
#define MODULE_VERSION_MINOR 0
#endif
#if !defined(MODULE_ATTR)
#define MODULE_ATTR 0
#endif
#define __stringify(s) __tostring(s)
#define __tostring(s) #s
PSP_MODULE_INFO(__stringify(MODULE_NAME), MODULE_ATTR, MODULE_VERSION_MAJOR, MODULE_VERSION_MINOR);
static
int exit_callback (int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
static
int update_thread (SceSize args, void *argp)
{
int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
static void setup_callbacks (void) __attribute__((constructor));
static void setup_callbacks (void)
{
int id;
if ((id = sceKernelCreateThread("update_thread", update_thread, 0x11, 0xFA0, 0, 0)) >= 0)
sceKernelStartThread(id, 0, 0);
}
static void back_to_kernel (void) __attribute__((destructor));
static void back_to_kernel (void)
{
sceKernelExitGame();
}
To compile it needs libjpeg, pspGL, and at runtime 10 jpeg files (480x272) in app's directory named 01.jpg to 10.jpg