// --------------------------------------------------------------------------------------------------------------------- bool rotozoom_tick(const FrameInput& input, FrameOutput& output, FXState& state) { output.clear(); return true; }
// --------------------------------------------------------------------------------------------------------------------- bool ripple_tick(const FrameInput& input, FrameOutput& output, FXState& state) { EffectData* data = (EffectData*)state.store; output.clear(); Fix16 divFour = fix16_from_float(0.1470588f); Fix16 edgeMult = fix16_from_float(0.75f); if(state.rng.genUInt32(0, 100) < data->dropFrequency) { data->source[state.rng.genUInt32(1, EffectData::Height-2) * EffectData::Width + state.rng.genUInt32(1, EffectData::Width-2)] = fix16_one; } for(int x = 1; x < EffectData::Width - 1; x++) { for(int y = 1; y < EffectData::Height - 1; y++) { // last last height as proxy for velocity. Fix16 velocity = -data->destination[y * EffectData::Width + x]; // average local neighborhood. // todo taking diagonal neigbors x 0.7 makes stuff rounder. Fix16 smoothed; smoothed = data->source[y * EffectData::Width + x + 1]; // x+1, y smoothed += data->source[y * EffectData::Width + x - 1]; // x-1, y smoothed += data->source[(y + 1) * EffectData::Width + x]; // x, y+1 smoothed += data->source[(y - 1) * EffectData::Width + x]; // x, y-1 smoothed += data->source[(y - 1) * EffectData::Width + (x - 1)] * edgeMult; smoothed += data->source[(y - 1) * EffectData::Width + (x + 1)] * edgeMult; smoothed += data->source[(y + 1) * EffectData::Width + (x - 1)] * edgeMult; smoothed += data->source[(y + 1) * EffectData::Width + (x + 1)] * edgeMult; smoothed *= divFour; // combine avg and velocity Fix16 newHeight = smoothed * fix16_from_float(0.3f) + velocity; // damp it newHeight *= data->damping; // store it... data->destination[y * EffectData::Width + x] = newHeight; // adjustments for drawing... newHeight = (newHeight * fix16_from_float(2.5f)); // are there fix16 clamping functions someplace? if(newHeight < fix16_zero) newHeight = fix16_zero; if(newHeight > fix16_one) newHeight = fix16_one; byte r, g; FullSpectrum(newHeight, r, g); setLED(output.frame, x-1, y-1, r, g, 0); } } Fix16* temp = data->destination; data->destination = data->source; data->source = temp; return true; }
//---------------------------------------------------------------------------------------------------------------------- BOOL CALLBACK basicHostProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { analogIncA = analogIncB = analogIncC = 1024; analogLastA = analogLastB = analogLastC = 1024; SendMessage(GetDlgItem(hWnd,IDC_SPIN1), UDM_SETRANGE, 0L, MAKELONG(2048, 0)); SendMessage(GetDlgItem(hWnd,IDC_SPIN1), UDM_SETPOS, 0L, MAKELONG(1024, 0)); SendMessage(GetDlgItem(hWnd,IDC_SPIN2), UDM_SETRANGE, 0L, MAKELONG(2048, 0)); SendMessage(GetDlgItem(hWnd,IDC_SPIN2), UDM_SETPOS, 0L, MAKELONG(1024, 0)); SendMessage(GetDlgItem(hWnd,IDC_SPIN3), UDM_SETRANGE, 0L, MAKELONG(2048, 0)); SendMessage(GetDlgItem(hWnd,IDC_SPIN3), UDM_SETPOS, 0L, MAKELONG(1024, 0)); createNinjaFrame(GetDlgItem(hWnd,IDC_FRAME1),NULL,NJALIGN_LEFT,FALSE); createNinjaButton(GetDlgItem(hWnd,IDC_EXITODD),NULL,NJALIGN_CENTER,FALSE); setBaseHeavyStyle(GetDlgItem(hWnd,IDC_EXITODD),TRUE); createNinjaButton(GetDlgItem(hWnd,IDC_CLICKER),NULL,NJALIGN_CENTER,FALSE); LEDdisplay = createNinjaLED(GetDlgItem(hWnd,IDC_LED), Constants::FrameWidth); ::SetWindowPos(GetDlgItem(hWnd,IDC_LED), NULL, 0, 0, (14 * Constants::FrameWidth) + 10, (14 * Constants::FrameHeight) + 10, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); SetTimer(hWnd, 0x01, 4, NULL); g_output.clear(); vfx::init(g_state); } break; case WM_HSCROLL: case WM_VSCROLL: { if ((HWND)(lParam) == GetDlgItem(hWnd,IDC_SPIN1)) { analogIncA = HIWORD(wParam); } else if ((HWND)(lParam) == GetDlgItem(hWnd,IDC_SPIN2)) { analogIncB = HIWORD(wParam); } else if ((HWND)(lParam) == GetDlgItem(hWnd,IDC_SPIN3)) { analogIncC = HIWORD(wParam); } } break; case WM_TIMER: { //g_output.clear(); g_state.counter ++; // work out changes from the encoders FrameInput inputs; int alA = analogIncA; int alB = analogIncB; int alC = analogIncC; inputs.dialChange[0] = (alA - analogLastA); inputs.dialChange[1] = (alB - analogLastB); inputs.dialChange[2] = (alC - analogLastC); inputs.dialClick = shouldClick; analogLastA = alA; analogLastB = alB; analogLastC = alC; shouldClick = false; vfx::tick(inputs, g_state, g_output); LEDdisplay->decodeFramebuffer(g_output.frame); InvalidateRect(LEDdisplay->hwHost, 0, FALSE); } break; case WM_NINJA_BUTTON: { switch(lParam) { case IDC_EXITODD: EndDialog(hWnd,0); break; case IDC_CLICKER: shouldClick = true; break; } } break; default: return FALSE; } return TRUE; }
// --------------------------------------------------------------------------------------------------------------------- bool tick(const FrameInput& input, FXState& state, FrameOutput& output) { switch (gCurrentInterfaceStage) { case InterfaceStage::IS_GUI: { output.clear(); if (input.dialChange[1] == 0) ticksSinceAdjust ++; else ticksSinceAdjust = 0; const int16_t radioLen = sizeof(radioGUI) / sizeof(gui_entry); Fix16 max_target = fix16_from_int(radioLen); Fix16 max_value = fix16_from_int(radioLen - 1); Fix16 dial16 = fix16_from_int( input.dialChange[1] ); Fix16 pt05 = fix16_from_float(-1.0f); vTargetA += dial16 * fix16_from_float(0.2f); if (vTargetA < fix16_neg_one) vTargetA = fix16_neg_one; if (vTargetA > max_target) vTargetA = max_target; vCurA += (vTargetA - vCurA) * fix16_from_float(0.035f); if (vCurA < fix16_zero) vCurA = fix16_zero; if (vCurA > max_value) vCurA = max_value; if (ticksSinceAdjust > 30) { vTargetA -= fpart(vTargetA); } int16_t off = ipart(vCurA).asInt(); if (off < 0) off = 0; if (off > radioLen - 1) off = radioLen - 1; const gui_entry* guient[3] = {&radioGUI[off], &radioGUI[off], &radioGUI[off]}; if (off - 1 >= 0) guient[2] = &radioGUI[off - 1]; if (off + 1 <= radioLen - 1) guient[1] = &radioGUI[off + 1]; Fix16 charASlide = fpart(vCurA); charASlide *= Fix16(-16.0f); int16_t slideAInt = charASlide.asInt(); IconGlyph(output.frame, guient[0]->gly, slideAInt, 0, true); IconGlyph(output.frame, guient[1]->gly, 16 + slideAInt, 0, false); if (off > 0) IconGlyph(output.frame, guient[2]->gly, slideAInt - 16, 0, false); if (fadeTick < 15) { fadeTick ++; output.fade(15 - fadeTick); } if (input.dialClick) { gCurrentInterfaceStage = InterfaceStage::IS_FADETO; gNextDisplayMode = guient[0]->mode; } } break; case InterfaceStage::IS_FADETO: { output.fade(1); fadeTick --; if (fadeTick <= 0) { vTargetA = vCurA; gCurrentDisplayMode = gNextDisplayMode; for(int i = 0; i < Constants::MemoryPool; ++i) state.store[i] = 0xFF; DisplayMode::doInitFor(gCurrentDisplayMode, state); fadeTick = 0; gCurrentInterfaceStage = InterfaceStage::IS_FX; } } break; case InterfaceStage::IS_FX: { DisplayMode::doTickFor(gCurrentDisplayMode, input, output, state); if (fadeTick < 15) { fadeTick ++; output.fade(15 - fadeTick); } if (input.dialClick) { gCurrentInterfaceStage = InterfaceStage::IS_FADEFROM; } } break; case InterfaceStage::IS_FADEFROM: { DisplayMode::doTickFor(gCurrentDisplayMode, input, output, state); output.fade(15 - fadeTick); fadeTick --; if (fadeTick <= 0) { gCurrentInterfaceStage = InterfaceStage::IS_GUI; fadeTick = 0; } } break; } // /* dial --; if (dial <= 0) { // clear the frame output.clear(); for (int y=0; y<Constants::FrameHeight; y++) { for (int x=0; x<Constants::FrameWidth; x++) { int32_t RR = state.rng.genInt32(-4, 4); if (RR<0) RR =0; int32_t GG = state.rng.genInt32(-4, 4); if (GG<0) GG =0; setLED(output.frame, x, y, RR, GG); } } dial = 6; } */ /* byte red, green; for (int y=0; y<Constants::FrameHeight; y++) { for (int x=0; x<Constants::FrameWidth; x++) { pixel &LEDpixel = output.frame[y * Constants::FrameWidth + x]; DecodeByte(LEDpixel, red, green); if (red > 0) red --; if (green > 0) green --; LEDpixel = red | (green << 4); } } vTargetA += fix16_from_int( input.dialChange[1] ); vTargetB += fix16_from_int( input.dialChange[2] ); vCurA += (vTargetA - vCurA) * fix16_from_float(0.05f); vCurB += (vTargetB - vCurB) * fix16_from_float(0.05f); Fix16 xo = fix16_from_float(8.0f); Fix16 yo = fix16_from_float(8.0f); Fix16 ss1 = fix16_sin(vCurA * fix16_from_float(0.1f)); Fix16 cc1 = fix16_cos(vCurA * fix16_from_float(0.1f)); Fix16 ss2 = fix16_sin(vCurB * fix16_from_float(0.1f)); Fix16 cc2 = fix16_cos(vCurB * fix16_from_float(0.1f)); Fix16 rad1(-2.0f), rad2(12.0f); draw::WuLine( output.frame, xo + (ss1 * rad1), yo + (cc1 * rad1), xo + (ss1 * rad2), yo + (cc1 * rad2), Red); draw::WuLine( output.frame, xo + (ss2 * rad1), yo + (cc2 * rad1), xo + (ss2 * rad2), yo + (cc2 * rad2), Green); */ return true; }