int main(int argc, char *argv[]) { const fixed dt = (1 << FIXPOINT_SHIFT) / 100; // 60 FPS fixed t = 0; fixed accumulator = 0; fixed delta_time = 0; SDL_Event event; init(); while (!app.quit) { start_frame(); delta_time = get_last_frame_time(); if (SDL_PollEvent(&event)) { handle_event(&event); } if (!app.paused) { accumulator += delta_time; // trace("accumulator %ld, dt: %ld, delta_time %ld", accumulator, dt, delta_time); while (accumulator >= dt) { move_objects(t, dt); t += dt; accumulator -= dt; } interpolate(fpdiv(accumulator, dt)); draw_scene(); } end_frame(); } return 0; }
void ParticleEmitter::render(unsigned short* vscreen, unsigned int pitch) { ParticleFX::render(vscreen, pitch); #ifdef LENSE_REFLECTION for (int i = 0; i < numEmitters; i++) { // draw lens-flare reflections VectorFP v = rotMatrix*emitters[i].pos; int z = v.z+zOffset; if (z>65536) { if (emitters[i].size) { int rz = fpdiv(65536,z); int ix = (fpmul((v.x),rz)*FOV)+(width>>1)*65536; int iy = (fpmul((v.y),rz)*FOV)+(height>>1)*65536; int size = fpmul((emitters[i].size>>1)*FOV,rz); int ix2 = (width-1)*65536-ix; int iy2 = (height-1)*65536-iy; int dx = ix2-ix; int dy = iy2-iy; int ix3 = (ix+ix2)>>1; int iy3 = (iy+iy2)>>1; Sprite spr; spr.tx = (ix+fpmul(dx,65536*3)); spr.ty = (iy+fpmul(dy,65536*3)); spr.xsize = size<<2; spr.ysize = size<<2; spr.xres = emitters[i].textureWidth-1; spr.yres = emitters[i].textureHeight-1; spr.xoffset = 0; spr.yoffset = 0; spr.texturexres = emitters[i].textureWidth; spr.flags = 0; spr.texture = emitterTexture[4]; drawSprite(vscreen,width, height, pitch, &spr); spr.tx = (ix+fpmul(dx,65536)); spr.ty = (iy+fpmul(dy,65536)); spr.xsize = fpmul(size,65536+32768); spr.ysize = fpmul(size,65536+32768); spr.texture = emitterTexture[1]; drawSprite(vscreen,width, height, pitch, &spr); spr.tx = ix3; spr.ty = iy3; spr.xsize = size>>2; spr.ysize = size>>2; spr.texture = emitterTexture[5]; drawSprite(vscreen,width, height, pitch, &spr); spr.tx = (ix+ix3)>>1; spr.ty = (iy+iy3)>>1; spr.xsize = size; spr.ysize = size; spr.texture = emitterTexture[2]; drawSprite(vscreen,width, height, pitch, &spr); spr.tx = (ix+fpmul(dx,65536*2)); spr.ty = (iy+fpmul(dy,65536*2)); spr.xsize = size; spr.ysize = size; spr.texture = emitterTexture[3]; drawSprite(vscreen,width, height, pitch, &spr); spr.tx = (ix+fpmul(dx,65536*3+32768)); spr.ty = (iy+fpmul(dy,65536*3+32768)); spr.xsize = size>>1; spr.ysize = size>>1; spr.texture = emitterTexture[5]; drawSprite(vscreen,width, height, pitch, &spr); } } }
enum RPNError rpn_run(byte *rpnExpr, word rpnLen, Float *yValue, Float *xValue) { rpnStackIndex = 0; word reader = 0; while (reader < rpnLen) { byte op = rpnExpr[reader++]; switch (op) { case RPN_VAR: // put a copy of the independent variable's value on rpnStack if (rpnStackIndex == RPN_STACK_SIZE) return RPN_ERR_OVERFLOW; rpn_push(xValue); break; case RPN_FUNC: { if (rpnStackIndex < 1) return RPN_ERR_UNDERFLOW; fp0load(rpn_get(rpnStackIndex - 1)); byte funcIndex = rpnExpr[reader++]; if (funcIndex == UNKNOWN_FUNCTION_INDEX) { --reader; return RPN_ERR_INVALID_FUNC; } // Check the argument (FP0). void *check = knownFunctions[funcIndex].checkArgFuncPtr; if (check) { enum RPNError e = (*check)(); // check FP0 if (e != RPN_ERR_NONE) return e; } // Argument (FP0) is valid. Apply the function to it. (*knownFunctions[funcIndex].evalFuncPtr)(); --rpnStackIndex; rpn_push(FP0ADDR); // push the result break; } case RPN_NUM: // put FP that follows on rpnStack if (rpnStackIndex == RPN_STACK_SIZE) return RPN_ERR_OVERFLOW; rpn_push((Float *) (rpnExpr + reader)); // push 6-byte accumulator reader += sizeof(Float); break; case RPN_ADD: case RPN_SUB: case RPN_MUL: if (rpnStackIndex < 2) return RPN_ERR_UNDERFLOW; fp0load(rpn_get(rpnStackIndex - 2)); fp1load(rpn_get(rpnStackIndex - 1)); switch (op) { case RPN_ADD: fpadd(); break; case RPN_SUB: fpsub(); break; case RPN_MUL: fpmul(); break; } rpnStackIndex -= 2; rpn_push(FP0ADDR); // push the result break; case RPN_DIV: { if (rpnStackIndex < 2) return RPN_ERR_UNDERFLOW; // Check if the divisor is too close to zero Float *divisor = rpn_get(rpnStackIndex - 1); fp0load(divisor); fpabs(); if (fpcmp(&verySmall) < 0) // if abs(divisor) too small return RPN_ERR_DIV_BY_ZERO; // avoid enormous (and unusable) quotient fp0load(divisor); fp1load(rpn_get(rpnStackIndex - 2)); // dividend fpdiv(); rpnStackIndex -= 2; rpn_push(FP0ADDR); // push the result break; } case RPN_NEG: if (rpnStackIndex < 1) return RPN_ERR_UNDERFLOW; fp0load(rpn_get(rpnStackIndex - 1)); fpneg(); --rpnStackIndex; rpn_push(FP0ADDR); // push the result break; case RPN_POW: if (rpnStackIndex < 2) return RPN_ERR_UNDERFLOW; fp0load(rpn_get(rpnStackIndex - 1)); // power fp1load(rpn_get(rpnStackIndex - 2)); // base if (fp1sgn() < 0 && ! fpisint()) // if negative base and non-int power return RPN_ERR_POW_OF_NEG; fppow(); rpnStackIndex -= 2; rpn_push(FP0ADDR); // push the result break; default: --reader; return RPN_ERR_UNEXPECTED; } } if (rpnStackIndex != 1) return RPN_ERR_INVALID_EXPR; #if 0 fp0load(rpn_get(0)); char buf[FPSTRBUFSIZ]; char *decimalResult = fpstr(buf); printf("Result: [%s]\n", decimalResult); #endif fpcpy(yValue, rpn_get(0)); return RPN_ERR_NONE; }