grafX2/main.c
Yves Rizoud 0a7bd889d1 Better command-line handling (issue 266) contributed by Pasi Kallinen
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1227 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2009-11-29 18:25:14 +00:00

902 lines
28 KiB
C
Raw Blame History

/* vim:expandtab:ts=2 sw=2:
*/
/* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2009 Pasi Kallinen
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
//--- 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>] [<picture1>] [<picture2>]\n\n");
printf("<arguments> can be:]\n");
printf("\t-? -h -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");
printf("Arguments can be prefixed either by / - or --\n");
printf("They can also be abbreviated.\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);
}
}
enum CMD_PARAMS
{
CMDPARAM_HELP,
CMDPARAM_MODE,
CMDPARAM_PIXELRATIO_TALL,
CMDPARAM_PIXELRATIO_WIDE,
CMDPARAM_PIXELRATIO_DOUBLE,
CMDPARAM_PIXELRATIO_TRIPLE,
CMDPARAM_PIXELRATIO_QUAD,
CMDPARAM_PIXELRATIO_TALL2,
CMDPARAM_PIXELRATIO_WIDE2,
CMDPARAM_RGB,
CMDPARAM_SKIN
};
struct {
const char *param;
int id;
} cmdparams[] = {
{"?", CMDPARAM_HELP},
{"h", CMDPARAM_HELP},
{"H", CMDPARAM_HELP},
{"help", CMDPARAM_HELP},
{"mode", CMDPARAM_MODE},
{"tall", CMDPARAM_PIXELRATIO_TALL},
{"wide", CMDPARAM_PIXELRATIO_WIDE},
{"double", CMDPARAM_PIXELRATIO_DOUBLE},
{"triple", CMDPARAM_PIXELRATIO_TRIPLE},
{"quadruple", CMDPARAM_PIXELRATIO_QUAD},
{"tall2", CMDPARAM_PIXELRATIO_TALL2},
{"wide2", CMDPARAM_PIXELRATIO_WIDE2},
{"rgb", CMDPARAM_RGB},
{"skin", CMDPARAM_SKIN}
};
#define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof(x[0]))
// --------------------- 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++)
{
char *s = argv[index];
int is_switch = ((strchr(s,'/') == s) || (strchr(s,'-') == s) || (strstr(s,"--") == s));
int tmpi;
int paramtype = -1;
if (is_switch)
{
int param_matches = 0;
int param_match = -1;
if (*s == '-')
{
s++;
if (*s == '-')
s++;
}
else
s++;
for (tmpi = 0; tmpi < ARRAY_SIZE(cmdparams); tmpi++)
{
if (!strcmp(s, cmdparams[tmpi].param))
{
paramtype = cmdparams[tmpi].id;
break;
}
else if (strstr(cmdparams[tmpi].param, s))
{
param_matches++;
param_match = cmdparams[tmpi].id;
}
}
if (paramtype == -1 && param_matches == 1)
paramtype = param_match;
}
switch (paramtype)
{
case CMDPARAM_HELP:
Display_syntax();
exit(0);
case CMDPARAM_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);
}
break;
case CMDPARAM_PIXELRATIO_TALL:
Pixel_ratio = PIXEL_TALL;
break;
case CMDPARAM_PIXELRATIO_WIDE:
Pixel_ratio = PIXEL_WIDE;
break;
case CMDPARAM_PIXELRATIO_DOUBLE:
Pixel_ratio = PIXEL_DOUBLE;
break;
case CMDPARAM_PIXELRATIO_TRIPLE:
Pixel_ratio = PIXEL_TRIPLE;
break;
case CMDPARAM_PIXELRATIO_QUAD:
Pixel_ratio = PIXEL_QUAD;
break;
case CMDPARAM_PIXELRATIO_TALL2:
Pixel_ratio = PIXEL_TALL2;
break;
case CMDPARAM_PIXELRATIO_WIDE2:
Pixel_ratio = PIXEL_WIDE2;
break;
case CMDPARAM_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);
}
break;
case CMDPARAM_SKIN:
// GUI skin file
index++;
if (index<argc)
{
strcpy(Config.Skin_file,argv[index]);
}
else
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
break;
default:
// 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);
free(buffer);
}
else
{
Extract_path(Spare_file_directory, buffer);
Extract_filename(Spare_filename, buffer);
free(buffer);
}
}
else
{
Error(ERROR_COMMAND_LINE);
Display_syntax();
exit(0);
}
break;
}
}
}
// ------------------------ 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];
T_Gui_skin *gfx;
// 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;
Main_current_layer=0;
Main_layers_visible=0xFFFFFFFF;
Spare_current_layer=0;
Spare_layers_visible=0xFFFFFFFF;
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:
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.
gfx = Load_graphics(Config.Skin_file);
if (gfx == NULL)
{
gfx = Load_graphics("skin_modern.png");
if (gfx == NULL)
{
printf("%s", Gui_loading_error_message);
Error(ERROR_GUI_MISSING);
}
}
Set_current_skin(Config.Skin_file, gfx);
Fore_color=MC_White;
Back_color=MC_Black;
// Override colors
// 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);
// Infos sur les trames (Sieve)
Sieve_mode=0;
Copy_preset_sieve(0);
// 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;
#ifndef NOLAYERS
Visible_image[0].Width = 0;
Visible_image[0].Height = 0;
Visible_image[0].Image = NULL;
Visible_image[1].Width = 0;
Visible_image[1].Height = 0;
Visible_image[1].Image = NULL;
Visible_image_depth_buffer.Width = 0;
Visible_image_depth_buffer.Height = 0;
Visible_image_depth_buffer.Image = NULL;
#endif
// Allocation de m<>moire pour les diff<66>rents <20>crans virtuels (et brosse)
if (Init_all_backup_lists(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;
}