Mercurial > hg > dmlib
view dmq3d.c @ 382:371edff7dc3d
Fix extern variables to match what are actually declared in dmengine.c
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 17 Oct 2012 18:15:53 +0300 |
parents | d5a90ba09dc4 |
children | 3d813c81f33c |
line wrap: on
line source
#include "dmlib.h" #include "dmq3d.h" #include "dmimage.h" #define DM_DRAWLINE_NAME dmDrawLineSpec #define DM_DRAWLINE_DST_BYTES 4 #define DM_DRAWLINE_DST_TYPE DMRGBA32 #define DM_DRAWLINE_ARGS , SDL_Surface *bmp #define DM_DRAWLINE_INIT const int px = bmp->w / 2, py = bmp->h / 2; #define DM_DRAWLINE_INNER \ dmUnscaledBlitSurface32to32Transparent(bmp, x0-px, y0-py, screen); #define DM_DRAWLINE_SPEC #include "dmdrawline.h" static int dmFind3DBitmap(int nitems, DM3DBitmap *items, DM3DBitmap *item) { int i; for (i = 0; i < nitems; i++) if (strcmp(item->name, items[i].name) == 0) return i; return -1; } #define DM_FIND_ITEM_FUNC(NAME, TYPE) \ static int dmFind3D ## NAME (int nitems, TYPE *items, TYPE *item) \ { \ int i; \ for (i = 0; i < nitems; i++) \ if (memcmp(item, items+i, sizeof(TYPE)) == 0) \ return i; \ return -1; \ } #define DM_ADD_ITEM_FUNC(NAME, TYPE) \ static int dmAdd3D ## NAME (int *nitems, int *nalloc, TYPE **items, TYPE *item, int *res) \ { \ int tmp; \ if ((tmp = dmFind3D ## NAME (*nitems, *items, item)) >= 0) \ { \ if (res != NULL) *res = tmp; \ return DMERR_OK; \ } \ if ((*nitems) + 1 >= *nalloc) \ { \ (*nalloc) += 16; \ if ((*items = dmRealloc(*items, *nalloc * sizeof(TYPE))) == NULL) \ { \ dmError("Error allocating memory for " # TYPE ".\n"); \ return DMERR_MALLOC; \ } \ } \ memcpy((*items) + (*nitems), item, sizeof(TYPE)); \ if (res != NULL) *res = *nitems; \ (*nitems)++; \ return DMERR_OK; \ } DM_FIND_ITEM_FUNC(Vertex, DMVector) DM_FIND_ITEM_FUNC(Vector, DM3DVector) DM_FIND_ITEM_FUNC(Sprite, DM3DSprite) DM_ADD_ITEM_FUNC(Vertex, DMVector) DM_ADD_ITEM_FUNC(Vector, DM3DVector) DM_ADD_ITEM_FUNC(Sprite, DM3DSprite) DM_ADD_ITEM_FUNC(Bitmap, DM3DBitmap) int dmAdd3DVectorSpriteModelVertex(DM3DVectorSpriteModel *model, DMVector *v, int *index) { return dmAdd3DVertex(&model->nvertices, &model->nvertexalloc, &model->vertices, v, index); } int dmAdd3DVectorSpriteModelVector(DM3DVectorSpriteModel *model, DM3DVector *v, int *index) { return dmAdd3DVector(&model->nlines, &model->nlinesalloc, &model->lines, v, index); } int dmAdd3DVectorSpriteModelSprite(DM3DVectorSpriteModel *model, DM3DSprite *v, int *index) { return dmAdd3DSprite(&model->nsprites, &model->nspritesalloc, &model->sprites, v, index); } int dmAdd3DVectorSpriteModelBitmap(DM3DVectorSpriteModel *model, DM3DBitmap *v, int *index) { return dmAdd3DBitmap(&model->nbitmaps, &model->nbitmapsalloc, &model->bitmaps, v, index); } static inline DMFloat dmPX(int cx, DMVector p) { return cx + (p.x * 250.0f) / p.z; } static inline DMFloat dmPY(int cy, DMVector p) { return cy + (p.y * 250.0f) / p.z; } void dmDraw3DVectorSpriteModel(SDL_Surface *screen, const DM3DVectorSpriteModel *model, const DMVector *pos, const DMMatrix *mat, SDL_Surface *fbmap, const Uint32 lcol) { int i; int cx = screen->w / 2, cy = screen->h / 2; for (i = 0; i < model->nlines; i++) { DM3DVector *line = &model->lines[i]; DMVector pv[2]; dm_vector_copy(&pv[0], &model->vertices[line->v1]); dm_vector_copy(&pv[1], &model->vertices[line->v2]); dm_vector_mul_by_mat_n(pv, 2, mat); dm_vector_add(&pv[0], pos); dm_vector_add(&pv[1], pos); if (pv[0].z <= 0 && pv[1].z <= 0) continue; if (line->type > 1) dmDrawLineSpec(screen, dmPX(cx, pv[0]), dmPY(cy, pv[0]), dmPX(cx, pv[1]), dmPY(cy, pv[1]), lcol, fbmap); else dmDrawLine32(screen, dmPX(cx, pv[0]), dmPY(cy, pv[0]), dmPX(cx, pv[1]), dmPY(cy, pv[1]), lcol); } for (i = 0; i < model->nsprites; i++) { DM3DSprite *sprite = &model->sprites[i]; DM3DBitmap *bmp = &model->bitmaps[sprite->bitmap]; DMVector pv; dm_vector_mul_by_mat(&pv, &model->vertices[sprite->v], mat); dm_vector_add(&pv, pos); if (pv.z <= 0) continue; dmUnscaledBlitSurface32to32Transparent(bmp->img, dmPX(cx, pv), dmPY(cy, pv), screen); } } static char *dmSkipWhitespace(char *line, BOOL invert) { if (invert) for (; *line && !isspace(*line); line++); else for (; *line && isspace(*line); line++); return line; } static char *dmSkipUntil(char *line, char ch) { for (; *line && *line != ch; line++); return line; } static BOOL dmReadCoordinate(const char *orig, char **line, float *value, BOOL next) { *line = dmSkipWhitespace(*line, FALSE); if (sscanf(*line, "%f", value) != 1) { dmError("Expected floating point value @ %d:\n%s\n", (*line - orig), orig); return FALSE; } if (next) { *line = dmSkipUntil(*line, ','); if (**line != ',') { dmError("Expected comma @ %d:\n%s\n", (*line - orig), orig); return FALSE; } *(*line)++; } else *line = dmSkipWhitespace(*line, TRUE); return TRUE; } static BOOL dmReadVectorSegments(char *line, DM3DVectorSpriteModel *model, BOOL relative, const DMVector *pt) { DMVector v, p, *t; int nvertices, vertex, type; int *indices = NULL; char *ptr = line; if (sscanf(ptr+1, "%d", &nvertices) != 1) { dmError("No # of segments @ '%s'\n", ptr); goto error; } if ((indices = dmMalloc(sizeof(int) * (nvertices+1))) == NULL) goto error; ptr = dmSkipWhitespace(ptr, TRUE); dm_vector_copy(&v, pt); for (vertex = 0; vertex <= nvertices; vertex++) { if (*ptr == 'Z') { indices[vertex] = indices[0]; ptr++; } else { if (!dmReadCoordinate(line, &ptr, &p.x, TRUE)) return FALSE; if (!dmReadCoordinate(line, &ptr, &p.y, TRUE)) return FALSE; if (!dmReadCoordinate(line, &ptr, &p.z, FALSE)) return FALSE; if (relative) { dm_vector_add(&v, &p); t = &v; } else { dm_vector_add_r(&v, &p, pt); t = &v; } if (dmAdd3DVectorSpriteModelVertex(model, t, &indices[vertex]) != DMERR_OK) goto error; } ptr = dmSkipWhitespace(ptr, FALSE); } if (sscanf(ptr, "%d", &type) != 1) { dmError("No line type @ '%s'\n", ptr); goto error; } for (vertex = 1; vertex <= nvertices; vertex++) { DM3DVector vec; vec.v1 = indices[vertex - 1]; vec.v2 = indices[vertex]; vec.type = type; if (dmAdd3DVectorSpriteModelVector(model, &vec, NULL) != DMERR_OK) goto error; } return TRUE; error: dmFree(indices); return FALSE; } static BOOL dmReadSprite(char *line, DM3DVectorSpriteModel *model, DMVector *pos) { DMVector pt; DM3DSprite spr; char *ptr = line; ptr++; if (!dmReadCoordinate(line, &ptr, &pt.x, TRUE)) return FALSE; if (!dmReadCoordinate(line, &ptr, &pt.y, TRUE)) return FALSE; if (!dmReadCoordinate(line, &ptr, &pt.z, FALSE)) return FALSE; ptr = dmSkipWhitespace(ptr, FALSE); if (*ptr != 'B') { dmError("No bitmap definition found for sprite.\n"); return FALSE; } spr.bitmap = atoi(ptr + 1); dm_vector_add(&pt, pos); if (dmAdd3DVectorSpriteModelVertex(model, &pt, &spr.v) != DMERR_OK) return FALSE; if (dmAdd3DVectorSpriteModelSprite(model, &spr, NULL) != DMERR_OK) return FALSE; return TRUE; } static BOOL dmReadBitmap(char *line, DM3DVectorSpriteModel *model, DMResourceLib *lib) { DM3DBitmap bmp, *rbmp; int index; char *ptr = line; strncpy(bmp.name, ptr + 1, sizeof(bmp.name)); bmp.img = NULL; if (dmAdd3DVectorSpriteModelBitmap(model, &bmp, &index) != DMERR_OK) return FALSE; rbmp = &(model->bitmaps[index]); if (rbmp->img == NULL) { DMResource *res = dmf_open(lib, rbmp->name); if (res == NULL) { dmError("Could not open resource file '%s'.\n", rbmp->name); return FALSE; } rbmp->img = dmLoadImage(res); dmf_close(res); if (rbmp->img == NULL) { dmError("Could not load image file '%s'.\n", rbmp->name); return FALSE; } } return TRUE; } static int dmDoRead3DVectorSpriteModel(DMResource *f, DM3DVectorSpriteModel *model, DMVector *pos) { char line[8192]; while (dmfgets(line, sizeof(line), f) != NULL) { char *start = dmSkipWhitespace(line, FALSE); switch (*start) { case 0: case '#': break; case 'G': { int res; DMVector pt; start++; if (!dmReadCoordinate(line, &start, &pt.x, TRUE)) return DMERR_INVALID_DATA; if (!dmReadCoordinate(line, &start, &pt.y, TRUE)) return DMERR_INVALID_DATA; if (!dmReadCoordinate(line, &start, &pt.z, FALSE)) return DMERR_INVALID_DATA; dm_vector_add_r(&pt, pos, &pt); if ((res = dmDoRead3DVectorSpriteModel(f, model, &pt)) != DMERR_OK) return res; } break; case 'E': return DMERR_OK; case 'B': if (!dmReadBitmap(start, model, f->lib)) return DMERR_INVALID_DATA; break; case 'L': if (!dmReadVectorSegments(start, model, FALSE, pos)) return DMERR_INVALID_DATA; break; case 'R': if (!dmReadVectorSegments(start, model, TRUE, pos)) return DMERR_INVALID_DATA; break; case 'S': if (!dmReadSprite(start, model, pos)) return DMERR_INVALID_DATA; break; default: break; } } return DMERR_OK; } int dmRead3DVectorSpriteModel(DMResource *f, DM3DVectorSpriteModel **model) { DMVector pos; if ((*model = dmMalloc0(sizeof(DM3DVectorSpriteModel))) == NULL) return DMERR_MALLOC; memset(&pos, 0, sizeof(pos)); return dmDoRead3DVectorSpriteModel(f, *model, &pos); } void dmFree3DVectorSpriteModel(DM3DVectorSpriteModel *model) { int i; for (i = 0; i < model->nbitmaps; i++) { if (model->bitmaps[i].img != NULL) SDL_FreeSurface(model->bitmaps[i].img); } dmFree(model->bitmaps); dmFree(model->vertices); dmFree(model->lines); dmFree(model->sprites); dmFree(model); }