• Steam recently changed the default privacy settings for all users. This may impact tracking. Ensure your profile has the correct settings by following the guide on our forums.

blitAlphaImageToScreen not working

VBMonkey

New Member
Hello everyone.
I'm developing a shell for the PSP that looks like the iPhone OS, and ironically, the shell is called iPhone OS. I first used blitAlphaImageToScreen to blit the empty springboard to the screen, then I use it again in my sceDisplayWaitVblankStart replacement, iPhoneOS_IdleWorker. iPhoneOS_IdleWorker() is supposed to update a battery image in the top left corner of the screen depending on the battery status, and it's not even blitting the image. Here's the contents of the iPhoneOS_IdleWorker function:
Code:
void iPhoneOS_IdleWorker()
{
	// my custom idle func that i use instead of sceDisplayWaitVblankStart
	char buffer[200];
	if(scePowerIsBatteryExist() == 1)
	{
		int battery = scePowerGetBatteryLifePercent();
		// what img to use for battery meter?
		if(battery >= 80)
		{
			// almost full
			sprintf(buffer, "img/battery/battery_full.png");
		}
		else if(battery >= 30 && battery <= 79)
  		{
			sprintf(buffer, "img/battery/battery_half.png");
		}
		else if(battery <= 29)
		{
			sprintf(buffer, "img/battery/battery_low.png");
		}
		else
		{
			sprintf(buffer, "img/battery/battery_none.png");
		}
	}
	else
	{
		sprintf(buffer, "img/battery/battery_none.png");
	}
	Image* batteryImage;
	batteryImage = loadImage(buffer);
	if(!batteryImage) { printf("Failed to load battery image."); }
	else {
		[B]blitAlphaImageToScreen(0,0,18,22,batteryImage,0,0);[/B]
		flipScreen();
		freeImage(batteryImage);
	}
	sceDisplayWaitVblankStart();
}
The bold line (or somewhere around there) is supposed to render the image on the screen, however it's not.
I also used the psp-programming.com graphics.h/graphics.c.
Includes:
(note: had to remove the greater-than-less-than signs otherwise they won't display)
Code:
#include psppower.h
#include pspdisplay.h
#include pspctrl.h
#include pspkernel.h
#include pspdebug.h
#include pspgu.h
#include png.h
#include stdio.h
#include "graphics.h"

Anyone have any ideas at all?

Okay, I got it to work. Now the springboard keeps flickering because the battery meter is updating too much... is there a way to fix this?
 

angelsniper45

New Member
Well first off, how did you define the "battery image", because the compiler may be reading it wrong. On a side note, are you sure the void command shouldnt go inside the ()?
 

Alex

Active Member
no he has that correct, why dont you use scekernaldelaythread or what ever it is called?
 

angelsniper45

New Member
its sceKernelDelayThread(4*1000*1000);

good point, this would help. You can change the numbers to whatever works for you, but keep it in the range of 2-5.

thats just my opinion.
 

VBMonkey

New Member
the sceKernelDelayThread works, I used 2*1000*1000, however whenever the battery image is rewritten to the screen the springboard (which the battery image is written on top of) disappears then reappears about 1sec before the battery image is written again. Is there any way to fix this?

NOTE: I uploaded a Youtube video demonstrating what it does now. The video hasn't processed as of this writing, but here it is: http://www.youtube.com/watch?v=XILr8XoyAgU
 

MenaceInc

Staff Member
well, guessing from the code above, you're flipping the screen after putting up the battery image then flipping it elsewhere. If I were you, I'd take flipScreen() out of your iPhoneOS_IdleWorker() function

EDIT: just to be clear as well, I'd use sceKernelDelayThread(2*1000*1000) in your main code as well just after flipScreen()
 

VBMonkey

New Member
no, taking out flipScreen doesn't work either. Here's the flow:
int main() calls initGraphics(), initalizes some variables, and calls revealSpringboard()
void revealSpringboard() outputs the springboard image to the screen and calls lookForPadData()
void lookForPadData() listens for data on the ctrlpad - if no activity is detected, it calls iPhoneOS_IdleWorker()
void iPhoneOS_IdleWorker() does the battery updating & stuff

Here's the entire code for main.c (in hopes this'll help - again, had to remove the greater-than-less-than-signs on includes so they'll display):
Code:
// iPhone OS 3.0

#include psppower.h
#include pspdisplay.h
#include pspctrl.h
#include pspkernel.h
#include pspdebug.h
#include pspgu.h
#include png.h
#include stdio.h
#include "graphics.h" 
#include pspwlan.h

#define printf pspDebugScreenPrintf
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 
#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16)) 

PSP_MODULE_INFO("iPhone OS", 0, 1, 1); 

int batteryLife;
char batteryImageBuffer[200];
char wlanImageBuffer[200];
char signalImageBuffer[200];
int wlan_isOn;
// 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;
} 
void iPhoneOS_IdleWorker()
{
	// my custom idle func that i use instead of sceDisplayWaitVblankStart
	char buffer[200];
		if(scePowerIsBatteryExist() == 1)
		{
			int battery = scePowerGetBatteryLifePercent();
			batteryLife = scePowerGetBatteryLifePercent();
			//printf("[DEBUG] Battery percentage = %i percent\n", battery);
			// what img to use for battery meter?
			if(battery >= 80)
			{
				// almost full
				sprintf(buffer, "img/battery/battery_full.png");
			}
			else if(battery >= 30 && battery <= 79)
			{
				sprintf(buffer, "img/battery/battery_half.png");
			}
			else if(battery <= 29)
			{
				sprintf(buffer, "img/battery/battery_low.png");
			}
			else
			{
				sprintf(buffer, "img/battery/battery_none.png");
			}
		}
		else
		{
			sprintf(buffer, "img/battery/battery_none.png");
		}
		//printf("[DEBUG] Battery image = %s\n", buffer);
		if(batteryImageBuffer != buffer)
		{
			sprintf(batteryImageBuffer, buffer);
			Image* batteryImage;
			batteryImage = loadImage(buffer);
			if(!batteryImage) { printf("Failed to load battery image."); }
			else {
				blitAlphaImageToScreen(0,0,18,22,batteryImage,0,0);
				flipScreen();
				freeImage(batteryImage);
			}
		}
	// Wlan img
	int wlan_active = sceWlanGetSwitchState();
	char wlanbuffer[200];
	if(wlan_active == 1)
	{
		sprintf(wlanbuffer, "img/wlan/wlan_on.png");
	}
	else
	{
		sprintf(wlanbuffer, "img/wlan/wlan_off.png");
	}
	if(wlanImageBuffer != wlanbuffer)
	{
		sprintf(wlanImageBuffer, wlanbuffer);
		Image* WlanImage;
		WlanImage = loadImage(wlanbuffer);
		if(!WlanImage) { printf("Failed to load wlan image."); }
		else
		{
			blitAlphaImageToScreen(0,0,15,16,WlanImage,0,201);
			flipScreen();
			freeImage(WlanImage);
		}
	}
	// Signal img
	// for now just blit a single img
	char signalbuffer[200];
	sprintf(signalbuffer, "img/signal/signal_none.png");
	if(signalImageBuffer != signalbuffer)
	{
		sprintf(signalImageBuffer, signalbuffer);
		Image* SignalImage;
		SignalImage = loadImage(signalbuffer);
		if(!SignalImage) { printf("Failed to load signal image."); }
		else
		{
			blitAlphaImageToScreen(0,0,16,50,SignalImage,0,220);
			flipScreen();
			freeImage(SignalImage);
		}
	}
	sceDisplayWaitVblankStart();
	//sceKernelDelayThread(2*1000*1000); //took it out as it prevented returning to lookForPadData() thus resulting in a delay before reading pad data
}
void lookForPadData()
{
	// Listens for ctrlpad data and performs the correct action when a button is pressed
	SceCtrlData pad;
	while(1)
	{
		sceCtrlReadBufferPositive(&pad, 1);
		if(pad.Buttons & PSP_CTRL_SQUARE) {
			// Load the springboard - iTouch home button pressed
			revealSpringboard();
		}
		else if(pad.Buttons & PSP_CTRL_CIRCLE) {
			// for testing purposes, load a full springboard
			revealFullSpringboard();
		}
		else
		{
			iPhoneOS_IdleWorker();
		}
	}
}
void revealFullSpringboard()
{
	// Reveals a full springboard for testing purposes
	char buffer[200];
	Image* FullSpringboardImage;
	sprintf(buffer, "img/fullspringboard.png");
	FullSpringboardImage = loadImage(buffer);
	if(!FullSpringboardImage)
	{
		printf("The Full Springboard image failed to load.");
		while(1)
		{
			iPhoneOS_IdleWorker();
		}
	}
	blitAlphaImageToScreen(0,0,480,272,FullSpringboardImage,0,0);
	flipScreen();
	freeImage(FullSpringboardImage);
}
void revealSpringboard()
{
	// Reveals the springboard
	// Called for one of three possible reasons:
	// 1. the user pressed [] (home button on the iPhone/iTouch)
	// 2. the iPhone OS app is starting
	// 3. an app exited
	char buffer[200];
	Image* SpringboardImage; 
	sprintf(buffer, "img/springboard.png");

	SpringboardImage = loadImage(buffer);
	if(!SpringboardImage)
	{
			printf("Springboard image loading failed.\nPlease ensure that springboard.png exists in ms0:/PSP/GAME/iPhoneOS/img/.");
		while(1)
		{
			iPhoneOS_IdleWorker();
		}
	}
	blitAlphaImageToScreen(0,0,480,272,SpringboardImage,0,0);
	flipScreen();
	freeImage(SpringboardImage);
	while(1)
	{
		lookForPadData();
	}
}
int main()
{ 
pspDebugScreenInit();
SetupCallbacks(); 
Color white = RGB(255,255,255);
Color black = RGB(0,0,0);
printf("Initalizing..."); 
initGraphics(); 
printf("\nOverclocking to 333/333/166...\n");
pspDebugScreenClear();
printf("Initalizing variables to 0...\n");
batteryLife = 0;
wlan_isOn = 0;
scePowerSetClockFrequency(333,333,166);
revealSpringboard();
return 0; 
}
I also accidentally made another problem. I added checking of the wifi (switch state, on/off) and signal (just prints a static image for now) to iPhoneOS_IdleWorker(), and now the memory stick is constantly accesses (orange light remains on). Any ideas? (the wifi/signal is second priority - the flickering problem is top)
 

angelsniper45

New Member
hmmm thats wierd. can you pm the full source and ill take a look at it further this weekend?

perhaps its the graphics itself, not the actual code. the code looks fine, but i dont know why the image would always be there, and you did use sceKernelDelay right?
 

Roe

Well-Known Member
Your code is pretty all over the place :p. Give me a while and I'll fix it up for you.

Edit: After looking at this it would appear you don't understand how the blitting to the screen works. I'll explain it the best I can for you;

There are two buffers, the draw buffer and the display buffer. Think of these as two sides of a sheet of paper. The draw buffer is on the back, and the display buffer is on the front. What happens is that you draw everything on the draw buffer(the back) then use the flipScreen function to "flip" the page over and display what you've just drawn. So you must draw everything first, then use the flipScreen function to display it on the screen.

I hope that makes sense to you, I'm not too good at explaining things... If you've got any questions about it just ask.
 

MenaceInc

Staff Member
Your code is pretty all over the place :p. Give me a while and I'll fix it up for you.

Edit: After looking at this it would appear you don't understand how the blitting to the screen works. I'll explain it the best I can for you;

There are two buffers, the draw buffer and the display buffer. Think of these as two sides of a sheet of paper. The draw buffer is on the back, and the display buffer is on the front. What happens is that you draw everything on the draw buffer(the back) then use the flipScreen function to "flip" the page over and display what you've just drawn. So you must draw everything first, then use the flipScreen function to display it on the screen.

I hope that makes sense to you, I'm not too good at explaining things... If you've got any questions about it just ask.


actually,that's pretty well explained. was what I was trying to get him to do since I guessed he was using flipScreen() elsewhere as well
 
Top