- Con_Printf ("R_DrawSprite: no such frame %d\n", frame);
- frame = 0;
- }
-
- if (psprite->frames[frame].type == SPR_SINGLE)
- {
- if (currententity->draw_lastmodel == currententity->model && currententity->draw_lerpstart < cl.time)
- {
- if (frame != currententity->draw_pose)
- {
- currententity->draw_lastpose = currententity->draw_pose;
- currententity->draw_pose = frame;
- currententity->draw_lerpstart = cl.time;
- *framelerp = 0;
- }
- else
- *framelerp = (cl.time - currententity->draw_lerpstart) * 10.0;
- }
- else // uninitialized
- {
- currententity->draw_lastmodel = currententity->model;
- currententity->draw_lastpose = currententity->draw_pose = frame;
- currententity->draw_lerpstart = cl.time;
- *framelerp = 0;
- }
- *oldframe = psprite->frames[currententity->draw_lastpose].frameptr;
- *newframe = psprite->frames[frame].frameptr;
- }
- else
- {
- pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
- pintervals = pspritegroup->intervals;
- numframes = pspritegroup->numframes;
- fullinterval = pintervals[numframes-1];
-
- time = cl.time + currententity->syncbase;
-
- // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
- // are positive, so we don't have to worry about division by 0
- targettime = time - ((int)(time / fullinterval)) * fullinterval;
-
- // LordHavoc: since I can't measure the time properly when it loops from numframes-1 to 0,
- // I instead measure the time of the first frame, hoping it is consistent
- j = numframes-1;jtime = 0;jinterval = pintervals[1] - pintervals[0];
- for (i=0 ; i<(numframes-1) ; i++)
- {
- if (pintervals[i] > targettime)
- break;
- j = i;jinterval = pintervals[i] - jtime;jtime = pintervals[i];
- }
- *framelerp = (targettime - jtime) / jinterval;
-
- *oldframe = pspritegroup->frames[j];
- *newframe = pspritegroup->frames[i];
+ case SPR_VP_PARALLEL_UPRIGHT:
+ // flames and such
+ // vertical beam sprite, faces view plane
+ scale = ent->scale / sqrt(r_viewforward[0]*r_viewforward[0]+r_viewforward[1]*r_viewforward[1]);
+ left[0] = -r_viewforward[1] * scale;
+ left[1] = r_viewforward[0] * scale;
+ left[2] = 0;
+ up[0] = 0;
+ up[1] = 0;
+ up[2] = ent->scale;
+ break;
+ case SPR_FACING_UPRIGHT:
+ // flames and such
+ // vertical beam sprite, faces viewer's origin (not the view plane)
+ scale = ent->scale / sqrt((org[0] - r_vieworigin[0])*(org[0] - r_vieworigin[0])+(org[1] - r_vieworigin[1])*(org[1] - r_vieworigin[1]));
+ left[0] = (org[1] - r_vieworigin[1]) * scale;
+ left[1] = -(org[0] - r_vieworigin[0]) * scale;
+ left[2] = 0;
+ up[0] = 0;
+ up[1] = 0;
+ up[2] = ent->scale;
+ break;
+ default:
+ Con_Printf("R_SpriteSetup: unknown sprite type %i\n", type);
+ // fall through to normal sprite
+ case SPR_VP_PARALLEL:
+ // normal sprite
+ // faces view plane
+ left[0] = r_viewleft[0] * ent->scale;
+ left[1] = r_viewleft[1] * ent->scale;
+ left[2] = r_viewleft[2] * ent->scale;
+ up[0] = r_viewup[0] * ent->scale;
+ up[1] = r_viewup[1] * ent->scale;
+ up[2] = r_viewup[2] * ent->scale;
+ break;
+ case SPR_ORIENTED:
+ // bullet marks on walls
+ // ignores viewer entirely
+ left[0] = ent->matrix.m[0][1];
+ left[1] = ent->matrix.m[1][1];
+ left[2] = ent->matrix.m[2][1];
+ up[0] = ent->matrix.m[0][2];
+ up[1] = ent->matrix.m[1][2];
+ up[2] = ent->matrix.m[2][2];
+ break;
+ case SPR_VP_PARALLEL_ORIENTED:
+ // I have no idea what people would use this for...
+ // oriented relative to view space
+ // FIXME: test this and make sure it mimicks software
+ left[0] = ent->matrix.m[0][1] * r_viewforward[0] + ent->matrix.m[1][1] * r_viewleft[0] + ent->matrix.m[2][1] * r_viewup[0];
+ left[1] = ent->matrix.m[0][1] * r_viewforward[1] + ent->matrix.m[1][1] * r_viewleft[1] + ent->matrix.m[2][1] * r_viewup[1];
+ left[2] = ent->matrix.m[0][1] * r_viewforward[2] + ent->matrix.m[1][1] * r_viewleft[2] + ent->matrix.m[2][1] * r_viewup[2];
+ up[0] = ent->matrix.m[0][2] * r_viewforward[0] + ent->matrix.m[1][2] * r_viewleft[0] + ent->matrix.m[2][2] * r_viewup[0];
+ up[1] = ent->matrix.m[0][2] * r_viewforward[1] + ent->matrix.m[1][2] * r_viewleft[1] + ent->matrix.m[2][2] * r_viewup[1];
+ up[2] = ent->matrix.m[0][2] * r_viewforward[2] + ent->matrix.m[1][2] * r_viewleft[2] + ent->matrix.m[2][2] * r_viewup[2];
+ break;