/** * @brief Blits a sprite, position is relative to the player. * * Since position is in "game coordinates" it is subject to all * sorts of position transformations. * * @param sprite Sprite to blit. * @param bx X position of the texture relative to the player. * @param by Y position of the texture relative to the player. * @param sx X position of the sprite to use. * @param sy Y position of the sprite to use. * @param c Colour to use (modifies texture colour). */ void gl_blitSprite( const glTexture* sprite, const double bx, const double by, const int sx, const int sy, const glColour* c ) { double x,y, w,h, tx,ty, z; /* Translate coords. */ z = cam_getZoom(); gl_gameToScreenCoords( &x, &y, bx - sprite->sw/2., by - sprite->sh/2. ); /* Scaled sprite dimensions. */ w = sprite->sw*z; h = sprite->sh*z; /* check if inbounds */ if ((x < -w) || (x > SCREEN_W+w) || (y < -h) || (y > SCREEN_H+h)) return; /* texture coords */ tx = sprite->sw*(double)(sx)/sprite->rw; ty = sprite->sh*(sprite->sy-(double)sy-1)/sprite->rh; gl_blitTexture( sprite, x, y, w, h, tx, ty, sprite->srw, sprite->srh, c ); }
/** * @brief Blits a sprite interpolating, position is relative to the player. * * Since position is in "game coordinates" it is subject to all * sorts of position transformations. * * Interpolation is: sa*inter + sb*1.-inter) * * @param sa Sprite A to blit. * @param sb Sprite B to blit. * @param inter Amount to interpolate. * @param bx X position of the texture relative to the player. * @param by Y position of the texture relative to the player. * @param sx X position of the sprite to use. * @param sy Y position of the sprite to use. * @param c Colour to use (modifies texture colour). */ void gl_blitSpriteInterpolateScale( const glTexture* sa, const glTexture *sb, double inter, const double bx, const double by, double scalew, double scaleh, const int sx, const int sy, const glColour *c ) { double x,y, w,h, tx,ty, z; /* Translate coords. */ gl_gameToScreenCoords( &x, &y, bx - scalew * sa->sw/2., by - scaleh * sa->sh/2. ); /* Scaled sprite dimensions. */ z = cam_getZoom(); w = sa->sw*z*scalew; h = sa->sh*z*scaleh; /* check if inbounds */ if ((x < -w) || (x > SCREEN_W+w) || (y < -h) || (y > SCREEN_H+h)) return; /* texture coords */ tx = sa->sw*(double)(sx)/sa->rw; ty = sa->sh*(sa->sy-(double)sy-1)/sa->rh; gl_blitTextureInterpolate( sa, sb, inter, x, y, w, h, tx, ty, sa->srw, sa->srh, c ); }
/** * @brief Renders the background images. */ static void background_renderImages( background_image_t *bkg_arr ) { int i; background_image_t *bkg; double px,py, x,y, xs,ys, z; /* Must have an image array created. */ if (bkg_arr == NULL) return; /* Render images in order. */ for (i=0; i<array_size(bkg_arr); i++) { bkg = &bkg_arr[i]; cam_getPos( &px, &py ); x = px + (bkg->x - px) * bkg->move - bkg->scale*bkg->image->sw/2.; y = py + (bkg->y - py) * bkg->move - bkg->scale*bkg->image->sh/2.; gl_gameToScreenCoords( &xs, &ys, x, y ); z = cam_getZoom(); z *= bkg->scale; gl_blitScale( bkg->image, xs, ys, z*bkg->image->sw, z*bkg->image->sh, &bkg->col ); } }
/** * @brief Updates a camera following a pilot. */ static void cam_updatePilot( Pilot *follow, double dt ) { Pilot *target; double diag2, a, r, dir, k; double x,y, dx,dy, mx,my, targ_x,targ_y, bias_x,bias_y, vx,vy; /* Get target. */ if (!pilot_isFlag(follow, PILOT_HYPERSPACE) && (follow->target != follow->id)) target = pilot_get( follow->target ); else target = NULL; /* Real diagonal might be a bit too harsh since it can cut out the ship, * we'll just use the largest of the two. */ /*diag2 = pow2(SCREEN_W) + pow2(SCREEN_H);*/ /*diag2 = pow2( MIN(SCREEN_W, SCREEN_H) );*/ diag2 = 100*100; x = follow->solid->pos.x; y = follow->solid->pos.y; /* Compensate player movement. */ mx = x - old_X; my = y - old_Y; camera_X += mx; camera_Y += my; /* Set old position. */ old_X = x; old_Y = y; /* No bias by default. */ bias_x = 0.; bias_y = 0.; /* Bias towards target. */ if (target != NULL) { bias_x += target->solid->pos.x - x; bias_y += target->solid->pos.y - y; } /* Bias towards velocity and facing. */ vx = follow->solid->vel.x*1.5; vy = follow->solid->vel.y*1.5; dir = angle_diff( atan2(vy,vx), follow->solid->dir); dir = (M_PI - fabs(dir)) / M_PI; /* Normalize. */ vx *= dir; vy *= dir; bias_x += vx; bias_y += vy; /* Limit bias. */ if (pow2(bias_x)+pow2(bias_y) > diag2/2.) { a = atan2( bias_y, bias_x ); r = sqrt(diag2)/2.; bias_x = r*cos(a); bias_y = r*sin(a); } /* Compose the target. */ targ_x = x + bias_x; targ_y = y + bias_y; /* Head towards target. */ k = 0.5*dt/dt_mod; dx = (targ_x-camera_X)*k; dy = (targ_y-camera_Y)*k; background_moveStars( -(mx+dx), -(my+dy) ); /* Update camera. */ camera_X += dx; camera_Y += dy; /* DEBUG. */ #if 0 glColor4d( 1., 1., 1., 1. ); glBegin(GL_LINES); gl_gameToScreenCoords( &x, &y, x, y ); glVertex2d( x, y ); gl_gameToScreenCoords( &x, &y, camera_X, camera_Y ); glVertex2d( x, y ); glEnd(); /* GL_LINES */ #endif /* Update zoom. */ cam_updatePilotZoom( follow, target, dt ); }