/* * ================= * RB_TableForFunc * ================= */ static float *RB_TableForFunc(const waveFunc_t *func) { switch (func->type) { case WAVEFORM_SIN: return rb_sinTable; case WAVEFORM_TRIANGLE: return rb_triangleTable; case WAVEFORM_SQUARE: return rb_squareTable; case WAVEFORM_SAWTOOTH: return rb_sawtoothTable; case WAVEFORM_INVERSESAWTOOTH: return rb_inverseSawtoothTable; case WAVEFORM_NOISE: return rb_noiseTable; } VID_Error(ERR_DROP, "RB_TableForFunc: unknown waveform type %i", func->type); return rb_sinTable; }
/* ================= Mod_LoadPlanes ================= */ void Mod_LoadPlanes (lump_t *l) { int i, j; cplane_t *out; dplane_t *in; int count; int bits; in = (dplane_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadPlanes: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (cplane_t *) Hunk_Alloc ( count*2*sizeof(*out)); loadmodel->planes = out; loadmodel->numplanes = count; for ( i=0 ; i<count ; i++, in++, out++) { bits = 0; for (j=0 ; j<3 ; j++) { out->normal[j] = LittleFloat(in->normal[j]); if (FLOAT_LT_ZERO(out->normal[j])) bits |= 1<<j; } out->dist = LittleFloat(in->dist); out->type = (byte)LittleLong(in->type); out->signbits = bits; } }
/* ================= Mod_LoadSubmodels ================= */ void Mod_LoadSubmodels (lump_t *l) { dmodel_t *in; mmodel_t *out; int i, count; in = (dmodel_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (mmodel_t *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->submodels = out; loadmodel->numsubmodels = count; for ( i=0 ; i<count ; i++, in++, out++) { out->mins[0] = LittleFloat(in->mins[0]) - 1; out->maxs[0] = LittleFloat(in->maxs[0]) + 1; out->origin[0] = LittleFloat(in->origin[0]); out->mins[1] = LittleFloat(in->mins[1]) - 1; out->maxs[1] = LittleFloat(in->maxs[1]) + 1; out->origin[1] = LittleFloat(in->origin[1]); out->mins[2] = LittleFloat(in->mins[2]) - 1; out->maxs[2] = LittleFloat(in->maxs[2]) + 1; out->origin[2] = LittleFloat(in->origin[2]); out->radius = RadiusFromBounds (out->mins, out->maxs); out->headnode = LittleLong(in->headnode); out->firstface = LittleLong(in->firstface); out->numfaces = LittleLong(in->numfaces); out->visleafs = 0; } }
/* ================= Mod_LoadEdges ================= */ void Mod_LoadEdges (lump_t *l) { dedge_t *in; medge_t *out; int i, count; in = (dedge_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadEdges: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); //r1: was count+1 out = (medge_t *) Hunk_Alloc (count * sizeof(*out)); loadmodel->edges = out; loadmodel->numedges = count; for ( i=0 ; i<count ; i++, in++, out++) { out->v[0] = (unsigned short)LittleShort(in->v[0]); out->v[1] = (unsigned short)LittleShort(in->v[1]); } }
/* ================= Mod_LoadLeafs ================= */ void Mod_LoadLeafs (lump_t *l) { dleaf_t *in; mleaf_t *out; int i, count; // glpoly_t *poly; in = (dleaf_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadLeafs: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (mleaf_t *) Hunk_Alloc ( count*sizeof(*out)); //memset (out, 0, count*sizeof(*out)); loadmodel->leafs = out; loadmodel->numleafs = count; for ( i=0 ; i<count ; i++, in++, out++) { out->minmaxs[0] = LittleShort(in->mins[0]); out->minmaxs[1] = LittleShort(in->mins[1]); out->minmaxs[2] = LittleShort(in->mins[2]); out->minmaxs[3] = LittleShort(in->maxs[0]); out->minmaxs[4] = LittleShort(in->maxs[1]); out->minmaxs[5] = LittleShort(in->maxs[2]); out->contents = LittleLong(in->contents); out->cluster = LittleShort(in->cluster); out->area = LittleShort(in->area); out->firstmarksurface = loadmodel->marksurfaces + LittleShort(in->firstleafface); out->nummarksurfaces = LittleShort(in->numleaffaces); out->parent = NULL; out->visframe = 0; // gl underwater warp #if 0 if (out->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_THINWATER) ) { for (j=0 ; j<out->nummarksurfaces ; j++) { out->firstmarksurface[j]->flags |= SURF_UNDERWATER; for (poly = out->firstmarksurface[j]->polys ; poly ; poly=poly->next) poly->flags |= SURF_UNDERWATER; } } #endif } }
/* ================= Mod_LoadSpriteModel ================= */ void Mod_LoadSpriteModel (model_t *mod, void *buffer) { dsprite_t *sprin, *sprout; int i; sprin = (dsprite_t *)buffer; sprout = (dsprite_t *) Hunk_Alloc (modfilelen); sprout->ident = LittleLong(sprin->ident); sprout->version = LittleLong(sprin->version); sprout->numframes = LittleLong(sprin->numframes); if (sprout->version != SPRITE_VERSION) VID_Error (ERR_DROP, "sprite %s has wrong version number (%i should be %i)", mod->name, sprout->version, SPRITE_VERSION); if (sprout->numframes > MAX_MD2SKINS) VID_Error (ERR_DROP, "sprite %s has too many frames (%i > %i)", mod->name, sprout->numframes, MAX_MD2SKINS); if (sprout->numframes <= 0) VID_Error (ERR_DROP, "sprite %s has no frames", mod->name); // byte swap everything for (i=0 ; i<sprout->numframes ; i++) { sprout->frames[i].width = LittleLong(sprin->frames[i].width); sprout->frames[i].height = LittleLong(sprin->frames[i].height); sprout->frames[i].origin_x = LittleLong(sprin->frames[i].origin_x); sprout->frames[i].origin_y = LittleLong(sprin->frames[i].origin_y); memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME); fast_strlwr (sprout->frames[i].name); mod->skins[i] = GL_FindImage (sprout->frames[i].name, sprout->frames[i].name, it_sprite); //r1: sprites crash if they don't have valid skins for framenum so be noisy if (!mod->skins[i]) VID_Printf (PRINT_ALL, "GL_FindImage: Couldn't find skin '%s' for sprite '%s'\n", sprout->frames[i].name, mod->name); } mod->type = mod_sprite; }
/* ================= Mod_LoadSurfedges ================= */ void Mod_LoadSurfedges (lump_t *l) { int count; int *in, *out; in = (int *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); if (count < 1 || count >= MAX_MAP_SURFEDGES) VID_Error (ERR_DROP, "MOD_LoadBmodel: bad surfedges count in %s: %i", loadmodel->name, count); out = (int *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->surfedges = out; loadmodel->numsurfedges = count; memcpy (out, in, sizeof(int)*count); }
/* ** GLimp_EndFrame ** ** Responsible for doing a swapbuffers and possibly for other stuff ** as yet to be determined. Probably better not to make this a GLimp ** function and instead do a call to GLimp_SwapBuffers. */ void GLimp_EndFrame (void) { int err; err = qglGetError(); assert( err == GL_NO_ERROR ); if ( stricmp( r_drawbuffer->string, "GL_BACK" ) == 0 ) { if ( !qwglSwapBuffers( glw_state.hDC ) ) VID_Error( ERR_FATAL, "GLimp_EndFrame() - SwapBuffers() failed!\n" ); } }
void LoadSP2(model_t *mod, void *buffer) { dsprite_t *sprin, *sprout; int i; sprin = (dsprite_t *)buffer; sprout = Hunk_Alloc(modfilelen); sprout->ident = LittleLong(sprin->ident); sprout->version = LittleLong(sprin->version); sprout->numframes = LittleLong(sprin->numframes); if (sprout->version != SPRITE_VERSION) { VID_Error(ERR_DROP, "%s has wrong version number (%i should be %i)", mod->name, sprout->version, SPRITE_VERSION); } if (sprout->numframes > MAX_MD2SKINS) { VID_Error(ERR_DROP, "%s has too many frames (%i > %i)", mod->name, sprout->numframes, MAX_MD2SKINS); } /* byte swap everything */ for (i = 0; i < sprout->numframes; i++) { sprout->frames[i].width = LittleLong(sprin->frames[i].width); sprout->frames[i].height = LittleLong(sprin->frames[i].height); sprout->frames[i].origin_x = LittleLong(sprin->frames[i].origin_x); sprout->frames[i].origin_y = LittleLong(sprin->frames[i].origin_y); memcpy(sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME); mod->skins[i] = R_FindImage(sprout->frames[i].name, it_sprite); } mod->type = mod_sprite; }
void RefreshFont (void) { con_font->modified = false; draw_chars = R_FindImage (va("fonts/%s.pcx", con_font->string), it_pic); if (!draw_chars) // fall back on default font draw_chars = R_FindImage ("fonts/default.pcx", it_pic); if (!draw_chars) // fall back on old Q2 conchars draw_chars = R_FindImage ("pics/conchars.pcx", it_pic); if (!draw_chars) // prevent crash caused by missing font VID_Error (ERR_FATAL, "RefreshFont: couldn't load pics/conchars"); GL_Bind( draw_chars->texnum ); }
/* ================= Mod_LoadMarksurfaces ================= */ void Mod_LoadMarksurfaces (lump_t *l) { int i, j, count; short *in; msurface_t **out; in = (short *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (msurface_t **) Hunk_Alloc ( count*sizeof(*out)); loadmodel->marksurfaces = out; loadmodel->nummarksurfaces = count; for ( i=0 ; i<count ; i++) { j = LittleShort(in[i]); if (j < 0 || j >= loadmodel->numsurfaces) VID_Error (ERR_DROP, "Mod_ParseMarksurfaces: bad surface number"); out[i] = loadmodel->surfaces + j; } }
/* ================= Mod_LoadNodes ================= */ void Mod_LoadNodes (lump_t *l) { int i, j, count, p; dnode_t *in; mnode_t *out; in = (dnode_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadNodes: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (mnode_t *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->nodes = out; loadmodel->numnodes = count; for ( i=0 ; i<count ; i++, in++, out++) { out->minmaxs[0] = LittleShort(in->mins[0]); out->minmaxs[1] = LittleShort(in->mins[1]); out->minmaxs[2] = LittleShort(in->mins[2]); out->minmaxs[3] = LittleShort(in->maxs[0]); out->minmaxs[4] = LittleShort(in->maxs[1]); out->minmaxs[5] = LittleShort(in->maxs[2]); p = LittleLong(in->planenum); out->plane = loadmodel->planes + p; out->firstsurface = LittleShort(in->firstface); out->numsurfaces = LittleShort(in->numfaces); out->contents = -1; // differentiate from leafs out->parent = NULL; out->visframe = 0; for (j=0 ; j<2 ; j++) { p = LittleLong(in->children[j]); if (p >= 0) out->children[j] = loadmodel->nodes + p; else out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); } } Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs }
/* ================= Mod_LoadVertexes ================= */ void Mod_LoadVertexes (lump_t *l) { dvertex_t *in; mvertex_t *out; int count; in = (dvertex_t *) (mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadVertexes: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (mvertex_t *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->vertexes = out; loadmodel->numvertexes = count; memcpy (out, in, sizeof(dvertex_t)*count); }
/* =============== Mod_PointInLeaf =============== */ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) { mnode_t *node; float d; cplane_t *plane; if (!model || !model->nodes) VID_Error (ERR_DROP, "Mod_PointInLeaf: bad model"); node = model->nodes; for (;;) { if (node->contents != -1) return (mleaf_t *)node; plane = node->plane; d = DotProduct (p,plane->normal) - plane->dist; if (FLOAT_GT_ZERO(d)) node = node->children[0]; else node = node->children[1]; } //return NULL; // never reached }
void ClipSkyPolygon (int nump, vec3_t vecs, int stage) { float *norm; float *v; qboolean front, back; float d, e; float dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; vec3_t newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if (nump > MAX_CLIP_VERTS-2) VID_Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS"); if (stage == 6) { // fully clipped, so draw it DrawSkyPolygon (nump, vecs); return; } front = back = false; norm = skyclip[stage]; for (i=0, v = vecs ; i<nump ; i++, v+=3) { d = DotProduct (v, norm); if (d > ON_EPSILON) { front = true; sides[i] = SIDE_FRONT; } else if (d < -ON_EPSILON) { back = true; sides[i] = SIDE_BACK; } else sides[i] = SIDE_ON; dists[i] = d; } if (!front || !back) { // not clipped ClipSkyPolygon (nump, vecs, stage+1); return; } // clip it sides[i] = sides[0]; dists[i] = dists[0]; VectorCopy (vecs, (vecs+(i*3)) ); newc[0] = newc[1] = 0; for (i=0, v = vecs ; i<nump ; i++, v+=3) { switch (sides[i]) { case SIDE_FRONT: VectorCopy (v, newv[0][newc[0]]); newc[0]++; break; case SIDE_BACK: VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; case SIDE_ON: VectorCopy (v, newv[0][newc[0]]); newc[0]++; VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; } if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; d = dists[i] / (dists[i] - dists[i+1]); for (j=0 ; j<3 ; j++) { e = v[j] + d*(v[j+3] - v[j]); newv[0][newc[0]][j] = e; newv[1][newc[1]][j] = e; } newc[0]++; newc[1]++; } // continue ClipSkyPolygon (newc[0], newv[0][0], stage+1); ClipSkyPolygon (newc[1], newv[1][0], stage+1); }
/* * Initializes the OpenGL window */ static qboolean GLimp_InitGraphics(qboolean fullscreen) { int flags; int msaa_samples; int stencil_bits; int width, height; char title[24]; if (GetWindowSize(&width, &height) && (width == vid.width) && (height == vid.height)) { /* If we want fullscreen, but aren't */ if (fullscreen != IsFullscreen()) { GLimp_ToggleFullscreen(); } /* Are we now? */ if (fullscreen == IsFullscreen()) { return true; } } /* Is the surface used? */ if (window) { #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); #else SDL_FreeSurface(window); #endif } /* Create the window */ VID_NewWindow(vid.width, vid.height); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); if (gl_msaa_samples->value) { msaa_samples = gl_msaa_samples->value; if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) == -1) { Com_Printf("MSAA is unsupported: %s\n", SDL_GetError()); Cvar_SetValue ("gl_msaa_samples", 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); } else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) == -1) { Com_Printf("MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError()); Cvar_SetValue("gl_msaa_samples", 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); } } /* Initiate the flags */ flags = SDL_OPENGL; if (fullscreen) { flags |= SDL_FULLSCREEN; } #if !SDL_VERSION_ATLEAST(2, 0, 0) /* For SDL1.2, these things must be done before creating the window */ /* Set the icon */ SetSDLIcon(); /* Set vsync */ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, gl_swapinterval->value ? 1 : 0); #endif while (1) { if (!CreateSDLWindow(flags)) { if (gl_msaa_samples->value) { VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n", SDL_GetError()); VID_Printf(PRINT_ALL, "Reverting to %s gl_mode %i (%ix%i) without MSAA.\n", (flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed", (int)Cvar_VariableValue("gl_mode"), vid.width, vid.height); /* Try to recover */ Cvar_SetValue("gl_msaa_samples", 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); } else if (vid.width != 640 || vid.height != 480 || (flags & SDL_FULLSCREEN)) { VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n", SDL_GetError()); VID_Printf(PRINT_ALL, "Reverting to windowed gl_mode 4 (640x480).\n"); /* Try to recover */ Cvar_SetValue("gl_mode", 4); Cvar_SetValue("vid_fullscreen", 0); vid.width = 640; vid.height = 480; flags &= ~SDL_FULLSCREEN; } else { VID_Error(ERR_FATAL, "Failed to revert to gl_mode 4. Exiting...\n"); return false; } } else { break; } } #if SDL_VERSION_ATLEAST(2, 0, 0) /* For SDL2, these things must be done after creating the window */ /* Set the icon */ SetSDLIcon(); /* Set vsync - TODO: -1 could be set for "late swap tearing" */ SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0); #endif /* Initialize the stencil buffer */ if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits)) { VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits); if (stencil_bits >= 1) { have_stencil = true; } } /* Initialize hardware gamma */ InitGamma(); /* Window title */ snprintf(title, sizeof(title), "Yamagi Quake II %s", YQ2VERSION); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetWindowTitle(window, title); #else SDL_WM_SetCaption(title, title); #endif /* No cursor */ SDL_ShowCursor(0); return true; }
/* ================= Mod_LoadBrushModel ================= */ void Mod_LoadBrushModel (model_t *mod, void *buffer) { int i; dheader_t *header; mmodel_t *bm; loadmodel->type = mod_brush; if (loadmodel != mod_known) VID_Error (ERR_DROP, "Loaded a brush model after the world"); header = (dheader_t *)buffer; i = LittleLong(header->version); if (i != BSPVERSION) VID_Error (ERR_DROP, "Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); // swap all the lumps mod_base = (byte *)header; //r1: check header pointers point within allocated data for (i = 0; i < MAX_LUMPS; i++) { //for some reason there are unused lumps with invalid values if (i == LUMP_POP) continue; if (header->lumps[i].fileofs < 0 || header->lumps[i].filelen < 0 || header->lumps[i].fileofs + header->lumps[i].filelen > modfilelen) VID_Error (ERR_DROP, "Mod_LoadBrushModel: offset %d of size %d is out of bounds (%s is possibly truncated)", header->lumps[i].fileofs, header->lumps[i].filelen, mod->name); } // load into heap Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); Mod_LoadEdges (&header->lumps[LUMP_EDGES]); Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); Mod_LoadFaces (&header->lumps[LUMP_FACES]); Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]); Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); Mod_LoadNodes (&header->lumps[LUMP_NODES]); Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); mod->numframes = 2; // regular and alternate animation // // set up the submodels // for (i=0 ; i<mod->numsubmodels ; i++) { model_t *starmod; bm = &mod->submodels[i]; starmod = &mod_inline[i]; *starmod = *loadmodel; starmod->firstmodelsurface = bm->firstface; starmod->nummodelsurfaces = bm->numfaces; starmod->firstnode = bm->headnode; if (starmod->firstnode >= loadmodel->numnodes) VID_Error (ERR_DROP, "Inline model %i has bad firstnode", i); FastVectorCopy (bm->maxs, starmod->maxs); FastVectorCopy (bm->mins, starmod->mins); starmod->radius = bm->radius; if (i == 0) *loadmodel = *starmod; starmod->numleafs = bm->visleafs; } }
/* * Initializes the OpenGL window */ static qboolean GLimp_InitGraphics(qboolean fullscreen) { int counter = 0; int flags; int stencil_bits; char title[24]; //QUAKETOON: forcing window fullscreen = false; if (surface && (surface->w == vid.width) && (surface->h == vid.height)) { /* Are we running fullscreen? */ int isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0; /* We should, but we don't */ if (fullscreen != isfullscreen) { SDL_WM_ToggleFullScreen(surface); } /* Do we now? */ isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0; if (fullscreen == isfullscreen) { return true; } } /* Is the surface used? */ if (surface) { SDL_FreeSurface(surface); } /* Create the window */ VID_NewWindow(vid.width, vid.height); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); /* Initiate the flags */ flags = SDL_OPENGL; if (fullscreen) { flags |= SDL_FULLSCREEN; } /* Set the icon */ SetSDLIcon(); /* Enable vsync */ /* if (gl_swapinterval->value) { SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); } */ while (1) { if ((surface = SDL_SetVideoMode(vid.width, vid.height, 0, flags)) == NULL) { if (counter == 1) { VID_Error(ERR_FATAL, "Failed to revert to gl_mode 4. Exiting...\n"); return false; } VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n", SDL_GetError()); VID_Printf(PRINT_ALL, "Reverting to gl_mode 4 (640x480) and windowed mode.\n"); /* Try to recover */ Cvar_SetValue("gl_mode", 4); Cvar_SetValue("vid_fullscreen", 0); vid.width = 640; vid.height = 480; counter++; continue; } else { break; } } /* Initialize the stencil buffer */ if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits)) { VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits); if (stencil_bits >= 1) { have_stencil = true; } } /* Initialize hardware gamma */ #ifdef X11GAMMA if ((dpy = XOpenDisplay(displayname)) == NULL) { VID_Printf(PRINT_ALL, "Unable to open display.\n"); } else { if (screen == -1) { screen = DefaultScreen(dpy); } gl_state.hwgamma = true; vid_gamma->modified = true; XF86VidModeGetGamma(dpy, screen, &x11_oldgamma); VID_Printf(PRINT_ALL, "Using hardware gamma via X11.\n"); } #else //gl_state.hwgamma = true; vid_gamma->modified = true; VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n"); #endif /* Window title */ snprintf(title, sizeof(title), "QuakeToon %f", (float) VERSION); SDL_WM_SetCaption(title, title); /* No cursor */ SDL_ShowCursor(0); return true; }
void SubdividePolygon (int numverts, float *verts) { int i, j, k; vec3_t mins, maxs; float m; float *v; vec3_t front[64], back[64]; int f, b, size; float dist[64]; float frac; glpoly_t *poly; float s, t; vec3_t total; float total_s, total_t; if (numverts > 60) VID_Error (ERR_DROP, "numverts = %i", numverts); BoundPoly (numverts, verts, mins, maxs); for (i=0; i<3; i++) { m = (mins[i] + maxs[i]) * 0.5; m = SUBDIVIDE_SIZE * floor (m/SUBDIVIDE_SIZE + 0.5); if (maxs[i] - m < 8) continue; if (m - mins[i] < 8) continue; // cut it v = verts + i; for (j=0; j<numverts; j++, v+= 3) dist[j] = *v - m; // wrap cases dist[j] = dist[0]; v-=i; VectorCopy (verts, v); f = b = 0; v = verts; for (j=0; j<numverts; j++, v+= 3) { if (dist[j] >= 0) { VectorCopy (v, front[f]); f++; } if (dist[j] <= 0) { VectorCopy (v, back[b]); b++; } if (dist[j] == 0 || dist[j+1] == 0) continue; if ( (dist[j] > 0) != (dist[j+1] > 0) ) { // clip point frac = dist[j] / (dist[j] - dist[j+1]); for (k=0; k<3; k++) front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); f++; b++; } } SubdividePolygon (f, front[0]); SubdividePolygon (b, back[0]); return; } // add a point in the center to help keep warp valid poly = Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float)); poly->next = warpface->polys; warpface->polys = poly; poly->numverts = numverts+2; // alloc vertex light fields size = poly->numverts*3*sizeof(byte); poly->vertexlight = Hunk_Alloc(size); poly->vertexlightbase = Hunk_Alloc(size); memset(poly->vertexlight, 0, size); memset(poly->vertexlightbase, 0, size); poly->vertexlightset = false; VectorClear (total); total_s = 0; total_t = 0; for (i=0; i<numverts; i++, verts+=3) { VectorCopy (verts, poly->verts[i+1]); s = DotProduct (verts, warpface->texinfo->vecs[0]); t = DotProduct (verts, warpface->texinfo->vecs[1]); total_s += s; total_t += t; VectorAdd (total, verts, total); poly->verts[i+1][3] = s; poly->verts[i+1][4] = t; } VectorScale (total, (1.0/(float)numverts), poly->verts[0]); VectorCopy(poly->verts[0], poly->center); // for vertex lighting poly->verts[0][3] = total_s/numverts; poly->verts[0][4] = total_t/numverts; // copy first vertex to last memcpy (poly->verts[i+1], poly->verts[1], sizeof(poly->verts[0])); }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel (model_t *mod, void *buffer) { unsigned int i; dmdl_t header; dmdl_t *pinmodel, *pheader; dstvert_t *pinst, *poutst; dtriangle_t *pintri, *pouttri; daliasframe_t *pinframe, *poutframe; int *pincmd, *poutcmd; int version; unsigned int required; char *skin_name; pinmodel = (dmdl_t *)buffer; version = LittleLong(pinmodel->version); if (version != ALIAS_VERSION) VID_Error (ERR_DROP, "%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); //pheader = Hunk_Alloc (size); pheader = &header; // byte swap the header fields and sanity check memcpy (pheader, buffer, sizeof(dmdl_t)); if (pheader->skinheight > MAX_LBM_HEIGHT) Com_DPrintf("model %s has a skin taller than traditional maximum of %d", mod->name, MAX_LBM_HEIGHT); if (pheader->num_xyz <= 0) VID_Error (ERR_DROP, "model %s has no vertices", mod->name); if (pheader->num_xyz > MAX_VERTS) VID_Error (ERR_DROP, "model %s has too many vertices", mod->name); if (pheader->num_st <= 0) VID_Error (ERR_DROP, "model %s has no st vertices", mod->name); if (pheader->num_tris <= 0) VID_Error (ERR_DROP, "model %s has no triangles", mod->name); if (pheader->num_frames <= 0) VID_Error (ERR_DROP, "model %s has no frames", mod->name); if (pheader->num_skins >= 31) VID_Error (ERR_DROP, "model %s has too many skins", mod->name); if (pheader->ofs_st <= 0 || pheader->ofs_frames <= 0 || pheader->ofs_glcmds <= 0 || pheader->ofs_skins <= 0 || pheader->ofs_tris <= 0) VID_Error (ERR_DROP, "model %s has invalid offsets", mod->name); required = 0; required += sizeof(dmdl_t); required += pheader->num_st * sizeof(dstvert_t); required += pheader->num_tris * sizeof(dtriangle_t); required += pheader->num_frames * (sizeof(daliasframe_t)-4); //variable sized required += pheader->num_xyz * pheader->num_frames * sizeof(dtrivertx_t); required += pheader->num_glcmds * sizeof(int); required += pheader->num_skins * MAX_SKINNAME; if (pheader->ofs_end != required) VID_Error (ERR_DROP, "model %s has bad size header (%d != %d)", mod->name, pheader->ofs_end, required); if (pheader->ofs_frames + pheader->num_frames * sizeof(daliasframe_t) > required) VID_Error (ERR_DROP, "model %s has illegal frames offset", mod->name); if (pheader->ofs_glcmds + pheader->num_glcmds * sizeof(int) > required) VID_Error (ERR_DROP, "model %s has illegal glcmds offset", mod->name); if (pheader->ofs_skins + pheader->num_skins * MAX_SKINNAME > required) VID_Error (ERR_DROP, "model %s has illegal skins offset", mod->name); if (pheader->ofs_st + pheader->num_st * sizeof(dstvert_t) > required) VID_Error (ERR_DROP, "model %s has illegal vertices offset", mod->name); if (pheader->ofs_tris + pheader->num_tris * sizeof(dtriangle_t) > required) VID_Error (ERR_DROP, "model %s has illegal triangles offset", mod->name); if (pheader->framesize * pheader->num_frames != pheader->num_frames * (int)((sizeof(daliasframe_t)-4) + pheader->num_xyz*sizeof(dtrivertx_t))) VID_Error (ERR_DROP, "model %s has invalid frame size", mod->name); pheader = (dmdl_t *) Hunk_Alloc (required); memcpy (pheader, &header, sizeof(dmdl_t)); // // load base s and t vertices (not used in gl version) // pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st); poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st); memcpy (poutst, pinst, pheader->num_st * sizeof(dstvert_t)); // // load triangle lists // pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris); pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris); memcpy (pouttri, pintri, pheader->num_tris * sizeof(dtriangle_t)); // // load the frames // for (i=0 ; i<pheader->num_frames ; i++) { pinframe = (daliasframe_t *) ((byte *)pinmodel + pheader->ofs_frames + i * pheader->framesize); poutframe = (daliasframe_t *) ((byte *)pheader + pheader->ofs_frames + i * pheader->framesize); memcpy (poutframe, pinframe, sizeof(daliasframe_t)-4); memcpy (poutframe->verts, pinframe->verts, pheader->num_xyz*sizeof(dtrivertx_t)); } mod->type = mod_alias; // // load the glcmds // pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds); poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds); memcpy (poutcmd, pincmd, pheader->num_glcmds * sizeof(int)); // register all skins memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins, pheader->num_skins*MAX_SKINNAME); for (i=0 ; i<pheader->num_skins ; i++) { skin_name = (char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME; fast_strlwr (skin_name); mod->skins[i] = GL_FindImage (skin_name, skin_name, it_skin); } mod->mins[0] = -32; mod->mins[1] = -32; mod->mins[2] = -32; mod->maxs[0] = 32; mod->maxs[1] = 32; mod->maxs[2] = 32; }
/* ================= Mod_LoadFaces ================= */ void Mod_LoadFaces (lump_t *l) { dface_t *in; msurface_t *out; int i, count, surfnum; int planenum, side; int ti; in = (dface_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadFaces: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (msurface_t *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->surfaces = out; loadmodel->numsurfaces = count; currentmodel = loadmodel; GL_BeginBuildingLightmaps (); for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++) { out->firstedge = LittleLong(in->firstedge); out->numedges = LittleShort(in->numedges); out->flags = 0; out->polys = NULL; out->texturechain = NULL; out->lightmapchain = NULL; out->dlight_s = 0; out->dlight_t = 0; out->dlightframe = 0; out->dlightbits = 0; out->visframe = 0; planenum = LittleShort(in->planenum); side = LittleShort(in->side); if (side) out->flags |= SURF_PLANEBACK; out->plane = loadmodel->planes + planenum; ti = LittleShort(in->texinfo); if (ti < 0 || ti >= loadmodel->numtexinfo) VID_Error (ERR_DROP, "MOD_LoadBmodel: bad texinfo number"); out->texinfo = loadmodel->texinfo + ti; CalcSurfaceExtents (out); // lighting info //for (i=0 ; i<MAXLIGHTMAPS ; i++) //out->styles[i] = in->styles[i]; memcpy (out->styles, in->styles, sizeof(byte) * MAXLIGHTMAPS); i = LittleLong(in->lightofs); if (i == -1) out->samples = NULL; else out->samples = loadmodel->lightdata + i; // set the drawing flags if (out->texinfo->flags & SURF_WARP) { out->flags |= SURF_DRAWTURB; for (i=0 ; i<2 ; i++) { out->extents[i] = 16384; out->texturemins[i] = -8192; } GL_SubdivideSurface (out); // cut up polygon for warps } // create lightmaps and polygons if (!(out->texinfo->flags & SURF_WARP)) { if (!(out->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_DRAWSKY|SURF_DRAWTURB))) { GL_CreateSurfaceLightmap (out); } else { out->light_s = out->light_t = 0; } GL_BuildPolygonFromSurface(out); } } GL_EndBuildingLightmaps (); }
/* ================= Mod_LoadTexinfo ================= */ void Mod_LoadTexinfo (lump_t *l) { texinfo_t *in; // image_t *last_image; mtexinfo_t *out, *step; int i, count; char name[MAX_QPATH]; int next; size_t length; in = (texinfo_t *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) VID_Error (ERR_DROP, "Mod_LoadTexinfo: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = (mtexinfo_t *) Hunk_Alloc ( count*sizeof(*out)); loadmodel->texinfo = out; loadmodel->numtexinfo = count; for ( i=0 ; i<count ; i++, in++, out++) { memcpy (out->vecs, in->vecs, sizeof(out->vecs)); out->flags = LittleLong(in->flags); next = LittleLong(in->nexttexinfo); if (next > 0) out->next = loadmodel->texinfo + next; else out->next = NULL; fast_strlwr (in->texture); out->image = GL_FindImageBase (in->texture, it_wall); if (out->image) continue; Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture); if (!GetWalInfo (name, &global_hax_texture_x, &global_hax_texture_y)) { VID_Printf (PRINT_ALL, "Couldn't load %s\n", name); out->image = r_notexture; continue; } length = strlen(name); if (load_tga_wals) { //Com_sprintf (name, sizeof(name), "textures/%s.tga", in->texture); memcpy (name + length-3, "tga", 3); out->image = GL_FindImage (name, in->texture, it_wall); } else { out->image = NULL; } if (!out->image) { if (load_png_wals) { memcpy (name + length-3, "png", 3); //Com_sprintf (name, sizeof(name), "textures/%s.png", in->texture); out->image = GL_FindImage (name, in->texture, it_wall); } if (!out->image) { if (load_jpg_wals) { memcpy (name + length-3, "jpg", 3); //Com_sprintf (name, sizeof(name), "textures/%s.jpg", in->texture); out->image = GL_FindImage (name, in->texture, it_wall); } if (!out->image) { memcpy (name + length-3, "wal", 3); //Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture); out->image = GL_FindImage (name, in->texture, it_wall); if (!out->image) { VID_Printf (PRINT_ALL, "Couldn't load %s\n", name); out->image = r_notexture; } } } } //last_image = out->image; global_hax_texture_x = global_hax_texture_y = 0; } // count animation frames for (i=0 ; i<count ; i++) { out = &loadmodel->texinfo[i]; out->numframes = 1; for (step = out->next ; step && step != out ; step=step->next) out->numframes++; } }
qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) { WNDCLASS wc; RECT r; cvar_t *vid_xpos, *vid_ypos; int stylebits; int x, y, w, h; int exstyle; /* Register the frame class */ wc.style = 0; wc.lpfnWndProc = (WNDPROC)glw_state.wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = glw_state.hInstance; if (modType("xatrix")) { // q2mp1 wc.hIcon = LoadIcon(glw_state.hInstance, MAKEINTRESOURCE(IDI_ICON2)); //wc.lpszClassName = WINDOW_CLASS_NAME2; } else if (modType("rogue")) { // q2mp2 wc.hIcon = LoadIcon(glw_state.hInstance, MAKEINTRESOURCE(IDI_ICON3)); //wc.lpszClassName = WINDOW_CLASS_NAME3; } else { wc.hIcon = LoadIcon(glw_state.hInstance, MAKEINTRESOURCE(IDI_ICON1)); } wc.hCursor = LoadCursor (NULL,IDC_ARROW); wc.hbrBackground = (void *)COLOR_GRAYTEXT; wc.lpszMenuName = 0; wc.lpszClassName = WINDOW_CLASS_NAME; if (!RegisterClass (&wc) ) VID_Error (ERR_FATAL, "Couldn't register window class"); if (fullscreen) { exstyle = WS_EX_TOPMOST; //stylebits = WS_POPUP|WS_VISIBLE; stylebits = WS_POPUP|WS_SYSMENU|WS_VISIBLE; } else { exstyle = 0; //stylebits = WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE; stylebits = WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_VISIBLE; } r.left = 0; r.top = 0; r.right = width; r.bottom = height; AdjustWindowRect (&r, stylebits, FALSE); w = r.right - r.left; h = r.bottom - r.top; if (fullscreen) { x = 0; y = 0; } else { vid_xpos = Cvar_Get ("vid_xpos", "0", 0); vid_ypos = Cvar_Get ("vid_ypos", "0", 0); x = vid_xpos->value; y = vid_ypos->value; } glw_state.hWnd = CreateWindowEx ( exstyle, WINDOW_CLASS_NAME, "Thirty Flights of Loving", //Knightmare changed stylebits, x, y, w, h, NULL, NULL, glw_state.hInstance, NULL); if (!glw_state.hWnd) VID_Error (ERR_FATAL, "Couldn't create window"); ShowWindow( glw_state.hWnd, SW_SHOW ); UpdateWindow( glw_state.hWnd ); // init all the gl stuff for the window if (!GLimp_InitGL ()) { VID_Printf( PRINT_ALL, "VID_CreateWindow() - GLimp_InitGL failed\n"); return false; } SetForegroundWindow( glw_state.hWnd ); SetFocus( glw_state.hWnd ); // let the sound and input subsystems know about the new window VID_NewWindow (width, height); return true; }
/* ================== Mod_ForName Loads in a model for the given name ================== */ model_t *Mod_ForName (const char *name_, qboolean crash) { model_t *mod; model_t *modelhash; mscache_t *model_size; byte *buf; int i; unsigned hash; size_t len = strlen(name_); char *name = (char *) alloca(len + 1); strcpy(name, name_); if (!name || !name[0]) VID_Error (ERR_DROP, "Mod_ForName: NULL name"); // // inline models are grabbed only from worldmodel // if (name[0] == '*') { i = atoi(name+1); if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels) VID_Error (ERR_DROP, "bad inline model number %d", i); return &mod_inline[i]; } fast_strlwr (name); hash = hashify (name) % MODEL_HASH_SIZE; for (modelhash = models_hash[hash]; modelhash; modelhash = modelhash->hash_next) { if (!strcmp (modelhash->name, name)) { return modelhash; } } for (model_size = model_size_cache[hash]; model_size; model_size = model_size->hash_next) { if (!strcmp (model_size->name, name)) break; } // // search the currently loaded models // /*for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) { if (!mod->name[0] || mod->hash != hash) continue; if (!strcmp (mod->name, name) ) return mod; }*/ // // find a free model slot spot // for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) { if (!mod->name[0]) break; // free spot } if (i == mod_numknown) { if (mod_numknown == MAX_MOD_KNOWN) VID_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN"); mod_numknown++; } strncpy (mod->name, name, sizeof(mod->name)-1); // // load the file // modfilelen = FS_LoadFile (name, (void **)&buf); if (!buf) { if (crash) VID_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name); mod->name[0] = 0; return NULL; } loadmodel = mod; // // fill it in // // call the apropriate loader switch (LittleLong(*(unsigned *)buf)) { case IDALIASHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x200000, 0); Mod_LoadAliasModel (mod, buf); break; case IDSPRITEHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x4000, 0); Mod_LoadSpriteModel (mod, buf); break; case IDBSPHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x1000000, 0); Mod_LoadBrushModel (mod, buf); break; default: VID_Error (ERR_DROP,"Mod_NumForName: unknown 0x%.8x fileid for %s", LittleLong(*(unsigned *)buf), mod->name); break; } if (model_size) { loadmodel->extradatasize = model_size->size; } else { loadmodel->extradatasize = Hunk_End (); model_size = (mscache_t *) malloc (sizeof(*model_size)); if (!model_size) VID_Error (ERR_FATAL, "Mod_ForName: out of memory"); strcpy (model_size->name, mod->name); model_size->size = loadmodel->extradatasize; model_size->hash_next = model_size_cache[hash]; model_size_cache[hash] = model_size; } mod->hash_next = models_hash[hash]; models_hash[hash] = mod; FS_FreeFile (buf); return mod; }