/* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon Copyright 2008 Franck Charlet Copyright 2007 Adrien Destugues Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Grafx2 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; version 2 of the License. Grafx2 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 Grafx2; if not, see */ #define GLOBAL_VARIABLES #include #include #include #include #include #include #include #include // There is no WM on the GP2X... #ifndef __GP2X__ #include #endif #include "const.h" #include "struct.h" #include "global.h" #include "graph.h" #include "misc.h" #include "init.h" #include "buttons.h" #include "engine.h" #include "pages.h" #include "loadsave.h" #include "sdlscreen.h" #include "errors.h" #include "readini.h" #include "saveini.h" #include "io.h" #include "text.h" #include "setup.h" #include "windows.h" #include "brush.h" #include "palette.h" #include "realpath.h" #if defined(__WIN32__) #include #include #define chdir(dir) SetCurrentDirectory(dir) #elif defined(__macosx__) #import #import #elif defined(__FreeBSD__) #import #endif #if defined (__WIN32__) // On Windows, SDL_putenv is not present in any compilable header. // It can be linked anyway, this declaration only avoids // a compilation warning. extern DECLSPEC int SDLCALL SDL_putenv(const char *variable); #endif // filename for the current GUI skin file. static char Gui_skin_file[MAX_PATH_CHARACTERS]= "skins" PATH_SEPARATOR ; //--- Affichage de la syntaxe, et de la liste des modes vidéos disponibles --- void Display_syntax(void) { int mode_index; printf("Syntax: grafx2 [] []\n\n"); printf(" can be:]\n"); printf("\t/? /h /help for this help screen\n"); printf("\t/wide to emulate a video mode with wide pixels (2x1)\n"); printf("\t/tall to emulate a video mode with tall pixels (1x2)\n"); printf("\t/double to emulate a video mode with double pixels (2x2)\n"); printf("\t/wide2 to emulate a video mode with double wide pixels (4x2)\n"); printf("\t/tall2 to emulate a video mode with double tall pixels (2x4)\n"); printf("\t/triple to emulate a video mode with triple pixels (3x3)\n"); printf("\t/quadruple to emulate a video mode with quadruple pixels (4x4)\n"); printf("\t/skin use an alternate file with the menu graphics\n"); printf("\t/mode to set a video mode\n\n"); printf("Available video modes:\n\n"); for (mode_index=0; mode_index 256) { Error(ERROR_COMMAND_LINE); Display_syntax(); exit(0); } Set_palette_RGB_scale(scale); } else { Error(ERROR_COMMAND_LINE); Display_syntax(); exit(0); } } else if ( !strcmp(argv[index],"/skin") ) { // GUI skin file index++; if (indexpixels))[(y*32+x)] != 255) icon_mask[(y*32+x)/8] |=0x80>>(x&7); SDL_WM_SetIcon(icon,icon_mask); free(icon_mask); SDL_FreeSurface(icon); } } // Texte Init_text(); // On initialise tous les modes vidéo Set_all_video_modes(); Pixel_ratio=PIXEL_SIMPLE; // On initialise les données sur l'état du programme: // Donnée sur la sortie du programme: Quit_is_required=0; Quitting=0; // Données sur l'état du menu: Pixel_in_menu=Pixel_in_toolbar; Menu_is_visible=1; // Données sur les couleurs et la palette: First_color_in_palette=0; // Données sur le curseur: Cursor_shape=CURSOR_SHAPE_TARGET; Cursor_hidden=0; // Données sur le pinceau: Paintbrush_X=0; Paintbrush_Y=0; Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND; Paintbrush_hidden=0; Pixel_load_function=Pixel_load_in_current_screen; // On initialise tout ce qui concerne les opérations et les effets Operation_stack_size=0; Selected_freehand_mode=OPERATION_CONTINUOUS_DRAW; Selected_line_mode =OPERATION_LINE; Selected_curve_mode =OPERATION_3_POINTS_CURVE; Effect_function=No_effect; // On initialise les infos de la loupe: Main_magnifier_mode=0; Main_magnifier_factor=DEFAULT_ZOOM_FACTOR; Main_separator_proportion=INITIAL_SEPARATOR_PROPORTION; Spare_separator_proportion=INITIAL_SEPARATOR_PROPORTION; // On initialise les infos du mode smear: Smear_mode=0; Smear_brush_width=PAINTBRUSH_WIDTH; Smear_brush_height=PAINTBRUSH_HEIGHT; // On initialise les infos du mode smooth: Smooth_mode=0; // On initialise les infos du mode shade: Shade_mode=0; // Les autres infos du Shade sont chargées avec la config Quick_shade_mode=0; // idem // On initialise les infos sur les dégradés: Gradient_pixel =Display_pixel; // Les autres infos sont chargées avec la config // On initialise les infos de la grille: Snap_mode=0; Snap_width=8; Snap_height=8; Snap_offset_X=0; Snap_offset_Y=0; // On initialise les infos du mode Colorize: Colorize_mode=0; // Mode colorize inactif par défaut Colorize_opacity=50; // Une interpolation de 50% par défaut Colorize_current_mode=0; // Par défaut, la méthode par interpolation Compute_colorize_table(); // On initialise les infos du mode Tiling: Tiling_mode=0; // Pas besoin d'initialiser les décalages car ça se fait // en prenant une brosse (toujours mis à 0). // On initialise les infos du mode Mask: Mask_mode=0; // Infos du Spray Airbrush_mode=1; // Mode Mono Airbrush_size=31; Airbrush_delay=1; Airbrush_mono_flow=10; memset(Airbrush_multi_flow,0,256); srand(time(NULL)); // On randomize un peu tout ça... // Initialisation des boutons Init_buttons(); // Initialisation des opérations Init_operations(); Windows_open=0; // Charger la configuration des touches Set_config_defaults(); switch(Load_CFG(1)) { case ERROR_CFG_MISSING: // Pas un problème, on a les valeurs par défaut. break; case ERROR_CFG_CORRUPTED: DEBUG("Corrupted CFG file.",0); break; case ERROR_CFG_OLD: DEBUG("Unknown CFG file version, not loaded.",0); break; } // Charger la configuration du .INI temp=Load_INI(&Config); if (temp) Error(temp); Analyze_command_line(argc,argv); // Load sprites, palette etc. strcpy(Gui_skin_file+6,Config.SkinFile); Gfx = Load_graphics(Gui_skin_file); if (Gfx == NULL) { printf("%s", Gui_loading_error_message); Error(ERROR_GUI_MISSING); } // Infos sur les trames (Sieve) Sieve_mode=0; Copy_preset_sieve(0); // Transfert des valeurs du .INI qui ne changent pas dans des variables // plus accessibles: Gfx->Default_palette[MC_Black]=Fav_menu_colors[0]=Config.Fav_menu_colors[0]; Gfx->Default_palette[MC_Dark] =Fav_menu_colors[1]=Config.Fav_menu_colors[1]; Gfx->Default_palette[MC_Light]=Fav_menu_colors[2]=Config.Fav_menu_colors[2]; Gfx->Default_palette[MC_White]=Fav_menu_colors[3]=Config.Fav_menu_colors[3]; Compute_optimal_menu_colors(Gfx->Default_palette); Fore_color=MC_White; Back_color=MC_Black; // Font { byte *font; font = Load_font("Classic"); if (font) Menu_font=font; } memcpy(Main_palette, Gfx->Default_palette, sizeof(T_Palette)); // Allocation de mémoire pour la brosse if (!(Brush =(byte *)malloc( 1* 1))) Error(ERROR_MEMORY); if (!(Smear_brush =(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE))) Error(ERROR_MEMORY); // Pinceau if (!(Paintbrush_sprite=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE))) Error(ERROR_MEMORY); *Paintbrush_sprite=1; Paintbrush_width=1; Paintbrush_height=1; starting_videomode=Current_resolution; Horizontal_line_buffer=NULL; Screen_width=Screen_height=Current_resolution=0; Init_mode_video( Video_mode[starting_videomode].Width, Video_mode[starting_videomode].Height, Video_mode[starting_videomode].Fullscreen, Pixel_ratio); // Windows only: move back the window to its original position. #if defined(__WIN32__) if (!Video_mode[starting_videomode].Fullscreen) { if (Config.Window_pos_x != 9999 && Config.Window_pos_y != 9999) { //RECT r; static SDL_SysWMinfo pInfo; SDL_VERSION(&pInfo.version); SDL_GetWMInfo(&pInfo); //GetWindowRect(pInfo.window, &r); SetWindowPos(pInfo.window, 0, Config.Window_pos_x, Config.Window_pos_y, 0, 0, SWP_NOSIZE); } } #endif Main_image_width=Screen_width/Pixel_width; Main_image_height=Screen_height/Pixel_height; Spare_image_width=Screen_width/Pixel_width; Spare_image_height=Screen_height/Pixel_height; // Allocation de mémoire pour les différents écrans virtuels (et brosse) if (Init_all_backup_lists(Config.Max_undo_pages+1,Screen_width,Screen_height)==0) Error(ERROR_MEMORY); // On remet le nom par défaut pour la page de brouillon car il été modifié // par le passage d'un fichier en paramètre lors du traitement précédent. // Note: le fait que l'on ne modifie que les variables globales // Brouillon_* et pas les infos contenues dans la page de brouillon // elle-même ne m'inspire pas confiance mais ça a l'air de marcher sans // poser de problèmes, alors... if (File_in_command_line) { strcpy(Spare_file_directory,Spare_current_directory); strcpy(Spare_filename,"NO_NAME.GIF"); Spare_fileformat=DEFAULT_FILEFORMAT; } // Nettoyage de l'écran virtuel (les autres recevront celui-ci par copie) memset(Main_screen,0,Main_image_width*Main_image_height); // Initialisation de diverses variables par calcul: Compute_magnifier_data(); Compute_limits(); Compute_paintbrush_coordinates(); // On affiche le menu: Display_menu(); Display_paintbrush_in_menu(); Display_sprite_in_menu(BUTTON_PAL_LEFT,18+(Config.Palette_vertical!=0)); // On affiche le curseur pour débutter correctement l'état du programme: Display_cursor(); Spare_image_is_modified=0; Main_image_is_modified=0; // Gestionnaire de signaux, quand il ne reste plus aucun espoir Init_sighandler(); // Le programme débute en mode de dessin à la main Select_button(BUTTON_DRAW,LEFT_SIDE); // On initialise la brosse initiale à 1 pixel blanc: Brush_width=1; Brush_height=1; Capture_brush(0,0,0,0,0); *Brush=MC_White; return(1); } // ------------------------- Fermeture du programme -------------------------- void Program_shutdown(void) { int return_code; // Windows only: Recover the window position. #if defined(__WIN32__) { RECT r; static SDL_SysWMinfo pInfo; SDL_GetWMInfo(&pInfo); GetWindowRect(pInfo.window, &r); Config.Window_pos_x = r.left; Config.Window_pos_y = r.top; } #else // All other targets: irrelevant dimensions. // Do not attempt to force them back on next program run. Config.Window_pos_x = 9999; Config.Window_pos_y = 9999; #endif // On libère le buffer de gestion de lignes free(Horizontal_line_buffer); // On libère le pinceau spécial free(Paintbrush_sprite); // On libère les différents écrans virtuels et brosse: free(Brush); Set_number_of_backups(0); free(Spare_screen); free(Main_screen); // Free the skin (Gui graphics) data if (Gfx) { free(Gfx); Gfx=NULL; } // On prend bien soin de passer dans le répertoire initial: if (chdir(Initial_directory)!=-1) { // On sauvegarde les données dans le .CFG et dans le .INI if (Config.Auto_save) { return_code=Save_CFG(); if (return_code) Error(return_code); return_code=Save_INI(&Config); if (return_code) Error(return_code); } } else Error(ERROR_MISSING_DIRECTORY); SDL_Quit(); } // -------------------------- Procédure principale --------------------------- int main(int argc,char * argv[]) { int phoenix_found=0; int phoenix2_found=0; char phoenix_filename1[MAX_PATH_CHARACTERS]; char phoenix_filename2[MAX_PATH_CHARACTERS]; if(!Init_program(argc,argv)) { return 0; } // Test de recuperation de fichiers sauvés strcpy(phoenix_filename1,Config_directory); strcat(phoenix_filename1,"phoenix.img"); strcpy(phoenix_filename2,Config_directory); strcat(phoenix_filename2,"phoenix2.img"); if (File_exists(phoenix_filename1)) phoenix_found=1; if (File_exists(phoenix_filename2)) phoenix2_found=1; if (phoenix_found || phoenix2_found) { if (phoenix2_found) { strcpy(Main_file_directory,Config_directory); strcpy(Main_filename,"phoenix2.img"); chdir(Main_file_directory); Button_Reload(); Main_image_is_modified=1; Warning_message("Spare page recovered"); // I don't really like this, but... remove(phoenix_filename2); Button_Page(); } if (phoenix_found) { strcpy(Main_file_directory,Config_directory); strcpy(Main_filename,"phoenix.img"); chdir(Main_file_directory); Button_Reload(); Main_image_is_modified=1; Warning_message("Main page recovered"); // I don't really like this, but... remove(phoenix_filename1); } } else { if (Config.Opening_message && (!File_in_command_line)) Button_Message_initial(); if (File_in_command_line) { Button_Reload(); Resolution_in_command_line=0; } } Main_handler(); Program_shutdown(); return 0; }