summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Gayot <duskcoder@gmail.com>2015-01-08 15:04:26 +0100
committerOlivier Gayot <duskcoder@gmail.com>2015-01-08 15:37:48 +0100
commit1f9c71b49eeef9cd05b542515c06200b4a25f693 (patch)
tree6a29ab8af1ae447236013cbd78e5089937b72b1f
parentadceeb1192fdd1d14e0f55219bbd1bcb14eacc05 (diff)
use a generic way to navigate through entries
entries are actually any action or subaction that can be performed. Attack, White Magic and so on are root actions. Fire, Ice X are subactions of Black Magic. Signed-off-by: Olivier Gayot <duskcoder@gmail.com>
-rw-r--r--actions.c25
-rw-r--r--blits.c40
-rw-r--r--entry.h30
-rw-r--r--jouer.c129
-rw-r--r--magies.c10
-rw-r--r--priv_entries.h137
-rw-r--r--prototypes.h12
-rw-r--r--structures.h2
8 files changed, 311 insertions, 74 deletions
diff --git a/actions.c b/actions.c
index 096fba9..cb0d8ea 100644
--- a/actions.c
+++ b/actions.c
@@ -5,7 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
-enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy)
+enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data)
{
int degats;
struct character_t *target;
@@ -13,6 +13,9 @@ enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct te
int selection = 0;
SDL_Event event;
SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions);
+
+ (void) data;
+
while(!enemy->chrs[selection].alive)
selection++;
update_selected_target(surfaces, positions, &enemy->chrs[selection]);
@@ -150,7 +153,7 @@ enum action_state_t Fselectionnermagienoire(SURFACES *surfaces,POSITIONS *positi
case SDLK_RETURN:
SDL_BlitSurface(surfaces->Pfondjeu,&positions->Vpositiondegats,surfaces->Pecran,&positions->Vpositiondegats);
SDL_Flip(surfaces->Pecran);
- ret = Fmagieelement(surfaces,positions, ally, enemy, selection);
+ ret = Fmagieelement(surfaces,positions, ally, enemy, (enum element_t []) {selection});
if (ret == ACTION_PERFORMED) {
continuer = 0;
@@ -211,7 +214,7 @@ enum action_state_t Fselectionnermagieblanche(SURFACES *surfaces,POSITIONS *posi
SDL_BlitSurface(surfaces->Pfondjeu,&positions->Vpositiondegats,surfaces->Pecran,&positions->Vpositiondegats);
SDL_Flip(surfaces->Pecran);
if(selection==SOIN)
- ret = Fmagiesoin(surfaces,positions, ally, enemy);
+ ret = Fmagiesoin(surfaces,positions, ally, enemy, NULL);
if (ret == ACTION_PERFORMED) {
continuer = 0;
@@ -273,17 +276,17 @@ enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions,
if(page==0)
{
if(selection==POTION)
- ret = Fpotion(surfaces,positions, ally, enemy, selection);
+ ret = Fpotion(surfaces,positions, ally, enemy, (int []) {selection});
else if(selection==ETHER)
- ret = Fether(surfaces,positions, ally, enemy, selection);
+ ret = Fether(surfaces,positions, ally, enemy, (int []) {selection});
else if(selection==POTIONPLUS)
- ret = Fpotion(surfaces,positions, ally, enemy, selection);
+ ret = Fpotion(surfaces,positions, ally, enemy, (int []) { selection});
}
else if(page==1)
{
if(selection==ETHERPLUS)
- ret = Fether(surfaces,positions, ally, enemy, selection);
+ ret = Fether(surfaces,positions, ally, enemy, (int []) { selection});
}
if (ret == ACTION_PERFORMED) {
@@ -300,7 +303,7 @@ enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions,
return ret;
}
-enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type)
+enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data)
{
struct character_t *target;
SDL_Event event;
@@ -308,6 +311,8 @@ enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team
int soins=0;
int clan=ALLIE;
+ int type = *((int *)data);
+
if (type == POTION && ally->objects.potions <= 0)
return ACTION_ERROR;
else if(type == POTIONPLUS && ally->objects.potionsplus <= 0)
@@ -365,7 +370,7 @@ enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team
}
}
-enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type)
+enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data)
{
struct character_t *target;
SDL_Event event;
@@ -373,6 +378,8 @@ enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_
int soins=0;
int clan=ALLIE;
+ int type = *((int *)data);
+
if (type == ETHER && ally->objects.ethers <= 0)
return ACTION_ERROR;
else if (type == ETHERPLUS && ally->objects.ethersplus <= 0)
diff --git a/blits.c b/blits.c
index 318e72f..2eb49d4 100644
--- a/blits.c
+++ b/blits.c
@@ -152,6 +152,46 @@ void Fchangercurseurpersos (SURFACES *surfaces, POSITIONS *positions, struct cha
TTF_CloseFont(police);
}
+void update_list_entries(SURFACES *surfaces, POSITIONS *positions, const struct entry_t *entries, int cnt, int selected)
+{
+ SDL_Color color = {0, 0, 0, 0};
+ TTF_Font *font;
+ SDL_Surface *surf;
+ int off;
+
+ if (selected == -1) {
+ SDL_BlitSurface(surfaces->Pfondjeu, &positions->Vpositioncadreactions, surfaces->Pecran, &positions->Vpositioncadreactions);
+ SDL_Flip(surfaces->Pecran);
+ return;
+ }
+
+ SDL_BlitSurface(surfaces->Pcadreactions, NULL, surfaces->Pecran, &positions->Vpositioncadreactions);
+
+ font = TTF_OpenFont("TIMESBI.TTF", 20);
+ off = selected / 3 * 3;
+ /* display at most three actions */
+ for (int i = 0; i < 3; ++i) {
+ if (off + i >= cnt) {
+ SDL_BlitSurface(surfaces->Pactiondesactivee, NULL, surfaces->Pecran, &positions->Vpositionactionselectionnee[i]);
+ continue;
+ }
+
+ /* if the current entry is the selected one */
+ if (selected == off + i) {
+ SDL_BlitSurface(surfaces->Pactionselectionnee, NULL, surfaces->Pecran, &positions->Vpositionactionselectionnee[i]);
+ }
+
+ surf = TTF_RenderText_Blended(font, entries[off + i].name, color);
+
+ SDL_BlitSurface(surf, NULL, surfaces->Pecran, &positions->Vpositionnomactions[i]);
+
+ SDL_FreeSurface(surf);
+ }
+
+ TTF_CloseFont(font);
+ SDL_Flip(surfaces->Pecran);
+}
+
void Fchangeractionselectionnee(SURFACES *surfaces, POSITIONS *positions,int selection,int page,int nbactions,int type)
{
int i;
diff --git a/entry.h b/entry.h
new file mode 100644
index 0000000..00b58e9
--- /dev/null
+++ b/entry.h
@@ -0,0 +1,30 @@
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include "structures.h"
+#include "players.h"
+
+struct entry_t {
+ /* displayed name */
+ char *name;
+ int children_cnt;
+
+ union {
+ struct entry_t *children;
+
+ struct {
+ void *data;
+ enum action_state_t (*f)(SURFACES *, POSITIONS *, struct team_t *, struct team_t *, void *data);
+ };
+ };
+};
+
+struct action_params_t {
+ SURFACES *surfaces;
+ POSITIONS *positions;
+
+ struct team_t *t1;
+ struct team_t *t2;
+};
+
+#endif /* ENTRY_H */
diff --git a/jouer.c b/jouer.c
index 04e7188..1d14e0f 100644
--- a/jouer.c
+++ b/jouer.c
@@ -5,6 +5,8 @@
#include "constantes.h"
#include "prototypes.h"
+#include "priv_entries.h"
+
static inline void highlight_current_character(struct team_t *team)
{
struct character_t *chr = &team->chrs[team->chr_cur];
@@ -61,19 +63,62 @@ static void update_current_character(struct team_t *ally, bool *ally_turn)
}
}
+enum action_state_t dig_entry(const struct entry_t *entries, int cnt_entries, struct action_params_t *params)
+{
+ SDL_Event event;
+ const struct entry_t *target;
+ int selection = 0;
+
+ update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection);
+
+ for (;;) {
+ SDL_WaitEvent(&event);
+
+ if (event.type != SDL_KEYDOWN)
+ continue;
+
+ switch (event.key.keysym.sym) {
+ case SDLK_a:
+ case SDLK_ESCAPE:
+ update_list_entries(params->surfaces, params->positions, NULL, 0, -1);
+ return ACTION_CANCELED;
+ case SDLK_k:
+ case SDLK_UP:
+ selection = (selection > 0) ? selection - 1 : cnt_entries - 1;
+ update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection);
+ break;
+ case SDLK_j:
+ case SDLK_DOWN:
+ selection = (selection < cnt_entries - 1) ? selection + 1 : 0;
+ update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection);
+ break;
+ case SDLK_f:
+ case SDLK_RETURN:
+ target = &entries[selection];
+ if (!target->children_cnt) {
+ return target->f(params->surfaces, params->positions, params->t1, params->t2, target->data);
+ }
+
+ if (dig_entry(target->children, target->children_cnt, params) == ACTION_PERFORMED)
+ return ACTION_PERFORMED;
+
+ update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection);
+ default:
+ break;
+ }
+ }
+}
+
int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struct team_t *enemy)
{
unsigned int continuer=1;
- int selection=0;
int i;
- SDL_Event event;
int Vtourennemi=0;
int Vtour;
int Vnbennemis=0;
- int page=0;
- int nbactions=5;
unsigned int gagne,perdu;
+
if(surfaces->Pfondjeu!=NULL)
{
SDL_FreeSurface(surfaces->Pfondjeu);
@@ -94,10 +139,22 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc
blit_team(surfaces, ally);
blit_team(surfaces, enemy);
+ SDL_Flip(surfaces->Pecran);
+
while (continuer)
{
if(Vtour==ALLIE) //si un player joue
{
+ struct action_params_t params = {
+ .surfaces = surfaces,
+ .positions = positions,
+
+ .t1 = ally,
+ .t2 = enemy,
+ };
+
+ enum action_state_t state;
+
while (!ally->chrs[ally->chr_cur].alive) //si le perso selectionné est mort
{
if (ally->chr_cur < ally->chr_cnt) // si ce n'est pas le dernier
@@ -105,62 +162,18 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc
else // sinon si c'est le dernier
ally->chr_cur = 0; // on reprend le 1er
}
- Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS);
- SDL_WaitEvent(&event);
- switch(event.type)
- {
- case SDL_KEYDOWN:
- switch(event.key.keysym.unicode)
- {
- case SDLK_ESCAPE:
- case SDLK_a:
- continuer=0;
- break;
- }
- switch (event.key.keysym.sym)
- {
- case SDLK_UP:
- case SDLK_k:
- if (selection!=0)
- selection--;
- else
- selection=nbactions-1;
- page=selection/3;
- Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS);
- break;
- case SDLK_DOWN:
- case SDLK_j:
- if (selection!=nbactions-1)
- selection++;
- else
- selection=0;
- page=selection/3;
- Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS);
+
+ state = dig_entry(action_entries_g, countof(action_entries_g), &params);
+ switch (state) {
+ case ACTION_CANCELED:
+ continuer = 0;
break;
- case SDLK_RETURN:
- case SDLK_f:
- {
- enum action_state_t (*actionp)(SURFACES *, POSITIONS *, struct team_t *ally, struct team_t *enemy) = NULL;
-
- switch (selection) {
- case ATTAQUE: actionp = Fattaquer; break;
- case MAGIE_BLANCHE: actionp = Fselectionnermagieblanche; break;
- case MAGIE_NOIRE: actionp = Fselectionnermagienoire; break;
- case TECHNIQUES: break;
- case OBJETS: actionp = Fselectionnerobjet; break;
- default: abort(); break;
- }
-
- if (actionp && (*actionp)(surfaces,positions, ally, enemy) == ACTION_PERFORMED) {
- update_current_character(ally, (bool *)&Vtour);
- blit_team(surfaces, ally);
- }
- }
+ case ACTION_PERFORMED:
+ update_current_character(ally, (bool *)&Vtour);
+ blit_team(surfaces, ally);
break;
- default:
+ default:
break;
- }
- break;
}
}
else if(Vtour==ENNEMI) // sinon si c'est le cpu qui joue
@@ -172,7 +185,7 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc
Vtourennemi = 0;
}
}
-/* TODO reactivate */
+ /* TODO reactivate */
#if 0
Factionennemi(&Vtourennemi,surfaces,positions,ennemis,persos,Vnbennemis,&Vtour,Vtourallie);
#else
diff --git a/magies.c b/magies.c
index 3740c84..94183e7 100644
--- a/magies.c
+++ b/magies.c
@@ -5,7 +5,7 @@
#include "constantes.h"
#include "prototypes.h"
-enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, enum element_t element)
+enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data)
{
struct character_t *target;
int degats;
@@ -13,6 +13,9 @@ enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, stru
int clan=ENNEMI;
SDL_Event event;
SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions);
+
+ enum element_t element = *((enum element_t *)data);
+
while (!enemy->chrs[selection].alive)
selection++;
update_selected_target(surfaces,positions, &enemy->chrs[selection]);
@@ -61,13 +64,16 @@ enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, stru
}
}
-enum action_state_t Fmagiesoin(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy)
+enum action_state_t Fmagiesoin(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data)
{
struct character_t *target;
SDL_Event event;
int soins;
int clan=ALLIE;
int selection=0;
+
+ (void) data;
+
SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions);
while(!ally->chrs[selection].alive)
selection++;
diff --git a/priv_entries.h b/priv_entries.h
new file mode 100644
index 0000000..c2fa5c6
--- /dev/null
+++ b/priv_entries.h
@@ -0,0 +1,137 @@
+#ifndef PRIV_ENTRIES_H
+#define PRIV_ENTRIES_H
+
+#include "prototypes.h"
+#include "entry.h"
+
+/* TODO general make difference between action / action + and action x */
+
+struct entry_t white_magic_entries[] = {
+ {
+ .name = "Cure",
+ .children_cnt = 0,
+ .f = Fattaquer,
+ .data = NULL,
+ }, {
+ .name = "Cure +",
+ .children_cnt = 0,
+ .f = Fattaquer,
+ .data = NULL,
+ },
+};
+
+struct entry_t black_magic_entries[] = {
+ {
+ .name = "Fire",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_FIRE },
+ }, {
+ .name = "Fire +",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_FIRE },
+ }, {
+ .name = "Fire x",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_FIRE },
+ }, {
+ .name = "Ice -",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_ICE },
+ }, {
+ .name = "Ice +",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_ICE },
+ }, {
+ .name = "Ice x",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_ICE },
+ }, {
+ .name = "Thunder",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_THUNDER },
+ }, {
+ .name = "Thunder +",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_THUNDER },
+ }, {
+ .name = "Thunder x",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_THUNDER },
+ }, {
+ .name = "Water",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_WATER },
+ }, {
+ .name = "Water + ",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_WATER },
+ }, {
+ .name = "Water x",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_WATER },
+ }, {
+ .name = "Choc",
+ .children_cnt = 0,
+ .f = Fmagieelement,
+ .data = (enum element_t []) { ELEMENT_NONE },
+ },
+};
+
+struct entry_t object_entries[] = {
+ {
+ .name = "Potion",
+ .children_cnt = 0,
+ .f = Fpotion,
+ .data = (int []) { POTION },
+ }, {
+ .name = "Potion +",
+ .children_cnt = 0,
+ .f = Fpotion,
+ .data = (int []) { POTIONPLUS },
+ }, {
+ .name = "Ether",
+ .children_cnt = 0,
+ .f = Fether,
+ .data = (int []) { ETHER },
+ }, {
+ .name = "Ether + ",
+ .children_cnt = 0,
+ .f = Fether,
+ .data = (int []) { ETHERPLUS },
+ },
+};
+
+struct entry_t action_entries_g[] = {
+ {
+ .name = "Attack",
+ .children_cnt = 0,
+ .f = Fattaquer,
+ .data = NULL,
+ }, {
+ .name = "White Magic",
+ .children = white_magic_entries,
+ .children_cnt = countof(white_magic_entries),
+ }, {
+ .name = "Black Magic",
+ .children = black_magic_entries,
+ .children_cnt = countof(black_magic_entries),
+ }, {
+ .name = "Use",
+ .children = object_entries,
+ .children_cnt = countof(object_entries),
+ },
+};
+
+#endif /* PRIV_ENTRIES_H */
diff --git a/prototypes.h b/prototypes.h
index d377fdf..a33c4ea 100644
--- a/prototypes.h
+++ b/prototypes.h
@@ -3,6 +3,7 @@
#include "constantes.h"
#include "players.h"
+#include "entry.h"
void Fmenuprincipal (SURFACES *surfaces, POSITIONS *positions);
void Fchangersurlignage (int Vmode, SURFACES *surfaces, POSITIONS *positions);
@@ -19,14 +20,14 @@ void Fdechargerimages (SURFACES *surfaces);
void Finitialiserpositions (POSITIONS *positions, SURFACES *surfaces);
/* actions */
-enum action_state_t Fattaquer (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy);
+enum action_state_t Fattaquer (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data);
enum action_state_t Fselectionnermagienoire (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy);
enum action_state_t Fselectionnermagieblanche(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy);
enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy);
-enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, enum element_t);
-enum action_state_t Fmagiesoin (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy);
-enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type);
-enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type);
+enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data);
+enum action_state_t Fmagiesoin (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data);
+enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data);
+enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data);
int compute_damages(const struct character_t *src, const struct character_t *target, enum damages_type_t, enum element_t);
int compute_cure(const struct character_t *src, const struct character_t *target);
@@ -40,6 +41,7 @@ void cure_target_mp(SURFACES *surfaces, POSITIONS *, struct character_t *target,
void update_selected_target(SURFACES *surfaces, POSITIONS *positions, struct character_t *);
void Fblitteractivedesactive (SURFACES *surfaces,POSITIONS *positions,ENNEMIS ennemis[],int selection);
void blit_character_affinities(SURFACES *, POSITIONS *, const struct character_t *);
+void update_list_entries(SURFACES *surfaces, POSITIONS *positions, const struct entry_t *entries, int cnt, int selected);
void Fchangeractionselectionnee(SURFACES *surfaces, POSITIONS *positions,int selection,int page,int nbactions,int type);
void Fblitterpvcible (SURFACES *surfaces,POSITIONS *positions, const struct character_t *);
void Fblitterpmcible (SURFACES *surfaces,POSITIONS *positions, const struct character_t *);
diff --git a/structures.h b/structures.h
index 11a0f76..fa7e5c0 100644
--- a/structures.h
+++ b/structures.h
@@ -1,6 +1,8 @@
#ifndef STRUCTURES_H
#define STRUCTURES_H
+#include <SDL/SDL.h>
+
typedef struct surfaces SURFACES;
struct surfaces
{