Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Example of using a simple model file, including a texture
- //
- // Additional code by Shaun Bebbington to make the beginnings
- // of a simple game engine v0.0000000001 MMXI Donkeysoft
- #include <stdlib.h>
- #include <malloc.h>
- #include <psptypes.h>
- #include <kernel.h>
- #include <displaysvc.h>
- #include <ctrlsvc.h>
- #include <libgu.h>
- #include <libgum.h>
- #include <gmo/gmo_model.h>
- // This tells the thingy to do the animation on the Dog
- #define DO_ANIMATION
- SCE_MODULE_INFO (Model, 0, 1, 1);
- int sce_newlib_heap_kb_size=4096;
- // File names of loaded objects:
- #define DOG_FILE "dog.gmo"
- #define CASTLE "Castle.gmo"
- // Exact value of PI:
- #define PI 3.1415
- //----------------------------------------------------------------
- // Forward declaration
- //----------------------------------------------------------------
- static void beginScene (void);
- static void swapBuffers (void);
- static void drawDog (float x, float y, float z);
- static bool loadDogModel (int argc, char **argv);
- static void unloadDogModel ();
- static void drawCastle(float x, float y, float z);
- static bool loadCastleModel (int argc, char **argv);
- static void unloadCastleModel (void);
- static bool loadFile (const char *filename, int **buf, int *size);
- static void readPad (void);
- static void dogJump (void);
- //----------------------------------------------------------------
- // Global variables
- //----------------------------------------------------------------
- // This integer is used to control the frame-rate, when you press 'select'
- // the frame-rate should be toggled between 30 FPS and 60 FPS
- int framerate=2;
- // This is set true when the movement buttons are pressed as follows:
- // left - rotate Dog left
- // right - rotate Dog right
- // up - Zoom into castle and animate Dog
- // down - Zoom out of castle and animate Dog
- bool CTRL=false;
- // We're hoping to make the Dog jump, like all good platform games,
- // so we need a boolean to say whether jump has been activated or not:
- bool JUMP=false;
- float jump=0.5;
- // Variables for dog and castle - TO DO: think of a use for them!
- float dogx=0.00f, dogy=0.00f, dogz=0.00f;
- float casx=0.00f, casy=0.00f, casz=0.00f;
- // These variables are used to move the camera view:
- float camx=0, camy=1, camz=50.00f;
- float xdirection=0.5, ydirection=0.5, zoomdirection=0.5;
- static void *malloc16 (size_t size)
- {
- return memalign (16,size);
- }
- static void free16 (void *addr)
- {
- free (addr);
- }
- static void *malloc64 (size_t size)
- {
- return memalign (64, (size+63)/64*64);
- }
- static void free64 (void *addr)
- {
- free (addr);
- }
- #define PACKET_BUFSIZE (1048576)
- static char g_packet_buf [PACKET_BUFSIZE] __attribute__((aligned(64)));
- static ScePspFMatrix4 g_matrix_buf [16];
- static bool running=true;
- static SceGmoModel *model1=0;
- static SceGmoModel *model2=0;
- static ScePspFVector3 translateDog;
- static ScePspFVector3 rotationDog;
- static ScePspFVector3 scaleDog;
- static ScePspFVector3 translateCas;
- static ScePspFVector3 rotationCas;
- static ScePspFVector3 scaleCas;
- // Main class:
- int main (int argc, char **argv)
- {
- // Tell kernal to use vector floating point unit for improved performance
- sceKernelChangeCurrentThreadAttr (0, SCE_KERNEL_TH_USE_VFPU);
- sceCtrlSetSamplingMode (SCE_CTRL_MODE_DIGITALANALOG);
- sceGuInit ();
- sceGuStart (SCEGU_IMMEDIATE, g_packet_buf, PACKET_BUFSIZE);
- sceGuDrawBuffer (SCEGU_PF5551, SCEGU_VRAM_BP_0, SCEGU_VRAM_WIDTH);
- sceGuDispBuffer (SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, SCEGU_VRAM_BP_1, SCEGU_VRAM_WIDTH);
- sceGuDepthBuffer (SCEGU_VRAM_BP_2, SCEGU_VRAM_WIDTH);
- sceGuOffset (SCEGU_SCR_OFFSETX, SCEGU_SCR_OFFSETY);
- sceGuFinish ();
- sceGuSync (SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
- sceGumSetMatrixStack (g_matrix_buf, 4, 4, 8, 0);
- // Initialise heap management functions
- sceGimPictureSetMemoryManager (malloc16, free16);
- sceGimPictureSetMemoryManager2 (malloc64, free64);
- sceGmoModelSetMemoryManager (malloc16, free16);
- sceGmoModelSetMemoryManager2 (malloc64, free64);
- if ((!loadDogModel(argc, argv)) || (!loadCastleModel(argc, argv)))
- {
- running=false;
- }
- sceGuDisplay (SCEGU_DISPLAY_ON);
- while (running)
- {
- readPad ();
- sceGuStart(SCEGU_IMMEDIATE, g_packet_buf, PACKET_BUFSIZE) ;
- beginScene ();
- drawDog (dogx, dogy, dogz);
- drawCastle (casx, casy, casz);
- sceGuFinish ();
- swapBuffers ();
- }
- unloadDogModel ();
- unloadCastleModel ();
- sceGuTerm ();
- return 0;
- }
- //----------------------------------------------------------------
- // begin and end
- //----------------------------------------------------------------
- void beginScene (void)
- {
- sceGuViewport (2048, 2048, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT);
- sceGuDepthRange (0xe000, 0x1000);
- sceGuEnable (SCEGU_SCISSOR_TEST);
- sceGuScissor (0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT);
- sceGuClearColor (0xff800000);
- sceGuClearDepth (0);
- sceGuClearStencil (0);
- sceGuClear (SCEGU_CLEAR_ALL);
- // Setup perspective and view transforms
- sceGumMatrixMode (SCEGU_MATRIX_VIEW);
- sceGumLoadIdentity ();
- // Uses global variables to position the camera, can be moved on the X, Y and Z plane:
- sceGumLookAt (&(ScePspFVector3){0, 0, camz}, &(ScePspFVector3){camx, camy, 0}, &(ScePspFVector3){0, 1, 0});
- sceGumMatrixMode (SCEGU_MATRIX_PROJECTION);
- sceGumLoadIdentity ();
- sceGumPerspective (30.0f*PI/180.0f, SCEGU_SCR_ASPECT, 10.0f, 1000000.0f);
- sceGumMatrixMode (SCEGU_MATRIX_WORLD);
- // Lighting
- sceGuEnable (SCEGU_FOG);
- sceGuFog (40, 100, 0xff800000);
- sceGuEnable (SCEGU_LIGHTING);
- sceGuAmbient (0xff404040);
- sceGuEnable (SCEGU_LIGHT0);
- sceGuLight (0, SCEGU_LIGHT_DIRECTION, SCEGU_DIFFUSE_AND_SPECULAR, &(ScePspFVector3){-5, 10, 5});
- sceGuLightColor (0, SCEGU_DIFFUSE, 0xf0f0f0ff);
- sceGuLightColor (0, SCEGU_SPECULAR, 0xf0f0f0ff);
- sceGuLight (2, SCEGU_LIGHT_DIRECTION, SCEGU_DIFFUSE, &(ScePspFVector3){1, 0, 0});
- sceGuLight (3, SCEGU_LIGHT_DIRECTION, SCEGU_DIFFUSE, &(ScePspFVector3){0, 1, 0});
- sceGuColorMaterial (SCEGU_DIFFUSE | SCEGU_AMBIENT);
- // Initialise render state
- sceGuEnable (SCEGU_ALPHA_TEST);
- sceGuEnable (SCEGU_DEPTH_TEST);
- sceGuEnable (SCEGU_BLEND);
- sceGuEnable (SCEGU_DITHER);
- sceGuEnable (SCEGU_TEXTURE);
- sceGuEnable (SCEGU_CULL_FACE);
- sceGuEnable (SCEGU_CLIP_PLANE);
- sceGuEnable (SCEGU_CULL_PATCH);
- sceGuEnable (SCEGU_NORMAL_REVERSE_PATCH);
- sceGuFrontFace (SCEGU_CCW);
- sceGuShadeModel (SCEGU_SMOOTH);
- sceGuAlphaFunc (SCEGU_GEQUAL, 0, 255);
- sceGuDepthFunc (SCEGU_GEQUAL);
- sceGuBlendFunc (SCEGU_ADD, SCEGU_SRC_ALPHA, SCEGU_ONE_MINUS_SRC_ALPHA, 0, 0);
- sceGuTexFilter (SCEGU_LINEAR_MIPMAP_LINEAR, SCEGU_LINEAR);
- sceGuTexFunc (SCEGU_TEX_MODULATE, SCEGU_RGBA);
- sceGuTexWrap (SCEGU_REPEAT, SCEGU_REPEAT);
- sceGuPatchDivide (4, 4);
- }
- void swapBuffers(void)
- {
- sceGuSync (SCEGU_SYNC_FINISH, SCEGU_SYNC_WAIT);
- sceDisplayWaitVblankStart ();
- sceGuSwapBuffers ();
- }
- void drawDog(float x, float y, float z)
- {
- // Currently unused local variables: could be used for direction of character
- // or something?
- float _x=x, _y=y, _z=z;
- // This makes our hero jump if the player has hit the triangle key:
- if(JUMP==true)
- {
- dogJump();
- }
- sceGumMatrixMode (SCEGU_MATRIX_WORLD);
- sceGumLoadIdentity ();
- sceGumTranslate (&translateDog);
- sceGumRotateY (SCEGU_RAD(rotationDog.y));
- // I don't think this is needed:
- // sceGumRotateX (SCEGU_RAD(rotationDog.x));
- // Draw model
- ScePspFMatrix4 m;
- sceGumScale (&scaleDog);
- sceGumStoreMatrix (&m);
- sceGmoModelSetWorldMatrix (model1, &m);
- #ifdef DO_ANIMATION
- // Will only animate the Dog if the relevant user interactions are set:
- if(CTRL)
- {
- sceGmoModelAnimate (model1, framerate/60.00f);
- }
- #endif
- // Does update stuffs:
- sceGmoModelUpdate (model1);
- sceGmoModelDraw (model1);
- //sceGmoModelUpdate (model2);
- //sceGmoModelDraw (model2);
- }
- //----------------------------------------------------------------
- // load and unload
- //----------------------------------------------------------------
- bool loadDogModel (int argc, char **argv)
- {
- const char *filename=(argc<2)?DOG_FILE : argv[1];
- // Load model from file
- int *data, size;
- if (!loadFile(filename, &data, &size ))
- {
- data=0;
- size=0;
- }
- // Create models
- model1=sceGmoModelCreate (0);
- sceGmoModelLoadFile (model1, data, size, 0);
- sceGmoModelSetOptionFlags (model1, SCEGMO_OPTION_MULTIPLY_WORLD, 0);
- #ifdef DO_ANIMATION
- sceGmoModelSetCurrentMotion (model1, 0, 0.0f);
- #endif
- // Initial position of dog
- translateDog=(ScePspFVector3){ 0, -5, 8 };
- rotationDog=(ScePspFVector3){ 0, 0, 0 };
- scaleDog=(ScePspFVector3){ 0.5, 0.5, 0.5 };
- // Free up data read from file
- free (data);
- return (model1!=0);
- }
- void unloadDogModel (void)
- {
- sceGmoModelDelete (model1);
- model1=0;
- }
- // Here's our jump routine... the physics could be improved to make it more
- // 'realistic', as you see dogs running around on their hind legs and jumping
- // from them all of the time, right? But for the purposes of a video game engine
- // it could be improved...
- void dogJump (void)
- {
- // Checks if the Dog has reached the highest point yet:
- if(translateDog.y>-1.00)
- {
- // if so, make him return to the ground by changing the jump parameter:
- jump=-0.5;
- }
- // if the dog has reached the floor, we want to stop calling this routine
- // and set the Dog to walk along the default floor co-ordinates:
- if(translateDog.y<-5)
- {
- translateDog.y=-5;
- JUMP=false;
- jump=0.5;
- return;
- }
- // This 'translates' the Dog's position on the Y plane, ie, looks as though he's
- // jumping or something:
- translateDog.y+=jump;
- }
- // Here's our spooky Castle:
- void drawCastle(float x, float y, float z)
- {
- // Again, I could think of a use for these - but leave them in the TO DO list:
- float _x=x, _y=y, _z=z;
- sceGumMatrixMode (SCEGU_MATRIX_WORLD);
- sceGumLoadIdentity ();
- sceGumTranslate (&translateCas);
- sceGumRotateY (SCEGU_RAD(rotationCas.y));
- sceGumRotateX (SCEGU_RAD(rotationCas.x));
- // Draw model
- ScePspFMatrix4 m;
- sceGumScale (&scaleCas);
- sceGumStoreMatrix (&m);
- sceGmoModelSetWorldMatrix (model2, &m);
- sceGmoModelUpdate (model2);
- sceGmoModelDraw (model2);
- }
- // Loads the castle into the memory, or adds it to the file or something:
- bool loadCastleModel (int argc, char **argv)
- {
- const char *filename=(argc<2)?CASTLE : argv[1];
- // Load model from file
- int *data, size;
- if (!loadFile(filename, &data, &size ))
- {
- data=0;
- size=0;
- }
- // Create models
- model2=sceGmoModelCreate (0);
- sceGmoModelLoadFile (model2, data, size, 0);
- sceGmoModelSetOptionFlags (model2, SCEGMO_OPTION_MULTIPLY_WORLD, 0);
- // Initial position of Castle
- translateCas=(ScePspFVector3){ 0, -5, 0 };
- rotationCas=(ScePspFVector3){ 0, 0, 0 };
- scaleCas=(ScePspFVector3){ 2, 2, 2 } ;
- // Free up data read from file
- free (data);
- return (model2!=0);
- }
- // Does the unload bit:
- void unloadCastleModel (void)
- {
- sceGmoModelDelete (model2);
- model2=0;
- }
- bool loadFile (const char *filename, int **buf, int *size)
- {
- char fullpath [256];
- snprintf (fullpath, sizeof(fullpath), "host0:%s", filename);
- SceUID fd=sceIoOpen (fullpath, SCE_O_RDONLY, 0777);
- if (fd<0)
- {
- return false;
- }
- *size=sceIoLseek (fd, 0, SCE_SEEK_END);
- if (*size<=0)
- {
- sceIoClose (fd);
- return false;
- }
- sceIoLseek (fd, 0, SCE_SEEK_SET);
- *buf=(int*)malloc(*size);
- if (*buf==0)
- {
- sceIoClose (fd);
- return false;
- }
- sceIoRead (fd, (void *)*buf, (unsigned int)*size);
- sceIoClose (fd);
- return true;
- }
- // Here's where much of the game mechanics are altered... well, there's not much
- // of a game, but it does some of what a real game would do:
- static void readPad (void)
- {
- SceCtrlData buf[8];
- SceInt32 ret =sceCtrlReadBufferPositive(buf, 8);
- SceUInt32 padd =(ret!=0)?buf[0].Buttons:0;
- // This is set just in case there is no control inputs from the user,
- // so in other words, the default is set and that means the animation
- // on the Dog is stopped. Of course, this boolean is made true on certain
- // user interactions as below:
- if (CTRL==true)
- {
- CTRL=false;
- }
- // CTRL will now be set true if the dog requires animation
- // This moves the Dog 'towards' the Castle:
- if (padd & SCE_CTRL_UP)
- {
- if (translateCas.z<4)
- {
- translateCas.z++;
- }
- // Animation is set to true even if the Dog is at the Castle
- // door or 'in' the castle walls - that latter is a bug I need to
- // work out how to fix!
- CTRL=true;
- }
- // This moves the Dog away from the castle:
- if (padd & SCE_CTRL_DOWN)
- {
- if (translateCas.z>-16)
- {
- translateCas.z--;
- }
- CTRL=true;
- }
- // This 'rotates' the Dog around the Y axis 'clockwise':
- if (padd & SCE_CTRL_LEFT)
- {
- rotationDog.y-=2;
- CTRL=true;
- }
- // This 'rotates' the Dog around the Y axis 'andi-clockwise':
- if (padd & SCE_CTRL_RIGHT)
- {
- rotationDog.y+=2;
- CTRL=true;
- }
- // Select flips between the two frame rates:
- if (padd & SCE_CTRL_SELECT)
- {
- if (framerate==1)
- {
- framerate=2;
- }
- else
- framerate=1;
- }
- // The top 'L' button basically moves the castle, but gives the impression
- // that the Dog is walking left as you're looking at the screen:
- if (padd & SCE_CTRL_L)
- {
- if(translateCas.x<20)
- {
- translateCas.x+=0.25;
- }
- CTRL=true;
- }
- // And the top 'R' button does the opposite as above:
- if (padd & SCE_CTRL_R)
- {
- if(translateCas.x>-16)
- {
- translateCas.x-=0.25;
- }
- CTRL=true;
- }
- // Triangle is used for jumping, so it sets the relevant boolean true:
- if (padd & SCE_CTRL_TRIANGLE)
- {
- JUMP=true;
- }
- // The Circle will move the camera on the X axis (hold down and it will
- // go both ways once it's reached it's limits on each side):
- if (padd & SCE_CTRL_CIRCLE)
- {
- camx=camx+xdirection;
- if(camx>12)
- {
- xdirection=-0.5;
- }
- if(camx<-12)
- {
- xdirection=0.5;
- }
- }
- // Square does the same as Circle but on the Y axis for the camera view:
- if (padd & SCE_CTRL_SQUARE)
- {
- camy=camy+ydirection;
- if(camy>12)
- {
- ydirection=-0.5;
- }
- if(camy<-12)
- {
- ydirection=0.5;
- }
- }
- // And the cross ('X') is used to zoom in and out of the scene (again, has a
- // bounce method when it reaches it's limits):
- if (padd & SCE_CTRL_CROSS)
- {
- camz=camz+zoomdirection;
- if(camz>75)
- {
- zoomdirection=-0.5;
- }
- if(camz<20)
- {
- zoomdirection=0.5;
- }
- }
- // The Start button will reset the camera to default:
- if (padd & SCE_CTRL_START)
- {
- framerate=2; dogx=0.00f; dogy=0.00f; dogz=0.00f;
- casx=0.00f, casy=0.00f, casz=0.00f;
- camx=0; camy=1; camz=50.00f;
- xdirection=0.5, ydirection=0.5;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement