extern "C" __declspec(dllexport) HRESULT __stdcall V2Link(iTVPFunctionExporter *exporter) { // スタブの初期化(必ず記述する) TVPInitImportStub(exporter); // 初期化 prevTime = TVPGetTickCount(); TVPAddContinuousEventHook(&limit); { // TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // Layer クラスオブジェクトを取得 tTJSVariant varScripts; TVPExecuteExpression(TJS_W("System"), &varScripts); iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef(); if (dispatch) { tTJSDispatch *method = new tFpsLimitProp(); tTJSVariant var(method); dispatch->PropSet(TJS_MEMBERENSURE, FPSLIMITNAME, NULL, &var, dispatch); method->Release(); } global->Release(); } GlobalRefCountAtInit = TVPPluginGlobalRefCount; return S_OK; }
//--------------------------------------------------------------------------- extern "C" HRESULT _stdcall _export V2Unlink() { // 吉里吉里側から、プラグインを解放しようとするときに呼ばれる関数。 // もし何らかの条件でプラグインを解放できない場合は // この時点で E_FAIL を返すようにする。 // ここでは、TVPPluginGlobalRefCount が GlobalRefCountAtInit よりも // 大きくなっていれば失敗ということにする。 TVPAddLog(TVPPluginGlobalRefCount); if(TVPPluginGlobalRefCount > GlobalRefCountAtInit) return E_FAIL; // E_FAIL が帰ると、Plugins.unlink メソッドは偽を返す // TJS のグローバルオブジェクトに登録した drawFFTGraph 関数を削除する // - まず、TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // - global の DeleteMember メソッドを用い、オブジェクトを削除する if(global) { // TJS 自体が既に解放されていたときなどは // global は NULL になり得るので global が NULL でない // ことをチェックする global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("drawFFTGraph"), // メンバ名 NULL, // ヒント global // コンテキスト ); // 登録した関数が複数ある場合は これを繰り返す } // - global を Release する if(global) global->Release(); // スタブの使用終了(必ず記述する) TVPUninitImportStub(); // その他の処理 if(SampleBuffer) delete [] SampleBuffer, SampleBuffer = NULL; if(FFTData) delete [] FFTData, FFTData = NULL; if(WindowData) delete [] WindowData, WindowData = NULL; if(fft_ip) delete [] fft_ip, fft_ip = NULL; if(fft_w) delete[] fft_w, fft_w = NULL; if(BandData) delete [] BandData, BandData = NULL; if(BandPeakData) delete [] BandPeakData, BandPeakData = NULL; if(BandPeakCount) delete [] BandPeakCount, BandPeakCount = NULL; if(BandStart) delete [] BandStart, BandStart = NULL; if(BandEnd) delete [] BandEnd, BandEnd = NULL; return S_OK; }
extern "C" HRESULT _stdcall _export V2Link(iTVPFunctionExporter *exporter) { // スタブの初期化(必ず記述する) TVPInitImportStub(exporter); // TestFunction の作成と登録 tTJSVariant val; // TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // 1 まずオブジェクトを作成 DrawFFTGraphFunction = new tDrawFFTGraphFunction(); // 2 DrawFFTGraphFunction を tTJSVariant 型に変換 val = tTJSVariant(DrawFFTGraphFunction); // 3 すでに val が DrawFFTGraphFunction を保持しているので、 // DrawFFTGraphFunction は Release する DrawFFTGraphFunction->Release(); // 4 global の PropSet メソッドを用い、オブジェクトを登録する global->PropSet( TJS_MEMBERENSURE, // メンバがなかった場合には作成するようにするフラグ TJS_W("drawFFTGraph"), // メンバ名 ( かならず TJS_W( ) で囲む ) NULL, // ヒント ( 本来はメンバ名のハッシュ値だが、NULL でもよい ) &val, // 登録する値 global // コンテキスト ( global でよい ) ); // - global を Release する global->Release(); // val をクリアする。 // これは必ず行う。そうしないと val が保持しているオブジェクト // が Release されず、次に使う TVPPluginGlobalRefCount が正確にならない。 val.Clear(); // この時点での TVPPluginGlobalRefCount の値を GlobalRefCountAtInit = TVPPluginGlobalRefCount; TVPAddLog(TVPPluginGlobalRefCount); // として控えておく。TVPPluginGlobalRefCount はこのプラグイン内で // 管理されている tTJSDispatch 派生オブジェクトの参照カウンタの総計で、 // 解放時にはこれと同じか、これよりも少なくなってないとならない。 // そうなってなければ、どこか別のところで関数などが参照されていて、 // プラグインは解放できないと言うことになる。 return S_OK; }
//--------------------------------------------------------------------------- extern "C" HRESULT _stdcall _export V2Unlink() { // 吉里吉里側から、プラグインを解放しようとするときに呼ばれる関数。 // もし何らかの条件でプラグインを解放できない場合は // この時点で E_FAIL を返すようにする。 // ここでは、TVPPluginGlobalRefCount が GlobalRefCountAtInit よりも // 大きくなっていれば失敗ということにする。 if(TVPPluginGlobalRefCount > GlobalRefCountAtInit) return E_FAIL; // E_FAIL が帰ると、Plugins.unlink メソッドは偽を返す // TJS のグローバルオブジェクトに登録した関数を削除する // - まず、TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); // - global の DeleteMember メソッドを用い、オブジェクトを削除する if(global) { // TJS 自体が既に解放されていたときなどは // global は NULL になり得るので global が NULL でない // ことをチェックする global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("wmrStart"), // メンバ名 NULL, // ヒント global // コンテキスト ); global->DeleteMember( 0, // フラグ ( 0 でよい ) TJS_W("wmrStop"), // メンバ名 NULL, // ヒント global // コンテキスト ); // 登録した関数が複数ある場合は これを繰り返す } // - global を Release する if(global) global->Release(); // スタブの使用終了(必ず記述する) TVPUninitImportStub(); return S_OK; }
///---------------------------------------------------------------------- /// BGを描画する void timeline_draw_bg(tTJSVariant item, tTJSVariant view, tjs_int y, tjs_int fromTime, tjs_int toTime) { ncbPropAccessor itemObj(item); ncbPropAccessor viewObj(view); ncbPropAccessor rootObj(itemObj.GetValue(L"root", ncbTypedefs::Tag<tTJSVariant>(), 0, &rootHint)); ncbPropAccessor ownerObj(rootObj.GetValue(L"owner", ncbTypedefs::Tag<tTJSVariant>(), 0, &ownerHint)); tjs_int fps = ownerObj.GetValue(L"framePerSecond", ncbTypedefs::Tag<tjs_int>(), 0 ,&framePerSecondHint); iTJSDispatch2 *global = TVPGetScriptDispatch(); ncbPropAccessor globalObj(global); global->Release(); tjs_int TIMELINE_FRAME_WIDTH = itemObj.GetValue(L"TIMELINE_FRAME_WIDTH", ncbTypedefs::Tag<tjs_int>(), 0, &timeLineFrameWidthHint); tjs_int TIMELINE_FRAME_HEIGHT = globalObj.GetValue(L"TIMELINE_FRAME_HEIGHT", ncbTypedefs::Tag<tjs_int>(), 0, &timelineFrameHeightHint); tTJSVariant oneSecondFrameBgLayer, halfSecondFrameBgLayer, fifthFrameBgLayer, normalFrameBgLayer; // バックグラウンドを描画 for (tjs_int time = fromTime; time < toTime; time ++) { tjs_int x = time * TIMELINE_FRAME_WIDTH; tTJSVariant layer; if (time % fps == 0) { if (oneSecondFrameBgLayer.Type() == tvtVoid) oneSecondFrameBgLayer = viewObj.GetValue(L"oneSecondFrameBgLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &oneSecondFrameBgLayerHint); layer = oneSecondFrameBgLayer; } else if (time % fps * 2 == fps) { if (halfSecondFrameBgLayer.Type() == tvtVoid) halfSecondFrameBgLayer = viewObj.GetValue(L"halfSecondFrameBgLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &halfSecondFrameBgLayerHint); layer = halfSecondFrameBgLayer; } else if (time % 5 == 0) { if (fifthFrameBgLayer.Type() == tvtVoid) fifthFrameBgLayer = viewObj.GetValue(L"fifthFrameBgLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &fifthFrameBgLayerHint); layer = fifthFrameBgLayer; } else { if (normalFrameBgLayer.Type() == tvtVoid) normalFrameBgLayer = viewObj.GetValue(L"normalFrameBgLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &normalFrameBgLayerHint); layer = normalFrameBgLayer; } viewObj.FuncCall(0, L"copyRect", ©RectHint, NULL, x, y, layer, 0, 0, TIMELINE_FRAME_WIDTH, TIMELINE_FRAME_HEIGHT); } }
//--------------------------------------------------------------------------- extern "C" __declspec(dllexport) HRESULT __stdcall V2Unlink() { if(TVPPluginGlobalRefCount > GlobalRefCountAtInit) return E_FAIL; // - まず、TJS のグローバルオブジェクトを取得する iTJSDispatch2 * global = TVPGetScriptDispatch(); if (global) { tTJSVariant varScripts; TVPExecuteExpression(TJS_W("System"), &varScripts); iTJSDispatch2 *dispatch = varScripts.AsObjectNoAddRef(); if (dispatch) { dispatch->DeleteMember(0, FPSLIMITNAME, NULL, dispatch); } global->Release(); } TVPRemoveContinuousEventHook(&limit); TVPUninitImportStub(); return S_OK; }
///---------------------------------------------------------------------- // タイムラインを描画する void timeline_draw_timeline(tTJSVariant item, tTJSVariant view, tjs_int fromTime, tjs_int toTime) { ncbPropAccessor itemObj(item); ncbPropAccessor viewObj(view); tTJSVariant layer = itemObj.GetValue(L"layer", ncbTypedefs::Tag<tTJSVariant>(), 0, &layerHint); ncbPropAccessor layerObj(layer); iTJSDispatch2 *global = TVPGetScriptDispatch(); ncbPropAccessor globalObj(global); global->Release(); tjs_int y = layerObj.GetValue(L"top", ncbTypedefs::Tag<tjs_int>(), 0, &topHint); tTJSVariant frameList = itemObj.GetValue(L"frameList", ncbTypedefs::Tag<tTJSVariant>(), 0, &frameListHint); ncbPropAccessor frameListObj(frameList); tjs_int frameListCount = frameListObj.GetArrayCount(); // 描画範囲を確定 tjs_int fromFrame = timeline_find_frame(frameList, fromTime, true); tjs_int toFrame = timeline_find_frame(frameList, toTime, true); // バックグラウンドを描画 if (fromFrame < 0 && toFrame < 0) { timeline_draw_bg(item, view, y, fromTime, toTime); } else { if (fromFrame < 0) timeline_draw_bg(item, view, y, fromTime, ncbPropAccessor(frameListObj.GetValue(0, ncbTypedefs::Tag<tTJSVariant>())).GetValue(L"time", ncbTypedefs::Tag<tjs_int>(), 0, &timeHint)); if (toFrame == frameListCount - 1) timeline_draw_bg(item, view, y, ncbPropAccessor(frameListObj.GetValue(-1, ncbTypedefs::Tag<tTJSVariant>())).GetValue(L"time", ncbTypedefs::Tag<tjs_int>(), 0, &timeHint), toTime); } // フレームを描画 for (tjs_int i = fromFrame; i <= toFrame; i++) { if (i == -1) continue; tTJSVariant frame = frameListObj.GetValue(i, ncbTypedefs::Tag<tTJSVariant>()); ncbPropAccessor frameObj(frame); tjs_int headTime, tailTime; headTime = frameObj.GetValue(L"time", ncbTypedefs::Tag<tjs_int>(), 0, &timeHint); if (i < frameListCount - 1) { tTJSVariant nextFrame = frameListObj.GetValue(i + 1, ncbTypedefs::Tag<tTJSVariant>()); ncbPropAccessor nextFrameObj(nextFrame); tailTime = nextFrameObj.GetValue(L"time", ncbTypedefs::Tag<tjs_int>(), 0, &timeHint); } else tailTime = headTime; if (! (tailTime < fromTime || headTime > toTime)) { itemObj.FuncCall(0, L"drawFrame", &drawFrameHint, NULL, view, y, frame, tailTime - headTime); } } // 選択範囲描画 tTJSVariant selection = itemObj.GetValue(L"selection", ncbTypedefs::Tag<tTJSVariant>(), 0, &selectionHint); if (selection.Type() != tvtVoid) { tjs_int TIMELINE_FRAME_WIDTH = itemObj.GetValue(L"TIMELINE_FRAME_WIDTH", ncbTypedefs::Tag<tjs_int>(), 0, &timeLineFrameWidthHint); tjs_int TIMELINE_FRAME_HEIGHT = globalObj.GetValue(L"TIMELINE_FRAME_HEIGHT", ncbTypedefs::Tag<tjs_int>(), 0, &timelineFrameHeightHint); ncbPropAccessor selectionObj(selection); viewObj.FuncCall(0, L"colorRect", &colorRectHint, NULL, selectionObj.getIntValue(0) * TIMELINE_FRAME_WIDTH, y, (selectionObj.getIntValue(1) - selectionObj.getIntValue(0)) * TIMELINE_FRAME_WIDTH, TIMELINE_FRAME_HEIGHT, selectionObj.getIntValue(2) ? 0xFF0000 : 0, 128); } }
///---------------------------------------------------------------------- /// フレームを描画する void timeline_draw_frame(tTJSVariant item, tTJSVariant view, tjs_int y, tTJSVariant frame, tjs_int length, tjs_uint markerMask) { ncbPropAccessor itemObj(item); ncbPropAccessor viewObj(view); ncbPropAccessor frameObj(frame); iTJSDispatch2 *global = TVPGetScriptDispatch(); ncbPropAccessor globalObj(global); global->Release(); tjs_int WIN_DARKEN2 = globalObj.GetValue(L"WIN_DARKEN2", ncbTypedefs::Tag<tjs_uint>(), 0, &winDarken2Hint); tjs_int TIMELINE_FRAME_WIDTH = itemObj.GetValue(L"TIMELINE_FRAME_WIDTH", ncbTypedefs::Tag<tjs_int>(), 0, &timeLineFrameWidthHint); tjs_int TIMELINE_FRAME_HEIGHT = globalObj.GetValue(L"TIMELINE_FRAME_HEIGHT", ncbTypedefs::Tag<tjs_int>(), 0, &timelineFrameHeightHint); tjs_int frameType = frameObj.GetValue(L"type", ncbTypedefs::Tag<tjs_int>(), 0, &typeHint); tjs_int frameTime = frameObj.GetValue(L"time", ncbTypedefs::Tag<tjs_int>(), 0, &timeHint); switch (frameType) { case TIMELINE_FRAME_TYPE_NULL: timeline_draw_bg(item, view, y, frameTime, frameTime + length); return; case TIMELINE_FRAME_TYPE_SINGLE: { timeline_draw_bg(item, view, y, frameTime + 1, frameTime + length); tjs_int singleFrameLeftColor = itemObj.GetValue(L"_singleFrameLeftColor", ncbTypedefs::Tag<tjs_int>(), 0, &_singleFrameLeftColorHint); tjs_int singleFrameRightColor = itemObj.GetValue(L"_singleFrameRightColor", ncbTypedefs::Tag<tjs_int>(), 0, &_singleFrameRightColorHint); singleFrameLeftColor |= 0xFF000000; singleFrameRightColor |= 0xFF000000; viewObj.FuncCall(0, L"fillGradientRectLR", &fillGradientRectLRHint, NULL, frameTime * TIMELINE_FRAME_WIDTH, y, TIMELINE_FRAME_WIDTH - 1, TIMELINE_FRAME_HEIGHT - 1, singleFrameLeftColor, singleFrameRightColor); return; } case TIMELINE_FRAME_TYPE_CONTINUOUS: case TIMELINE_FRAME_TYPE_TWEEN: { tjs_int leftColor, rightColor; if (frameType == TIMELINE_FRAME_TYPE_CONTINUOUS) { leftColor = itemObj.GetValue(L"_continuousFrameLeftColor", ncbTypedefs::Tag<tjs_int>(), 0, &_continuousFrameLeftColorHint); rightColor = itemObj.GetValue(L"_continuousFrameRightColor", ncbTypedefs::Tag<tjs_int>(), 0, &_continuousFrameRightColorHint); } else { leftColor = itemObj.GetValue(L"_tweenFrameLeftColor", ncbTypedefs::Tag<tjs_int>(), 0, &_tweenFrameLeftColorHint); rightColor = itemObj.GetValue(L"_tweenFrameRightColor", ncbTypedefs::Tag<tjs_int>(), 0, &_tweenFrameRightColorHint); } leftColor |= 0xFF000000; rightColor |= 0xFF000000; // BG描画 viewObj.FuncCall(0, L"fillRect", &fillRectHint, NULL, (frameTime + length) * TIMELINE_FRAME_WIDTH - 1, y, 1, TIMELINE_FRAME_HEIGHT, WIN_DARKEN2); viewObj.FuncCall(0, L"fillRect", &fillRectHint, NULL, frameTime * TIMELINE_FRAME_WIDTH, y + TIMELINE_FRAME_HEIGHT - 1, length * TIMELINE_FRAME_WIDTH, 1, WIN_DARKEN2); viewObj.FuncCall(0, L"fillGradientRectLR", &fillGradientRectLRHint, NULL, frameTime * TIMELINE_FRAME_WIDTH, y, length * TIMELINE_FRAME_WIDTH - 1, TIMELINE_FRAME_HEIGHT - 1, leftColor, rightColor); bool leftMarker = (markerMask & TIMELINE_MARKER_MASK_LEFT) != 0; bool rightMarker = (markerMask & TIMELINE_MARKER_MASK_RIGHT) != 0; if (rightMarker && leftMarker && length == 1) rightMarker = false; // 左マーカー描画 if (leftMarker) { tTJSVariant frameLeftMarkerLayer = viewObj.GetValue(L"frameLeftMarkerLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &frameLeftMarkerLayerHint); ncbPropAccessor frameLeftMarkerLayerObj(frameLeftMarkerLayer); tjs_int mw = frameLeftMarkerLayerObj.GetValue(L"width", ncbTypedefs::Tag<tjs_int>(), 0, &widthHint); tjs_int mh = frameLeftMarkerLayerObj.GetValue(L"height", ncbTypedefs::Tag<tjs_int>(), 0, &heightHint); viewObj.FuncCall(0, L"operateRect", &operateRectHint, NULL, frameTime * TIMELINE_FRAME_WIDTH, y, frameLeftMarkerLayer, 0, 0, mw, mh); } // 右マーカー描画 if (rightMarker) { tTJSVariant frameRightMarkerLayer = viewObj.GetValue(L"frameRightMarkerLayer", ncbTypedefs::Tag<tTJSVariant>(), 0, &frameRightMarkerLayerHint); ncbPropAccessor frameRightMarkerLayerObj(frameRightMarkerLayer); tjs_int mw = frameRightMarkerLayerObj.GetValue(L"width", ncbTypedefs::Tag<tjs_int>(), 0, &widthHint); tjs_int mh = frameRightMarkerLayerObj.GetValue(L"height", ncbTypedefs::Tag<tjs_int>(), 0, &heightHint); viewObj.FuncCall(0, L"operateRect", &operateRectHint, NULL, (frameTime + length) * TIMELINE_FRAME_WIDTH - mw, y, frameRightMarkerLayer, 0, 0, mw, mh); } // トゥイーンの破線描画 tjs_int fromTime = frameTime + (leftMarker ? 1 : 0), toTime = frameTime + length - (rightMarker ? 1 : 0); if (frameType == TIMELINE_FRAME_TYPE_TWEEN) { tTJSVariant dashLineApp = viewObj.GetValue(L"dashLineApp", ncbTypedefs::Tag<tTJSVariant>(), 0, &dashLineAppHint); if (dashLineApp.Type() != tvtVoid) { viewObj.FuncCall(0, L"drawLine", &drawLineHint, NULL, dashLineApp, fromTime * TIMELINE_FRAME_WIDTH, y + TIMELINE_FRAME_HEIGHT / 2 - 1, toTime * TIMELINE_FRAME_WIDTH, y + TIMELINE_FRAME_HEIGHT / 2 - 1); } else { for (tjs_int i = fromTime; i < toTime; i++) { viewObj.FuncCall(0, L"fillRect", &fillRectHint, NULL, i * TIMELINE_FRAME_WIDTH, y + TIMELINE_FRAME_HEIGHT / 2 - 1, TIMELINE_FRAME_WIDTH / 2 - 2, 1, WIN_DARKEN2); viewObj.FuncCall(0, L"fillRect", &fillRectHint, NULL, i * TIMELINE_FRAME_WIDTH + TIMELINE_FRAME_WIDTH / 2, y + TIMELINE_FRAME_HEIGHT / 2 - 1, TIMELINE_FRAME_WIDTH / 2 - 2, 1, WIN_DARKEN2); } } } // フレーム数描画 if (length > 2) { tTJSVariant canvas = viewObj.GetValue(L"canvas", ncbTypedefs::Tag<tTJSVariant>(), 0, &canvasHint); ncbPropAccessor canvasObj(canvas); tjs_int fontHeight = TIMELINE_FRAME_HEIGHT - 4; canvasObj.SetValue(L"fontHeight", fontHeight, 0, &fontHeightHint); ttstr text(length); tTJSVariant textWidth; tTJSVariant font = canvasObj.GetValue(L"font", ncbTypedefs::Tag<tTJSVariant>(), 0, &fontHint); ncbPropAccessor fontObj(font); fontObj.FuncCall(0, L"getTextWidth", &getTextWidthHint, &textWidth, text); tjs_int l = frameTime * TIMELINE_FRAME_WIDTH + ((length * TIMELINE_FRAME_WIDTH) - tjs_int(textWidth)) / 2; tjs_int t = y + int((TIMELINE_FRAME_HEIGHT - fontHeight) / 2) - 1; viewObj.FuncCall(0, L"setClip", &setClipHint, NULL, l - 1, t - 1, tjs_int(textWidth) + 2, fontHeight + 2); viewObj.FuncCall(0, L"fillGradientRectLR", &fillGradientRectLRHint, NULL, frameTime * TIMELINE_FRAME_WIDTH, y, length * TIMELINE_FRAME_WIDTH - 1, TIMELINE_FRAME_HEIGHT - 1, leftColor, rightColor); viewObj.FuncCall(0, L"setClip", &setClipHint, NULL); viewObj.FuncCall(0, L"drawText", &drawTextHint, NULL, l, t, text, tjs_int(WIN_DARKEN2 & 0xFFFFFF)); } return; } } }