X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=share%2Fmapc.c;h=d79984fdc865158fddeb601206742f33b1044530;hb=c02ae9f8fce350c74e6ac7d281f03857c44964a7;hp=7e0b7221dbf4965593e4e95521119216666bb104;hpb=3df1a70fc44066a2a68a788aaa8ddbb57e6b1fe2;p=neverball diff --git a/share/mapc.c b/share/mapc.c index 7e0b722..d79984f 100644 --- a/share/mapc.c +++ b/share/mapc.c @@ -14,19 +14,6 @@ /*---------------------------------------------------------------------------*/ -#ifdef WIN32 -#pragma comment(lib, "SDL_ttf.lib") -#pragma comment(lib, "SDL_image.lib") -#pragma comment(lib, "SDL_mixer.lib") -#pragma comment(lib, "SDL.lib") -#pragma comment(lib, "SDLmain.lib") -#pragma comment(lib, "opengl32.lib") -#endif - -/*---------------------------------------------------------------------------*/ - -#include -#include #include #include #include @@ -34,6 +21,7 @@ #include "vec3.h" #include "solid.h" +#include "base_image.h" #include "base_config.h" #define MAXSTR 256 @@ -57,29 +45,6 @@ static int debug_output = 0; /* Ohhhh... arbitrary! */ -/* Old Limits: -#define MAXM 256 -#define MAXV 32767 -#define MAXE 32767 -#define MAXS 32767 -#define MAXT 32767 -#define MAXG 32767 -#define MAXL 1024 -#define MAXN 1024 -#define MAXP 512 -#define MAXB 512 -#define MAXH 1024 -#define MAXZ 16 -#define MAXJ 32 -#define MAXX 256 -#define MAXR 1024 -#define MAXU 16 -#define MAXW 32 -#define MAXD 128 -#define MAXA 8192 -#define MAXI 32767 -*/ - #define MAXM 1024 #define MAXV 65534 #define MAXE 65534 @@ -356,15 +321,11 @@ static void free_imagedata() static int size_load(const char *file, int *w, int *h) { - SDL_Surface *S; + void *p; - if ((S = IMG_Load(file))) + if ((p = image_load(file, w, h, NULL))) { - *w = S->w; - *h = S->h; - - SDL_FreeSurface(S); - + free(p); return 1; } return 0; @@ -373,7 +334,6 @@ static int size_load(const char *file, int *w, int *h) static void size_image(const char *name, int *w, int *h) { char jpg[MAXSTR]; - char tga[MAXSTR]; char png[MAXSTR]; int i; @@ -391,11 +351,9 @@ static void size_image(const char *name, int *w, int *h) *h = 0; strcpy(jpg, name); strcat(jpg, ".jpg"); - strcpy(tga, name); strcat(tga, ".tga"); strcpy(png, name); strcat(png, ".png"); if (size_load(config_data(png), w, h) || - size_load(config_data(tga), w, h) || size_load(config_data(jpg), w, h)) { @@ -450,6 +408,7 @@ static int read_mtrl(struct s_file *fp, const char *name) mp->e[0] = mp->e[1] = mp->e[2] = mp->e[3] = 1.0f; mp->h[0] = 0.0f; mp->fl = 0; + mp->angle = 45.0f; if ((fin = fopen(config_data(name), "r"))) { @@ -458,12 +417,12 @@ static int read_mtrl(struct s_file *fp, const char *name) "%f %f %f %f " "%f %f %f %f " "%f %f %f %f " - "%f %d ", + "%f %d %f", mp->d, mp->d + 1, mp->d + 2, mp->d + 3, mp->a, mp->a + 1, mp->a + 2, mp->a + 3, mp->s, mp->s + 1, mp->s + 2, mp->s + 3, mp->e, mp->e + 1, mp->e + 2, mp->e + 3, - mp->h, &mp->fl); + mp->h, &mp->fl, &mp->angle); fclose(fin); } @@ -504,10 +463,34 @@ static void move_lump(struct s_file *fp, static void move_body(struct s_file *fp, struct s_body *bp) { - int i; + int i, *b; + + /* Move the lumps. */ for (i = 0; i < bp->lc; i++) move_lump(fp, fp->lv + bp->l0 + i, fp->pv[bp->pi].p); + + /* Create an array to mark any verts referenced by moved geoms. */ + + if (bp->gc > 0 && (b = (int *) calloc(fp->vc, sizeof (int)))) + { + /* Mark the verts. */ + + for (i = 0; i < bp->gc; i++) + { + b[fp->gv[fp->iv[bp->g0 + i]].vi] = 1; + b[fp->gv[fp->iv[bp->g0 + i]].vj] = 1; + b[fp->gv[fp->iv[bp->g0 + i]].vk] = 1; + } + + /* Apply the motion to the marked vertices. */ + + for (i = 0; i < fp->vc; ++i) + if (b[i]) + move_vert(fp->vv + i, fp->pv[bp->pi].p); + + free(b); + } } static void move_file(struct s_file *fp) @@ -810,6 +793,7 @@ static void make_path(struct s_file *fp, pp->t = 1.f; pp->pi = pi; pp->f = 1; + pp->s = 1; for (i = 0; i < c; i++) { @@ -825,6 +809,9 @@ static void make_path(struct s_file *fp, if (strcmp(k[i], "speed") == 0) sscanf(v[i], "%f", &pp->t); + if (strcmp(k[i], "smooth") == 0) + pp->s = atoi(v[i]); + if (strcmp(k[i], "origin") == 0) { int x = 0, y = 0, z = 0; @@ -863,6 +850,8 @@ static void make_dict(struct s_file *fp, strncpy(fp->av + dp->aj, v, space_left - strlen(k) - 1); } +static int read_dict_entries = 0; + static void make_body(struct s_file *fp, char k[][MAXSTR], char v[][MAXSTR], int c, int l0) @@ -898,7 +887,7 @@ static void make_body(struct s_file *fp, else if (strcmp(k[i], "origin") == 0) sscanf(v[i], "%d %d %d", &x, &y, &z); - else if (strcmp(k[i], "classname") != 0) + else if (read_dict_entries && strcmp(k[i], "classname") != 0) make_dict(fp, k[i], v[i]); } @@ -916,6 +905,8 @@ static void make_body(struct s_file *fp, for (i = v0; i < fp->vc; i++) v_add(fp->vv[i].p, fp->vv[i].p, p); + + read_dict_entries = 0; } static void make_item(struct s_file *fp, @@ -1032,17 +1023,11 @@ static void make_goal(struct s_file *fp, zp->p[1] = 0.f; zp->p[2] = 0.f; zp->r = 0.75; - zp->s = 0; - zp->c = 0; for (i = 0; i < c; i++) { if (strcmp(k[i], "radius") == 0) sscanf(v[i], "%f", &zp->r); - if (strcmp(k[i], "skip") == 0) - sscanf(v[i], "%d", &zp->s); - if (strcmp(k[i], "special") == 0) - sscanf(v[i], "%d", &zp->c); if (strcmp(k[i], "origin") == 0) { @@ -1158,7 +1143,10 @@ static void make_swch(struct s_file *fp, sscanf(v[i], "%f", &xp->t0); if (strcmp(k[i], "state") == 0) - xp->f = atoi(v[i]); + { + xp->f = atoi(v[i]); + xp->f0 = atoi(v[i]); + } if (strcmp(k[i], "invisible") == 0) xp->i = atoi(v[i]); @@ -1289,7 +1277,11 @@ static void read_ent(struct s_file *fp, FILE *fin) if (!strcmp(v[i], "info_player_deathmatch")) make_goal(fp, k, v, c); if (!strcmp(v[i], "target_teleporter")) make_jump(fp, k, v, c); if (!strcmp(v[i], "target_position")) make_targ(fp, k, v, c); - if (!strcmp(v[i], "worldspawn")) make_body(fp, k, v, c, l0); + if (!strcmp(v[i], "worldspawn")) + { + read_dict_entries = 1; + make_body(fp, k, v, c, l0); + } if (!strcmp(v[i], "func_train")) make_body(fp, k, v, c, l0); if (!strcmp(v[i], "misc_model")) make_body(fp, k, v, c, l0); } @@ -1919,17 +1911,169 @@ static void uniq_side(struct s_file *fp) static void uniq_file(struct s_file *fp) { - if (debug_output) - return; + /* Debug mode skips optimization, producing oversized output files. */ + + if (debug_output == 0) + { + uniq_mtrl(fp); + uniq_vert(fp); + uniq_edge(fp); + uniq_side(fp); + uniq_texc(fp); + uniq_geom(fp); + } +} + +/*---------------------------------------------------------------------------*/ + +struct s_trip +{ + int vi; + int mi; + int si; + int gi; +}; + +static int comp_trip(const void *p, const void *q) +{ + const struct s_trip *tp = (const struct s_trip *) p; + const struct s_trip *tq = (const struct s_trip *) q; + + if (tp->vi < tq->vi) return -1; + if (tp->vi > tq->vi) return +1; + if (tp->mi < tq->mi) return -1; + if (tp->mi > tq->mi) return +1; + + return 0; +} - uniq_mtrl(fp); - uniq_vert(fp); - uniq_edge(fp); - uniq_side(fp); - uniq_texc(fp); - uniq_geom(fp); +static void smth_file(struct s_file *fp) +{ + struct s_trip temp, *T; + + if (debug_output == 0) + { + if ((T = (struct s_trip *) malloc(fp->gc * 3 * sizeof (struct s_trip)))) + { + int gi, i, j, k, l, c = 0; + + /* Create a list of all non-faceted vertex triplets. */ + + for (gi = 0; gi < fp->gc; ++gi) + { + struct s_geom *gp = fp->gv + gi; + + T[c].vi = gp->vi; + T[c].mi = gp->mi; + T[c].si = gp->si; + T[c].gi = gi; + c++; + + T[c].vi = gp->vj; + T[c].mi = gp->mi; + T[c].si = gp->sj; + T[c].gi = gi; + c++; + + T[c].vi = gp->vk; + T[c].mi = gp->mi; + T[c].si = gp->sk; + T[c].gi = gi; + c++; + } + + /* Sort all triplets by vertex index and material. */ + + qsort(T, c, sizeof (struct s_trip), comp_trip); + + /* For each set of triplets sharing vertex index and material... */ + + for (i = 0; i < c; i = l) + { + int acc = 0; + + float N[3], angle = fp->mv[T[i].mi].angle; + const float *Ni = fp->sv[T[i].si].n; + + /* Sort the set by side similarity to the first. */ + + for (j = i + 1; j < c && (T[j].vi == T[i].vi && + T[j].mi == T[i].mi); ++j) + { + for (k = j + 1; k < c && (T[k].vi == T[i].vi && + T[k].mi == T[i].mi); ++k) + { + const float *Nj = fp->sv[T[j].si].n; + const float *Nk = fp->sv[T[k].si].n; + + if (T[j].si != T[k].si && v_dot(Nk, Ni) > v_dot(Nj, Ni)) + { + temp = T[k]; + T[k] = T[j]; + T[j] = temp; + } + } + } + + /* Accumulate all similar side normals. */ + + N[0] = Ni[0]; + N[1] = Ni[1]; + N[2] = Ni[2]; + + for (l = i + 1; l < c && (T[l].vi == T[i].vi && + T[l].mi == T[i].mi); ++l) + if (T[l].si != T[i].si) + { + const float *Nl = fp->sv[T[l].si].n; + + if (V_DEG(facosf(v_dot(Ni, Nl))) > angle) + break; + + N[0] += Nl[0]; + N[1] += Nl[1]; + N[2] += Nl[2]; + + acc++; + } + + /* If at least two normals have been accumulated... */ + + if (acc) + { + /* Store the accumulated normal as a new side. */ + + int ss = incs(fp); + + v_nrm(fp->sv[ss].n, N); + fp->sv[ss].d = 0.0f; + + /* Assign the new normal to the merged triplets. */ + + for (j = i; j < l; ++j) + T[j].si = ss; + } + } + + /* Assign the remapped normals to the original geoms. */ + + for (i = 0; i < c; ++i) + { + struct s_geom *gp = fp->gv + T[i].gi; + + if (gp->vi == T[i].vi) gp->si = T[i].si; + if (gp->vj == T[i].vi) gp->sj = T[i].si; + if (gp->vk == T[i].vi) gp->sk = T[i].si; + } + + free(T); + } + + uniq_side(fp); + } } + /*---------------------------------------------------------------------------*/ static void sort_file(struct s_file *fp) @@ -2192,11 +2336,6 @@ static void dump_file(struct s_file *p, const char *name) p->rc, p->uc, p->ac, p->dc, p->ic); } -/* Skip the ugly SDL main substitution since we only need sdl_image. */ -#ifdef main -# undef main -#endif - int main(int argc, char *argv[]) { char src[MAXSTR]; @@ -2208,7 +2347,7 @@ int main(int argc, char *argv[]) { if (argc > 3 && strcmp(argv[3], "--debug") == 0) debug_output = 1; - + if (config_data_path(argv[2], NULL)) { strncpy(src, argv[1], MAXSTR); @@ -2230,6 +2369,7 @@ int main(int argc, char *argv[]) clip_file(&f); move_file(&f); uniq_file(&f); + smth_file(&f); sort_file(&f); node_file(&f); dump_file(&f, dst);