Strange behavior. Probably memory allocation error.

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Kiel
Posts: 2
Joined: Mon Sep 25, 2006 6:01 am

Strange behavior. Probably memory allocation error.

Post by Kiel »

Can someone help me with the code :

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&#91;1&#93;;


void loadJPEG&#40;char *filename&#41;
&#123;
	int i, y, rowsRead;
	unsigned char* m_data;
	unsigned char** rowPtr;
	
	if&#40;loading == 0&#41;
	&#123;
	loading = 1;
	
	glDeleteTextures&#40;1, &tex&#91;0&#93;&#41;;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error&#40;&jerr&#41;;
	jpeg_create_decompress&#40;&cinfo&#41;; 
	FILE* infile;
	if &#40;&#40;infile = fopen&#40;filename, "rb"&#41;&#41; == NULL&#41; 
	&#123;
		exit&#40;0&#41;;
	&#125;

	jpeg_stdio_src&#40;&cinfo, infile&#41;;
	jpeg_read_header&#40;&cinfo, TRUE&#41;;
	y = cinfo.image_height;
	m_data = &#40;unsigned char *&#41; malloc&#40;sizeof&#40;unsigned char&#41;*512*512*3&#41;;
	rowPtr = &#40;unsigned char**&#41; malloc&#40;sizeof&#40;unsigned char*&#41;*y&#41;;

	for &#40;i = 0; i < y; i++&#41;
	&#123;
		rowPtr&#91;i&#93; = &&#40;m_data&#91;i*512*3&#93;&#41;;
	&#125;
	jpeg_start_decompress&#40;&cinfo&#41;;
	rowsRead = cinfo.output_height - 1;
	while &#40;cinfo.output_scanline < cinfo.output_height&#41;
	&#123;
		rowsRead -= jpeg_read_scanlines&#40;&cinfo, &rowPtr&#91;rowsRead&#93;, 1&#41;;
	&#125;
	free&#40;rowPtr&#41;;
	jpeg_finish_decompress&#40;&cinfo&#41;;
	jpeg_destroy_decompress&#40;&cinfo&#41;; 
	fclose&#40;infile&#41;;
	glEnable&#40;GL_DEPTH_TEST&#41;;
	glEnable&#40;GL_CULL_FACE&#41;;
	glEnable&#40;GL_TEXTURE_2D&#41;;
	glGenTextures&#40;1, &tex&#91;0&#93;&#41;;
	glBindTexture&#40;GL_TEXTURE_2D, tex&#91;0&#93;&#41;;	
	glPixelStorei&#40;GL_UNPACK_ALIGNMENT, 0&#41;;
	glTexParameteri&#40;GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT&#41;;
	glTexParameteri &#40;GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT&#41;;
	glTexParameteri &#40;GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR&#41;;
	glTexParameteri &#40;GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR&#41;;
	// 	glTexEnvf&#40;GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE&#41;;

	glTexImage2D &#40;GL_TEXTURE_2D, 0, GL_RGB, 512 , 512, 0, GL_RGB, GL_UNSIGNED_BYTE, m_data&#41;;
	free&#40;m_data&#41;;
	
	loading = 0;
	&#125;
&#125;

/* A general OpenGL initialization function.  Sets all of the initial parameters. */
void InitGL&#40;int Width, int Height&#41;	        // We call this right after our OpenGL window is created.
&#123;
  loading = 0;
  page = 1;
  loadJPEG&#40;"01.jpg"&#41;;
  glClearColor&#40;0.0f, 1.0f, 0.0f, 0.0f&#41;;		// This Will Clear The Background Color To Black
  glClearDepth&#40;1.0&#41;;				// Enables Clearing Of The Depth Buffer
  glDepthFunc&#40;GL_LESS&#41;;				// The Type Of Depth Test To Do
  glEnable&#40;GL_DEPTH_TEST&#41;;			// Enables Depth Testing
  glShadeModel&#40;GL_SMOOTH&#41;;			// Enables Smooth Color Shading

  glMatrixMode&#40;GL_PROJECTION&#41;;
  glLoadIdentity&#40;&#41;;				// Reset The Projection Matrix

//  gluPerspective&#40;45.0f,&#40;float&#41;Width/&#40;float&#41;Height,0.1f,100.0f&#41;;	// Calculate The Aspect Ratio Of The Window

  glMatrixMode&#40;GL_MODELVIEW&#41;;
&#125;

/* The function called when our window is resized &#40;which shouldn't happen, because we're fullscreen&#41; */
void ReSizeGLScene&#40;int Width, int Height&#41;
&#123;
  if &#40;Height==0&#41;				// Prevent A Divide By Zero If The Window Is Too Small
    Height=1;

  glViewport&#40;0, 0, Width, Height&#41;;		// Reset The Current Viewport And Perspective Transformation

  glMatrixMode&#40;GL_PROJECTION&#41;;
  glLoadIdentity&#40;&#41;;

//  gluPerspective&#40;45.0f,&#40;float&#41;Width/&#40;float&#41;Height,0.1f,100.0f&#41;;
  glMatrixMode&#40;GL_MODELVIEW&#41;;
&#125;

/* The main drawing function. */
void DrawGLScene&#40;&#41;
&#123;
	glClear&#40;GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT&#41;;
	glLoadIdentity&#40;&#41;;
	glBindTexture&#40;GL_TEXTURE_2D, tex&#91;0&#93;&#41;;
	glTranslatef&#40;0.0, 0.0, -1.0&#41;;
	glBegin&#40;GL_QUADS&#41;;
	float x_d = &#40;512 - 480&#41; / 512.0; 
	float y_d = &#40;512 - 272&#41; / 512.0; 
	glTexCoord2f&#40;0.0, 0.0&#41;;
	glVertex3d&#40;-1.0, -1.0, 0.5&#41;;
	glTexCoord2d&#40;1 - x_d, 0.0&#41;;
	glVertex3d&#40;1.0, -1.0, 0.5&#41;;
	glTexCoord2d&#40;1 - x_d, 1 - y_d&#41;;
	glVertex3d&#40;1.0, 1.0, 0.5&#41;;
	glTexCoord2d&#40;0.0, 1 - y_d&#41;;
	glVertex3d&#40;-1.0, 1.0, 0.5&#41;;
	glEnd&#40;&#41;;
	glutSwapBuffers&#40;&#41;;
&#125;

/* The function called whenever a key is pressed. */
void keyPressed&#40;unsigned char key, int x, int y&#41; 
&#123;
	switch &#40;key&#41; &#123;
	case 'd'&#58;			/* delta, triangle */
		break;
	case 'o'&#58;			/* round */
		break;
	case 'q'&#58;			/* square*/
		break;
	case 'x'&#58;			/* cross */
		break;
	case 'n'&#58;			/* key with the music note */
		break;
	case 's'&#58;			/* select */
		break;
	case 'a'&#58;			/* startbutton */  /* If START is pressed, kill everything. */
 		/* exit the program...normal termination. */
		exit&#40;0&#41;;                   
	default&#58;
		;
	&#125;
 &#125;

/* The function called whenever a key is released. */
void keyReleased&#40;unsigned char key, int x, int y&#41; 
&#123;
	switch &#40;key&#41; &#123;
	case 'd'&#58;			/* delta, triangle */
		break;
	case 'o'&#58;			/* round */
		break;
	case 'q'&#58;			/* square*/
		break;
	case 'x'&#58;			/* cross */
		break;
	case 'n'&#58;			/* key with the music note */
		break;
	case 's'&#58;			/* select */
		break;
	case 'a'&#58;			/* startbutton */
		break;
	default&#58;
		;
	&#125;
 &#125;

/* The function called whenever a special key is pressed. */
void specialKeyPressed&#40;int key, int x, int y&#41; 
&#123;
    switch &#40;key&#41; &#123;    
    case GLUT_KEY_UP&#58; // pad arrow up
	break;

    case GLUT_KEY_DOWN&#58; //  pad arrow down
	break;

    case GLUT_KEY_LEFT&#58; //  pad arrow left
	break;
    
    case GLUT_KEY_RIGHT&#58; //  pad arrow right
	break;

    case GLUT_KEY_HOME&#58; // home
	break;
	
    default&#58;
	break;
    &#125;	
&#125;

/* The function called whenever a special key is released. */
void specialKeyReleased&#40;int key, int x, int y&#41; 
&#123;
    switch &#40;key&#41; &#123;    
    case GLUT_KEY_UP&#58; // pad arrow up
	break;

    case GLUT_KEY_DOWN&#58; //  pad arrow down
	break;

    case GLUT_KEY_LEFT&#58; //  pad arrow left
		if&#40;page > 1&#41;
		&#123;
			char nazwa&#91;20&#93;;
			page--;
			sprintf&#40;nazwa, "%.2i.jpg", page&#41;;
			loadJPEG&#40;nazwa&#41;;		&#125;
	break;
    
    case GLUT_KEY_RIGHT&#58; //  pad arrow right
		if&#40;page < 10&#41;
		&#123;
			char nazwa&#91;20&#93;;
			page++;
			sprintf&#40;nazwa, "%.2i.jpg", page&#41;;
			loadJPEG&#40;nazwa&#41;;
		&#125;
    
	break;

    case GLUT_KEY_HOME&#58; // home
	break;
	
    default&#58;
	break;
    &#125;	
&#125;

/* The function called whenever the joystick is moved. */
void joystickMoved &#40;unsigned int buttonMask, int x, int y, int z&#41;
&#123;
	if &#40;abs&#40;x&#41; > 150&#41; // dead zone
	&#123;	
		// use x value
	&#125;

	if &#40;abs&#40;y&#41; > 150&#41; // dead zone
	&#123;	
		// use y value
	&#125;
&#125;

/* The function called whenever the triggers are pressed. */
void triggerHandle &#40;int button, int state, int x, int y&#41;
&#123;
	if &#40;button == GLUT_LEFT_BUTTON&#41; &#123;  // left trigger...
		if &#40;state == GLUT_DOWN&#41; &#123;  // ...is pressed
		&#125;
		if &#40;state == GLUT_UP&#41; &#123;  // ...is released
		&#125;
	&#125;

	if &#40;button == GLUT_RIGHT_BUTTON&#41; &#123;  // right trigger...
		if &#40;state == GLUT_DOWN&#41; &#123;  // ...is pressed
		&#125;
		if &#40;state == GLUT_DOWN&#41; &#123;  // ...is released
		&#125;
	&#125;
&#125;

/* main function */
int main&#40;int argc, char **argv&#41; 
&#123;  
  /* Initialize GLUT state - glut will take any command line arguments that pertain to it or 
     X Windows - look at its documentation at http&#58;//reality.sgi.com/mjk/spec3/spec3.html */  
  glutInit&#40;&argc, argv&#41;;  

  /* Select type of Display mode&#58;   
     Double buffer 
     RGBA color
     Alpha components supported 
     Depth buffer */  
  glutInitDisplayMode&#40;GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH&#41;;  

  /* get a 640 x 480 window */
  glutInitWindowSize&#40;480, 272&#41;; 

  /* the window starts at the upper left corner of the screen */
  glutInitWindowPosition&#40;0, 0&#41;;  

  /* Open a window */  
  window = glutCreateWindow&#40;"Jeff Molofee's GL Code Tutorial ... NeHe '99"&#41;;  

  /* Register the function to do all our OpenGL drawing. */
  glutDisplayFunc&#40;&DrawGLScene&#41;;  

  /* Even if there are no events, redraw our gl scene. */
  glutIdleFunc&#40;&DrawGLScene&#41;;

  /* Register the function called when our window is resized. */
  glutReshapeFunc&#40;&ReSizeGLScene&#41;;

  /* Register the function called when the keyboard is pressed. */
  glutKeyboardFunc&#40;&keyPressed&#41;;
  /* Register the function called when the keyboard is released. */
  glutKeyboardUpFunc&#40;&keyReleased&#41;;
  /* Register the function called when special keys &#40;arrows, page down, etc&#41; are pressed. */
  glutSpecialFunc&#40;&specialKeyPressed&#41;;
  /* Register the function called when special keys &#40;arrows, page down, etc&#41; are released. */
  glutSpecialUpFunc&#40;&specialKeyReleased&#41;;
  /* Register the function called when joystick is moved. */
  glutJoystickFunc&#40;&joystickMoved, 0&#41;; // 0 = Joystick polling interval in milliseconds
  /* Register the function called when Trigger_left or Trigger_right is pressed */
  glutMouseFunc&#40;&triggerHandle&#41;;
  
  /* Initialize our window. */
  InitGL&#40;480, 272&#41;; 
  
  /* Start Event Processing Engine */  
  glutMainLoop&#40;&#41;;  

  return &#40;0&#41;;
&#125;
And it's makefile

Code: Select all

TARGET = lesson1
OBJS = main.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

PSPBIN = $&#40;PSPSDK&#41;/../bin
CFLAGS += -I$&#40;PSPSDK&#41;/../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=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
and callbacks setup stuff

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&#58; 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&#58;
 *         -DMODULE_NAME="name" -- set the name &#40;default NONAME&#41;
 *         -DMODULE_ATTR=0      -- module attributes &#40;default 0&#41;
 *         -DVERSION_MAJOR=1    -- version 1.x &#40;default 1&#41;
 *         -DVERSION_MINOR=0    -- version x.0 &#40;default 0&#41;
 *
 *  Note&#58;  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&#40;MODULE_NAME&#41;
	#define MODULE_NAME NONAME
#endif


#if !defined&#40;MODULE_VERSION_MAJOR&#41;
	#define MODULE_VERSION_MAJOR 1
#endif


#if !defined&#40;MODULE_VERSION_MINOR&#41;
	#define MODULE_VERSION_MINOR 0
#endif


#if !defined&#40;MODULE_ATTR&#41;
	#define MODULE_ATTR 0
#endif


#define __stringify&#40;s&#41;	__tostring&#40;s&#41;
#define __tostring&#40;s&#41;	#s

PSP_MODULE_INFO&#40;__stringify&#40;MODULE_NAME&#41;, MODULE_ATTR, MODULE_VERSION_MAJOR, MODULE_VERSION_MINOR&#41;;


static
int exit_callback &#40;int arg1, int arg2, void *common&#41;
&#123;
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;


static
int update_thread &#40;SceSize args, void *argp&#41;
&#123;
	int cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;
	sceKernelSleepThreadCB&#40;&#41;;
	return 0;
&#125;


static void setup_callbacks &#40;void&#41; __attribute__&#40;&#40;constructor&#41;&#41;;
static void setup_callbacks &#40;void&#41;
&#123;
	int id;

	if &#40;&#40;id = sceKernelCreateThread&#40;"update_thread", update_thread, 0x11, 0xFA0, 0, 0&#41;&#41; >= 0&#41;
		sceKernelStartThread&#40;id, 0, 0&#41;;
&#125;



static void back_to_kernel &#40;void&#41; __attribute__&#40;&#40;destructor&#41;&#41;;
static void back_to_kernel &#40;void&#41;
&#123;
	sceKernelExitGame&#40;&#41;;
&#125;

It works for a few moments, but after some time is just crashes. I suspect memory alocation problems but after whole day of searching for a bug I gave up.
To compile it needs libjpeg, pspGL, and at runtime 10 jpeg files (480x272) in app's directory named 01.jpg to 10.jpg
Kiel
Posts: 2
Joined: Mon Sep 25, 2006 6:01 am

Post by Kiel »

Problem solved. It was bug in glDeleteTextures that caused the trouble.
Post Reply