void collision_response_slide(void* x, vec3* position, vec3* velocity, collision (*colfunc)(void* x, vec3* pos, vec3* vel) ) { collision col = colfunc(x, position, velocity); int count = 0; while (col.collided) { //renderer_add(x, render_object_line(*position, vec3_add(*position, col.norm), vec3_red(), count+1)); if (count++ == 100) { *velocity = vec3_zero(); break; } vec3 fwrd = vec3_mul(*velocity, col.time); float len = max(vec3_length(fwrd) - 0.001, 0.0) / vec3_length(fwrd); vec3 move = vec3_add(*position, vec3_mul(fwrd, len)); vec3 proj = vec3_project(vec3_mul(*velocity, (1.0-col.time)), col.norm); //renderer_add(x, render_object_line(*position, vec3_add(*position, vec3_normalize(proj)), vec3_green(), count+1)); *position = move; *velocity = proj; col = colfunc(x, position, velocity); } *position = vec3_add(*position, *velocity); }
// // R_DrawPlanes // At the end of each frame. // void R_DrawPlane (visplane_t *pl) { int light; int x; int stop; int angle; if (pl->minx > pl->maxx) return; // sky flat if (pl->picnum == skyflatnum) { dc_iscale = pspriteiscale>>detailshift; // Sky is allways drawn full bright, // i.e. colormaps[0] is used. // Because of this hack, sky is not affected // by INVUL inverse mapping. dc_colormap = colormaps; dc_texturemid = skytexturemid; for (x=pl->minx ; x <= pl->maxx ; x++) { dc_yl = pl->top[x]; dc_yh = pl->bottom[x]; if (dc_yl <= dc_yh) { angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; dc_x = x; dc_source = R_GetColumn(skytexture, angle); colfunc (); } }
// // R_DrawPlanes // At the end of each frame. // void R_DrawPlanes (void) { visplane_t* pl; int light; int x; int stop; int angle; int lumpnum; #ifdef RANGECHECK if (ds_p - drawsegs > MAXDRAWSEGS) I_Error ("R_DrawPlanes: drawsegs overflow (%i)", ds_p - drawsegs); if (lastvisplane - visplanes > MAXVISPLANES) I_Error ("R_DrawPlanes: visplane overflow (%i)", lastvisplane - visplanes); if (lastopening - openings > MAXOPENINGS) I_Error ("R_DrawPlanes: opening overflow (%i)", lastopening - openings); #endif for (pl = visplanes ; pl < lastvisplane ; pl++) { if (pl->minx > pl->maxx) continue; // sky flat if (pl->picnum == skyflatnum) { dc_iscale = pspriteiscale>>detailshift; // Sky is allways drawn full bright, // i.e. colormaps[0] is used. // Because of this hack, sky is not affected // by INVUL inverse mapping. dc_colormap = colormaps; dc_texturemid = skytexturemid; for (x=pl->minx ; x <= pl->maxx ; x++) { dc_yl = pl->top[x]; dc_yh = pl->bottom[x]; if (dc_yl <= dc_yh) { angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; dc_x = x; dc_source = R_GetColumn(skytexture, angle); colfunc (); } } continue; }
static void R_DrawMaskedSpriteColumn(column_t *column, int baseclip) { while (column->topdelta != 0xff) { // calculate unclipped screen coordinates for post int topscreen = sprtopscreen + spryscale * column->topdelta + 1; dc_yl = MAX((topscreen + FRACUNIT) >> FRACBITS, mceilingclip[dc_x] + 1); dc_yh = MIN((topscreen + spryscale * column->length) >> FRACBITS, mfloorclip[dc_x] - 1); if (baseclip != -1) dc_yh = MIN(baseclip, dc_yh); fuzzclip = baseclip; dc_texturefrac = dc_texturemid - (column->topdelta << FRACBITS) + FixedMul((dc_yl - centery) << FRACBITS, dc_iscale); if (dc_texturefrac < 0) { int cnt = (FixedDiv(-dc_texturefrac, dc_iscale) + FRACUNIT - 1) >> FRACBITS; dc_yl += cnt; dc_texturefrac += cnt * dc_iscale; } { const fixed_t endfrac = dc_texturefrac + (dc_yh - dc_yl) * dc_iscale; const fixed_t maxfrac = column->length << FRACBITS; if (endfrac >= maxfrac) dc_yh -= (FixedDiv(endfrac - maxfrac - 1, dc_iscale) + FRACUNIT - 1) >> FRACBITS; } if (dc_yl <= dc_yh && dc_yh < viewheight) { dc_source = (byte *)column + 3; colfunc(); } column = (column_t *)((byte *)column + column->length + 4); }
void R_DrawMaskedColumn(column_t *column) { int topscreen, bottomscreen; fixed_t basetexturemid = dc_texturemid; dc_texheight = 0; // killough 11/98 while (column->topdelta != 0xff) { // calculate unclipped screen coordinates for post topscreen = sprtopscreen + spryscale*column->topdelta; bottomscreen = topscreen + spryscale*column->length; // Here's where "sparkles" come in -- killough: dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; if (dc_yh >= mfloorclip[dc_x]) dc_yh = mfloorclip[dc_x]-1; if (dc_yl <= mceilingclip[dc_x]) dc_yl = mceilingclip[dc_x]+1; // killough 3/2/98, 3/27/98: Failsafe against overflow/crash: if (dc_yl <= dc_yh && dc_yh < viewheight ) { dc_source = (byte *) column + 3; dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS); // Drawn by either R_DrawColumn // or (SHADOW) R_DrawFuzzColumn. colfunc(); } column = (column_t *)((byte *) column + column->length + 4); } dc_texturemid = basetexturemid; }
static int __collision( INSTANCE * my, int id, int colltype ) { INSTANCE * ptr, ** ctx ; int status, p ; int ( *colfunc )( INSTANCE *, GRAPH *, REGION *, INSTANCE * ); REGION bbox1 ; GRAPH * bmp1 ; if ( id == -1 ) return ( check_collision_with_mouse( my, colltype ) ) ? 1 : 0 ; switch ( colltype ) { case COLLISION_NORMAL: colfunc = check_collision; break; case COLLISION_BOX: colfunc = check_collision_box; break; case COLLISION_CIRCLE: colfunc = check_collision_circle; break; default: return 0; } bmp1 = instance_graph( my ) ; if ( !bmp1 ) return 0 ; instance_get_bbox( my, bmp1, &bbox1 ); int ctype = LOCDWORD( mod_grproc, my, CTYPE ); /* Checks only for a single instance */ if ( id >= FIRST_INSTANCE_ID ) return ( ( ( ptr = instance_get( id ) ) && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) ) ? colfunc( my, bmp1, &bbox1, ptr ) : 0 ) ; /* we must use full list of instances or get types from it */ ptr = first_instance ; if ( !id ) { LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) = 0 ; if ( ( p = LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) ) ) { ptr = instance_get( p ) ; if ( ptr ) ptr = ptr->next ; } while ( ptr ) { if ( ptr != my && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) && ( ( status = ( LOCDWORD( mod_grproc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) ) == STATUS_RUNNING || status == STATUS_FROZEN ) && colfunc( my, bmp1, &bbox1, ptr ) ) { LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) = LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; return LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; } ptr = ptr->next ; } return 0 ; } LOCDWORD( mod_grproc, my, GRPROC_ID_SCAN ) = 0 ; /* Check if already in scan by type and we reach limit */ ctx = ( INSTANCE ** ) LOCADDR( mod_grproc, my, GRPROC_CONTEXT ); if ( LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) != id ) /* Check if type change from last call */ { *ctx = NULL; LOCDWORD( mod_grproc, my, GRPROC_TYPE_SCAN ) = id; } while ( ( ptr = instance_get_by_type( id, ctx ) ) ) { if ( ptr != my && ctype == LOCDWORD( mod_grproc, ptr, CTYPE ) && ( ( status = ( LOCDWORD( mod_grproc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) ) == STATUS_RUNNING || status == STATUS_FROZEN ) && colfunc( my, bmp1, &bbox1, ptr ) ) { return LOCDWORD( mod_grproc, ptr, PROCESS_ID ) ; } } return 0 ; }
//----------------------------------------------------------------------------- // // R_DrawPlanes // At the end of each frame. // void R_DrawPlanes(void) { int i; visplane_t *pl; #ifdef RANGECHECK if (ds_p > &drawsegs[MAXDRAWSEGS]) I_Error ("R_DrawPlanes: drawsegs overflow (%i)", ds_p - drawsegs); if (lastvisplane > &visplanes[MAXVISPLANES]) I_Error ("R_DrawPlanes: visplane overflow (%i)", lastvisplane - visplanes); if (lastopening > &openings[MAXOPENINGS]) I_Error ("R_DrawPlanes: opening overflow (%i)", lastopening - openings); #endif if (showrplanestats) { #ifdef __riscos extern void _kernel_oswrch (int); _kernel_oswrch (31); _kernel_oswrch (0); _kernel_oswrch (0); #endif printf ("Drawsegs = %u/%u, Visplanes = %u/%u, Openings = %u/%u\n", ds_p - drawsegs, MAXDRAWSEGS, lastvisplane - visplanes, MAXVISPLANES, lastopening - openings, MAXOPENINGS); } for (pl = visplanes ; pl < lastvisplane ; pl++) { if (pl->minx <= pl->maxx) { int picnum = pl->picnum; // sky flat if (picnum == skyflatnum || (picnum & PL_SKYFLAT)) { int x; int texture; int offset; angle_t an, flip; rpatch_t *tex_patch; // killough 10/98: allow skies to come from sidedefs. // Allows scrolling and/or animated skies, as well as // arbitrary multiple skies per level without having // to use info lumps. an = viewangle; if (picnum & PL_SKYFLAT) { // Sky Linedef const line_t *l = &lines[picnum & ~PL_SKYFLAT]; // Sky transferred from first sidedef const side_t *s = *l->sidenum + sides; // Texture comes from upper texture of reference sidedef texture = texturetranslation[s->toptexture]; // Horizontal offset is turned into an angle offset, // to allow sky rotation as well as careful positioning. // However, the offset is scaled very small, so that it // allows a long-period of sky rotation. an += s->textureoffset; // Vertical offset allows careful sky positioning. dc_texturemid = s->rowoffset - 28 * FRACUNIT; // We sometimes flip the picture horizontally. // // DOOM always flipped the picture, so we make it optional, // to make it easier to use the new feature, while to still // allow old sky textures to be used. flip = l->special==272 ? 0u : ~0u; } else // Normal DOOM sky, only one allowed per level { dc_texturemid = skytexturemid; // Default y-offset texture = skytexture; // Default texture flip = 0; // DOOM flips it } // Sky is always drawn full bright, // i.e. colormaps[0] is used. // Because of this hack, sky is not affected // by INVUL inverse mapping. dc_colormap = (fixedcolormap ? fixedcolormap : colormaps); dc_ylim = textureheight[texture]; dc_iscale = skyiscale; tex_patch = R_CacheTextureCompositePatchNum (texture); offset = skycolumnoffset >> FRACBITS; for (x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x+1]; dc_yh = pl->bottom[x+1]; if (dc_yl <= dc_yh) { dc_x = x; dc_source = R_GetTextureColumn(tex_patch, (((an + xtoviewangle[x]) ^ flip) >> ANGLETOSKYSHIFT) + offset); dc_texturefrac = R_CalcFrac (); colfunc(); } } R_UnlockTextureCompositePatchNum (texture); }