Files
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

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,'Ç',COULEUR_TITRE);
Print(79, 2,'¶',COULEUR_TITRE);
for i:=1 to 78 do
Print(i,2,'Ä',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,'³ Hot-key',COULEUR_SETUP);
Print(75, 8,'³Err',COULEUR_SETUP);
Cadre( 0, 9,79,45,COULEUR_SETUP);
Print( 0, 9,'Ì',COULEUR_SETUP);
Print(79, 9,'¹',COULEUR_SETUP);
Print(38, 7,'Ñ',COULEUR_SETUP);
Print(75, 7,'Ñ',COULEUR_SETUP);
Print(38, 9,'Ø',COULEUR_SETUP);
Print(75, 9,'Ø',COULEUR_SETUP);
Print(38,45,'Ï',COULEUR_SETUP);
Print(75,45,'Ï',COULEUR_SETUP);
Cadre( 0,46,79,49,COULEUR_EXPLIC);
end;
{--------------- Transformer une chaŒ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Šte une chaine avec un caractŠ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;
{------------------- Slectionner une touche … 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;
{------------------------ Dslectionner 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 … 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 vidos -}
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 tagge}
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 dgrads -}
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 rcuprer 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 rcupŠre les touches et on s'arrˆ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 rcupŠ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 vido}
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 tagge}
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 dgrads}
blockread(Fichier,Infos_degrades,sizeof(Infos_degrades));
if (IOresult<>0) then
begin
OK:=FALSE; {Erreur => On remet des infos sur les dgrads 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: Numro,Touche,Touche2}
{Sauvegarde de l'tat de chaque mode vido}
Chunk.Numero:=1;
Chunk.Taille:=sizeof(Modes_video);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Modes_video,sizeof(Modes_video));
{Ecriture des donnes du Shade (prcdes 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 donnes du Masque}
Chunk.Numero:=3;
Chunk.Taille:=sizeof(Masque);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Masque,Sizeof(Masque));
{Ecriture des donnes du Stencil}
Chunk.Numero:=4;
Chunk.Taille:=sizeof(Stencil);
blockwrite(Fichier,Chunk,sizeof(Chunk));
blockwrite(Fichier,Stencil,Sizeof(Stencil));
{Ecriture des donnes sur les dgrads}
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 donnes 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;