grafX2/cfg/gfxcfg.pas
Adrien Destugues 92c4340dbd Video modes can now be windowed or fullscreen. Quite hacky, however. We would need a way to :
-Easily change the number of video modes in the list (i'd like to use my 1440x900 screen at full resoluution !)
-Maybe add a resizeable window mode, but that would require more work, so i'd like to keep that for 2.0 .

In the meantime, i've made the list symetric, ie, mode are loaded from the cfg file and when the list is processed, each mode is copied to a fullscreen equivalent. Note this way of doing things will prevent the config file to save the selected video mode properly, so the program will switch to the default 800x600 windowed. When you load an image, Grafx2 will switch back to windowed mode when selecting the appropriate resolution for that image.

The NB_MODES_VIDEO constant is also only the HALF of the actually available video modes


git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@183 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2008-09-30 15:12:40 +00:00

648 lines
20 KiB
ObjectPascal
Raw Blame History

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;