Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd March 2008, 00:29   #1  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
CutFrames: Opposite of Trim

Code:
# CutFrames() - March 9th, 2008
#  Cut a range of frames from a single a/v clip.
#
# Parameters: 
#  int start - start of cut
#  int end - end of cut
#  int duration - duration of fade between cuts
#  int fade_color - blank clip color (usually in Hex RGB) used at start or end of clip only
#  string transition - pass a function name, if user wants to use something other then Dissolve
#  val opt1 - pass a variable to the fade/transition function
#  val opt2 - pass a variable to the fade/transition function
#  val opt3 - pass a variable to the fade/transition function
# 
# Preconditions:
#  start >= 0 ; start can not be a negative value
#  start-duration > 0
#  start = 0 then a fade in is used
#  end = 0 cut till the end of the clip and a fade out is used
#  start != end ; mainly a condition to check for start == 0 and end == 0


function CutFrames(clip c, int start, int end, int "duration", int "fade_color", string "transition", val "opt1", val "opt2", val "opt3")
{
	# Set Defaults
	duration = default(duration, 0)
	transition = default(transition, "Dissolve")
	fade_color = default(fade_color,$000000)
	opt1=(Defined(opt1) ? ", "+string(opt1): "")
	opt2=(Defined(opt2) ? ", "+string(opt2): "")
	opt3=(Defined(opt3) ? ", "+string(opt3): "")
	opts = opt1 + opt2 + opt3
	end = c.Framecount()-1 == end ? 0: end
	d = c.BlankClip(duration, color=fade_color)
	
	# Check For Any Unreasonable Inputs
	Assert(start >= 0, "CutFrames: Starting Frame[" + String(start) + "] must be a positive value")
	Assert((start == 0) || (start-duration >= 0), "CutFrames: Starting Frame[" + String(start) + "] must be greater then or equal to" + Chr(10) + " inputed duration[" + String(duration) + "]")
	Assert(start <> end, "CutFrames: Start and End cannot both be the same")
	Assert(end <= c.Framecount()-1, "CutFrames: End[" + String(end) + "] is greater then " + Chr(10) + "clip length[" + String(c.Framecount()-1) + "]")
	Assert((end == 0) || (end+duration <= c.Framecount()-1), "CutFrames: Ending Frame[" + String(end) + "] must be less then or equal to" + Chr(10) + " last frame - duration [" + String(c.Framecount()-1-duration) + "]")

	# Select uncut frames (or blanks) as transition components:
	clip1 = (start == 0) ? d : c.trim(0, -start)
	clip2 = (end == 0) ? d : c.trim(end+1, 0)

	# Perform transition:
	Eval(transition + "(clip1, clip2," + string(duration) + opts + ")")
}
General Examples: - Assuming clip is 1000 frames in length
CutFrames(200, 400) - Cut out frames 200-400 from the video. Resulting length: 799
CutFrames(200, 400, 20) - Cut out frames 200-400 using Dissolve() for a 20 frame fade. Transition starts on frame 180; Resulting length: 779
CutFrames(210, 390, 20) - Cut out frames 210-390 using Dissolve() for a 20 frame fade. Transition starts on frame 190; Resulting length: 799
CutFrames(400, 200, 20) - Replay frames 200-400 using Dissolve() with a 20 frame fade. Transition starts on frame 380; Resulting length: 1179
CutFrames(200, 400, 20, $000000, "TransSwing", false, 1, 1) - Cut out frames 200-400 using TransSwing() for a 20 frame fade, passing 3 additional arguments to TransSwing(). Transition starts on frame 180; Resulting length: 779
CutFrames(0, 400) - Cut out frames 0-400 from the video. Resulting length: 599
CutFrames(0, 400, 20) - Cut out frames 0-400 from the video using Dissolve() for a 20 frame fade from black (FadeIn). Resulting length: 599
CutFrames(200, 0) - Cut out frames 200-1000 from the video. Resulting length: 199
CutFrames(200, 0, 20) - Cut out frames 200-1000 from the video using Dissolve() for a 20 frame fade into black (FadeOut). Resulting length: 199
CutFrames(0, 400, 20, $FF0000) - Cut out frames 0-400 from the video using Dissolve() for a 20 frame fade from red (FadeIn). Resulting length: 599

Tips:
  • When using this multiple times, work backwards. Cut frames from the end of the clip first. By doing this, your cuts will be independent from each other.
    Example:
    CutFrames(900, 950)
    CutFrames(800, 850)
    CutFrames(650, 700)
  • Inserting ShowFrameNumber(x=10, y=30) before any cutframes() will show what frame you're currently on.
  • If your looking for audio cuts add something like this before CutFrames()
    Code:
    Histogram("stereo")
    AddBorders(300, 0, 0, 0)
    Histogram("Audiolevels")
    ShowFrameNumber(x=width()-100, y=30)
    ShowSMPTE()
    Or a better way using AudioGraph(). Stickboy made a nice wrapper for stereo output. http://forum.doom9.org/showthread.php?s=&threadid=59412
    Code:
    Grayscale()
    ConvertToRGB()
    AudioGraph(Width()/96)
    ShowFrameNumber(x=10, y=30)
    ShowSMPTE()
    You can place these after all your CutFrames() to see the resulting sound/waveform.
  • Place your CutFrames() inside a function. This allows you to comment out all your cuts at once.
    Code:
    cut()
    Function Cut(clip c)
    {
    	c
    	CutFrames(254700, 0, 15)
    	CutFrames(194974, 254027, 15)
    	CutFrames(0, 189730, 15)
    }
    Taking this one step further, you can create multiple segments and order them in any way; selectively applying filters as well.
    Code:
    original = last
    segmentA(original)
    last + Grayscale(segmentB(original))
    function segmentA(clip c)
    {
    	c
    	CutFrames(254700, 0, 15)
    	CutFrames(194974, 254027, 15)
    	CutFrames(0, 189730, 15)
    }
    function segmentB(clip c)
    {
    	c
    	CutFrames(3390, 0, 15)
    	CutFrames(580, 2700, 15)
    	CutFrames(0, 460, 15)
    }

Footnotes:
Loop() can delete frames as well. Second to last example on page.

Future Ideas:
This is a RFC (Request For Comments), your input is greatly appreciated.

Edits:
March 4th, 2008: Got rid of ugly logic - Thanks Gavino
March 7th, 2008: Added error checking and FadeIn/FadeOut - Thanks stickboy for pointing out how this can fail and for header suggestions
March 8th, 2008: Improved End error checking
March 8th, 2008: Fixed cut points, now they are excluded - Thanks Gavino. Examples changed as a result.
March 9th, 2008: More code cleanup, added color option to fadeI/O, fixed end boundary condition - Thanks Gavino.

Last edited by mikeytown2; 15th March 2008 at 14:04.
mikeytown2 is offline   Reply With Quote
Old 2nd March 2008, 12:54   #2  |  Link
stickboy
AviSynth Enthusiast
 
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
Even your simple version is problematic. Be careful when using Trim with variable arguments.
stickboy is offline   Reply With Quote
Old 2nd March 2008, 15:02   #3  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Thanks for pointing this out! After looking at your functions and reading the headers, i think i will use Trim3.
http://avisynth.org/stickboy/jdl-util.avsi

You really like Assert, i had to go look it up.
http://avisynth.org/mediawiki/Intern...trol_functions


So reworking my first example it should be something like this
Code:
function CutFrames(clip c, int start, int end)
{
	return c.trim3(0, start) + c.trim3(end, c.Framecount())
}
mikeytown2 is offline   Reply With Quote
Old 2nd March 2008, 21:16   #4  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by mikeytown2 View Post
This is a very simple script, but i would like it to be smart.
Code:
function CutFrames(clip c, int start, int end)
{
	return c.trim(0, start) + c.trim(end, c.Framecount())
}
I would like to make it aware of the other times it is called. So when i edit a video and call this function, multiple times, it knows. So if i remove the very first call to CutFrames i would not have to change all the other ones.
The solution to your problem is much easier: simply apply your cuts in reverse order in your script, eg

CutFrames(4444, 5555)
CutFrames(2222, 3333)
...

Then if you decide to remove any of the cuts, the frame numbers in the other ones will still be valid.

Gavino
Gavino is offline   Reply With Quote
Old 3rd March 2008, 08:08   #5  |  Link
Ebobtron
Errant Knight
 
Ebobtron's Avatar
 
Join Date: Oct 2004
Location: St Louis, M0 US
Posts: 364
Hello,
Lots of ways to skin this cat, here is one I use often, it is easier for me to understand weeks, maybe months, into something.

Code:
some source filter or filters 
# source filters return a clip "last"
# which is equivalent  to " last =  source filter "
# unless assigned to a clip variable,
# (for example " source = source filter ")

trim(framestart, frameend) + trim(fs, fe) + trim(fs, fe) + trim(fs, fe)
# yep that sucks, and if there are a lot of them it really sucks

aclip = trim(fs, fe)
# aclip is assigned the clip returned by " trim(last, fs, fe) "
aclip = aclip + trim(fs, fe)
# The just keep doing it
aclip = aclip + trim(fs, fe)
aclip = aclip + trim(fs, fe)
aclip = aclip + trim(fs, fe)
aclip = aclip + trim(fs, fe)
aclip = aclip + trim(fs, fe)
aclip = aclip + trim(fs, fe)

# want to comment one out
#aclip = aclip + trim(fs, fe)
 
aclip = aclip + trim(fs, fe)

# at this point the script's output is still equal to " last '
#

aclip  
# which is the same as last = aclip
Code:
# add dissolves between all clips
aclip = trim(fs, fe)
aclip = Dissolve(aclip, trim(fs, fe), 60)
aclip = Dissolve(aclip, trim(fs, fe), 60)
aclip = Dissolve(aclip, trim(fs, fe), 60)
aclip = Dissolve(aclip, trim(fs, fe), 60)

aclip
have fun
Ebobtron is offline   Reply With Quote
Old 3rd March 2008, 19:30   #6  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
@Gavino Thank you for the reverse order hint, that makes this a lot simpler to implement.

@Ebobtron The option to dissolve/blend the clips would be a good thing. [http://avisynth.org/mediawiki/Dissolve] In the long run, i would like to be able to support any transition. [http://avisynth.org/vcmohan/TransAll/docs/index.html] I think i would have to use an eval statement in order to do it. [http://avisynth.org/mediawiki/Intern...trol_functions]

In terms of the structure of the AddCutPoint function, i think it would look something like this
AddCutPoint(clip c, int start, int end, string transition, int duration)

where clip c is the a/v stream to cut up. int start is the starting frame to cut, int end would be the last or ending frame to cut. String transition would be the function name, and int duration is how long the transition will last. This function call would then store these 5 values into a 5 dim array. the only question i have is about storing a clip into an array; is this a bad idea? Int's and strings shouldn't be an issue but i'm not sure about the clip variable. The reason for storing the clip variable would be in the case of multiple a/v clips in a single script.


Anyway here is the simple script with transitions added
Code:
function CutFrames(clip c, int start, int end, string "transition", int "duration")
{
	duration = default(duration, 0)
	return Defined(transition) ? Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ")") : c.trim(0, start) + c.trim(end, c.Framecount())
}


CutFrames(200, 800, "Dissolve", 60)

EDIT
I think i like this function better
Code:
function CutFrames(clip c, int start, int end, int "duration", string "transition")
{
	duration = default(duration, 0)
	transition = default(transition, "Dissolve")
	return Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ")")
}


CutFrames(200, 800, 60)

Last edited by mikeytown2; 3rd March 2008 at 22:28.
mikeytown2 is offline   Reply With Quote
Old 4th March 2008, 01:30   #7  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by mikeytown2 View Post
@Gavino Thank you for the reverse order hint, that makes this a lot simpler to implement.

...

In terms of the structure of the AddCutPoint function, i think it would look something like this
AddCutPoint(clip c, int start, int end, string transition, int duration)
My point was that if you adopt the 'reverse order' strategy (ie put the cuts in reverse chronological order), you no longer need the AddCutPoint function. This approach will still work with your extended CutFrames function which supports transitions.

Gavino
Gavino is offline   Reply With Quote
Old 4th March 2008, 03:31   #8  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
@Gavion I was planing on using a sort array method, to order the array from largest to smallest, inside the ProcessCutPoints() function. Without your helpful input, i probably would have done it another way, with a lot of math calc involved.

After looking at [http://avisynth.org/mediawiki/Arrays] and [http://avslib.sourceforge.net/functi...raycreate.html], i have decided to drop the idea of processing multiple clips simultaneously. The ProcessCutPoints() function should clear the arrays, so that it can still do cuts on multiple clips; just not all at the same time. Speaking of arrays i think 4 single dim arrays would be the easiest to do with the avisynth language. I just need a way to sort this, otherwise as Gavion has pointed out, my simple method is quite adequate.

Any input would greatly be appreciated, should i go for the 2 step process or should i leave this as is?


EDIT
Multiple options can be passed to the blending function now
Code:
function CutFrames(clip c, int start, int end, int "duration", string "transition", string "opt1", string "opt2", string "opt3")
{
	duration = default(duration, 0)
	transition = default(transition, "Dissolve")
	return 
	\	Defined(opt3) ? Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ", " + String(opt1) + ", " + String(opt2) + ", " + String(opt3) + ")") :
	\	Defined(opt2) ? Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ", " + String(opt1) + ", " + String(opt2) + ")") :
	\	Defined(opt1) ? Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ", " + String(opt1) + ")") :
	\	Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", c.Framecount()), " + string(duration) + ")")
}


CutFrames(200, 800, 60, "TransSwing", "false", "1", "1")
http://avisynth.org/vcmohan/TransAll...ransSwing.html


You can also use this as a quick, apply effect to range function, that takes 2 clips as input
Code:
CutFrames(200, 150, 50, "EffectName")
Or instant replay
Code:
CutFrames(300, 150)
Or "Drunk Effect"
Code:
CutFrames(800, 100, 695)

Last edited by mikeytown2; 4th March 2008 at 04:39.
mikeytown2 is offline   Reply With Quote
Old 4th March 2008, 13:15   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by mikeytown2 View Post
Any input would greatly be appreciated, should i go for the 2 step process or should i leave this as is?
It's a matter of taste, but I think the introduction of AddCutPoint and ProcessCutPoints (if that's what you mean by the 2 step process) is overkill, and the CutFrames function is all you need. The 'reverse order' approach solves the problem you initially identified, of each cut potentially changing the frame numbers to be used in the others.

Of course YMMV, and your time and effort are yours to spend as you wish.

Incidentally, I suggest a modification to your enhanced CutFrames function: change the types of opt1, opt2 and opt3 from 'string' to 'val'. This would allow you to pass numerical parameters without quotes.
Also (and again, it's a matter of personal taste), I would tidy up the last part as follows:
Code:
  opt1=(Defined(opt1) ? ", "+string(opt1): "")
  opt2=(Defined(opt2) ? ", "+string(opt2): "")
  opt3=(Defined(opt3) ? ", "+string(opt3): "")
  return Eval(transition + "(c.trim(0, " + string(start) + "), c.trim(" + string(end) + ", 0), " + string(duration) + opt1 + opt2 + opt3 + ")")
Gavino is offline   Reply With Quote
Old 4th March 2008, 22:50   #10  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Updated first post with latest function and put up examples as well as a very helpful tip.

Thanks to Gavino for your help in cleaning up the code and the tip.
Thanks to Ebobtron for pointing out transitions.
Thanks to stickboy for directing me towards his other trim functions; i didn't use them because of dependency issues though.
mikeytown2 is offline   Reply With Quote
Old 5th March 2008, 20:37   #11  |  Link
stickboy
AviSynth Enthusiast
 
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
Quote:
Originally Posted by mikeytown2 View Post
Updated first post with latest Thanks to stickboy for directing me towards his other trim functions; i didn't use them because of dependency issues though.
So you'd rather have functions that silently do the wrong thing when given certain inputs? You don't even bother using Assert() to validate them, nor do you describe in the comments which values to avoid.

It's not as if they're unlikely inputs. You only need to call CutFrames(c, 0, ...) for it to be wrong.

I've made my functions public domain for a reason. If you don't want to tell people to go download my scripts (and I don't think anyone actually has any problem with that), you're free to simply copy and paste the parts you need.
stickboy is offline   Reply With Quote
Old 7th March 2008, 22:54   #12  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by stickboy View Post
So you'd rather have functions that silently do the wrong thing when given certain inputs? You don't even bother using Assert() to validate them, nor do you describe in the comments which values to avoid.

It's not as if they're unlikely inputs. You only need to call CutFrames(c, 0, ...) for it to be wrong.

I've made my functions public domain for a reason. If you don't want to tell people to go download my scripts (and I don't think anyone actually has any problem with that), you're free to simply copy and paste the parts you need.
It's nothing against your scripts, just me personally, any time i have to download multiple files to get a function working, i find that annoying; trying to avoid that if i can. Thank you for the option to paste your script into this.

I never considered 0 as an input for this function (was thinking they would use trim), now i think CutFrames handles this quite nicely.

I also added Preconditions to the header.



Where should i pass the BlankClip Color property into this function? i was thinking after int "duration".
mikeytown2 is offline   Reply With Quote
Old 9th March 2008, 02:37   #13  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
@mikeytown2: Looking at this again, I've just spotted something ...
Quote:
Originally Posted by mikeytown2 View Post
General Examples: - Assuming clip is 1000 frames in length
CutFrames(200, 400) - Cut out frames 200-400 from the video. Resulting length: 800
...
In fact, it cuts out frames 201-399, for a resulting length of 801.
(and even if it did cut out 200-400, the length would then be 799)

As the function is written, frames 'start' and 'end' are excluded from the cut, ie they appear in the output clip. I assume this is an oversight and you intended it to work as described in the example.

Gavino
Gavino is offline   Reply With Quote
Old 9th March 2008, 03:24   #14  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Quote:
Originally Posted by Gavino View Post
@mikeytown2: Looking at this again, I've just spotted something ...


In fact, it cuts out frames 201-399, for a resulting length of 801.
(and even if it did cut out 200-400, the length would then be 799)

As the function is written, frames 'start' and 'end' are excluded from the cut, ie they appear in the output clip. I assume this is an oversight and you intended it to work as described in the example.

Gavino
Thanks for pointing this out. I think i have it fixed now. Trim acts kinda odd when you just want the first frame [http://avisynth.org/mediawiki/Trim].
mikeytown2 is offline   Reply With Quote
Old 9th March 2008, 17:05   #15  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by mikeytown2 View Post
I think i have it fixed now.
Almost, but I think you've still got one of the boundary conditions wrong.
Since the last frame of a clip is actually framecount-1, this value (rather than framecount) should be the max allowed for end (and mapped internally to 0).

Also, it might be clearer to replace:
Code:
#Funkey Conditions
start = (start == 0) ? -1 : start
start = (start == 1) ? 0 : start

#Perform Cut
return start == -1 ? 
\Eval(transition + "(d, c.trim(" + string(end+1) + ", 0), " + string(duration) + opts + ")"):
\end == 0 ?
\Eval(transition + "(c.trim(0, " + string(start-1) + "), d, " + string(duration) + opts + ")"):
\Eval(transition + "(c.trim(0, " + string(start-1) + "), c.trim(" + string(end+1) + ", 0), " + string(duration) + opts + ")")
by
Code:
# Select uncut frames (or blanks) as transition components:
clip1 = (start == 0) ? d : c.trim(0, -start)
clip2 = (end == 0) ? d : c.trim(end+1, 0)

# Perform transition:
Eval(transition + "(clip1, clip2," + string(duration) + opts + ")")
The effect is the same, but this way it seems clearer what the special cases are and how they are handled. (And by always using the negative Trim argument to select the first start frames, start=1 is no longer a special case)

Gavino
Gavino is offline   Reply With Quote
Old 9th March 2008, 23:25   #16  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Gavino thank you for improving this function, it would be a lot uglier without your help!


I was thinking about the fade color option, is there any way to test if an int is hex ($000000), if it has a "$" in it? If there is, then an idea i have is to get rid of the fade_color variable and use the start and end variables instead. Because the only time the blank clip is used is when start or end = 0; then if start or end is a color it would set the color with that value and then set start or end to 0.
Example: CutFrames(0, 400, 20, $FF0000) would be CutFrames($FF0000, 400, 20) and CutFrames(400, 0, 20, $FF0000) would be CutFrames(400, $FF0000, 20).
This would eliminate the unnecessary color variable in this example: CutFrames(200, 400, 20, $000000, "TransSwing", false, 1, 1)

Good/Bad, is it even possible idea?
mikeytown2 is offline   Reply With Quote
Old 10th March 2008, 00:57   #17  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by mikeytown2 View Post
I was thinking about the fade color option, is there any way to test if an int is hex ($000000), if it has a "$" in it? If there is, then an idea i have is to get rid of the fade_color variable and use the start and end variables instead.
It's not possible to distinguish an int passed in hex from one passed in decimal; once you get your hands on it it's just an int value.

If passing an unnecessary color parameter bothers you, you could move fade_color to the end of the function parameter list, then pass it by name on the infrequent occasions that a non-default value is wanted.

There seems to be a typo in your latest edit:
Code:
bg_color = default(fade_color,$000000)
should be
Code:
fade_color = default(fade_color,$000000)
(or maybe you meant to use bg_color as the parameter to BlankClip later?)
Gavino is offline   Reply With Quote
Old 10th March 2008, 01:05   #18  |  Link
mikeytown2
Resize Abuser
 
mikeytown2's Avatar
 
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
Thanks for the catching the typo! I originally called it background color, then i thought fade described it better. Thanks for looking into the int/hex issue, it's not a major issue, just thought it might be better if it was possible. I'll leave fade_color where it is.
mikeytown2 is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:52.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.