Files
commandergenius/project/jni/application/lmarbles-1.0.8/src/main.c
2010-12-24 12:05:03 +00:00

540 lines
13 KiB
C

/***************************************************************************
main.c - description
-------------------
begin : Sam Aug 5 12:36:32 MEST 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. *
* *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef _WIN32
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "menu.h"
#include "cfg.h"
#include "levels.h"
#include "timer.h"
#include "sdl.h"
#include "audio.h"
#include "profile.h"
#include "game.h"
// timer -- timer.c //
extern struct timeb t_c, t_lc;
// quit game quickly ? //
int trm_gm = 0;
// menu config -- cfg.c //
extern Cfg cfg;
// menu manager -- menu.c //
extern MMng mm;
// sdl struct //
extern Sdl sdl;
// levelset list and number of entries -- levels.c //
extern char **ls_lst;
extern int ls_n;
// profiles //
extern DLst prfs;
// string list for the menu -- profile.c //
extern char **prf_lst;
extern int prf_n;
// menu entry containing the profile list //
MEnt *me_prf, *me_del, *me_clr;
// menu actions MUST BE GREATER THAN 0 //
#define MA_NONE 0
#define MA_QUT 1
#define MA_PLY 2
#define MA_HSC 3
/*
====================================================================
Clear the SDL event key (keydown events)
====================================================================
*/
int all_filter( const SDL_Event *event )
{
return 0;
}
void event_clear_sdl_queue()
{
SDL_Event event;
SDL_SetEventFilter( all_filter );
while ( SDL_PollEvent( &event ) );
SDL_SetEventFilter( 0 );
}
/*
previously defined hiscore.h but this file no longer needed
*/
typedef struct {
char nm[12];
int lvl;
int lvs;
int scr;
int pct;
} H_E;
/*
show hiscore and highlight rank r
*/
void H_Shw()
{
int i, j;
SDL_Surface *buf = 0;
SFnt *ft;
Prf *p;
int e_h = mm.ft_nml->h + 2;
int off = 50;
int a_y = 100;
char str[12];
int e_num = prfs.cntr > 10 ? 10 : prfs.cntr;
H_E hscr[e_num];
DL_E *e;
// save screen //
buf = SS_Crt(sdl.scr->w, sdl.scr->h, SDL_SWSURFACE);
D_FDST(buf);
D_FSRC(sdl.scr);
SS_Blt();
// darken screen //
if (cfg.dim)
SDL_DIM();
// draw background //
D_FDST(sdl.scr);
D_FSRC(mm.ss_bkgd);
SS_Blt();
// brighten screen //
if (cfg.dim)
SDL_UNDIM();
else
Sdl_FUpd();
// create highscore list //
memset(hscr, 0, sizeof(hscr));
e = prfs.hd.n;
while (e != &prfs.tl) {
p = (Prf*)e->d;
for (i = 0; i < e_num; i++)
if (p->scr >= hscr[i].scr) {
for (j = e_num - 1; j > i; j--)
hscr[j] = hscr[j - 1];
hscr[i].scr = p->scr;
hscr[i].pct = p->pct;
hscr[i].lvl = p->lvls;
strcpy(hscr[i].nm, p->nm);
break;
}
e = e->n;
}
// write hiscores //
SF_Wrt(mm.ft_nml, sdl.scr, sdl.scr->w / 2, 50, "Best Profiles", 0);
mm.ft_nml->algn = mm.ft_sel->algn = TA_X_L | TA_Y_T;
for (i = 0; i < e_num; i++) {
if (0) // changed later
ft = mm.ft_sel;
else
ft = mm.ft_nml;
ft->algn = TA_X_L | TA_Y_T;
SF_Wrt(ft, sdl.scr, off, a_y + i * e_h, hscr[i].nm, 0);
ft->algn = TA_X_C | TA_Y_T;
sprintf(str, "%i", hscr[i].lvl);
SF_Wrt(ft, sdl.scr, sdl.scr->w / 2, a_y + i * e_h, str, 0);
sprintf(str, "%i", hscr[i].scr);
// sprintf(str, "%i (%i.%i%%)", hscr[i].scr, hscr[i].pct / 10, hscr[i].pct % 10);
ft->algn = TA_X_R | TA_Y_T;
SF_Wrt(ft, sdl.scr, sdl.scr->w - off, a_y + i * e_h, str, 0);
}
mm.ft_nml->algn = mm.ft_sel->algn = TA_X_C | TA_Y_C;
Sdl_FUpd();
// wait for a click //
Sdl_WtFrClk();
//darken screen //
if (cfg.dim)
SDL_DIM();
// restore screen //
D_FDST(sdl.scr);
D_FSRC(buf);
SS_Blt();
// brighten screen //
if (cfg.dim)
SDL_UNDIM();
else
Sdl_FUpd();
// reset timer //
T_Rst();
}
// menu callbacks //
/*
activate / deactivate sound
*/
void CB_Snd()
{
#ifdef SOUND
sound_enable(cfg.s_on);
#endif
}
/*
set sound volume
*/
void CB_StV()
{
#ifdef SOUND
sound_volume(cfg.s_vol * 16);
#endif
}
/*
create a profile
*/
void CB_CrtP()
{
Prf_Crt(cfg.prf_nm);
Prf_CrtLst();
// update menu entries //
ME_CngSwX(me_prf, &cfg.prf, prf_lst, prf_n);
ME_CngSwX(me_del, &cfg.prf, prf_lst, prf_n);
ME_CngSwX(me_clr, &cfg.prf, prf_lst, prf_n);
}
/*
clear a profile
*/
void CB_ClrP()
{
Prf *p = DL_Get(&prfs, cfg.prf);
DL_Clr(&p->sts);
p->lvls = 0;
p->scr = 0;
p->pct = 0;
}
/*
delete a profile
*/
void CB_DelP()
{
if (prfs.cntr < 2) {
printf("WARNING: last profile cannot be deleted\n");
return;
}
// delete from list //
DL_Del(&prfs, cfg.prf);
Prf_CrtLst();
// update menu entries //
ME_CngSwX(me_prf, &cfg.prf, prf_lst, prf_n);
ME_CngSwX(me_del, &cfg.prf, prf_lst, prf_n);
ME_CngSwX(me_clr, &cfg.prf, prf_lst, prf_n);
}
void CB_SrtP()
{
// Prf_Srt();
}
/*
init menu
add all entries
check them
*/
void MM_CrtE()
{
SDL_Surface *ss_bk, *ss_lg;
SFnt *ft_y, *ft_w, *ft_t;
Menu *_main, *opts, *snd, *new, *edit, *del, *clr, *crt, *c_del, *c_clr, *c_crt, *gfx, *ctrl;
MEnt *e;
char *str_diff[] = {"Easy", "Normal", "Hard", "Brainstorm"};
// load and assign gfx //
ss_bk = SS_Ld("gfx/title.bmp", SDL_SWSURFACE);
ss_lg = SS_Ld("gfx/logo.bmp", SDL_SWSURFACE);
ft_y = SF_LdFxd("gfx/f_yellow.bmp", 32, 96, 10);
ft_w = SF_LdFxd("gfx/f_white.bmp", 32, 96, 10);
MM_Ini(ss_bk->w / 2, ss_bk->h - 100, 50, ss_bk, ss_lg, ft_y, ft_w);
// add copyright //
ft_t = SF_Ld("gfx/tiny.sdlfnt");
ft_t->algn = TA_X_R | TA_Y_B;
SF_Wrt(ft_t, ss_bk, ss_bk->w-3, ss_bk->h-1, "(C) 2000 Michael Speck", 0);
ft_t->algn = TA_X_L | TA_Y_B;
SF_Wrt(ft_t, ss_bk, 0, ss_bk->h-1, "http://lgames.sourceforge.net", 0);
SF_Fr(ft_t);
// create and add entrys //
_main = M_Crt(); MM_Add(_main);
opts = M_Crt(); MM_Add(opts);
snd = M_Crt(); MM_Add(snd);
new = M_Crt(); MM_Add(new);
edit = M_Crt(); MM_Add(edit);
del = M_Crt(); MM_Add(del);
clr = M_Crt(); MM_Add(clr);
crt = M_Crt(); MM_Add(crt);
c_del = M_Crt(); MM_Add(c_del);
c_clr = M_Crt(); MM_Add(c_clr);
c_crt = M_Crt(); MM_Add(c_crt);
gfx = M_Crt(); MM_Add(gfx);
ctrl = M_Crt(); MM_Add(ctrl);
// main //
M_Add(_main, ME_CrtSub("New Game", new));
M_Add(_main, ME_CrtAct("Best Profiles", MA_HSC));
M_Add(_main, ME_CrtSub("Options", opts));
M_Add(_main, ME_CrtAct("Quit", MA_QUT));
// options //
M_Add(opts, ME_CrtSub("Controls", ctrl));
M_Add(opts, ME_CrtSub("Graphics", gfx));
#ifdef SOUND
M_Add(opts, ME_CrtSub("Audio", snd));
#else
M_Add(opts, ME_CrtSep("Audio"));
#endif
M_Add(opts, ME_CrtSep(""));
M_Add(opts, ME_CrtSub("Back", _main));
// sound //
e = ME_CrtSw2("Sound: ", &cfg.s_on, "Off", "On");
e->cb = CB_Snd;
M_Add(snd, e);
e = ME_CrtRng("Volume: ", &cfg.s_vol, 1, 8, 1);
e->cb = CB_StV;
M_Add(snd, e);
M_Add(snd, ME_CrtSep(""));
M_Add(snd, ME_CrtSub("Back", opts));
// new game //
M_Add(new, ME_CrtAct("Start", MA_PLY));
M_Add(new, ME_CrtSep(""));
M_Add(new, ME_CrtSwX("Difficulty:", &cfg.diff, str_diff, 4));
if (cfg.ls >= ls_n) cfg.ls = 0; // maybe someone deleted some level sets //
M_Add(new, ME_CrtSwX("Levelset:", &cfg.ls, ls_lst, ls_n));
me_prf = ME_CrtSwX("Profile:", &cfg.prf, prf_lst, prf_n);
M_Add(new, me_prf);
M_Add(new, ME_CrtSep(""));
M_Add(new, ME_CrtSub("Edit Profiles", edit));
M_Add(new, ME_CrtSep(""));
M_Add(new, ME_CrtSub("Back", _main));
// edit //
M_Add(edit, ME_CrtSub("Create Profile", crt));
M_Add(edit, ME_CrtSub("Clear Profile", clr));
M_Add(edit, ME_CrtSub("Delete Profile", del));
M_Add(edit, ME_CrtSep(""));
e = ME_CrtSub("Back", new);
e->cb = CB_SrtP;
M_Add(edit, e);
// create //
M_Add(crt, ME_CrtStr("Profile Name", cfg.prf_nm, 11));
M_Add(crt, ME_CrtSub("Create Profile", c_crt));
M_Add(crt, ME_CrtSep(""));
M_Add(crt, ME_CrtSub("Back", edit));
// confirm create //
e = ME_CrtSub("Yes", crt);
e->cb = CB_CrtP;
M_Add(c_crt, e);
M_Add(c_crt, ME_CrtSub("No", crt));
// clear //
me_clr = ME_CrtSwX("Profile:", &cfg.prf, prf_lst, prf_n);
M_Add(clr, me_clr);
M_Add(clr, ME_CrtSub("Clear Profile", c_clr));
M_Add(clr, ME_CrtSep(""));
M_Add(clr, ME_CrtSub("Back", edit));
// confirm clear //
e = ME_CrtSub("Yes", clr);
e->cb = CB_ClrP;
M_Add(c_clr, e);
M_Add(c_clr, ME_CrtSub("No", clr));
// delete //
me_del = ME_CrtSwX("Profile:", &cfg.prf, prf_lst, prf_n);
M_Add(del, me_del);
M_Add(del, ME_CrtSub("Delete Profile", c_del));
M_Add(del, ME_CrtSep(""));
M_Add(del, ME_CrtSub("Back", edit));
// confirm clear //
e = ME_CrtSub("Yes", del);
e->cb = CB_DelP;
M_Add(c_del, e);
M_Add(c_del, ME_CrtSub("No", del));
// graphics //
M_Add(gfx, ME_CrtSw2("Animations:", &cfg.ani, "Off", "On"));
// M_Add(gfx, ME_CrtSw2("Transparency:", &cfg.trp, "Off", "On"));
M_Add(gfx, ME_CrtSw2("Fullscreen:", &cfg.fscr, "Off", "On"));
M_Add(gfx, ME_CrtSw2("Dim Effect:", &cfg.dim, "Off", "On"));
M_Add(gfx, ME_CrtSep(""));
M_Add(gfx, ME_CrtSub("Back", opts));
// controls
M_Add(ctrl, ME_CrtKey("Up", &cfg.k_up));
M_Add(ctrl, ME_CrtKey("Down", &cfg.k_down));
M_Add(ctrl, ME_CrtKey("Left", &cfg.k_left));
M_Add(ctrl, ME_CrtKey("Right", &cfg.k_right));
M_Add(ctrl, ME_CrtKey("Undo", &cfg.k_undo));
M_Add(ctrl, ME_CrtSep(""));
M_Add(ctrl, ME_CrtSub("Back", opts));
// default valid keys
MM_DfVKys();
// adjust position of all entries in all menus //
MM_AdjP();
// call all callbacks //
MM_CB();
// check for errors
MM_Ck();
}
/*
init sound, menu, profiles, game
main loop for the menu
*/
int main(int argc, char *argv[])
{
SDL_Event e;
int go_on = 1;
int ms;
char aux[64];
#ifdef _WIN32
/* Get Windows to open files in binary mode instead of default text mode */
_fmode = _O_BINARY;
#endif
// just query version? //
if ( argc > 1 && !strncmp( "--version", argv[1], 9 ) ) {
printf( "%s\n", VERSION );
return 0;
}
// random init
srand(time(NULL));
// sdl init //
#ifdef SOUND
Sdl_Ini(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
#else
Sdl_Ini(SDL_INIT_VIDEO | SDL_INIT_TIMER);
#endif
sprintf( aux, "LMarbles %s", VERSION );
SDL_WM_SetCaption(aux, 0);
// show logo //
Sdl_StVdMd(512, 384, 16, SDL_SWSURFACE);
// show hardware capabilities //
Sdl_HwCps();
// load config //
C_StPth();
C_Ld();
// load profiles //
Prf_Ini();
if (!Prf_Ld())
cfg.prf = 0;
// create levelset list and reset config's levelset index if nescessary //
L_CrtLst();
if (cfg.ls >= ls_n)
cfg.ls = 0;
#ifdef SOUND
audio_open();
sound_enable( cfg.s_on );
sound_volume( cfg.s_vol * 16 );
#endif
// game init //
G_Ini();
// init and show menu//
MM_CrtE();
MM_Shw(MM_RSZ);
event_clear_sdl_queue();
//menu loop
T_Rst(); // reset time //
while (go_on && !trm_gm) {
M_Hd(mm.c_mn);
if (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT)
trm_gm = 1;
if (e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_ESCAPE)
go_on = 0;
switch (MM_Evt(&e)) {
case MA_QUT:
go_on = 0;
break;
case MA_PLY:
if (G_Opn()) {
G_Run();
G_Cls();
}
break;
case MA_HSC:
M_Shw(mm.c_mn);
Sdl_UpdR();
H_Shw(); // defined in main.c //
break;
}
}
ms = T_Gt();
M_CmA(mm.c_mn, ms);
M_Shw(mm.c_mn);
Sdl_UpdR();
SDL_Delay( 5 );
}
// terminate menu //
MM_Trm();
// terminate game //
G_Trm();
// close soundserver //
#ifdef SOUND
audio_close();
#endif
// save config //
C_Sv();
// free levelset list //
L_DelLst();
// save profiles //
Prf_Sv();
Prf_Trm();
// free screen //
Sdl_Qut();
printf("Bye, bye!\n");
return 0;
}