grafX2/main.c
Adrien Destugues fb3404e2ba Partial patch to allow loading spare page from command line.
It's not working yet but does not introduce regressions instead.
Cleaned up version of patch proposed on the issue tracker.


git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1122 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2009-10-31 16:42:08 +00:00

838 lines
26 KiB
C
Raw Blame History

/* 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 <http://www.gnu.org/licenses/>
*/
#define GLOBAL_VARIABLES
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <SDL.h>
#include <SDL_image.h>
// There is no WM on the GP2X...
#ifndef __GP2X__
#include <SDL_syswm.h>
#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 <windows.h>
#include <shlwapi.h>
#define chdir(dir) SetCurrentDirectory(dir)
#elif defined(__macosx__)
#import <corefoundation/corefoundation.h>
#import <sys/param.h>
#elif defined(__FreeBSD__)
#import <sys/param.h>
#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];
//--- Affichage de la syntaxe, et de la liste des modes vid<69>os disponibles ---
void Display_syntax(void)
{
int mode_index;
printf("Syntax: grafx2 [<arguments>] [<picture>]\n\n");
printf("<arguments> 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/rgb n to reduce RGB precision from 256 to n levels\n");
printf("\t/skin <filename> to use an alternate file with the menu graphics\n");
printf("\t/mode <videomode> to set a video mode\n\n");
printf("Available video modes:\n\n");
for (mode_index = 0; mode_index < Nb_video_modes; mode_index += 12)
{
int k;
for (k = 0; k < 6; k++)
{
if (mode_index + k >= Nb_video_modes) break;
printf("%12s",Mode_label(mode_index + k));
}
puts("");
}
}
// ---------------------------- Sortie impromptue ----------------------------
void Error_function(int error_code, const char *filename, int line_number, const char *function_name)
{
T_Palette temp_palette;
int index;
printf("Error number %d occured in file %s, line %d, function %s.\n", error_code, filename,line_number,function_name);
if (error_code==0)
{
// L'erreur 0 n'est pas une vraie erreur, elle fait seulement un flash rouge de l'<27>cran pour dire qu'il y a un probl<62>me.
// Toutes les autres erreurs d<>clenchent toujours une sortie en catastrophe du programme !
memcpy(temp_palette,Main_palette,sizeof(T_Palette));
for (index=0;index<=255;index++)
temp_palette[index].R=255;
Set_palette(temp_palette);
SDL_Delay(500);
Set_palette(Main_palette);
}
else
{
switch (error_code)
{
case ERROR_GUI_MISSING : printf("Error: File containing the GUI graphics is missing!\n");
printf("This program cannot run without this file.\n");
break;
case ERROR_GUI_CORRUPTED : printf("Error: File containing the GUI graphics couldn't be parsed!\n");
printf("This program cannot run without a correct version of this file.\n");
break;
case ERROR_INI_MISSING : printf("Error: File gfx2def.ini is missing!\n");
printf("This program cannot run without this file.\n");
break;
case ERROR_MEMORY : printf("Error: Not enough memory!\n\n");
printf("You should try exiting other programs to free some bytes for Grafx2.\n\n");
break;
case ERROR_FORBIDDEN_MODE : printf("Error: The requested video mode has been disabled from the resolution menu!\n");
printf("If you want to run the program in this mode, you'll have to start it with an\n");
printf("enabled mode, then enter the resolution menu and enable the mode you want.\n");
printf("Check also if the 'Default_video_mode' parameter in gfx2.ini is correct.\n");
break;
case ERROR_COMMAND_LINE : printf("Error: Invalid parameter or file not found.\n\n");
Display_syntax();
break;
case ERROR_SAVING_CFG : printf("Error: Write error while saving settings!\n");
printf("Settings have not been saved correctly, and the gfx2.cfg file may have been\n");
printf("corrupt. If so, please delete it and Grafx2 will restore default settings.\n");
break;
case ERROR_MISSING_DIRECTORY : printf("Error: Directory you ran the program from not found!\n");
break;
case ERROR_INI_CORRUPTED : printf("Error: File gfx2.ini is corrupt!\n");
printf("It contains bad values at line %d.\n",Line_number_in_INI_file);
printf("You can re-generate it by deleting the file and running GrafX2 again.\n");
break;
case ERROR_SAVING_INI : printf("Error: Cannot rewrite file gfx2.ini!\n");
break;
case ERROR_SORRY_SORRY_SORRY : printf("Error: Sorry! Sorry! Sorry! Please forgive me!\n");
break;
}
SDL_Quit();
exit(error_code);
}
}
// --------------------- Analyse de la ligne de commande ---------------------
void Analyze_command_line(int argc, char * argv[])
{
char *buffer ;
int index;
File_in_command_line = 0;
Resolution_in_command_line = 0;
Current_resolution = Config.Default_resolution;
for (index = 1; index<argc; index++)
{
if ( !strcmp(argv[index],"/?") ||
!strcmp(argv[index],"/h") ||
!strcmp(argv[index],"/H") )
{
// help
Display_syntax();
exit(0);
}
else if ( !strcmp(argv[index],"/mode") )
{
// mode
index++;
if (index<argc)
{
Resolution_in_command_line = 1;
Current_resolution = Convert_videomode_arg(argv[index]);
if (Current_resolution == -1)
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
if ((Video_mode[Current_resolution].State & 0x7F) == 3)
{
Error(ERROR_FORBIDDEN_MODE);
exit(0);
}
}
else
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
}
else if ( !strcmp(argv[index],"/tall") )
{
Pixel_ratio = PIXEL_TALL;
}
else if ( !strcmp(argv[index],"/wide") )
{
Pixel_ratio = PIXEL_WIDE;
}
else if ( !strcmp(argv[index],"/double") )
{
Pixel_ratio = PIXEL_DOUBLE;
}
else if ( !strcmp(argv[index],"/triple") )
{
Pixel_ratio = PIXEL_TRIPLE;
}
else if ( !strcmp(argv[index],"/quadruple") )
{
Pixel_ratio = PIXEL_QUAD;
}
else if ( !strcmp(argv[index],"/tall2") )
{
Pixel_ratio = PIXEL_TALL2;
}
else if ( !strcmp(argv[index],"/wide2") )
{
Pixel_ratio = PIXEL_WIDE2;
}
else if ( !strcmp(argv[index],"/rgb") )
{
// echelle des composants RGB
index++;
if (index<argc)
{
int scale;
scale = atoi(argv[index]);
if (scale < 2 || scale > 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 (index<argc)
{
strcpy(Gui_skin_file, argv[index]);
}
else
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
}
else
{
// Si ce n'est pas un param<61>tre, c'est le nom du fichier <20> ouvrir
if (File_in_command_line > 1)
{
// Il y a d<>j<EFBFBD> 2 noms de fichiers et on vient d'en trouver un 3<>me
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
else if (File_exists(argv[index]))
{
File_in_command_line ++;
buffer = Realpath(argv[index], NULL);
if (File_in_command_line == 1)
{
// Separate path from filename
Extract_path(Main_file_directory, buffer);
Extract_filename(Main_filename, buffer);
DEBUG(Main_filename, 0);
free(buffer);
} else {
Extract_path(Spare_file_directory, buffer);
Extract_filename(Spare_filename, buffer);
DEBUG(Spare_filename, 1);
free(buffer);
}
}
else
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
}
}
}
// ------------------------ Initialiser le programme -------------------------
// Returns 0 on fail
int Init_program(int argc,char * argv[])
{
int temp;
int starting_videomode;
char program_directory[MAX_PATH_CHARACTERS];
// On cr<63>e d<>s maintenant les descripteurs des listes de pages pour la page
// principale et la page de brouillon afin que leurs champs ne soient pas
// invalide lors des appels aux multiples fonctions manipul<75>es <20>
// l'initialisation du programme.
Main_backups=(T_List_of_pages *)malloc(sizeof(T_List_of_pages));
Spare_backups=(T_List_of_pages *)malloc(sizeof(T_List_of_pages));
Init_list_of_pages(Main_backups);
Init_list_of_pages(Spare_backups);
// Determine the executable directory
Set_program_directory(argv[0],program_directory);
// Choose directory for data (read only)
Set_data_directory(program_directory,Data_directory);
// Choose directory for settings (read/write)
Set_config_directory(program_directory,Config_directory);
// On d<>termine le r<>pertoire courant:
getcwd(Main_current_directory,256);
// On en profite pour le m<>moriser dans le r<>pertoire principal:
strcpy(Initial_directory,Main_current_directory);
// On initialise les donn<6E>es sur le nom de fichier de l'image principale:
strcpy(Main_file_directory,Main_current_directory);
strcpy(Main_filename,"NO_NAME.GIF");
Main_fileformat=DEFAULT_FILEFORMAT;
// On initialise les donn<6E>es sur le nom de fichier de l'image de brouillon:
strcpy(Spare_current_directory,Main_current_directory);
strcpy(Spare_file_directory,Main_file_directory);
strcpy(Spare_filename ,Main_filename);
Spare_fileformat =Main_fileformat;
strcpy(Brush_current_directory,Main_current_directory);
strcpy(Brush_file_directory,Main_file_directory);
strcpy(Brush_filename ,Main_filename);
Brush_fileformat =Main_fileformat;
// On initialise ce qu'il faut pour que les fileselects ne plantent pas:
Main_fileselector_position=0; // Au d<>but, le fileselect est en haut de la liste des fichiers
Main_fileselector_offset=0; // Au d<>but, le fileselect est en haut de la liste des fichiers
Main_format=FORMAT_ALL_IMAGES;
Spare_fileselector_position=0;
Spare_fileselector_offset=0;
Spare_format=FORMAT_ALL_IMAGES;
Brush_fileselector_position=0;
Brush_fileselector_offset=0;
Brush_format=FORMAT_ALL_IMAGES;
// On initialise les commentaires des images <20> des cha<68>nes vides
Main_comment[0]='\0';
Spare_comment[0]='\0';
Brush_comment[0]='\0';
// On initialise d'ot' trucs
Main_offset_X=0;
Main_offset_Y=0;
Old_main_offset_X=0;
Old_main_offset_Y=0;
Main_separator_position=0;
Main_X_zoom=0;
Main_separator_proportion=INITIAL_SEPARATOR_PROPORTION;
Main_magnifier_mode=0;
Main_magnifier_factor=DEFAULT_ZOOM_FACTOR;
Main_magnifier_height=0;
Main_magnifier_width=0;
Main_magnifier_offset_X=0;
Main_magnifier_offset_Y=0;
Spare_offset_X=0;
Spare_offset_Y=0;
Old_spare_offset_X=0;
Old_spare_offset_Y=0;
Spare_separator_position=0;
Spare_X_zoom=0;
Spare_separator_proportion=INITIAL_SEPARATOR_PROPORTION;
Spare_magnifier_mode=0;
Spare_magnifier_factor=DEFAULT_ZOOM_FACTOR;
Spare_magnifier_height=0;
Spare_magnifier_width=0;
Spare_magnifier_offset_X=0;
Spare_magnifier_offset_Y=0;
Keyboard_click_allowed = 0;
// SDL
if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0)
{
// The program can't continue without that anyway
printf("Couldn't initialize SDL.\n");
return(0);
}
Joystick = SDL_JoystickOpen(0);
SDL_EnableKeyRepeat(250, 32);
SDL_EnableUNICODE(SDL_ENABLE);
SDL_WM_SetCaption("GrafX2","GrafX2");
{
// Routine pour d<>finir l'icone.
char icon_path[MAX_PATH_CHARACTERS];
SDL_Surface * icon;
sprintf(icon_path, "%s%s", Data_directory, "gfx2.gif");
icon = IMG_Load(icon_path);
if (icon)
{
byte *icon_mask;
int x,y;
icon_mask=malloc(128);
memset(icon_mask,0,128);
for (y=0;y<32;y++)
for (x=0;x<32;x++)
if (((byte *)(icon->pixels))[(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<69>o
Set_all_video_modes();
Pixel_ratio=PIXEL_SIMPLE;
// On initialise les donn<6E>es sur l'<27>tat du programme:
// Donn<6E>e sur la sortie du programme:
Quit_is_required=0;
Quitting=0;
// Donn<6E>es sur l'<27>tat du menu:
Pixel_in_menu=Pixel_in_toolbar;
Menu_is_visible=1;
Menu_height=MENU_HEIGHT;
// Donn<6E>es sur les couleurs et la palette:
First_color_in_palette=0;
// Donn<6E>es sur le curseur:
Cursor_shape=CURSOR_SHAPE_TARGET;
Cursor_hidden=0;
// Donn<6E>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<6F>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<72>es avec la config
Quick_shade_mode=0; // idem
// On initialise les infos sur les d<>grad<61>s:
Gradient_pixel =Display_pixel; // Les autres infos sont charg<72>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 <20>a se fait
// en prenant une brosse (toujours mis <20> 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 <20>a...
// Initialisation des boutons
Init_buttons();
// Initialisation des op<6F>rations
Init_operations();
// Initialize the brush container
Init_brush_container();
Windows_open=0;
// Charger la configuration des touches
Set_config_defaults();
switch(Load_CFG(1))
{
case ERROR_CFG_MISSING:
// Pas un probl<62>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);
Current_help_section=0;
Help_position=0;
// Load sprites, palette etc.
strcpy(Gui_skin_file,Config.Skin_file);
Gfx = Load_graphics(Gui_skin_file);
if (Gfx == NULL)
{
Gfx = Load_graphics("skin_modern.png");
if (Gfx == NULL)
{
printf("%s", Gui_loading_error_message);
Error(ERROR_GUI_MISSING);
}
}
Config.Fav_menu_colors[0] = Gfx->Default_palette[Gfx->Color_black];
Config.Fav_menu_colors[1] = Gfx->Default_palette[Gfx->Color_dark];
Config.Fav_menu_colors[2] = Gfx->Default_palette[Gfx->Color_light];
Config.Fav_menu_colors[3] = Gfx->Default_palette[Gfx->Color_white];
MC_Black = Gfx->Color_black;
MC_Dark = Gfx->Color_dark;
MC_Light = Gfx->Color_light;
MC_White = Gfx->Color_white;
MC_Trans = Gfx->Color_trans;
// 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:
// Let's load the colors from the skin instead !
// 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
if (!(Menu_font=Load_font(Config.Font_file)))
if (!(Menu_font=Load_font("font_Classic.png")))
{
printf("Unable to open the default font file: %s\n", "font_Classic.png");
Error(ERROR_GUI_MISSING);
}
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<66>rents <20>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 <20>t<EFBFBD> modifi<66>
// par le passage d'un fichier en param<61>tre lors du traitement pr<70>c<EFBFBD>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 <20>a a l'air de marcher sans
// poser de probl<62>mes, alors...
if (File_in_command_line == 1)
{
strcpy(Spare_file_directory,Spare_current_directory);
strcpy(Spare_filename,"NO_NAME.GIF");
Spare_fileformat=DEFAULT_FILEFORMAT;
}
// Nettoyage de l'<27>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'<27>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 <20> la main
Select_button(BUTTON_DRAW,LEFT_SIDE);
// On initialise la brosse initiale <20> 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<69>re le buffer de gestion de lignes
if(Horizontal_line_buffer) free(Horizontal_line_buffer);
// On lib<69>re le pinceau sp<73>cial
if (Paintbrush_sprite) free(Paintbrush_sprite);
// On lib<69>re les diff<66>rents <20>crans virtuels et brosse:
if(Brush) free(Brush);
Set_number_of_backups(0);
if(Spare_screen) free(Spare_screen);
if(Main_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<6E>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<6F>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))
{
Program_shutdown();
return 0;
}
// Test de recuperation de fichiers sauv<75>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();
switch (File_in_command_line)
{
case 2:
Button_Reload();
DEBUG(Main_filename, 0);
DEBUG(Spare_filename, 0);
Button_Page();
// no break ! proceed with the other file now
case 1:
Button_Reload();
Resolution_in_command_line = 0;
default:
break;
}
}
Main_handler();
Program_shutdown();
return 0;
}