|
01-13-2010, 10:41 AM
|
#1
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
My first IPlug: Combo Model V
Hi all,
I have just released a sneak preview of my first real IPlug project. It is a transistor organ simulation called Combo Model V. Although it has only a very basic GUI (for now anyway), it does feature stepped sliders ( drawbars) and a keyboard:
My project is not open source (sorry!), but if anyone is interested I am willing to share the IPlug related stuff; just ask.
If you want to give the VSTi a try you can download the DLL from my company's website:
http://www.martinic.com/combov/
Last edited by Tale; 04-28-2010 at 03:22 PM.
Reason: Fixed broken image
|
|
|
01-16-2010, 01:23 AM
|
#2
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Quote:
Originally Posted by Tale
My project is not open source (sorry!), but if anyone is interested I am willing to share the IPlug related stuff; just ask.
|
What did you add? I'm always interested in IPlug related stuff!
|
|
|
01-18-2010, 02:13 AM
|
#3
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
IDrawbarControl
Here's my organ drawbar control. It's a reversed vertical fader with 9 discrete steps (0..8). You can drag its handle/tip to move the drawbar, or you can click on the numbers (usually) displayed on the drawbar itself.
Code:
// Handles the GUI control for the drawbars. The value for len is the height
// of the drawbar, *not* including the tip/handle.
class IDrawbarControl: public IControl
{
public:
IDrawbarControl(IPlugBase* pPlug, int x, int y, int len, int paramIdx, IBitmap* pBitmap): IControl(pPlug, &IRECT(x, y, x + pBitmap->W, y + pBitmap->H), paramIdx),
mLen(len), mBitmap(*pBitmap) {}
~IDrawbarControl() {}
void OnMouseDown(int x, int y, IMouseMod* pMod)
{
if (pMod->R)
{
PromptUserInput();
return;
}
y -= mRECT.T;
if (y < int(mValue * (double)mLen))
{
mValue = mValue - floor((double)y / (double)mLen / 0.125) * 0.125;
SetDirty();
}
}
void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod)
{
mValue += (double)dY / (double)mLen;
SetDirty();
}
bool Draw(IGraphics* pGraphics)
{
return pGraphics->DrawBitmap(&mBitmap, &mRECT, 0, int((1. - floor(mValue / 0.125 + 0.5) * 0.125) * (double)mLen), &mBlend);
}
protected:
int mLen;
IBitmap mBitmap;
};
You should feed this control a single bitmap which contains the drawbar including the handle. You'll need to specify the length (height) of the drawbar (without the handle) when you attach it to the plug's GUI:
Code:
MyPlug::MyPlug(IPlugInstanceInfo instanceInfo): IPLUG_CTOR(kNumParams, 0, instanceInfo)
{
...
int width = 500, height = 426;
IGraphics* pGraphics = MakeGraphics(this, width, height);
// Add drawbar control
IBitmap bitmap = pGraphics->LoadIBitmap(DRAWBAR_ID, DRAWBAR_FN);
int x = 48, y = 86;
int len = 62;
pGraphics->AttachControl(new IDrawbarControl(this, x, y, len, kMyDrawbar, &bitmap));
AttachGraphics(pGraphics);
...
}
I will also post my keyboard control, but not right now as I really need to get some work done.
|
|
|
01-19-2010, 01:12 AM
|
#4
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Cool, I don't think I'll be using the drawbar any time soon, but a keyboard would be useful...
|
|
|
01-19-2010, 01:49 AM
|
#5
|
Human being with feelings
Join Date: Nov 2006
Location: Belgium
Posts: 1,462
|
cool plug-in.
I hit the random key and i got instant B-52's :-D
Yves
|
|
|
01-19-2010, 03:28 AM
|
#6
|
Human being with feelings
Join Date: Nov 2008
Location: Darmstadt, Germany
Posts: 673
|
Awesome! Thank you very much for that control, I just started writing my first synth (only fx before... and mostly dynamics processing) which is... a drawbar organ!
|
|
|
01-19-2010, 10:45 AM
|
#7
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
IKeyboardControl
Thanks!
--
Here's my keyboard control:
Code:
#define MIN_MIDI_NOTE 48 // C3
#define MAX_MIDI_NOTE 96 // C7
#define NUM_MIDI_NOTES (MAX_MIDI_NOTE - MIN_MIDI_NOTE + 1)
class IKeyboardControl: public IControl
{
public:
IKeyboardControl(IPlugBase* pPlug, IRECT* pR, IBitmap* pWhiteKey, IBitmap* pBlackKey): IControl(pPlug, pR, -1),
mWhiteKey(*pWhiteKey), mBlackKey(*pBlackKey), mOctaveWidth(mWhiteKey.W * 7), mBlackKeyOffset(mBlackKey.W / 2), mNumOctaves(mRECT.W() / mOctaveWidth), mKey(-1) {}
~IKeyboardControl() {}
void OnMouseDown(int x, int y, IMouseMod* pMod)
{
if (!pMod->L) return;
// Skip if this key is already being played using the mouse.
int key = GetMouseNote(x, y);
if (key == mKey) return;
// Send a Note Off for the previous key (if any).
if (mKey != -1) SendNoteOff();
// Send a Note On for the new key.
mKey = key;
if (mKey != -1) SendNoteOn();
// Update the keyboard in the GUI.
SetDirty();
}
void OnMouseUp(int x, int y, IMouseMod* pMod)
{
// Skip if no key is playing.
if (mKey == -1) return;
// Send a Note Off.
SendNoteOff();
mKey = -1;
// Update the keyboard in the GUI.
SetDirty();
}
void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod) { OnMouseDown(x, y, pMod); }
// Draws only the keys that are currently playing.
bool Draw(IGraphics* pGraphics)
{
// Skip if no keys are playing.
// if (((MyPlug*)mPlug)->HowManyKeys() == 0) return true;
// White keys
IRECT r(mRECT.L, mRECT.T, mRECT.L + mWhiteKey.W, mRECT.T + mWhiteKey.H);
int note = 0;
while (note < NUM_MIDI_NOTES)
{
// Draw the key.
if (((MyPlug*)mPlug)->GetKeyStatus(note)) pGraphics->DrawBitmap(&mWhiteKey, &r, 0, &mBlend);
// Next, please!
int n = note % 12;
if (n == 4 || n == 11) // E or B
++note;
else
note += 2;
r.L += mWhiteKey.W;
r.R += mWhiteKey.W;
}
// Black keys
r.L = mRECT.L + mWhiteKey.W - mBlackKeyOffset;
if (mBlackKey.W % 2) --r.L;
r.R = r.L + mBlackKey.W;
r.B = mRECT.T + mBlackKey.H;
note = 1;
while (note < NUM_MIDI_NOTES)
{
// Draw the key.
if (((MyPlug*)mPlug)->GetKeyStatus(note)) pGraphics->DrawBitmap(&mBlackKey, &r, 0, &mBlend);
// Next, please!
int n = note % 12;
if (n == 3 || n == 10) // Eb or Bb
{
note += 3;
r.L += 2 * mWhiteKey.W;
r.R += 2 * mWhiteKey.W;
}
else
{
note += 2;
r.L += mWhiteKey.W;
r.R += mWhiteKey.W;
}
}
return true;
}
protected:
// Returns the note (key) number at the (x, y) coordinates.
int GetMouseNote(int x, int y)
{
// Skip if the coordinates are outside the keyboard's rectangle.
if (x < mTargetRECT.L || x >= mTargetRECT.R || y < mTargetRECT.T || y >= mTargetRECT.B) return -1;
x -= mTargetRECT.L;
y -= mTargetRECT.T;
// Calculate the octave.
int octave = x / mOctaveWidth;
x -= octave * mOctaveWidth;
// Is it a black key?
int note = -1;
int h = mBlackKey.H;
if (y < h && octave < mNumOctaves)
{
int n = (x - mBlackKeyOffset) / mWhiteKey.W;
if (n >= 0 && n < 2) // C#..D#
{
int offset = (n + 1) * mWhiteKey.W - mBlackKeyOffset;
if (x >= offset && x < offset + mBlackKey.W) note = n * 2 + 1;
}
else if (n >= 3 && n < 6) // F#..A#
{
int offset = (n + 1) * mWhiteKey.W - mBlackKeyOffset;
if (x >= offset && x < offset + mBlackKey.W) note = n * 2;
}
}
// If it's not a black key...
if (note == -1)
{
// ... then it must be a white key.
int n = x / mWhiteKey.W;
if (n < 3) // C..E
note = n * 2;
else // F..B
note = n * 2 - 1;
h = mWhiteKey.H;
}
// Calculate the velocity depeding on the vertical coordinate
// relative to the key height.
mVelocity = 1 + int((double)y / (double)h * 126. + 0.5);
return note + octave * 12;
}
// Sends a Note On/Off MIDI message to the plug-in.
void SendNoteOn() { mPlug->ProcessMidiMsg(&IMidiMsg(0, IMidiMsg::kNoteOn << 4, MIN_MIDI_NOTE + mKey, mVelocity)); }
void SendNoteOff() { mPlug->ProcessMidiMsg(&IMidiMsg(0, IMidiMsg::kNoteOff << 4, MIN_MIDI_NOTE + mKey, 64 )); }
IBitmap mWhiteKey, mBlackKey;
int mOctaveWidth, mBlackKeyOffset, mNumOctaves;
int mKey, mVelocity;
};
The control assumes the keyboard (with all keys released) is already drawn in the GUI's background. So when attaching the conrol to the plug-in it needs only two bitmaps: one with a single depressed white key, and one with a black key. It also needs to know the rectangular area that holds the entire keyboard:
Code:
IBitmap white = pGraphics->LoadIBitmap(WHITE_KEY_ID, WHITE_KEY_FN, 1);
IBitmap black = pGraphics->LoadIBitmap(BLACK_KEY_ID, BLACK_KEY_FN, 1);
mGuiKeyboard = new IKeyboardControl(this, &IRECT(33, 301, 467, 393), &white, &black);
pGraphics->AttachControl(mGuiKeyboard);
As you can see I store a pointer to the keyboard control in a member variable ( mGuiKeyboard). That way if I want to update the keyboard in the GUI from within my plug-in (e.g. because it's received a MIDI Note On/Off message), I can simply call mGuiKeyboard->SetDirty();.
The plug-in should keep track of which keys are playing, and provide a method that returns this status:
Code:
bool MyPlug::GetKeyStatus(int key)
{
// To-do: Lookup the key's status, and return true if it's playing, false if it's not.
}
I think that about wraps it up... Any questions?
|
|
|
02-04-2010, 01:29 AM
|
#8
|
Human being with feelings
Join Date: Mar 2007
Location: Vancouver
Posts: 2,279
|
It seems to run in PT quite well via the FXpansion VST to RTAS wrapper. It doesn't have a mono version(which I think can be added to the code easy enough) so I set it up to do mono in the VST wrapper. Here is a screen shot of both the mono and stereo version inserted:
Shane
__________________
"Music should be performed by the musician not by the engineer."
Michael Wagener 25th July 2005, 02:59 PM
Last edited by Shan; 02-04-2010 at 01:34 AM.
|
|
|
02-04-2010, 02:24 AM
|
#9
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by Shan
It seems to run in PT quite well via the FXpansion VST to RTAS wrapper.
|
Cool, thanks for testing.
Quote:
Originally Posted by Shan
It doesn't have a mono version(which I think can be added to the code easy enough) so I set it up to do mono in the VST wrapper.
|
At first I had a 1-channel (mono) only version, but then FL Studio would only output audio on the left channel, so I changed it to fake stereo (the left and right channels are always the same). I guess I still have to figure out how I can add a mono option again.
--
Meanwhile I've working on a new GUI. Here's a screendump of what I have so far:
This means I had the change the keyboard control code a bit, because the flat/sharp keys are not exactly centered in between the regular keys anymore. When I'm done I could post the new code (if anyone's still interested).
|
|
|
02-04-2010, 04:08 AM
|
#10
|
Human being with feelings
Join Date: Apr 2009
Location: Berlin, Germany
Posts: 1,248
|
wow, thanks for sharing the keyboard code tale! i have some gui code i will share at some point too.
If anyone has a polyphony management class, that would be really handy for me at the moment :-)
oli
|
|
|
02-04-2010, 04:46 AM
|
#11
|
Human being with feelings
Join Date: Jun 2009
Location: Buffalo, NY
Posts: 777
|
Is it possible for someone to get all the contributions and add it to iplug? And make a killer iplug example?
~Rob.
|
|
|
02-06-2010, 08:51 AM
|
#12
|
Human being with feelings
Join Date: Mar 2007
Location: Vancouver
Posts: 2,279
|
Quote:
Originally Posted by Tale
Meanwhile I've working on a new GUI. Here's a screendump of what I have so far:
|
Nice! Looks like a Vox Continental to me.
Shane
__________________
"Music should be performed by the musician not by the engineer."
Michael Wagener 25th July 2005, 02:59 PM
|
|
|
02-08-2010, 03:42 AM
|
#13
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by Shan
Nice! Looks like a Vox Continental to me.
|
Quote:
Originally Posted by RRokkenAudio
Is it possible for someone to get all the contributions and add it to iplug?
|
I don't know about that, but I have documented and packaged my contributions (IDrawbarControl, IKeyboardControl, midiqueue) as C header files, so they can more easily be included (see attacked .zip file).
|
|
|
02-08-2010, 03:50 AM
|
#14
|
Human being with feelings
Join Date: Jun 2009
Location: Buffalo, NY
Posts: 777
|
woo! thanks!
|
|
|
02-09-2010, 02:43 PM
|
#15
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
I mailed schwa about getting my IPlug changes into the wdl distribution, he's going to look at it when he gets time.
For anyone that wants them now I've attached a zip file. See the file cc_iplug.txt in there for more details, there is a whole bunch of stuff.
Edit: The latest code is here: http://forum.cockos.com/showthread.php?t=52820
Last edited by cc_; 02-27-2010 at 07:42 AM.
|
|
|
02-10-2010, 03:08 AM
|
#16
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Cool!
|
|
|
04-10-2010, 11:02 AM
|
#17
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Combo Model V 0.0.4 BETA
I've just released a new version of Combo Model V:
http://www.martinic.com/combov/
It now uses my new keyboard control, otherwise it isn't very interesting from an IPlug point of view. (Although it does use a seperate thread to recalculate wave tables inspired by this forum thread, but I haven't made a reusable component for this.)
|
|
|
04-21-2010, 03:24 PM
|
#18
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
tale_iplug_contribs.zip
Quote:
Originally Posted by Tale
I don't know about that, but I have documented and packaged my contributions (IDrawbarControl, IKeyboardControl, midiqueue) as C header files, so they can more easily be included (see attacked .zip file).
|
I've updated my contributions:
IDrawbarControl:
+ Made OnMouse*() and Draw() methods virtual
+ Added specialized OnMouseWheel() method
IKeyboardControl:
+ Treat double-clicks a single-clicks
+ Made OnMouse*() and Draw() methods virtual
+ Disabled mouse wheel
The updated tale_iplug_contribs.zip can be downloaded here:
http://www.taletn.com/wdl/
|
|
|
04-22-2010, 01:14 AM
|
#19
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Cool!
I see you used the d parameter in your OnMouseWheel function... have you seen any problems with the control not moving if the wheel is turned slowly? I found that d was set to 0 if you turned the wheel slowly, because each event was only a fraction ( 1/3 I think ).
I was thinking of fixing this in IPlug either by accumulating the fractions and only calling OnMouseWheel when it got to more than 1, or maybe changing d to be a double.
|
|
|
04-22-2010, 11:26 AM
|
#20
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by cc_
I see you used the d parameter in your OnMouseWheel function... have you seen any problems with the control not moving if the wheel is turned slowly? I found that d was set to 0 if you turned the wheel slowly, because each event was only a fraction ( 1/3 I think ).
|
No problems here in REAPER, but in other hosts I don't know... I will try.
|
|
|
04-22-2010, 11:54 AM
|
#21
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
I don't think it depends on the sequencer, probably depends on the mouse. There's some info here:
http://blogs.msdn.com/oldnewthing/ar.../07/54615.aspx
But I have noticed it more on my Mac than on my PC.
|
|
|
04-22-2010, 12:34 PM
|
#22
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Ok. Nevertheless I've just tried using the mouse wheel on my Combo Model V in VSTHost, and... nothing. B4-II does react to the mouse wheel in VSTHost. I guess I will have to try more hosts, and more mice.
|
|
|
04-23-2010, 12:56 AM
|
#23
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Ah, interesting, maybe the host does have an effect. Maybe some host batch up more events before they send them? I see the problem in Reaper on OSX, but not on Reaper on Windows...
|
|
|
04-23-2010, 04:56 AM
|
#24
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
I can only test on Windows, so I don't know about OSX.
Meanwhile I have tried the mouse wheel in a number of different hosts (FL Studio 9.0.3, Cantabile 2.0.0.2055, VSTHost 1.47), but none of them seem to ever call OnMouseWheel(). In all of these hosts B4-II does see the mouse wheel.
|
|
|
04-28-2010, 04:29 AM
|
#25
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
I've tried more hosts (SONAR 8, Ableton Live 8), and no mouse wheel support in any of them. Still, mouse support in REAPER works excellent.
|
|
|
04-28-2010, 08:14 AM
|
#26
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
I just tried Live7 on windows. Something strange happened, at first the wheel did not work, but if I right clicked a control to start then hit enter to finish editing then the wheel started working (in any control I hovered over).
B4 also behaved a bit funnily, again at first the wheel didn't work, but in its case it was enough just to move one of the controls to get the wheel working.
|
|
|
04-28-2010, 10:45 AM
|
#27
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Yeah, I also had the weird behaviour with B4, even in REAPER.
I will try my IPlug in Live 8 again tomorrow at work, to see if your right-click technique also works for me.
[edit]Yes, you're right. After having right-clicked a control VSTHost "suddenly" starts seeing the mouse wheel for all controls. However, after the plug has lost focus the mouse wheel is not seen again until you right-click some control again.[/edit]
Last edited by Tale; 04-28-2010 at 10:55 AM.
|
|
|
04-28-2010, 01:28 PM
|
#28
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Now knowing that the mouse wheel does work after a right-click, I thought I'd [grab a beer and] have another look at IGraphicsWin::WndProc().
Apparently mouse wheel messages only make it to plug-in's window after the window has explicitly received focus. Simply clicking in the plug-in's window doesn't sent a WM_SETFOCUS message to the window, so any mouse wheel messages are lost. After a right-click a WM_SETFOCUS message is sent to the plug-in's window, so that's why mouse wheel messages do work from then on (or at least until the window loses focus again).
Here's a solution that I think more or less works (but which will require more testing, and probably more thinking):
Code:
case WM_MOUSEACTIVATE: {
SetFocus(hWnd);
return MA_ACTIVATE;
}
You add this case to the switch(msg) statement in IGraphicsWin::WndProc().
This sets the focus to the plug-in's window when it receives its first mouse click. So you do need to click inside the plug-in's window at least once first, but after that the mouse wheel works fine.
|
|
|
04-28-2010, 02:15 PM
|
#29
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Cool! I was trying to figure it out, but getting nowhere... will try your fix tomorrow.
|
|
|
04-29-2010, 08:30 AM
|
#30
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
I tried the focus thing in Cubase 4.5 , Sonar5, FL8, Live7... seems to work as you said it would.
It's not quite the same as other plugins though, they seem to get focus for the mousewheel as soon as you open the editor or click on the title bar (no need to click inside the plugin window).
|
|
|
04-29-2010, 02:15 PM
|
#31
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Setting focus when you open the editor is easy (and probably a good idea indeed). You just add SetFocus() to the WM_CREATE block:
Code:
if (msg == WM_CREATE) {
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM) (lpcs->lpCreateParams));
int mSec = int(1000.0 / sFPS);
SetTimer(hWnd, IPLUG_TIMER_ID, mSec, NULL);
SetFocus(hWnd); // <--- Add this line
return 0;
}
However, setting focus when you click on the title bar is trickier. I think the problem is that the window frame including the title bar is provided by the host, i.e. it's not actually part of the plug-in window. So when you click on the titlebar this will cause window messages to be sent to the host providing the frame, but not to the plug-in window itself.
|
|
|
05-05-2010, 07:02 AM
|
#32
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
I haven't come up with a better solution for the mouse wheel, so today I've released Combo Model V 0.0.6 beta with the SetFocus() on creation and mouse activation. Now we'll wait and see if I get any complaints.
|
|
|
05-06-2010, 05:01 AM
|
#33
|
Human being with feelings
Join Date: Mar 2009
Posts: 256
|
Let me know how it goes.
I was thinking maybe handling WM_ACTIVATE might be the way to get the clicking on the title working, but didn't get round to trying it yet.
|
|
|
05-06-2010, 05:46 AM
|
#34
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
I've already tried that, but in both REAPER and FL Studio WM_ACTIVATE never reaches IGraphicsWin::WndProc(). It might work in other hosts though.
|
|
|
05-10-2010, 11:38 AM
|
#35
|
Human being with feelings
Join Date: Apr 2010
Location: Moscow, Russia
Posts: 19
|
More About Focus
In Carbon window on OSX setting focus is simple, you can use: SetUserFocusWindow(pWindow);
But in Cocoa, I couldn't find and understand, how to do it... CC_ may be you know?
|
|
|
05-10-2010, 01:37 PM
|
#36
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Cool. But do we know whether Carbon and/or Cocoa require focus for mouse wheel support?
|
|
|
05-10-2010, 01:40 PM
|
#37
|
Human being with feelings
Join Date: Apr 2010
Location: Moscow, Russia
Posts: 19
|
MouseWheel works great without focus on Carbon and Cocoa. You need focus only for keyboard input (arrow keys for example).
|
|
|
05-14-2010, 07:03 AM
|
#38
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Thanks for checking/sharing. Carbon and Cocoa don't need the focus thing then.
Meanwhile I've released yet another beta version of my plug-in, still with the SetFocus() on WM_CREATE and WM_MOUSEACTIVATE. By now my patched code has been (implicitly) tested by a lot of people, and I've had no complains. This means that there probably are no side effects, so I'm keeping the patched code.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 10:08 PM.
|