diff --git a/init.c b/init.c index 070f5e7d..fb661419 100644 --- a/init.c +++ b/init.c @@ -22,6 +22,11 @@ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +// Signal handler: I activate it for the two platforms who certainly +// support them. Feel free to check with others. +#if defined(__WIN32__) || defined(__linux__) + #define GRAFX2_CATCHES_SIGNALS +#endif #include #include #include @@ -36,10 +41,12 @@ #if defined(__WIN32__) #include // GetLogicalDrives(), GetDriveType(), DRIVE_* #endif - #if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) -#include -#include + #include + #include +#endif +#ifdef GRAFX2_CATCHES_SIGNALS + #include #endif #include "const.h" @@ -60,6 +67,7 @@ #include "windows.h" #include "sdlscreen.h" #include "mountlist.h" // read_file_system_list +#include "loadsave.h" // Image_emergency_backup // Ajouter un lecteur à la liste de lecteurs void Ajouter_lecteur(char Lettre, byte Type, char *Chemin) @@ -72,7 +80,6 @@ void Ajouter_lecteur(char Lettre, byte Type, char *Chemin) Nb_drives++; } - // Rechercher la liste et le type des lecteurs de la machine #if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) @@ -2364,3 +2371,47 @@ void Config_par_defaut(void) Snap_Decalage_X=Snap_Decalage_Y=0; } + +#ifdef GRAFX2_CATCHES_SIGNALS + +// Memorize the signal handlers of SDL +__p_sig_fn_t Handler_TERM=SIG_DFL; +__p_sig_fn_t Handler_INT=SIG_DFL; +__p_sig_fn_t Handler_ABRT=SIG_DFL; +__p_sig_fn_t Handler_SEGV=SIG_DFL; +__p_sig_fn_t Handler_FPE=SIG_DFL; + +void sig_handler(int sig) +{ + // Restore default behaviour + signal(SIGTERM, Handler_TERM); + signal(SIGINT, Handler_INT); + signal(SIGABRT, Handler_ABRT); + signal(SIGSEGV, Handler_SEGV); + signal(SIGFPE, Handler_FPE); + + switch(sig) + { + case SIGTERM: + case SIGINT: + case SIGABRT: + case SIGSEGV: + Image_emergency_backup(); + default: + break; + } +} +#endif + +void Initialiser_sighandler(void) +{ +#ifdef GRAFX2_CATCHES_SIGNALS + Handler_TERM=signal(SIGTERM,sig_handler); + Handler_INT =signal(SIGINT,sig_handler); + Handler_ABRT=signal(SIGABRT,sig_handler); + Handler_SEGV=signal(SIGSEGV,sig_handler); + Handler_FPE =signal(SIGFPE,sig_handler); + +#endif +} + diff --git a/init.h b/init.h index c010f39b..0b6749db 100644 --- a/init.h +++ b/init.h @@ -28,3 +28,4 @@ void Initialiser_les_tables_de_multiplication(void); void Definition_des_modes_video(void); int ActiverLecteur(int); void Config_par_defaut(void); +void Initialiser_sighandler(void); diff --git a/loadsave.c b/loadsave.c index b3cb918c..59636aae 100644 --- a/loadsave.c +++ b/loadsave.c @@ -5864,3 +5864,58 @@ void Save_PNG(void) row_pointers=NULL; } } + +// Saves an image. +// This routine will only be called when all hope is lost, memory thrashed, etc +// It's the last chance to save anything, but the code has to be extremely careful, +// anything could happen. +// The chosen format is IMG since it's extremely simple, difficult to make it create an unusable image. +void Emergency_backup(const char *Fname, byte *Source, int Largeur, int Hauteur, T_Palette *Palette) +{ + char Nom_du_fichier[TAILLE_CHEMIN_FICHIER]; // Nom complet du fichier + FILE *Fichier; + short Pos_X,Pos_Y; + T_Header_IMG IMG_Header; + + strcpy(Nom_du_fichier,Repertoire_de_configuration); + strcat(Nom_du_fichier,Fname); + + // Ouverture du fichier + Fichier=fopen(Nom_du_fichier,"wb"); + if (!Fichier) + return; + + memcpy(IMG_Header.Filler1,"\x01\x00\x47\x12\x6D\xB0",6); + memset(IMG_Header.Filler2,0,118); + IMG_Header.Filler2[4]=0xFF; + IMG_Header.Filler2[22]=64; // Lo(Longueur de la signature) + IMG_Header.Filler2[23]=0; // Hi(Longueur de la signature) + memcpy(IMG_Header.Filler2+23,"GRAFX2 by SunsetDesign (IMG format taken from PV (c)W.Wiedmann)",64); + + if (!write_bytes(Fichier,IMG_Header.Filler1,6) || + !write_word_le(Fichier,Largeur) || + !write_word_le(Fichier,Hauteur) || + !write_bytes(Fichier,IMG_Header.Filler2,118) || + !write_bytes(Fichier,Palette,sizeof(T_Palette))) + { + fclose(Fichier); + return; + } + + for (Pos_Y=0; ((Pos_Y