I have just a little problem on make colors changes, when i specify a new color in Draw() function, seems it take only the first one.
Somebody can help with the issue?
I hope this snippets can be useful anyway :]
- {l Code}: {l Select All Code}
// gcc -o bmpfont bmpfont.c -lSDL
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
SDL_Color white = {255, 255, 255};
SDL_Color cyan = {0, 255, 255};
SDL_Color orange = {255, 128, 0};
//Global variables
int t, tl = 0, frequency = 1000 / 100, temp;
int repeat, i, quit=0;
int playing = 1;
SDL_Event event;
SDL_Surface *screen, *textSurface;
SDL_Rect rect; //Main drawing surface
Uint8 *keystate; // keyboard state
char text[20]; //Hold text
char message[35];
SDL_Surface *bmpfont;
SDL_Rect area;
Uint32 get_pixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch (bpp)
{
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0;
}
}
void put_pixel(SDL_Surface *_ima, int x, int y, Uint32 pixel)
{
int bpp = _ima->format->BytesPerPixel;
Uint8 *p = (Uint8 *)_ima->pixels + y * _ima->pitch + x*bpp;
switch (bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0]=(pixel >> 16) & 0xff;
p[1]=(pixel >> 8) & 0xff;
p[2]=pixel & 0xff;
}
else
{
p[0]=pixel & 0xff;
p[1]=(pixel >> 8) & 0xff;
p[2]=(pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = pixel;
break;
}
}
/**
* Rimpiazza un colore specifico (target) con uno un rimpiazzo (replecement)
* in una zona ben precisa di una determinata superficie pixel per pixel
*
* @param SDL_Surface *src
* Puntatore alla superficie su cui agire
* @param Uint32 target
* Colore RGB da sostituire
* @param Uint32 replacement
* Colore RGB di rimpiazzo
* @param SDL_Rect pick
* Regione della superifice su cui agire
**/
void replaceColor (SDL_Surface * src, Uint32 target, Uint32 replacement, SDL_Rect pick)
{
int x;
int y;
if (SDL_MUSTLOCK (src))
{
if (SDL_LockSurface (src) < 0)
return;
}
for (x = pick.x; x < (pick.x+pick.w); x ++)
{
//~ printf("X %d\n", x);
for (y = pick.y; y < (pick.y+pick.h); y ++)
{
//~ printf("Y %d\n", y);
if (get_pixel (src, x, y) == target)
put_pixel (src, x, y, replacement);
}
}
if (SDL_MUSTLOCK (src))
SDL_UnlockSurface (src);
}
/**
* Copia una porzione dalla superficie bmpfont e la copia sulla superficie screen
*
* @param SDL_Surface *screen
* Puntatore alla superficie di destinazione
* @param SDL_Surface *bmpfont
* Puntatore alla superficie di origine
* @param int X, int Y
* Destinazione in cui si andra' a copiare il contenuto di origine
* @param int w, int h
* Rispettivamente, larghezza e grandezza della superficie da copiare
* @param int asciicode
* Singolo carattere convertito in un equivalente decimale
* @param SDL_Color color
* Struttura contenente i valori RGB di colore da usare per la superficie
**/
void DrawChar(SDL_Surface *screen, SDL_Surface *bmpfont, int X, int Y, int w, int h, int asciicode, SDL_Color color)
{
SDL_Rect pick;
SDL_Surface temp;
//Cordinate nella superficie con le lettere
pick.x=(asciicode % 32)*w;
pick.y=(asciicode / 32)*h;
pick.w=w;
pick.h=h;
area.x=X;
area.y=Y;
area.w=w;
area.h=h;
replaceColor (bmpfont, SDL_MapRGB (bmpfont->format, 255, 255, 255),
SDL_MapRGB (bmpfont->format, color.r, color.g, color.b), pick);
//int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
SDL_BlitSurface(bmpfont,&pick,screen,&area);
}
void Drawstring(SDL_Surface *screen, int X, int Y, char text[], SDL_Color color) {
int i=0;
int asciicode;
area.x=X;
area.y=Y;
//Per la lunghezza della stringa
for (i=0;i<35;i++){
asciicode=text[i]; //Valori decimali del carattere
//~ printf("%d ascii\n", asciicode);
if (asciicode == 0 ) {
break;
}
// 8x16 dimensioni della lettera
DrawChar(screen, bmpfont, area.x, area.y, 8, 16, asciicode, color);
area.x=area.x+8;
}
}
void DrawRect(int x, int y, int width, int height, int color)
{
rect.x = x;
rect.y = y;
rect.w = width;
rect.h = height;
SDL_FillRect(screen, &rect, color);
}
void Draw()
{
sprintf(message,"Example text! AAAABBBBBBCCCCCCCCC");
Drawstring(screen, 10, 10, message, cyan); //draw string with bmp font
sprintf(message,"Example text!");
Drawstring(screen, 10, 40, message, orange); //draw string with bmp font
}
int fps_sync (void)
{
t = SDL_GetTicks ();
if (t - tl >= frequency)
{
temp = (t - tl) / frequency;
tl += temp * frequency;
return temp;
}
else
{
SDL_Delay (frequency - (t - tl));
tl += frequency;
return 1;
}
}
int getInput()
{
// Grab a keystate snapshot
keystate = SDL_GetKeyState( NULL );
/* Handle key presses */
}
int mainLoop()
{
//main game loop
while(!quit)
{
SDL_PollEvent(&event);
repeat = fps_sync ();
for (i = 0; i < repeat; i ++)
{
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE))
quit = 1; /* Window closed and game stopped */
}
// Cancella tutto lo schermo di gioco
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
//draw to the screen
Draw();
// Aggiorna lo schermo di gioco
SDL_Flip(screen);
}
}
int main()
{
// init video stuff
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
fprintf(stderr, "Can't initialize SDL: %s\n", SDL_GetError());
exit(-1);
}
atexit(SDL_Quit);
// init screen
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE);
if(screen == NULL)
{
fprintf(stderr, "Can't initialize SDL: %s\n", SDL_GetError());
exit(-1);
}
bmpfont=SDL_LoadBMP("dosemu.bmp");
if (bmpfont == NULL) {
printf("Can't load font: %s\n", SDL_GetError()); //check stdout.txt for this
exit(1);
}
//main game loop
mainLoop();
printf("Game has exit\n");
SDL_Quit();
return 0;
}
The font is here http://i56.tinypic.com/29z861.jpg