grafX2/cfg/gfxcfg.pas
Yves Rizoud 5fd1e42ea0 Copyright notices in source files
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@217 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2008-10-08 19:40:47 +00:00

667 lines
21 KiB
ObjectPascal
Raw Blame History

{ Grafx2 - The Ultimate 256-color bitmap paint program
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/> or
write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
program GrafX2_Setup;
{============================================================================}
const
TAILLE_FICHIER_CONFIG=10351;
TAILLE_INI =16203;
NB_MODES_VIDEO =60;
VERSION1 =2;
VERSION2 =0;
BETA1 =96;
BETA2 =5;
COULEUR_TITRE =$5D;
COULEUR_SETUP =$1B;
COULEUR_SELECT =$3F;
COULEUR_EXPLIC =$2A;
COULEUR_MESSAGE =$3F;
HAUTEUR_DEBUT_SETUP =10;
HAUTEUR_FIN_SETUP =44;
TAILLE_SETUP =(HAUTEUR_FIN_SETUP-HAUTEUR_DEBUT_SETUP)*40;
{$I SCANCODE.PAS}
{$I VIDEOMOD.PAS}
{============================================================================}
{------------------------ Passer en mode texte 80x50 ------------------------}
procedure Text_mode_80x50; assembler;
asm
mov ax,3
int 10h
mov ax,1112h
xor bl,bl
mov dl,50
int 10h
end;
{------------------------ Passer en mode texte 80x25 ------------------------}
procedure Text_mode_80x25; assembler;
asm
mov ax,3
int 10h
end;
{---------------------------- Gestion du curseur ----------------------------}
procedure Montrer_Curseur; assembler;
asm
mov ax,0103h
mov cx,0E0Fh
int 10h
end;
procedure Cacher_Curseur; assembler;
asm
mov ax,0103h
mov cx,0F0Eh
int 10h
end;
procedure Goto_XY(X,Y:byte); assembler;
asm
mov ah,2
xor bh,bh
mov dl,X
mov dh,Y
int 10h
end;
{---------------------- Change la couleur d'une ligne -----------------------}
procedure Set_color_of_line(Num_ligne:word; X1,X2,Couleur:byte); assembler;
asm
mov ax,0B800h
mov es,ax
mov ax,Num_ligne
mov bx,80
mul bl
mov bl,X1
add ax,bx
add ax,ax
mov di,ax
mov cl,X2
sub cl,X1
inc cl
mov al,Couleur
@Set_col_loop:
inc di
stosb
dec cl
jnz @Set_col_loop
end;
{------------------------ Passer en mode texte 80x25 ------------------------}
procedure Dessiner_ecran_principal;
var
i:byte;
begin
Cadre( 0, 0,79, 6,COULEUR_TITRE);
Print( 2, 1,'Setup program for GRAFX 2.00 (c)1996-98 Sunset Design (G.DORME & K.MARITAUD)',COULEUR_TITRE);
Print( 0, 2,'<27>',COULEUR_TITRE);
Print(79, 2,'<27>',COULEUR_TITRE);
for i:=1 to 78 do
Print(i,2,'<27>',COULEUR_TITRE);
Print( 2, 3,'Use Up/Down arrows & Page-Up/Page-Down to scroll, Enter to modify, Delete to',COULEUR_TITRE);
Print( 2, 4,'remove a hot-key, and Escape to validate or cancel. (Warning: QWERTY keys!)',COULEUR_TITRE);
Print( 2, 5,'DO NOT USE Print-screen, Pause, and all other special keys!',COULEUR_TITRE);
Cadre( 0, 7,79, 9,COULEUR_SETUP);
Print( 2, 8,'Option',COULEUR_SETUP);
Print(38, 8,'<27> Hot-key',COULEUR_SETUP);
Print(75, 8,'<27>Err',COULEUR_SETUP);
Cadre( 0, 9,79,45,COULEUR_SETUP);
Print( 0, 9,'<27>',COULEUR_SETUP);
Print(79, 9,'<27>',COULEUR_SETUP);
Print(38, 7,'<27>',COULEUR_SETUP);
Print(75, 7,'<27>',COULEUR_SETUP);
Print(38, 9,'<27>',COULEUR_SETUP);
Print(75, 9,'<27>',COULEUR_SETUP);
Print(38,45,'<27>',COULEUR_SETUP);
Print(75,45,'<27>',COULEUR_SETUP);
Cadre( 0,46,79,49,COULEUR_EXPLIC);
end;
{--------------- Transformer une cha<68>ne AZT en String Pascal ----------------}
function Pchar2string(Chaine:pchar):string;
var
Temp:string;
i:byte;
begin
Temp:='';
i:=0;
while Chaine[i]>#0 do
begin
Temp:=Temp+Chaine[i];
inc(i);
end;
Pchar2string:=Temp;
end;
{------------------- Compl<70>te une chaine avec un caract<63>re ------------------}
function Completer_chaine(Chaine:string; Taille:byte; Caractere:char):string;
var
i:byte;
begin
for i:=length(Chaine)+1 to Taille do
Chaine[i]:=Caractere;
Chaine[0]:=chr(Taille);
Completer_chaine:=Chaine;
end;
{--------------------- Test de duplication des touches ----------------------}
procedure Test_duplic;
var
i,j:word;
Pas_encore_erreur:boolean;
begin
for i:=1 to NB_OPTIONS do
if (Config[i].Touche<>$00FF) then
begin
j:=1;
Pas_encore_erreur:=true;
while (j<=NB_OPTIONS) and (Pas_encore_erreur) do
begin
if (i<>j) and (Config[i].Touche=Config[j].Touche) then
begin
Pas_encore_erreur:=false;
Config[i].Erreur:=true;
end;
inc(j);
end;
if Pas_encore_erreur then Config[i].Erreur:=false;
end;
end;
{------------------- S<>lectionner une touche <20> modifier ---------------------}
procedure Select(Decalage_curseur, Position_curseur:word);
var
Touche,Num_ligne,Num_option,Num_table:word;
begin
Num_ligne:=Position_curseur+HAUTEUR_DEBUT_SETUP-1;
Num_option:=Position_curseur+Decalage_curseur;
Config[Num_option].Touche:=$00FF;
Ecrire(Num_ligne,Num_option,COULEUR_SELECT);
Goto_XY(40,Num_ligne);
Montrer_curseur;
repeat
Touche:=Lire_touche;
until Touche<>$0000;
Config[Num_option].Touche:=Touche;
Cacher_curseur;
Test_duplic;
Num_table:=1;
if (hi(Touche) and 1)>0
then Num_table:=2;
if (hi(Touche) and 2)>0
then Num_table:=3;
if (hi(Touche) and 4)>0
then Num_table:=4;
case Num_table of
1: if Pchar2string(Table_Normal[lo(Touche)])='???'
then Config[Num_option].Erreur:=true;
2: if Pchar2string(Table_Shift[lo(Touche)])='???'
then Config[Num_option].Erreur:=true;
3: if Pchar2string(Table_Ctrl[lo(Touche)])='???'
then Config[Num_option].Erreur:=true;
4: if Pchar2string(Table_Alt[lo(Touche)])='???'
then Config[Num_option].Erreur:=true;
end;
Tout_ecrire(Decalage_curseur,Position_curseur);
end;
{------------------------ D<>s<EFBFBD>lectionner une touche -------------------------}
procedure Unselect(Decalage_curseur, Position_curseur:word);
var
Num_option:word;
begin
Num_option:=Decalage_curseur+Position_curseur;
Config[Num_option].Erreur:=false;
Config[Num_option].Touche:=$00FF;
Test_duplic;
if not Config[Num_option].Suppr
then Config[Num_option].Erreur:=true;
Tout_ecrire(Decalage_curseur,Position_curseur);
end;
{---------------------- Validation de la configuration ----------------------}
function Validation:boolean;
var
Y_a_des_erreurs:boolean;
i:word;
begin
Y_a_des_erreurs:=false;
i:=1;
while (i<=NB_OPTIONS) and not Y_a_des_erreurs do
begin
Y_a_des_erreurs:=Config[i].Erreur;
inc(i);
end;
if Y_a_des_erreurs
then Choix_enreg:=4-Fenetre_choix(30,12,
'There are errors in the^hot-keys configuration.^Check out the "Err" column^in order to correct them.^',
'OK^Quit anyway^',1,$4C,$3F)
else Choix_enreg:=Fenetre_choix(30,10,'Save configuration?^','Yes^No^Cancel^',1,$2A,$6F);
Validation:=(Choix_enreg<>3);
end;
{------------------------ Configuration des touches -------------------------}
procedure Setup;
var
Sortie_OK:boolean;
Touche:word;
Decalage_curseur:word;
Position_curseur:word;
begin
Sortie_OK:=false;
Decalage_curseur:=0;
Position_curseur:=1;
Test_duplic;
Tout_ecrire(0,1);
repeat
Touche:=Lire_Touche;
case Touche of
$0048 : Scroll_haut(Decalage_curseur,Position_curseur);
$0050 : Scroll_bas(Decalage_curseur,Position_curseur);
$0049 : Page_up(Decalage_curseur,Position_curseur);
$0051 : Page_down(Decalage_curseur,Position_curseur);
$001C : Select(Decalage_curseur,Position_curseur);
$0053 : Unselect(Decalage_curseur,Position_curseur);
$0001 : Sortie_OK:=Validation;
end;
until Sortie_OK;
end;
{--- Lecture (et mise <20> jour s'il est ancien) du fichier de configuration ---}
type
Type_shade=record
Table:array[1..512] of word;
Pas:byte;
Mode:byte;
end;
Type_mode_video=record
Etat :byte;
Largeur:word;
Hauteur:word;
end;{
Type_header=record
Signature:array[1..3] of char;
Version1:byte;
Version2:byte;
Beta1:byte;
Beta2:byte;
end;
Type_chunk=record
Numero:byte;
Taille:word;
end;}
Type_infos_touche=record
Numero : word;
Touche : word;
Touche2: word;
end;
var
Modes_video :array[1..NB_MODES_VIDEO] of Type_mode_video;
Shade_actuel :byte;
Shades :array[1..8] of Type_shade;
Masque :array[1..256] of byte;
Stencil :array[1..256] of byte;
Infos_degrades:array[1..225] of byte;
Smooth_Matrice:array[1..3,1..3] of byte;
Exclude_color :array[1..256] of byte;
Quick_shade :array[1..2] of byte;
procedure Interpretation_du_fichier_config;
var
Fichier :file;
Indice :word;
Indice2 :word;
Taille_fichier:longint;
Header :Type_header;
Chunk :Type_chunk;
Infos_touche :Type_infos_touche;
Mode_video :Type_mode_video;
OK :boolean;
begin
{- Modes vid<69>os -}
for Indice:=1 to NB_MODES_VIDEO do
begin
Modes_video[Indice].Etat :=Table_modes_video[Indice,1];
Modes_video[Indice].Largeur:=Table_modes_video[Indice,2];
Modes_video[Indice].Hauteur:=Table_modes_video[Indice,3];
end;
{- Shade -}
Shade_actuel:=0; {1er shade}
for Indice:=1 to 8 do
begin
for Indice2:=1 to 512 do
Shades[Indice].Table[Indice2]:=256; {Case vide pas tagg<67>e}
Shades[Indice].Pas:=1; {Pas de 1}
Shades[Indice].Mode:=0; {Mode Normal}
end;
{- Masque -}
fillchar(Masque,sizeof(Masque),0);
{- Stencil -}
fillchar(Stencil,sizeof(Stencil),0);
{- Infos sur les d<>grad<61>s -}
fillchar(Infos_degrades,sizeof(Infos_degrades),0);
{- Matrice du Smooth -}
Smooth_matrice[1][1]:=1;
Smooth_matrice[2][1]:=2;
Smooth_matrice[3][1]:=1;
Smooth_matrice[1][2]:=2;
Smooth_matrice[2][2]:=4;
Smooth_matrice[3][2]:=2;
Smooth_matrice[1][3]:=1;
Smooth_matrice[2][3]:=2;
Smooth_matrice[3][3]:=1;
{- Exclude colors -}
fillchar(Exclude_color,sizeof(Exclude_color),0);
{- Quick-shade -}
Quick_shade[1]:=1; {Step}
Quick_shade[2]:=0; {Loop mode (0=normal,1=loop,2=no sat.}
Taille_fichier:=0;
assign(Fichier,'GFX2.CFG');
{$I-}
reset(Fichier,1);
{$I+}
if (IOresult=0) then
begin {On tente de r<>cup<75>rer les infos du fichier}
Taille_fichier:=filesize(Fichier);
if (Taille_fichier>=7) then
begin
blockread(Fichier,Header,7);
if Header.Signature='CFG' then
begin
{On regarde si c'est un fichier de la version actuelle}
if (Taille_fichier =TAILLE_FICHIER_CONFIG) and
(Header.Version1=VERSION1 ) and
(Header.Version2=VERSION2 ) and
(Header.Beta1 =BETA1 ) and
(Header.Beta2 =BETA2 ) then
begin {Si oui, on r<>cup<75>re les touches et on s'arr<72>te l<>}
seek(Fichier,sizeof(Header)+Sizeof(Chunk));
for Indice:=1 to NB_OPTIONS do
blockread(Fichier,Config[Indice],6);
close(Fichier);
exit;
end
else
begin {Si non, c'est une ancienne version et on r<>cup<75>re tout ce qu'on peut}
OK:=TRUE;
{$I-}
while OK(*not eof(Fichier)*) do
begin
blockread(Fichier,Chunk,sizeof(Chunk));
if (IOresult<>0) then
OK:=FALSE
else
case Chunk.Numero of
0:begin {Touches}
for Indice:=1 to (Chunk.Taille div sizeof(Infos_touche)) do
begin
blockread(Fichier,Infos_touche,sizeof(Infos_touche));
if (IOresult<>0) then
OK:=FALSE
else
begin
Indice2:=1;
while (Indice2<=NB_OPTIONS) and
(Config[Indice2].Numero<>Infos_touche.Numero) do
inc(Indice2);
if (Indice2<=NB_OPTIONS) then
begin
Config[Indice2].Touche :=Infos_touche.Touche;
Config[Indice2].Touche2:=Infos_touche.Touche2;
end;
end;
end;
end;
1:begin {Modes vid<69>o}
for Indice:=1 to (Chunk.Taille div sizeof(Mode_video)) do
begin
blockread(Fichier,Mode_video,sizeof(Mode_video));
if (IOresult<>0) then
OK:=FALSE
else
begin
Indice2:=1;
while (Indice2<=NB_MODES_VIDEO) and
( (Modes_video[Indice2].Largeur<>Mode_video.Largeur) or
(Modes_video[Indice2].Hauteur<>Mode_video.Hauteur) or
((Modes_video[Indice2].Etat and $C0)<>(Mode_video.Etat and $C0)) ) do
inc(Indice2);
if (Indice2<=NB_MODES_VIDEO) then
Modes_video[Indice2].Etat:=Mode_video.Etat;
end;
end;
end;
2:begin {Shade}
blockread(Fichier,Shade_actuel,sizeof(Shade_actuel));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet un shade actuel propre}
Shade_actuel:=0;
end
else
begin
blockread(Fichier,Shades,sizeof(Shades));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet des tables de shades propres}
for Indice:=1 to 8 do
begin
for Indice2:=1 to 512 do
Shades[Indice].Table[Indice2]:=256; {Case vide pas tagg<67>e}
Shades[Indice].Pas:=1; {Pas de 1}
Shades[Indice].Mode:=0; {Mode Normal}
end;
end;
end;
end;
3:begin {Masque}
blockread(Fichier,Masque,sizeof(Masque));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet un masque propre}
fillchar(Masque,sizeof(Masque),0);
end;
end;
4:begin {Stencil}
blockread(Fichier,Stencil,sizeof(Stencil));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet un stencil propre}
fillchar(Stencil,sizeof(Stencil),0);
end;
end;
5:begin {Infos sur les d<>grad<61>s}
blockread(Fichier,Infos_degrades,sizeof(Infos_degrades));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet des infos sur les d<>grad<61>s propres}
fillchar(Stencil,sizeof(Infos_degrades),0);
end;
end;
6:begin {Matrice du Smooth}
blockread(Fichier,Smooth_Matrice,sizeof(Smooth_Matrice));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet une matrice de Smooth propre}
Smooth_matrice[1][1]:=1;
Smooth_matrice[2][1]:=2;
Smooth_matrice[3][1]:=1;
Smooth_matrice[1][2]:=2;
Smooth_matrice[2][2]:=4;
Smooth_matrice[3][2]:=2;
Smooth_matrice[1][3]:=1;
Smooth_matrice[2][3]:=2;
Smooth_matrice[3][3]:=1;
end;
end;
7:begin {Exclude colors}
blockread(Fichier,Exclude_color,sizeof(Exclude_color));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet une table d'exclusion propre}
fillchar(Exclude_color,sizeof(Exclude_color),0);
end;
end;
8:begin {Quick-shade}
blockread(Fichier,Quick_shade,sizeof(Quick_shade));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet un quick-shade propre}
Quick_shade[1]:=1; {Step}
Quick_shade[2]:=0; {Loop mode}
end;
end
else
begin
seek(Fichier,filepos(Fichier)+Chunk.Taille);
if (IOresult<>0) then
OK:=FALSE;
end;
end;
end;
{$I+}
end;
end;
end;
end;
{- Ecriture du fichier d'options -}
assign(Fichier,'GFX2.CFG');
rewrite(Fichier,1);
{Ecriture du header}
Header.Signature:='CFG';
Header.Version1 :=VERSION1;
Header.Version2 :=VERSION2;
Header.Beta1 :=BETA1;
Header.Beta2 :=BETA2;
blockwrite(Fichier,Header,sizeof(Header));
{Enregistrement des touches}
Chunk.Numero:=0;
Chunk.Taille:=NB_OPTIONS*sizeof(Infos_touche);
blockwrite(Fichier,Chunk,sizeof(Chunk));
for Indice:=1 to NB_OPTIONS do
blockwrite(Fichier,Config[Indice],sizeof(Infos_touche)); {Les 3 premiers champs (words) sont: Num<75>ro,Touche,Touche2}
{Sauvegarde de l'<27>tat de chaque mode vid<69>o}
Chunk.Numero:=1;
Chunk.Taille:=sizeof(Modes_video);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Modes_video,sizeof(Modes_video));
{Ecriture des donn<6E>es du Shade (pr<70>c<EFBFBD>d<EFBFBD>es du shade en cours)}
Chunk.Numero:=2;
Chunk.Taille:=sizeof(Shades)+Sizeof(Shade_actuel);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Shade_actuel,Sizeof(Shade_actuel));
blockwrite(Fichier,Shades,Sizeof(Shades));
{Ecriture des donn<6E>es du Masque}
Chunk.Numero:=3;
Chunk.Taille:=sizeof(Masque);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Masque,Sizeof(Masque));
{Ecriture des donn<6E>es du Stencil}
Chunk.Numero:=4;
Chunk.Taille:=sizeof(Stencil);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Stencil,Sizeof(Stencil));
{Ecriture des donn<6E>es sur les d<>grad<61>s}
Chunk.Numero:=5;
Chunk.Taille:=sizeof(Infos_degrades);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Infos_degrades,Sizeof(Infos_degrades));
{Ecriture de la matrice de Smooth}
Chunk.Numero:=6;
Chunk.Taille:=sizeof(Smooth_Matrice);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Smooth_Matrice,Sizeof(Smooth_Matrice));
{Ecriture de la table d'exclusion de couleurs}
Chunk.Numero:=7;
Chunk.Taille:=sizeof(Exclude_color);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Exclude_color,Sizeof(Exclude_color));
{Ecriture des donn<6E>es du Quick-shade}
Chunk.Numero:=8;
Chunk.Taille:=sizeof(Quick_shade);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Quick_shade,Sizeof(Quick_shade));
close(Fichier);
end;
function Recreer_INI:boolean;
type
T_Buffer=array[1..TAILLE_INI] of byte;
var
Fichier_INI,Fichier_DAT:file;
Buffer:pointer;{^T_Buffer;}
Erreur:boolean;
begin
assign(Fichier_INI,'GFX2.INI');
assign(Fichier_DAT,'GFX2.DAT');
{$I-}
reset(Fichier_DAT,1);
if IOresult<>0 then
Erreur:=true
else
begin
seek(Fichier_DAT,filesize(Fichier_DAT)-TAILLE_INI);
if IOresult<>0 then
Erreur:=true
else
begin
Erreur:=false;
rewrite(Fichier_INI,1);
getmem(Buffer,TAILLE_INI);
blockread (Fichier_DAT,Buffer^,TAILLE_INI);
blockwrite(Fichier_INI,Buffer^,TAILLE_INI);
freemem(Buffer,TAILLE_INI);
close(Fichier_INI);
end;
close(Fichier_DAT);
end;
{$I+}
Recreer_INI:=Erreur;
end;