src/SAL.cpp

00001 /*
00002     SAL - Simple Application Library
00003     Copyright (C) 2006-2006 Kronon
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     Kronon
00020     kronon88@users.sourceforge.net
00021 */
00022 
00023 //SAL main file 
00024 //Created by Kronon
00025 
00026 //Doxy gen information
00027 
00033 #define __SAL_CORE__
00034 #include "SAL.h"
00035 
00036 
00037 int SAL_set_video_mode(int width, int height,int depth,int refresh_rate, bool full_screen);
00038 
00054 //Load SAL library
00055 int SAL(const char* name, int width, int height,int depth,int refresh_rate, bool full_screen)
00056 {
00057     if(SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
00058     {
00059         salError("Fatal: SDL couldn't initialise properly");
00060     }
00061         atexit(SAL_quit);
00062     
00063     if(TTF_Init()==-1) {
00064         salError("Couldn't load TTF library");
00065     }
00066     
00067         //TODO:Should be /etc/SAL.conf or ~/.SAL.conf
00068     //Load the default config file
00069         salConf config = salConf(".SAL.conf", 20);
00070     
00071     //Color masks
00072     #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00073         SAL_struct.setting.render.cmask.r = 0xff000000;
00074         SAL_struct.setting.render.cmask.g = 0x00ff0000;
00075         SAL_struct.setting.render.cmask.b = 0x0000ff00;
00076         SAL_struct.setting.render.cmask.a = 0x000000ff;
00077     #else
00078         SAL_struct.setting.render.cmask.r = 0x000000ff;
00079         SAL_struct.setting.render.cmask.g = 0x0000ff00;
00080         SAL_struct.setting.render.cmask.b = 0x00ff0000;
00081         SAL_struct.setting.render.cmask.a = 0xff000000;
00082     #endif
00083         
00085     
00086     //Init gui objects
00087     SAL_struct.internal.gui.buttons.last_id=1;
00088 //     SAL_init_button();
00089         SAL_struct.internal.gui.images.last_id=1001;
00090         SAL_struct.internal.gui.textboxes.last_id=2001;
00091         SAL_struct.internal.gui.inputBoxes.last_id=3001;
00092 //     SAL_init_inputBox();
00093 
00094         SAL_struct.setting.gui.button.w = 120;
00095         SAL_struct.setting.gui.button.h = 30;
00096         SAL_struct.internal.event.action_handler.action = NULL;
00097         SAL_struct.internal.event.action_handler.mouse = NULL;
00098         SAL_struct.internal.event.action_handler.keyboard = NULL;
00099         SAL_struct.internal.event.active_object = NULL;
00100         SAL_struct.setting.common.network_time_out_time = 1000;
00101         SAL_struct.setting.common.max_con_network_listener = 5;
00102     
00103         SAL_struct.internal.checks.start = 1;
00104         SAL_struct.setting.audio.on = false;
00105         SAL_struct.setting.render.refresh_rate = 0;
00106         SDL_WM_SetCaption(name, name);
00107         
00108     //Button colors
00109         SAL_struct.setting.gui.button.bgcolor   = config.getColor("button_bg");
00110         SAL_struct.setting.gui.button.bocolor   = config.getColor("button_bo");
00111         SAL_struct.setting.gui.button.fgcolor   = config.getColor("button_fg");
00112         SAL_struct.setting.gui.button.prcolor   = config.getColor("button_pr");
00113         SAL_struct.setting.gui.mouse_delay              = config.getInt("mouse_delay");
00114         SAL_struct.setting.gui.keyboard_delay   = config.getInt("keyboard_delay");
00115         SAL_struct.setting.common.library_dir   = config.getString("lib_dir").c_str();
00116         SAL_struct.setting.render.mode                  = config.getString("render_mode").c_str();
00117     
00118         SAL_struct.setting.gui.button.w = config.getInt("textbox_width");
00119     
00120     if(SAL_set_video_mode(width, height, depth, refresh_rate, full_screen) < 0)
00121         return -1;
00122     
00123         //Set standard font
00124         SAL_struct.setting.gui.button.font = config.getFont("font_uri","font_size");
00125         
00126 #ifdef SAL_DEBUG_ON
00127         SAL_computer_info();
00128 #endif
00129         
00130         int out =0;
00131         //Load the renderer
00132 #ifndef SAL_RENDER_OFF
00133         out |= SAL_start_renderer();
00134 #endif
00135     
00136     //Load the event listener
00137 #ifndef SAL_LISTENER_OFF
00138         out |= SAL_start_event_listener(SAL_struct.setting.gui.mouse_delay, SAL_struct.setting.gui.keyboard_delay);
00139 #endif
00140         
00141 #ifndef SAL_NETWORK_LISTNER_OFF
00142         //Load network listener
00143         SAL_start_network();
00144 #endif
00145     
00146     return out;
00147 }
00148 
00162 //In: width of window, height of window, color depth, refresh rate, render mode (software/hardware/opengl), full screen on/off
00163 //Out: Error code
00164 //Action: Load video mode and enable corresponding module
00165 int SAL_set_video_mode(int width, int height,int depth,int refresh_rate, bool full_screen)
00166 {
00167         //Set some variables
00168         if(refresh_rate != 0)
00169                 SAL_struct.setting.render.refresh_rate = 1000 / refresh_rate;
00170         else
00171                 SAL_struct.setting.render.refresh_rate = 0;
00172         SAL_struct.internal.checks.alive = true;
00173         
00174         //Load render library
00175         void * lib;
00176         string url = SAL_struct.setting.render.mode + ".so.1";
00177         if( -1 == SAL_load_library(url.c_str(), lib))
00178                 exit(-1);
00179                 
00181         // Enable all render functions
00183                 
00184         //Run init function for library setup
00185         int (*init)(int & , int & , int & , bool &, TTF_Font *& font, SDL_Surface *&, void *);
00186         init = (int (*)(int & , int & , int & , bool &, TTF_Font *& font, SDL_Surface *&, void *)) SDL_LoadFunction(lib, "init");
00187         init(width, height, depth, full_screen, SAL_struct.setting.gui.button.font, SAL_struct.internal.render.display, lib);
00188                 
00189         //salNewSurface
00190         salNewSurface = (int (*)(int, int, SDL_Surface *&)) SDL_LoadFunction(lib, "NewSurface");
00191         //salRect
00192         salDrawRect = (int (*)(int, int, int, int, Uint32)) SDL_LoadFunction(lib, "DrawRect");
00193         SALDrawRect = (int (*)(int, int, int, int, Uint32, SDL_Surface *)) SDL_LoadFunction(lib, "sDrawRect");
00194         salFillRect = (int (*)(int, int, int, int, Uint32)) SDL_LoadFunction(lib, "FillRect");
00195         SALFillRect = (int (*)(int, int, int, int, Uint32, SDL_Surface *)) SDL_LoadFunction(lib, "sFillRect");
00196         //salLine
00197         salDrawLine = (int (*)(int, int, int, int, Uint32)) SDL_LoadFunction(lib, "DrawLine");
00198         SALDrawLine = (int (*)(int, int, int, int, Uint32, SDL_Surface *)) SDL_LoadFunction(lib, "sDrawLine");
00199         //salText
00200         salDrawText = (int (*)(int, int, int, int, const char*, Uint32)) SDL_LoadFunction(lib, "DrawText");
00201         SALDrawText = (int (*)(int, int, int, int, const char*, Uint32, TTF_Font *, SDL_Surface *)) SDL_LoadFunction(lib, "sDrawText");
00202         //salDrawImage
00203         salDrawImage = (int (*)(int, int, int, int, SDL_Surface *)) SDL_LoadFunction(lib, "DrawImage");
00204         SALDrawImage = (int (*)(int, int, int, int, SDL_Surface *, SDL_Surface *)) SDL_LoadFunction(lib, "sDrawImage");
00205         salDrawCImage = (int (*)(int, int, int, int, int, int, int, int, SDL_Surface *)) SDL_LoadFunction(lib, "DrawCImage");
00206         SALDrawCImage = (int (*)(int, int, int, int, int, int, int, int, SDL_Surface *, SDL_Surface *)) SDL_LoadFunction(lib, "sDrawCImage");
00207         
00208         salLoadFont = (TTF_Font* (*)(const char* url, int size)) SDL_LoadFunction(lib, "sLoadFont");
00209         salClear = (void (*)(void)) SDL_LoadFunction(lib, "Clear");
00210 
00211         if(SAL_struct.internal.render.display == NULL)
00212         {
00213                 salError("Fatal: Couldn't use this display mode");
00214                 return -1;
00215         }
00216         
00217         SAL_struct.internal.checks.start=1;
00218         return 0;
00219 }
00220 
00221 //TODO: to draw file
00222 //In: Url to picture
00223 //Out: Image inf sdl_surface format
00224 //Action: Load url and convert image to sdl_surface format
00225 SDL_Surface* salLoadImage(const char* url)
00226 {
00227     SDL_Surface *image;
00228     image=IMG_Load(url);
00229     if(!image) 
00230     {
00231         //If not done this way then a crash will happen
00232         printf("SAL error: Couldn't load image: %s.\n SDL error: %s\n",url,IMG_GetError());
00233         return image;
00234     }
00235     return image;
00236 }
00237 
00238 //Misc
00239 
00240 #ifdef SAL_DEBUG_ON
00241 
00247 //In:   Nothing
00248 //Out:  Nothing
00249 //Action: Print computer information like rendere etc to console
00250 int SAL_computer_info()
00251 {
00252     //Echo the name of the current driver ("x11" in most cases)
00253         char videoDriverName[20];
00254         SDL_VideoDriverName(videoDriverName, 10);
00255         salPrint("Video driver: %s", videoDriverName);
00256     
00257     //Echo all known info about the video cards hardware acceleration
00258         const SDL_VideoInfo *videoCard;
00259         videoCard = SDL_GetVideoInfo();
00260         int hardwareAcceleration = videoCard->hw_available + videoCard->blit_hw + videoCard->blit_hw_CC + 
00261                         videoCard->blit_hw_A + videoCard->blit_sw + videoCard->blit_sw_CC + videoCard->blit_sw_A + videoCard->blit_fill + videoCard->video_mem;
00262         if(hardwareAcceleration >= 10)
00263                  salPrint("  Hardware acceleration FULLY SUPPORTED"); 
00264         else if(hardwareAcceleration == 0)
00265                 salPrint("  Hardware acceleration NOT SUPPORTED");
00266         else 
00267                 salPrint("  Hardware acceleration PARTIALLY SUPPORTED");
00268         //Echo if there is an window manager we can use
00269         if(videoCard->wm_available)
00270                 salPrint("  Window manager detected");
00271         
00272         return 0;
00273 }
00274 #endif
00275 
00282 //In: Nothing
00283 //Out: Nothing
00284 //Action: Wait for threads to die and then quit
00285 void salStop(void)
00286 {
00287     //Application stop!
00288     SAL_struct.internal.checks.alive = false;
00289         
00290 }
00291 
00292 //TODO: To draw file
00293 //In: 32 bits color code
00294 //Out: Color in sdl_color format
00295 //Action: Put right part of integer to right part of sdl_color structur
00296 SDL_Color salTranslateColor(Uint32 int_color)                                   //Change from an int color to an SDL_Color
00297 {
00298         #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00299         SDL_Color color = {(int_color & 0x00ff0000)/0x10000,(int_color & 0x0000ff00)/0x100,(int_color & 0x000000ff),0};
00300     #else
00301         SDL_Color color = {(int_color & 0x000000ff),(int_color & 0x0000ff00)/0x100,(int_color & 0x00ff0000)/0x10000,0};
00302     #endif
00303     return color;
00304 }
00305 
00314 //Load an library
00315 //In: Library name/ void pointer to library
00316 //Out: Error code
00317 //Action: Get pointer to function from lib
00318 int SAL_load_library(const char* name, void*& lib)
00319 {
00320         //Load file
00321         string url = (string)SAL_struct.setting.common.library_dir + (string)name;
00322         
00323         lib = SDL_LoadObject(url.c_str());
00324         if(lib)
00325         {
00326 #ifdef SAL_DEBUG_ON
00327                 salPrint("Library: \"%s\" loading SUCCES", name);
00328 #endif
00329                 return 0;
00330         }
00331 #ifdef SAL_DEBUG_ON
00332         salError("Library: \"%s\" loading FAILED", name);
00333 #endif
00334         return(-1);
00335 }
00336 
00345 //Quit SAL
00346 //In:   nothing
00347 //Out:  error code
00348 //Action:       wait for SAL to finish and the exit
00349 void SAL_quit()
00350 {
00351         SDL_WaitThread(SAL_struct.internal.event.thread, NULL);
00352         SDL_WaitThread(SAL_struct.internal.render.thread, NULL);
00353         SAL_stop_network();
00354         SDL_Quit();
00355         exit(0);
00356 }