Lesson 05 - Onwards and Upwards
k, so you've set up the development environment, written your first program, leaned some programming techniques, and dabbled in image programming, but what's next? Well, since you're on this page, I'll bet it comes as no surprise to you that it's Lesson 05! Here we will improve our programming skills (and by "we," I really mean "you") by learning about some more advanced concepts.
Advanced, though, is subjective. We are still forming the groundwork in C that you will build upon in truly advanced applications. By the end of this lesson, you should know how to "overclock" the PSP to its true speed of 333 MHz, be able to write text to the screen (graphic text, not the debug text we used before), and have an understanding of how colors work on the PSP.
The program that we are going to construct in this tutorial is a "backround changer." Basically, we are going to allow the user to select the color of the background, and we are going to change it accordingly, as well as display the components of that color on the screen.
First, some background. There is a wide misconception about "overclocking" the PSP. Because of preconceived notions, people associate "overclocking" with heat issues and broken hardware. There is a myth that "overclocking" the PSP is dangerous to the hardware. This is simply not the case with the PSP. The truth is that the PSP is underclocked when it ships from the factory. There are several theories for why Sony did this. One theory is that it drained battery life too quickly for Sony's liking (for us, that isn't much of a concern; spinning the UMD takes up far more battery power than loading off of the Memory Stick, so we already have a tremendous advantage in terms of battery life). Another theory is that Sony wanted developers to write streamlined code. And the third prevalent theory (and the most likely in my opinion) is that they want to allow developers to use the full speed at some point in the future to give a boost to games that will come out later. Anyway, the PSP normally runs at 222 MHz. If you need more power for your programs, "overclocking" is an option. The program we make here will not need the power per se, but I think it's a good place to introduce the concept.
So here we go, let's start out our program. You'll need to download another zip file for this lesson. You can get it here. You'll need to make a main.c file in the same folder as the files you extract from the zip file.
#include <pspkernel.h> #include <pspdisplay.h> #include <pspctrl.h> #include <stdio.h> #include <psppower.h> #include "graphics.h"
Assuming you have completed the previous lessons, this isn't anything you haven't seen. The only thing that should look new to you is the "psppower.h" include. This file contains the functions we will use to change the PSP's clock speed.
On to some more familiar code:
PSP_MODULE_INFO("Background Changer", 0, 1, 1); #define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))
Remember how in Lesson 02 we just glossed over this line without explaining what it really did? Well, I think it's time that you learn. The first parameter is your program identifier, so basically your program name. The second parameter allows you to pass attributes. For most of your programs you will just want to use a 0, but if you are making a kernel mode app, you will need to switch this to "0x1000". The third parameter is for the major version, the fourth is minor version. These are just meant to document the version number of your program.
Now the standard callbacks:
/* Exit callback */ int exit_callback(int arg1, int arg2, void *common) { sceKernelExitGame(); return 0; } /* Callback thread */ int CallbackThread(SceSize args, void *argp) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); sceKernelRegisterExitCallback(cbid); sceKernelSleepThreadCB(); return 0; } /* Sets up the callback thread and returns its thread id */ int SetupCallbacks(void) { int thid = 0; thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); if(thid >= 0) { sceKernelStartThread(thid, 0, 0); } return thid; }