Getting started


quadcricket

Very Active Member
Joined
Mar 28, 2008
Messages
104
So I just got my Pandora and am trying to get started in this whole development/porting scene. 

I followed the wiki to the point of installing Ivanovic's cross compiler. 

I've run the script and it loaded a folder called pandora_dev in my ~/Code folder. 

I'm an amateur C programmer who is familiar with Linux (Currently running Centos 6.3 Desktop).

I am just trying to get from running "./openpandora_toolchain.sh" to "gcc hello.c -o hello" and copying the program to my SD card.

Any help would be appreciated. 

Edit:

I found the pandora-gcc (symlink) in the pandora-dev/arm-2011.09/bin folder and it looks like it compiles just fine. I will get to test the binary it created this evening.

For some reason (even when I tried to manually export it) it would not add the bin folder to my $PATH. I will have to look into that later. 

(I will also try to test lSDL linking if my "Hello world" program works just fine.)

Edit2:

"Hello world" works! The $PATH works as well (updated .bashrc and logged out/in). Now on to testing SDL.

Edit3: 

I am currently running into problems with the cross-compiler finding SDL.h. In my code I have #include <SDL/SDL.h> and it compiles fine on the pandora

when I use the dev tools PND and compile it natively. Though on my computer I get: 

"prints.c:3:17: fatal error: SDL.h: No such file or directory"

Any help/suggestions would be appreciated. 

Edit4:

Got it to cross compile with SDL. I don't know why I didn't think of adding the paths manually before:


pandora-gcc prints.c -o prints.panda -I/home/$USER/Code/pandora-dev/arm-2011.09/usr/include/SDL -L/home/$USER/Code/pandora-dev/arm-2011.09/usr/lib -lts -lSDL -lfreetype -lSDL_ttf -lpthread

I will look for other compile options for C as well (for optimization and to get rid of the "assertion fail" errors I'm getting.

If you have any suggestions please let me know. 

May the coding fun begin!
 
Last edited by a moderator:
Cool! it's good to see you got it working... your little guide here might be helpful to others ;)

I'm still compiling only on the Pandora, have not tried a cross-compiler yet.

Are you going to do some porting or original coding or what? Let us know, and good luck with it!
 
Cool! it's good to see you got it working... your little guide here might be helpful to others ;)


I'm still compiling only on the Pandora, have not tried a cross-compiler yet.


Are you going to do some porting or original coding or what? Let us know, and good luck with it!
My goal is to start programming original content for the Pandora. I am still very much a programming newbie but know games and *nix stuff pretty well. 

Hopefully I can get through a few more tutorials and start making demos.

If there is any interest in a beginner C tutorial specific to the Pandora I wouldn't mind making one of those either. It's nice to get other people interested in coding.

Thanks for the support! I'll post back with any news.  :)
 
I've so far created a portable header file that allows me to just enter "prints("Hello, world... MUAHAHAHA!", screen, letters, attributes );" and it will render. 

Not the most graceful thing in the world but a lot simpler for getting basic text-based applications to render on the Panda. It handles tabs and newlines as well.  

With it I made a printsInit() function that sets up your TTF font(s) for rendering (uses SDL_ttf). 

Screenshot of my desktop where the app compiles and cross-compiles:

Hello_world_desktop-small.png

 

Screenshot taken from Pandora:

hello-panda.png
 
Last edited by a moderator:
Have made it to 1-2 in K&R. Will go a little further in the book to see of I run into further problems with handling text with my new header and game loops. 

I'm still starting out so of course if you see some issues/mistakes let me know. 

fahr.png


prints.h




/*
* This is prints.h (for the Pandora handheld).
* GOAL: to create a header that defines a function prints() and it's initializer printsInit().
* I am creating this since I want other developers to be able to just include this header to create their first graphical "Hello world" program easily.
*
* prints( const char text[], SDL_surface *screen, SDL_Surface *abc[MAXCHAR], int v[7] )
*
* SDL_surface *screen - the SDL_surface created that will have the text written to it
* SDL_surface *abc - the character string that will be parsed
* int v[5] - I made this an int array for the easy of coding.
*
* example: prints( text, \ // the text you want to render
* screen, \ // the surface you want to render to
* chars, \ // the font you setup with printsInit
* v \ // the extra stuff
* );
*
* Here are the contents explained:
*
*
* v[0] - character width spacing (how far apart the letters are written on the x coord).
* v[1] - character height spacing
* v[2] - surface width in pixels (in the case of the Pandora 800 should be popular.
* v[3] - surface height in pixels (480 for full screen Pandora surface).
* v[4] - tab width (I like four, some like 2, others like 8...).
*
*
* printsInit( SDL_Surface *abc[MAXCHAR], char *fontPath, char *fontName, int fontSize, int color[4] )
*
* SDL_Surface *abc - an array of surfaces that we will render the letters to
* char *fontPath - the character string that defines the location where fonts are stored
* char *fontName - the TTF font to be rendered
* int fontSize - how large to render the TTF font to the surfaces created for each individual letter
* int color[4] - font color: color[0] = Red value, color[1] = Green value, color[2] = Blue value, color[3] = opacity (for use in SDL_Color rgb = {255,255,255,255})
*
*/

#include "SDL_ttf.h"

#define MAXCHAR 95 // the maximum number of printable characters to create (normally 95 for English ASCII)
#define TABWIDTH 4


/* printsInit */
int printsInit( SDL_Surface *abc[MAXCHAR], char *fontPath, char *fontName, int fontSize, SDL_Color color ) {

/* initialize SDL_ttf and check for errors. */
if ( TTF_Init() == -1 ) {
printf("Unable to initialize TTF: %s\n", TTF_GetError());
return 1;
}

int i = 0; /* our counter */

/* let's creat a variable with the full font path. */
char *fullFontPath;
fullFontPath = malloc(512 * sizeof(char)); /* Make sure it's large enough. */
strncpy( fullFontPath, fontPath, 512); /* Add the path. */
strncat( fullFontPath, fontName, 512); /* use strcat to append the fontName to the path. */

/* Open the font you would like to use for rendering. */
TTF_Font *font = TTF_OpenFont( fullFontPath, fontSize);

/* Check if file actually exists. */
if( font == NULL ) {
printf("Font not found!\n");
return -1;
}

/* Lets fill an array of little pre-rendered surfaces for each letter to save time. */
char letter[] = " "; /* Set the first character to space which is the beginning of ASCII printable characters. */

/* Now loop through the entire printable ASCII set and reder them to a surface. */
for ( i = 0; i < MAXCHAR; i++ ) {
abc = TTF_RenderText_Blended( font, letter, color );
letter[0] += 1; /* this looks odd.. letter is a STRING not a char.. so [1] is always \0.
this increment turns a into b and b into c etc. */
}

/* free our malloc. */
free(fullFontPath);

TTF_CloseFont( font );

return 0;
}


/* Here is our prints function for writing TTF fonts to a SDL_Surface array. */
int prints( const char *text, SDL_Surface *surface, SDL_Surface *abc[MAXCHAR], int v[7] ) {

// check to see if anything is NULL
if ( text == NULL ) {
printf("character string is NULL\n");
return -1;
}

// tabcount will keep track of which column we are currently in.
int tabcount = 1;

/* create a SDL_Rect (x, y coord) in order to blit. */
SDL_Rect dest;

/* this modifies our variable that tells us WHERE to write our surface
* and how big to create the surface for each character. */
dest.x = 0;
dest.y = 0;

// set i for use
int i = 0;

for( ; i < MAXCHAR; i++ )
SDL_ConvertSurface( abc, surface->format, SDL_HWSURFACE );

i = 0;

/* Once we have all of the letters we may move on to rendering them to the screen. */
while ( text != '\0' ) {

// check for escape character.
while ( text == '\\' && text[i+1] != '\\' ) { // If the current character is "\".
// and the next char is not "\".
i++; // skip to the next character!
tabcount = 1; // reset our tab counter
switch ( text ) {

case 'n': // and the character is 'n' which indicates newline.
dest.y += v[1]; // Skip one line's worth of pixels DOWN on the surface.
dest.x = 0; // AND reset X to start all the way to the left.
i++; // Now increment to print the next character
break;

case 't': // and the character is 't' which idicates a tab.
// here we need to figure out which tab column to align to.
while(1) {

if ( dest.x < v[0]*v[4]*tabcount ) {
dest.x = v[0]*v[4]*tabcount;
break;
}
tabcount++;
}
i++; // skip past t
break;

case 'a': // and is a for "alert" do nothing.
i++; // increment past a.
break;

case 'b': // and is b for "backspace" so subtract letter width from x.
dest.x -= v[0];
i++; // increment past b.
break;

case 'f': // and is f for "formfeed" so go down one character height.
dest.y += v[1];
i++; // increment past f.
break;

case 'v': // and is v for "vertical tab" do nothing.
i++; // increment past v.
break;

case 'r': // and is r for "return" so return x to 0.
dest.x = 0;
i++; // increment past r.
break;

default: // The character is anything other than the aforementioned.
break; // Do nothing.
}
}
// check to see if the next printed character is off the screen (x axis)
if ( dest.x >= v[2])
{
dest.x = 0; // Go back to the beginning of the line.
dest.y += v[1]; // And go down one line.
}

// check to see if the next printed character is off the screen (y axis)
if ( dest.y >= v[3])
{
break; // just quit the loop if it is.
}

if ( text == '\0' ) {
break;
}

SDL_BlitSurface(abc[text-32], NULL, surface, &dest);
dest.x += v[0];

// Now if the current character is "\" then the next one is as well...
// see exception in the while() above
// so we need to increment past the next "\" AFTER we render the current one
// which we are doing here.
if ( text == '\\' )
{
i+=2;
}
else
{
i++; // Otherwise just increment the array to print the next character.
}
}

return 0;
}


fahr.c




/* fahr.c
* a simple "Hello world" type program using prints.h
*/
/* this has been modified to change font. */

#include "stdio.h"
#include "SDL.h"
#include "SDL_image.h"
#include "prints.h"

#define PRNTABL 95 // There are 95 printable letters in ASCII

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

/* initial setup */
SDL_Surface *screen; // the surface that will be blitted to the screen
SDL_Event event; // event needed to capture input
short int running = 1; // boolian for the main game loop
int i = 0; // our incrementer

/* create the screen surface */
screen = SDL_SetVideoMode( 800, 480, 16, SDL_HWSURFACE ); // screen width, screen height, bits per pixel, screen option (0 is window)
//screen = SDL_SetVideoMode( 800, 480, 16, SDL_FULLSCREEN );
if( screen == NULL ) {
printf( "Unable to set video mode: %s\n", SDL_GetError());
return 1;
}

SDL_Color color0 = { 175, 175, 255 }; // The color of our font { RRR, GGG, BBB }

SDL_Surface *letters[PRNTABL]; // surfaces to hold our font
int attributes[5] = { 8, // Letter spacing horizontally
16, // Letter spacing vertically
800, // surface width (in this case screen width)
480, // surface height
4 }; // spaces in a tab

/* Start SDL */
if ( SDL_Init( SDL_INIT_VIDEO ) == -1 ) {
printf("Unable to initialize SDL: %s\n", SDL_GetError() );
return 1;
}
atexit(SDL_Quit);

/* Create our font */
if ( printsInit( letters, "./fonts/", "ProggyCleanSZBP.ttf", 16, color0 ) == -1 ) { // letters, font path, font, font size, font color
printf("Unable to initialize prints\n");
return 1;
}

/* put your code here vvv */

// fahr to celsius variables:
int fahr, celsius;
int lower, upper, step;

lower = -40; // lower limit of conversion table
upper = 90; // upper limit of conversion table
step = 5; // our incrementer

fahr = lower;

char text[3200]; // our text array for printing our conversion table.
char conversionText[80]; // the buffer to hold the text of the conversion (to be cat'd to text[])

strncpy( text, "Farenheit to celsius conversion:\\t\\t\\t\\t\\t\\t\\t\\t\\t(Press 'q' or 'escape' to quit.)\\n\\n", 256 );

while( fahr <= upper ) {
celsius = 5 * (fahr-32) / 9;
sprintf( conversionText, "If the temperature is %dF\\tthen it is %dC.\\n", fahr, celsius);
strncat( text, conversionText , 3200 );
fahr = fahr + step;
}

/* main game loop */
while( running ) {

SDL_FillRect( screen, NULL, SDL_MapRGB( screen->format, 0, 0, 42 ) ); // add some color to the screen surface.

prints( text, screen, letters, attributes );

while( SDL_PollEvent( &event ) ) {
switch( event.type ) {
case SDL_KEYDOWN:
case SDL_KEYUP:
switch( event.key.keysym.sym ) {
case SDLK_q:
running = 0;
break;
case SDLK_ESCAPE:
running = 0;
break;
}

break;
case SDL_QUIT:
running = 0;
break;
}
}
// render screen to actual video buffer
SDL_UpdateRect( screen, 0, 0, 0, 0 );
SDL_Delay( 100 );
}
/* put your code here ^^^ */


// SDL_Delay( 9000 );

// Free our surfaces
SDL_FreeSurface( screen );

i = 0;
for ( ; i <= PRNTABL-1; i++ ) {
SDL_FreeSurface( letters );
}

return 0;
}

compile.sh




#!/bin/bash
gcc main.c `sdl-config --cflags --libs` -lSDL_ttf -lSDL_image
echo done!

(You shouldn't need "-lSDL_imge for this app since I didn't use any .pngs in it. )

compile-pandora.sh


#!/bin/bash
#pandora-gcc prints.c -o prints.panda `sdl-config --cflags --libs` -I/home/$USER/Code/pandora-dev/arm-2011.09/usr/include/SDL -lSDL_ttf
pandora-gcc main.c -o test.panda -I/home/$USER/Code/pandora-dev/arm-2011.09/usr/include/SDL -L/home/$USER/Code/pandora-dev/arm-2011.09/usr/lib -lts -lSDL -lfreetype -lpng -lz -ltiff -ljpeg -lSDL_ttf -lSDL_image -lpthread
echo done!
(remember to replace $USER for the path and change the path to the correct "pandora-dev" folder.)
 
Last edited by a moderator:
Back
Top