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

423 lines
12 KiB
C

/***************************************************************************
profile.c - description
-------------------
begin : Sun Sep 17 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 "profile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cfg.h"
#include "file.h"
// profiles //
DLst prfs;
// string list for the menu //
char **prf_lst = 0;
int prf_n = 0;
// profile source path //
char prf_pth[256];
// configuration //
extern Cfg cfg;
/* initialize dyn list and source path */
void Prf_Ini()
{
DL_Ini(&prfs);
prfs.flgs = DL_AUTODEL;
prfs.cb = Prf_Del;
sprintf(prf_pth, "%s/lmarbles.prfs", PRF_DIR);
}
/* terminate profiles; must be saved first */
void Prf_Trm()
{
Prf_DelLst();
DL_Clr(&prfs);
}
/* load profiles */
int Prf_Ld()
{
Prf *p;
SInf *st;
int s_num = 0, p_num = 0;
FILE *f = 0;
int not_f = 0;
char str[256];
#ifdef ASCII
int i;
#endif
printf("loading profiles... ");
// read access ? //
if ((f = fopen(prf_pth, "r")) == 0) {
printf("\nWARNING: file %s does not exist; cannot read profiles\n", prf_pth);
Prf_Crt("Michael");
not_f = 1;
}
else {
/* load ascii identification */
#ifdef ASCII
F_GetE(f, str, F_VAL); str[strlen(str) - 1] = 0;
if (strncmp(str,"ascii",5)) {
printf("\nWARNING: trying to load raw binary data in ascii; cannot read profiles\n", prf_pth);
Prf_Crt("Michael");
not_f = 1;
}
else {
#else
fread(str, 5, 1, f);
if (!strncmp(str,"ascii",5)) {
printf("\nWARNING: trying to load in ascii instead of raw binary format; cannot read profiles\n");
Prf_Crt("Michael");
not_f = 1;
}
else {
fseek(f, SEEK_SET, 0);
#endif
/* load numbers of profiles */
#ifdef ASCII
F_GetE(f, str, F_VAL); F_ValToInt(str, &p_num);
#else
fread((void*)&p_num, sizeof(int), 1, f);
#endif
if (p_num <= 0) {
printf("WARNING: bad profile counter: %i\n", p_num);
Prf_Crt("Michael");
not_f = 1;
}
else {
while (p_num--) {
p = malloc(sizeof(Prf));
#ifdef ASCII
/* name */
F_GetE(f, p->nm, F_VAL); p->nm[strlen(p->nm) - 1] = 0;
/* levels played */
F_GetE(f, str, F_VAL); F_ValToInt(str, &p->lvls);
/* score */
F_GetE(f, str, F_VAL); F_ValToInt(str, &p->scr);
/* percentage */
F_GetE(f, str, F_VAL); F_ValToFloat(str, &p->pct);
/* number of levelsets */
F_GetE(f, str, F_VAL); F_ValToInt(str, &s_num);
#else
/* name */
fread(p->nm, sizeof(p->nm), 1, f);
/* levels played */
fread(&p->lvls, sizeof(p->lvls), 1, f);
/* score */
fread(&p->scr, sizeof(p->scr), 1, f);
/* percentage */
fread(&p->pct, sizeof(p->pct), 1, f);
/* number of levelsets */
fread(&s_num, sizeof(int), 1, f);
#endif
DL_Ini(&p->sts);
p->sts.flgs = DL_AUTODEL | DL_NOCB;
if (s_num >= 0)
while (s_num--) {
/* level sets */
st = malloc(sizeof(SInf));
#ifdef ASCII
F_GetE(f, st->nm, F_VAL); st->nm[strlen(st->nm) - 1] = 0;
F_GetE(f, str, F_VAL); F_ValToInt(str, &st->num);
F_GetE(f, str, F_VAL); F_ValToInt(str, &st->l_num);
F_GetE(f, str, F_VAL); F_ValToInt(str, &st->c_num);
for ( i = 0; i < st->c_num; i++) {
F_GetE(f, str, F_VAL); F_ValToChar(str, &st->c_opn[i]);
}
for ( i = 0; i < st->num; i++) {
F_GetE(f, str, F_VAL); F_ValToChar(str, &st->cmp[i]);
}
#else
fread(st->nm, sizeof(st->nm), 1, f);
fread(&st->num, sizeof(int), 1, f);
fread(&st->l_num, sizeof(int), 1, f);
fread(&st->c_num, sizeof(int), 1, f);
fread(st->c_opn, sizeof(char), st->c_num, f);
fread(st->cmp, sizeof(char), st->num, f);
#endif
DL_Add(&p->sts, st);
}
DL_Add(&prfs, p);
}
}
printf("ok\n");
#ifdef ASCII
}
#else
}
#endif
fclose(f);
}
Prf_CrtLst();
return !not_f;
}
/* save profiles */
void Prf_Sv()
{
DL_E *e = prfs.hd.n, *le = 0;
Prf *p;
SInf *st;
FILE *f;
#ifdef ASCII
int i;
char str[256];
#endif
printf("saving profiles... ");
if ((f = fopen(prf_pth, "w")) == 0) {
printf("WARNING: no write access to %s\n", prf_pth);
}
else {
/* save ascii identification */
#ifdef ASCII
F_WrtE(f, "ascii");
#endif
/* save numbers of profiles */
#ifdef ASCII
F_IntToStr(str, prfs.cntr); F_WrtE(f, str);
#else
fwrite((void*)&prfs.cntr, sizeof(int), 1, f);
#endif
while (e != &prfs.tl) {
p = (Prf*)e->d;
#ifdef ASCII
/* save name -- 12 chars */
F_WrtE(f, p->nm);
/* levels played */
F_IntToStr(str, p->lvls); F_WrtE(f, str);
/* score */
F_IntToStr(str, p->scr); F_WrtE(f, str);
/* percentage */
F_FloatToStr(str, p->pct); F_WrtE(f, str);
/* save number of levelsets */
F_IntToStr(str, p->sts.cntr); F_WrtE(f, str);
#else
/* save name -- 12 chars */
fwrite(p->nm, sizeof(p->nm), 1, f);
/* levels played */
fwrite(&p->lvls, sizeof(p->lvls), 1, f);
/* score */
fwrite(&p->scr, sizeof(p->scr), 1, f);
/* percentage */
fwrite(&p->pct, sizeof(p->pct), 1, f);
/* save number of levelsets */
fwrite(&p->sts.cntr, sizeof(int), 1, f);
#endif
/* save all levelsets */
le = p->sts.hd.n;
while (le != &p->sts.tl) {
st = (SInf*)le->d;
#ifdef ASCII
/* save name -- 32 chars */
F_WrtE(f, st->nm);
/* save number of flags */
F_IntToStr(str, st->num); F_WrtE(f, str);
/* save level peer chapter number */
F_IntToStr(str, st->l_num); F_WrtE(f, str);
/* save chapter number */
F_IntToStr(str, st->c_num); F_WrtE(f, str);
/* save chapter open flags */
for ( i = 0; i < st->c_num; i++ ) {
F_IntToStr(str, st->c_opn[i]); F_WrtE(f, str);
}
/* save flags */
for ( i = 0; i < st->num; i++ ) {
F_IntToStr(str, st->cmp[i]); F_WrtE(f, str);
}
#else
/* save name -- 32 chars */
fwrite(st->nm, sizeof(st->nm), 1, f);
/* save number of flags */
fwrite(&st->num, sizeof(int), 1, f);
/* save level peer chapter number */
fwrite(&st->l_num, sizeof(int), 1, f);
/* save chapter number */
fwrite(&st->c_num, sizeof(int), 1, f);
/* save chapter open flags */
fwrite(st->c_opn, sizeof(char), st->c_num, f);
/* save flags */
fwrite(st->cmp, sizeof(char), st->num, f);
#endif
le = le->n;
}
e = e->n;
}
printf("ok\n");
fclose(f);
}
}
/* create a new profile */
void Prf_Crt(char *nm)
{
Prf *p;
DL_E *e = prfs.hd.n;
// if the name already exists the profile is not created //
while (e != &prfs.tl) {
if (!strcmp(((Prf*)e->d)->nm, nm)) {
printf("WARNING: profile '%s' already exists\n", nm);
return;
}
e = e->n;
}
p = malloc(sizeof(Prf));
strcpy(p->nm, nm);
p->scr = 0;
p->pct = 0;
p->lvls = 0;
DL_Ini(&p->sts);
p->sts.flgs = DL_AUTODEL | DL_NOCB;
DL_Add(&prfs, p);
}
/* delete an existing profile by pointer */
void Prf_Del(void *p)
{
DL_Clr(&((Prf*)p)->sts);
free(p);
}
/* register or find a levelset with name nm */
SInf* Prf_RegLS(Prf *p, LSet *l_st)
{
int i;
DL_E *e = p->sts.hd.n;
SInf *s;
/* maybe it already exists */
while (e != &p->sts.tl) {
s = (SInf*)e->d;
if (!strcmp(s->nm, l_st->nm)) {
if (l_st->c_num != s->c_num || l_st->l_num != s->l_num) {
// seems to be changed; clear it //
s->num = l_st->c_num * l_st->l_num;
s->l_num = l_st->l_num;
s->c_num = l_st->c_num;
for (i = 0; i < s->c_num; i++)
s->c_opn[i] = l_st->ch[i].opn;
memset(s->cmp, 0, sizeof(s->cmp));
printf("WARNING: profile '%s': set info '%s' seems to be out of date\n", p->nm, l_st->nm);
}
return s;
}
e = e->n;
}
/* must be registered */
s = malloc(sizeof(SInf));
strcpy(s->nm, l_st->nm);
s->num = l_st->c_num * l_st->l_num;
s->l_num = l_st->l_num;
s->c_num = l_st->c_num;
for (i = 0; i < s->c_num; i++)
s->c_opn[i] = l_st->ch[i].opn;
memset(s->cmp, 0, sizeof(s->cmp));
DL_Add(&p->sts, s);
return s;
}
/* create profile name list */
void Prf_CrtLst()
{
int i = 0;
DL_E *e = prfs.hd.n;
Prf *p;
Prf_DelLst();
prf_lst = malloc(sizeof(char*) * prfs.cntr);
while (e != &prfs.tl) {
p = (Prf*)e->d;
prf_lst[i] = malloc(sizeof(p->nm) + 1);
strcpy(prf_lst[i], p->nm);
i++;
e = e->n;
}
prf_n = i;
}
/* delete profile name list */
void Prf_DelLst()
{
int i;
if (prf_lst == 0) return;
for (i = 0; i < prf_n; i++)
free(prf_lst[i]);
free(prf_lst);
}
/*
sort all profiles best profile comes first
*/
void Prf_Srt()
{
void *p;
DL_E *e = prfs.hd.n, *e2;
if (prfs.cntr == 0) return;
while (e != prfs.tl.p) {
e2 = e->n;
while (e2 != &prfs.tl) {
if (((Prf*)e2->d)->scr > ((Prf*)e->d)->scr) {
p = e2->d;
e2->d = e->d;
e->d = p;
}
e2 = e2->n;
}
e = e->n;
}
}
/*
update Profile p's score and info
s is rem_time / max_time of that level
*/
void Prf_Upd(Prf *p, SInf *inf, int l_id, float pct, int scr)
{
float new_p;
#ifdef DEBUG
float old_p = p->pct;
printf("level %i...", l_id);
#endif
if (!inf->cmp[l_id]) {
/* mark as completed */
inf->cmp[l_id] = 1;
/* update percentage */
if (p->lvls == 0)
p->pct = pct;
else {
new_p = (p->pct * p->lvls + pct) / (p->lvls + 1);
p->pct = new_p;
}
p->lvls++;
p->scr += scr;
#ifdef DEBUG
printf("marked as completed\n");
printf("added %4.2f: percentage changed from %4.2f to %4.2f\n", pct, old_p, p->pct);
printf("score added: %i\n", scr);
#endif
}
#ifdef DEBUG
else
printf("already finished\n");
#endif
}