764 lines
15 KiB
C
764 lines
15 KiB
C
/***************************************************************************
|
|
menu.c - description
|
|
-------------------
|
|
begin : Sat Aug 5 2000
|
|
copyright : (C) 2000 by Michael Speck
|
|
email : kulkanie@gmx.net
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program 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; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "menu.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "cfg.h"
|
|
|
|
extern Sdl sdl;
|
|
MMng mm;
|
|
extern Cfg cfg;
|
|
|
|
// menu entry //
|
|
/*
|
|
free entry
|
|
*/
|
|
void ME_Fr(void *e)
|
|
{
|
|
DL_Clr(&((MEnt*)e)->sw);
|
|
free(e);
|
|
}
|
|
|
|
/*
|
|
all entries have these init steps in common
|
|
*/
|
|
void ME_Ini(MEnt *e, int t, char *n)
|
|
{
|
|
DL_Ini(&e->sw);
|
|
e->sw.flgs = DL_NOCB | DL_AUTODEL;
|
|
e->a = 255;
|
|
strcpy(e->nm, n);
|
|
e->t = t;
|
|
e->dx = e->dy = e->dw = e->dh = 0;
|
|
e->x = e->y = 0;
|
|
e->cb = 0;
|
|
}
|
|
|
|
/*
|
|
set range
|
|
*/
|
|
void ME_StRng(MEnt* e, int *p, int min, int max, int stp)
|
|
{
|
|
e->p = p;
|
|
e->min = min;
|
|
e->max = max;
|
|
e->stp = stp;
|
|
}
|
|
|
|
/*
|
|
create an empty entry
|
|
*/
|
|
MEnt* ME_Crt()
|
|
{
|
|
MEnt *e;
|
|
e = malloc(sizeof(MEnt));
|
|
if (e == 0) {
|
|
printf("ME_Crt: Ups... not enough memory to create menu entry...\n");
|
|
exit(1);
|
|
}
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create separator
|
|
*/
|
|
MEnt* ME_CrtSep(char *s)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_SEP, s);
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create two switches group
|
|
*/
|
|
MEnt* ME_CrtSw2(char *n, int *p, char *cap1, char *cap2)
|
|
{
|
|
char *sw;
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_SWT, n);
|
|
ME_StRng(e, p, 0, 1, 1);
|
|
|
|
sw = malloc(32);
|
|
strcpy(sw, cap1);
|
|
DL_Add(&e->sw, sw);
|
|
sw = malloc(32);
|
|
strcpy(sw, cap2);
|
|
DL_Add(&e->sw, sw);
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create multi switches group
|
|
*/
|
|
MEnt* ME_CrtSwX(char *n, int *p, char **caps, int num)
|
|
{
|
|
int i;
|
|
char *sw;
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_SWT, n);
|
|
ME_StRng(e, p, 0, num - 1, 1);
|
|
|
|
for (i = 0; i < num; i++) {
|
|
sw = malloc(32);
|
|
strcpy(sw, caps[i]);
|
|
DL_Add(&e->sw, sw);
|
|
}
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create range
|
|
*/
|
|
MEnt* ME_CrtRng(char *n, int *p, int min, int max, int stp)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_RNG, n);
|
|
ME_StRng(e, p, min, max, stp);
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create action
|
|
*/
|
|
MEnt* ME_CrtAct(char *n, int a_id)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_ACT, n);
|
|
e->act = a_id;
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create an edit
|
|
min is the current length
|
|
max the max length
|
|
and p the char pointer
|
|
*/
|
|
MEnt* ME_CrtStr(char *n, char *p, int m)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_STR, n);
|
|
|
|
e->max = m;
|
|
e->min = strlen(p);
|
|
e->p = (int*)p;
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create a submenu
|
|
*/
|
|
MEnt* ME_CrtSub(char *n, void *m)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_SUB, n);
|
|
|
|
e->smn = m;
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
create a key
|
|
*/
|
|
MEnt* ME_CrtKey(char *n, int *p)
|
|
{
|
|
MEnt *e = ME_Crt();
|
|
|
|
ME_Ini(e, ME_KEY, n);
|
|
e->p = p;
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
update the string and compute size
|
|
*/
|
|
void ME_SUpd(MEnt* e)
|
|
{
|
|
char c;
|
|
switch (e->t) {
|
|
case ME_STR:
|
|
sprintf(e->str, "%s: %s", e->nm, (char*)e->p);
|
|
break;
|
|
case ME_SWT:
|
|
sprintf(e->str, "%s %s", e->nm, (char*)DL_Get(&e->sw, *e->p));
|
|
break;
|
|
case ME_RNG:
|
|
sprintf(e->str, "%s %i", e->nm, *e->p);
|
|
break;
|
|
case ME_KEY:
|
|
c = *((char*)e->p);
|
|
if (c > 32 && c < 127)
|
|
sprintf(e->str, "%s: '%c'", e->nm, c);
|
|
else
|
|
if (*e->p == 0)
|
|
sprintf(e->str, "%s: ???", e->nm);
|
|
else
|
|
switch (*e->p){
|
|
case SDLK_UP:
|
|
sprintf(e->str, "%s: Up", e->nm);
|
|
break;
|
|
case SDLK_DOWN:
|
|
sprintf(e->str, "%s: Down", e->nm);
|
|
break;
|
|
case SDLK_LEFT:
|
|
sprintf(e->str, "%s: Left", e->nm);
|
|
break;
|
|
case SDLK_RIGHT:
|
|
sprintf(e->str, "%s: Right", e->nm);
|
|
break;
|
|
case SDLK_SPACE:
|
|
sprintf(e->str, "%s: Space", e->nm);
|
|
break;
|
|
default:
|
|
sprintf(e->str, "%s: %i", e->nm, c);
|
|
}
|
|
break;
|
|
default:
|
|
strcpy(e->str, e->nm);
|
|
break;
|
|
}
|
|
|
|
e->dw = SF_TxtW(mm.ft_nml, e->str);
|
|
e->dh = mm.ft_nml->h;
|
|
e->dx = e->x - (e->dw >> 1);
|
|
e->dy = e->y - (e->dh >> 1);
|
|
}
|
|
|
|
/*
|
|
edit string
|
|
*/
|
|
void ME_Edt(MEnt *e, int c, int u)
|
|
{
|
|
if (e->t != ME_STR) return;
|
|
if (c == SDLK_BACKSPACE && e->min > 0) {
|
|
//clear last char
|
|
((char*)e->p)[--e->min] = 0;
|
|
}
|
|
else
|
|
if (c >= 32 && c < 128 && e->min < e->max) {
|
|
//letter
|
|
((char*)e->p)[e->min++] = u;
|
|
}
|
|
}
|
|
|
|
/*
|
|
change multi switches group
|
|
*/
|
|
void ME_CngSwX(MEnt *e, int *p, char **caps, int num)
|
|
{
|
|
int i;
|
|
char *sw;
|
|
|
|
DL_Clr(&e->sw);
|
|
ME_StRng(e, p, 0, num - 1, 1);
|
|
for (i = 0; i < num; i++) {
|
|
sw = malloc(32);
|
|
strcpy(sw, caps[i]);
|
|
DL_Add(&e->sw, sw);
|
|
}
|
|
*e->p = 0;
|
|
}
|
|
|
|
// menu //
|
|
/*
|
|
create an empty menu
|
|
*/
|
|
Menu* M_Crt()
|
|
{
|
|
Menu *m;
|
|
m = malloc(sizeof(Menu));
|
|
if (m == 0) {
|
|
printf("M_Crt(): Ups... not enough memory to create a menu\n");
|
|
exit(1);
|
|
}
|
|
m->c_e = 0;
|
|
DL_Ini(&m->ent);
|
|
m->ent.flgs = DL_AUTODEL;
|
|
m->ent.cb = ME_Fr;
|
|
return m;
|
|
}
|
|
|
|
/*
|
|
clear a menu
|
|
*/
|
|
void M_Fr(void *m)
|
|
{
|
|
DL_Clr(&((Menu*)m)->ent);
|
|
free(m);
|
|
}
|
|
|
|
/*
|
|
add an entry and select first entry as current
|
|
*/
|
|
void M_Add(Menu *m, MEnt *e)
|
|
{
|
|
DL_Add(&m->ent, e);
|
|
if (m->c_e == 0 && e->t != ME_SEP) {
|
|
m->c_e = e;
|
|
m->c_e->a = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
hide a menu
|
|
*/
|
|
void M_Hd(Menu *m)
|
|
{
|
|
DL_E *e = m->ent.hd.n;
|
|
MEnt *me;
|
|
|
|
while (e != &m->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
D_DST(sdl.scr, me->dx, me->dy, me->dw, me->dh);
|
|
D_SRC(mm.ss_bkgd, me->dx, me->dy);
|
|
SS_Blt();
|
|
Sdl_AddR(me->dx, me->dy, me->dw, me->dh);
|
|
e = e->n;
|
|
}
|
|
}
|
|
|
|
/*
|
|
show a menu by drawing each entry
|
|
*/
|
|
void M_Shw(Menu *m)
|
|
{
|
|
DL_E *e = m->ent.hd.n;
|
|
MEnt *me;
|
|
|
|
M_SUpd(m);
|
|
|
|
while (e != &m->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
if (me == m->c_e) {
|
|
if (me->a > 0) {
|
|
SF_Wrt(mm.ft_nml, sdl.scr, me->x, me->y, me->str, 0);
|
|
SF_Wrt(mm.ft_sel, sdl.scr, me->x, me->y, me->str, (int)me->a);
|
|
}
|
|
else
|
|
SF_Wrt(mm.ft_sel, sdl.scr, me->x, me->y, me->str, 0);
|
|
}
|
|
else {
|
|
SF_Wrt(mm.ft_nml, sdl.scr, me->x, me->y, me->str, 0);
|
|
if (me->a < 255)
|
|
SF_Wrt(mm.ft_sel, sdl.scr, me->x, me->y, me->str, (int)me->a);
|
|
}
|
|
Sdl_AddR(me->dx, me->dy, me->dw, me->dh);
|
|
e = e->n;
|
|
}
|
|
}
|
|
|
|
/*
|
|
do an ME_SUpd() for all entries
|
|
*/
|
|
void M_SUpd(Menu *m)
|
|
{
|
|
DL_E *e = m->ent.hd.n;
|
|
|
|
while (e != &m->ent.tl) {
|
|
ME_SUpd((MEnt*)e->d);
|
|
e = e->n;
|
|
}
|
|
}
|
|
|
|
/*
|
|
compute new alpha value for all entries
|
|
*/
|
|
void M_CmA(Menu *m, int ms)
|
|
{
|
|
DL_E *e = m->ent.hd.n;
|
|
MEnt *me;
|
|
|
|
while (e != &m->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
if (me->a < 255 && me != m->c_e) {
|
|
me->a += mm.a_c * ms;
|
|
if (me->a > 255)
|
|
me->a = 255;
|
|
}
|
|
e = e->n;
|
|
}
|
|
}
|
|
|
|
// menu manager //
|
|
/*
|
|
initialize graphics, menu and positions of menu and logo
|
|
*/
|
|
void MM_Ini(int x, int y, int ly, SDL_Surface *ss_bk, SDL_Surface *ss_lg, SFnt *fn, SFnt *fs)
|
|
{
|
|
mm.ss_bkgd = ss_bk;
|
|
mm.ss_logo = ss_lg;
|
|
mm.ft_nml = fn;
|
|
mm.ft_sel = fs;
|
|
mm.ft_nml->algn = mm.ft_sel->algn = TA_X_C | TA_Y_C;
|
|
mm.x = x;
|
|
mm.y = y;
|
|
mm.ly = ly;
|
|
mm.lx = (ss_bk->w - ss_lg->w) / 2;
|
|
DL_Ini(&mm.mn);
|
|
mm.mn.flgs = DL_AUTODEL;
|
|
mm.mn.cb = M_Fr;
|
|
mm.c_mn = 0;
|
|
mm.a_c = 0.28;
|
|
#ifdef SOUND
|
|
mm.s_clk = sound_chunk_load("click.wav");
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
show the menu
|
|
sets a new video mode if wanted
|
|
*/
|
|
void MM_Shw(int rsz)
|
|
{
|
|
if (rsz)
|
|
Sdl_StVdMd(mm.ss_bkgd->w, mm.ss_bkgd->h, 16, SDL_SWSURFACE);
|
|
D_FDST(sdl.scr);
|
|
D_FSRC(mm.ss_bkgd);
|
|
SS_Blt();
|
|
D_DST(sdl.scr, mm.lx, mm.ly, mm.ss_logo->w, mm.ss_logo->h);
|
|
D_SRC(mm.ss_logo, 0, 0);
|
|
SS_Blt();
|
|
if (cfg.dim)
|
|
SDL_UNDIM();
|
|
else
|
|
Sdl_FUpd();
|
|
if (mm.c_mn == 0 || mm.c_mn->ent.cntr == 0) {
|
|
fprintf(stderr, "MM_Shw(): Ups... no current or empty menu defined!\n");
|
|
exit(1);
|
|
}
|
|
mm.c_mn->c_e->a = 0;
|
|
M_Shw(mm.c_mn);
|
|
Sdl_UpdR();
|
|
}
|
|
|
|
/*
|
|
free memory used
|
|
*/
|
|
void MM_Trm()
|
|
{
|
|
if (mm.ss_bkgd) SDL_FreeSurface(mm.ss_bkgd);
|
|
if (mm.ss_logo) SDL_FreeSurface(mm.ss_logo);
|
|
if (mm.ft_nml) SF_Fr(mm.ft_nml);
|
|
if (mm.ft_sel) SF_Fr(mm.ft_sel);
|
|
DL_Clr(&mm.mn);
|
|
#ifdef SOUND
|
|
if (mm.s_clk) sound_chunk_free(&mm.s_clk);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
add a menu
|
|
*/
|
|
void MM_Add(Menu *m)
|
|
{
|
|
DL_Add(&mm.mn, m);
|
|
if (mm.mn.cntr == 1)
|
|
mm.c_mn = m;
|
|
}
|
|
|
|
/*
|
|
adjust position of all entries in all menus relative to mm.x | mm.y as centre
|
|
*/
|
|
void MM_AdjP()
|
|
{
|
|
DL_E *m = mm.mn.hd.n;
|
|
DL_E *e;
|
|
MEnt *me;
|
|
int i;
|
|
|
|
while (m != &mm.mn.tl) {
|
|
e = ((Menu*)m->d)->ent.hd.n;
|
|
i = 0;
|
|
while (e != &((Menu*)m->d)->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
me->x = mm.x;
|
|
me->y = (mm.y - (((Menu*)m->d)->ent.cntr * mm.ft_nml->h) / 2) + i * mm.ft_nml->h + mm.ft_nml->h / 2;
|
|
i++;
|
|
e = e->n;
|
|
}
|
|
m = m->n;
|
|
}
|
|
}
|
|
|
|
/*
|
|
allow default keys: alphanumerical and arrows
|
|
*/
|
|
void MM_DfVKys()
|
|
{
|
|
int i;
|
|
memset(mm.vkys, 0, sizeof(mm.vkys));
|
|
for (i = 32; i < 128; i++)
|
|
mm.vkys[i] = 1;
|
|
mm.vkys[SDLK_UP] = 1;
|
|
mm.vkys[SDLK_DOWN] = 1;
|
|
mm.vkys[SDLK_RIGHT] = 1;
|
|
mm.vkys[SDLK_LEFT] = 1;
|
|
mm.vkys[SDLK_p] = 0;
|
|
mm.vkys[SDLK_f] = 0;
|
|
mm.vkys[SDLK_r] = 0;
|
|
}
|
|
|
|
/*
|
|
checks if all menus contain at least one entry
|
|
and if every menu has an current entry selected
|
|
|
|
stuff like submenu in an entry is not checked
|
|
*/
|
|
void MM_Ck()
|
|
{
|
|
#ifdef DEBUG
|
|
DL_E *e = mm.mn.hd.n;
|
|
Menu *m;
|
|
|
|
printf("checking menu... ");
|
|
|
|
// no menu at all? //
|
|
if (mm.mn.cntr == 0) {
|
|
printf("NOT ONE MENU FOUND!\n");
|
|
exit(1);
|
|
}
|
|
if (mm.c_mn == 0) {
|
|
printf("NO CURRENT MENU SELECTED!\n");
|
|
exit(1);
|
|
}
|
|
|
|
while (e != &mm.mn.tl) {
|
|
m = (Menu*)e->d;
|
|
if (m->ent.cntr == 0) {
|
|
printf("YOU'VE ADDED AN EMPTY MENU!\n");
|
|
exit(1);
|
|
}
|
|
if (m->c_e == 0) {
|
|
printf("NO CURRENT ENTRY SELECTED!\n");
|
|
exit(1);
|
|
}
|
|
e = e->n;
|
|
}
|
|
printf("OK\n");
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
process incoming events
|
|
*/
|
|
int MM_Evt(SDL_Event *e)
|
|
{
|
|
DL_E *m, *le;
|
|
MEnt *me;
|
|
int ex = 0;
|
|
|
|
// waiting for a key ? //
|
|
if (mm.c_mn->c_e->t == ME_KEY && *mm.c_mn->c_e->p == 0) {
|
|
if (e->type == SDL_KEYUP && mm.vkys[e->key.keysym.sym]) {
|
|
// check other key entries for their value //
|
|
m = mm.mn.hd.n;
|
|
while (!ex && m != &mm.mn.tl) {
|
|
le = ((Menu*)m->d)->ent.hd.n;
|
|
while (!ex && le != &((Menu*)m->d)->ent.tl) {
|
|
me = (MEnt*)le->d;
|
|
if (me->t == ME_KEY && *me->p == e->key.keysym.sym)
|
|
ex = 1;
|
|
le = le->n;
|
|
}
|
|
m = m->n;
|
|
}
|
|
// set key
|
|
if (!ex) {
|
|
*mm.c_mn->c_e->p = e->key.keysym.sym;
|
|
if (mm.c_mn->c_e->cb != 0)
|
|
mm.c_mn->c_e->cb();
|
|
}
|
|
}
|
|
return MM_NONE;
|
|
}
|
|
// normal event
|
|
switch (e->type) {
|
|
case SDL_MOUSEMOTION:
|
|
return MM_SelE(e->motion.x, e->motion.y);
|
|
case SDL_MOUSEBUTTONUP:
|
|
if (e->button.button == 1)
|
|
return MM_UseE(MM_INC);
|
|
else
|
|
return MM_UseE(MM_DEC);
|
|
case SDL_KEYDOWN:
|
|
switch (e->key.keysym.sym) {
|
|
case SDLK_RETURN:
|
|
return MM_UseE(MM_NONE);
|
|
case SDLK_UP:
|
|
return MM_PrvE();
|
|
case SDLK_DOWN:
|
|
return MM_NxtE();
|
|
case SDLK_LEFT:
|
|
return MM_UseE(MM_DEC);
|
|
case SDLK_RIGHT:
|
|
return MM_UseE(MM_INC);
|
|
default:
|
|
if (mm.c_mn->c_e->t == ME_STR)
|
|
ME_Edt(mm.c_mn->c_e, e->key.keysym.sym, e->key.keysym.unicode);
|
|
return MM_NONE;
|
|
}
|
|
return MM_NONE;
|
|
}
|
|
return MM_NONE;
|
|
}
|
|
|
|
/*
|
|
use an entry
|
|
submenu: set submenu
|
|
action: return action
|
|
range: change pos due to c (inc or dec)
|
|
str: add or delete char
|
|
*/
|
|
int MM_UseE(int c)
|
|
{
|
|
MEnt *me = mm.c_mn->c_e;
|
|
switch (me->t) {
|
|
case ME_SUB:
|
|
#ifdef SOUND
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
if (mm.c_mn->c_e->cb != 0)
|
|
mm.c_mn->c_e->cb();
|
|
mm.c_mn = (Menu*)me->smn;
|
|
break;
|
|
case ME_ACT:
|
|
#ifdef SOUND
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
if (mm.c_mn->c_e->cb != 0)
|
|
mm.c_mn->c_e->cb();
|
|
return me->act;
|
|
case ME_SWT:
|
|
case ME_RNG:
|
|
#ifdef SOUND
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
if (c == MM_DEC) {
|
|
*me->p -= me->stp;
|
|
if (*me->p < me->min)
|
|
*me->p = me->max - ((me->max - me->min) % me->stp);
|
|
}
|
|
else
|
|
if (c == MM_INC) {
|
|
*me->p += me->stp;
|
|
if (*me->p > me->max)
|
|
*me->p = me->min;
|
|
}
|
|
if (mm.c_mn->c_e->cb != 0)
|
|
mm.c_mn->c_e->cb();
|
|
break;
|
|
case ME_KEY:
|
|
*me->p = 0;
|
|
if (mm.c_mn->c_e->cb != 0)
|
|
mm.c_mn->c_e->cb();
|
|
break;
|
|
}
|
|
return MM_NONE;
|
|
}
|
|
|
|
/*
|
|
select prev entry
|
|
*/
|
|
int MM_PrvE()
|
|
{
|
|
DL_E *e = DL_GetE(&mm.c_mn->ent, mm.c_mn->c_e)->p;
|
|
|
|
while (e != &mm.c_mn->ent.hd && ((MEnt*)e->d)->t == ME_SEP) e = e->p;
|
|
if (e != &mm.c_mn->ent.hd) {
|
|
mm.c_mn->c_e = (MEnt*)e->d;
|
|
mm.c_mn->c_e->a = 0;
|
|
}
|
|
|
|
#ifdef SOUND
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
return MM_NONE;
|
|
}
|
|
|
|
/*
|
|
select next entry
|
|
*/
|
|
int MM_NxtE()
|
|
{
|
|
DL_E *e = DL_GetE(&mm.c_mn->ent, mm.c_mn->c_e)->n;
|
|
|
|
while (e != &mm.c_mn->ent.tl && ((MEnt*)e->d)->t == ME_SEP) e = e->n;
|
|
if (e != &mm.c_mn->ent.tl) {
|
|
mm.c_mn->c_e = (MEnt*)e->d;
|
|
mm.c_mn->c_e->a = 0;
|
|
}
|
|
|
|
#ifdef SOUND
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
return MM_NONE;
|
|
}
|
|
|
|
/*
|
|
select an entry at pos x,y if valid
|
|
*/
|
|
int MM_SelE(int x, int y)
|
|
{
|
|
DL_E *e = mm.c_mn->ent.hd.n;
|
|
MEnt *me, *old = mm.c_mn->c_e;
|
|
|
|
while (e != &mm.c_mn->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
if (me->t != ME_SEP && x >= me->dx && x < me->dx + me->dw && y >= me->dy && y < me->dy + me->dh) {
|
|
mm.c_mn->c_e = me;
|
|
mm.c_mn->c_e->a = 0;
|
|
#ifdef SOUND
|
|
if (mm.c_mn->c_e != old)
|
|
sound_play(mm.s_clk);
|
|
#endif
|
|
return MM_NONE;
|
|
}
|
|
e = e->n;
|
|
}
|
|
return MM_NONE;
|
|
}
|
|
|
|
void MM_CB()
|
|
{
|
|
DL_E *e = mm.c_mn->ent.hd.n;
|
|
MEnt *me;
|
|
|
|
while (e != &mm.c_mn->ent.tl) {
|
|
me = (MEnt*)e->d;
|
|
if (me->cb != 0)
|
|
me->cb();
|
|
e = e->n;
|
|
}
|
|
}
|