Les paramètres

On va créer un nouveau projet. Ce sera un programme qui permettra de lire et écrire les paramètres du jeu à partir du fichier param.alx. Pour faciliter le dessin de la fenêtre nous créerons un projet de type MFC.

Une fois le projet créé, nous allons réaliser la fenêtre comme dans ci-dessous. Pour cela il faut aller dans RessourceViews et cliquer sur IPP_NOM_DIALOG. Il est facile d'utiliser les outils proposés par le Visual.

Maintenant dans le fichier NomDlg.h, nous déclarons les différents pointeurs utilisés ainsi que les méthodes :

class CParam3Dlg : public CDialog
{
// Construction
public:
CParam3Dlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CParam3Dlg)
enum { IDD = IDD_PARAM3_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CParam3Dlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:

CEdit *edit1, *edit2, *edit3;
CSliderCtrl *slide;
CHotKeyCtrl *hk2, *hk3, *hk4, *hk5, *hk6, *hk7, *hk8, *hk9, *hk10, *hk11;

HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CParam3Dlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

unsigned int cumul(FILE*);
void lecture(FILE*);
void ecriture(FILE*, unsigned int);

};

Ensuite nous construisons dans la méthode OnInitDialog nos différents objets en récupérant les identifiants grâce à la fonction GetDlgItem. Les différentes valeurs sont quand à elles récupérées dans le fichier param.alx.

BOOL CParam3Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

edit1 = (CEdit*) GetDlgItem(IDC_EDIT1);
edit2 = (CEdit*) GetDlgItem(IDC_EDIT2);
edit3 = (CEdit*) GetDlgItem(IDC_EDIT3);
slide = (CSliderCtrl*) GetDlgItem(IDC_SLIDER1);
hk2 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY2);
hk3 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY3);
hk4 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY4);
hk5 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY5);
hk6 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY6);
hk7 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY7);
hk8 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY8);
hk9 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY9);
hk10 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY10);
hk11 = (CHotKeyCtrl*) GetDlgItem(IDC_HOTKEY11);

FILE *fich;

fich = fopen("param.alx", "rb");
if (fich==NULL) exit(-1);

lecture(fich);

fclose(fich);

SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control
}

Chaque valeur récupérée dans le fichier param.alx est composée de 4 octets, ce qui offre une possibilité allant de 0 à 2 puissance 32, sauf pour les touches clavier. La fonction fgetc récupère 8 bits à la fois. Il faut donc à chaque fois effectuer un décalage de bits pour récupérer notre valeur entière sans que les bits ne s'écrasent entre eux.

Ainsi si l 'on a dans le fichier :

8, 7, 45, 200

v = 8 * 2 puissance 24 + 7 * 2 puissance 16 + 45 * 2 puissance 8 + 200

soit en C : v = 8 << 24 + 7 << 16 + 45 << 8 + 200

Notre fonction lecture utilise donc la fonction cumul inspirée sur l'exemple ci-haut.

La méthode SetHotKey prend pour premier paramètre la valeur de la touche clavier et en second paramètre tout ce qui est Ctrl, combinaison de touches.

void CParam3Dlg::lecture(FILE *fichier)
{

char c[10];
unsigned int val;

hk2->SetHotKey(fgetc(fichier), 0);
hk3->SetHotKey(fgetc(fichier), 0);
hk4->SetHotKey(fgetc(fichier), 0);
hk5->SetHotKey(fgetc(fichier), 0);
hk6->SetHotKey(fgetc(fichier), 0);
hk7->SetHotKey(fgetc(fichier), 0);
hk8->SetHotKey(fgetc(fichier), 0);
hk9->SetHotKey(fgetc(fichier), 0);
hk10->SetHotKey(fgetc(fichier), 0);
hk11->SetHotKey(fgetc(fichier), 0);

val = cumul(fichier);
itoa(val, c, 10);
edit1->SetWindowText(c);

val = cumul(fichier);
itoa(val, c, 10);
edit2->SetWindowText(c);

val = cumul(fichier);
itoa(val, c, 10);
edit3->SetWindowText(c);

val = cumul(fichier);
slide->SetRange(0, 255, TRUE);
slide->SetPos(val);

}

unsigned int CParam3Dlg::cumul(FILE *fichier)
{

unsigned int val = 0;

val += fgetc(fichier) << 24;
val += fgetc(fichier) << 16;
val += fgetc(fichier) << 8;
val += fgetc(fichier);

return val;
}

Lorsque nous appuyons sur le bouton OK, l'écriture des différents paramètres doit s'effectuer. Pour créer la méthode correspondante au bouton OK, faites clic droit sur le dessin du bouton OK dans RessourceView et choisissez ClassWizard. Puis sélectionnez BN_CLICKED et enfin Add Function.

Voilà il suffit de compléter la méthode ainsi :

void CParam3Dlg::OnOK() 
{
// TODO: Add extra validation here

char c[10];


FILE *fich;

fich = fopen("param.alx", "wb");

if (fich==NULL)
exit(-1);

DWORD v0 = 0;
v0 = hk2->GetHotKey();
fputc(v0, fich);

v0 = hk3->GetHotKey();
fputc(v0, fich);

v0 = hk4->GetHotKey();
fputc(v0, fich);

v0 = hk5->GetHotKey();
fputc(v0, fich);

v0 = hk6->GetHotKey();
fputc(v0, fich);

v0 = hk7->GetHotKey();
fputc(v0, fich);

v0 = hk8->GetHotKey();
fputc(v0, fich);

v0 = hk9->GetHotKey();
fputc(v0, fich);

v0 = hk10->GetHotKey();
fputc(v0, fich);

v0 = hk11->GetHotKey();
fputc(v0, fich);

edit1->GetWindowText(c, 4);
unsigned int v = atoi(c);

if(v > 2048)
v = 2048;

ecriture(fich, v);

edit2->GetWindowText(c, 4);
v = atoi(c);

if(v > 2048)
v = 2048;

ecriture(fich, v);

edit3->GetWindowText(c, 4);
v = atoi(c);

if(v > 20)
v = 20;

ecriture(fich, v);

ecriture(fich, slide->GetPos());

fclose(fich);

CDialog::OnOK();
}

Et voici la méthode écriture :

void CParam3Dlg::ecriture(FILE *fichier, unsigned int val)
{

unsigned int val2;

val2 = val >> 24;
fputc(val2, fichier);

val -= (val2 << 24);
val2 = val >> 16;

fputc(val2, fichier);

val -= (val2 << 16);
val2 = val >> 8;

fputc(val2, fichier);

val -= (val2 << 8);
val2 = val;

fputc(val2, fichier);

}

En ce qui concerne le projet principal, on effectue une lecture des différents paramètres tout comme dans le projet précédent.

directions direc;

unsigned int cumul(FILE *fichier)
{

unsigned int val = 0;

val += fgetc(fichier) << 24;
val += fgetc(fichier) << 16;
val += fgetc(fichier) << 8;
val += fgetc(fichier);

return val;
}

void lecture(_module_ *rp, _module_ *rp2)
{
FILE *fichier;
fichier = fopen("param.alx", "rb");

char c[10];
unsigned int val;

direc.j1.haut = fgetc(fichier);
direc.j1.bas = fgetc(fichier);
direc.j1.gauche = fgetc(fichier);
direc.j1.droite = fgetc(fichier);
direc.j1.feu = fgetc(fichier);
direc.j2.haut = fgetc(fichier);
direc.j2.bas = fgetc(fichier);
direc.j2.gauche = fgetc(fichier);
direc.j2.droite = fgetc(fichier);
direc.j2.feu = fgetc(fichier);

val = cumul(fichier);
long_fenetre = val;

val = cumul(fichier);
larg_fenetre = val;

val = cumul(fichier);
rp->vies = rp2->vies = val; 

val = cumul(fichier);
ambiance = val;
ambiance += val << 8;
ambiance += val << 16;

fclose(fichier);
}

Dans la fonction main du fichier principal on a

module2->nbr_texture = 1;
module2->stopecl = 0;
module2->k_spac_miss = 0;

lecture(module1, module2);

// Enregistre la classe de la fenêtre
WNDCLASSEX wc = {

La structure direction est définie dans le fichier entête principal

struct clavier {
unsigned char gauche;
unsigned char droite;
unsigned char haut;
unsigned char bas;
unsigned char feu;
};

struct directions {
clavier j1;
clavier j2;
};

Téléchargez la source, cliquez ci-dessous :