Files
GameLib/Draw.c
2011-12-22 20:00:00 +01:00

494 lines
9.1 KiB
C

// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado)
#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <windows.h>
#endif
#include <SDL/SDL.h>
#include <time.h>
#include "Time.h"
#include "Util.h"
#include "Draw.h"
#include "Input.h"
#include "Audio.h"
// Globals
SDL_Surface *_screen=NULL;
long long _t_frame=17000;
/////////////////////////////
// Draw_Init
//
// Initializes the game window.
int Draw_Init(int width,int height,char *title,int fps){
#ifdef WIN32
// Stdout on the parent console
AttachConsole(ATTACH_PARENT_PROCESS);
if(GetStdHandle(STD_OUTPUT_HANDLE)!=0){
fclose(stdin);
fclose(stdout);
fclose(stderr);
freopen("CONIN$","r",stdin);
freopen("CONOUT$","w",stdout);
freopen("CONOUT$","w",stderr);
}
#endif
// Initialize SDL
if(SDL_Init(SDL_INIT_VIDEO)<0){
printf("Draw_Init: Failure initializing SDL.\n");
printf("Draw_Init: SDL Error: %s\n",SDL_GetError());
return(0);
}
// Initialize video mode
_screen=SDL_SetVideoMode(width,height,32,SDL_HWSURFACE);
if( _screen == NULL){
printf("Draw_Init: Failure initializing video mode.\n");
printf("Draw_Init: SDL Error: %s\n",SDL_GetError());
return(0);
}
SDL_WM_SetCaption(title, NULL);
_t_frame=1000000/fps;
return(1);
}
/////////////////////////////
// Draw_Loop
//
// Loops updating the game window.
void Draw_Loop(int (*proc)()){
int done=0;
SDL_Event event;
Uint8* keys;
long long t_framestart;
long long t_frame;
long long t_swap;
long long t_proc;
int f_count;
t_framestart=Time_GetTime();
while(!done){
// Update screen
t_swap=Time_GetTime();
SDL_Flip(_screen);
t_swap=Time_GetTime()-t_swap;
// Process Events
while(SDL_PollEvent(&event) ){
if(event.type == SDL_QUIT ){
done=1;
}
if(event.type == SDL_KEYDOWN ){
if(event.key.keysym.sym == SDLK_ESCAPE ) {
done=1;
}
}
}
// Process keys for Draw
keys=SDL_GetKeyState(NULL);
if(keys[SDLK_F12]){
// Screenshot key
SDL_SaveBMP(_screen,"shot.bmp");
}
// Input and sound Frame
Input_Frame();
Audio_Frame();
// Process loop, with frameskip for slow swapping systems
t_proc=Time_GetTime();
if(!proc()){
done=1;
}
f_count=(t_swap/_t_frame);
while(f_count>0 && !done){
if(!proc()){
done=1;
}
f_count--;
t_framestart+=_t_frame;
}
t_proc=Time_GetTime()-t_proc;
t_framestart+=_t_frame*(t_proc/_t_frame);
// Sleep to limit frames
t_frame=Time_GetTime()-t_framestart;
if(t_frame<_t_frame){
Time_Pause(_t_frame-t_frame);
}else{
Time_Pause(0);
}
t_framestart=Time_GetTime();
}
}
/////////////////////////////
// Draw_Clean
//
// Cleans the game window.
void Draw_Clean(
unsigned char r,
unsigned char g,
unsigned char b)
{
SDL_Rect rect;
// Draw a full rectangle
rect.x=0;
rect.y=0;
rect.w=_screen->w;
rect.h=_screen->h;
SDL_FillRect(_screen, &rect,
SDL_MapRGB(_screen->format, r, g, b));
}
////////////////////////////////////////////////
// DrawImage //
///////////////
// Image container.
typedef struct Tag_DrawImage {
SDL_Surface *surf;
int x,y;
} DrawImage;
/////////////////////////////
// Draw_LoadSurface
//
// Loads a surface.
SDL_Surface *Draw_LoadSurface(char *filename){
SDL_Surface *surf;
// Load the BMP as a surface
surf=SDL_LoadBMP(filename);
if(surf == NULL){
printf("Draw_LoadImage: Failure Loading image: %s\n",filename);
printf("Draw_LoadImage: SDL Error: %s\n",SDL_GetError());
return(NULL);
}
// FIX: Setting up the alpha channel.
if(surf->format->BytesPerPixel==4){
int i,len,trans;
// set the correct values
surf->format->Amask=0xFF000000;
surf->format->Ashift=24;
// Check if the image has some area transparent
trans=0;
len=surf->w*surf->h;
for(i=0;i<len;i++){
if((((Uint32 *)surf->pixels)[i]&0xFF000000)!=0xFF000000){
trans=1;
break;
}
}
if(trans){
// Make it use the alpha channel
SDL_SetAlpha(surf, SDL_SRCALPHA, 255);
}
}
return(surf);
}
/////////////////////////////
// Draw_LoadImage
//
// Loads a image, giving a reference.
DrawImg Draw_LoadImage(char *filename){
DrawImage *image;
SDL_Surface *surf;
// Loads the surface
surf=Draw_LoadSurface(filename);
if(surf == NULL){
return(NULL);
}
// Create the image container
image=malloc(sizeof(DrawImage));
image->surf=surf;
image->x=0;
image->y=0;
return((DrawImg)image);
}
/////////////////////////////
// Draw_GetSize
//
// Gets the image size.
void Draw_GetSize(DrawImg img,int *w,int *h){
DrawImage *image=img;
// Gets the image size
*w=image->surf->w;
*h=image->surf->h;
}
/////////////////////////////
// Draw_SetOffset
// Draw_GetOffset
//
// Sets and Gets the image offset.
void Draw_SetOffset(DrawImg img,int x,int y){
DrawImage *image=img;
// Sets the image offset
image->x=x;
image->y=y;
}
void Draw_GetOffset(DrawImg img,int *x,int *y){
DrawImage *image=img;
// Gets the image offset
*x=image->x;
*y=image->y;
}
/////////////////////////////
// Draw_ImgSetKeyCol
//
// Setting the image color key.
void Draw_ImgSetKeyCol(DrawImg img,
unsigned char r,
unsigned char g,
unsigned char b)
{
DrawImage *image=img;
// Set the color key for the surface
SDL_SetColorKey(image->surf, SDL_SRCCOLORKEY,
SDL_MapRGB(image->surf->format, r, g, b));
}
/////////////////////////////
// Draw_ImgSetAlpha
//
// Setting the image alpha.
void Draw_ImgSetAlpha(DrawImg img, unsigned char a){
DrawImage *image=img;
// Set the alpha for the surface
SDL_SetAlpha(image->surf, SDL_SRCALPHA, a);
}
/////////////////////////////
// Draw_DrawImg
//
// Draws an image.
void Draw_DrawImg(DrawImg img,int x,int y){
DrawImage *image=img;
SDL_Rect orig;
SDL_Rect dest;
// Prepare the rects
orig.x=0;
orig.y=0;
dest.x=x+image->x;
dest.y=y+image->y;
orig.w=dest.w=image->surf->w;
orig.h=dest.h=image->surf->h;
// Blit the surface on the screen
SDL_BlitSurface(image->surf,&orig,_screen,&dest);
}
/////////////////////////////
// Draw_DrawImgPart
//
// Draws an image part.
void Draw_DrawImgPart(DrawImg img,int x,int y,int w,int i){
DrawImage *image=img;
SDL_Rect orig;
SDL_Rect dest;
// Prepare the rects
orig.x=w*i;
orig.y=0;
dest.x=x+image->x;
dest.y=y+image->y;
orig.w=dest.w=w;
orig.h=dest.h=image->surf->h;
// Blit the surface on the screen
SDL_BlitSurface(image->surf,&orig,_screen,&dest);
}
/////////////////////////////
// Draw_DrawImgTrans
//
// Draws an image transformed.
void Draw_DrawImgTrans(DrawImg img,int x,int y,float angle){
DrawImage *image=img;
SDL_Rect orig;
SDL_Rect dest;
// Prepare the rects
orig.x=0;
orig.y=0;
dest.x=x+image->x;
dest.y=y+image->y;
orig.w=dest.w=image->surf->w;
orig.h=dest.h=image->surf->h;
// Blit the surface on the screen
SDL_BlitSurface(image->surf,&orig,_screen,&dest);
}
////////////////////////////////////////////////
// DrawFnt //
/////////////
// Reference to a Font.
typedef struct {
SDL_Surface *surf;
int w,h;
int min,max;
} DrawFont;
/////////////////////////////
// Draw_DefaultFont
//
// Creates a surface with the default font.
#include "FontData.h"
SDL_Surface *Draw_DefaultFontSurface(
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
{
SDL_Surface *surf;
int x,y,c;
Uint32 color,color2;
// Create the surface
surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
8*256, 8, 32,0,0,0,0);
surf->format->Amask=0xFF000000;
surf->format->Ashift=24;
SDL_SetAlpha(surf, SDL_SRCALPHA, 255);
// Draw the font
SDL_LockSurface(surf);
color =SDL_MapRGBA(surf->format,r,g,b,a);
color2=SDL_MapRGBA(surf->format,r,g,0,0);
for(c=0;c<256;c++){
for(y=0;y<8;y++){
for(x=0;x<8;x++){
if(((fontdata_8x8[c*8+y]>>(7-x)) & 0x01)==1){
//Imagen_PutPixel(dest,c*8+x,y,color);
((Uint32 *)surf->pixels)[(c*8+x)+(8*256*y)]=
color;
}else{
//Imagen_PutPixel(dest,c*8+x,y,color2);
((Uint32 *)surf->pixels)[(c*8+x)+(8*256*y)]=
color2;
}
}
}
}
SDL_UnlockSurface(surf);
return(surf);
}
/////////////////////////////
// Draw_DefaultFont
//
// Creates the default font.
DrawFnt Draw_DefaultFont(
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
{
DrawFont *font;
// Create the default font
font=malloc(sizeof(DrawFont));
font->surf = Draw_DefaultFontSurface(r,g,b,a);
font->w=8;
font->h=8;
font->min=0;
font->max=128;
return((DrawFnt)font);
}
/////////////////////////////
// Draw_LoadFont
//
// Load a font from a file.
DrawFnt Draw_LoadFont(char *fichero,int min,int max){
DrawFont *font;
int w,h;
// Create the default font
font=malloc(sizeof(DrawFont));
font->surf = Draw_LoadSurface(fichero);
font->w=font->surf->w/(max-min);
font->h=font->surf->h;
font->min=min;
font->max=max;
return((DrawFnt)font);
}
/////////////////////////////
// Draw_DrawText
//
// Draws text using a font
void Draw_DrawText(DrawFnt f,char *text,int x,int y){
DrawFont *font=f;
SDL_Rect orig;
SDL_Rect dest;
char *ptr;
// Prepare the rects
orig.w=dest.w=font->w;
orig.h=dest.h=font->h;
orig.y=0;
dest.x=x;
dest.y=y;
// Iterate the string
ptr=text;
while(*ptr){
if((*ptr)<font->max){
orig.x=((*ptr)-font->min)*font->w;
dest.x=x;
dest.y=y;
// Blit every character
SDL_BlitSurface(font->surf,&orig,_screen,&dest);
}
x+=font->w;
ptr++;
}
}