inline Quaternion Quaternion_fromEuler(int32 roll, int32 pitch, int32 yaw) { //http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q60 /*Quaternion q = Quaternion_identity(); Quaternion qt = Quaternion_identity(); Quaternion qx = { cosLerp(pitch/2), sinLerp(pitch/2), 0, 0 }; Quaternion qy = { cosLerp(yaw/2), 0, sinLerp(yaw/2), 0 }; Quaternion qz = { cosLerp(roll/2), 0, 0, sinLerp(roll/2) }; qt = Quaternion_multiplied(qx, qy); q = Quaternion_multiplied(qt, qz); return q;*/ //http://content.gpwiki.org/index.php/OpenGL%3aTutorials%3aUsing_Quaternions_to_represent_rotation#Quaternion_from_Euler_angles Quaternion this; int32 p = pitch / 2; int32 y = yaw / 2; int32 r = roll / 2; int32 sinp = sinLerp(p); int32 siny = sinLerp(y); int32 sinr = sinLerp(r); int32 cosp = cosLerp(p); int32 cosy = cosLerp(y); int32 cosr = cosLerp(r); this.x = mulf32(mulf32(sinr, cosp), cosy) - mulf32(mulf32(cosr, sinp), siny); this.y = mulf32(mulf32(cosr, sinp), cosy) + mulf32(mulf32(sinr, cosp), siny); this.z = mulf32(mulf32(cosr, cosp), siny) - mulf32(mulf32(sinr, sinp), cosy); this.w = mulf32(mulf32(cosr, cosp), cosy) + mulf32(mulf32(sinr, sinp), siny); return this; }
void orange_loop(orangeObjectInstance *me) { me->variables->vy += 16; me->bx += me->variables->vx; me->by += me->variables->vy; me->x = me->bx >> me->bitshift; me->y = me->by >> me->bitshift; if(me->y > 192) { DSGM_DeleteObjectInstance(me); } if(me->frame == 0) { int x = drawCoords[0].x, y = drawCoords[0].y, x2 = drawCoords[1].x, y2 = drawCoords[1].y, length = 32; int angle = DSGM_GetAngle(x, y, x2, y2) + degreesToAngle(90); x = (cosLerp(angle) * length / 2) >> 12; y = (-sinLerp(angle) * length / 2) >> 12; angle += degreesToAngle(180); x2 = (cosLerp(angle) * length / 2) >> 12; y2 = (-sinLerp(angle) * length / 2) >> 12; if(DSGM_Intersection(drawCoords[0].x, drawCoords[0].y, drawCoords[1].x, drawCoords[1].y, me->x + 16 + x, me->y + 16 + y, me->x + 16 + x2, me->y + 16 + y2)) { me->frame = 1; orangeObjectInstance *o = (orangeObjectInstance *)DSGM_CreateObjectInstance(DSGM_BOTTOM, me->x, me->y, me->object); o->variables->vx = me->variables->vx / 2; o->variables->vy = me->variables->vy / 2; o->frame = 2; } }
void TunnelPartExec(int time) { int i; int32 dir[3]; CurrentTime = time; TunnelFxDraw((time>>6), sinLerp(time>>1), cosLerp(time>>1)); glEnable(GL_BLEND); DiscoElephant->transform->translation[2] = floattof32(-1) + ABS(sinLerp(time)/2); DiscoElephant->transform->rotation[0] = (DEGREES_IN_CIRCLE/16); DiscoElephant->transform->rotation[1] = sinLerp(time*2) / 2; for(i=0; i<4; i++) { dir[0] = (DiscoElephant->transform->translation[0] - flares[i]->position[0]); dir[1] = (DiscoElephant->transform->translation[1] - flares[i]->position[1]); dir[2] = (DiscoElephant->transform->translation[2] - flares[i]->position[2]); normalizef32(dir); dir[0] *= 0.9; dir[1] *= 0.9; dir[2] *= 0.9; Scene->lights[i]->direction[0] = f32tov10(dir[0]); Scene->lights[i]->direction[1] = f32tov10(dir[1]); Scene->lights[i]->direction[2] = f32tov10(dir[2]); } RenderScene(Scene); for(i=0; i<4; i++) { flares[i]->position[0] = DiscoElephant->transform->translation[0] + (int32)sinLerp((time<<1) + (i+1) * DEGREES_IN_CIRCLE/4)/2; flares[i]->position[1] = DiscoElephant->transform->translation[1] + (int32)cosLerp((time<<2) + (i+1) * DEGREES_IN_CIRCLE/4)/2; flares[i]->position[2] = DiscoElephant->transform->translation[2] + (int32)sinLerp((time<<3) + DEGREES_IN_CIRCLE/(i+1))/2; DrawBillboard(flares[i], false, 0, 0, 0, 0); } if(time < 1000) { FadeIn(time); } else if(time >= 28000) { FadeOut(time); } else { DrawFlash(time); } glFlush(0); swiWaitForVBlank(); }
void CharActor::explode() { dead = true; int r = 4; f32 xx, yy; sc->toWorldCoords(xx, yy, x, y); for(int ang = 0; ang < DEGREES_IN_CIRCLE; ang+=DEGREES_IN_CIRCLE / 12) { Particle *p2 = sc->addParticle60(); p2->vx = (vx+sc->vxCam).tof5()+sinLerp(ang)/160+irand(r); p2->vy = (vy+sc->vyCam).tof5()+cosLerp(ang)/160+irand(r); p2->x = xx.tof5(); p2->y = yy.tof5(); p2->nTexture = 1; p2->r = 255; p2->g = 160+irand(80); p2->b = 0; p2->a = 18; p2->sizePerLife = 6; p2->effect = FX_NOFRICTION; } }
/*********************************************************************************** * on_stream_request * * Audio stream data request handler. ***********************************************************************************/ mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) { //---------------------------------------------------------------------------------- s16 *target = dest; //------------------------------------------------------------ // synthensize a sine wave with an LFO applied to the pitch // the stereo data is interleaved //------------------------------------------------------------ int len = length; for( ; len; len-- ) { int sample = sinLerp(sine); // output sample for left *target++ = sample; // output inverted sample for right *target++ = -sample; sine += sine_freq + (sinLerp(lfo) >> lfo_shift); lfo = (lfo + lfo_freq); } return length; }
void initMenu(void) { lcdMainOnTop(); videoSetMode(MODE_5_3D); videoSetModeSub(MODE_5_2D); vramSetPrimaryBanks(VRAM_A_TEXTURE,VRAM_B_TEXTURE,VRAM_C_SUB_BG,VRAM_D_TEXTURE); initD3D(); glInit(); glEnable(GL_TEXTURE_2D); glEnable(GL_ANTIALIAS); glEnable(GL_BLEND); glEnable(GL_OUTLINE); glClearPolyID(63); glClearDepth(0x7FFF); glViewport(0,0,255,191); initVramBanks(2); initTextures(); initMenuScene(); initMenuButtons(); //TEMP glLight(0, RGB15(31,31,31), cosLerp(4096), 0, sinLerp(4096)); glMaterialf(GL_AMBIENT, RGB15(8,8,8)); glMaterialf(GL_DIFFUSE, RGB15(24,24,24)); glMaterialf(GL_SPECULAR, RGB15(0,0,0)); glMaterialf(GL_EMISSION, RGB15(0,0,0)); glSetToonTableRange(0, 15, RGB15(8,8,8)); //TEMP? glSetToonTableRange(16, 31, RGB15(24,24,24)); //TEMP? applyCameraState(&menuCamera,&cameraStates[4]); tempState=cameraStates[4]; testTransition=startCameraTransition(&cameraStates[1],&cameraStates[4],64); setupMenuPage(startMenuPage, startMenuPageLength); logoMain=createTexture("logo.pcx", "menu"); logoRotate=createTexture("rotate_logo.pcx", "menu"); logoAlpha=31; glSetOutlineColor(0,RGB15(0,0,0)); //TEMP? glSetOutlineColor(1,RGB15(0,0,0)); //TEMP? glSetOutlineColor(7,RGB15(0,0,0)); //TEMP? NOGBA("END mem free : %dko (%do)",getMemFree()/1024,getMemFree()); fadeIn(); }
void (DSGM_MoveObjectInstanceAtRotatedAngle)(DSGM_ObjectInstance *me) { if(me->bx >> me->bitshift != me->x || me->by >> me->bitshift != me->y) { me->bx = me->x << me->bitshift; me->by = me->y << me->bitshift; } me->bx += cosLerp(*me->angle); me->by -= sinLerp(*me->angle); me->x = me->bx >> me->bitshift; me->y = me->by >> me->bitshift; }
void TestScene::tick() { if(time == 1) { fires[0] = new FireActor(this); fires[0]->x = xCam; fires[0]->vx = camvel; fires[0]->y = -60; fires[0]->colorShift = 0; actors.push_back(fires[0]); } if(time % 5 == 0) { Particle* star = addParticle1000(); star->sizePerLife = -(1+rand() % 4); if(rand() % 6 == 0) star->sizePerLife -= 7+rand() % 4; star->vx = camvel.tof5()+star->sizePerLife*17-10; star->vy = 0; star->vx2 = 0; star->vy2 = 0; star->x = xCam.tof5()+230*32; // star->x = rand() % (192*32) - (192*32/16); star->y = rand() % (192*32) - (192*32/2); star->nTexture = TEX_DIAMOND; star->effect = FX_NOFRICTION; star->r = 150+rand() % 100; star->g = 150+rand() % 100; star->b = 255; star->a = 10+rand() % 21; } xCam += camvel; if(fires[0]) { // int ny = sinLerp(time*100) + sinLerp(time*240) + sinLerp(time*174)/2; // if(time < 250) int ny = sinLerp(time*440)*4; // if(time < 150) // ny = sinLerp(time*440)*3; f32 dy = fires[0]->y-(f32(ny) / (1<<7)); fires[0]->vy *= 0.7; fires[0]->vy -= dy/24; } Scene::tick(); }
polygon_struct* createEllipseOutline(vect3D po, vect3D v1_1, vect3D v2_1, vect3D v1_2, vect3D v2_2, vect3D norm, int n) { int i; polygon_struct *p, *pp; p=pp=createPolygon(addVect(po,v1_1)); p->next=createPolygon(addVect(norm,addVect(po,v1_2))); p=p->next; if(!p)return NULL; for(i=1;i<=n;i++) { const u16 a1=i*32768/n; vect3D v=addVect(po,addVect(vectMult(v1_1,cosLerp(a1)),vectMult(v2_1,sinLerp(a1)))); p->next=createPolygon(v); p=p->next; if(!p)return NULL; v=addVect(po,addVect(vectMult(v1_2,cosLerp(a1)),vectMult(v2_2,sinLerp(a1)))); p->next=createPolygon(addVect(norm,v)); p=p->next; if(!p)return NULL; } return pp; }
Quaternion Quaternion_fromAxisAngle(vect3D axis, int angle) { Quaternion quaternion; int32 sinAngle; angle /= 2; axis = normalize(axis); sinAngle = sinLerp(angle); quaternion.x = mulf32(axis.x, sinAngle); quaternion.y = mulf32(axis.y, sinAngle); quaternion.z = mulf32(axis.z, sinAngle); quaternion.w = cosLerp(angle); return quaternion; }
void GLFont::PrintSineVertical(int x, int y, const char *text, int height_offset, int _width, int cycles, s32 start_angle) { unsigned char font_char; unsigned int length = strlen(text); s32 angle_inc = div32(32768/2, length-1)*cycles; s32 _x; while(*text) { font_char = (*(unsigned char*)text++) - 32; _x = sinLerp(start_angle) * _width; glSprite( x + (_x >> 12), y, GL_FLIP_NONE, &font_sprite[font_char] ); y += font_sprite[font_char].height + height_offset; start_angle += angle_inc; } }
void GLFont::PrintSine(int x, int y, const char *text, int width_offset, int _height, int cycles, s32 start_angle) { unsigned char font_char; unsigned int length = strlen(text); s32 angle_inc = div32(32768/2, length-1)*cycles; s32 _y; while(*text) { font_char = (*(unsigned char*)text++) - 32; _y = sinLerp(start_angle) * _height; glSprite( x,y + (_y >> 12), GL_FLIP_NONE, &font_sprite[font_char] ); x += font_sprite[font_char].width + width_offset; start_angle += angle_inc; } }
void updateTurret(turret_struct* t) { if(!t || !t->used)return; if(!t->OBB || !t->OBB->used){t->OBB=NULL;t->used=false;return;} t->counter+=2;t->counter%=63; //TEMP if(t->dead)t->counter=31; editPalette((u16*)t->OBB->modelInstance.palette,0,RGB15(abs(31-t->counter),0,0)); //TEMP int32* m=t->OBB->transformationMatrix; room_struct* r=getPlayer()->currentRoom; if(!r)return; int32 angle, d; bool b=pointInTurretSight(t, getPlayer()->object->position, &angle, &d); if(b) { vect3D u=vectDifference(getPlayer()->object->position,t->laserOrigin); int32 d=magnitude(u); u=divideVect(u,d); if(collideLineMap(&gameRoom, NULL, t->laserOrigin, u, d, NULL, NULL))b=false; } switch(t->state) { case TURRET_CLOSED: changeAnimation(&t->OBB->modelInstance, 0, false); t->drawShot[0]=t->drawShot[1]=0; if(b && !t->dead){t->state=TURRET_OPENING; playSFX(turretDeploySFX);} break; case TURRET_OPENING: if(t->OBB->modelInstance.currentAnim==2) { t->state=TURRET_OPEN; }else if(t->OBB->modelInstance.currentAnim!=1) { changeAnimation(&t->OBB->modelInstance, 2, false); changeAnimation(&t->OBB->modelInstance, 1, true); } t->drawShot[0]=t->drawShot[1]=0; break; case TURRET_OPEN: { if(angle>mulf32(sinLerp(TURRET_SIGHTANGLE/3),d))changeAnimation(&t->OBB->modelInstance, 4, false); else if(angle<-mulf32(sinLerp(TURRET_SIGHTANGLE/3),d))changeAnimation(&t->OBB->modelInstance, 5, false); else changeAnimation(&t->OBB->modelInstance, 2, false); int i; for(i=0;i<2;i++) { if(!t->drawShot[i] && !(rand()%3)) { t->drawShot[i]=rand()%8; t->shotAngle[i]=rand(); shootPlayer(NULL, normalize(vectDifference(t->laserDestination,t->laserOrigin)), 6); playSFX(turretFireSFX); } if(t->drawShot[i])t->drawShot[i]--; } if(!b || t->dead){t->state=TURRET_CLOSING; playSFX(turretRetractSFX);} } break; case TURRET_CLOSING: if(t->OBB->modelInstance.currentAnim==0) { t->state=TURRET_CLOSED; }else if(t->OBB->modelInstance.currentAnim!=3) { changeAnimation(&t->OBB->modelInstance, 0, false); changeAnimation(&t->OBB->modelInstance, 3, true); } t->drawShot[0]=t->drawShot[1]=0; break; } if(!t->dead) { t->laserOrigin=addVect(vectDivInt(t->OBB->position,4),evalVectMatrix33(m,laserOrigin)); t->laserDestination=addVect(t->laserOrigin,vect(m[2],m[5],m[8])); if(b)t->laserDestination=getPlayer()->object->position; vect3D dir=normalize(vectDifference(t->laserDestination,t->laserOrigin)); t->laserThroughPortal=false; laserProgression(r, &t->laserOrigin, &t->laserDestination, dir); int32 x, y, z; vect3D v; portal_struct* portal=NULL; if(isPointInPortal(&portal1, t->laserDestination, &v, &x, &y, &z))portal=&portal1; if(abs(z)>=32)portal=NULL; if(!portal) { if(isPointInPortal(&portal2, t->laserDestination, &v, &x, &y, &z))portal=&portal2; if(abs(z)>=32)portal=NULL; } if(portal) { t->laserDestination=addVect(t->laserDestination,vectMult(dir,TILESIZE)); t->laserThroughPortal=true; dir=warpVector(portal,dir); t->laserOrigin2=addVect(portal->targetPortal->position, warpVector(portal, vectDifference(t->laserDestination, portal->position))); t->laserDestination2=addVect(t->laserOrigin2,dir); laserProgression(r, &t->laserOrigin2, &t->laserDestination2, dir); t->laserOrigin2=addVect(t->laserOrigin2,vectMult(dir,-TILESIZE)); } if(m[4]<sinLerp(8192/2))t->dead=true; } updateAnimation(&t->OBB->modelInstance); }
void IntroScene::tick() { if(time == 29) { fires[0] = new FireActor(this); fires[0]->x = xCam; fires[0]->vx = camvel; fires[0]->y = -60; fires[0]->colorShift = 0; actors.push_back(fires[0]); } if(time > 30 && time < 40) fires[0]->activated(); if(time < 10) for(int ang = 0; ang < DEGREES_IN_CIRCLE; ang+=DEGREES_IN_CIRCLE / 30) { Particle *p2 = addParticle60(); p2->vx = camvel.tof5()+sinLerp(ang)/30+irand(10); p2->vy = cosLerp(ang)/30+irand(10); p2->x = (xCam+70+time).tof5()-p2->vx*20; p2->y = (yCam).tof5()-p2->vy*20; p2->nTexture = 1; p2->r = 255; p2->g = 120-time*10; p2->b = 20; p2->a = 18; p2->sizePerLife = 7; p2->effect = FX_NOFRICTION; } if(time % 5 == 0) { Particle* star = addParticle1000(); star->sizePerLife = -(1+rand() % 4); if(rand() % 6 == 0) star->sizePerLife -= 7+rand() % 4; star->vx = camvel.tof5()+star->sizePerLife*17-10; star->vy = 0; star->vx2 = 0; star->vy2 = 0; star->x = xCam.tof5()+230*32; // star->x = rand() % (192*32) - (192*32/16); star->y = rand() % (192*32) - (192*32/2); star->nTexture = TEX_DIAMOND; star->effect = FX_NOFRICTION; star->r = 150+rand() % 100; star->g = 150+rand() % 100; star->b = 255; star->a = 10+rand() % 21; } xCam += camvel; if(fires[0]) { int ny = sinLerp(time*100) + sinLerp(time*240) + sinLerp(time*174)/2; if(time < 250) ny = sinLerp(time*440)*2; if(time < 150) ny = sinLerp(time*440)*3; f32 dy = fires[0]->y-(f32(ny) / (1<<7)); fires[0]->vy *= 0.7; fires[0]->vy -= dy/24; } if((texts[0]->touched || inputKeysDown & KEY_A) && canChangeScene()) { texts[0]->explode(); doSceneChange(new LevelSelectScene()); } if((texts[1]->touched) && canChangeScene()) { texts[1]->explode(); doSceneChange(new CreditsScene(false)); } Scene::tick(); }
void updatePlayer(struct PLAYER * player, struct CAMERA * camera) { scanKeys(); int hold = keysHeld(); player->yPos = -500; int vec[3]; vec[0] = (2000 * sinLerp(camera->yRot)) / 4096; vec[1] = 0; vec[2] = (2000 * cosLerp(camera->yRot)) / 4096; if(!(vec[0] == 0 && vec[1] == 0 && vec[2] == 0)) normalizef32(&vec[0]); //printf("%d, %d\n", xCam, zCam); printf("%d, %d\n", vec[0], vec[2]); if (hold & KEY_LEFT) { player->yRot += degreesToAngle(1); player->xPos += vec[0] * 15/ 4096; player->zPos += vec[2] * 15/ 4096; } if (hold & KEY_RIGHT) { player->yRot -= degreesToAngle(1); player->xPos += vec[0] * 15/ 4096; player->zPos += vec[2] * 15/ 4096; } if (hold & KEY_UP) { player->xPos += vec[0] * 20/ 4096; player->zPos += vec[2] * 20/ 4096; //not 100% correct, because when you press up and left together, you will not rotate! if(abs(player->yRot - camera->yRot) < 150) player->yRot = camera->yRot; else { if(camera->yRot > player->yRot) player->yRot += 150; if(camera->yRot < player->yRot) player->yRot -= 150; } //player->yRot = camera->yRot; } if (hold & KEY_DOWN) { player->xPos -= vec[0] * 20/ 4096; player->zPos -= vec[2] * 20/ 4096; if(abs(player->yRot - camera->yRot) < 150) player->yRot = camera->yRot; else { if(camera->yRot > player->yRot) player->yRot += 150; if(camera->yRot < player->yRot) player->yRot -= 150; } /*if(abs(player->yRot - (degreesToAngle(180) - camera->yRot)) < 300) player->yRot = (degreesToAngle(180) - camera->yRot); else { if(camera->yRot > (degreesToAngle(180) - camera->yRot)) player->yRot += 300; if(camera->yRot < (degreesToAngle(180) - camera->yRot)) player->yRot -= 300; }*/ } }
inline int SeaActor::getc(int x, int z) { return ((sinLerp(x*4000+sc->time*100)+sinLerp(x*2555-sc->time*140)+sinLerp(z*2000+sc->time*700))>>7)+100; }
inline int SeaActor::gety(int x, int z) { return (sinLerp(x*5000+sc->time*400)+sinLerp(x*2415-sc->time*300)+sinLerp(z*3000+sc->time*100))/15+ydelta; }
//--------------------------------------------------------------------------------- int main(void) { //--------------------------------------------------------------------------------- SoundEngine* soundengine = new SoundEngine( SAMPLERATE ); SoundSetup( soundengine, SAMPLERATE, BUFSIZE ); int* tempBuf = (int*)malloc(sizeof(int)*soundengine->granulizerBufferSize); int displayBuf[CIRCLEDIVS]; int time = 0; u8 squares = 10; while(1) { // -------------------- // // -- INPUT HANDLING -- // // -------------------- // touchPosition touch; touchRead( &touch ); scanKeys(); u32 down=0, up=0, held=0; down=keysDown(); held=keysHeld(); up=keysUp(); if(down&KEY_UP) squares++; if(down&KEY_DOWN) squares--; if(down&KEY_TOUCH) soundengine->granulizer->SetPlaybackRate(0,1); if(held&KEY_TOUCH) { soundengine->granulizer->SetPlaybackPos(touch.px,SCREEN_WIDTH); soundengine->granulizer->SetGrainSize(touch.py); } if(up&KEY_TOUCH) { soundengine->granulizer->SetPlaybackRate(1,1); soundengine->stop(0); } // -------------- // // -- GRAPHICS -- // // -------------- // for(int i=0; i<soundengine->granulizerBufferSize; i++) { tempBuf[i]=abs(soundengine->granulizerBuffer[i]); } downSampleArray(tempBuf,soundengine->granulizerBufferSize,displayBuf,CIRCLEDIVS); for(int i=0; i<CIRCLEDIVS; i++) { int maxRadius=700; int radius=maxRadius*displayBuf[i]/MAXAMP; int nextRadius=maxRadius*displayBuf[(i+1)%CIRCLEDIVS]/MAXAMP; int angle=DEGREES_IN_CIRCLE*i/CIRCLEDIVS; int nextAngle=DEGREES_IN_CIRCLE*((i+1)%CIRCLEDIVS)/CIRCLEDIVS; int x=sinLerp(angle)*radius/DEGREES_IN_CIRCLE+(SCREEN_WIDTH/2); int y=cosLerp(angle)*radius/DEGREES_IN_CIRCLE+(SCREEN_HEIGHT/2); int nextX=sinLerp(nextAngle)*nextRadius/DEGREES_IN_CIRCLE+(SCREEN_WIDTH/2); int nextY=cosLerp(nextAngle)*nextRadius/DEGREES_IN_CIRCLE+(SCREEN_HEIGHT/2); GraphicsEng::Instance()->DrawLine(x,y,nextX,nextY,RGB15(31,31,31),ALPHA_ON,SUB_LAYER); } for(int i=0; i<GLOBALBUFFERSIZE; i++) { int val = soundengine->globalBuffer[(soundengine->globalBufferCursor+i)%GLOBALBUFFERSIZE]; val = val*(SCREEN_HEIGHT/2)/MAXAMP; GraphicsEng::Instance()->DrawPoint( SCREEN_WIDTH*i/GLOBALBUFFERSIZE, (SCREEN_HEIGHT/2)+val, RGB15(31,31,31), ALPHA_ON, MAIN_LAYER); } GraphicsEng::Instance()->Update(); time++; } }
void renderObject(LevelObj& obj, f32 xx, f32 yy, Scene* sc) { int x = xx.toint(); int y = yy.toint(); const int z = 1000; if(obj.type == BEH_WATER || obj.type == BEH_LAVA || obj.type == BEH_WATERDOWN || obj.type == BEH_LAVADOWN) { bool top = obj.type == BEH_WATER || obj.type == BEH_LAVA; bool lava = obj.type == BEH_LAVADOWN || obj.type == BEH_LAVA; if(top) { setTexture(TEX_VERTGRAD); glPolyFmt(POLY_ALPHA(28) | POLY_ID(WATER_POLYID) | POLY_CULL_NONE); glBegin(GL_QUAD_STRIP); int divnum = 32; f32 dx = obj.x[1]-obj.x[0]; f32 dy = obj.y[1]-obj.y[0]; f32 len = fsqrt(dx*dx+dy*dy); if(len < 90) divnum = 16; if(len < 45) divnum = 8; if(!top) divnum = 1; for(int j = 0; j <= divnum; j++) { int x1 = (obj.x[0]*j+obj.x[1]*(divnum-j))/divnum; int y1 = (obj.y[0]*j+obj.y[1]*(divnum-j))/divnum; int x2 = (obj.x[3]*j+obj.x[2]*(divnum-j))/divnum; int y2 = (obj.y[3]*j+obj.y[2]*(divnum-j))/divnum; f32 dx = x2-x1; f32 dy = y2-y1; f32 len = fsqrt(dx*dx+dy*dy); dx /= len; dy /= len; int in = x1*19+y1*14+sc->time*20; int in2 = x1*24-y1*18-sc->time*12; // int in2 = x1*18-y1*21-sc->time*15; if(top) { int xw = 0; if(!lava) { xw += sinLerp(in*40)/600; xw += sinLerp(in2*23)/600; } else { xw += sinLerp(in*27)/800; xw += sinLerp(in2*13)/300; } dx *= xw; dy *= xw; x1 += dx.toint(); y1 += dy.toint(); if(!lava) glColor3b(130, 180, 255); else glColor3b(255, 180, 30); } GFX_TEX_COORD = TEXTURE_PACK(inttot16(64), inttot16(64)); glVertex3v16((x1-x)*32, (y1-y)*32, z); if(!lava) glColor3b(20, 50, 215); else glColor3b(255, 60, 0); GFX_TEX_COORD = TEXTURE_PACK(inttot16(64), inttot16(0)); glVertex3v16((x2-x)*32, (y2-y)*32, z); } glEnd(); } else { if(!lava) glColor3b(20, 50, 215); else glColor3b(255, 60, 0); setNoTexture(); glPolyFmt(POLY_ALPHA(7) | POLY_ID(WATER_POLYID) | POLY_CULL_NONE); glBegin(GL_QUAD); glVertex3v16((obj.x[0]-x)*32, (obj.y[0]-y)*32, z); glVertex3v16((obj.x[1]-x)*32, (obj.y[1]-y)*32, z); glVertex3v16((obj.x[2]-x)*32, (obj.y[2]-y)*32, z); glVertex3v16((obj.x[3]-x)*32, (obj.y[3]-y)*32, z); glEnd(); } } else { int a = 28; if(obj.type == BEH_WALL) glColor3b(200, 200, 255); else if(obj.type == BEH_BOUNCY) glColor3b(255, 100, 210); else if(obj.type == BEH_PORTAL1) glColor3b(100, 255, 20); else if(obj.type == BEH_PORTAL2) glColor3b(30, 140, 210); if(obj.type == BEH_PORTAL1 && sc->switchesActive[0]) a = 6; if(obj.type == BEH_PORTAL2 && sc->switchesActive[1]) a = 6; if(debugShown) { if(obj.state == 1) glColor3b(0, 200, 0); else if(obj.state == 2) glColor3b(0, 000, 200); } setTexture(TEX_INVBALL); glPolyFmt(POLY_ALPHA(a) | POLY_ID(LEVEL_POLYID) | POLY_CULL_NONE); glBegin(GL_QUAD); GFX_TEX_COORD = TEXTURE_PACK(inttot16(64), inttot16(0)); glVertex3v16((obj.x[0]-x)*32, (obj.y[0]-y)*32, z); GFX_TEX_COORD = TEXTURE_PACK(inttot16(64), inttot16(64)); glVertex3v16((obj.x[1]-x)*32, (obj.y[1]-y)*32, z); GFX_TEX_COORD = TEXTURE_PACK(inttot16(0), inttot16(64)); glVertex3v16((obj.x[2]-x)*32, (obj.y[2]-y)*32, z); GFX_TEX_COORD = TEXTURE_PACK(inttot16(0), inttot16(0)); glVertex3v16((obj.x[3]-x)*32, (obj.y[3]-y)*32, z); glEnd(); } }
void Level::tickBlock(int bx, int by, f32 x, f32 y) { int offs = objs->blocks[bx][by].offs; int count = objs->blocks[bx][by].count; for(int i = 0; i < count; i++) { LevelObj& obj = objs->objs[offs+i]; obj.state = 0; if(obj.type == BEH_WATER || obj.type == BEH_LAVA || obj.type == BEH_WATERDOWN || obj.type == BEH_LAVADOWN) { bool top = obj.type == BEH_WATER || obj.type == BEH_LAVA; bool lava = obj.type == BEH_LAVADOWN || obj.type == BEH_LAVA; if(top) { int j = rand() % 128; int x1 = (obj.x[0]*j+obj.x[1]*(128-j))/128; int y1 = (obj.y[0]*j+obj.y[1]*(128-j))/128; int x2 = (obj.x[3]*j+obj.x[2]*(128-j))/128; int y2 = (obj.y[3]*j+obj.y[2]*(128-j))/128; f32 dx = x1-x2; f32 dy = y1-y2; f32 len = fsqrt(dx*dx+dy*dy); dx /= len; dy /= len; int in = x1*19+y1*14+sc->time*20; int in2 = x1*24-y1*18-sc->time*12; int xw = 0; xw += sinLerp(in*40)/600; xw += sinLerp(in2*23)/600; x1 += (dx*xw).toint(); y1 += (dy*xw).toint(); if(sc->inCam(x1, y1)) { Particle *star = sc->addParticle20(); star->x = x1*32; star->y = y1*32; if(lava) { star->vx = (dx*100).toint() + rand()%100-50; star->vy = (dy*100).toint() + rand()%100-50; star->r = 200+rand() % 50; star->g = 120+rand() % 50; star->b = 50; star->effect = FX_BLUR; } else { int d = (rand()%2)*2-1; star->vx = -(dy*20).toint()*d + rand()%30-15; star->vy = (dx*20).toint()*d + rand()%30-15; star->r = 205+rand() % 50; star->g = 205+rand() % 50; star->b = 255; star->effect = FX_NONE; } star->vx2 = 0; star->vy2 = 0; star->nTexture = 3; star->a = 10+rand() % 21; star->sizePerLife = 12+rand() % 10; } } if(sc->time % 3 != 0) continue; int xMin = obj.x[0]; int xMax = obj.x[0]; int yMin = obj.y[0]; int yMax = obj.y[0]; for(int i = 1; i < 4; i++) { if(obj.x[i] < xMin) xMin = obj.x[i]; if(obj.x[i] > xMax) xMax = obj.x[i]; if(obj.y[i] < yMin) yMin = obj.y[i]; if(obj.y[i] > yMax) yMax = obj.y[i]; } int xs = xMax-xMin; int ys = yMax-yMin; int x = xMin + rand() % xs; int y = yMin + rand() % ys; if(!collisionWith(obj, x, y)) continue; Particle *star = sc->addParticle20(); star->x = x*32; star->y = y*32; star->vx = rand() % 100 -50; star->vy = rand() % 100 -50; if(lava) { star->r = 200+rand() % 50; star->g = 120+rand() % 50; star->b = 50; } else { star->r = 205+rand() % 50; star->g = 205+rand() % 50; star->b = 255; } star->nTexture = 3; star->a = 10+rand() % 21; star->sizePerLife = 4+rand() % 6; star->effect = FX_NONE; } else { } } }
s16 cosLerp(s16 angle) { return sinLerp(angle + LIBNDS_QUARTER_ANGLE); // Cos/sin symmetry }