void IntroSequence::DrawZoomedLogoInCenter(int y1, int y2) { int logowidth = fixtoi(fixmul(itofix(al_get_bitmap_width(iLogo)), iZoom)); int logoheight = fixtoi(fixmul(itofix(al_get_bitmap_height(iLogo)), iZoom)); int targetwidth = width; int targetheight = y2 - y1; int xs, ys, ws, hs; int xd, yd, wd, hd; if (logowidth > targetwidth) { ws = fixtoi(fixdiv(itofix(targetwidth), iZoom)); xs = (al_get_bitmap_width(iLogo) - ws) / 2; xd = 0; wd = targetwidth; } else { xs = 0; ws = al_get_bitmap_width(iLogo); xd = (targetwidth - logowidth) / 2; wd = logowidth; } if (logoheight > targetheight) { hs = fixtoi(fixdiv(itofix(targetheight), iZoom)); ys = (al_get_bitmap_height(iLogo) - hs) / 2; yd = 0; hd = targetheight; } else { ys = 0; hs = al_get_bitmap_height(iLogo); yd = (targetheight - logoheight) / 2; hd = logoheight; } stretch_blit(iLogo, iDoublebuffer, xs, ys, ws, hs, xd, yd, wd, hd); }
BOOL ObjectActionCornerScale(C4Object *cObj) { int32_t iRangeX,iRangeY; // Scaling: check range max to min if (cObj->GetProcedure()==DFA_SCALE) { if (!CheckCornerScale(cObj,iRangeX,iRangeY)) return FALSE; } // Swimming: check range min to max else { iRangeY=2; while (!CornerScaleOkay(cObj,iRangeY,iRangeY)) { iRangeY++; if (iRangeY>CornerRange) return FALSE; } iRangeX=iRangeY; } // Do corner scale if (!cObj->SetActionByName("KneelUp")) cObj->SetActionByName("Walk"); cObj->xdir=cObj->ydir=0; //if (cObj->Action.Dir==DIR_Left) cObj->Action.ComDir=COMD_Left; else cObj->Action.ComDir=COMD_Right; if (cObj->Action.Dir==DIR_Left) cObj->fix_x-=itofix(iRangeX); else cObj->fix_x+=itofix(iRangeX); cObj->fix_y-=itofix(iRangeY); cObj->x=fixtoi(cObj->fix_x); cObj->y=fixtoi(cObj->fix_y); return TRUE; }
// Returns whether or not the effect finished bool updateExplosionEffect() { bool effectDone = true; areaToCheck.x = 319; areaToCheck.y = 239; areaToCheck.w = 1; areaToCheck.h = 1; // Handle particles for(int i = 0; i < MAX_EXPLOSION_PARTICLE; i++) { if(explosionArray[i]->isActive()) { explosionArray[i]->update(); areaToCheck.x = max(1, min(areaToCheck.x, fixtoi(explosionArray[i]->x))); areaToCheck.y = max(1, min(areaToCheck.y, fixtoi(explosionArray[i]->y))); areaToCheck.w = min(319, max(areaToCheck.w, fixtoi(explosionArray[i]->x))); areaToCheck.h = min(239, max(areaToCheck.h, fixtoi(explosionArray[i]->y))); } } // Erase unwanted parts for(int i = 0; i < 320; i++) explosionBuffer[i][0] = explosionBuffer[i][239] = 0; for(int i = 0; i < 240; i++) explosionBuffer[0][i] = explosionBuffer[319][i] = 0; // Shift the fire buffer for(int y = areaToCheck.y; y < areaToCheck.h; y++) { for(int x = areaToCheck.x; x < areaToCheck.w; x++) { int temp; int x1 = x - 1, x2 = x + 1, y1 = y - 1, y2 = y + 1; temp = explosionBuffer[x1][y1]; temp += explosionBuffer[x][y1]; temp += explosionBuffer[x2][y1]; temp += explosionBuffer[x1][y]; temp += explosionBuffer[x2][y]; temp += explosionBuffer[x1][y2]; temp += explosionBuffer[x][y2]; temp += explosionBuffer[x2][y2]; temp /= 8; if(temp > 4) { temp -= 4; effectDone = false; } else temp = 0; explosionBuffer[x][y] = temp; } } explosionGoing = !effectDone; return effectDone; }
/* draw_object just draws a single object at a fixed position, although this can easily be modified to allow for more objects. bmp = bitmap to draw to. obj = sprite for the object. angle, cx, cy define the camera position. */ void draw_object (BITMAP *bmp, BITMAP *obj, fixed angle, fixed cx, fixed cy, MODE_7_PARAMS params) { int width, height; int screen_y, screen_x; // The object in this case is at a fixed position of (160, 100). // Calculate the position relative to the camera. fixed obj_x = itofix(160) - cx; fixed obj_y = itofix(100) - cy; // use a rotation transformation to rotate the object by the camera // angle fixed space_x = fmul (obj_x, fcos (angle)) + fmul (obj_y, fsin (angle)); fixed space_y = -fmul (obj_x, fsin (angle)) + fmul (obj_y, fcos (angle)); // calculate the screen coordinates that go with these space coordinates // by dividing everything by space_x (the distance) screen_x = bmp->w/2 + fixtoi (fmul (fdiv (params.scale_x, space_x), space_y)); screen_y = fixtoi (fdiv (fmul (params.space_z, params.scale_y), space_x)) - params.horizon; // the size of the object has to be scaled according to the distance height = fixtoi (obj->h * fdiv(params.obj_scale_y, space_x)); width = fixtoi (obj->w * fdiv(params.obj_scale_x, space_x)); // draw the object stretch_sprite (bmp, obj, screen_x - width / 2, screen_y - height, width, height); }
bool C4MaterialMap::mrfScript(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged) { // do generic checks for user-defined reactions if (!mrfUserCheck(pReaction, iX, iY, iLSPosX, iLSPosY, fXDir, fYDir, iPxsMat, iLsMat, evEvent, pfPosChanged)) return false; // check script func if (!pReaction->pScriptFunc) return false; // OK - let's call it! // 0 1 2 3 4 5 6 7 8 int32_t iXDir1, iYDir1, iXDir2, iYDir2; C4AulParSet pars(iX, iY, iLSPosX, iLSPosY, iXDir1 = fixtoi(fXDir, 100), iYDir1 = fixtoi(fYDir, 100), iPxsMat, iLsMat, int(evEvent)); if (!!pReaction->pScriptFunc->Exec(NULL, &pars, false)) { // PXS shall be killed! return true; } // PXS shall exist further: write back parameters iPxsMat = pars[6].getInt(); int32_t iX2 = pars[0].getInt(), iY2 = pars[1].getInt(); iXDir2 = pars[4].getInt(); iYDir2 = pars[5].getInt(); if (iX!=iX2 || iY!=iY2 || iXDir1!=iXDir2 || iYDir1!=iYDir2) { // changes to pos/speed detected if (pfPosChanged) *pfPosChanged = true; iX=iX2; iY=iY2; fXDir = C4REAL100(iXDir2); fYDir = C4REAL100(iYDir2); } // OK; done return false; }
static inline void tur_do_laser(game_data_t *gd, turret_t *turret) { /* shoot something? */ turret->laser_fire = 0; if (turret->target_monster != NULL) { if ((fixtoi(turret->angle) == fixtoi(turret->desired_angle)) && tur_target_within_range(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16)) { if (tur_target_within_sight(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16) == 1) { if (turret->fire_reset_count == 0) { turret->fire_reset_count = 1; turret->laser_fire = 1; stop_sample(gd->samples->gun_laser); play_sample(gd->samples->gun_laser, 255, 128, 1000, 0); /* register damage */ monster_register_hit(turret->target_monster, 0.5); } } } } if (turret->fire_reset_count > 0) turret->fire_reset_count--; tur_rotate(turret); tur_target(turret); }
static inline void tur_do_gun(game_data_t *gd, turret_t *turret) { /* shoot something? */ if (turret->target_monster != NULL) { if ((fixtoi(turret->angle) == fixtoi(turret->desired_angle)) && tur_target_within_range(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16)) { if (tur_target_within_sight(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16) == 1) { if (turret->fire_reset_count == 0) { turret->fire_reset_count = 100 / turret->fire_rate; bullet_add_bullet(turret, turret->target_monster, tur_get_distance(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16)); play_sample(gd->samples->gun_gun, 180, 128, 1000, 0); } } } } if (turret->fire_reset_count > 0) turret->fire_reset_count--; tur_rotate(turret); tur_target(turret); }
static inline void tur_rotate(turret_t *turret) { fixed dx, dy; int i; int dir_n, dir_p; int x, y; int rotate_direction; x = turret->x * 32; y = turret->y * 32; rotate_direction = 0; /* rotate: get desired angle from target */ if (turret->target_monster != NULL) { dx = itofix((x + 16) - (int)(turret->target_monster->x + 16)); dy = itofix((y + 16) - (int)(turret->target_monster->y + 16)); turret->desired_angle = fatan2(dy, dx) - itofix(64); } else turret->desired_angle = itofix(-420); if (turret->target_monster != NULL) { if (fixtoi(turret->angle) != fixtoi(turret->desired_angle) && tur_target_within_range(turret,(int)turret->target_monster->x + 16,(int)turret->target_monster->y + 16)) { dir_n = 0; dir_p = 0; /* calculate travel distances */ i = fixtoi(turret->angle); for (;;) { i--; dir_n++; if (i < -192) i = 64; if (i > 64) i = -192; if (i == fixtoi(turret->desired_angle)) break; } i = fixtoi(turret->angle); for (;;) { i++; dir_p++; if (dir_p > dir_n) break; if (i < -192) i = 64; if (i > 64) i = -192; if (i == fixtoi(turret->desired_angle)) break; } /* rotate */ if (dir_n < dir_p) rotate_direction = 1; else rotate_direction = 2; if (rotate_direction == 1) turret->angle = itofix(fixtoi(turret->angle) - 1); if (rotate_direction == 2) turret->angle = itofix(fixtoi(turret->angle) + 1); if (fixtoi(turret->angle) > 64) turret->angle = itofix(-192); if (fixtoi(turret->angle) < -192) turret->angle = itofix(64); } } /* rotate */ }
static int grproc_xadvance( INSTANCE * my, int * params ) { int angle = params[0] ; LOCINT32( mod_grproc, my, COORDX ) += fixtoi( fmul( fcos( angle ), itofix( params[1] ) ) ) ; LOCINT32( mod_grproc, my, COORDY ) -= fixtoi( fmul( fsin( angle ), itofix( params[1] ) ) ) ; return 1 ; }
C4MapScriptAlgoRotate::C4MapScriptAlgoRotate(const C4PropList *props) : C4MapScriptAlgoModifier(props,1,1) { // Get MAPALGO_Rotate properties int32_t r = props->GetPropertyInt(P_R); sr=fixtoi(Sin(itofix(r)), Precision); cr=fixtoi(Cos(itofix(r)), Precision); ox = props->GetPropertyInt(P_OffX); oy = props->GetPropertyInt(P_OffY); }
static inline void tur_do_storm(game_data_t *gd, turret_t *turret) { monster_t *monster; monster_t *area_monster[100]; int area_i = 0; /* shoot something? */ turret->laser_fire--; if (turret->laser_fire < 0) turret->laser_fire = 0; if (turret->target_monster == NULL) turret->laser_fire = 0; if (turret->target_monster != NULL) { if ((fixtoi(turret->angle) == fixtoi(turret->desired_angle)) && tur_target_within_range(turret, (int)turret->target_monster->x + 16, (int)turret->target_monster->y + 16)) { if (turret->fire_reset_count == 0 && turret->laser_fire == 0) { turret->laser_fire = 20; turret->fire_reset_count = 200 / turret->fire_rate; play_sample(gd->samples->gun_storm, 150, 128, 1000, 0); } if (turret->laser_fire > 0) { /* do areal damage ! */ monster = gd->monster; for (;;) { if (monster == NULL) break; if (monster == turret->target_monster || get_distance(turret->target_monster->x, turret->target_monster->y, monster->x, monster->y) < 35) { area_monster[area_i++] = monster; if (area_i >= 99) break; } monster = monster->next; } /* for */ for (;;) { area_i--; if (area_i < 0) break; monster_register_hit(area_monster[area_i], 2); } } /* laser_fire > 0 */ } } /* shoot */ if (turret->fire_reset_count > 0) turret->fire_reset_count--; tur_rotate(turret); tur_target(turret); }
/* calc_spline: * Calculates a set of pixels for the bezier spline defined by the four * points specified in the points array. The required resolution * is specified by the npts parameter, which controls how many output * pixels will be stored in the x and y arrays. */ void calc_spline(int points[8], int npts, int *x, int *y) { int i; fixed denom; for (i=0; i<npts; i++) { denom = fdiv(itofix(i), itofix(npts-1)); x[i] = fixtoi(bezval(denom, points)); y[i] = fixtoi(bezval(denom, points+1)); } }
void drawVectorSpace(SH_VectorSpace *s, uint16_t c) { int i; SH_Vector cv; // TODO : background for(i = 0; i < 6; i++) { cv = extendToScreenEdge(&s->vectors[i]); drawLine(160, 120, fixtoi(fixmul(cv.r, fixcos(cv.a))) + 160, fixtoi(fixmul(cv.r, fixsin(cv.a))) + 120, c); } }
void alienrocket::update(){ if(fired){ // rocket moves towards destination: if((fixtoi(x) > 0) && (fixtoi(x) < 800) && (fixtoi(y) < 600) && (fixtoi(y) > 0)){ x += speed * fcos (angle); y += speed * fsin (angle); }else{ fired = false; } //angle = (angle + angle_stepsize) & 0xFFFFFF; //if we hit the player if (abs (x - targetX) + abs (y - targetY) < itofix(50)){ hit = true; fired = false; } } }
bool C4ValueProviderSinV::Execute() { // Object might have been removed if(!Object) return false; // TODO: Maybe we can optimize this by using cos(r) = x/sqrt(x*x+y*y), sin(r)=y/sqrt(x*x+y*y), // plus addition theorems for sin or cos. int angle = Angle(0, 0, fixtoi(Object->xdir, 256), fixtoi(Object->ydir, 256)); Value = Begin + (End - Begin) * Sin(itofix(angle) + Offset); return true; }
void mode_7 (BITMAP *bmp, BITMAP *tile, fixed angle, fixed cx, fixed cy, MODE_7_PARAMS params) { // current screen position int screen_x, screen_y; // the distance and horizontal scale of the line we are drawing fixed distance, horizontal_scale; // masks to make sure we don't read pixels outside the tile int mask_x = (tile->w - 1); int mask_y = (tile->h -1); // step for points in space between two pixels on a horizontal line fixed line_dx, line_dy; // current space position fixed space_x, space_y; for (screen_y = 0; screen_y < bmp->h; screen_y++) { // first calculate the distance of the line we are drawing distance = fdiv (fmul (params.space_z, params.scale_y), itofix (screen_y + params.horizon)); // then calculate the horizontal scale, or the distance between // space points on this horizontal line horizontal_scale = fdiv (distance, params.scale_x); // calculate the dx and dy of points in space when we step // through all points on this line line_dx = fmul (-fsin(angle), horizontal_scale); line_dy = fmul (fcos(angle), horizontal_scale); // calculate the starting position space_x = cx + fmul (distance, fcos(angle)) - bmp->w/2 * line_dx; space_y = cy + fmul (distance, fsin(angle)) - bmp->w/2 * line_dy; // go through all points in this screen line for (screen_x = 0; screen_x < bmp->w; screen_x++) { // get a pixel from the tile and put it on the screen putpixel (bmp, screen_x, screen_y, getpixel (tile, fixtoi (space_x) & mask_x, fixtoi (space_y) & mask_y )); // advance to the next position in space space_x += line_dx; space_y += line_dy; } } }
void Particles::handle() { for(int i = 0; i < MAX_PARTICLE; i++) { if(time[i]) { time[i]--; x[i] += dx[i]; y[i] += dy[i]; fillCircle(fixtoi(x[i]), fixtoi(y[i]), time[i] / dt[i], polarity[i] ? 0 : 0xffff); } } }
bool ObjectActionJump(C4Object *cObj, C4Real xdir, C4Real ydir, bool fByCom) { // scripted jump? assert(cObj); C4AulParSet pars(fixtoi(xdir, 100), fixtoi(ydir, 100), fByCom); if (!!cObj->Call(PSF_OnActionJump, &pars)) return true; // hardcoded jump by action if (!cObj->SetActionByName("Jump")) return false; cObj->xdir=xdir; cObj->ydir=ydir; cObj->Mobile=true; // unstick from ground, because jump command may be issued in an Action-callback, // where attach-values have already been determined for that frame cObj->Action.t_attach&=~CNAT_Bottom; return true; }
BOOL ObjectActionJump(C4Object *cObj, FIXED xdir, FIXED ydir, bool fByCom) { // scripted jump? assert(cObj); C4AulParSet pars(C4VInt(fixtoi(xdir, 100)), C4VInt(fixtoi(ydir, 100)), C4VBool(fByCom)); if (!!cObj->Call(PSF_OnActionJump, &pars)) return TRUE; // hardcoded jump by action if (!cObj->SetActionByName("Jump")) return FALSE; cObj->xdir=xdir; cObj->ydir=ydir; cObj->Mobile=1; // unstick from ground, because jump command may be issued in an Action-callback, // where attach-values have already been determined for that frame cObj->Action.t_attach&=~CNAT_Bottom; return TRUE; }
static t_int *sigvd_perform(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_sample *out = (t_sample *)(w[2]); t_delwritectl *ctl = (t_delwritectl *)(w[3]); #ifndef ROCKBOX t_sigvd *x = (t_sigvd *)(w[4]); #endif int n = (int)(w[5]); int nsamps = ctl->c_n; int fn = n; t_sample limit = nsamps - n - 1; t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase; #ifndef ROCKBOX t_sample zerodel = x->x_zerodel; #endif while (n--) { t_time delsamps = ((long long) mult((*in++),ftofix(44.1)));//- itofix(zerodel); int index = fixtoi(delsamps); t_sample frac; // post("%d: index %d f %lld",index,findex,*in); frac = delsamps - itofix(index); index+=fn; if (index < 1 ) index += nsamps ; if (index > limit) index-= nsamps; bp = wp - index; if (bp < vp + 2) bp += nsamps; *out++ = bp[-1] + mult(frac,bp[-1]-bp[0]); wp++; } return (w+6); }
static t_int *osc_perform(t_int *w) { t_osc *x = (t_osc *)(w[1]); t_sample *in = (t_sample *)(w[2]); t_sample *out = (t_sample *)(w[3]); int n = (int)(w[4]); t_sample *tab = cos_table; unsigned int phase = x->x_phase; int conv = x->x_conv; int off; int frac; while (n--) { phase+= mult(conv ,(*in++)); phase &= (itofix(1) -1); off = fixtoi((long long)phase<<ILOGCOSTABSIZE); #ifdef NO_INTERPOLATION *out = *(tab+off); #else // frac = phase & (itofix(1)-1); frac = phase & ((1<<ILOGCOSTABSIZE)-1); frac <<= (fix1-ILOGCOSTABSIZE); *out = mult(*(tab + off),(itofix(1) - frac)) + mult(*(tab + off + 1),frac); #endif out++; } x->x_phase = phase; return (w+5); }
/* calculates the control points for a spline segment */ void get_control_points(NODE n1, NODE n2, int points[8]) { fixed dist = fixmul(node_dist(n1, n2), curviness); points[0] = n1.x; points[1] = n1.y; points[2] = n1.x + fixtoi(fixmul(fixcos(n1.tangent), dist)); points[3] = n1.y + fixtoi(fixmul(fixsin(n1.tangent), dist)); points[4] = n2.x - fixtoi(fixmul(fixcos(n2.tangent), dist)); points[5] = n2.y - fixtoi(fixmul(fixsin(n2.tangent), dist)); points[6] = n2.x; points[7] = n2.y; }
void C4Weather::Execute() { // Season if (!::Game.iTick35) { SeasonDelay+=YearSpeed; if (SeasonDelay>=200) { SeasonDelay=0; Season++; if (Season>Game.C4S.Weather.StartSeason.Max) Season=Game.C4S.Weather.StartSeason.Min; SetSeasonGamma(); } } // Temperature if (!::Game.iTick35) { int32_t iTemperature = Climate - fixtoi(Cos(itofix(36 * Season, 10)), TemperatureRange); if (Temperature<iTemperature) Temperature++; else if (Temperature>iTemperature) Temperature--; } // Wind if (!::Game.iTick1000) TargetWind=Game.C4S.Weather.Wind.Evaluate(); if (!::Game.iTick10) Wind=Clamp<int32_t>(Wind+Sign(TargetWind-Wind), Game.C4S.Weather.Wind.Min, Game.C4S.Weather.Wind.Max); }
bool mrfInsertCheck(int32_t &iX, int32_t &iY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, bool *pfPosChanged) { // always manipulating pos/speed here if (pfPosChanged) *pfPosChanged = true; // Move up by up to 3px to account for moving SolidMasks, other material insertions, etc. int32_t mdens = std::min(::MaterialMap.Map[iPxsMat].Density, C4M_Solid); int32_t max_upwards = 3; bool was_pushed_upwards = false; while (max_upwards-- && (::Landscape.GetDensity(iX, iY) >= mdens)) { --iY; was_pushed_upwards = true; } // Rough contact? May splash if (fYDir > itofix(1)) if (::MaterialMap.Map[iPxsMat].SplashRate && !Random(::MaterialMap.Map[iPxsMat].SplashRate)) { fYDir = -fYDir/8; fXDir = fXDir/8 + C4REAL100(Random(200) - 100); if (fYDir) return false; } // Contact: Stop fYDir = -GravAccel; // Incendiary mats smoke on contact even before doing their slide if (::MaterialMap.Map[iPxsMat].Incendiary) if (!Random(25)) { Smoke(iX, iY, 4 + Random(3)); } // Move by mat path/slide int32_t iSlideX = iX, iSlideY = iY; if (::Landscape.FindMatSlide(iSlideX,iSlideY,Sign(GravAccel),mdens,::MaterialMap.Map[iPxsMat].MaxSlide)) { // Sliding on equal material: Move directly to optimize insertion of rain onto lakes // Also move directly when shifted upwards to ensure movement on permamently moving SolidMask if (iPxsMat == iLsMat || was_pushed_upwards) { iX = iSlideX; iY = iSlideY; fXDir = 0; return false; } // Otherwise, just move using xdir/ydir for nice visuals when rain is moving over landscape // Accelerate into the direction fXDir = (fXDir * 10 + Sign(iSlideX - iX)) / 11 + C4REAL10(Random(5)-2); // Slide target in range? Move there directly. if (Abs(iX - iSlideX) <= Abs(fixtoi(fXDir))) { iX = iSlideX; iY = iSlideY; if (fYDir <= 0) fXDir = 0; } // Continue existance return false; } // insertion OK return true; }
/* draw a quad */ void draw_quad(BITMAP *b, VTX *v1, VTX *v2, VTX *v3, VTX *v4, int mode) { int col; /* four vertices */ V3D vtx1 = { v1->x, v1->y, v1->z, 0, 0, 0 }; V3D vtx2 = { v2->x, v2->y, v2->z, 0, 0, 0 }; V3D vtx3 = { v3->x, v3->y, v3->z, 0, 0, 0 }; V3D vtx4 = { v4->x, v4->y, v4->z, 0, 0, 0 }; /* cull backfaces */ if (polygon_z_normal(&vtx1, &vtx2, &vtx3) < 0) return; /* set up the vertex color, differently for each rendering mode */ switch (mode) { case POLYTYPE_FLAT: col = MID(128, 255 - fixtoi(v1->z+v2->z) / 16, 255); vtx1.c = vtx2.c = vtx3.c = vtx4.c = col; break; case POLYTYPE_GCOL: vtx1.c = 208; vtx2.c = 128; vtx3.c = vtx2.c + 1; vtx4.c = vtx1.c + 1; /* vtx1.c = 208; vtx2.c = 128; vtx3.c = vtx2.c + 48; vtx4.c = vtx1.c + 48;*/ break; case POLYTYPE_ATEX_LIT: case POLYTYPE_PTEX_LIT: vtx1.c = MID(0, 255 - fixtoi(v1->z) / 4, 255); vtx2.c = MID(0, 255 - fixtoi(v2->z) / 4, 255); vtx3.c = MID(0, 255 - fixtoi(v3->z) / 4, 255); vtx4.c = MID(0, 255 - fixtoi(v4->z) / 4, 255); break; } /* draw the quad */ quad3d(buffer, mode, NULL, &vtx1, &vtx2, &vtx3, &vtx4); }
bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter) { bool hitOnTime = true; bool fBreak = false; int32_t ctcox,ctcoy,cx,cy,i; cx = fixtoi(x); cy = fixtoi(y); i = iIter; do { if (!--i) {hitOnTime = false; break;} // If the object isn't moving and there is no gravity either, abort if (xdir == 0 && ydir == 0 && GravAccel == 0) return false; // If the object is above the landscape flying upwards in no/negative gravity, abort if (ydir <= 0 && GravAccel <= 0 && cy < 0) return false; // Set target position by momentum x+=xdir; y+=ydir; // Movement to target ctcox=fixtoi(x); ctcoy=fixtoi(y); // Bounds if (!Inside<int32_t>(ctcox,0,GBackWdt) || (ctcoy>=GBackHgt)) return false; // Move to target do { // Set next step target cx+=Sign(ctcox-cx); cy+=Sign(ctcoy-cy); // Contact check if (Inside(GBackDensity(cx,cy), iDensityMin, iDensityMax)) { fBreak = true; break; } } while ((cx!=ctcox) || (cy!=ctcoy)); // Adjust GravAccel once per frame ydir+=GravAccel; } while (!fBreak); // write position back x = itofix(cx); y = itofix(cy); // how many steps did it take to get here? iIter -= i; return hitOnTime; }
/* draws the spline paths */ void draw_splines(void) { int i; acquire_screen(); clear_to_color(screen, makecol(255, 255, 255)); textout_centre_ex(screen, font, "Spline curve path", SCREEN_W/2, 8, palette_color[255], palette_color[0]); textprintf_centre_ex(screen, font, SCREEN_W/2, 32, palette_color[255], palette_color[0], "Curviness = %.2f", fixtof(curviness)); textout_centre_ex(screen, font, "Up/down keys to alter", SCREEN_W/2, 44, palette_color[255], palette_color[0]); textout_centre_ex(screen, font, "Space to walk", SCREEN_W/2, 68, palette_color[255], palette_color[0]); textout_centre_ex(screen, font, "C to display control points", SCREEN_W/2, 92, palette_color[255], palette_color[0]); textout_centre_ex(screen, font, "T to display tangents", SCREEN_W/2, 104, palette_color[255], palette_color[0]); for (i=1; i<node_count-2; i++) draw_spline(nodes[i], nodes[i+1]); for (i=1; i<node_count-1; i++) { draw_node(i); if (show_tangents) { line(screen, nodes[i].x - fixtoi(fixcos(nodes[i].tangent) * 24), nodes[i].y - fixtoi(fixsin(nodes[i].tangent) * 24), nodes[i].x + fixtoi(fixcos(nodes[i].tangent) * 24), nodes[i].y + fixtoi(fixsin(nodes[i].tangent) * 24), palette_color[1]); } } release_screen(); }
bool SimFlightHitsLiquid(C4Real fcx, C4Real fcy, C4Real xdir, C4Real ydir) { // Start in water? int temp; if (DensityLiquid(GBackDensity(fixtoi(fcx), fixtoi(fcy)))) if (!SimFlight(fcx, fcy, xdir, ydir, 0, C4M_Liquid - 1, temp=10)) return false; // Hits liquid? if (!SimFlight(fcx, fcy, xdir, ydir, C4M_Liquid, 100, temp=-1)) return false; // liquid & deep enough? return GBackLiquid(fixtoi(fcx), fixtoi(fcy)) && GBackLiquid(fixtoi(fcx), fixtoi(fcy) + 9); }
int d_agtk_slider_proc(int msg, DIALOG *d, int c) { if (msg == MSG_DRAW) { BITMAP *bmp = gui_get_screen(); int vert = TRUE; /* flag: is slider vertical? */ int hh = 32; /* handle height (width for horizontal sliders) */ int slp; /* slider position */ int irange; int slx, sly, slh, slw; fixed slratio, slmax, slpos; /* check for slider direction */ if (d->h < d->w) vert = FALSE; irange = (vert) ? d->h : d->w; slmax = itofix(irange-hh); slratio = slmax / (d->d1); slpos = slratio * d->d2; slp = fixtoi(slpos); /* draw background */ gtk_box(bmp, d->x, d->y, d->w, d->h, 2, 0); /* now draw the handle */ if (vert) { slx = d->x+2; sly = d->y+2+(d->h)-(hh+slp); slw = d->w-1-3; slh = hh-1-3; } else { slx = d->x+2+slp; sly = d->y+2; slw = hh-1-3; slh = d->h-1-3; } gtk_box(bmp, slx, sly, slw, slh, (d->flags & D_GOTFOCUS) ? 1 : 0, 0); return D_O_K; } return d_slider_proc(msg, d, c); }
void line(struct fb *dst, int x0, int y0, int x1, int y1, int cl) { int len; fixed x, y, dx, dy; len = imax(iabs(x1 - x0), iabs(y1 - y0)); if(!len) { putpixel(dst, x0, y0, cl); return; } x = itofix(x0); y = itofix(y0); dx = frac(x1 - x0, len); dy = frac(y1 - y0, len); for(; len >= 0; len--) { putpixel(dst, fixtoi(x), fixtoi(y), cl); x += dx; y += dy; } }