summaryrefslogblamecommitdiff
path: root/src/main.cpp
blob: d2af2a2877d67cfb2de3905d84c21b52100e0a10 (plain) (tree)
1
  


















                                                                             
        
   

                 


                            
                          

                              
                                      

                   





                     
 
                                                              



























                             
               

  
                


                                         
                                         
 
                               
                       
 

                            





                         
                                       
                                        
          

                           
             
            
                      

                                
 






















                                                          
                     
                 

 


                              
                    















                                                          

             









                                                          
 
                         


                   
                                      

                                            
                        

                    














                                   
 



                                                                          
 











                                                                            
 

                                                                       



                                              
                          


                                                                     
                              
                                                                   

              
                            
                               



                                                          




                                                     
 







                                                                            
 


                                                  
 
                              
         
     
 
                     













                                                         

                                       








                                                                             
                             
     
 

                                                           


                                            
                          


                                         
                                


                                         
                                                      
                                     
                  


                                                    

                                                             
                                                            


                                                                 
                                                           










                                                                            
 
 
                                                           
                                            
                  
 
             
                                                                   
         
                                                



                                                 


                             

                                               
                                                                      

                                 




                                                                
     
                      






                       
                                      






                           
 
                           













                                      
             
                                
                      
                               

                                
                           







                                                                       
                                                    


                                                           



                             
         
     


                   

              
/*
 *  The Mana World
 *  Copyright 2004 The Mana World Development Team
 *
 *  This file is part of The Mana World.
 *
 *  The Mana World is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  The Mana World is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with The Mana World; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id$
 */

#include "main.h"
#include "gui/char_server.h"
#include "gui/char_select.h"
#include "gui/inventory.h"
#include "gui/ok_dialog.h"
#include "./sound/sound.h"
#include "./graphic/graphic.h"
#include "resources/resourcemanager.h"
#include <iostream>

#ifdef __USE_UNIX98
#include <sys/stat.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>
#endif

// Language map can probably be removed after switching to SDL
typedef struct {
    unsigned int code;
    char* name;
} LanguageMap;

LanguageMap languageMap[] = {
    { 0x0813, "BE" },
    { 0x0416, "BR" },
    { 0x1009, "CF" },
    { 0x1009, "CF" },
    { 0x0807, "CH" },
    { 0x0405, "CZ" },
    { 0x0407, "DE" },
    { 0x0406, "DK" },
    { 0x040a, "ES" },
    { 0x040b, "FI" },
    { 0x040c, "FR" },
    { 0x0410, "IT" },
    { 0x0414, "NO" },
    { 0x0415, "PL" },
    { 0x0416, "PT" },
    { 0x0816, "PT" },
    { 0x0419, "RU" },
    { 0x041d, "SE" },
    { 0x041b, "SK" },
    { 0x0424, "SK" },
    { 0x0809, "UK" },
    { 0x0409, "US" },
    { 0, NULL }
};

// Account infos
int account_ID, session_ID1, session_ID2;
char sex, n_server, n_character;
SERVER_INFO *server_info;
PLAYER_INFO *char_info = new PLAYER_INFO;

Spriteset *hairset, *playerset;
Image *login_wallpaper;

char username[LEN_USERNAME];
char password[LEN_PASSWORD];
int map_address, char_ID;
short map_port;
char map_name[16];
unsigned char state;
unsigned short x, y;
unsigned char direction;
//unsigned short job, hair, hair_color;
unsigned char stretch_mode, screen_mode;
char *dir;

// new sound-engine /- kth5
#ifndef WIN32
Sound sound;
#endif /* not WIN32 */
// ini file configuration reader
Configuration config;


/**
 * Listener used for responding to map start error dialog.
 */
class MapStartErrorListener : public gcn::ActionListener {
    void action(const std::string &eventId) {
        if (eventId == "ok") {
            state = LOGIN;
        }
    }
} mapStartErrorListener;

/**
 * Listener used for responding to init warning.
 */
class InitWarningListener : public gcn::ActionListener {
    void action(const std::string &eventId) {
        if (eventId == "ok") {
            state = LOGIN;
        }
    }
} initWarningListener;

void request_exit() {
    state = EXIT;
}

/**
 * Do all initialization stuff
 */
void init_engine() {
#ifdef WIN32
    // After switching to SDL this can probably be removed
    char keyb_buffer[KL_NAMELENGTH + 1];
    unsigned int langID;
    char* code = NULL;
    int running = 1;
    int a;
    if (GetKeyboardLayoutName(keyb_buffer)) {
        //printf("layout name: %s\n", buffer);
        langID = strtol(keyb_buffer, NULL, 16);
        langID &= 0xffff;
        //printf("language id: %x\n", langID);
        for (a = 0; languageMap[a].code != 0; ++a) {
            if (languageMap[a].code == langID) {
                code = languageMap[a].name;
                break;
            }
        }
    }
#endif

    // Initialize SDL
    //if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
    //    std::cerr << "Could not initialize SDL: " <<
    //        SDL_GetError() << std::endl;
    //    exit(1);
    //}
    //atexit(SDL_Quit);

    // Initialize Allegro
    allegro_init();

    init_log();
    // SDL will send an event for this
    set_close_button_callback(request_exit);

    dir = new char[400];
    strcpy(dir, "");

#ifndef __USE_UNIX98
    // WIN32 and others
    strcpy(dir, "tmw.ini");
#else
    // UNIX
    char *userHome;
    char *name = getlogin();
    passwd *pass;

    if (name != NULL) {
        pass = getpwnam(name);
    }
    else {
        pass = getpwuid(geteuid());
    }

    if (pass == NULL) {
        printf("Couldn't determine the user home directory. Exitting.\n");
        exit(1);
    }

    userHome = pass->pw_dir;

    // Checking if homeuser/.manaworld folder exists.
    sprintf(dir, "%s/.manaworld", userHome);
    if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) &&
            (errno != EEXIST))
    {
        printf("%s can't be made... And doesn't exist ! Exitting ...", dir);
        exit(1);
    }
    sprintf(dir, "%s/.manaworld/tmw.ini", userHome);
#endif

    // Checking if the tmw.ini file exists... otherwise creates it with
    // default options !
    FILE *tmwFile = 0;
    tmwFile = fopen(dir, "r");

    // If we can't read it, it doesn't exist !
    if (tmwFile == NULL) {
        // We reopen the file in write mode and we create it
        printf("No file : %s\n, Creating Default Options...\n", dir);
        tmwFile = fopen(dir, "wt");
        if (tmwFile == NULL) {
            printf("Can't create %s file. Using Defaults.\n", dir);
        }
        else {
            fclose(tmwFile);
            // tmw.ini creation
            config.setValue("system", "");
            config.setValue("keyboard", "en");
            config.setValue("language", "");
            config.setValue("core_version", CORE_VERSION);
            config.setValue("host", "animesites.de");
            config.setValue("port", 6901);
            config.setValue("screen", 1);
            config.setValue("sound", 1);


#ifdef __USE_UNIX98
            char *chatlogFilename = new char[400];
            sprintf(chatlogFilename, "%s/.manaworld/chatlog.txt", userHome);
            config.setValue("chatlog", chatlogFilename);
            delete chatlogFilename;
#else
            config.setValue("chatlog", "chatlog.txt");
#endif

            config.setValue("stretch", 1);
            config.setValue("remember", 1);
            config.setValue("username", "Player");

            config.write(dir);
        }
    }

    config.init(dir);
#ifdef WIN32
    // With SDL this part should probably just be removed
    if (code) {
        set_config_string("system", "keyboard", code);
    }
#endif

#ifdef MACOSX
    set_color_depth(32);
#else
    set_color_depth(16);
#endif

    //SDL_WM_SetCaption("The Mana World", NULL);
    set_window_title("The Mana World");

    //screen = SDL_SetVideoMode(800, 600, 16, SDL_SWSURFACE | SDL_ANYFORMAT);
    //if (screen == NULL) {
    //    std::cerr << "Couldn't set 800x600x16 video mode: " <<
    //        SDL_GetError() << std::endl;
    //    exit(1);
    //}

    if (set_gfx_mode((unsigned char)config.getValue("screen", 0), 800, 600,
                0, 0)) {
        error(allegro_error);
    }

    // In SDL these three are all done in the SDL_Init call
    if (install_keyboard()) {
        error("Unable to install keyboard");
    }

    if (install_timer()) {
        error("Unable to install timer");
    }

    if (install_mouse() == -1) {
        error("Unable to install mouse");
    }

    // Buffer creation shouldn't be necessary with SDL
    buffer = create_bitmap(800, 600);
    if (!buffer) {
        error("Not enough memory to create buffer");
    }

    ResourceManager *resman = ResourceManager::getInstance();

    login_wallpaper = resman->getImage("graphic/login.bmp");
    Image *playerImg = resman->getImage("graphic/playerset.bmp");
    Image *hairImg = resman->getImage("graphic/hairset.bmp");

    if (!login_wallpaper) error("Couldn't load login.bmp");
    if (!playerImg) error("Couldn't load playerset.bmp");
    if (!hairImg) error("Couldn't load hairset.bmp");

    // Stretch some bitmaps while they haven't been replaced with higher res
    Image *scaledPlayerImg = playerImg->getScaledInstance(
            playerImg->getWidth() * 2, playerImg->getHeight() * 2);
    Image *scaledHairImg = hairImg->getScaledInstance(
            hairImg->getWidth() * 2, hairImg->getHeight() * 2);

    playerset = new Spriteset(scaledPlayerImg, 160, 120);
    hairset = new Spriteset(scaledHairImg, 40, 40);


    // TODO: Remove Allegro config file usage from GUI look
    init_gui(buffer, "data/Skin/aqua.skin");
    state = LOGIN;

#ifndef WIN32
    // initialize sound-engine and start playing intro-theme /-kth5
    try {
         if (config.getValue("sound", 0) == 1) {
             //SDL_InitSubSystem(SDL_INIT_AUDIO);
             SDL_Init(SDL_INIT_AUDIO);
             atexit(SDL_Quit);
             sound.init(32, 20);
         }
         sound.setVolume(64);
        
         // left here to serve as an example ;)
         /*
         SOUND_SID id = sound.loadItem("./data/sound/wavs/level.ogg");
         sound.startItem(id, 70);
         */
    }
    catch (const char *err) {
        state = ERROR;
        new OkDialog("Sound Engine", err, &initWarningListener);
        warning(err);
    }
#endif /* not WIN32 */
}

/** Clear the engine */
void exit_engine() {
    config.write(dir);
    delete dir;
    gui_exit();
    ResourceManager::deleteInstance();
    destroy_bitmap(buffer);
    allegro_exit();
}

/** Main */
int main() {
    init_engine();

    while (state != EXIT) {
        switch (state) {
            case LOGIN:
                status("LOGIN");
                login();
                break;
            case CHAR_SERVER:
                status("CHAR_SERVER");
                char_server();
                break;
            case CHAR_SELECT:
                status("CHAR_SELECT");
                charSelect();
                break;
            case GAME:
#ifndef WIN32
                sound.stopBgm();
#endif /* not WIN32 */
                status("GAME");
                try {
                    map_start();
                    game();
                }
                catch (const char* err) {
                    state = ERROR;
                    new OkDialog("Error", err, &mapStartErrorListener);
                }
                break;
            case ERROR:
                // Redraw GUI
                login_wallpaper->draw(buffer, 0, 0);
                guiGraphics->setTarget(buffer);
                gui->update();
                blit(buffer, screen, 0, 0, 0, 0, 800, 600);
                break;
            default:
                state = EXIT;
                break;
        }
    }
    status("EXIT");
    exit_engine();
    return 0;
}
END_OF_MAIN();