void sub_80DCF60(struct Sprite *sprite) { StartSpriteAnim(sprite, gBattleAnimArgs[5]); AnimateSprite(sprite); if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) sprite->pos1.x -= gBattleAnimArgs[0]; else sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[0] = gBattleAnimArgs[4]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[3]; InitSpriteDataForLinearTranslation(sprite); sprite->data[3] = 0; sprite->data[4] = 0; sprite->callback = sub_8078394; StoreSpriteCallbackInData(sprite, move_anim_8074EE0); }
void PSBTM(Object* self) { switch(self->routine) { case Routine_Init: self->routine = Routine_PrsStart; self->x = PSB_ScreenX; self->screenY = PSB_ScreenY; self->map = Map_PSB; self->gfx = GFX_PSB; if(self->frame >= Frame_SpriteLineLimiter) { self->routine = Routine_Exit; if(self->frame == Frame_TM) { self->gfx = GFX_TM; self->x = TM_ScreenX; self->screenY = TM_ScreenY; } break; } // fall through case Routine_PrsStart: AnimateSprite(self, Ani_PSBTM); break; case Routine_Exit: break; } DisplaySprite(self); }
void TitleSonic(Object* self) { switch(self->routine) { case Routine_Init: self->routine = Routine_Delay; self->x = TitleSonic_ScreenX; self->screenY = TitleSonic_ScreenY; self->map = Map_TitleSonic; self->gfx = GFX_TitleSonic; self->priority = 1; self->delayAni = 29; AnimateSprite(self, Ani_TitleSonic); // fall through case Routine_Delay: if(TimerNeg(self->delayAni)) { self->routine = Routine_Move; DisplaySprite(self); } break; case Routine_Move: self->obScreenY -= 8; if(self->screenY == (128 + 22)) self->routine = Routine_Animate; DisplaySprite(self); break; case Routine_Animate: AnimateSprite(self, Ani_TitleSonic); DisplaySprite(self); break; } }
void sub_80DCE9C(struct Sprite *sprite) { if (gBattleAnimArgs[3] != 0) SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y); sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += 14; StartSpriteAnim(sprite, gBattleAnimArgs[1]); AnimateSprite(sprite); sprite->data[0] = 0; sprite->data[1] = 0; sprite->data[2] = 4; sprite->data[3] = 16; sprite->data[4] = -70; sprite->data[5] = gBattleAnimArgs[2]; StoreSpriteCallbackInData(sprite, sub_80DCF1C); sprite->callback = sub_8078278; sprite->callback(sprite); }
void Splash(Object* self) { switch(self->routine) { case Routine_Init: self->routine = Routine_Main; self->map = Map_Splash; Obj_SetSomething(self); self->priority = 1; self->obActWid = 16; self->gfx = GFX_Splash; self->x = v_player->x; // fall through case Routine_Main: self->y = v_waterpos1; AnimateSprite(self, Ani_Splash) DisplaySprite(self); break; case Routine_Delete: DeleteObject(self); break; } }
void DrownCount(Object* self) { switch(self->routine) { case Routine_Init: self->routine = Routine_BubbleExpanding; self->map = Map_Bub; self->gfx = GFX_Bubble; Obj_SetVisible(self); Obj_SetBehind(self); self->actWid = 16; self->priority = 1; if(BTST(self->subtype, Subtype_Master)) { self->routine = Routine_Master; self->map = Map_Drown; self->gfx = GFX_Master; VAR_B(self, alwaysOneB) = self->subtype & ~Subtype_Master; goto _masterRoutine; } // Bubble self->anim = self->subtype; VAR_W(self, origXW) = self->x; self->velY = -Bubble_Velocity; // fall through case Routine_BubbleExpanding: AnimateSprite(self, Ani_Drown); // fall through case Routine_BubbleRising: // Still underwater? if(self->y >= vWaterpos1) { // Move bubbles with tunnel current if(fWtunnelmode) VAR_W(self, origXW) += 4; // Wobble self->x = VAR_W(self, origXW) + Bubble_Wobble[self->angle & 0x7F]; self->angle++; // Update appearance CheckNumberBubbleConversion(self); SpeedToPos(self); if(Object_IsVisible(self)) DisplaySprite(self); else DeleteObject(self); break; } else { // Reached surface? For small bubbles, this sets their anim to blank and will go routine 6 > 8 and die // Big bubbles actually glitch out when they reach the surface cause there aren't enough enim mappings! self->routine = Routine_BubbleDying; self->anim += 7; } // fall through case Routine_BubbleDying: case Routine_NumberUpdate: _display: // Update appearance CheckNumberBubbleConversion(self); AnimateSprite(self, Ani_Drown); DisplaySprite(self); break; case Routine_BubbleDead: case Routine_NumberDead: DeleteObject(self); break; // Once a number-bubble gets plastered to the screen, it enters this state which handles switching to the // "flashing number" animation. case Routine_NumberTransition: if(v_air > Drown_Air) { DeleteObject(self); break; } if(TimerZero(VAR_W(self, frameTimerW))) { self->routine = Routine_NumberUpdate; self->anim += 7; goto _display; } AnimateSprite(self, Ani_Drown); if(Object_IsVisible(self)) DisplaySprite(self); else DeleteObject(self); break; // The "master" object, spawned when Sonic goes underwater for the first time, goes into this routine forever. // It manages counting down the air meter, spawning bubbles/numbers, and drowning/killing Sonic. case Routine_Master: _masterRoutine: // If we're not currently drowning... if(VAR_W(self, drowningTimeW) == 0) { // Manage counting down the timer and stuff if(Player_IsDead() || !Player_IsUnderwater()) return; // Count down frames until the next second if(TimerNeg(VAR_W(self, frameTimerW), 59)) { VAR_W(self, bubbleFlagsW) = BubbleFlags_Enable; VAR_B(self, spawnTimerB) = RandomNumber(2); if(ShouldDing()) PlaySound_Special(SFX_Warning); // ding-ding else if(v_air <= Drown_Air) { if(v_air == Drown_Air) PlaySound(BGM_Drowning); // uh oh if(TimerNeg(VAR_B(self, sillyTimerB), VAR_B(self, alwaysOneB))) BSET(VAR_W(self, bubbleFlagsW), BubbleFlags_SpawnNumber); } if(TimerNeg(v_air)) { // Drowning time. ResumeMusic(); f_lockmulti = 0x81; PlaySound_Special(SFX_Drown); VAR_B(self, spawnTimerB) = 10; VAR_W(self, bubbleFlagsW) = BubbleFlags_Enable; VAR_W(self, drowningTimeW) = Drown_Length; Player_ResetOnFloor(v_player); Player_SetAnimDrowning(); Player_SetInAir(); v_player->gfx |= 0x80; v_player->velY = 0; v_player->velX = 0; v_player->inertia = 0; f_nobgscroll = true; return; } goto _makeBubble; } } else { // Manage the drowning animation (Sonic falling offscreen) if(TimerZero(VAR_W(self, drowningTimeW))) { Player_SetDead(); return; } SpeedToPos(v_player); v_player->velY += Drown_Velocity; } // Bubble spawning enabled? if(VAR_W(self, bubbleFlagsW)) { if(TimerNeg(VAR_W(self, bubbleTimerW))) { _makeBubble: VAR_W(self, bubbleTimerW) = RandomNumber(16); if(auto bubble = FindFreeObj()) { auto bubble = &v_objspace[slot]; bubble->id = ID_DrownCount; bubble->x v_player->x + (Player_IsFlipped() ? -Bubble_OffsX : Bubble_OffsX); bubble->y = v_player->y; bubble->angle = Player_IsFlipped() ? Bubble_AngleFlipped : 0; bubble->subtype = Subtype_SmallBubble; // If we're doing drowning-bubbles.. if(VAR_W(self, drowningTimeW) != 0) { VAR_W(self, bubbleTimerW) &= 7; bubble->y = v_player->y - Bubble_DrownOffsY; bubble->angle = RandomNumber(256); // 1/4 bubbles are made bigger if((v_framecount & 3) == 0) bubble->subtype = Subtype_MediumBubble; } else if(ShouldSpawnNumberBubble(self)) { BSET(VAR_W(self, bubbleFlagsW), BubbleFlags_NumberSpawned); bubble->subtype = GetCountdownDigit(); VAR_W(bubble, frameTimerW) = NumberBubble_Timer1; } if(TimerNeg(VAR_B(self, spawnTimerB))) VAR_W(self, bubbleFlagsW) = 0; } } } break; } }
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) // Anyway, so here is our "main()" for windows. Must Have this for a windows app. { // Create the handle to the window. HWND hwnd; // Create the variable to hold the window messages MSG msg; // Create the structure that holds the attributes of the window. // I just crammed them in like this to save space because we know what they do. WNDCLASSEX wndclass = {sizeof (wndclass), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, LoadIcon (NULL, IDI_WINLOGO), LoadCursor (NULL, IDC_ARROW), (HBRUSH) GetStockObject (WHITE_BRUSH), NULL, "Window Class", LoadIcon (NULL, IDI_WINLOGO)}; // Register the window class with the operating system RegisterClassEx (&wndclass); // Now, we actually create the window hwnd = CreateWindow ("Window Class", // window class name "Animation", // window's Title WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position WIDTH, // Here we pass in our desired width (800) HEIGHT, // Here we pass in our desired height (600) NULL, // This is the parent window handle. NULL, // This is the window menu handle hInstance, // This is the programs instance handle. NULL); // We don't want to pass any extra data in, so NULL // This shows our window. ShowWindow (hwnd, iCmdShow); // This pretty much paints our window to the screen. UpdateWindow (hwnd); // Here is our main loop. while (1) { // *We use PeekMessage() instead of GetMessage() to see if there is a message // from windows, if not, then we want to animate when nothing is going on.* // Check if there is a window message and remove it from the queue if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // If the message was to quit, break out of the while loop if(msg.message == WM_QUIT) break; // This Translates messages so windows understands them. TranslateMessage (&msg); // This sends the messages to the WndProc(). DispatchMessage (&msg); } else { // *Now we do the computationally expensive stuff in this else* // Check if we want to animate the next frame of animation if(AnimateNextFrame(FRAME_RATE)) { // Animate the first water sprite AnimateSprite(&gBuffer, &gSprite); // Animate the second water sprite AnimateSprite(&gBuffer, &gSprite2); // Now swap the backbuffer to display it to the front and clear the screen SwapBackBuffer(&gBuffer, TRUE); } } } // Unregister the window class with the operating system UnregisterClass("Window Class",hInstance); // Quit the program return msg.wParam ; }