Sign in to follow this  
Stormtrooper

Wii homebrew

Recommended Posts

Stormtrooper    100
Hey all...the following code something I'm trying to get working. Drawing a square on screen. The "bork" appears on screen, but not the square. I'm using devkitPro devkitPPC and libogc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
#include <gccore.h>

u32 *xfb[2] = {NULL, NULL};
int buffer = 0;
GXRModeObj *vmode;


u32 CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2);
static void init();
void (*reload)() = (void (*) ()) 0x80001800;

int main(int argc, char **argv) {

	init();

	u32 color = CvtRGB(0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0);
	
	printf("bork\n");
	
	//  Game Loop	
	while(1) 
	{
		// Flip the buffer
		buffer ^= 1;
		
		int rows, col;
		// Draw a box
		for(rows = 0; rows < 32; rows++)
		{
			for(col = 0; col < 32; col++)
			{
				xfb[buffer][col] = color;
			}
		}
		
		/*** Set this as next frame to display ***/
		VIDEO_SetNextFramebuffer (xfb[buffer]);
		VIDEO_Flush ();
		VIDEO_WaitVSync();
		
		PAD_ScanPads ();
		
		if (PAD_ButtonsDown (0) & PAD_BUTTON_START){
			reload ();
		}
	}

	return 0;
}

/****************************************************************************
* CvtRGB
*
* This function simply returns two RGB pixels as one Y1CbY2Cr.
*****************************************************************************/
u32 CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
{
  int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
 
  y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
  cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
  cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
 
  y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
  cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
  cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
 
  cb = (cb1 + cb2) >> 1;
  cr = (cr1 + cr2) >> 1;
 
  return (y1 << 24) | (cb << 16) | (y2 << 8) | cr;
}

static void init()
{
	// Setup libogc
	VIDEO_Init();
	
	// Setup into
	PAD_Init();
	
	// Setup the video mode
	switch(VIDEO_GetCurrentTvMode()) {
		case VI_NTSC:
			vmode = &TVNtsc480IntDf;
			break;
		case VI_PAL:
			vmode = &TVPal528IntDf;
			break;
		case VI_MPAL:
			vmode = &TVMpal480IntDf;
			break;
		default:
			vmode = &TVNtsc480IntDf;
			break;
	}

	// Configure the video
	VIDEO_Configure (vmode);
	
	// Two frame buffers
	xfb[0] = (u32*)MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode));
	xfb[1] = (u32*)MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode));
	
	// Define a console
	console_init(xfb[0],20,30,vmode->fbWidth,vmode->xfbHeight,vmode->fbWidth*VI_DISPLAY_PIX_SZ);
	
	// We are going to clear the framebuffers to black
	VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
	VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
	
	// Set the framebuffer to be displayed at the next VBlank
	VIDEO_SetNextFramebuffer (xfb[0]);
	
	// Get the PAD status updated
	VIDEO_SetBlack (0);
	
	// Update the video for the next VBlank
	VIDEO_Flush();
	
	// Wait for VBL
	VIDEO_WaitVSync(); 
	
	if(vmode->viTVMode&VI_NON_INTERLACE) 
		VIDEO_WaitVSync();	
	
}

This is what I used as my reference, which works perfectly. What am I missing?
/****************************************************************************
* pflip.c
*
* libogc example for 2D video page flipping without tearing.
* Shows a checkerboard and bouncing square.
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
/*** 2D Video Globals ***/
GXRModeObj *vmode;        /*** Graphics Mode Object ***/
u32 *xfb[2] = { NULL, NULL };    /*** Framebuffers ***/
int whichfb = 0;        /*** Frame buffer toggle ***/
 
/****************************************************************************
* CvtRGB
*
* This function simply returns two RGB pixels as one Y1CbY2Cr.
*****************************************************************************/
u32
CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
{
  int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
 
  y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
  cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
  cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
 
  y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
  cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
  cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
 
  cb = (cb1 + cb2) >> 1;
  cr = (cr1 + cr2) >> 1;
 
  return (y1 << 24) | (cb << 16) | (y2 << 8) | cr;
}
 
/****************************************************************************
* Initialise Video
*
* Before doing anything in libogc, it's recommended to configure a video
* output.
****************************************************************************/
static void
Initialise (void) {

	VIDEO_Init();		/*** ALWAYS CALL FIRST IN ANY LIBOGC PROJECT!
							Not only does it initialise the video 
							subsystem, but also sets up the ogc os
						***/
 
	PAD_Init();			/*** Initialise pads for input ***/
 
	/*** Try to match the current video display mode
		using the higher resolution interlaced.
    
		So NTSC/MPAL gives a display area of 640x480
		PAL display area is 640x528
	***/

	switch (VIDEO_GetCurrentTvMode ()) {

	case VI_NTSC:
		vmode = &TVNtsc480IntDf;
		break;
 
	case VI_PAL:
		vmode = &TVPal528IntDf;
		break;
 
	case VI_MPAL:
		vmode = &TVMpal480IntDf;
		break;
 
	default:
		vmode = &TVNtsc480IntDf;
		break;
    }
 
	/*** Let libogc configure the mode ***/
	VIDEO_Configure (vmode);
 
	/*** Now configure the framebuffer. 
		Really a framebuffer is just a chunk of memory
		to hold the display line by line.
	***/
 
	xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));

	/*** I prefer also to have a second buffer for double-buffering.
		This is not needed for the console demo.
	***/
	xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
 

	/*** Define a console ***/
	console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight, vmode->fbWidth * 2);
 
	/*** Clear framebuffer to black ***/
	VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
	VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
 
	/*** Set the framebuffer to be displayed at next VBlank ***/
	VIDEO_SetNextFramebuffer (xfb[0]);
 
	/*** Get the PAD status updated by libogc ***/
	VIDEO_SetBlack (0);
 
	/*** Update the video for next vblank ***/
	VIDEO_Flush ();

	VIDEO_WaitVSync ();        /*** Wait for VBL ***/

	if (vmode->viTVMode & VI_NON_INTERLACE)
		VIDEO_WaitVSync ();
 
}


/****************************************************************************
* Main
*
* Create a checkerboard, and flip it
****************************************************************************/
int main () {
	u32 *checkerboard;
	u32 colour1, colour2, colswap;
	int rows, cols;
	int height;
	int i, j, t, v;
	int pos = 0;
	int startx, starty;
	int directionx, directiony;
	PADStatus pads[4];
 
	/*** Start libOGC ***/
	Initialise ();
 
	/*** Allocate a buffer to hold the checkerboard ***/
	height = vmode->xfbHeight + 64;
	checkerboard = (u32 *) malloc ((704 * height * 2));
	colour1 = CvtRGB (0x00, 0x00, 0x80, 0x00, 0x00, 0x80);
	colour2 = CvtRGB (0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0);
 
	for (i = 0; i < height; i += 32) {
		/*** Draw a line ***/
		colswap = colour1;
		colour1 = colour2;
		colour2 = colswap;
 
		for (v = 0; v < 32; v++)
		{
			for (t = 0; t < 11; t++)
			{
				for (j = 0; j < 16; j++)
					checkerboard[pos++] = colour1;
 
				for (j = 0; j < 16; j++)
					checkerboard[pos++] = colour2;
			}
 
		}
    }
 
	pos = 0;
	colour1 = CvtRGB (0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
	startx = starty = directionx = directiony = 0;
 
	while(1) {

		/*** Flip to off screen xfb ***/
		whichfb ^= 1;
 
		/*** Draw checkerboard ***/
		t = 0;
		v = 0;

		for (j = 0; j < vmode->xfbHeight; j++) {
			memcpy (&xfb[whichfb][v], &checkerboard[pos + t], 1280);
			t += 352;
			v += 320;
		}

		/*** Draw Bouncing Square ***/
		if (directionx)
			startx -= 4;
		else
			startx += 4;
 
		if (directiony)
			starty -= 2;
		else
			starty += 2;
 
		if (startx >= 576) directionx = 1;
 
		if (starty >= (vmode->xfbHeight - 64)) directiony = 1;
 
		if (startx < 0) {
			startx = 0;
			directionx = 0;
		}
 
		if (starty < 0) {
			starty = 0;
			directiony = 0;
		}
 
		v = (starty * 320) + (startx >> 1);

		for (rows = 0; rows < 64; rows++) {
			for (cols = 0; cols < 32; cols++)
				xfb[whichfb][v + cols] = colour1;
 
			v += 320;
		}
 
		/*** Set this as next frame to display ***/
		VIDEO_SetNextFramebuffer (xfb[whichfb]);
		VIDEO_Flush ();
		VIDEO_WaitVSync ();
 
		/*** Move the checkerboard along ***/
		pos += 353;

		if (pos == ((352 * 64) + 64)) pos = 0;

		PAD_ScanPads(0);
		PAD_Read(pads);
		if (pads[0].button & PAD_BUTTON_START) {
			void (*reload)() = (void(*)())0x80001800;
			reload();
		}

	}

	return 0;
}


Share this post


Link to post
Share on other sites
kiwibonga    183
for(rows = 0; rows < 32; rows++)
{
for(col = 0; col < 32; col++)
{
xfb[buffer][col] = color;
}
}


Should probably be:

for(cols = 0; cols < 32; cols++)
{
for(rows = 0; rows < 32; rows++)
{
xfb[buffer][rows+cols*32] = color;
}
}


Otherwise, you're just drawing a 32 pixel horizontal line at the very top left (which probably will be off-screen on a TV).

Also, you didn't specify an offset, this means it'll draw the box in the top left corner of the screen. You might want to change that to xfb[buffer][rows+box_x + (cols+box_y)*32].

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this