void update_wall_scale(World *w, int wall_num, fixed xscale, fixed yscale) { Wall *wall; Texture *texture; fixed wall_length; if (wall_num < 0 || wall_num > TABLE_SIZE(w->walls)) fatal_error("invalid wall number"); wall = (Wall *) w->walls->table + wall_num; texture = wall->surface_texture; wall_length = FLOAT_TO_FIXED(sqrt(FIXED_TO_FLOAT(wall->vertex2->x - wall->vertex1->x) * FIXED_TO_FLOAT(wall->vertex2->x - wall->vertex1->x) + FIXED_TO_FLOAT(wall->vertex2->y - wall->vertex1->y) * FIXED_TO_FLOAT(wall->vertex2->y - wall->vertex1->y))); wall->yscale = fixmul(yscale, INT_TO_FIXED(texture->height)); wall->xscale = fixmul(fixmul(xscale, INT_TO_FIXED(texture->width)), wall_length); }
fixed_t FixedHypot(fixed_t x, fixed_t y) { #ifdef HAVE_HYPOT const float fx = FIXED_TO_FLOAT(x); const float fy = FIXED_TO_FLOAT(y); float fz; #ifdef HAVE_HYPOTF fz = hypotf(fx, fy); #else fz = (float)hypot(fx, fy); #endif return FLOAT_TO_FIXED(fz); #else // !HAVE_HYPOT fixed_t ax, yx, yx2, yx1; if (abs(y) > abs(x)) // |y|>|x| { ax = abs(y); // |y| => ax yx = FixedDiv(x, y); // (x/y) } else // |x|>|y| { ax = abs(x); // |x| => ax yx = FixedDiv(y, x); // (x/y) } yx2 = FixedMul(yx, yx); // (x/y)^2 yx1 = FixedSqrt(1+FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) #endif }
//============================================================================= static void HW3S_FillSourceParameters (const mobj_t *origin, source3D_data_t *data, channel_type_t c_type) { fixed_t x = 0, y = 0, z = 0; data->max_distance = MAX_DISTANCE; data->min_distance = MIN_DISTANCE; if (origin && origin != players[displayplayer].mo) { data->head_relative = false; data->pos.momx = TPS(FIXED_TO_FLOAT(origin->momx)); data->pos.momy = TPS(FIXED_TO_FLOAT(origin->momy)); data->pos.momz = TPS(FIXED_TO_FLOAT(origin->momz)); x = origin->x; y = origin->y; z = origin->z; if (c_type == CT_ATTACK) { const angle_t an = origin->angle >> ANGLETOFINESHIFT; x += FixedMul(16*FRACUNIT, FINECOSINE(an)); y += FixedMul(16*FRACUNIT, FINESINE(an)); z += origin->height >> 1; } else if (c_type == CT_SCREAM)
// the bsp divline have not enouth presition // search for the segs source of this divline static inline void SearchDivline(node_t *bsp, fdivline_t *divline) { #if 0 // MAR - If you don't use the same partition line that the BSP uses, the front/back polys won't match the subsectors in the BSP! #endif divline->x = FIXED_TO_FLOAT(bsp->x); divline->y = FIXED_TO_FLOAT(bsp->y); divline->dx = FIXED_TO_FLOAT(bsp->dx); divline->dy = FIXED_TO_FLOAT(bsp->dy); }
void wt_get_player_info(float *pfX,float *pfY,float *pfAngle,float *pfHeight) { //this is a sucky way to do this. should just fill in a View struct. if (view) { *pfX = (float)FIXED_TO_FLOAT(view->x); *pfY = (float)FIXED_TO_FLOAT(view->y); *pfAngle = (float)FIXED_TO_FLOAT(view->angle); *pfHeight = (float)FIXED_TO_FLOAT(view->height); } }
// sf: string value of an svalue_t const char *stringvalue(svalue_t v) { static char buffer[256]; switch(v.type) { case svt_string: return v.value.s; case svt_actor: return "map object"; case svt_fixed: { float val = FIXED_TO_FLOAT(v.value.i); sprintf(buffer, "%g", val); return buffer; } case svt_int: default: sprintf(buffer, "%i", v.value.i); return buffer; } }
static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly) { poly_t *q; INT32 j,k; if (bspnum & NF_SUBSECTOR) { if (bspnum!=-1) { bspnum&=~NF_SUBSECTOR; q = extrasubsectors[bspnum].planepoly; if (poly == q || !q) return; for (j = 0; j < q->numpts; j++) { k = j+1; if (k == q->numpts) k = 0; if (!SameVertice(p, &q->pts[j]) && !SameVertice(p, &q->pts[k]) && PointInSeg(p, &q->pts[j], &q->pts[k])) { poly_t *newpoly = HWR_AllocPoly(q->numpts+1); INT32 n; for (n = 0; n <= j; n++) newpoly->pts[n] = q->pts[n]; newpoly->pts[k] = *p; for (n = k+1; n < newpoly->numpts; n++) newpoly->pts[n] = q->pts[n-1]; numsplitpoly++; extrasubsectors[bspnum].planepoly = newpoly; HWR_FreePoly(q); return; } } } return; } if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXBOTTOM])-MAXDIST <= p->y) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x)) SearchSegInBSP(nodes[bspnum].children[0],p,poly); if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXBOTTOM])-MAXDIST <= p->y) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) && (FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x)) SearchSegInBSP(nodes[bspnum].children[1],p,poly); }
fixed_t FixedSqrt(fixed_t x) { const float fx = FIXED_TO_FLOAT(x); float fr; #ifdef HAVE_SQRTF fr = sqrtf(fx); #else fr = (float)sqrt(fx); #endif return FLOAT_TO_FIXED(fr); }
/*********************************************************************************** Function Name : glDrawTexxOES Inputs : Outputs : Returns : Description : ************************************************************************************/ GL_API_EXT void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) { GLfloat fX, fY, fZ, fWidth, fHeight; __GLES1_GET_CONTEXT(); PVR_DPF((PVR_DBG_CALLTRACE,"glDrawTexxOES")); GLES1_TIME_START(GLES1_TIMES_glDrawTexxOES); fX = FIXED_TO_FLOAT(x); fY = FIXED_TO_FLOAT(y); fZ = FIXED_TO_FLOAT(z); fWidth = FIXED_TO_FLOAT(width); fHeight = FIXED_TO_FLOAT(height); DrawTexture(gc, fX, fY, fZ, fWidth, fHeight); GLES1_TIME_STOP(GLES1_TIMES_glDrawTexxOES); }
/*********************************************************************************** Function Name : glDrawTexxvOES Inputs : Outputs : Returns : Description : ************************************************************************************/ GL_API_EXT void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords) { GLfloat fX, fY, fZ, fWidth, fHeight; __GLES1_GET_CONTEXT(); PVR_DPF((PVR_DBG_CALLTRACE,"glDrawTexxvOES")); GLES1_TIME_START(GLES1_TIMES_glDrawTexxvOES); fX = FIXED_TO_FLOAT(coords[0]); fY = FIXED_TO_FLOAT(coords[1]); fZ = FIXED_TO_FLOAT(coords[2]); fWidth = FIXED_TO_FLOAT(coords[3]); fHeight = FIXED_TO_FLOAT(coords[4]); DrawTexture(gc, fX, fY, fZ, fWidth, fHeight); GLES1_TIME_STOP(GLES1_TIMES_glDrawTexxvOES); }
void get_vector_xy( double *vx, double *vy, Wall *wall ) { fixed fdx, fdy; double dx, dy, line_len; fdx = wall->vertex2->x - wall->vertex1->x; fdy = wall->vertex2->y - wall->vertex1->y; dx = (double)FIXED_TO_FLOAT(fdx); dy = (double)FIXED_TO_FLOAT(fdy); line_len = sqrt( dx*dx + dy*dy ); *vx = dx/line_len; *vy = dy/line_len; /* printf( "line_len %f, dx %f, dy %f\n", line_len, dx, dy ); */ }
static void _glitz_filter_params_set (glitz_float_t *value, const glitz_float_t default_value, glitz_fixed16_16_t **params, int *n_params) { if (*n_params > 0) { *value = FIXED_TO_FLOAT (**params); (*params)++; (*n_params)--; } else *value = default_value; }
void grideffects::init(void) { Vector3 *v = &direction[0]; for (int y = GRID_HEIGHT; y; --y) { for (int x = GRID_WIDTH; x; --x) { #if 0 Vector3 dir((x - SCREEN_WIDTH / 2), (y - SCREEN_HEIGHT / 2), 200); dir.x *= SCREEN_WIDTH; dir.x /= GRID_WIDTH; dir.y *= SCREEN_HEIGHT; dir.y /= GRID_HEIGHT; dir = dir.normalize(); printf("%f %f %f\n", FIXED_TO_FLOAT(dir.x), FIXED_TO_FLOAT(dir.y), FIXED_TO_FLOAT(dir.z)); printf("%f\n", FIXED_TO_FLOAT(dir.x) * FIXED_TO_FLOAT(dir.x) + FIXED_TO_FLOAT(dir.y) * FIXED_TO_FLOAT(dir.y) + FIXED_TO_FLOAT(dir.z) * FIXED_TO_FLOAT(dir.z)); // printf("%f\n", FIXED_TO_FLOAT(dir.mag())); *v++ = dir; #else Vector3 dir( fixed16::make_raw(int(x - (GRID_WIDTH / 2))), fixed16::make_raw(int(y - (GRID_HEIGHT / 2))), fixed16::make_raw(40) // fixed16::make_raw(70) ); dir.x *= SCREEN_WIDTH; dir.x /= GRID_WIDTH; dir.y *= SCREEN_HEIGHT; dir.y /= GRID_HEIGHT; dir.normalize(); *v++ = dir; #endif } } // exit(0); }
int main(int argc, char *argv[]) { World *w; FILE *fp; Boolean quit = False; Intent *intent; fixed v = FIXED_ZERO; double vx = 0.0, vy = 0.0, va = 0.0; #ifdef MSDOS long frames; time_t starttime, endtime; #endif if (argc != 2) { fprintf(stderr, "Usage: wt <world file>\n"); exit(EXIT_FAILURE); } if ((fp = fopen(argv[1], "r")) == NULL) { perror(argv[1]); exit(EXIT_FAILURE); } w = read_world_file(fp); fclose(fp); init_graphics(); init_renderer(SCREEN_WIDTH, SCREEN_HEIGHT); init_input_devices(); /* setup view */ view = new_view(fixdiv(FIXED_2PI, INT_TO_FIXED(4))); view->x = FIXED_ZERO; view->y = FIXED_ZERO; view->height = FIXED_ONE; view->angle = FIXED_ZERO; #ifdef MSDOS starttime = time(NULL); frames = 0; #endif while (!quit) { double sin_facing, cos_facing; render(w, view); #ifdef MSDOS frames++; #endif intent = read_input_devices(); /* This block code is a hack to do acceleration and deceleration. */ if (fabs(vx) > fabs(intent->force_x)) { if (vx < 0.0) vx = MIN(vx + 0.1, intent->force_x); else vx = MAX(vx - 0.1, intent->force_x); } else if (fabs(vx) < fabs(intent->force_x)) { vx += intent->force_x / 5.0; if (fabs(vx) > fabs(intent->force_x)) vx = intent->force_x; } if (fabs(vy) > fabs(intent->force_y)) { if (vy < 0.0) vy = MIN(vy + 0.1, intent->force_y); else vy = MAX(vy - 0.1, intent->force_y); } else if (fabs(vy) < fabs(intent->force_y)) { vy += intent->force_y / 5.0; if (fabs(vy) > fabs(intent->force_y)) vy = intent->force_y; } if (fabs(vy) > fabs(intent->force_y)) { if (vy < 0.0) vy = MIN(vy + 0.1, intent->force_y); else vy = MAX(vy - 0.1, intent->force_y); } else if (fabs(vy) < fabs(intent->force_y)) { vy += intent->force_y / 5.0; if (fabs(vy) > fabs(intent->force_y)) vy = intent->force_y; } /* Angular deceleration here is weird and unrealistic, but it feels ** right to me. */ if (fabs(va) > fabs(intent->force_rotate)) va *= 0.6; else if (fabs(va) < fabs(intent->force_rotate)) { va += intent->force_rotate / 8.0; if (fabs(va) > fabs(intent->force_rotate)) va = intent->force_rotate; } view->angle += FLOAT_TO_FIXED(0.3 * va); sin_facing = sin(FIXED_TO_FLOAT(view->angle)); cos_facing = cos(FIXED_TO_FLOAT(view->angle)); view->x += FLOAT_TO_FIXED(0.8 * vx * cos_facing); view->y += FLOAT_TO_FIXED(0.8 * vx * sin_facing); view->x += FLOAT_TO_FIXED(0.8 * vy * -sin_facing); view->y += FLOAT_TO_FIXED(0.8 * vy * cos_facing); if (view->height > FIXED_ONE) v -= FIXED_ONE / 16; view->height += v; if (view->height < FIXED_ONE) { v = FIXED_ZERO; view->height = FIXED_ONE; } while (intent->n_special--) { if (intent->special[intent->n_special] == INTENT_END_GAME) quit = True; else v = FIXED_ONE / 2; } } #ifdef MSDOS endtime = time(NULL); #endif end_input_devices(); end_graphics(); #ifdef MSDOS printf("%li frames in %lu seconds - %.2f frames per second", (long) frames, (long) endtime - starttime, (float) frames / (float) (endtime-starttime)); #endif return EXIT_SUCCESS; }
int wt_input(void) { int quit = False; double sin_facing, cos_facing; intent = read_input_devices(); /* This block code is a hack to do acceleration and deceleration. */ if (fabs(vx) > fabs(intent->force_x)) { if (vx < 0.0) vx = MIN(vx + 0.1, intent->force_x); else vx = MAX(vx - 0.1, intent->force_x); } else if (fabs(vx) < fabs(intent->force_x)) { vx += intent->force_x / 5.0; if (fabs(vx) > fabs(intent->force_x)) vx = intent->force_x; } if (fabs(vy) > fabs(intent->force_y)) { if (vy < 0.0) vy = MIN(vy + 0.1, intent->force_y); else vy = MAX(vy - 0.1, intent->force_y); } else if (fabs(vy) < fabs(intent->force_y)) { vy += intent->force_y / 5.0; if (fabs(vy) > fabs(intent->force_y)) vy = intent->force_y; } if (fabs(vy) > fabs(intent->force_y)) { if (vy < 0.0) vy = MIN(vy + 0.1, intent->force_y); else vy = MAX(vy - 0.1, intent->force_y); } else if (fabs(vy) < fabs(intent->force_y)) { vy += intent->force_y / 5.0; if (fabs(vy) > fabs(intent->force_y)) vy = intent->force_y; } /* Angular deceleration here is weird and unrealistic, but it feels ** right to me. */ if (fabs(va) > fabs(intent->force_rotate)) va *= 0.6; else if (fabs(va) < fabs(intent->force_rotate)) { va += intent->force_rotate / 8.0; if (fabs(va) > fabs(intent->force_rotate)) va = intent->force_rotate; } view->angle += FLOAT_TO_FIXED(0.3 * va); sin_facing = sin(FIXED_TO_FLOAT(view->angle)); cos_facing = cos(FIXED_TO_FLOAT(view->angle)); view->x += FLOAT_TO_FIXED(0.8 * vx * cos_facing); view->y += FLOAT_TO_FIXED(0.8 * vx * sin_facing); view->x += FLOAT_TO_FIXED(0.8 * vy * -sin_facing); view->y += FLOAT_TO_FIXED(0.8 * vy * cos_facing); if (view->height > FIXED_ONE) v -= FIXED_ONE / 16; view->height += v; if (view->height < FIXED_ONE) { v = FIXED_ZERO; view->height = FIXED_ONE; } while (intent->n_special--) { if (intent->special[intent->n_special] == INTENT_END_GAME) quit = True; else v = FIXED_ONE / 2; } return quit; }
// DoScript() // ----------------------------------------------------- // // static BAEResult DoScript(int subMenu) { BAEResult err; BAE_BOOL validerr; short tmpShort1, tmpShort2, tmpShort3; long tmpLong1, tmpLong2; char buffer[256]; BAE_BOOL tmpBool1; BAE_UNSIGNED_FIXED tmpUFixed1; short int midiVoices, pcmVoices; BAEQuality q; BAEAudioModifiers s; validerr = TRUE; err = BAE_NO_ERROR; s = BAE_NONE; switch (subMenu) { case SCRIPT_MIXER_OPEN_8_16_MONO: case SCRIPT_MIXER_OPEN_22_16_MONO: case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: case SCRIPT_MIXER_OPEN_22_16_8_MONO: { switch (subMenu) { case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_8_16_MONO: q = BAE_8K; break; case SCRIPT_MIXER_OPEN_22_16_8_MONO: q = BAE_22K; break; case SCRIPT_MIXER_OPEN_22_16_MONO: q = BAE_22K; break; case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: q = BAE_16K; break; default: return BAE_PARAM_ERR; } switch (subMenu) { case SCRIPT_MIXER_OPEN_22_16_8_MONO: midiVoices = 8; pcmVoices = 0; break; case SCRIPT_MIXER_OPEN_8_16_MONO: case SCRIPT_MIXER_OPEN_22_16_MONO: case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: midiVoices = 7; pcmVoices = 1; break; case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: midiVoices = 8; pcmVoices = 0; break; default: return BAE_PARAM_ERR; } if (gMixer == NULL) { gMixer = BAEMixer_New(); } else { printf("Mixer already allocated\n"); validerr = FALSE; } err = BAEMixer_Open(gMixer, q, BAE_LINEAR_INTERPOLATION,BAE_USE_16 | s, midiVoices, pcmVoices, 7, TRUE); printf("\n"); } break; case SCRIPT_MIXER_CLOSE: DoFunction(FUNC_MIXER_DELETE); validerr = FALSE; break; case SCRIPT_MIXER_SET_DEFAULT_SMALL_BANK: { BAEBankToken token; err = BAEMixer_UnloadBanks(gMixer); // free all banks if (err) { printf("Error unloading banks (%d)\n", err); } err = BAEMixer_AddBankFromFile(gMixer, "npatches.hsb", &token); if (err == 0) { printf("token = %d\n", token); } } break; case SCRIPT_MIXER_SET_DEFAULT_BIG_BANK: { BAEBankToken token; err = BAEMixer_UnloadBanks(gMixer); // free all banks if (err) { printf("Error unloading banks (%d)\n", err); } err = BAEMixer_AddBankFromFile(gMixer, "patches.hsb", &token); if (err == 0) { printf("token = %d\n", token); } } break; case SCRIPT_MIXER_DISPLAY_CPU_LOAD: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETCPULOADINPERCENT); } } break; case SCRIPT_MIXER_DISPLAY_SAMPLE_FRAMES: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETAUDIOSAMPLEFRAME); } } break; case SCRIPT_MIXER_DISPLAY_REALTIME_STATUS: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETREALTIMESTATUS); } } break; case SCRIPT_MIXER_GET_DEVICE_INFO: { err = BAEMixer_GetMaxDeviceCount(gMixer, &tmpLong1); if (err) break; printf("Num devices = %d\n", tmpLong1); for (tmpLong2=0; tmpLong2<tmpLong1; tmpLong2++) { err = BAEMixer_GetDeviceName(gMixer, tmpLong2, buffer, 256); if (err) break; printf(" device %d: %s\n", tmpLong2, buffer); } err = BAEMixer_GetCurrentDevice(gMixer, NULL, &tmpLong1); if (err) break; printf("Current device: %d\n", tmpLong1); err = BAEMixer_Is16BitSupported(gMixer, &tmpBool1); if (err) break; printf(" 16-bit support? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_Is8BitSupported(gMixer, &tmpBool1); if (err) break; printf(" 8-bit support? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_GetAudioLatency(gMixer, (unsigned long *)&tmpLong1); if (err) break; printf(" Latency: %d milliseconds\n", tmpLong1); err = BAEMixer_GetMasterVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Master volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); err = BAEMixer_GetHardwareVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Hardware volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); err = BAEMixer_GetMasterSoundEffectsVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Master Sfx volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); } break; case SCRIPT_MIXER_GET_MIXER_INFO: { BAEQuality q; BAETerpMode t; err = BAEMixer_GetMixerVersion(gMixer, &tmpShort1, &tmpShort2, &tmpShort3); if (err) break; printf("\nBAEMixer v%d.%d.%d\n", tmpShort1, tmpShort2, tmpShort3); err = BAEMixer_IsOpen(gMixer, &tmpBool1); if (err) break; printf(" Is Open? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_GetQuality(gMixer, &q); if (err) break; printf(" Quality: %s\n", BAEQualityToStr(q)); err = BAEMixer_GetTerpMode(gMixer, &t); if (err) break; printf(" Terp mode: %s\n", BAETerpModeToStr(t)); err = BAEMixer_GetModifiers(gMixer, &tmpLong1); if (err) break; printf(" Modifiers: %x\n", tmpLong1); err = BAEMixer_GetMidiVoices(gMixer, &tmpShort1); if (err) break; printf(" Midi voices: %d\n", tmpShort1); err = BAEMixer_GetSoundVoices(gMixer, &tmpShort1); if (err) break; printf(" Sound voices: %d\n", tmpShort1); err = BAEMixer_GetMixLevel(gMixer, &tmpShort1); if (err) break; printf(" Mix level: %d\n", tmpShort1); err = BAEMixer_IsAudioEngaged(gMixer, &tmpBool1); if (err) break; printf(" Audio engaged? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_IsAudioActive(gMixer, &tmpBool1); if (err) break; printf(" Audio active? %s\n", (tmpBool1) ? "Yes" : "No"); } break; case SCRIPT_MIXER_GET_BANK_INFO: { tmpLong1 = GetLong(">>Bank token: "); err = BAEMixer_GetBankVersion(gMixer, (BAEBankToken)tmpLong1, &tmpShort1, &tmpShort2, &tmpShort3); if (err) break; printf("Bank version %d.%d.%d\n", tmpShort1, tmpShort2, tmpShort3); } break; default: break; } return err; }
// call this routine after the BSP of a Doom wad file is loaded, // and it will generate all the convex polys for the hardware renderer void HWR_CreatePlanePolygons(INT32 bspnum) { poly_t *rootp; polyvertex_t *rootpv; size_t i; fixed_t rootbbox[4]; DEBPRINT("Creating polygons, please wait...\n"); ls_count = ls_percent = 0; // reset the loading status CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer HWR_ClearPolys(); // find min/max boundaries of map //DEBPRINT("Looking for boundaries of map...\n"); M_ClearBox(rootbbox); for (i = 0;i < numvertexes; i++) M_AddToBox(rootbbox, vertexes[i].x, vertexes[i].y); //DEBPRINT("Generating subsector polygons... %d subsectors\n", numsubsectors); HWR_FreeExtraSubsectors(); // allocate extra data for each subsector present in map totsubsectors = numsubsectors + NEWSUBSECTORS; extrasubsectors = calloc(totsubsectors, sizeof (*extrasubsectors)); if (extrasubsectors == NULL) I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors)); // allocate table for back to front drawing of subsectors /*gr_drawsubsectors = (INT16 *)malloc(sizeof (*gr_drawsubsectors) * totsubsectors); if (!gr_drawsubsectors) I_Error("couldn't malloc gr_drawsubsectors\n");*/ // number of the first new subsector that might be added addsubsector = numsubsectors; // construct the initial convex poly that encloses the full map rootp = HWR_AllocPoly(4); rootpv = rootp->pts; rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXLEFT ]); rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXBOTTOM]); //lr rootpv++; rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXLEFT ]); rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXTOP ]); //ur rootpv++; rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXRIGHT ]); rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXTOP ]); //ul rootpv++; rootpv->x = FIXED_TO_FLOAT(rootbbox[BOXRIGHT ]); rootpv->y = FIXED_TO_FLOAT(rootbbox[BOXBOTTOM]); //ll rootpv++; WalkBSPNode(bspnum, rootp, NULL,rootbbox); i = SolveTProblem(); //DEBPRINT("%d point divides a polygon line\n",i); AdjustSegs(); //debug debug.. //if (nobackpoly) // DEBPRINT("no back polygon %u times\n",nobackpoly); //"(should happen only with the deep water trick)" //if (skipcut) // DEBPRINT("%u cuts were skipped because of only one point\n",skipcut); //DEBPRINT("done: %u total subsector convex polygons\n", totalsubsecpolys); }
void engine_move_actors (Context* context) { static int ticks = ANIM_LEN; Player* player = context->engine->player; if (player->v_buf->v == NULL) { return; } if ( player->target_x < 0 || ( player->target_x == *player->x && player->target_y == *player->y ) ) { player->anim = 0; player->v_buf->v->bitmap = player->anims[0]; return; } Fixed vector_x = player->vector_x; Fixed vector_y = player->vector_y; if (player->recalculate) { vector_x = FIXED_FROM_INT(player->target_x) - player->real_x; vector_y = FIXED_FROM_INT(player->target_y) - player->real_y; Fixed dist = FIXED_FROM_FLOAT( Q_rsqrt( FIXED_TO_FLOAT( FIXED_MUL(vector_x, vector_x) + FIXED_MUL(vector_y, vector_y) ) ) ); vector_x = FIXED_MUL(vector_x, dist); vector_y = FIXED_MUL(vector_y, dist); player->vector_x = vector_x; player->vector_y = vector_y; player->recalculate = 0; } player->real_x += FIXED_MUL(vector_x, FIXED_FROM_INT(PLAYER_SPEED)); player->real_y += FIXED_MUL(vector_y, FIXED_FROM_INT(PLAYER_SPEED)); if (ticks >= ANIM_LEN) { ticks = 0; player->anim++; if (vector_x > 0 && player->anim > 2) { player->anim = 2; } else if (vector_x < 0 && player->anim > 4) { player->anim = 4; } else if (vector_x < 0 && player->anim < 3) { player->anim = 3; } player->v_buf->v->bitmap = player->anims[player->anim]; } if ( (vector_x > 0 && FIXED_TO_FLOAT(player->real_x) >= player->target_x) || (vector_x <= 0 && FIXED_TO_FLOAT(player->real_x) < player->target_x) ) { player->real_x = FIXED_FROM_INT(player->target_x); player->v_buf->v->bitmap = player->anims[0]; player->anim = 0; } if ( (vector_y > 0 && FIXED_TO_FLOAT(player->real_y) > player->target_y) || (vector_y < 0 && FIXED_TO_FLOAT(player->real_y) < player->target_y) ) { player->real_y = FIXED_FROM_INT(player->target_y); } *player->x = FIXED_TO_INT(player->real_x); *player->y = FIXED_TO_INT(player->real_y); engine_update_box(player, context->engine); ticks++; }
void parse_wall(FILE *fp, World *w) { Wall wall; char texture_name[STRING_TOKEN_MAX_LENGTH]; int texture_index; int front_region, back_region; int vertex1, vertex2; fixed wall_length; /* vertices */ if (get_integer_token(fp, &vertex1) != Token_integer) parse_error("integer expected"); if (get_integer_token(fp, &vertex2) != Token_integer) parse_error("integer expected"); if (vertex1 < 0 || vertex1 > TABLE_SIZE(w->vertices)) parse_error("invalid vertex number"); if (vertex2 < 0 || vertex2 > TABLE_SIZE(w->vertices)) parse_error("invalid vertex number"); wall.vertex1 = &WORLD_VERTEX(w, vertex1); wall.vertex2 = &WORLD_VERTEX(w, vertex2); /* texture */ if (get_string_token(fp, texture_name) != Token_string) parse_error("texture name expected"); texture_index = get_texture_index(texture_name); if (texture_index < 0 || texture_index > TABLE_SIZE(w->textures)) parse_error("non-existent texture"); else wall.surface_texture = WORLD_TEXTURE(w, texture_index); if (strcmp(texture_name, "sky") == 0) wall.sky = True; else wall.sky = False; /* front and back regions */ if (get_integer_token(fp, &front_region) != Token_integer) fatal_error("non-existent region"); if (get_integer_token(fp, &back_region) != Token_integer) fatal_error("non-existent region"); if (front_region < 0 || front_region > TABLE_SIZE(w->regions)) fatal_error("non-existent region"); if (back_region < 0 || back_region > TABLE_SIZE(w->regions)) fatal_error("non-existent region"); wall.front = &WORLD_REGION(w, front_region); wall.back = &WORLD_REGION(w, back_region); /* Texture phase and scale. This code is somewhat more complicated than ** you'd expect, since the texture scale must be normalized to the ** wall length. */ if (get_real_token(fp, &wall.xscale) != Token_real) parse_error("number expected"); if (get_real_token(fp, &wall.yscale) != Token_real) parse_error("number expected"); if (get_real_token(fp, &wall.xphase) != Token_real) parse_error("number expected"); if (get_real_token(fp, &wall.yphase) != Token_real) parse_error("number expected"); wall_length = FLOAT_TO_FIXED(sqrt(FIXED_TO_FLOAT(wall.vertex2->x - wall.vertex1->x) * FIXED_TO_FLOAT(wall.vertex2->x - wall.vertex1->x) + FIXED_TO_FLOAT(wall.vertex2->y - wall.vertex1->y) * FIXED_TO_FLOAT(wall.vertex2->y - wall.vertex1->y))); wall.yscale = fixmul(wall.yscale, INT_TO_FIXED(wall.surface_texture->height)); wall.xscale = fixmul(fixmul(wall.xscale, INT_TO_FIXED(wall.surface_texture->width)), wall_length); add_wall(w, &wall); }
int checkwalls( World *w, View *v ) { extern fixed view_height; Wall *wall = (Wall *) w->walls->table, *mem_wall; double x1, y1, tmp, min = 512.0; int i; x1 = FIXED_TO_FLOAT(v->x); y1 = FIXED_TO_FLOAT(v->y); if ( x1 == x && y1 == y ) return DONT_INTERSECT; for (i = 0; i < TABLE_SIZE(w->walls); i++, wall++ ) { /* Check Distance */ tmp = LineDistance( x1, y1, FIXED_TO_FLOAT(wall->vertex1->x ), FIXED_TO_FLOAT(wall->vertex1->y ), FIXED_TO_FLOAT(wall->vertex2->x ), FIXED_TO_FLOAT(wall->vertex2->y ) ); if ( fabs(tmp) < fabs( min ) ) { min = tmp; mem_wall = wall; } } /* is there any point in checking further. */ if ( fabs( min ) < VECTOR_LEN ) { /* start examine the wall */ fixed ceiling, floor; /* Check the outher side of the object */ if ( min > 0.0 ) { floor = mem_wall->front->floor; ceiling = mem_wall->front->ceiling; } else { floor = mem_wall->back->floor; ceiling = mem_wall->back->ceiling; } /* if the stair is less than FIXED_ONE_QUARTER and the head has goes free and there are enought room. */ if ( FIXED_ONE_QUARTER >= (floor-v->height) && ( ceiling > v->height ) && ( MAN_SIZE <= (ceiling-floor) ) ) { if ( s_wall != mem_wall || ( min > 0.0 && side <= 0.0 ) || (min <= 0.0 && side > 0.0 ) ) { if ( min < 0.0 ) view_height = mem_wall->front->floor+MAN_SIZE; else view_height = mem_wall->back->floor+MAN_SIZE; s_wall = mem_wall; } } else /* am i running towards the wall? */ if ( fabs( min ) < fabs( side ) ) { s_wall = mem_wall; slide_wall( &x, &y, x1, y1, side, min ); v->x = FLOAT_TO_FIXED( x ); v->y = FLOAT_TO_FIXED( y ); return 0; } } side = min; x = x1; y = y1; return 0; }
// ---------------------------------------------------------------------------- // void UTL_LocomotionController::ControlOjbect( object_control_s* pObjctl, Vector3* pDesiredVelocity, fixed_t _DesiredSpeed ) { ASSERT( pObjctl != NULL ); ASSERT( pDesiredVelocity != NULL ); Vector3 xDir, yDir, zDir; FetchXVector( pObjctl->pShip->ObjPosition, &xDir ); FetchYVector( pObjctl->pShip->ObjPosition, &yDir ); FetchZVector( pObjctl->pShip->ObjPosition, &zDir ); geomv_t len = VctLenX( pDesiredVelocity ); // stop control if desired velocity is zero if ( len <= GEOMV_VANISHING ) { pObjctl->rot_x = 0; pObjctl->rot_y = 0; pObjctl->accel = -0.82; #ifdef BOT_LOGFILES BOT_MsgOut( "ControlOjbect() got dimishing desired velocity" ); #endif // BOT_LOGFILES return; } else { Vector3 DesVelNorm; DesVelNorm.X = FLOAT_TO_GEOMV( pDesiredVelocity->X / len ); DesVelNorm.Y = FLOAT_TO_GEOMV( pDesiredVelocity->Y / len ); DesVelNorm.Z = FLOAT_TO_GEOMV( pDesiredVelocity->Z / len ); geomv_t yaw_dot = DOT_PRODUCT( &DesVelNorm, &xDir ); geomv_t pitch_dot = DOT_PRODUCT( &DesVelNorm, &yDir ); geomv_t heading_dot = DOT_PRODUCT( &DesVelNorm, &zDir ); float fDesiredSpeed = FIXED_TO_FLOAT( _DesiredSpeed ); float fCurSpeed = FIXED_TO_FLOAT( pObjctl->pShip->CurSpeed ); float pitch = 0; float yaw = 0; // target is behind us sincosval_s fullturn; GetSinCos( DEG_TO_BAMS( 2 * m_nRelaxedHeadingAngle ), &fullturn ); //if ( heading_dot < 0.0f ) { if ( heading_dot < -fullturn.cosval ) { // we must initiate a turn, if not already in a turn if ( !pObjctl->IsYaw() || !pObjctl->IsPitch() ) { // default to random yaw = (float)( RAND() % 3 ) - 1; pitch = (float)( RAND() % 3 ) - 1; // steer towards goal if ( yaw_dot < -GEOMV_VANISHING ) { yaw = OCT_YAW_LEFT; } else if ( yaw_dot > GEOMV_VANISHING ) { yaw = OCT_YAW_RIGHT; } if ( pitch_dot < -GEOMV_VANISHING ) { pitch = OCT_PITCH_UP; } else if ( pitch_dot > GEOMV_VANISHING ) { pitch = OCT_PITCH_DOWN; } } else { // reuse prev. turn information pitch = pObjctl->rot_x; yaw = pObjctl->rot_y; } // slow down, until in direction of target // pObjctl->accel = heading_dot; //pObjctl->accel = OCT_DECELERATE; // also maintain min. speed during turns if ( fCurSpeed > m_fMinSpeedTurn ) { pObjctl->accel = -0.42; } } else { // determine accel if ( fDesiredSpeed > fCurSpeed ) { // accelerate towards target pObjctl->accel = OCT_ACCELERATE; } else if ( fDesiredSpeed < fCurSpeed ) { // decelerate towards target pObjctl->accel = OCT_DECELERATE; } else { // no accel pObjctl->accel = 0; } // heading must be inside of 5 degrees cone angle sincosval_s sincosv; GetSinCos( DEG_TO_BAMS( m_nRelaxedHeadingAngle ), &sincosv ); if ( yaw_dot < -sincosv.sinval ) { yaw = OCT_YAW_LEFT; } else if ( yaw_dot > sincosv.sinval ) { yaw = OCT_YAW_RIGHT; } if ( pitch_dot < -sincosv.sinval ) { pitch = OCT_PITCH_UP; } else if ( pitch_dot > sincosv.sinval ) { pitch = OCT_PITCH_DOWN; } // if heading outside of 30 degrees cone angle, we decelerate GetSinCos( DEG_TO_BAMS( m_nFullSpeedHeading ), &sincosv ); bool_t bYawOutsideHeading = ( ( yaw_dot < -sincosv.sinval ) || ( yaw_dot > sincosv.sinval ) ); bool_t bPitchOutsideHeading = ( ( pitch_dot < -sincosv.sinval ) || ( pitch_dot > sincosv.sinval ) ); if ( bYawOutsideHeading || bPitchOutsideHeading ) { // also maintain min. speed during turns if ( fCurSpeed > min( m_fMinSpeedTurn, fDesiredSpeed ) ) { // decelerate towards target pObjctl->accel = OCT_DECELERATE; } } } #ifdef BOT_LOGFILES BOT_MsgOut( "heading_dot: %f, yaw_dot: %f, pitch_dot: %f", heading_dot, yaw_dot, pitch_dot ); #endif // BOT_LOGFILES //FIXME: oct must also handle slide horiz./vert. pObjctl->rot_x = pitch; pObjctl->rot_y = yaw; } }
// use each seg of the poly as a partition line, keep only the // part of the convex poly to the front of the seg (that is, // the part inside the sector), the part behind the seg, is // the void space and is cut out // static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly) { INT32 i, j; polyvertex_t *pv; INT32 nump = 0, ps, pe; polyvertex_t vs = {0, 0, 0}, ve = {0, 0, 0}, p1 = {0, 0, 0}, p2 = {0, 0, 0}; float fracs = 0.0f; fdivline_t cutseg; // x, y, dx, dy as start of node_t struct poly_t *temppoly; // for each seg of the subsector for (; count--; lseg++) { //x,y,dx,dy (like a divline) line_t *line = lseg->linedef; p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x); p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y); p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x); p2.y = FIXED_TO_FLOAT(lseg->side ? line->v1->y : line->v2->y); cutseg.x = p1.x; cutseg.y = p1.y; cutseg.dx = p2.x - p1.x; cutseg.dy = p2.y - p1.y; // see if it cuts the convex poly ps = -1; pe = -1; for (i = 0; i < poly->numpts; i++) { j = i + 1; if (j == poly->numpts) j = 0; pv = fracdivline(&cutseg, &poly->pts[i], &poly->pts[j]); if (pv) { if (ps < 0) { ps = i; vs = *pv; fracs = bspfrac; } else { //frac 1 on previous segment, // 0 on the next, //the split line goes through one of the convex poly // vertices, happens quite often since the convex // poly is already adjacent to the subsector segs // on most borders if (SameVertice(pv, &vs)) continue; if (fracs <= bspfrac) { nump = 2 + poly->numpts - (i-ps); pe = ps; ps = i; ve = *pv; } else { nump = 2 + (i-ps); pe = i; ve = vs; vs = *pv; } //found 2nd point break; } } } // there was a split if (ps >= 0) { //need 2 points if (pe >= 0) { // generate FRONT poly temppoly = HWR_AllocPoly(nump); pv = temppoly->pts; *pv++ = vs; *pv++ = ve; do { if (++ps == poly->numpts) ps = 0; *pv++ = poly->pts[ps]; } while (ps != pe); HWR_FreePoly(poly); poly = temppoly; } //hmmm... maybe we should NOT accept this, but this happens // only when the cut is not needed it seems (when the cut // line is aligned to one of the borders of the poly, and // only some times..) else skipcut++; // I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos); } } return poly; }
static void Removeack(INT32 i) { INT32 node = ackpak[i].destinationnode; #ifndef NEWPING fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<<FRACBITS; if (ackpak[i].resentnum) { // +FRACUNIT/2 for round nodes[node].ping = (nodes[node].ping*7 + trueping)/8; nodes[node].varping = (nodes[node].varping*7 + abs(nodes[node].ping-trueping))/8; nodes[node].timeout = TIMEOUT(nodes[node].ping,nodes[node].varping); } DEBFILE(va("Remove ack %d trueping %d ping %f var %f timeout %d\n",ackpak[i].acknum,trueping>>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout)); #else DEBFILE(va("Remove ack %d\n",ackpak[i].acknum)); #endif ackpak[i].acknum = 0; if (nodes[node].flags & CLOSE) Net_CloseConnection(node); }
void R_InitSkyTexCoords( bfixed heightCloud ) { int i, s, t; bfixed radiusWorld = BFIXED(4096,0); double fradiusWorld = 4096.0; double fheightCloud = FIXED_TO_DOUBLE(heightCloud); float p; gfixed sRad, tRad; bvec3_t skyVec; bvec3_t v; float fskyvec[3]; // init zfar so MakeSkyVec works even though // a world hasn't been bounded backEnd.viewParms.zFar = BFIXED(1024,0); for ( i = 0; i < 6; i++ ) { for ( t = 0; t <= SKY_SUBDIVISIONS; t++ ) { for ( s = 0; s <= SKY_SUBDIVISIONS; s++ ) { // compute vector from view origin to sky side integral point MakeSkyVec( FIXED_INT32RATIO_G( s - HALF_SKY_SUBDIVISIONS, HALF_SKY_SUBDIVISIONS), FIXED_INT32RATIO_G( t - HALF_SKY_SUBDIVISIONS, HALF_SKY_SUBDIVISIONS), i, NULL, skyVec ); fskyvec[0]=FIXED_TO_FLOAT(skyVec[0]); fskyvec[1]=FIXED_TO_FLOAT(skyVec[1]); fskyvec[2]=FIXED_TO_FLOAT(skyVec[2]); // compute parametric value 'p' that intersects with cloud layer p = ( 1.0 / ( 2.0* ( fskyvec[0]*fskyvec[0] + fskyvec[1]*fskyvec[1] + fskyvec[2]*fskyvec[2] ) ) ) * ( -2.0* fskyvec[2] * fradiusWorld + 2.0* sqrt( SQR( fskyvec[2] ) * SQR( fradiusWorld ) + 2.0* SQR( fskyvec[0] ) * fradiusWorld * fheightCloud + SQR( fskyvec[0] ) * SQR( fheightCloud ) + 2.0* SQR( fskyvec[1] ) * fradiusWorld * fheightCloud + SQR( fskyvec[1] ) * SQR( fheightCloud ) + 2.0* SQR( fskyvec[2] ) * fradiusWorld * fheightCloud + SQR( fskyvec[2] ) * SQR( fheightCloud ) ) ); s_cloudTexP[i][t][s] = MAKE_GFIXED(p); // compute intersection point based on p FIXED_VEC3SCALE( skyVec, MAKE_BFIXED(p), v ); v[2] += radiusWorld; // compute vector from world origin to intersection point 'v' VectorNormalize( v ); sRad = MAKE_GFIXED(Q_acos( v[0] )); tRad = MAKE_GFIXED(Q_acos( v[1] )); s_cloudTexCoords[i][t][s][0] = sRad; s_cloudTexCoords[i][t][s][1] = tRad; } } } }
/* Adjust true segs (from the segs lump) to be exactely the same as * plane polygone segs * This also convert fixed_t point of segs in float (in moste case * it share the same vertice */ static void AdjustSegs(void) { size_t i, count; INT32 j; seg_t *lseg; poly_t *p; INT32 v1found = 0, v2found = 0; float nearv1, nearv2; for (i = 0; i < numsubsectors; i++) { count = subsectors[i].numlines; lseg = &segs[subsectors[i].firstline]; p = extrasubsectors[i].planepoly; if (!p) continue; for (; count--; lseg++) { float distv1,distv2,tmp; nearv1 = nearv2 = MYMAX; #ifdef POLYOBJECTS // Don't touch polyobject segs. We'll compensate // for this when we go about drawing them. if (lseg->polyseg) continue; #endif for (j = 0; j < p->numpts; j++) { distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x); tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y); distv1 = distv1*distv1+tmp*tmp; if (distv1 <= nearv1) { v1found = j; nearv1 = distv1; } // the same with v2 distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x); tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y); distv2 = distv2*distv2+tmp*tmp; if (distv2 <= nearv2) { v2found = j; nearv2 = distv2; } } if (nearv1 <= NEARDIST*NEARDIST) // share vertice with segs lseg->v1 = (vertex_t *)&(p->pts[v1found]); else { // BP: here we can do better, using PointInSeg and compute // the right point position also split a polygone side to // solve a T-intersection, but too mush work // convert fixed vertex to float vertex polyvertex_t *pv = HWR_AllocVertex(); pv->x = FIXED_TO_FLOAT(lseg->v1->x); pv->y = FIXED_TO_FLOAT(lseg->v1->y); lseg->v1 = (vertex_t *)pv; } if (nearv2 <= NEARDIST*NEARDIST) lseg->v2 = (vertex_t *)&(p->pts[v2found]); else { polyvertex_t *pv = HWR_AllocVertex(); pv->x = FIXED_TO_FLOAT(lseg->v2->x); pv->y = FIXED_TO_FLOAT(lseg->v2->y); lseg->v2 = (vertex_t *)pv; } // recompute length { float x,y; x = ((polyvertex_t *)lseg->v2)->x - ((polyvertex_t *)lseg->v1)->x + FIXED_TO_FLOAT(FRACUNIT/2); y = ((polyvertex_t *)lseg->v2)->y - ((polyvertex_t *)lseg->v1)->y + FIXED_TO_FLOAT(FRACUNIT/2); lseg->flength = (float)hypot(x, y); // BP: debug see this kind of segs //if (nearv2 > NEARDIST*NEARDIST || nearv1 > NEARDIST*NEARDIST) // lseg->length = 1; } } } }