Line endings...be normalized!

This commit is contained in:
Jason Felds
2011-03-17 01:47:30 -04:00
parent 146e8e14f1
commit a085d0d1da
1962 changed files with 444486 additions and 444486 deletions
+51 -51
View File
@@ -1,51 +1,51 @@
-- This file is always executed first.
-- Override Lua's upper and lower functions with our own, which is always UTF-8.
if Uppercase then
string.upper = Uppercase
string.lower = Lowercase
Uppercase = nil -- don't use directly
Lowercase = nil -- don't use directly
end
Trace = lua.Trace
Warn = lua.Warn
print = Trace
PLAYER_1 = "PlayerNumber_P1"
PLAYER_2 = "PlayerNumber_P2"
NUM_PLAYERS = #PlayerNumber
function string:find_last( text )
local LastPos = 0
while true do
local p = string.find( self, text, LastPos+1, true )
if not p then
return LastPos
end
LastPos = p
end
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- This file is always executed first.
-- Override Lua's upper and lower functions with our own, which is always UTF-8.
if Uppercase then
string.upper = Uppercase
string.lower = Lowercase
Uppercase = nil -- don't use directly
Lowercase = nil -- don't use directly
end
Trace = lua.Trace
Warn = lua.Warn
print = Trace
PLAYER_1 = "PlayerNumber_P1"
PLAYER_2 = "PlayerNumber_P2"
NUM_PLAYERS = #PlayerNumber
function string:find_last( text )
local LastPos = 0
while true do
local p = string.find( self, text, LastPos+1, true )
if not p then
return LastPos
end
LastPos = p
end
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+22 -22
View File
@@ -1,23 +1,23 @@
--[[ sm-ssc aliases (non-compatibility)
This is mainly here for making commands case-insensitive without needing to
clutter up the C++ code. It can also be used to add custom functions that
wouldn't otherwise belong somewhere else.
--]]
-- in fact, this probably belongs in Sprite.lua...
function Sprite:cropto(w,h)
self:CropTo(w,h)
end
function Actor:SetSize(w,h)
self:setsize(w,h)
end
-- shorthand! this is tedious to type and makes things ugly so let's make it shorter.
-- screen.w, screen.h, etc.
local _screen = {
w = SCREEN_WIDTH,
h = SCREEN_HEIGHT,
cx = SCREEN_CENTER_X,
cy = SCREEN_CENTER_Y
--[[ sm-ssc aliases (non-compatibility)
This is mainly here for making commands case-insensitive without needing to
clutter up the C++ code. It can also be used to add custom functions that
wouldn't otherwise belong somewhere else.
--]]
-- in fact, this probably belongs in Sprite.lua...
function Sprite:cropto(w,h)
self:CropTo(w,h)
end
function Actor:SetSize(w,h)
self:setsize(w,h)
end
-- shorthand! this is tedious to type and makes things ugly so let's make it shorter.
-- screen.w, screen.h, etc.
local _screen = {
w = SCREEN_WIDTH,
h = SCREEN_HEIGHT,
cx = SCREEN_CENTER_X,
cy = SCREEN_CENTER_Y
}
+68 -68
View File
@@ -1,68 +1,68 @@
-- Override Lua's loadfile to use lua.ReadFile.
function loadfile(file)
local data, err = lua.ReadFile(file);
if not data then
return nil, ("what " .. file)
end
local chunk, err = load(
function()
local ret = data
data = nil
return ret
end,
"@" .. file );
if not chunk then return nil, err end
-- Set the environment, like loadfile does.
setfenv( chunk, getfenv(2) );
return chunk
end
-- Override Lua's dofile to use our loadfile.
function dofile(file)
if not file then
error( "dofile(nil) unsupported", 2 );
end
local chunk, err = loadfile(file)
if not chunk then
error( err, 2 );
end
return chunk
end
-- Like ipairs(), but returns only values.
function ivalues(t)
local n = 0
return function()
n = n + 1
return t[n];
end
end
Var = lua.GetThreadVariable
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Override Lua's loadfile to use lua.ReadFile.
function loadfile(file)
local data, err = lua.ReadFile(file);
if not data then
return nil, ("what " .. file)
end
local chunk, err = load(
function()
local ret = data
data = nil
return ret
end,
"@" .. file );
if not chunk then return nil, err end
-- Set the environment, like loadfile does.
setfenv( chunk, getfenv(2) );
return chunk
end
-- Override Lua's dofile to use our loadfile.
function dofile(file)
if not file then
error( "dofile(nil) unsupported", 2 );
end
local chunk, err = loadfile(file)
if not chunk then
error( err, 2 );
end
return chunk
end
-- Like ipairs(), but returns only values.
function ivalues(t)
local n = 0
return function()
n = n + 1
return t[n];
end
end
Var = lua.GetThreadVariable
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+65 -65
View File
@@ -1,66 +1,66 @@
--[[ sm-ssc compatibility helpers
sm-ssc changes quite a few things which would make various SM4 content break.
Also, certain things are deprecated/removed from sm-ssc (and sometimes SM4 too).
--]]
--[[ Actor ]]
function Actor:hidden(bHide)
Warn("hidden is deprecated, use visible instead. (used on ".. self:GetName() ..")")
self:visible(not bHide)
end
-- for when horizalign and vertalign get killed by glenn:
--[[
function Actor:horizalign(v)
local values = {
left = 0,
center = 0.5,
right = 1
}
self:halign(values[v])
end
function Actor:vertalign(v)
local values = {
top = 0,
middle = 0.5,
bottom = 1
}
self:valign(values[v])
end
--]]
--[[ ActorScroller: all of these got renamed, so alias the lowercase ones if
things are going to look for them. ]]
function ActorScroller:getsecondtodestination()
self:GetSecondsToDestination()
end
function ActorScroller:setsecondsperitem(secs)
self:SetSecondsPerItem(secs)
end
function ActorScroller:setnumsubdivisions(subs)
self:SetNumSubdivisions(subs)
end
function ActorScroller:scrollthroughallitems()
self:ScrollThroughAllItems()
end
function ActorScroller:scrollwithpadding(fPadStart,fPadEnd)
self:ScrollWithPadding(fPadStart,fPadEnd)
end
function ActorScroller:setfastcatchup(bFastCatchup)
self:SetFastCatchup(bFastCatchup)
end
-- renaming various StepMania functions to sm-ssc ones:
if ScreenString then
ScreenString = Screen.String
end
if ScreenMetric then
ScreenMetric = Screen.Metric
--[[ sm-ssc compatibility helpers
sm-ssc changes quite a few things which would make various SM4 content break.
Also, certain things are deprecated/removed from sm-ssc (and sometimes SM4 too).
--]]
--[[ Actor ]]
function Actor:hidden(bHide)
Warn("hidden is deprecated, use visible instead. (used on ".. self:GetName() ..")")
self:visible(not bHide)
end
-- for when horizalign and vertalign get killed by glenn:
--[[
function Actor:horizalign(v)
local values = {
left = 0,
center = 0.5,
right = 1
}
self:halign(values[v])
end
function Actor:vertalign(v)
local values = {
top = 0,
middle = 0.5,
bottom = 1
}
self:valign(values[v])
end
--]]
--[[ ActorScroller: all of these got renamed, so alias the lowercase ones if
things are going to look for them. ]]
function ActorScroller:getsecondtodestination()
self:GetSecondsToDestination()
end
function ActorScroller:setsecondsperitem(secs)
self:SetSecondsPerItem(secs)
end
function ActorScroller:setnumsubdivisions(subs)
self:SetNumSubdivisions(subs)
end
function ActorScroller:scrollthroughallitems()
self:ScrollThroughAllItems()
end
function ActorScroller:scrollwithpadding(fPadStart,fPadEnd)
self:ScrollWithPadding(fPadStart,fPadEnd)
end
function ActorScroller:setfastcatchup(bFastCatchup)
self:SetFastCatchup(bFastCatchup)
end
-- renaming various StepMania functions to sm-ssc ones:
if ScreenString then
ScreenString = Screen.String
end
if ScreenMetric then
ScreenMetric = Screen.Metric
end
+169 -169
View File
@@ -1,169 +1,169 @@
-- Convenience aliases:
left = "HorizAlign_Left";
center = "HorizAlign_Center";
right = "HorizAlign_Right";
top = "VertAlign_Top";
middle = "VertAlign_Middle";
bottom = "VertAlign_Bottom";
function Actor:ease(t, fEase)
-- Optimizations:
-- fEase = -100 is equivalent to TweenType_Accelerate.
if fEase == -100 then
self:accelerate(t);
return;
end
-- fEase = 0 is equivalent to TweenType_Linear.
if fEase == 0 then
self:linear(t);
return;
end
-- fEase = +100 is equivalent to TweenType_Decelerate.
if fEase == 100 then
self:decelerate(t);
return;
end
self:tween( t, "TweenType_Bezier",
{
0,
scale(fEase, -100, 100, 0/3, 2/3),
scale(fEase, -100, 100, 1/3, 3/3),
1
}
);
end
-- Notes On Beziers --
-- They can be 1D ( Quadratic ) or 2D ( Bezier )
-- 1D:
-- XA XB YC YD
-- 2D:
-- XA XB XC XD YA YB YC YD
-- In 1D Quads, XA XB are beginning time and size, YC YD are ending time and size
-- In 2D Quads, X
local BounceBeginBezier =
{
0, 0,
0.42, -0.42,
2/3, 0.3,
1, 1
}
function Actor:bouncebegin(t)
self:tween( t, "TweenType_Bezier", BounceBeginBezier );
end
local BounceEndBezier =
{
0,0,
1/3, 0.7,
0.58, 1.42,
1, 1
}
function Actor:bounceend(t)
self:tween( t, "TweenType_Bezier", BounceEndBezier );
end
local SmoothBezier =
{
0, 0, 1, 1
}
function Actor:smooth(t)
self:tween( t, "TweenType_Bezier", SmoothBezier );
end
-- SSC Additions
local DropBezier =
{
0 , 0,
1/3 , 1,
2/3 , 0.5,
1 , 1,
}
function Actor:drop(t)
self:tween( t, "TweenType_Bezier", DropBezier );
end
-- Hide if b is true, but don't unhide if b is false.
function Actor:hide_if(b)
if b then
self:visible(false)
end
end
function Actor:player(p)
self:visible( GAMESTATE:IsHumanPlayer(p) )
end
function ActorFrame:propagatecommand(...)
self:propagate(1);
self:playcommand(...);
self:propagate(0);
end
-- Shortcut for alignment.
-- cmd(align,0.5,0.5) -- align center
-- cmd(align,0.0,0.0) -- align top-left
-- cmd(align,0.5,0.0) -- align top-center
function Actor:align(h, v)
self:halign( h );
self:valign( v );
end
function Actor:FullScreen()
self:stretchto( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
end
--[[ Typical background sizes:
320x240 - DDR 1st-Extreme, most NVLM_ZK songs
640x480 - most simfiles in distribution today are this big.
768x480 - 16:10 aspect ratio backgrounds
854x480 - pump it up pro
]]
-- "Most backgrounds are 640x480. Some are 768x480. Stretch the 4:3 ones."
function Actor:scale_or_crop_background()
if (self:GetWidth() * 3) / 4 == self:GetHeight() then
self:stretchto( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
else
self:scaletocover( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
end
end
function Actor:Center()
self:x(SCREEN_CENTER_X)
self:y(SCREEN_CENTER_Y)
end
function Actor:bezier(...)
local a = {...}
local b = {}
local c = 0
assert((a == 9 or a == 5), "bad number of arguments for Actor:bezier()")
for i=3,c do
b[#b+1] = a[i]
end
self:tween(a[2], "TweenMode_Bezier", b)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Convenience aliases:
left = "HorizAlign_Left";
center = "HorizAlign_Center";
right = "HorizAlign_Right";
top = "VertAlign_Top";
middle = "VertAlign_Middle";
bottom = "VertAlign_Bottom";
function Actor:ease(t, fEase)
-- Optimizations:
-- fEase = -100 is equivalent to TweenType_Accelerate.
if fEase == -100 then
self:accelerate(t);
return;
end
-- fEase = 0 is equivalent to TweenType_Linear.
if fEase == 0 then
self:linear(t);
return;
end
-- fEase = +100 is equivalent to TweenType_Decelerate.
if fEase == 100 then
self:decelerate(t);
return;
end
self:tween( t, "TweenType_Bezier",
{
0,
scale(fEase, -100, 100, 0/3, 2/3),
scale(fEase, -100, 100, 1/3, 3/3),
1
}
);
end
-- Notes On Beziers --
-- They can be 1D ( Quadratic ) or 2D ( Bezier )
-- 1D:
-- XA XB YC YD
-- 2D:
-- XA XB XC XD YA YB YC YD
-- In 1D Quads, XA XB are beginning time and size, YC YD are ending time and size
-- In 2D Quads, X
local BounceBeginBezier =
{
0, 0,
0.42, -0.42,
2/3, 0.3,
1, 1
}
function Actor:bouncebegin(t)
self:tween( t, "TweenType_Bezier", BounceBeginBezier );
end
local BounceEndBezier =
{
0,0,
1/3, 0.7,
0.58, 1.42,
1, 1
}
function Actor:bounceend(t)
self:tween( t, "TweenType_Bezier", BounceEndBezier );
end
local SmoothBezier =
{
0, 0, 1, 1
}
function Actor:smooth(t)
self:tween( t, "TweenType_Bezier", SmoothBezier );
end
-- SSC Additions
local DropBezier =
{
0 , 0,
1/3 , 1,
2/3 , 0.5,
1 , 1,
}
function Actor:drop(t)
self:tween( t, "TweenType_Bezier", DropBezier );
end
-- Hide if b is true, but don't unhide if b is false.
function Actor:hide_if(b)
if b then
self:visible(false)
end
end
function Actor:player(p)
self:visible( GAMESTATE:IsHumanPlayer(p) )
end
function ActorFrame:propagatecommand(...)
self:propagate(1);
self:playcommand(...);
self:propagate(0);
end
-- Shortcut for alignment.
-- cmd(align,0.5,0.5) -- align center
-- cmd(align,0.0,0.0) -- align top-left
-- cmd(align,0.5,0.0) -- align top-center
function Actor:align(h, v)
self:halign( h );
self:valign( v );
end
function Actor:FullScreen()
self:stretchto( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
end
--[[ Typical background sizes:
320x240 - DDR 1st-Extreme, most NVLM_ZK songs
640x480 - most simfiles in distribution today are this big.
768x480 - 16:10 aspect ratio backgrounds
854x480 - pump it up pro
]]
-- "Most backgrounds are 640x480. Some are 768x480. Stretch the 4:3 ones."
function Actor:scale_or_crop_background()
if (self:GetWidth() * 3) / 4 == self:GetHeight() then
self:stretchto( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
else
self:scaletocover( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT );
end
end
function Actor:Center()
self:x(SCREEN_CENTER_X)
self:y(SCREEN_CENTER_Y)
end
function Actor:bezier(...)
local a = {...}
local b = {}
local c = 0
assert((a == 9 or a == 5), "bad number of arguments for Actor:bezier()")
for i=3,c do
b[#b+1] = a[i]
end
self:tween(a[2], "TweenMode_Bezier", b)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+234 -234
View File
@@ -1,234 +1,234 @@
-- Convert "@/path/file" to "/path/".
local function DebugPathToRealPath( p )
if not p or p:sub( 1, 1 ) ~= "@" then
return nil
end
local Path = p:sub( 2 )
local pos = Path:find_last( '/' )
return string.sub( Path, 1, pos )
end
local function MergeTables( left, right )
local ret = { }
for key, val in pairs(left) do
ret[key] = val
end
for key, val in pairs(right) do
if ret[key] then
if type(val) == "function" and
type(ret[key]) == "function" then
local f1 = ret[key]
local f2 = val
val = function(...)
f1(...)
return f2(...)
end
else
Warn( string.format( "%s\n\nOverriding \"%s\": %s with %s",
debug.traceback(), key, type(ret[key]), type(val)) )
end
end
ret[key] = val
end
setmetatable( ret, getmetatable(left) )
return ret
end
DefMetatable = {
__concat = function(left, right)
return MergeTables( left, right )
end
}
-- This is used as follows:
--
-- t = Def.Class { table }
Def = {}
setmetatable( Def, {
__index = function(self, Class)
-- t is an actor definition table. name is the type
-- given to Def. Fill in standard fields.
return function(t)
if not ActorUtil.IsRegisteredClass(Class) then
error( Class .. " is not a registered actor class", 2 )
end
t.Class = Class
local level = 2
if t._Level then
level = t._Level + 1
end
local info = debug.getinfo(level,"Sl");
-- Source file of caller:
local Source = info.source
t._Source = Source
t._Dir = DebugPathToRealPath( Source )
-- Line number of caller:
t._Line = info.currentline
setmetatable( t, DefMetatable )
return t
end
end,
})
function ResolveRelativePath( path, level )
if path:sub(1,1) ~= "/" then
-- "Working directory":
local sDir = DebugPathToRealPath( debug.getinfo(level+1,"S").source )
assert( sDir )
path = sDir .. path
end
path = ActorUtil.ResolvePath( path, level+1 )
return path
end
-- Load an actor template.
function LoadActorFunc( path, level )
level = level or 1
if path == "" then
error( "Passing in a blank filename is a great way to eat up RAM. Good thing we warn you about this." )
end
local ResolvedPath = ResolveRelativePath( path, level+1 )
if not ResolvedPath then
error( path .. ": not found", level+1 )
end
path = ResolvedPath
local Type = ActorUtil.GetFileType( path )
Trace( "Loading " .. path .. ", type " .. tostring(Type) )
if Type == "FileType_Lua" then
-- Load the file.
local chunk, errmsg = loadfile( path )
if not chunk then error(errmsg) end
return chunk
end
if Type == "FileType_Bitmap" or Type == "FileType_Movie" then
return function()
return Def.Sprite {
_Level = level+1,
Texture = path
}
end
elseif Type == "FileType_Sound" then
return function()
return Def.Sound {
_Level = level+1,
File = path
}
end
elseif Type == "FileType_Model" then
return function()
return Def.Model {
_Level = level+1,
Meshes = path,
Materials = path,
Bones = path
}
end
elseif Type == "FileType_Directory" then
return function()
return Def.BGAnimation {
_Level = level+1,
AniDir = path
}
end
end
error( path .. ": unknown file type (" .. tostring(Type) .. ")", level+1 )
end
-- Load and create an actor template.
function LoadActor( path, ... )
local t = LoadActorFunc( path, 2 )
assert(t)
return t(...)
end
function LoadActorWithParams( path, params, ... )
local t = LoadActorFunc( path, 2 )
assert(t)
return lua.RunWithThreadVariables( function(...) return t(...) end, params, ... )
end
function LoadFont(a, b)
local sSection = b and a or ""
local sFile = b or a
if sFile == "" or not sFile then
sSection = "Common"
sFile = "normal"
end
local sPath = THEME:GetPathF(sSection, sFile)
return Def.BitmapText {
_Level = 2,
File = sPath
}
end
function WrapInActorFrame( t )
return Def.ActorFrame { children = t }
end
function StandardDecorationFromTable( MetricsName, t )
if type(t) == "table" then
t = t .. {
InitCommand=function(self)
self:name(MetricsName)
ActorUtil.LoadAllCommandsAndSetXY(self,Var "LoadingScreen")
end
}
end
return t
end
function StandardDecorationFromFile( MetricsName, FileName )
local t = LoadActor( THEME:GetPathG(Var "LoadingScreen",FileName) )
return StandardDecorationFromTable( MetricsName, t )
end
function StandardDecorationFromFileOptional( MetricsName, FileName )
if ShowStandardDecoration(MetricsName) then
return StandardDecorationFromFile( MetricsName, FileName )
end
end
function ShowStandardDecoration( MetricsName )
return THEME:GetMetric(Var "LoadingScreen","Show"..MetricsName)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Convert "@/path/file" to "/path/".
local function DebugPathToRealPath( p )
if not p or p:sub( 1, 1 ) ~= "@" then
return nil
end
local Path = p:sub( 2 )
local pos = Path:find_last( '/' )
return string.sub( Path, 1, pos )
end
local function MergeTables( left, right )
local ret = { }
for key, val in pairs(left) do
ret[key] = val
end
for key, val in pairs(right) do
if ret[key] then
if type(val) == "function" and
type(ret[key]) == "function" then
local f1 = ret[key]
local f2 = val
val = function(...)
f1(...)
return f2(...)
end
else
Warn( string.format( "%s\n\nOverriding \"%s\": %s with %s",
debug.traceback(), key, type(ret[key]), type(val)) )
end
end
ret[key] = val
end
setmetatable( ret, getmetatable(left) )
return ret
end
DefMetatable = {
__concat = function(left, right)
return MergeTables( left, right )
end
}
-- This is used as follows:
--
-- t = Def.Class { table }
Def = {}
setmetatable( Def, {
__index = function(self, Class)
-- t is an actor definition table. name is the type
-- given to Def. Fill in standard fields.
return function(t)
if not ActorUtil.IsRegisteredClass(Class) then
error( Class .. " is not a registered actor class", 2 )
end
t.Class = Class
local level = 2
if t._Level then
level = t._Level + 1
end
local info = debug.getinfo(level,"Sl");
-- Source file of caller:
local Source = info.source
t._Source = Source
t._Dir = DebugPathToRealPath( Source )
-- Line number of caller:
t._Line = info.currentline
setmetatable( t, DefMetatable )
return t
end
end,
})
function ResolveRelativePath( path, level )
if path:sub(1,1) ~= "/" then
-- "Working directory":
local sDir = DebugPathToRealPath( debug.getinfo(level+1,"S").source )
assert( sDir )
path = sDir .. path
end
path = ActorUtil.ResolvePath( path, level+1 )
return path
end
-- Load an actor template.
function LoadActorFunc( path, level )
level = level or 1
if path == "" then
error( "Passing in a blank filename is a great way to eat up RAM. Good thing we warn you about this." )
end
local ResolvedPath = ResolveRelativePath( path, level+1 )
if not ResolvedPath then
error( path .. ": not found", level+1 )
end
path = ResolvedPath
local Type = ActorUtil.GetFileType( path )
Trace( "Loading " .. path .. ", type " .. tostring(Type) )
if Type == "FileType_Lua" then
-- Load the file.
local chunk, errmsg = loadfile( path )
if not chunk then error(errmsg) end
return chunk
end
if Type == "FileType_Bitmap" or Type == "FileType_Movie" then
return function()
return Def.Sprite {
_Level = level+1,
Texture = path
}
end
elseif Type == "FileType_Sound" then
return function()
return Def.Sound {
_Level = level+1,
File = path
}
end
elseif Type == "FileType_Model" then
return function()
return Def.Model {
_Level = level+1,
Meshes = path,
Materials = path,
Bones = path
}
end
elseif Type == "FileType_Directory" then
return function()
return Def.BGAnimation {
_Level = level+1,
AniDir = path
}
end
end
error( path .. ": unknown file type (" .. tostring(Type) .. ")", level+1 )
end
-- Load and create an actor template.
function LoadActor( path, ... )
local t = LoadActorFunc( path, 2 )
assert(t)
return t(...)
end
function LoadActorWithParams( path, params, ... )
local t = LoadActorFunc( path, 2 )
assert(t)
return lua.RunWithThreadVariables( function(...) return t(...) end, params, ... )
end
function LoadFont(a, b)
local sSection = b and a or ""
local sFile = b or a
if sFile == "" or not sFile then
sSection = "Common"
sFile = "normal"
end
local sPath = THEME:GetPathF(sSection, sFile)
return Def.BitmapText {
_Level = 2,
File = sPath
}
end
function WrapInActorFrame( t )
return Def.ActorFrame { children = t }
end
function StandardDecorationFromTable( MetricsName, t )
if type(t) == "table" then
t = t .. {
InitCommand=function(self)
self:name(MetricsName)
ActorUtil.LoadAllCommandsAndSetXY(self,Var "LoadingScreen")
end
}
end
return t
end
function StandardDecorationFromFile( MetricsName, FileName )
local t = LoadActor( THEME:GetPathG(Var "LoadingScreen",FileName) )
return StandardDecorationFromTable( MetricsName, t )
end
function StandardDecorationFromFileOptional( MetricsName, FileName )
if ShowStandardDecoration(MetricsName) then
return StandardDecorationFromFile( MetricsName, FileName )
end
end
function ShowStandardDecoration( MetricsName )
return THEME:GetMetric(Var "LoadingScreen","Show"..MetricsName)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+195 -195
View File
@@ -1,195 +1,195 @@
--[[
[en] The Branch table replaces the various functions used for branching in the
StepMania 4 default theme.
Lines with a single string (e.g. TitleMenu = "ScreenTitleMenu") are referenced
in the metrics as Branch.keyname.
If the line is a function, you'll have to use Branch.keyname() instead.
--]]
-- used for various SMOnline-enabled screens:
function SMOnlineScreen()
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
if not IsSMOnlineLoggedIn(pn) then
return "ScreenSMOnlineLogin"
end
end
return "ScreenNetRoom"
end
function SelectMusicOrCourse()
if IsNetSMOnline() then
return "ScreenNetSelectMusic";
elseif GAMESTATE:IsCourseMode() then
return "ScreenSelectCourse"
else
return "ScreenSelectMusic"
end
end
-- functions used for Routine mode
function IsRoutine()
return GAMESTATE:GetCurrentStyle() and GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_TwoPlayersSharedSides";
end
Branch = {
Init = function()
if GAMESTATE:GetCoinMode() == 'CoinMode_Home' then
return "ScreenInit"
else
return "ScreenInit"
end
end,
AfterInit = function()
if GAMESTATE:GetCoinMode() == 'CoinMode_Home' then
return Branch.TitleMenu()
else
return "ScreenLogo"
end
end,
TitleMenu = function()
-- home mode is the most assumed use of sm-ssc.
if GAMESTATE:GetCoinMode() == "CoinMode_Home" then
return "ScreenTitleMenu"
end
-- arcade junk:
if GAMESTATE:GetCoinsNeededToJoin() > GAMESTATE:GetCoins() then
-- if no credits are inserted, don't show the Join screen. SM4 has
-- this as the initial screen, but that means we'd be stuck in a
-- loop with ScreenInit. No good.
return "ScreenTitleJoin"
else
return "ScreenTitleJoin"
end
end,
StartGame = function()
-- Check to see if there are 0 songs installed. Also make sure to check
-- that the additional song count is also 0, because there is
-- a possibility someone will use their existing StepMania simfile
-- collection with sm-ssc via AdditionalFolders/AdditionalSongFolders.
if SONGMAN:GetNumSongs() == 0 and SONGMAN:GetNumAdditionalSongs() == 0 then
return "ScreenHowToInstallSongs";
end;
return "ScreenSelectProfile";
end,
AfterProfileLoad = function()
return "ScreenSelectProfile"
end,
AfterSelectProfile = function()
if ( THEME:GetMetric("Common","AutoSetStyle") == true ) then
if IsNetConnected() then
-- use SelectStyle in online...
return "ScreenSelectStyle"
else
return "ScreenSelectPlayMode"
end
else
return "ScreenSelectStyle"
end
end,
AfterSelectPlayMode = function()
if IsNetConnected() then
ReportStyle()
GAMESTATE:ApplyGameCommand("playmode,regular")
end
if IsNetSMOnline() then
return SMOnlineScreen()
end
if IsNetConnected() then
return "ScreenNetRoom"
end
return "ScreenSelectPlayMode"
end,
AfterSelectStyle = function()
if CHARMAN:GetAllCharacters() ~= nil then
return "ScreenSelectCharacter"
else
return "ScreenGameInformation"
end
end,
AfterProfileSave = function()
-- Might be a little too broken? -- Midiman
if GAMESTATE:IsEventMode() then
return SelectMusicOrCourse()
elseif STATSMAN:GetCurStageStats():AllFailed() then
return "ScreenGameOver"
elseif GAMESTATE:GetSmallestNumStagesLeftForAnyHumanPlayer() == 0 then
return "ScreenEvaluationSummary"
else
return SelectMusicOrCourse()
end
end,
GetGameInformationScreen = function()
bTrue = PREFSMAN:GetPreference("ShowInstructions")
return (bTrue and GoToMusic() or "ScreenGameInformation")
end,
AfterSMOLogin = SMOnlineScreen(),
BackOutOfPlayerOptions = function()
return SelectMusicOrCourse()
end,
BackOutOfStageInformation = function()
return SelectMusicOrCourse()
end,
AfterSelectMusic = function()
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return SelectFirstOptionsScreen()
else
return "ScreenStageInformation"
end
end,
PlayerOptions = function()
local pm = GAMESTATE:GetPlayMode()
local restricted = { "PlayMode_Oni", "PlayMode_Rave",
--"PlayMode_Battle" -- ??
};
local optionsScreen = "ScreenPlayerOptions"
for i=1,#restricted do
if restricted[i] == pm then
optionsScreen = "ScreenPlayerOptionsRestricted"
end;
end
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return optionsScreen;
else
return "ScreenStageInformation";
end
end,
SongOptions = function()
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return "ScreenSongOptions"
else
return "ScreenStageInformation"
end
end,
GameplayScreen = function()
if IsRoutine() then
return "ScreenGameplayShared"
end
return "ScreenGameplay"
end,
AfterGameplay = function()
-- pick an evaluation screen based on settings.
if IsNetSMOnline() then
return "ScreenNetEvaluation"
else
-- todo: account for courses etc?
return "ScreenEvaluationNormal"
end
end,
AfterEvaluation = function()
if GAMESTATE:GetSmallestNumStagesLeftForAnyHumanPlayer() >= 1 then
return "ScreenProfileSave"
else
return "ScreenEvaluationSummary"
end
end,
AfterSummary = "ScreenProfileSaveSummary",
Network = function()
return IsNetConnected() and "ScreenTitleMenu" or "ScreenTitleMenu"
end,
QuickSetupStart = "ScreenQuickSetupOverview",
QuickSetupA = "ScreenQuickSetupPhaseOne",
QuickSetupB = "ScreenQuickSetupPhaseTwo",
QuickSetupC = "ScreenQuickSetupPhaseThree",
QuickSetupD = "ScreenQuickSetupPhaseFour",
QuickSetupFinished = "ScreenQuickSetupFinished"
}
--[[
[en] The Branch table replaces the various functions used for branching in the
StepMania 4 default theme.
Lines with a single string (e.g. TitleMenu = "ScreenTitleMenu") are referenced
in the metrics as Branch.keyname.
If the line is a function, you'll have to use Branch.keyname() instead.
--]]
-- used for various SMOnline-enabled screens:
function SMOnlineScreen()
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
if not IsSMOnlineLoggedIn(pn) then
return "ScreenSMOnlineLogin"
end
end
return "ScreenNetRoom"
end
function SelectMusicOrCourse()
if IsNetSMOnline() then
return "ScreenNetSelectMusic";
elseif GAMESTATE:IsCourseMode() then
return "ScreenSelectCourse"
else
return "ScreenSelectMusic"
end
end
-- functions used for Routine mode
function IsRoutine()
return GAMESTATE:GetCurrentStyle() and GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_TwoPlayersSharedSides";
end
Branch = {
Init = function()
if GAMESTATE:GetCoinMode() == 'CoinMode_Home' then
return "ScreenInit"
else
return "ScreenInit"
end
end,
AfterInit = function()
if GAMESTATE:GetCoinMode() == 'CoinMode_Home' then
return Branch.TitleMenu()
else
return "ScreenLogo"
end
end,
TitleMenu = function()
-- home mode is the most assumed use of sm-ssc.
if GAMESTATE:GetCoinMode() == "CoinMode_Home" then
return "ScreenTitleMenu"
end
-- arcade junk:
if GAMESTATE:GetCoinsNeededToJoin() > GAMESTATE:GetCoins() then
-- if no credits are inserted, don't show the Join screen. SM4 has
-- this as the initial screen, but that means we'd be stuck in a
-- loop with ScreenInit. No good.
return "ScreenTitleJoin"
else
return "ScreenTitleJoin"
end
end,
StartGame = function()
-- Check to see if there are 0 songs installed. Also make sure to check
-- that the additional song count is also 0, because there is
-- a possibility someone will use their existing StepMania simfile
-- collection with sm-ssc via AdditionalFolders/AdditionalSongFolders.
if SONGMAN:GetNumSongs() == 0 and SONGMAN:GetNumAdditionalSongs() == 0 then
return "ScreenHowToInstallSongs";
end;
return "ScreenSelectProfile";
end,
AfterProfileLoad = function()
return "ScreenSelectProfile"
end,
AfterSelectProfile = function()
if ( THEME:GetMetric("Common","AutoSetStyle") == true ) then
if IsNetConnected() then
-- use SelectStyle in online...
return "ScreenSelectStyle"
else
return "ScreenSelectPlayMode"
end
else
return "ScreenSelectStyle"
end
end,
AfterSelectPlayMode = function()
if IsNetConnected() then
ReportStyle()
GAMESTATE:ApplyGameCommand("playmode,regular")
end
if IsNetSMOnline() then
return SMOnlineScreen()
end
if IsNetConnected() then
return "ScreenNetRoom"
end
return "ScreenSelectPlayMode"
end,
AfterSelectStyle = function()
if CHARMAN:GetAllCharacters() ~= nil then
return "ScreenSelectCharacter"
else
return "ScreenGameInformation"
end
end,
AfterProfileSave = function()
-- Might be a little too broken? -- Midiman
if GAMESTATE:IsEventMode() then
return SelectMusicOrCourse()
elseif STATSMAN:GetCurStageStats():AllFailed() then
return "ScreenGameOver"
elseif GAMESTATE:GetSmallestNumStagesLeftForAnyHumanPlayer() == 0 then
return "ScreenEvaluationSummary"
else
return SelectMusicOrCourse()
end
end,
GetGameInformationScreen = function()
bTrue = PREFSMAN:GetPreference("ShowInstructions")
return (bTrue and GoToMusic() or "ScreenGameInformation")
end,
AfterSMOLogin = SMOnlineScreen(),
BackOutOfPlayerOptions = function()
return SelectMusicOrCourse()
end,
BackOutOfStageInformation = function()
return SelectMusicOrCourse()
end,
AfterSelectMusic = function()
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return SelectFirstOptionsScreen()
else
return "ScreenStageInformation"
end
end,
PlayerOptions = function()
local pm = GAMESTATE:GetPlayMode()
local restricted = { "PlayMode_Oni", "PlayMode_Rave",
--"PlayMode_Battle" -- ??
};
local optionsScreen = "ScreenPlayerOptions"
for i=1,#restricted do
if restricted[i] == pm then
optionsScreen = "ScreenPlayerOptionsRestricted"
end;
end
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return optionsScreen;
else
return "ScreenStageInformation";
end
end,
SongOptions = function()
if SCREENMAN:GetTopScreen():GetGoToOptions() then
return "ScreenSongOptions"
else
return "ScreenStageInformation"
end
end,
GameplayScreen = function()
if IsRoutine() then
return "ScreenGameplayShared"
end
return "ScreenGameplay"
end,
AfterGameplay = function()
-- pick an evaluation screen based on settings.
if IsNetSMOnline() then
return "ScreenNetEvaluation"
else
-- todo: account for courses etc?
return "ScreenEvaluationNormal"
end
end,
AfterEvaluation = function()
if GAMESTATE:GetSmallestNumStagesLeftForAnyHumanPlayer() >= 1 then
return "ScreenProfileSave"
else
return "ScreenEvaluationSummary"
end
end,
AfterSummary = "ScreenProfileSaveSummary",
Network = function()
return IsNetConnected() and "ScreenTitleMenu" or "ScreenTitleMenu"
end,
QuickSetupStart = "ScreenQuickSetupOverview",
QuickSetupA = "ScreenQuickSetupPhaseOne",
QuickSetupB = "ScreenQuickSetupPhaseTwo",
QuickSetupC = "ScreenQuickSetupPhaseThree",
QuickSetupD = "ScreenQuickSetupPhaseFour",
QuickSetupFinished = "ScreenQuickSetupFinished"
}
+179 -179
View File
@@ -1,180 +1,180 @@
-- SSC Color Module and Library
local nilColor = color("0,0,0,0")
-- Original Color Module.
Color = {
-- Color Library
-- These colors are pure swatch colors and are here purely to be used
-- on demand without having to type color("stuff") or dig through
-- a palette to get the color you want.
Black = color("0,0,0,1"),
White = color("1,1,1,1"),
Red = color("#ed1c24"),
Blue = color("#00aeef"),
Green = color("#39b54a"),
Yellow = color("#fff200"),
Orange = color("#f7941d"),
Purple = color("#92278f"),
Outline = color("0,0,0,0.5"),
Invisible = color("1,1,1,0"),
Stealth = nilColor,
-- Color Functions
-- These functions alter colors in a certain way so that you can make
-- new ones without having to copy a color or find a new one.
--[[ Brightness(fInput)
Hue(hInput)
Saturation(hInput)
Alpha(hInput)
HSV(iHue,fSaturation,fValue or any other overload) --]]
Alpha = function(cColor,fAlpha)
local c = cColor;
return { c[1],c[2],c[3],fAlpha };
end
}
-- Remapped Color Module, since some themes are crazy
Colors = Color;
GameColor = {
PlayerColors = {
PLAYER_1 = color("#ef403d"),
PLAYER_2 = color("#0089cf"),
},
Difficulty = {
--[[ These are for 'Custom' Difficulty Ranks. It can be very useful
in some cases, especially to apply new colors for stuff you
couldn't before. (huh? -aj) ]]
Beginner = color("#ff32f8"), -- light cyan
Easy = color("#2cff00"), -- green
Medium = color("#fee600"), -- yellow
Hard = color("#ff2f39"), -- red
Challenge = color("#1cd8ff"), -- light blue
Edit = color("0.8,0.8,0.8,1"), -- gray
Couple = color("#ed0972"), -- hot pink
Routine = color("#ff9a00"), -- orange
--[[ These are for courses, so let's slap them here in case someone
wanted to use Difficulty in Course and Step regions. ]]
Difficulty_Beginner = color("#ff32f8"), -- purple
Difficulty_Easy = color("#2cff00"), -- green
Difficulty_Medium = color("#fee600"), -- yellow
Difficulty_Hard = color("#ff2f39"), -- red
Difficulty_Challenge = color("#1cd8ff"), -- light blue
Difficulty_Edit = color("0.8,0.8,0.8,1"), -- gray
Difficulty_Couple = color("#ed0972"), -- hot pink
Difficulty_Routine = color("#ff9a00") -- orange
},
Stage = {
Stage_1st = color("#00ffc7"),
Stage_2nd = color("#58ff00"),
Stage_3rd = color("#f400ff"),
Stage_4th = color("#00ffda"),
Stage_5th = color("#ed00ff"),
Stage_6th = color("#73ff00"),
Stage_Next = color("#73ff00"),
Stage_Final = color("#ff0707"),
Stage_Extra1 = color("#fafa00"),
Stage_Extra2 = color("#ff0707"),
Stage_Nonstop = color("#FFFFFF"),
Stage_Oni = color("#FFFFFF"),
Stage_Endless = color("#FFFFFF"),
Stage_Event = color("#FFFFFF"),
Stage_Demo = color("#FFFFFF")
},
Judgment = {
JudgmentLine_W1 = color("#bfeaff"),
JudgmentLine_W2 = color("#fff568"),
JudgmentLine_W3 = color("#a4ff00"),
JudgmentLine_W4 = color("#34bfff"),
JudgmentLine_W5 = color("#e44dff"),
JudgmentLine_Held = color("#FFFFFF"),
JudgmentLine_Miss = color("#ff3c3c"),
JudgmentLine_MaxCombo = color("#ffc600")
},
};
GameColor.Difficulty["Crazy"] = GameColor.Difficulty["Hard"];
GameColor.Difficulty["Freestyle"] = GameColor.Difficulty["Easy"];
GameColor.Difficulty["Nightmare"] = GameColor.Difficulty["Challenge"];
GameColor.Difficulty["HalfDouble"] = GameColor.Difficulty["Medium"];
--[[ Fallbacks ]]
function Color(c)
return Colors[c]
end
function BoostColor( cColor, fBoost )
local c = cColor
return { c[1]*fBoost, c[2]*fBoost, c[3]*fBoost, c[4] }
end
function ColorLightTone(c)
return { c[1]+(c[1]/2), c[2]+(c[2]/2), c[3]+(c[3]/2), c[4] }
end
function ColorMidTone(c)
return { c[1]/1.5, c[2]/1.5, c[3]/1.5, c[4] }
end
function ColorDarkTone(c)
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function PlayerColor( pn )
if pn == PLAYER_1 then
return color("#ef403d") -- pink-red
end
if pn == PLAYER_2 then
return color("#0089cf") -- sea-blue
end
return color("1,1,1,1")
end
function PlayerScoreColor( pn )
if pn == PLAYER_1 then
return color("#ef403d") -- pink-red
end
if pn == PLAYER_2 then
return color("#0089cf") -- sea-blue
end
return color("1,1,1,1")
end
function CustomDifficultyToColor( sCustomDifficulty )
return GameColor.Difficulty[sCustomDifficulty]
end
function CustomDifficultyToDarkColor( sCustomDifficulty )
local c = GameColor.Difficulty[sCustomDifficulty]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function CustomDifficultyToLightColor( sCustomDifficulty )
local c = GameColor.Difficulty[sCustomDifficulty]
return { scale(c[1],0,1,0.5,1), scale(c[2],0,1,0.5,1), scale(c[3],0,1,0.5,1), c[4] }
end
function StepsOrTrailToColor(StepsOrTrail)
return CustomDifficultyToColor( StepsOrTrailToCustomDifficulty(stepsOrTrail) )
end
function StageToColor( stage )
local c = GameColor.Stage[stage]
if c then
return c
end
return color("#000000")
end
function StageToStrokeColor( stage )
local c = GameColor.Stage[stage]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function JudgmentLineToColor( i )
local c = GameColor.Judgment[i]
if c then
return c
end
return color("#000000")
end
function JudgmentLineToStrokeColor( i )
local c = GameColor.Judgment[i]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
-- SSC Color Module and Library
local nilColor = color("0,0,0,0")
-- Original Color Module.
Color = {
-- Color Library
-- These colors are pure swatch colors and are here purely to be used
-- on demand without having to type color("stuff") or dig through
-- a palette to get the color you want.
Black = color("0,0,0,1"),
White = color("1,1,1,1"),
Red = color("#ed1c24"),
Blue = color("#00aeef"),
Green = color("#39b54a"),
Yellow = color("#fff200"),
Orange = color("#f7941d"),
Purple = color("#92278f"),
Outline = color("0,0,0,0.5"),
Invisible = color("1,1,1,0"),
Stealth = nilColor,
-- Color Functions
-- These functions alter colors in a certain way so that you can make
-- new ones without having to copy a color or find a new one.
--[[ Brightness(fInput)
Hue(hInput)
Saturation(hInput)
Alpha(hInput)
HSV(iHue,fSaturation,fValue or any other overload) --]]
Alpha = function(cColor,fAlpha)
local c = cColor;
return { c[1],c[2],c[3],fAlpha };
end
}
-- Remapped Color Module, since some themes are crazy
Colors = Color;
GameColor = {
PlayerColors = {
PLAYER_1 = color("#ef403d"),
PLAYER_2 = color("#0089cf"),
},
Difficulty = {
--[[ These are for 'Custom' Difficulty Ranks. It can be very useful
in some cases, especially to apply new colors for stuff you
couldn't before. (huh? -aj) ]]
Beginner = color("#ff32f8"), -- light cyan
Easy = color("#2cff00"), -- green
Medium = color("#fee600"), -- yellow
Hard = color("#ff2f39"), -- red
Challenge = color("#1cd8ff"), -- light blue
Edit = color("0.8,0.8,0.8,1"), -- gray
Couple = color("#ed0972"), -- hot pink
Routine = color("#ff9a00"), -- orange
--[[ These are for courses, so let's slap them here in case someone
wanted to use Difficulty in Course and Step regions. ]]
Difficulty_Beginner = color("#ff32f8"), -- purple
Difficulty_Easy = color("#2cff00"), -- green
Difficulty_Medium = color("#fee600"), -- yellow
Difficulty_Hard = color("#ff2f39"), -- red
Difficulty_Challenge = color("#1cd8ff"), -- light blue
Difficulty_Edit = color("0.8,0.8,0.8,1"), -- gray
Difficulty_Couple = color("#ed0972"), -- hot pink
Difficulty_Routine = color("#ff9a00") -- orange
},
Stage = {
Stage_1st = color("#00ffc7"),
Stage_2nd = color("#58ff00"),
Stage_3rd = color("#f400ff"),
Stage_4th = color("#00ffda"),
Stage_5th = color("#ed00ff"),
Stage_6th = color("#73ff00"),
Stage_Next = color("#73ff00"),
Stage_Final = color("#ff0707"),
Stage_Extra1 = color("#fafa00"),
Stage_Extra2 = color("#ff0707"),
Stage_Nonstop = color("#FFFFFF"),
Stage_Oni = color("#FFFFFF"),
Stage_Endless = color("#FFFFFF"),
Stage_Event = color("#FFFFFF"),
Stage_Demo = color("#FFFFFF")
},
Judgment = {
JudgmentLine_W1 = color("#bfeaff"),
JudgmentLine_W2 = color("#fff568"),
JudgmentLine_W3 = color("#a4ff00"),
JudgmentLine_W4 = color("#34bfff"),
JudgmentLine_W5 = color("#e44dff"),
JudgmentLine_Held = color("#FFFFFF"),
JudgmentLine_Miss = color("#ff3c3c"),
JudgmentLine_MaxCombo = color("#ffc600")
},
};
GameColor.Difficulty["Crazy"] = GameColor.Difficulty["Hard"];
GameColor.Difficulty["Freestyle"] = GameColor.Difficulty["Easy"];
GameColor.Difficulty["Nightmare"] = GameColor.Difficulty["Challenge"];
GameColor.Difficulty["HalfDouble"] = GameColor.Difficulty["Medium"];
--[[ Fallbacks ]]
function Color(c)
return Colors[c]
end
function BoostColor( cColor, fBoost )
local c = cColor
return { c[1]*fBoost, c[2]*fBoost, c[3]*fBoost, c[4] }
end
function ColorLightTone(c)
return { c[1]+(c[1]/2), c[2]+(c[2]/2), c[3]+(c[3]/2), c[4] }
end
function ColorMidTone(c)
return { c[1]/1.5, c[2]/1.5, c[3]/1.5, c[4] }
end
function ColorDarkTone(c)
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function PlayerColor( pn )
if pn == PLAYER_1 then
return color("#ef403d") -- pink-red
end
if pn == PLAYER_2 then
return color("#0089cf") -- sea-blue
end
return color("1,1,1,1")
end
function PlayerScoreColor( pn )
if pn == PLAYER_1 then
return color("#ef403d") -- pink-red
end
if pn == PLAYER_2 then
return color("#0089cf") -- sea-blue
end
return color("1,1,1,1")
end
function CustomDifficultyToColor( sCustomDifficulty )
return GameColor.Difficulty[sCustomDifficulty]
end
function CustomDifficultyToDarkColor( sCustomDifficulty )
local c = GameColor.Difficulty[sCustomDifficulty]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function CustomDifficultyToLightColor( sCustomDifficulty )
local c = GameColor.Difficulty[sCustomDifficulty]
return { scale(c[1],0,1,0.5,1), scale(c[2],0,1,0.5,1), scale(c[3],0,1,0.5,1), c[4] }
end
function StepsOrTrailToColor(StepsOrTrail)
return CustomDifficultyToColor( StepsOrTrailToCustomDifficulty(stepsOrTrail) )
end
function StageToColor( stage )
local c = GameColor.Stage[stage]
if c then
return c
end
return color("#000000")
end
function StageToStrokeColor( stage )
local c = GameColor.Stage[stage]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
function JudgmentLineToColor( i )
local c = GameColor.Judgment[i]
if c then
return c
end
return color("#000000")
end
function JudgmentLineToStrokeColor( i )
local c = GameColor.Judgment[i]
return { c[1]/2, c[2]/2, c[3]/2, c[4] }
end
+97 -97
View File
@@ -1,97 +1,97 @@
if not debug then
-- stubs
debug = {}
debug.traceback = function() return "" end
return
end
-- Override debug.traceback.
function debug.traceback(...)
local thread = coroutine.running()
local msg = ""
local level = 1
local args = {...}
if type(args[1]) == "thread" then
thread = args[1]
table.remove(args)
end
if type(args[1]) == "string" then
msg = args[1]
table.remove(args)
end
if type(args[1]) == "number" then
level = args[1]
table.remove(args)
end
if thread == coroutine.running() then
level = level + 1 -- skip this function
end
local stack = {}
repeat
local info = debug.getinfo(level, "Sln")
table.insert( stack, info )
level = level + 1
until not info
if #stack == 0 then
return ""
end
-- The original caller is usually C; remove it.
if( stack[#stack].what == "C" ) then
table.remove( stack )
end
local function FormatFrame(level, frame)
local sFrameInfo = ""
sFrameInfo = sFrameInfo .. "#" .. level .. " "
if( frame.what == "tail" ) then
-- sFrameInfo = sFrameInfo .. "(tail call)"
-- return sFrameInfo
elseif( frame.what == "main" ) then
sFrameInfo = sFrameInfo .. "main in "
elseif frame.name then
sFrameInfo = sFrameInfo .. frame.name .. "() in "
else
sFrameInfo = sFrameInfo .. "... in "
end
sFrameInfo = sFrameInfo .. frame.short_src
if frame.currentline ~= -1 then
sFrameInfo = sFrameInfo .. ":" .. frame.currentline
end
return sFrameInfo
end
local FrameInfo = {}
for level, frame in ipairs(stack) do
FrameInfo[level] = FormatFrame(level, frame)
end
return table.concat( FrameInfo, "\n" )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
if not debug then
-- stubs
debug = {}
debug.traceback = function() return "" end
return
end
-- Override debug.traceback.
function debug.traceback(...)
local thread = coroutine.running()
local msg = ""
local level = 1
local args = {...}
if type(args[1]) == "thread" then
thread = args[1]
table.remove(args)
end
if type(args[1]) == "string" then
msg = args[1]
table.remove(args)
end
if type(args[1]) == "number" then
level = args[1]
table.remove(args)
end
if thread == coroutine.running() then
level = level + 1 -- skip this function
end
local stack = {}
repeat
local info = debug.getinfo(level, "Sln")
table.insert( stack, info )
level = level + 1
until not info
if #stack == 0 then
return ""
end
-- The original caller is usually C; remove it.
if( stack[#stack].what == "C" ) then
table.remove( stack )
end
local function FormatFrame(level, frame)
local sFrameInfo = ""
sFrameInfo = sFrameInfo .. "#" .. level .. " "
if( frame.what == "tail" ) then
-- sFrameInfo = sFrameInfo .. "(tail call)"
-- return sFrameInfo
elseif( frame.what == "main" ) then
sFrameInfo = sFrameInfo .. "main in "
elseif frame.name then
sFrameInfo = sFrameInfo .. frame.name .. "() in "
else
sFrameInfo = sFrameInfo .. "... in "
end
sFrameInfo = sFrameInfo .. frame.short_src
if frame.currentline ~= -1 then
sFrameInfo = sFrameInfo .. ":" .. frame.currentline
end
return sFrameInfo
end
local FrameInfo = {}
for level, frame in ipairs(stack) do
FrameInfo[level] = FormatFrame(level, frame)
end
return table.concat( FrameInfo, "\n" )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+50 -50
View File
@@ -1,50 +1,50 @@
function Enum:Compare( e1, e2 )
local Reverse = self:Reverse()
local Value1 = Reverse[e1]
local Value2 = Reverse[e2]
assert( Value1, tostring(e1) .. " is not an enum of type " .. self:GetName() )
assert( Value2, tostring(e2) .. " is not an enum of type " .. self:GetName() )
-- Nil enums correspond to "invalid". These compare greater
-- than any valid enum value, to line up with the equivalent
-- C++ code.
-- should this be changed to math.huge()? -shake
if not e1 then
Value1 = 99999999
end
if not e2 then
Value2 = 99999999
end
return Value1 - Value2
end
function ToEnumShortString( e )
local pos = string.find( e, '_' )
assert( pos, "'" .. e .. "' is not an enum value" )
return string.sub( e, pos+1 )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
function Enum:Compare( e1, e2 )
local Reverse = self:Reverse()
local Value1 = Reverse[e1]
local Value2 = Reverse[e2]
assert( Value1, tostring(e1) .. " is not an enum of type " .. self:GetName() )
assert( Value2, tostring(e2) .. " is not an enum of type " .. self:GetName() )
-- Nil enums correspond to "invalid". These compare greater
-- than any valid enum value, to line up with the equivalent
-- C++ code.
-- should this be changed to math.huge()? -shake
if not e1 then
Value1 = 99999999
end
if not e2 then
Value2 = 99999999
end
return Value1 - Value2
end
function ToEnumShortString( e )
local pos = string.find( e, '_' )
assert( pos, "'" .. e .. "' is not an enum value" )
return string.sub( e, pos+1 )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+39 -39
View File
@@ -1,39 +1,39 @@
function HelpDisplay:setfromsongorcourse()
local Artists = {}
local AltArtists = {}
local Song = GAMESTATE:GetCurrentSong()
local Trail = GAMESTATE:GetCurrentTrail( GAMESTATE:GetMasterPlayerNumber() )
if Song then
table.insert( Artists, Song:GetDisplayArtist() )
table.insert( AltArtists, Song:GetTranslitArtist() )
elseif Trail then
Artists, AltArtists = Trail:GetArtists()
end
self:settips( Artists, AltArtists )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
function HelpDisplay:setfromsongorcourse()
local Artists = {}
local AltArtists = {}
local Song = GAMESTATE:GetCurrentSong()
local Trail = GAMESTATE:GetCurrentTrail( GAMESTATE:GetMasterPlayerNumber() )
if Song then
table.insert( Artists, Song:GetDisplayArtist() )
table.insert( AltArtists, Song:GetTranslitArtist() )
elseif Trail then
Artists, AltArtists = Trail:GetArtists()
end
self:settips( Artists, AltArtists )
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+70 -70
View File
@@ -1,70 +1,70 @@
function Actor:LyricCommand(side)
self:settext( Var "LyricText" )
self:stoptweening()
self:shadowlengthx(0)
self:shadowlengthy(5)
self:strokecolor(color("#000000"))
local Zoom = SCREEN_WIDTH / (self:GetZoomedWidth()+1)
if( Zoom > 1 ) then
Zoom = 1
end
self:zoomx( Zoom )
local lyricColor = Var "LyricColor"
local Factor = 1
if side == "Back" then
Factor = 0.5
elseif side == "Front" then
Factor = 0.9
end
self:diffuse( {
lyricColor[1] * Factor,
lyricColor[2] * Factor,
lyricColor[3] * Factor,
lyricColor[4] * Factor } )
if side == "Front" then
self:cropright(1)
else
self:cropleft(0)
end
self:diffusealpha(0)
self:linear(0.2)
self:diffusealpha(0.75)
self:linear( Var "LyricDuration" * 0.75)
if side == "Front" then
self:cropright(0)
else
self:cropleft(1)
end
self:sleep( Var "LyricDuration" * 0.25 )
self:linear(0.2)
self:diffusealpha(0)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
function Actor:LyricCommand(side)
self:settext( Var "LyricText" )
self:stoptweening()
self:shadowlengthx(0)
self:shadowlengthy(5)
self:strokecolor(color("#000000"))
local Zoom = SCREEN_WIDTH / (self:GetZoomedWidth()+1)
if( Zoom > 1 ) then
Zoom = 1
end
self:zoomx( Zoom )
local lyricColor = Var "LyricColor"
local Factor = 1
if side == "Back" then
Factor = 0.5
elseif side == "Front" then
Factor = 0.9
end
self:diffuse( {
lyricColor[1] * Factor,
lyricColor[2] * Factor,
lyricColor[3] * Factor,
lyricColor[4] * Factor } )
if side == "Front" then
self:cropright(1)
else
self:cropleft(0)
end
self:diffusealpha(0)
self:linear(0.2)
self:diffusealpha(0.75)
self:linear( Var "LyricDuration" * 0.75)
if side == "Front" then
self:cropright(0)
else
self:cropleft(1)
end
self:sleep( Var "LyricDuration" * 0.25 )
self:linear(0.2)
self:diffusealpha(0)
end
-- (c) 2006 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+120 -120
View File
@@ -1,120 +1,120 @@
-- Sample options menu item.
function OptionsRowTest()
local function Set(self,list,pn)
if list[1] then
Trace("FOO: 1")
end
if list[2] then
Trace("FOO: 2")
end
end
return
{
-- Name is used to retrieve the header and explanation text.
Name = "Foo",
-- Flags for this row. Note that as this table only defines
-- a row, not a menu, only row settings can be set here, not
-- OptionMenuFlags.
LayoutType = "ShowAllInRow",
SelectType = "SelectMultiple",
OneChoiceForAllPlayers = false,
ExportOnChange = false,
-- Choices are not resolved as metrics, since they might
-- be dynamic. Add THEME Lua hooks if we want to translate
-- these.
Choices = { "Option1", "Option2" },
-- Or:
-- for i = 1,20 do Choices[i] = "Option " .. i end
-- Set list[1] to true if Option1 should be selected, and
-- list[2] if Option2 should be selected. This will be
-- called once per enabled player.
LoadSelections = function(self,list,pn)
list[1] = true
end,
SaveSelections = Set
}
end
-- This option row loads and saves the results to a table. For example, if you
-- have options "fast" and "slow", and the name of the option is "run", then the
-- table will be set to table["run"] = "fast" (or "slow"), and loaded appropriately.
-- (This could handle SelectMultiple, by saving the result to a table, eg.
-- table["run"]["fast"] = true.)
OptionRowTable =
{
SaveTo = nil, -- set this
Default = nil, -- set this
LoadSelections = function(self, list, pn)
local Sort = self.SaveTo[self.Name] or self.Default
-- Find the index of the current sort.
local Index = FindValue(self.RawChoices, Sort) or 1
list[Index] = true
end,
SaveSelections = function(self, list, pn)
local Selection = FindSelection( list )
self.SaveTo[self.Name] = self.RawChoices[Selection]
end
}
function OptionsRandomJukebox()
local function AllChoices()
Trace('all choices')
local ret = { 'Off', 'Random' }
return ret
end
local t =
{
-- Name is used to retrieve the header and explanation text.
Name = "OptionsRandomJukebox",
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = true,
ExportOnChange = false,
Choices = AllChoices(),
LoadSelections = function(self, list, pn)
list[1] = true
end,
SaveSelections = function(self, list, pn)
local val
if list[1] then
val = false
else
val = true
end
GAMESTATE:SetJukeboxUsesModifiers(val)
end
}
setmetatable( t, t )
return t
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Sample options menu item.
function OptionsRowTest()
local function Set(self,list,pn)
if list[1] then
Trace("FOO: 1")
end
if list[2] then
Trace("FOO: 2")
end
end
return
{
-- Name is used to retrieve the header and explanation text.
Name = "Foo",
-- Flags for this row. Note that as this table only defines
-- a row, not a menu, only row settings can be set here, not
-- OptionMenuFlags.
LayoutType = "ShowAllInRow",
SelectType = "SelectMultiple",
OneChoiceForAllPlayers = false,
ExportOnChange = false,
-- Choices are not resolved as metrics, since they might
-- be dynamic. Add THEME Lua hooks if we want to translate
-- these.
Choices = { "Option1", "Option2" },
-- Or:
-- for i = 1,20 do Choices[i] = "Option " .. i end
-- Set list[1] to true if Option1 should be selected, and
-- list[2] if Option2 should be selected. This will be
-- called once per enabled player.
LoadSelections = function(self,list,pn)
list[1] = true
end,
SaveSelections = Set
}
end
-- This option row loads and saves the results to a table. For example, if you
-- have options "fast" and "slow", and the name of the option is "run", then the
-- table will be set to table["run"] = "fast" (or "slow"), and loaded appropriately.
-- (This could handle SelectMultiple, by saving the result to a table, eg.
-- table["run"]["fast"] = true.)
OptionRowTable =
{
SaveTo = nil, -- set this
Default = nil, -- set this
LoadSelections = function(self, list, pn)
local Sort = self.SaveTo[self.Name] or self.Default
-- Find the index of the current sort.
local Index = FindValue(self.RawChoices, Sort) or 1
list[Index] = true
end,
SaveSelections = function(self, list, pn)
local Selection = FindSelection( list )
self.SaveTo[self.Name] = self.RawChoices[Selection]
end
}
function OptionsRandomJukebox()
local function AllChoices()
Trace('all choices')
local ret = { 'Off', 'Random' }
return ret
end
local t =
{
-- Name is used to retrieve the header and explanation text.
Name = "OptionsRandomJukebox",
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = true,
ExportOnChange = false,
Choices = AllChoices(),
LoadSelections = function(self, list, pn)
list[1] = true
end,
SaveSelections = function(self, list, pn)
local val
if list[1] then
val = false
else
val = true
end
GAMESTATE:SetJukeboxUsesModifiers(val)
end
}
setmetatable( t, t )
return t
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+150 -150
View File
@@ -1,150 +1,150 @@
local g_metrics_group = nil;
local g_element = nil;
SSC = (ProductID() == "sm-ssc");
function LoadFallbackB()
-- Load the fallback BGA for the element that is currently being loaded.
-- The fallback metrics group and element name will come either from LuaThreadVars
-- (loading from C++) or from the Lua globals above (loading from Lua).
--Warn( "g_element " .. (g_element or "") );
--Warn( "MatchingElement " .. (Var 'MatchingElement' or "") );
--Warn( "g_metrics_group " .. (g_metrics_group or "") );
--Warn( "MatchingMetricsGroup " .. (Var 'MatchingMetricsGroup' or "") );
local metrics_group = g_metrics_group or Var 'MatchingMetricsGroup';
local element = g_element or Var 'MatchingElement';
local fallback = THEME:GetMetric(metrics_group,'Fallback');
local old_metrics_group = g_metrics_group;
local old_element = g_element;
local path;
path, g_metrics_group, g_element = THEME:GetPathInfoB(fallback,element);
--Trace('path ' .. path );
local t = LoadActor( path );
g_metrics_group = old_metrics_group;
g_element = old_element;
return t;
end
function FormatNumSongsPlayed( num )
local s = num..' song';
if s == 1 then
s = s .. ' ';
else
s = s .. 's';
end
return s..' played';
end
function JudgmentTransformCommand( self, params )
local x = 0
local y = -30
if params.bReverse then y = y * -1 end
-- This makes no sense and wasn't even being used due to misspelling.
-- if bCentered then y = y * 2 end
self:x( x )
self:y( y )
end
function JudgmentTransformSharedCommand( self, params )
local x = -120
local y = -30
if params.bReverse then y = 30 end
if params.Player == PLAYER_1 then x = 120 end
self:x( x )
self:y( y )
end
function ComboTransformCommand( self, params )
local x = 0
local y = 30
if params.bReverse then y = y * -1 end
if params.bCentered then
if params.bReverse then
y = y - 30
else
y = y + 40
end
end
self:x( x )
self:y( y )
end
function GetEditModeSubScreens()
return
"ScreenMiniMenuEditHelp," ..
"ScreenMiniMenuMainMenu," ..
"ScreenMiniMenuAreaMenu," ..
"ScreenMiniMenuStepsInformation," ..
"ScreenMiniMenuSongInformation," ..
"ScreenMiniMenuBackgroundChange," ..
"ScreenMiniMenuInsertTapAttack," ..
"ScreenMiniMenuInsertCourseAttack," ..
"ScreenMiniMenuCourseDisplay," ..
"ScreenEditOptions";
end
function GetCoursesToShowRanking()
local CoursesToShowRanking = PREFSMAN:GetPreference("CoursesToShowRanking")
if CoursesToShowRanking ~= "" then return CoursesToShowRanking end
return "Courses/Default/MostPlayed_01-04.crs,Courses/Default/MostPlayed_05-08.crs,Courses/Default/MostPlayed_09-12.crs"
end
-- Get a metric from the currently-loading screen. This is only valid while loading
-- an actor, such as from File or InitCommand attributes; not from commands.
Screen = {
Metric = function ( sName )
local sClass = Var "LoadingScreen"
return THEME:GetMetric( sClass, sName )
end,
String = function ( sName )
local sClass = Var "LoadingScreen";
return THEME:GetString( sClass, sName )
end
};
function TextBannerAfterSet(self,param)
local Title=self:GetChild("Title");
local Subtitle=self:GetChild("Subtitle");
--local Artist=self:GetChild("Artist");
if Subtitle:GetText() == "" then
(cmd(maxwidth,208;y,0;zoom,1.0;))(Title);
(cmd(visible,false))(Subtitle);
--(cmd(zoom,0.66;maxwidth,300;y,7))(Artist);
else
-- subtitle below
(cmd(zoom,1;y,-6;zoom,0.9;))(Title);
(cmd(visible,true;zoom,0.6;y,7))(Subtitle);
--(cmd(zoom,0.66;maxwidth,300;y,9))(Artist);
end
end
-- (c) 2005 Chris Danford
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
local g_metrics_group = nil;
local g_element = nil;
SSC = (ProductID() == "sm-ssc");
function LoadFallbackB()
-- Load the fallback BGA for the element that is currently being loaded.
-- The fallback metrics group and element name will come either from LuaThreadVars
-- (loading from C++) or from the Lua globals above (loading from Lua).
--Warn( "g_element " .. (g_element or "") );
--Warn( "MatchingElement " .. (Var 'MatchingElement' or "") );
--Warn( "g_metrics_group " .. (g_metrics_group or "") );
--Warn( "MatchingMetricsGroup " .. (Var 'MatchingMetricsGroup' or "") );
local metrics_group = g_metrics_group or Var 'MatchingMetricsGroup';
local element = g_element or Var 'MatchingElement';
local fallback = THEME:GetMetric(metrics_group,'Fallback');
local old_metrics_group = g_metrics_group;
local old_element = g_element;
local path;
path, g_metrics_group, g_element = THEME:GetPathInfoB(fallback,element);
--Trace('path ' .. path );
local t = LoadActor( path );
g_metrics_group = old_metrics_group;
g_element = old_element;
return t;
end
function FormatNumSongsPlayed( num )
local s = num..' song';
if s == 1 then
s = s .. ' ';
else
s = s .. 's';
end
return s..' played';
end
function JudgmentTransformCommand( self, params )
local x = 0
local y = -30
if params.bReverse then y = y * -1 end
-- This makes no sense and wasn't even being used due to misspelling.
-- if bCentered then y = y * 2 end
self:x( x )
self:y( y )
end
function JudgmentTransformSharedCommand( self, params )
local x = -120
local y = -30
if params.bReverse then y = 30 end
if params.Player == PLAYER_1 then x = 120 end
self:x( x )
self:y( y )
end
function ComboTransformCommand( self, params )
local x = 0
local y = 30
if params.bReverse then y = y * -1 end
if params.bCentered then
if params.bReverse then
y = y - 30
else
y = y + 40
end
end
self:x( x )
self:y( y )
end
function GetEditModeSubScreens()
return
"ScreenMiniMenuEditHelp," ..
"ScreenMiniMenuMainMenu," ..
"ScreenMiniMenuAreaMenu," ..
"ScreenMiniMenuStepsInformation," ..
"ScreenMiniMenuSongInformation," ..
"ScreenMiniMenuBackgroundChange," ..
"ScreenMiniMenuInsertTapAttack," ..
"ScreenMiniMenuInsertCourseAttack," ..
"ScreenMiniMenuCourseDisplay," ..
"ScreenEditOptions";
end
function GetCoursesToShowRanking()
local CoursesToShowRanking = PREFSMAN:GetPreference("CoursesToShowRanking")
if CoursesToShowRanking ~= "" then return CoursesToShowRanking end
return "Courses/Default/MostPlayed_01-04.crs,Courses/Default/MostPlayed_05-08.crs,Courses/Default/MostPlayed_09-12.crs"
end
-- Get a metric from the currently-loading screen. This is only valid while loading
-- an actor, such as from File or InitCommand attributes; not from commands.
Screen = {
Metric = function ( sName )
local sClass = Var "LoadingScreen"
return THEME:GetMetric( sClass, sName )
end,
String = function ( sName )
local sClass = Var "LoadingScreen";
return THEME:GetString( sClass, sName )
end
};
function TextBannerAfterSet(self,param)
local Title=self:GetChild("Title");
local Subtitle=self:GetChild("Subtitle");
--local Artist=self:GetChild("Artist");
if Subtitle:GetText() == "" then
(cmd(maxwidth,208;y,0;zoom,1.0;))(Title);
(cmd(visible,false))(Subtitle);
--(cmd(zoom,0.66;maxwidth,300;y,7))(Artist);
else
-- subtitle below
(cmd(zoom,1;y,-6;zoom,0.9;))(Title);
(cmd(visible,true;zoom,0.6;y,7))(Subtitle);
--(cmd(zoom,0.66;maxwidth,300;y,9))(Artist);
end
end
-- (c) 2005 Chris Danford
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+119 -119
View File
@@ -1,119 +1,119 @@
-- Serialize the table "t".
function Serialize(t)
local ret = ""
local queue = { }
local already_queued = { }
-- Convert a value to an identifier. If we encounter a table that we've never seen before,
-- it's an anonymous table and we'll create a name for it; for example, in t = { [ {10} ] = 1 },
-- "{10}" has no name.
local next_id = 1
local function convert_to_identifier( v, name )
-- print("convert_to_identifier: " .. (name or "nil"))
if type(v) == "string" then
return string.format("%q", v)
elseif type(v) == "nil" then
return "nil"
elseif type(v) == "boolean" then
if v then return "true" end
return "false"
elseif type(v) == "number" then
return string.format("%i", v)
elseif type(v) == "table" then
if already_queued[v] then
return already_queued[v]
end
-- Create the table. If we have no name, give it one; be sure to make it local.
if not name then
name = "tab" .. next_id
next_id = next_id + 1
ret = ret .. "local " .. name .. " = { }\n"
else
-- The name is probably something like "x[1][2][3]", so don't emit "local".
ret = ret .. name .. " = { }\n"
end
for i, tab in pairs(v) do
local to_fill = { ["name"] = name .. "[" .. convert_to_identifier(i) .. "]", with = tab }
table.insert( queue, to_fill )
end
already_queued[v] = name
return name
else
return '"UNSUPPORTED TYPE (' .. type(v) .. ')"', true
end
end
local top_name = convert_to_identifier( t )
while table.getn(queue) > 0 do
local to_fill = table.remove( queue, 1 )
local str = convert_to_identifier( to_fill.with, to_fill.name )
-- Assign the result. If to_fill.with is a non-anonymous table, we just created
-- it ("ret[1] = { }"); don't redundantly write "ret[1] = ret[1]".
if to_fill.name ~= str then
ret = ret .. to_fill.name .. " = " .. str .. "\n"
end
end
ret = ret .. "return " .. top_name
return ret
end
-- Recursively deep-copy a table.
function DeepCopy(From, To, already_copied)
if not To then To = {} end
already_copied = already_copied or { }
already_copied[From] = To
for a, b in pairs(From) do
local aCopy, bCopy
if type(a) ~= "table" then
aCopy = a
elseif already_copied[a] then
aCopy = already_copied[a]
else
aCopy = {}
DeepCopy( a, aCopy, already_copied )
end
if type(b) ~= "table" then
bCopy = b
elseif already_copied[b] then
bCopy = already_copied[b]
else
bCopy = {}
DeepCopy( b, bCopy, already_copied )
end
To[aCopy] = bCopy
end
return To
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Serialize the table "t".
function Serialize(t)
local ret = ""
local queue = { }
local already_queued = { }
-- Convert a value to an identifier. If we encounter a table that we've never seen before,
-- it's an anonymous table and we'll create a name for it; for example, in t = { [ {10} ] = 1 },
-- "{10}" has no name.
local next_id = 1
local function convert_to_identifier( v, name )
-- print("convert_to_identifier: " .. (name or "nil"))
if type(v) == "string" then
return string.format("%q", v)
elseif type(v) == "nil" then
return "nil"
elseif type(v) == "boolean" then
if v then return "true" end
return "false"
elseif type(v) == "number" then
return string.format("%i", v)
elseif type(v) == "table" then
if already_queued[v] then
return already_queued[v]
end
-- Create the table. If we have no name, give it one; be sure to make it local.
if not name then
name = "tab" .. next_id
next_id = next_id + 1
ret = ret .. "local " .. name .. " = { }\n"
else
-- The name is probably something like "x[1][2][3]", so don't emit "local".
ret = ret .. name .. " = { }\n"
end
for i, tab in pairs(v) do
local to_fill = { ["name"] = name .. "[" .. convert_to_identifier(i) .. "]", with = tab }
table.insert( queue, to_fill )
end
already_queued[v] = name
return name
else
return '"UNSUPPORTED TYPE (' .. type(v) .. ')"', true
end
end
local top_name = convert_to_identifier( t )
while table.getn(queue) > 0 do
local to_fill = table.remove( queue, 1 )
local str = convert_to_identifier( to_fill.with, to_fill.name )
-- Assign the result. If to_fill.with is a non-anonymous table, we just created
-- it ("ret[1] = { }"); don't redundantly write "ret[1] = ret[1]".
if to_fill.name ~= str then
ret = ret .. to_fill.name .. " = " .. str .. "\n"
end
end
ret = ret .. "return " .. top_name
return ret
end
-- Recursively deep-copy a table.
function DeepCopy(From, To, already_copied)
if not To then To = {} end
already_copied = already_copied or { }
already_copied[From] = To
for a, b in pairs(From) do
local aCopy, bCopy
if type(a) ~= "table" then
aCopy = a
elseif already_copied[a] then
aCopy = already_copied[a]
else
aCopy = {}
DeepCopy( a, aCopy, already_copied )
end
if type(b) ~= "table" then
bCopy = b
elseif already_copied[b] then
bCopy = already_copied[b]
else
bCopy = {}
DeepCopy( b, bCopy, already_copied )
end
To[aCopy] = bCopy
end
return To
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+32 -32
View File
@@ -1,32 +1,32 @@
-- Can this be moved into some other file? Feels like clutter. -shake
-- Play the sound on the given player's side. Must set SupportPan = true
-- on load.
function ActorSound:playforplayer(pn)
local fBalance = SOUND:GetPlayerBalance(pn)
self:get():SetProperty("Pan", fBalance)
self:play()
end
-- (c) 2007 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Can this be moved into some other file? Feels like clutter. -shake
-- Play the sound on the given player's side. Must set SupportPan = true
-- on load.
function ActorSound:playforplayer(pn)
local fBalance = SOUND:GetPlayerBalance(pn)
self:get():SetProperty("Pan", fBalance)
self:play()
end
-- (c) 2007 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+89 -89
View File
@@ -1,89 +1,89 @@
function Sprite:LoadFromSongBanner(song)
if song then
local Path = song:GetBannerPath()
if not Path then
Path = THEME:GetPathG("Common","fallback banner")
end
self:LoadBanner( Path )
else
self:LoadBanner( THEME:GetPathG("Common","fallback banner") )
end
end
function Sprite:LoadFromSongBackground(song)
local Path = song:GetBackgroundPath()
if not Path then
Path = THEME:GetPathG("Common","fallback background")
end
self:LoadBackground( Path )
end
function LoadSongBackground()
return Def.Sprite {
InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y),
BeginCommand=cmd(LoadFromSongBackground,GAMESTATE:GetCurrentSong();scale_or_crop_background)
}
end
function Sprite:LoadFromCurrentSongBackground()
local song = GAMESTATE:GetCurrentSong();
if not song then
local trail = GAMESTATE:GetCurrentTrail(GAMESTATE:GetMasterPlayerNumber());
local e = trail:GetEntries()
if #e > 0 then
song = e[1]:GetSong();
end
end
if not song then return end
self:LoadFromSongBackground(song);
end
function Sprite:position( f )
self:GetTexture():position( f )
end
function Sprite:loop( f )
self:GetTexture():loop( f )
end
function Sprite:rate( f )
self:GetTexture():rate( f )
end
function Sprite.LinearFrames(NumFrames, Seconds)
local Frames = {}
for i = 0,NumFrames-1 do
Frames[#Frames+1] = {
Frame = i,
Delay = (1/NumFrames)*Seconds
}
end
return Frames
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
function Sprite:LoadFromSongBanner(song)
if song then
local Path = song:GetBannerPath()
if not Path then
Path = THEME:GetPathG("Common","fallback banner")
end
self:LoadBanner( Path )
else
self:LoadBanner( THEME:GetPathG("Common","fallback banner") )
end
end
function Sprite:LoadFromSongBackground(song)
local Path = song:GetBackgroundPath()
if not Path then
Path = THEME:GetPathG("Common","fallback background")
end
self:LoadBackground( Path )
end
function LoadSongBackground()
return Def.Sprite {
InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y),
BeginCommand=cmd(LoadFromSongBackground,GAMESTATE:GetCurrentSong();scale_or_crop_background)
}
end
function Sprite:LoadFromCurrentSongBackground()
local song = GAMESTATE:GetCurrentSong();
if not song then
local trail = GAMESTATE:GetCurrentTrail(GAMESTATE:GetMasterPlayerNumber());
local e = trail:GetEntries()
if #e > 0 then
song = e[1]:GetSong();
end
end
if not song then return end
self:LoadFromSongBackground(song);
end
function Sprite:position( f )
self:GetTexture():position( f )
end
function Sprite:loop( f )
self:GetTexture():loop( f )
end
function Sprite:rate( f )
self:GetTexture():rate( f )
end
function Sprite.LinearFrames(NumFrames, Seconds)
local Frames = {}
for i = 0,NumFrames-1 do
Frames[#Frames+1] = {
Frame = i,
Delay = (1/NumFrames)*Seconds
}
end
return Frames
end
-- (c) 2005 Glenn Maynard
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+112 -112
View File
@@ -1,112 +1,112 @@
function AreStagePlayerModsForced()
local bExtraStage = GAMESTATE:IsAnExtraStage()
local bOni = GAMESTATE:GetPlayMode() == "PlayMode_Oni"
return bExtraStage or bOni
end
function AreStageSongModsForced()
local bExtraStage = GAMESTATE:IsAnExtraStage()
local pm = GAMESTATE:GetPlayMode()
local bOni = pm == "PlayMode_Oni"
local bBattle = pm == "PlayMode_Battle"
local bRave = pm == "PlayMode_Rave"
return bExtraStage or bOni or bBattle or bRave
end
function ScreenSelectMusic:setupmusicstagemods()
Trace( "setupmusicstagemods" )
local pm = GAMESTATE:GetPlayMode()
if pm == "PlayMode_Battle" or pm == "PlayMode_Rave" then
-- FIX DAT BUG;
local sFail = "";
if GetGamePref("DefaultFail") then
sFail = string.format("Fail%s", GetGamePref("DefaultFail") );
else
sFail = "Failoff";
end;
--
local so = GAMESTATE:GetDefaultSongOptions() .. "," .. sFail;
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so );
MESSAGEMAN:Broadcast( "SongOptionsChanged" );
elseif GAMESTATE:IsAnExtraStage() then
if GAMESTATE:GetPreferredSongGroup() == "---Group All---" then
local song = GAMESTATE:GetCurrentSong()
GAMESTATE:SetPreferredSongGroup( song:GetGroupName() )
end
local bExtra2 = GAMESTATE:IsExtraStage2()
local style = GAMESTATE:GetCurrentStyle()
local song, steps = SONGMAN:GetExtraStageInfo( bExtra2, style )
local po, so
if bExtra2 then
po = THEME:GetMetric("SongManager","OMESPlayerModifiers");
so = THEME:GetMetric("SongManager","OMESStageModifiers");
else
po = THEME:GetMetric("SongManager","ExtraStagePlayerModifiers");
so = THEME:GetMetric("SongManager","ExtraStageStageModifiers");
end
local difficulty = steps:GetDifficulty()
local Reverse = PlayerNumber:Reverse()
GAMESTATE:SetCurrentSong( song )
GAMESTATE:SetPreferredSong( song )
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
GAMESTATE:SetCurrentSteps( pn, steps )
GAMESTATE:GetPlayerState(pn):SetPlayerOptions( "ModsLevel_Stage", po )
GAMESTATE:SetPreferredDifficulty( pn, difficulty )
MESSAGEMAN:Broadcast( "PlayerOptionsChanged", {PlayerNumber = pn} )
end
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so )
MESSAGEMAN:Broadcast( "SongOptionsChanged" )
end
end
function ScreenSelectMusic:setupcoursestagemods()
local mode = GAMESTATE:GetPlayMode()
if mode == "PlayMode_Oni" then
local po = "clearall,default"
-- Let SSMusic set battery.
-- local so = "failimmediate,battery"
local so = "failimmediate"
local Reverse = PlayerNumber:Reverse()
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
GAMESTATE:GetPlayerState(pn):SetPlayerOptions( "ModsLevel_Stage", po )
MESSAGEMAN:Broadcast( "PlayerOptionsChanged", {PlayerNumber = pn} )
end
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so )
MESSAGEMAN:Broadcast( "SongOptionsChanged" )
end
end
--
-- (c) 2006-2007 Steve Checkoway
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
function AreStagePlayerModsForced()
local bExtraStage = GAMESTATE:IsAnExtraStage()
local bOni = GAMESTATE:GetPlayMode() == "PlayMode_Oni"
return bExtraStage or bOni
end
function AreStageSongModsForced()
local bExtraStage = GAMESTATE:IsAnExtraStage()
local pm = GAMESTATE:GetPlayMode()
local bOni = pm == "PlayMode_Oni"
local bBattle = pm == "PlayMode_Battle"
local bRave = pm == "PlayMode_Rave"
return bExtraStage or bOni or bBattle or bRave
end
function ScreenSelectMusic:setupmusicstagemods()
Trace( "setupmusicstagemods" )
local pm = GAMESTATE:GetPlayMode()
if pm == "PlayMode_Battle" or pm == "PlayMode_Rave" then
-- FIX DAT BUG;
local sFail = "";
if GetGamePref("DefaultFail") then
sFail = string.format("Fail%s", GetGamePref("DefaultFail") );
else
sFail = "Failoff";
end;
--
local so = GAMESTATE:GetDefaultSongOptions() .. "," .. sFail;
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so );
MESSAGEMAN:Broadcast( "SongOptionsChanged" );
elseif GAMESTATE:IsAnExtraStage() then
if GAMESTATE:GetPreferredSongGroup() == "---Group All---" then
local song = GAMESTATE:GetCurrentSong()
GAMESTATE:SetPreferredSongGroup( song:GetGroupName() )
end
local bExtra2 = GAMESTATE:IsExtraStage2()
local style = GAMESTATE:GetCurrentStyle()
local song, steps = SONGMAN:GetExtraStageInfo( bExtra2, style )
local po, so
if bExtra2 then
po = THEME:GetMetric("SongManager","OMESPlayerModifiers");
so = THEME:GetMetric("SongManager","OMESStageModifiers");
else
po = THEME:GetMetric("SongManager","ExtraStagePlayerModifiers");
so = THEME:GetMetric("SongManager","ExtraStageStageModifiers");
end
local difficulty = steps:GetDifficulty()
local Reverse = PlayerNumber:Reverse()
GAMESTATE:SetCurrentSong( song )
GAMESTATE:SetPreferredSong( song )
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
GAMESTATE:SetCurrentSteps( pn, steps )
GAMESTATE:GetPlayerState(pn):SetPlayerOptions( "ModsLevel_Stage", po )
GAMESTATE:SetPreferredDifficulty( pn, difficulty )
MESSAGEMAN:Broadcast( "PlayerOptionsChanged", {PlayerNumber = pn} )
end
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so )
MESSAGEMAN:Broadcast( "SongOptionsChanged" )
end
end
function ScreenSelectMusic:setupcoursestagemods()
local mode = GAMESTATE:GetPlayMode()
if mode == "PlayMode_Oni" then
local po = "clearall,default"
-- Let SSMusic set battery.
-- local so = "failimmediate,battery"
local so = "failimmediate"
local Reverse = PlayerNumber:Reverse()
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
GAMESTATE:GetPlayerState(pn):SetPlayerOptions( "ModsLevel_Stage", po )
MESSAGEMAN:Broadcast( "PlayerOptionsChanged", {PlayerNumber = pn} )
end
GAMESTATE:SetSongOptions( "ModsLevel_Stage", so )
MESSAGEMAN:Broadcast( "SongOptionsChanged" )
end
end
--
-- (c) 2006-2007 Steve Checkoway
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+207 -207
View File
@@ -1,207 +1,207 @@
-- Find a key in tab with the given value.
function FindValue(tab, value)
for key, name in tab do
if value == name then
return key
end
end
return nil
end
-- Return the index of a true value in list.
function FindSelection( list )
for index, on in list do
if on then
return index
end
end
return nil
end
-- Look up each value in a table, returning a table with the resulting strings.
function TableStringLookup( t, group )
local ret = { }
for key, val in t do
Trace(val)
ret[key] = THEME:GetString(group,val)
end
return ret
end
function split( delimiter, text )
local list = {}
local pos = 1
while 1 do
local first,last = string.find( text, delimiter, pos )
if first then
table.insert( list, string.sub(text, pos, first-1) )
pos = last+1
else
table.insert( list, string.sub(text, pos) )
break
end
end
return list
end
function join( delimiter, list )
local ret = list[1]
for i = 2,table.getn(list) do
ret = ret .. delimiter .. list[i]
end
return ret or ""
end
function wrap(val,n)
local x = val
Trace( "wrap "..x.." "..n )
if x<0 then
x = x + (math.ceil(-x/n)+1)*n
end
Trace( "adjusted "..x )
local ret = math.mod(x,n)
Trace( "ret "..ret )
return ret
end
function fapproach( val, other_val, to_move )
if val == other_val then
return val -- already done!
end
local delta = other_val - val
local sign = delta / math.abs(delta)
local toMove = sign*to_move
if math.abs(toMove) > math.abs(delta) then
toMove = delta -- snap
end
val = val + toMove
return val
end
function tableshuffle( t )
local ret = { }
for i=1,table.getn(t) do
table.insert( ret, math.random(i), t[i] )
end
return ret
end
table.shuffle = tableshuffle
function tableslice( t, num )
local ret = { }
for i=1,table.getn(t) do
table.insert( ret, i, t[i] )
end
return ret
end
table.slice = tableslice
-- add together the contents of a table
function table.sum( t )
local sum = 0
for i=1,#t do
sum = sum + t[i]
end
return sum
end
-- average of all table values
function table.average( t )
return table.sum( t ) / #t
end
-- furthest value from the average of a given table
function table.deviation( t )
local offset = math.abs(table.average(t))
for i=1,#t do
offset = math.max(math.abs(t[i]), offset)
end
return offset
end
-- See if this exists
function table.search( t, sFind )
for i=1,#t do
if t[i] == sFind then
return true
end
end
end
-- Retreive the entry that has this
function table.find( t, sFind )
for i=1,#t do
if t[i] == sFind then
return i
end
end
end
function round(val, decimal)
if (decimal) then
return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
else
return math.floor(val+0.5)
end
end
function GetRandomSongBackground()
for i=0,50 do
local song = SONGMAN:GetRandomSong()
if song then
local path = song:GetBackgroundPath()
if path then
return path
end
end
end
return THEME:GetPathG("", "_blank")
end
function GetSongBackground()
local song = GAMESTATE:GetCurrentSong()
if song then
local path = song:GetBackgroundPath()
if path then
return path
end
end
return THEME:GetPathG("Common","fallback background")
end
function StepsOrTrailToCustomDifficulty( stepsOrTrail )
if lua.CheckType("Steps", stepsOrTrail) then
return StepsToCustomDifficulty( stepsOrTrail )
end
if lua.CheckType("Trail", stepsOrTrail) then
return TrailToCustomDifficulty( stepsOrTrail )
end
end
-- (c) 2005 Glenn Maynard, Chris Danford
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
-- Find a key in tab with the given value.
function FindValue(tab, value)
for key, name in tab do
if value == name then
return key
end
end
return nil
end
-- Return the index of a true value in list.
function FindSelection( list )
for index, on in list do
if on then
return index
end
end
return nil
end
-- Look up each value in a table, returning a table with the resulting strings.
function TableStringLookup( t, group )
local ret = { }
for key, val in t do
Trace(val)
ret[key] = THEME:GetString(group,val)
end
return ret
end
function split( delimiter, text )
local list = {}
local pos = 1
while 1 do
local first,last = string.find( text, delimiter, pos )
if first then
table.insert( list, string.sub(text, pos, first-1) )
pos = last+1
else
table.insert( list, string.sub(text, pos) )
break
end
end
return list
end
function join( delimiter, list )
local ret = list[1]
for i = 2,table.getn(list) do
ret = ret .. delimiter .. list[i]
end
return ret or ""
end
function wrap(val,n)
local x = val
Trace( "wrap "..x.." "..n )
if x<0 then
x = x + (math.ceil(-x/n)+1)*n
end
Trace( "adjusted "..x )
local ret = math.mod(x,n)
Trace( "ret "..ret )
return ret
end
function fapproach( val, other_val, to_move )
if val == other_val then
return val -- already done!
end
local delta = other_val - val
local sign = delta / math.abs(delta)
local toMove = sign*to_move
if math.abs(toMove) > math.abs(delta) then
toMove = delta -- snap
end
val = val + toMove
return val
end
function tableshuffle( t )
local ret = { }
for i=1,table.getn(t) do
table.insert( ret, math.random(i), t[i] )
end
return ret
end
table.shuffle = tableshuffle
function tableslice( t, num )
local ret = { }
for i=1,table.getn(t) do
table.insert( ret, i, t[i] )
end
return ret
end
table.slice = tableslice
-- add together the contents of a table
function table.sum( t )
local sum = 0
for i=1,#t do
sum = sum + t[i]
end
return sum
end
-- average of all table values
function table.average( t )
return table.sum( t ) / #t
end
-- furthest value from the average of a given table
function table.deviation( t )
local offset = math.abs(table.average(t))
for i=1,#t do
offset = math.max(math.abs(t[i]), offset)
end
return offset
end
-- See if this exists
function table.search( t, sFind )
for i=1,#t do
if t[i] == sFind then
return true
end
end
end
-- Retreive the entry that has this
function table.find( t, sFind )
for i=1,#t do
if t[i] == sFind then
return i
end
end
end
function round(val, decimal)
if (decimal) then
return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
else
return math.floor(val+0.5)
end
end
function GetRandomSongBackground()
for i=0,50 do
local song = SONGMAN:GetRandomSong()
if song then
local path = song:GetBackgroundPath()
if path then
return path
end
end
end
return THEME:GetPathG("", "_blank")
end
function GetSongBackground()
local song = GAMESTATE:GetCurrentSong()
if song then
local path = song:GetBackgroundPath()
if path then
return path
end
end
return THEME:GetPathG("Common","fallback background")
end
function StepsOrTrailToCustomDifficulty( stepsOrTrail )
if lua.CheckType("Steps", stepsOrTrail) then
return StepsToCustomDifficulty( stepsOrTrail )
end
if lua.CheckType("Trail", stepsOrTrail) then
return TrailToCustomDifficulty( stepsOrTrail )
end
end
-- (c) 2005 Glenn Maynard, Chris Danford
-- All rights reserved.
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, and/or sell copies of the Software, and to permit persons to
-- whom the Software is furnished to do so, provided that the above
-- copyright notice(s) and this permission notice appear in all copies of
-- the Software and that both the above copyright notice(s) and this
-- permission notice appear in supporting documentation.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
-- THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
-- INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
-- OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
+310 -310
View File
@@ -1,311 +1,311 @@
--[[
Custom Speed Mods v2.0 (for sm-ssc)
by AJ Kelly of KKI Labs ( http://kki.ajworld.net/ )
changelog:
v2.0 (for sm-ssc)
Giant rewrite of the speed mod parser.
This rewrite comes with the following changes/features:
* Speed mods are now tied to profiles.
This is arguably the biggest change, as it allows the speed mods to be
portable, as well as per-profile.
Thanks to this, we can now support reading SpeedMods from a USB stick or
other external storage. (I didn't test writing yet, but it should work.)
* Data/SpeedMods.txt is the fallback.
Previously, all speed mods were stored in {SM4 folder}/Data/SpeedMods.txt.
For compatibility reasons, this file is still read by the script.
This version of Custom Speed Mods will only run on sm-ssc for the time being,
DO NOT use it in themes for StepMania 4 alpha versions.
--------------------------------------------------------------------------------
v1.4
* Try to auto-set the speed mod to 1.0 if:
1) The player hasn't already chosen a speed mod
2) The player's custom speed mod collection starts with a value under 1x.
Due to the way the custom speed mods were coded, it will always pick the
first value, even if it's not 1.0x.
v1.3
* strip whitespace out of file in case people use it.
(I don't think it really works but SM seems to think the mods are legal)
* fixed an error related to using the fallback return value.
v1.2
* small fixes
* more comments
v1.1
* Cleaned up code some, I think.
________________________________________________________________________________
anticipated future changes:
* M-Mod support (when sm-ssc imntegrates it)
]]
-- ProfileDir(slot): gets the profile dir for slot,
-- where slot is a 'ProfileSlot_*' enum value.
local function ProfileDir(slot)
local profileDir = PROFILEMAN:GetProfileDir(slot)
return profileDir or nil
end
-- Tries to parse the file at path. If successful, returns a table of mods.
-- If it can't open the file, it will write a fallback set of mods.
local function ParseSpeedModFile(path)
local file = RageFileUtil.CreateRageFile()
if file:Open(path, 1) then
-- success
local contents = file:Read()
mods = split(',',contents)
-- strip any whitespace
for i=1,#mods do
string.gsub(mods[i], "%s", "")
end
file:destroy()
return mods
else
-- error; write a fallback mod file and return it
local fallbackString = "0.5x,0.75x,1x,1.75x,2x,2.25x,2.5x,C150,C300"
Trace("[CustomSpeedMods]: Could not read SpeedMods; writing fallback to "..path)
file:Open(path, 2)
file:Write(fallbackString)
file:destroy()
return split(',',fallbackString)
end
end
-- MarkDupes(src,parent)
-- Marks duplicates in src from any matches in parent.
-- the overall mods are usually used as the parent.
local function MarkDupes(src,parent)
for iPar=1,#parent do
for iSrc=1,#src do
if parent[iPar] == src[iSrc] then
src[iSrc] = "XXX"
end
end
end
return src
end
-- RemoveMarked(src)
-- Removes any values marked for deletion.
local function RemoveMarked(src)
for iSrc=1,#src do
if src[iSrc] == "XXX" then
table.remove(src,iSrc)
end
end
return src
end
-- MergeTables(parent,child)
-- Adds the child's contents to the parent.
-- the overall mods are usually used as the parent.
local function MergeTables(parent,child)
child = RemoveMarked(child)
if #child == 0 then
return parent
end
local addMe = true
for iC=1,#child do
--[[
for iP=1,#parent do
if addMe then
-- check if that's the case.
-- why am I doing this anyways?
-- by the time these tables are passed in,
-- dupes should be gone.
end
end
]]
if addMe then
table.insert(parent,child[iC])
end
end
return parent
end
-- code in this function is based off of code in
-- http://astrofra.com/weblog/files/sort.lua
local function AnonSort(t)
local index_min
for i=1,#t,1 do
index_min = i
for j=i+1,#t,1 do
if (t[j] < t[index_min]) then
index_min = j
end
end
t[i], t[index_min] = t[index_min], t[i]
end
return t
end
local function SpeedModSort(tab)
local xMods = {}
local cMods = {}
--local mMods = {}
-- convert to numbers so sorting works:
for i=1,#tab do
local typ,val
-- xxx: If people use a floating point CMod (e.g. C420.50),
-- it will get rounded. C420.50 gets rounded to 421, btw. -aj
if string.find(tab[i],"C%d") then
typ = cMods
val = string.gsub(tab[i], "C", "")
elseif string.find(tab[i],"M%d") then
Trace("[CustomSpeedMods] OpenITG's M-Mods are not supported yet in sm-ssc.")
--typ = mMods
--val = string.gsub(tab[i], "M", "")
else
typ = xMods
val = string.gsub(tab[i], "x", "")
end
table.insert(typ,tonumber(val))
end
-- sort xMods
xMods = AnonSort(xMods)
-- sort cMods
cMods = AnonSort(cMods)
-- sort mMods
--mMods = AnonSort(mMods)
local fin = {}
-- convert it back to a string since that's what it expects
for i=1,#xMods do
table.insert(fin, xMods[i].."x")
end
for i=1,#cMods do
table.insert(fin, "C"..cMods[i])
end
--for i=1,#mMods do table.insert(fin, "M"..mMods[i]); end;
return fin
end
-- parse everything
local function GetSpeedMods()
local finalMods = {}
local baseFilename = "SpeedMods.txt"
local profileDirs = {
Fallback = "Data/",
Machine = ProfileDir('ProfileSlot_Machine'),
PlayerNumber_P1 = ProfileDir('ProfileSlot_Player1'),
PlayerNumber_P2 = ProfileDir('ProfileSlot_Player2')
}
-- figure out how many players we have to deal with.
local numPlayers = GAMESTATE:GetNumPlayersEnabled()
-- load fallback
local fallbackMods = ParseSpeedModFile(profileDirs.Fallback..baseFilename)
-- load machine
local machineMods = ParseSpeedModFile(profileDirs.Machine..baseFilename)
local playerMods = {}
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
-- file loading logic per player;
-- only bother if it's not the machine profile though.
if PROFILEMAN:IsPersistentProfile(pn) or
MEMCARDMAN:GetCardState(pn) == 'MemoryCardState_ready' then
playerMods[#playerMods+1] = ParseSpeedModFile(profileDirs[pn]..baseFilename)
end
end
-- with all loaded... the merging BEGINS!!
finalMods = fallbackMods
-- mine for duplicates, first pass (fallback <-> machine)
machineMods = MarkDupes(machineMods,finalMods)
for ply=1,#playerMods do
playerMods[ply] = MarkDupes(playerMods[ply],finalMods)
end
-- remove XXX, first pass
machineMods = RemoveMarked(machineMods);
for ply=1,#playerMods do
playerMods[ply] = RemoveMarked(playerMods[ply])
end
-- mine for duplicates, second pass (machine <-> player)
for ply=1,#playerMods do
playerMods[ply] = MarkDupes(playerMods[ply],machineMods)
end
-- remove XXX, second pass
machineMods = RemoveMarked(machineMods)
for ply=1,#playerMods do
playerMods[ply] = RemoveMarked(playerMods[ply])
end
-- merge zone
finalMods = MergeTables(finalMods,machineMods)
for ply=1,#playerMods do
finalMods = MergeTables(finalMods,playerMods[ply])
end
-- final removal of XXX before sorting
finalMods = RemoveMarked(finalMods)
-- sort the mods before returning them
return SpeedModSort(finalMods)
end
function SpeedMods()
-- here we see the option menu itself.
local t = {
Name = "Speed",
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = false,
ExportOnChange = false,
Choices = GetSpeedMods(),
LoadSelections = function(self, list, pn)
local pMods = GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred")
for i = 1,table.getn(self.Choices) do
if string.find(pMods, self.Choices[i]) then
list[i] = true
return
end
end
-- if we've reached this point, try to find 1x or 1.0x instead,
-- in case the player has defined a speed mod under 1.0x
for i = 1,table.getn(self.Choices) do
if self.Choices[i] == "1x" or self.Choices[i] == "1.0x" then
list[i] = true
return
end
end
end,
SaveSelections = function(self, list, pn)
for i = 1,table.getn(self.Choices) do
if list[i] then
local PlayerState = GAMESTATE:GetPlayerState(pn)
PlayerState:SetPlayerOptions("ModsLevel_Preferred",self.Choices[i])
return
end
end
end
}
setmetatable( t, t )
return t
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs.
Use freely, so long this notice and the above documentation remains.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--[[
Custom Speed Mods v2.0 (for sm-ssc)
by AJ Kelly of KKI Labs ( http://kki.ajworld.net/ )
changelog:
v2.0 (for sm-ssc)
Giant rewrite of the speed mod parser.
This rewrite comes with the following changes/features:
* Speed mods are now tied to profiles.
This is arguably the biggest change, as it allows the speed mods to be
portable, as well as per-profile.
Thanks to this, we can now support reading SpeedMods from a USB stick or
other external storage. (I didn't test writing yet, but it should work.)
* Data/SpeedMods.txt is the fallback.
Previously, all speed mods were stored in {SM4 folder}/Data/SpeedMods.txt.
For compatibility reasons, this file is still read by the script.
This version of Custom Speed Mods will only run on sm-ssc for the time being,
DO NOT use it in themes for StepMania 4 alpha versions.
--------------------------------------------------------------------------------
v1.4
* Try to auto-set the speed mod to 1.0 if:
1) The player hasn't already chosen a speed mod
2) The player's custom speed mod collection starts with a value under 1x.
Due to the way the custom speed mods were coded, it will always pick the
first value, even if it's not 1.0x.
v1.3
* strip whitespace out of file in case people use it.
(I don't think it really works but SM seems to think the mods are legal)
* fixed an error related to using the fallback return value.
v1.2
* small fixes
* more comments
v1.1
* Cleaned up code some, I think.
________________________________________________________________________________
anticipated future changes:
* M-Mod support (when sm-ssc imntegrates it)
]]
-- ProfileDir(slot): gets the profile dir for slot,
-- where slot is a 'ProfileSlot_*' enum value.
local function ProfileDir(slot)
local profileDir = PROFILEMAN:GetProfileDir(slot)
return profileDir or nil
end
-- Tries to parse the file at path. If successful, returns a table of mods.
-- If it can't open the file, it will write a fallback set of mods.
local function ParseSpeedModFile(path)
local file = RageFileUtil.CreateRageFile()
if file:Open(path, 1) then
-- success
local contents = file:Read()
mods = split(',',contents)
-- strip any whitespace
for i=1,#mods do
string.gsub(mods[i], "%s", "")
end
file:destroy()
return mods
else
-- error; write a fallback mod file and return it
local fallbackString = "0.5x,0.75x,1x,1.75x,2x,2.25x,2.5x,C150,C300"
Trace("[CustomSpeedMods]: Could not read SpeedMods; writing fallback to "..path)
file:Open(path, 2)
file:Write(fallbackString)
file:destroy()
return split(',',fallbackString)
end
end
-- MarkDupes(src,parent)
-- Marks duplicates in src from any matches in parent.
-- the overall mods are usually used as the parent.
local function MarkDupes(src,parent)
for iPar=1,#parent do
for iSrc=1,#src do
if parent[iPar] == src[iSrc] then
src[iSrc] = "XXX"
end
end
end
return src
end
-- RemoveMarked(src)
-- Removes any values marked for deletion.
local function RemoveMarked(src)
for iSrc=1,#src do
if src[iSrc] == "XXX" then
table.remove(src,iSrc)
end
end
return src
end
-- MergeTables(parent,child)
-- Adds the child's contents to the parent.
-- the overall mods are usually used as the parent.
local function MergeTables(parent,child)
child = RemoveMarked(child)
if #child == 0 then
return parent
end
local addMe = true
for iC=1,#child do
--[[
for iP=1,#parent do
if addMe then
-- check if that's the case.
-- why am I doing this anyways?
-- by the time these tables are passed in,
-- dupes should be gone.
end
end
]]
if addMe then
table.insert(parent,child[iC])
end
end
return parent
end
-- code in this function is based off of code in
-- http://astrofra.com/weblog/files/sort.lua
local function AnonSort(t)
local index_min
for i=1,#t,1 do
index_min = i
for j=i+1,#t,1 do
if (t[j] < t[index_min]) then
index_min = j
end
end
t[i], t[index_min] = t[index_min], t[i]
end
return t
end
local function SpeedModSort(tab)
local xMods = {}
local cMods = {}
--local mMods = {}
-- convert to numbers so sorting works:
for i=1,#tab do
local typ,val
-- xxx: If people use a floating point CMod (e.g. C420.50),
-- it will get rounded. C420.50 gets rounded to 421, btw. -aj
if string.find(tab[i],"C%d") then
typ = cMods
val = string.gsub(tab[i], "C", "")
elseif string.find(tab[i],"M%d") then
Trace("[CustomSpeedMods] OpenITG's M-Mods are not supported yet in sm-ssc.")
--typ = mMods
--val = string.gsub(tab[i], "M", "")
else
typ = xMods
val = string.gsub(tab[i], "x", "")
end
table.insert(typ,tonumber(val))
end
-- sort xMods
xMods = AnonSort(xMods)
-- sort cMods
cMods = AnonSort(cMods)
-- sort mMods
--mMods = AnonSort(mMods)
local fin = {}
-- convert it back to a string since that's what it expects
for i=1,#xMods do
table.insert(fin, xMods[i].."x")
end
for i=1,#cMods do
table.insert(fin, "C"..cMods[i])
end
--for i=1,#mMods do table.insert(fin, "M"..mMods[i]); end;
return fin
end
-- parse everything
local function GetSpeedMods()
local finalMods = {}
local baseFilename = "SpeedMods.txt"
local profileDirs = {
Fallback = "Data/",
Machine = ProfileDir('ProfileSlot_Machine'),
PlayerNumber_P1 = ProfileDir('ProfileSlot_Player1'),
PlayerNumber_P2 = ProfileDir('ProfileSlot_Player2')
}
-- figure out how many players we have to deal with.
local numPlayers = GAMESTATE:GetNumPlayersEnabled()
-- load fallback
local fallbackMods = ParseSpeedModFile(profileDirs.Fallback..baseFilename)
-- load machine
local machineMods = ParseSpeedModFile(profileDirs.Machine..baseFilename)
local playerMods = {}
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
-- file loading logic per player;
-- only bother if it's not the machine profile though.
if PROFILEMAN:IsPersistentProfile(pn) or
MEMCARDMAN:GetCardState(pn) == 'MemoryCardState_ready' then
playerMods[#playerMods+1] = ParseSpeedModFile(profileDirs[pn]..baseFilename)
end
end
-- with all loaded... the merging BEGINS!!
finalMods = fallbackMods
-- mine for duplicates, first pass (fallback <-> machine)
machineMods = MarkDupes(machineMods,finalMods)
for ply=1,#playerMods do
playerMods[ply] = MarkDupes(playerMods[ply],finalMods)
end
-- remove XXX, first pass
machineMods = RemoveMarked(machineMods);
for ply=1,#playerMods do
playerMods[ply] = RemoveMarked(playerMods[ply])
end
-- mine for duplicates, second pass (machine <-> player)
for ply=1,#playerMods do
playerMods[ply] = MarkDupes(playerMods[ply],machineMods)
end
-- remove XXX, second pass
machineMods = RemoveMarked(machineMods)
for ply=1,#playerMods do
playerMods[ply] = RemoveMarked(playerMods[ply])
end
-- merge zone
finalMods = MergeTables(finalMods,machineMods)
for ply=1,#playerMods do
finalMods = MergeTables(finalMods,playerMods[ply])
end
-- final removal of XXX before sorting
finalMods = RemoveMarked(finalMods)
-- sort the mods before returning them
return SpeedModSort(finalMods)
end
function SpeedMods()
-- here we see the option menu itself.
local t = {
Name = "Speed",
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = false,
ExportOnChange = false,
Choices = GetSpeedMods(),
LoadSelections = function(self, list, pn)
local pMods = GAMESTATE:GetPlayerState(pn):GetPlayerOptionsString("ModsLevel_Preferred")
for i = 1,table.getn(self.Choices) do
if string.find(pMods, self.Choices[i]) then
list[i] = true
return
end
end
-- if we've reached this point, try to find 1x or 1.0x instead,
-- in case the player has defined a speed mod under 1.0x
for i = 1,table.getn(self.Choices) do
if self.Choices[i] == "1x" or self.Choices[i] == "1.0x" then
list[i] = true
return
end
end
end,
SaveSelections = function(self, list, pn)
for i = 1,table.getn(self.Choices) do
if list[i] then
local PlayerState = GAMESTATE:GetPlayerState(pn)
PlayerState:SetPlayerOptions("ModsLevel_Preferred",self.Choices[i])
return
end
end
end
}
setmetatable( t, t )
return t
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs.
Use freely, so long this notice and the above documentation remains.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]
+69 -69
View File
@@ -1,70 +1,70 @@
-- freem, inc. DateTime for StepMania
-- todo: accept format parameters for things
-- reference: http://us.php.net/manual/en/function.date.php
local dateChars = {
--[[ day ]]
'd', -- Day of the month, 2 digits with leading zeros (01-31)
'D', -- A textual representation of a day, three letters ("Mon"-"Sun")
'j', -- Day of the month without leading zeros (1-31)
'l', -- A full textual representation of the day of the week
'N', -- ISO-8601 numeric representation of the day of the week (1=Mon,7=Sun)
'S', -- English ordinal suffix for the day of the month, 2 characters
'w', -- Numeric representation of the day of the week (0=Sun,6=Sat)
'z', -- The day of the year (0-365)
--[[ week ]]
'W', -- ISO-8601 week number of year, weeks starting on Monday
--[[ month ]]
'F', -- A full textual representation of a month, such as January or March
'm', -- Numeric representation of a month, with leading zeros
'M', -- A short textual representation of a month, three letters
'n', -- Numeric representation of a month, without leading zeros
't', -- Number of days in the given month
--[[ year ]]
'L', -- Whether it's a leap year (1 or 0)
'o', -- (sux) ISO-8601 year number
'Y', -- A full numeric representation of a year, 4 digits
'y', -- (sux) A two digit representation of a year
--[[ time ]]
'a', -- Lowercase Ante meridiem and Post meridiem
'A', -- Uppercase Ante meridiem and Post meridiem
'B', -- Swatch Beats
'g', -- 12-hour format of an hour without leading zeros
'G', -- 24-hour format of an hour without leading zeros
'h', -- 12-hour format of an hour with leading zeros
'H', -- 24-hour format of an hour with leading zeros
'i', -- Minutes with leading zeros
's', -- Seconds, with leading zeros
'u', -- Microseconds
--[[ timezone ]]
'e', -- Timezone identifier
'I', -- Whether or not the date is in daylight saving time
'O', -- Difference to Greenwich time (GMT) in hours
'P', -- Difference to Greenwich time (GMT) with colon between hours and minutes
'T', -- Timezone abbreviation
'Z', -- Timezone offset in seconds.
--[[ full datetime ]]
'c', -- ISO 8601 date
'r', -- RFC 2822 formatted date
'U' -- Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
}
function date(format,...)
if ... then
-- convert value
else
-- convert current time
end
end
Date = {
Today = function()
return string.format("%i%02i%02i", Year(), (MonthOfYear()+1), DayOfMonth())
end
}
Time = {
Now = function()
return string.format( "%02i:%02i:%02i", Hour(), Minute(), Second() )
end
-- freem, inc. DateTime for StepMania
-- todo: accept format parameters for things
-- reference: http://us.php.net/manual/en/function.date.php
local dateChars = {
--[[ day ]]
'd', -- Day of the month, 2 digits with leading zeros (01-31)
'D', -- A textual representation of a day, three letters ("Mon"-"Sun")
'j', -- Day of the month without leading zeros (1-31)
'l', -- A full textual representation of the day of the week
'N', -- ISO-8601 numeric representation of the day of the week (1=Mon,7=Sun)
'S', -- English ordinal suffix for the day of the month, 2 characters
'w', -- Numeric representation of the day of the week (0=Sun,6=Sat)
'z', -- The day of the year (0-365)
--[[ week ]]
'W', -- ISO-8601 week number of year, weeks starting on Monday
--[[ month ]]
'F', -- A full textual representation of a month, such as January or March
'm', -- Numeric representation of a month, with leading zeros
'M', -- A short textual representation of a month, three letters
'n', -- Numeric representation of a month, without leading zeros
't', -- Number of days in the given month
--[[ year ]]
'L', -- Whether it's a leap year (1 or 0)
'o', -- (sux) ISO-8601 year number
'Y', -- A full numeric representation of a year, 4 digits
'y', -- (sux) A two digit representation of a year
--[[ time ]]
'a', -- Lowercase Ante meridiem and Post meridiem
'A', -- Uppercase Ante meridiem and Post meridiem
'B', -- Swatch Beats
'g', -- 12-hour format of an hour without leading zeros
'G', -- 24-hour format of an hour without leading zeros
'h', -- 12-hour format of an hour with leading zeros
'H', -- 24-hour format of an hour with leading zeros
'i', -- Minutes with leading zeros
's', -- Seconds, with leading zeros
'u', -- Microseconds
--[[ timezone ]]
'e', -- Timezone identifier
'I', -- Whether or not the date is in daylight saving time
'O', -- Difference to Greenwich time (GMT) in hours
'P', -- Difference to Greenwich time (GMT) with colon between hours and minutes
'T', -- Timezone abbreviation
'Z', -- Timezone offset in seconds.
--[[ full datetime ]]
'c', -- ISO 8601 date
'r', -- RFC 2822 formatted date
'U' -- Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
}
function date(format,...)
if ... then
-- convert value
else
-- convert current time
end
end
Date = {
Today = function()
return string.format("%i%02i%02i", Year(), (MonthOfYear()+1), DayOfMonth())
end
}
Time = {
Now = function()
return string.format( "%02i:%02i:%02i", Hour(), Minute(), Second() )
end
}
+43 -43
View File
@@ -1,44 +1,44 @@
--[[
EnvUtils2: Environmental Variable Utilities
Written by AJ Kelly of KKI Labs / Version 2.0
This code is a rewrite of what typically exists in EnvUtils.lua
(as seen in dubaiOne), hereafter referred to as EnvUtils1.
I felt it was time for a simplification of the code.
This new version should also work better and be less confusing.
--]]
-- Env table global
envTable = GAMESTATE:Env()
-- setenv(name,value)
-- Sets aside an entry for /name/ and puts /value/ into it.
-- Unlike EnvUtils1, this is the only setenv function available to you.
-- If you need to store more than one value, you're welcome to use a
-- table as /value/, it should work just fine.
function setenv(name,value)
envTable[name] = value
end
-- getenv(name)
-- This will return whatever value is at envTable[name].
function getenv(name)
return envTable[name]
end
--[[
Copyright © 2008 AJ Kelly/KKI Labs
Use freely.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--[[
EnvUtils2: Environmental Variable Utilities
Written by AJ Kelly of KKI Labs / Version 2.0
This code is a rewrite of what typically exists in EnvUtils.lua
(as seen in dubaiOne), hereafter referred to as EnvUtils1.
I felt it was time for a simplification of the code.
This new version should also work better and be less confusing.
--]]
-- Env table global
envTable = GAMESTATE:Env()
-- setenv(name,value)
-- Sets aside an entry for /name/ and puts /value/ into it.
-- Unlike EnvUtils1, this is the only setenv function available to you.
-- If you need to store more than one value, you're welcome to use a
-- table as /value/, it should work just fine.
function setenv(name,value)
envTable[name] = value
end
-- getenv(name)
-- This will return whatever value is at envTable[name].
function getenv(name)
return envTable[name]
end
--[[
Copyright © 2008 AJ Kelly/KKI Labs
Use freely.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]
+146 -146
View File
@@ -1,147 +1,147 @@
-- GamePreferences: Clone of AJ's User Preferences "Module"
-- Written by AJ Kelly of KKI Labs / Version 2.11-ssc
-- (modified slightly for Cerulean Skies 2's disregard of the name of the
-- themeinfo variable lol :p)
--[[
the first released version was broken.
this version aims to be simpler, and therefore work.
[changelog]
v2.11-ssc
Remove EnvUtils references; we have it in sm-ssc.
v2.1-ssc
sm-ssc version of UserPrefs. We can now assume players have certain
functionality, like RageFile:GetError().
v2.1
Added type specific GetUserPref functions.
[usage]
First, edit PrefPath to match your theme.
If you use ThemeInfo, then you shouldn't have to edit this.
If you're not using ThemeInfo, then you can replace
".. themeInfo.Name .." with the theme's folder name.
ThemeInfo is documented at http://kki.ajworld.net/wiki/ThemeInfo.lua
After that's set up, read the docs.
]]
local PrefPath = "Data/GamePrefs/"
--[[ begin internal stuff; no need to edit below this line. ]]
-- Local internal function to write envs. ___Not for themer use.___
local function WriteEnv(envName,envValue)
return setenv(envName,envValue)
end
function ReadGamePrefFromFile(name)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
local option
if f:Open(fullFilename,1) then
option = tostring( f:Read() )
WriteEnv(name,option)
f:destroy()
return option
else
local fError = f:GetError()
Trace( "[FileUtils] Error reading ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return nil
end
end
function WriteGamePrefToFile(name,value)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
if f:Open(fullFilename, 2) then
f:Write( tostring(value) )
WriteEnv(name,value)
else
local fError = f:GetError()
Trace( "[FileUtils] Error writing to ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return false
end
f:destroy()
return true
end
--[[ end internal functions; still don't edit below this line ]]
function GetGamePref(name)
return ReadGamePrefFromFile(name)
end
function SetGamePref(name,value)
return WriteGamePrefToFile(name,value)
end
--[[ type specific, for when you want to be lazy ]]
-- XXX: make set funcs, since I hate dealing with colors and I know
-- other themers would too.
-- GetUserPrefB: boolean
function GetGamePrefB(name)
-- this one is a bit trickier.
local pref = ReadGamePrefFromFile(name)
if type(pref) == "string" then
pref = string.lower(pref)
if pref == "true" or cmp == "t" then
return true
elseif pref == "false" or cmp == "f" then
return false
else
Trace("Error in GetUserPrefB(".. name ..") converting from string" )
return false
end
elseif type(pref) == "number" then
-- both 0 and -1 are false; if you want to change this,
-- feel free to remove "or pref == -1".
if pref == 0 or pref == -1 then
else
return true
end
end
end
-- GetUserPrefC: color
function GetGamePrefC(name)
-- XXX: make sure it's grabbing a string that can be turned into a color
-- and also possibly handle HSV values too.
return color( ReadGamePrefFromFile(name) )
end
-- GetUserPrefN: numbers (integers, floats)
function GetGamePrefN(name)
return tonumber( ReadGamePrefFromFile(name) )
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- GamePreferences: Clone of AJ's User Preferences "Module"
-- Written by AJ Kelly of KKI Labs / Version 2.11-ssc
-- (modified slightly for Cerulean Skies 2's disregard of the name of the
-- themeinfo variable lol :p)
--[[
the first released version was broken.
this version aims to be simpler, and therefore work.
[changelog]
v2.11-ssc
Remove EnvUtils references; we have it in sm-ssc.
v2.1-ssc
sm-ssc version of UserPrefs. We can now assume players have certain
functionality, like RageFile:GetError().
v2.1
Added type specific GetUserPref functions.
[usage]
First, edit PrefPath to match your theme.
If you use ThemeInfo, then you shouldn't have to edit this.
If you're not using ThemeInfo, then you can replace
".. themeInfo.Name .." with the theme's folder name.
ThemeInfo is documented at http://kki.ajworld.net/wiki/ThemeInfo.lua
After that's set up, read the docs.
]]
local PrefPath = "Data/GamePrefs/"
--[[ begin internal stuff; no need to edit below this line. ]]
-- Local internal function to write envs. ___Not for themer use.___
local function WriteEnv(envName,envValue)
return setenv(envName,envValue)
end
function ReadGamePrefFromFile(name)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
local option
if f:Open(fullFilename,1) then
option = tostring( f:Read() )
WriteEnv(name,option)
f:destroy()
return option
else
local fError = f:GetError()
Trace( "[FileUtils] Error reading ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return nil
end
end
function WriteGamePrefToFile(name,value)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
if f:Open(fullFilename, 2) then
f:Write( tostring(value) )
WriteEnv(name,value)
else
local fError = f:GetError()
Trace( "[FileUtils] Error writing to ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return false
end
f:destroy()
return true
end
--[[ end internal functions; still don't edit below this line ]]
function GetGamePref(name)
return ReadGamePrefFromFile(name)
end
function SetGamePref(name,value)
return WriteGamePrefToFile(name,value)
end
--[[ type specific, for when you want to be lazy ]]
-- XXX: make set funcs, since I hate dealing with colors and I know
-- other themers would too.
-- GetUserPrefB: boolean
function GetGamePrefB(name)
-- this one is a bit trickier.
local pref = ReadGamePrefFromFile(name)
if type(pref) == "string" then
pref = string.lower(pref)
if pref == "true" or cmp == "t" then
return true
elseif pref == "false" or cmp == "f" then
return false
else
Trace("Error in GetUserPrefB(".. name ..") converting from string" )
return false
end
elseif type(pref) == "number" then
-- both 0 and -1 are false; if you want to change this,
-- feel free to remove "or pref == -1".
if pref == 0 or pref == -1 then
else
return true
end
end
end
-- GetUserPrefC: color
function GetGamePrefC(name)
-- XXX: make sure it's grabbing a string that can be turned into a color
-- and also possibly handle HSV values too.
return color( ReadGamePrefFromFile(name) )
end
-- GetUserPrefN: numbers (integers, floats)
function GetGamePrefN(name)
return tonumber( ReadGamePrefFromFile(name) )
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]
+269 -269
View File
@@ -1,270 +1,270 @@
-- sm-ssc fallback theme | script ring 03 | Gameplay.lua
-- [en] This file is used to store settings that should be different in each
-- game mode.
-- shakesoda calls this pump.lua
-- GetExtraColorThreshold()
-- [en] returns the difficulty threshold in meter
-- for songs that should be counted as boss songs.
function GetExtraColorThreshold()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Modes = {
dance = 10,
pump = 15,
beat = 12,
kb7 = 10,
para = 10,
techno = 10,
lights = 10, -- lights shouldn't be playable
}
return Modes[sGame]
end
-- GameCompatibleModes:
-- [en] returns possible modes for ScreenSelectPlayMode
function GameCompatibleModes()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Modes = {
dance = "Single,Double,Solo,Versus,Couple",
pump = "Single,Double,HalfDouble,Versus,Couple",
beat = "5Keys,7Keys,10Keys,14Keys",
kb7 = "KB7",
para = "Single",
techno = "Single4,Single5,Single8,Double4,Double8",
lights = "Single" -- lights shouldn't be playable
}
return Modes[sGame]
end
function SelectProfileKeys()
local sGame = GAMESTATE:GetCurrentGame():GetName()
if sGame == "pump" then
return "Up,Down,Start,Back,Center,DownLeft,DownRight"
elseif sGame == "dance" then
return "Up,Down,Start,Back,Up2,Down2"
else
return "Up,Down,Start,Back"
end
end
-- ScoreKeeperClass:
-- [en] Determines the correct ScoreKeeper class to use.
function ScoreKeeperClass()
sGame = GAMESTATE:GetCurrentGame():GetName()
local ScoreKeepers = {
-- xxx: allow for ScoreKeeperShared when needed
dance = "ScoreKeeperNormal",
pump = "ScoreKeeperNormal",
beat = "ScoreKeeperNormal",
kb7 = "ScoreKeeperNormal",
para = "ScoreKeeperNormal",
techno = "ScoreKeeperNormal",
ez2 = "ScoreKeeperNormal",
ds3ddx = "ScoreKeeperNormal",
maniax = "ScoreKeeperNormal",
guitar = "ScoreKeeperGuitar"
}
return ScoreKeepers[sGame]
end
-- ComboContinue:
-- [en]
function ComboContinue()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Continue = {
dance = GAMESTATE:GetPlayMode() == "PlayMode_Oni" and "TapNoteScore_W2" or "TapNoteScore_W3",
pump = "TapNoteScore_W3",
beat = "TapNoteScore_W3",
kb7 = "TapNoteScore_W3",
para = "TapNoteScore_W4"
}
return Continue[sGame]
end
function ComboMaintain()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Maintain = {
dance = "TapNoteScore_W3",
pump = "TapNoteScore_W4",
beat = "TapNoteScore_W3",
kb7 = "TapNoteScore_W3",
para = "TapNoteScore_W4"
}
return Maintain[sGame]
end
function ComboPerRow()
sGame = GAMESTATE:GetCurrentGame():GetName()
if sGame == "pump" then
return true
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
return true
else
return false
end
end
-- these need cleanup really.
function HitCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = 2,
pump = 4,
beat = 2,
kb7 = 2,
para = 2,
guitar = 2
}
return Combo[sGame]
end
function MissCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = 2,
pump = 4,
beat = 0,
kb7 = 0,
para = 0,
guitar = 0
}
return Combo[sGame]
end
-- FailCombo:
-- [en] The combo that causes game failure.
function FailCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = -1, -- ITG uses 30
pump = 51, -- Pump Pro uses 30, real Pump uses 51
beat = -1,
kb7 = -1,
para = -1,
guitar = -1
}
return Combo[sGame]
end
function RoutineSkinP1()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = "midi-routine-p1",
pump = "cmd-routine-p1",
beat = "default",
kb7 = "default",
para = "default",
guitar = "default"
}
return Combo[sGame]
end
function RoutineSkinP2()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = "midi-routine-p2",
pump = "cmd-routine-p2",
beat = "default",
kb7 = "retrobar",
para = "default",
guitar = "default"
}
return Combo[sGame]
end
-- todo: use tables for some of these -aj
function HoldTiming()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0
else
return PREFSMAN:GetPreference("TimingWindowSecondsHold")
end
end
function ShowHoldJudgments()
return not GAMESTATE:GetCurrentGame():GetName() == "pump"
end
function HoldHeadStep()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function InitialHoldLife()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0.05
else
return 1
end
end
function MaxHoldLife()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0.05
else
return 1
end
end
function ImmediateHoldLetGo()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function RollBodyIncrementsCombo()
return false
--[[ if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end --]]
end
function CheckpointsTapsSeparateJudgment()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function ScoreMissedHoldsAndRolls()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
local tNotePositions = {
-- StepMania 3.9/4.0
Normal = {
-144,
144,
},
-- ITG
Lower = {
-125,
145,
}
}
function GetTapPosition( sType )
bCategory = (sType == 'Standard') and 1 or 2
-- true: Normal
-- false: Lower
bPreference = GetUserPrefB("UserPrefNotePosition") and "Normal" or "Lower"
tNotePos = tNotePositions[bPreference]
return tNotePos[bCategory]
end
function ComboUnderField()
return GetUserPrefB("UserPrefComboUnderField")
-- sm-ssc fallback theme | script ring 03 | Gameplay.lua
-- [en] This file is used to store settings that should be different in each
-- game mode.
-- shakesoda calls this pump.lua
-- GetExtraColorThreshold()
-- [en] returns the difficulty threshold in meter
-- for songs that should be counted as boss songs.
function GetExtraColorThreshold()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Modes = {
dance = 10,
pump = 15,
beat = 12,
kb7 = 10,
para = 10,
techno = 10,
lights = 10, -- lights shouldn't be playable
}
return Modes[sGame]
end
-- GameCompatibleModes:
-- [en] returns possible modes for ScreenSelectPlayMode
function GameCompatibleModes()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Modes = {
dance = "Single,Double,Solo,Versus,Couple",
pump = "Single,Double,HalfDouble,Versus,Couple",
beat = "5Keys,7Keys,10Keys,14Keys",
kb7 = "KB7",
para = "Single",
techno = "Single4,Single5,Single8,Double4,Double8",
lights = "Single" -- lights shouldn't be playable
}
return Modes[sGame]
end
function SelectProfileKeys()
local sGame = GAMESTATE:GetCurrentGame():GetName()
if sGame == "pump" then
return "Up,Down,Start,Back,Center,DownLeft,DownRight"
elseif sGame == "dance" then
return "Up,Down,Start,Back,Up2,Down2"
else
return "Up,Down,Start,Back"
end
end
-- ScoreKeeperClass:
-- [en] Determines the correct ScoreKeeper class to use.
function ScoreKeeperClass()
sGame = GAMESTATE:GetCurrentGame():GetName()
local ScoreKeepers = {
-- xxx: allow for ScoreKeeperShared when needed
dance = "ScoreKeeperNormal",
pump = "ScoreKeeperNormal",
beat = "ScoreKeeperNormal",
kb7 = "ScoreKeeperNormal",
para = "ScoreKeeperNormal",
techno = "ScoreKeeperNormal",
ez2 = "ScoreKeeperNormal",
ds3ddx = "ScoreKeeperNormal",
maniax = "ScoreKeeperNormal",
guitar = "ScoreKeeperGuitar"
}
return ScoreKeepers[sGame]
end
-- ComboContinue:
-- [en]
function ComboContinue()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Continue = {
dance = GAMESTATE:GetPlayMode() == "PlayMode_Oni" and "TapNoteScore_W2" or "TapNoteScore_W3",
pump = "TapNoteScore_W3",
beat = "TapNoteScore_W3",
kb7 = "TapNoteScore_W3",
para = "TapNoteScore_W4"
}
return Continue[sGame]
end
function ComboMaintain()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Maintain = {
dance = "TapNoteScore_W3",
pump = "TapNoteScore_W4",
beat = "TapNoteScore_W3",
kb7 = "TapNoteScore_W3",
para = "TapNoteScore_W4"
}
return Maintain[sGame]
end
function ComboPerRow()
sGame = GAMESTATE:GetCurrentGame():GetName()
if sGame == "pump" then
return true
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
return true
else
return false
end
end
-- these need cleanup really.
function HitCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = 2,
pump = 4,
beat = 2,
kb7 = 2,
para = 2,
guitar = 2
}
return Combo[sGame]
end
function MissCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = 2,
pump = 4,
beat = 0,
kb7 = 0,
para = 0,
guitar = 0
}
return Combo[sGame]
end
-- FailCombo:
-- [en] The combo that causes game failure.
function FailCombo()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = -1, -- ITG uses 30
pump = 51, -- Pump Pro uses 30, real Pump uses 51
beat = -1,
kb7 = -1,
para = -1,
guitar = -1
}
return Combo[sGame]
end
function RoutineSkinP1()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = "midi-routine-p1",
pump = "cmd-routine-p1",
beat = "default",
kb7 = "default",
para = "default",
guitar = "default"
}
return Combo[sGame]
end
function RoutineSkinP2()
sGame = GAMESTATE:GetCurrentGame():GetName()
local Combo = {
dance = "midi-routine-p2",
pump = "cmd-routine-p2",
beat = "default",
kb7 = "retrobar",
para = "default",
guitar = "default"
}
return Combo[sGame]
end
-- todo: use tables for some of these -aj
function HoldTiming()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0
else
return PREFSMAN:GetPreference("TimingWindowSecondsHold")
end
end
function ShowHoldJudgments()
return not GAMESTATE:GetCurrentGame():GetName() == "pump"
end
function HoldHeadStep()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function InitialHoldLife()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0.05
else
return 1
end
end
function MaxHoldLife()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return 0.05
else
return 1
end
end
function ImmediateHoldLetGo()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function RollBodyIncrementsCombo()
return false
--[[ if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end --]]
end
function CheckpointsTapsSeparateJudgment()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function ScoreMissedHoldsAndRolls()
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
local tNotePositions = {
-- StepMania 3.9/4.0
Normal = {
-144,
144,
},
-- ITG
Lower = {
-125,
145,
}
}
function GetTapPosition( sType )
bCategory = (sType == 'Standard') and 1 or 2
-- true: Normal
-- false: Lower
bPreference = GetUserPrefB("UserPrefNotePosition") and "Normal" or "Lower"
tNotePos = tNotePositions[bPreference]
return tNotePos[bCategory]
end
function ComboUnderField()
return GetUserPrefB("UserPrefComboUnderField")
end
+248 -248
View File
@@ -1,249 +1,249 @@
--[[
functions for using HSV colors in StepMania.
Code adapted from http://www.cs.rit.edu/~ncs/color/t_convert.html
changelog:
v 1
= v1.1 =
* Hue(color, newHue) changed to wrap around for invalid values.
* Desaturate(color, percent) renamed to Saturation(color, percent).
______________________________________________________________________________
xxx: support HSL<->RGB (which is different) too?
http://en.wikipedia.org/wiki/HSV_color_space#Conversion_from_RGB_to_HSL_or_HSV
HSL treats absolute brightness of a color at 0.5 in L, whereas
HSV treats absolute brightness of a color at 1.0 in V.
Saturation is different too.
]]
-- HasAlpha(c)
function HasAlpha(c)
if c[4] then
return c[4]
else
return 1
end
end
-- ColorToHSV(c)
-- Takes in a normal color("") and returns a table with the HSV values.
function ColorToHSV(c)
local r = c[1]
local g = c[2]
local b = c[3]
-- alpha requires error checking sometimes.
local a = HasAlpha(c)
local h = 0
local s = 0
local v = 0
local min = math.min( r, g, b )
local max = math.max( r, g, b )
v = max
local delta = max - min
-- xxx: how do we deal with complete black?
if min == 0 and max == 0 then
-- we have complete darkness; make it cheap.
return {
Hue = 0,
Sat = 0,
Value = 0,
Alpha = a
}
end
if max ~= 0 then
s = delta / max -- rofl deltamax :|
else
-- r = g = b = 0; s = 0, v is undefined
s = 0
h = -1
return {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
end
if r == max then
h = ( g - b ) / delta -- yellow/magenta
elseif g == max then
h = 2 + ( b - r ) / delta -- cyan/yellow
else
h = 4 + ( r - g ) / delta -- magenta/cyan
end
h = h * 60 -- degrees
if h < 0 then
h = h + 360
end
return {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
end
-- HSVToColor(hsv)
-- Converts a set of HSV values to a color. hsv is a table.
-- See also: HSV(h, s, v)
function HSVToColor(hsv)
local i
local f, q, p, t
local r, g, b
local h, s, v
local a
s = hsv.Sat
v = hsv.Value
if hsv.Alpha then
a = hsv.Alpha
else
a = 0
end
if s == 0 then
return { v, v, v, a }
end
h = hsv.Hue / 60
i = math.floor(h)
f = h - i
p = v * (1-s)
q = v * (1-s*f)
t = v * (1-s*(1-f))
if i == 0 then
return { v, t, p, a }
elseif i == 1 then
return { q, v, p, a }
elseif i == 2 then
return { p, v, t, a }
elseif i == 3 then
return { p, q, v, a }
elseif i == 4 then
return { t, p, v, a }
else
return { v, p, q, a }
end
end
-- ColorToHex(c)
-- Takes in a normal color("") and returns the hex representation.
-- Adapted from code in LuaBit (http://luaforge.net/projects/bit/),
-- which is MIT licensed and copyright (C) 2006~2007 hanzhao.
function ColorToHex(c)
local r = c[1]
local g = c[2]
local b = c[3]
local a = HasAlpha(c)
local function hex(value)
value = math.ceil(value)
local hexVals = { 'A', 'B', 'C', 'D', 'E', 'F' }
local out = ""
local last = 0
while(value ~= 0) do
last = math.mod(value, 16)
if(last < 10) then
out = tostring(last) .. out
else
out = hexVals[(last-10)+1] .. out
end
value = math.floor(value/16)
end
if(out == "") then
return "00"
end
return string.format( "%02X", tonumber(out,16) )
end
local rX = hex( scale(r, 0, 1, 0, 255) )
local gX = hex( scale(g, 0, 1, 0, 255) )
local bX = hex( scale(b, 0, 1, 0, 255) )
local aX = hex( scale(a, 0, 1, 0, 255) )
return rX .. gX .. bX .. aX
end
function HSVToHex(hsv)
return ColorToHex( HSVToColor(hsv) )
end
--[[ you should mainly use these functions ]]
-- this is the lazy one; use this when you mean fullly visible
function HSV(h, s, v)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
return HSVToColor(t)
end
-- here's the proper one
function HSVA(h, s, v, a)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
return HSVToColor(t)
end
function Saturation(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Sat = percent
return HSVToColor(c)
end
function Brightness(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Value = percent
return HSVToColor(c)
end
function Hue(color,newHue)
local c = ColorToHSV(color)
-- handle wrapping
if newHue < 0 then
newHue = 360 + newHue
elseif newHue > 360 then
--newHue = math.mod(newHue, 360); -- ?? untested
newHue = newHue - 360
end
c.Hue = newHue
return HSVToColor(c)
--[[
functions for using HSV colors in StepMania.
Code adapted from http://www.cs.rit.edu/~ncs/color/t_convert.html
changelog:
v 1
= v1.1 =
* Hue(color, newHue) changed to wrap around for invalid values.
* Desaturate(color, percent) renamed to Saturation(color, percent).
______________________________________________________________________________
xxx: support HSL<->RGB (which is different) too?
http://en.wikipedia.org/wiki/HSV_color_space#Conversion_from_RGB_to_HSL_or_HSV
HSL treats absolute brightness of a color at 0.5 in L, whereas
HSV treats absolute brightness of a color at 1.0 in V.
Saturation is different too.
]]
-- HasAlpha(c)
function HasAlpha(c)
if c[4] then
return c[4]
else
return 1
end
end
-- ColorToHSV(c)
-- Takes in a normal color("") and returns a table with the HSV values.
function ColorToHSV(c)
local r = c[1]
local g = c[2]
local b = c[3]
-- alpha requires error checking sometimes.
local a = HasAlpha(c)
local h = 0
local s = 0
local v = 0
local min = math.min( r, g, b )
local max = math.max( r, g, b )
v = max
local delta = max - min
-- xxx: how do we deal with complete black?
if min == 0 and max == 0 then
-- we have complete darkness; make it cheap.
return {
Hue = 0,
Sat = 0,
Value = 0,
Alpha = a
}
end
if max ~= 0 then
s = delta / max -- rofl deltamax :|
else
-- r = g = b = 0; s = 0, v is undefined
s = 0
h = -1
return {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
end
if r == max then
h = ( g - b ) / delta -- yellow/magenta
elseif g == max then
h = 2 + ( b - r ) / delta -- cyan/yellow
else
h = 4 + ( r - g ) / delta -- magenta/cyan
end
h = h * 60 -- degrees
if h < 0 then
h = h + 360
end
return {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
end
-- HSVToColor(hsv)
-- Converts a set of HSV values to a color. hsv is a table.
-- See also: HSV(h, s, v)
function HSVToColor(hsv)
local i
local f, q, p, t
local r, g, b
local h, s, v
local a
s = hsv.Sat
v = hsv.Value
if hsv.Alpha then
a = hsv.Alpha
else
a = 0
end
if s == 0 then
return { v, v, v, a }
end
h = hsv.Hue / 60
i = math.floor(h)
f = h - i
p = v * (1-s)
q = v * (1-s*f)
t = v * (1-s*(1-f))
if i == 0 then
return { v, t, p, a }
elseif i == 1 then
return { q, v, p, a }
elseif i == 2 then
return { p, v, t, a }
elseif i == 3 then
return { p, q, v, a }
elseif i == 4 then
return { t, p, v, a }
else
return { v, p, q, a }
end
end
-- ColorToHex(c)
-- Takes in a normal color("") and returns the hex representation.
-- Adapted from code in LuaBit (http://luaforge.net/projects/bit/),
-- which is MIT licensed and copyright (C) 2006~2007 hanzhao.
function ColorToHex(c)
local r = c[1]
local g = c[2]
local b = c[3]
local a = HasAlpha(c)
local function hex(value)
value = math.ceil(value)
local hexVals = { 'A', 'B', 'C', 'D', 'E', 'F' }
local out = ""
local last = 0
while(value ~= 0) do
last = math.mod(value, 16)
if(last < 10) then
out = tostring(last) .. out
else
out = hexVals[(last-10)+1] .. out
end
value = math.floor(value/16)
end
if(out == "") then
return "00"
end
return string.format( "%02X", tonumber(out,16) )
end
local rX = hex( scale(r, 0, 1, 0, 255) )
local gX = hex( scale(g, 0, 1, 0, 255) )
local bX = hex( scale(b, 0, 1, 0, 255) )
local aX = hex( scale(a, 0, 1, 0, 255) )
return rX .. gX .. bX .. aX
end
function HSVToHex(hsv)
return ColorToHex( HSVToColor(hsv) )
end
--[[ you should mainly use these functions ]]
-- this is the lazy one; use this when you mean fullly visible
function HSV(h, s, v)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
return HSVToColor(t)
end
-- here's the proper one
function HSVA(h, s, v, a)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
return HSVToColor(t)
end
function Saturation(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Sat = percent
return HSVToColor(c)
end
function Brightness(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Value = percent
return HSVToColor(c)
end
function Hue(color,newHue)
local c = ColorToHSV(color)
-- handle wrapping
if newHue < 0 then
newHue = 360 + newHue
elseif newHue > 360 then
--newHue = math.mod(newHue, 360); -- ?? untested
newHue = newHue - 360
end
c.Hue = newHue
return HSVToColor(c)
end;
+119 -119
View File
@@ -1,119 +1,119 @@
--[[
IniFile: basically a Lua rewrite of SM's IniFile class that serves as the
basis for the sm-ssc UserPrefs and ThemePrefs configuration systems.
Note that this is a namespace, not a class per se.
--]]
-- TODO: move this into a more general section
-- func takes a key and a value
function foreach_ordered( tbl, func )
local keys = { }
for k,_ in pairs(tbl) do keys[#keys+1] = k end
table.sort( keys )
-- iterate in sorted order
for _,key in ipairs(keys) do func( key, tbl[key]) end
end
-- redeclared here for my sanity's sake
-- TODO: declare these as global variables
local RageFile =
{
READ = 1,
WRITE = 2,
STREAMED = 4,
SLOW_FLUSH = 8
}
-- IniFile namespace
IniFile =
{
StrToKeyVal = function( str )
local _, _, key, value = str:find( "(.+)=(.*)" )
-- key is always a string, but value may be num, bool, or nil.
-- do a few quick checks to see which one it is.
-- if it's a nil, convert it to an empty string and return
if value == nil then value = ""; return key, value; end
-- if it's a number, convert it in place and return
if tonumber(value) ~= nil then value = tonumber(value); return key, value; end
-- not a number, so let's try a boolean value
if value == "true" then value = true;
elseif value == "false" then value = false;
end
return key, value
end,
ReadFile = function( file_path )
Trace( "IniFile.ReadFile( " .. file_path .. " )" )
local file = RageFileUtil.CreateRageFile()
if not file:Open(file_path, RageFile.READ) then
Warn( string.format("ReadFile(%s): %s",file_path,file:GetError()) )
file:destroy()
return { } -- return a blank table
end
local tbl = { }
local current = tbl
while not file:AtEOF() do
local str = file:GetLine()
-- is this a section?
local _, _, sec = str:find( "%[(.+)%]" )
-- if so, set focus there; otherwise, try to
-- read a key/value pair (ignore blank lines)
if sec then
-- if this section doesn't exist, create it
tbl[sec] = tbl[sec] and tbl[sec] or { }
current = tbl[sec]
Warn( "Switching section to " .. sec )
else
local k, v = IniFile.StrToKeyVal( str )
if k and v then current[k] = v end
end
end
file:Close()
file:destroy()
return tbl
end,
WriteFile = function( file_path, tbl )
Trace( "IniFile.WriteFile( " .. file_path .. " )" )
local file = RageFileUtil.CreateRageFile()
if not file:Open(file_path, RageFile.WRITE) then
Warn( string.format("WriteFile(%s): %s",file_path.file:GetError()) )
file:destroy()
return false
end
-- declare functions so we can write with foreach_ordered
local function put_pair( k, v )
file:PutLine( string.format("%s=%s", k, tostring(v)) )
end
local function put_section( section, pair )
file:PutLine( "[" .. section .. "]" )
foreach_ordered( pair, put_pair )
file:PutLine("") -- put a blank line between sections
end
-- each base key is a section and its value is a
-- table of key-value pairs under that section.
foreach_ordered( tbl, put_section )
file:Close()
file:destroy()
return true
end
};
--[[
IniFile: basically a Lua rewrite of SM's IniFile class that serves as the
basis for the sm-ssc UserPrefs and ThemePrefs configuration systems.
Note that this is a namespace, not a class per se.
--]]
-- TODO: move this into a more general section
-- func takes a key and a value
function foreach_ordered( tbl, func )
local keys = { }
for k,_ in pairs(tbl) do keys[#keys+1] = k end
table.sort( keys )
-- iterate in sorted order
for _,key in ipairs(keys) do func( key, tbl[key]) end
end
-- redeclared here for my sanity's sake
-- TODO: declare these as global variables
local RageFile =
{
READ = 1,
WRITE = 2,
STREAMED = 4,
SLOW_FLUSH = 8
}
-- IniFile namespace
IniFile =
{
StrToKeyVal = function( str )
local _, _, key, value = str:find( "(.+)=(.*)" )
-- key is always a string, but value may be num, bool, or nil.
-- do a few quick checks to see which one it is.
-- if it's a nil, convert it to an empty string and return
if value == nil then value = ""; return key, value; end
-- if it's a number, convert it in place and return
if tonumber(value) ~= nil then value = tonumber(value); return key, value; end
-- not a number, so let's try a boolean value
if value == "true" then value = true;
elseif value == "false" then value = false;
end
return key, value
end,
ReadFile = function( file_path )
Trace( "IniFile.ReadFile( " .. file_path .. " )" )
local file = RageFileUtil.CreateRageFile()
if not file:Open(file_path, RageFile.READ) then
Warn( string.format("ReadFile(%s): %s",file_path,file:GetError()) )
file:destroy()
return { } -- return a blank table
end
local tbl = { }
local current = tbl
while not file:AtEOF() do
local str = file:GetLine()
-- is this a section?
local _, _, sec = str:find( "%[(.+)%]" )
-- if so, set focus there; otherwise, try to
-- read a key/value pair (ignore blank lines)
if sec then
-- if this section doesn't exist, create it
tbl[sec] = tbl[sec] and tbl[sec] or { }
current = tbl[sec]
Warn( "Switching section to " .. sec )
else
local k, v = IniFile.StrToKeyVal( str )
if k and v then current[k] = v end
end
end
file:Close()
file:destroy()
return tbl
end,
WriteFile = function( file_path, tbl )
Trace( "IniFile.WriteFile( " .. file_path .. " )" )
local file = RageFileUtil.CreateRageFile()
if not file:Open(file_path, RageFile.WRITE) then
Warn( string.format("WriteFile(%s): %s",file_path.file:GetError()) )
file:destroy()
return false
end
-- declare functions so we can write with foreach_ordered
local function put_pair( k, v )
file:PutLine( string.format("%s=%s", k, tostring(v)) )
end
local function put_section( section, pair )
file:PutLine( "[" .. section .. "]" )
foreach_ordered( pair, put_pair )
file:PutLine("") -- put a blank line between sections
end
-- each base key is a section and its value is a
-- table of key-value pairs under that section.
foreach_ordered( tbl, put_section )
file:Close()
file:destroy()
return true
end
};
@@ -1,252 +1,252 @@
-- ProductivityHelpers: A set of useful aliases for theming.
-- This is the sm-ssc version. You should not be using this in themes for
-- SM4 right now... We'll post an updated version soon.
--[[ Globals ]]
function IsArcade()
local sPayMode = GAMESTATE:GetCoinMode();
local bIsArcade = (sPayMode ~= 'CoinMode_Home');
return bIsArcade;
end
function IsHome()
local sPayMode = GAMESTATE:GetCoinMode();
local bIsHome = (sPayMode == 'CoinMode_Home');
return bIsHome;
end
function IsFreePlay()
if IsArcade() then
return (GAMESTATE:GetCoinMode() == 'CoinMode_Free');
else
return false
end
end
function Center1Player()
if GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerTwoSides" then
return true
elseif PREFSMAN:GetPreference("Center1Player") then
if GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerOneSide" then
return true
else
return false
end
else
return false
end
--[[ return PREFSMAN:GetPreference("Center1Player") and
THEME:GetMetric("ScreenGameplay","AllowCenter1Player") and
not GAMESTATE:GetPlayMode("PlayMode_Battle") and
not GAMESTATE:GetPlayMode("PlayMode_Rave") and
GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerOneSide"; --]]
end
--[[ 3.9 Conditionals ]]
Condition = {
Hour = function()
return Hour()
end,
IsDemonstration = function()
return GAMESTATE:IsDemonstration()
end,
CurSong = function(sSongName)
return GAMESTATE:GetCurrentSong():GetDisplayMainTitle() == sSongName
end,
DayOfMonth = function()
return DayOfMonth()
end,
MonthOfYear = function()
return MonthOfYear()
end,
UsingModifier = function(pnPlayer, sModifier)
return GAMESTATE:PlayerIsUsingModifier( pnPlayer, sModifier );
end,
}
--[[ 3.9 Functions ]]
Game = {
GetStage = function()
end,
}
--[[ Aliases ]]
-- Blend Modes
-- Aliases for blend modes.
Blend = {
Normal = 'BlendMode_Normal',
Add = 'BlendMode_Add',
Modulate = 'BlendMode_Modulate',
Multiply = 'BlendMode_WeightedMultiply',
Invert = 'BlendMode_InvertDest',
NoEffect = 'BlendMode_NoEffect',
}
-- Health Declarations
-- Used primarily for lifebars.
Health = {
Max = 'HealthState_Hot',
Alive = 'HealthState_Alive',
Danger = 'HealthState_Danger',
Dead = 'HealthState_Dead'
}
-- Make graphics their true size at any resolution.
--[[
Note: for screens taller than wide (i.e. phones, sideways displays),
you'll need to get width rather than height (I just don't feel like
uglyfying my code just to handle rare cases). -shake
--]]
-- useful
function GetReal()
local theme = THEME:GetMetric("Common","ScreenHeight")
local res = PREFSMAN:GetPreference("DisplayHeight")
return theme/res
end
function GetRealInverse()
local theme = THEME:GetMetric("Common","ScreenHeight")
local res = PREFSMAN:GetPreference("DisplayHeight")
return res/theme
end
function Actor:Real()
-- scale back down to real pixels.
self:basezoom(GetReal())
-- don't make this ugly
self:SetTextureFiltering(false)
end
-- Scale things back up after they have already been scaled down.
function Actor:RealInverse()
-- scale back up to theme resolution
self:basezoom(GetRealInverse())
self:SetTextureFiltering(true)
end
--[[ Actor commands ]]
function Actor:CenterX()
self:x(SCREEN_CENTER_X)
end
function Actor:CenterY()
self:y(SCREEN_CENTER_Y)
end
-- xy(actorX,actorY)
-- Sets the x and y of an actor in one command.
function Actor:xy(actorX,actorY)
self:x(actorX)
self:y(actorY)
end
-- MaskSource([clearzbuffer])
-- Sets an actor up as the source for a mask. Clears zBuffer by default.
function Actor:MaskSource(noclear)
self:clearzbuffer(noclear or true)
self:zwrite(true)
self:blend('BlendMode_NoEffect')
end
-- MaskDest()
-- Sets an actor up to be masked by anything with MaskSource().
function Actor:MaskDest()
self:ztest(true)
end
-- Thump()
-- A customized version of pulse that is more appealing for on-beat
-- effects;
function Actor:thump(fEffectPeriod)
self:pulse()
if fEffectPeriod ~= nil then
self:effecttiming(0,0,0.75*fEffectPeriod,0.25*fEffectPeriod)
else
self:effecttiming(0,0,0.75,0.25)
end
-- The default effectmagnitude will make this effect look very bad.
self:effectmagnitude(1,1.125,1)
end
-- Heartbeat()
-- A customized version of pulse that is more appealing for on-beat
-- effects;
function Actor:heartbeat(fEffectPeriod)
self:pulse()
if fEffectPeriod ~= nil then
self:effecttiming(0,0.125*fEffectPeriod,0.125*fEffectPeriod,0.75*fEffectPeriod);
else
self:effecttiming(0,0.125,0.125,0.75);
end
self:effecmagnitude(1,1.125,1)
end
--[[ BitmapText commands ]]
-- PixelFont()
-- An alias that turns off texture filtering.
-- Named because it works best with pixel fonts.
function BitmapText:PixelFont()
self:SetTextureFiltering(false)
end
-- Stroke(color)
-- Sets the text's stroke color.
function BitmapText:Stroke(c)
self:strokecolor( c )
end
-- NoStroke()
-- Removes any stroke.
function BitmapText:NoStroke()
self:strokecolor( color("0,0,0,0") )
end
-- Set Text With Format (contributed by Daisuke Master)
-- this function is my hero - shake
function BitmapText:settextf(...)
self:settext(string.format(...))
end
-- DiffuseAndStroke(diffuse,stroke)
-- Set diffuse and stroke at the same time.
function BitmapText:DiffuseAndStroke(diffuseC,strokeC)
self:diffuse(diffuseC)
self:strokecolor(strokeC)
end;
--[[ end BitmapText commands ]]
--[[ ----------------------------------------------------------------------- ]]
--[[ helper functions ]]
function tobool(v)
if type(v) == "string" then
local cmp = string.lower(v)
if cmp == "true" or cmp == "t" then
return true
elseif cmp == "false" or cmp == "f" then
return false
end
elseif type(v) == "number" then
if v == 0 then
return false
else
return true
end
end
end
function pname(pn)
return ToEnumShortString(pn)
end
function math.round(num, pre)
if pre and pre < 0 then pre = 0 end
local mult = 10^(pre or 0)
if num >= 0 then return math.floor(num*mult+.5)/mult
else return math.ceil(num*mult-.5)/mult end
end
--[[ end helper functions ]]
-- this code is in the public domain.
-- ProductivityHelpers: A set of useful aliases for theming.
-- This is the sm-ssc version. You should not be using this in themes for
-- SM4 right now... We'll post an updated version soon.
--[[ Globals ]]
function IsArcade()
local sPayMode = GAMESTATE:GetCoinMode();
local bIsArcade = (sPayMode ~= 'CoinMode_Home');
return bIsArcade;
end
function IsHome()
local sPayMode = GAMESTATE:GetCoinMode();
local bIsHome = (sPayMode == 'CoinMode_Home');
return bIsHome;
end
function IsFreePlay()
if IsArcade() then
return (GAMESTATE:GetCoinMode() == 'CoinMode_Free');
else
return false
end
end
function Center1Player()
if GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerTwoSides" then
return true
elseif PREFSMAN:GetPreference("Center1Player") then
if GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerOneSide" then
return true
else
return false
end
else
return false
end
--[[ return PREFSMAN:GetPreference("Center1Player") and
THEME:GetMetric("ScreenGameplay","AllowCenter1Player") and
not GAMESTATE:GetPlayMode("PlayMode_Battle") and
not GAMESTATE:GetPlayMode("PlayMode_Rave") and
GAMESTATE:GetCurrentStyle():GetStyleType() == "StyleType_OnePlayerOneSide"; --]]
end
--[[ 3.9 Conditionals ]]
Condition = {
Hour = function()
return Hour()
end,
IsDemonstration = function()
return GAMESTATE:IsDemonstration()
end,
CurSong = function(sSongName)
return GAMESTATE:GetCurrentSong():GetDisplayMainTitle() == sSongName
end,
DayOfMonth = function()
return DayOfMonth()
end,
MonthOfYear = function()
return MonthOfYear()
end,
UsingModifier = function(pnPlayer, sModifier)
return GAMESTATE:PlayerIsUsingModifier( pnPlayer, sModifier );
end,
}
--[[ 3.9 Functions ]]
Game = {
GetStage = function()
end,
}
--[[ Aliases ]]
-- Blend Modes
-- Aliases for blend modes.
Blend = {
Normal = 'BlendMode_Normal',
Add = 'BlendMode_Add',
Modulate = 'BlendMode_Modulate',
Multiply = 'BlendMode_WeightedMultiply',
Invert = 'BlendMode_InvertDest',
NoEffect = 'BlendMode_NoEffect',
}
-- Health Declarations
-- Used primarily for lifebars.
Health = {
Max = 'HealthState_Hot',
Alive = 'HealthState_Alive',
Danger = 'HealthState_Danger',
Dead = 'HealthState_Dead'
}
-- Make graphics their true size at any resolution.
--[[
Note: for screens taller than wide (i.e. phones, sideways displays),
you'll need to get width rather than height (I just don't feel like
uglyfying my code just to handle rare cases). -shake
--]]
-- useful
function GetReal()
local theme = THEME:GetMetric("Common","ScreenHeight")
local res = PREFSMAN:GetPreference("DisplayHeight")
return theme/res
end
function GetRealInverse()
local theme = THEME:GetMetric("Common","ScreenHeight")
local res = PREFSMAN:GetPreference("DisplayHeight")
return res/theme
end
function Actor:Real()
-- scale back down to real pixels.
self:basezoom(GetReal())
-- don't make this ugly
self:SetTextureFiltering(false)
end
-- Scale things back up after they have already been scaled down.
function Actor:RealInverse()
-- scale back up to theme resolution
self:basezoom(GetRealInverse())
self:SetTextureFiltering(true)
end
--[[ Actor commands ]]
function Actor:CenterX()
self:x(SCREEN_CENTER_X)
end
function Actor:CenterY()
self:y(SCREEN_CENTER_Y)
end
-- xy(actorX,actorY)
-- Sets the x and y of an actor in one command.
function Actor:xy(actorX,actorY)
self:x(actorX)
self:y(actorY)
end
-- MaskSource([clearzbuffer])
-- Sets an actor up as the source for a mask. Clears zBuffer by default.
function Actor:MaskSource(noclear)
self:clearzbuffer(noclear or true)
self:zwrite(true)
self:blend('BlendMode_NoEffect')
end
-- MaskDest()
-- Sets an actor up to be masked by anything with MaskSource().
function Actor:MaskDest()
self:ztest(true)
end
-- Thump()
-- A customized version of pulse that is more appealing for on-beat
-- effects;
function Actor:thump(fEffectPeriod)
self:pulse()
if fEffectPeriod ~= nil then
self:effecttiming(0,0,0.75*fEffectPeriod,0.25*fEffectPeriod)
else
self:effecttiming(0,0,0.75,0.25)
end
-- The default effectmagnitude will make this effect look very bad.
self:effectmagnitude(1,1.125,1)
end
-- Heartbeat()
-- A customized version of pulse that is more appealing for on-beat
-- effects;
function Actor:heartbeat(fEffectPeriod)
self:pulse()
if fEffectPeriod ~= nil then
self:effecttiming(0,0.125*fEffectPeriod,0.125*fEffectPeriod,0.75*fEffectPeriod);
else
self:effecttiming(0,0.125,0.125,0.75);
end
self:effecmagnitude(1,1.125,1)
end
--[[ BitmapText commands ]]
-- PixelFont()
-- An alias that turns off texture filtering.
-- Named because it works best with pixel fonts.
function BitmapText:PixelFont()
self:SetTextureFiltering(false)
end
-- Stroke(color)
-- Sets the text's stroke color.
function BitmapText:Stroke(c)
self:strokecolor( c )
end
-- NoStroke()
-- Removes any stroke.
function BitmapText:NoStroke()
self:strokecolor( color("0,0,0,0") )
end
-- Set Text With Format (contributed by Daisuke Master)
-- this function is my hero - shake
function BitmapText:settextf(...)
self:settext(string.format(...))
end
-- DiffuseAndStroke(diffuse,stroke)
-- Set diffuse and stroke at the same time.
function BitmapText:DiffuseAndStroke(diffuseC,strokeC)
self:diffuse(diffuseC)
self:strokecolor(strokeC)
end;
--[[ end BitmapText commands ]]
--[[ ----------------------------------------------------------------------- ]]
--[[ helper functions ]]
function tobool(v)
if type(v) == "string" then
local cmp = string.lower(v)
if cmp == "true" or cmp == "t" then
return true
elseif cmp == "false" or cmp == "f" then
return false
end
elseif type(v) == "number" then
if v == 0 then
return false
else
return true
end
end
end
function pname(pn)
return ToEnumShortString(pn)
end
function math.round(num, pre)
if pre and pre < 0 then pre = 0 end
local mult = 10^(pre or 0)
if num >= 0 then return math.floor(num*mult+.5)/mult
else return math.ceil(num*mult-.5)/mult end
end
--[[ end helper functions ]]
-- this code is in the public domain.
File diff suppressed because it is too large Load Diff
+41 -41
View File
@@ -1,42 +1,42 @@
-- theme library: juicy library that returns lua objects on demand.
Library = {
GrooveRadar = function(self)
local function radarSet(self,player)
local selection = nil;
if GAMESTATE:IsCourseMode() then
if GAMESTATE:GetCurrentCourse() then
selection = GAMESTATE:GetCurrentTrail(player);
end;
else
if GAMESTATE:GetCurrentSong() then
selection = GAMESTATE:GetCurrentSteps(player);
end;
end;
if selection then
self:SetFromRadarValues(player, selection:GetRadarValues(player));
else
self:SetEmpty(player);
end;
end
--
local t = Def.ActorFrame {
Name="Radar";
Def.GrooveRadar {
OnCommand=cmd(zoom,0;sleep,0.583;decelerate,0.150;zoom,1);
OffCommand=cmd(sleep,0.183;decelerate,0.167;zoom,0);
CurrentSongChangedMessageCommand=function(self)
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
radarSet(self, pn);
end;
end;
CurrentStepsP1ChangedMessageCommand=function(self) radarSet(self, PLAYER_1); end;
CurrentStepsP2ChangedMessageCommand=function(self) radarSet(self, PLAYER_2); end;
CurrentTrailP1ChangedMessageCommand=function(self) radarSet(self, PLAYER_1); end;
CurrentTrailP2ChangedMessageCommand=function(self) radarSet(self, PLAYER_2); end;
};
};
return t;
end;
-- theme library: juicy library that returns lua objects on demand.
Library = {
GrooveRadar = function(self)
local function radarSet(self,player)
local selection = nil;
if GAMESTATE:IsCourseMode() then
if GAMESTATE:GetCurrentCourse() then
selection = GAMESTATE:GetCurrentTrail(player);
end;
else
if GAMESTATE:GetCurrentSong() then
selection = GAMESTATE:GetCurrentSteps(player);
end;
end;
if selection then
self:SetFromRadarValues(player, selection:GetRadarValues(player));
else
self:SetEmpty(player);
end;
end
--
local t = Def.ActorFrame {
Name="Radar";
Def.GrooveRadar {
OnCommand=cmd(zoom,0;sleep,0.583;decelerate,0.150;zoom,1);
OffCommand=cmd(sleep,0.183;decelerate,0.167;zoom,0);
CurrentSongChangedMessageCommand=function(self)
for pn in ivalues(GAMESTATE:GetHumanPlayers()) do
radarSet(self, pn);
end;
end;
CurrentStepsP1ChangedMessageCommand=function(self) radarSet(self, PLAYER_1); end;
CurrentStepsP2ChangedMessageCommand=function(self) radarSet(self, PLAYER_2); end;
CurrentTrailP1ChangedMessageCommand=function(self) radarSet(self, PLAYER_1); end;
CurrentTrailP2ChangedMessageCommand=function(self) radarSet(self, PLAYER_2); end;
};
};
return t;
end;
}
+141 -141
View File
@@ -1,141 +1,141 @@
--[[
ThemePrefs: handles the underlying structure for ThemePrefs, so any themes
built off of this can simply declare their prefs and default values, and
access them through this system.
v0.7.1: Dec. 28, 2010. Added language support.
v0.7.0: Dec. 15, 2010. Initial version.
vyhd wrote this for sm-ssc. <3 you guys
--]]
-- local function to handle themed error strings
-- (and to ensure we're getting all of them from the same section)
local function GetString( name )
return THEME:GetString( "ThemePrefs", name )
end
function PrintTable( tbl )
Trace( "Printing table" )
for k,v in pairs(tbl) do
Trace( ("[%s] -> %s"):format(tostring(k),tostring(v)) )
end
end
local ThemePrefsPath = "Save/ThemePrefs.ini";
local FallbackTheme = "_fallback";
-- This will be set on load.
local PrefsTable = nil;
-- Gets the name of the current theme using themeInfo
-- if available and the ThemeManager name otherwise.
local function GetThemeName()
return themeInfo and themeInfo.Name or THEME:GetThemeDisplayName()
end
-- Given a preference name, returns the table it's in. Checks the current
-- theme first, then _fallback, then all other sections, in that order.
local function ResolveTable( pref )
-- check the section for this theme
local name = GetThemeName()
local val = PrefsTable[name][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in %s"):format(pref,name) )
return PrefsTable[name]
end
-- not in the current theme; check the fallback if it exists
if PrefsTable[FallbackTheme] then
val = PrefsTable[FallbackTheme][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in fallback"):format(pref) )
return PrefsTable[FallbackTheme]
end
end
-- not there either. check every section.
-- XXX: we should do this less redundantly.
for section, _ in pairs(PrefsTable) do
val = PrefsTable[section][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in section %s"):format(pref,section) )
return PrefsTable[section] end
end
-- not found at all
Trace( ("ResolveTable(%s): pref not found"):format(pref) )
return nil
end
ThemePrefs =
{
NeedsSaved = false,
-- Loads preferences from Save/ThemePrefs.ini, then adds theme
-- preferences (and default values if applicable) to PrefsTable.
-- Only read from disk once, when _fallback calls this; we just
-- need the base set once to add prefs onto.
Init = function( prefs, bLoadFromDisk )
-- If we don't have IniFile, we can't read/write from/to disk
if not IniFile then Warn( GetString("IniFileMissing") ) end
Trace( ("ThemePrefs.Init(prefs, %s)"):format(tostring(bLoadFromDisk)) )
if bLoadFromDisk then
Trace( "ThemePrefs.Init: loading from disk" )
if not ThemePrefs.Load() then return false end
end
Trace( "ThemePrefs.Init: not loading from disk" )
-- create the section if it doesn't exist
local section = GetThemeName()
PrefsTable[section] = PrefsTable[section] and PrefsTable[section] or { }
Trace( "Using section " .. section )
-- if the key doesn't exist, add it with our default value
for k, tbl in pairs(prefs) do
if not PrefsTable[section][k] then
Trace( k .. " doesn't exist, creating" )
PrefsTable[section][k] = tbl.Default
end
end
PrintTable( PrefsTable[section] )
end,
Load = function()
if not IniFile then return false end
PrefsTable = IniFile.ReadFile( ThemePrefsPath )
return true
end,
Save = function()
Trace( "ThemePrefs.Save" )
if not IniFile then return false end
if not NeedsSaved then return end
NeedsSaved = false
IniFile.WriteFile( ThemePrefsPath, PrefsTable )
end,
Get = function( name )
Trace( ("ThemePrefs.Get(%s)"):format(name) )
local tbl = ResolveTable(name)
if tbl then return tbl[name] end
Warn( "Get: "..GetString("UnknownPreference"):format(name) )
return nil
end,
Set = function( name, value )
Trace( ("ThemePrefs.Set(%s, %s)"):format(name, tostring(value)) )
local tbl = ResolveTable(name)
if tbl then tbl[name] = value; NeedsSaved = true; return end
Warn( "Set: "..GetString("UnknownPreference"):format(name) )
end,
};
-- global aliases
GetThemePref = ThemePrefs.Get
SetThemePref = ThemePrefs.Set
--[[
ThemePrefs: handles the underlying structure for ThemePrefs, so any themes
built off of this can simply declare their prefs and default values, and
access them through this system.
v0.7.1: Dec. 28, 2010. Added language support.
v0.7.0: Dec. 15, 2010. Initial version.
vyhd wrote this for sm-ssc. <3 you guys
--]]
-- local function to handle themed error strings
-- (and to ensure we're getting all of them from the same section)
local function GetString( name )
return THEME:GetString( "ThemePrefs", name )
end
function PrintTable( tbl )
Trace( "Printing table" )
for k,v in pairs(tbl) do
Trace( ("[%s] -> %s"):format(tostring(k),tostring(v)) )
end
end
local ThemePrefsPath = "Save/ThemePrefs.ini";
local FallbackTheme = "_fallback";
-- This will be set on load.
local PrefsTable = nil;
-- Gets the name of the current theme using themeInfo
-- if available and the ThemeManager name otherwise.
local function GetThemeName()
return themeInfo and themeInfo.Name or THEME:GetThemeDisplayName()
end
-- Given a preference name, returns the table it's in. Checks the current
-- theme first, then _fallback, then all other sections, in that order.
local function ResolveTable( pref )
-- check the section for this theme
local name = GetThemeName()
local val = PrefsTable[name][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in %s"):format(pref,name) )
return PrefsTable[name]
end
-- not in the current theme; check the fallback if it exists
if PrefsTable[FallbackTheme] then
val = PrefsTable[FallbackTheme][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in fallback"):format(pref) )
return PrefsTable[FallbackTheme]
end
end
-- not there either. check every section.
-- XXX: we should do this less redundantly.
for section, _ in pairs(PrefsTable) do
val = PrefsTable[section][pref]
if val ~= nil then
Trace( ("ResolveTable(%s): found in section %s"):format(pref,section) )
return PrefsTable[section] end
end
-- not found at all
Trace( ("ResolveTable(%s): pref not found"):format(pref) )
return nil
end
ThemePrefs =
{
NeedsSaved = false,
-- Loads preferences from Save/ThemePrefs.ini, then adds theme
-- preferences (and default values if applicable) to PrefsTable.
-- Only read from disk once, when _fallback calls this; we just
-- need the base set once to add prefs onto.
Init = function( prefs, bLoadFromDisk )
-- If we don't have IniFile, we can't read/write from/to disk
if not IniFile then Warn( GetString("IniFileMissing") ) end
Trace( ("ThemePrefs.Init(prefs, %s)"):format(tostring(bLoadFromDisk)) )
if bLoadFromDisk then
Trace( "ThemePrefs.Init: loading from disk" )
if not ThemePrefs.Load() then return false end
end
Trace( "ThemePrefs.Init: not loading from disk" )
-- create the section if it doesn't exist
local section = GetThemeName()
PrefsTable[section] = PrefsTable[section] and PrefsTable[section] or { }
Trace( "Using section " .. section )
-- if the key doesn't exist, add it with our default value
for k, tbl in pairs(prefs) do
if not PrefsTable[section][k] then
Trace( k .. " doesn't exist, creating" )
PrefsTable[section][k] = tbl.Default
end
end
PrintTable( PrefsTable[section] )
end,
Load = function()
if not IniFile then return false end
PrefsTable = IniFile.ReadFile( ThemePrefsPath )
return true
end,
Save = function()
Trace( "ThemePrefs.Save" )
if not IniFile then return false end
if not NeedsSaved then return end
NeedsSaved = false
IniFile.WriteFile( ThemePrefsPath, PrefsTable )
end,
Get = function( name )
Trace( ("ThemePrefs.Get(%s)"):format(name) )
local tbl = ResolveTable(name)
if tbl then return tbl[name] end
Warn( "Get: "..GetString("UnknownPreference"):format(name) )
return nil
end,
Set = function( name, value )
Trace( ("ThemePrefs.Set(%s, %s)"):format(name, tostring(value)) )
local tbl = ResolveTable(name)
if tbl then tbl[name] = value; NeedsSaved = true; return end
Warn( "Set: "..GetString("UnknownPreference"):format(name) )
end,
};
-- global aliases
GetThemePref = ThemePrefs.Get
SetThemePref = ThemePrefs.Set
+164 -164
View File
@@ -1,164 +1,164 @@
--[[
ThemePrefsRows: you give it the choices, values, and params, and it'll
generate the rest; quirky behavior to be outlined below. Documentation
will be provided once this system is stabilized.
v0.5.2: Dec. 28, 2010. Throw an error for default/value type mismatches.
v0.5.1: Dec. 27, 2010. Fix Choices not necessarily being strings.
v0.5.0: Dec. 15, 2010. Initial version. Not very well tested.
vyhd wrote this for sm-ssc
--]]
-- unless overridden, these parameters will be used for the OptionsRow
local DefaultParams =
{
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = true,
ExportOnChange = false,
EnabledForPlayers = nil,
ReloadRowMessages = nil,
-- takes a function(self, list, pn);
-- if not used, we use the default
LoadSelections = nil,
SaveSelections = nil,
}
-- local alias to simplify error reporting
local function GetString( name )
return THEME:GetString( "ThemePrefsRows", name )
end
local function DefaultLoad( pref, default, choices, values )
return function(self, list, pn)
local val = ThemePrefs.Get( pref )
-- if our current value is here, set focus to that
for i=1, #choices do
if values[i] == val then list[i] = true return end
end
-- try the default value
for i=1, #choices do
if values[i] == default then list[i] = true return end
end
-- set to the first value and output a warning
Warn( GetString("NoDefaultInValues"):format(pref) )
list[1] = true
end
end
local function DefaultSave( pref, choices, values )
local msg = "ThemePrefChanged"
local params = { Name = pref }
return function(self, list, pn)
for i=1, #choices do
if list[i] then ThemePrefs.Set( pref, values[i] ) break end
MESSAGEMAN:Broadcast( msg, params )
end
end
end
-- This function checks for mismatches between the default value and the
-- values table passed to the ThemePrefRow, e.g. it will return false if
-- you have a boolean default and an integer value. I'm somewhat stricter
-- about types than Lua is because I don't like the unpredictability and
-- complexity of coercing values transparently in a bunch of places.
local function TypesMatch( Values, Default )
local DefaultType = type(Default)
for i, value in ipairs(Values) do
local ValueType = type(value)
if ValueType ~= DefaultType then
Warn( GetString("TypeMismatch"):format(DefaultType, i, ValueType) )
return false
end
end
return true
end
local function CreateThemePrefRow( pref, tbl )
-- can't make an option handler without options
if not tbl.Choices then return nil end
local Choices = tbl.Choices
local Default = tbl.Default
local Values = tbl.Values and tbl.Values or Choices
local Params = tbl.Params and tbl.Params or { }
-- if the choices aren't strings, make them strings now
for i, str in ipairs(Choices) do
Choices[i] = tostring( Choices[i] )
end
-- check to see that Values and Choices have the same length
if #Choices ~= #Values then
Warn( GetString("ChoicesSizeMismatch") )
return nil
end
-- check to see that everything in Values matches the type of Default
if not TypesMatch( Values, Default ) then return nil end
-- set the name and choices here; we'll do the rest below
local Handler = { Name = pref, Choices = Choices }
-- add all the keys in DefaultParams, get the value from
-- Params if it exists and DefaultParams otherwise
-- (note that we explicitly check for nil, due to bools.)
for k, _ in pairs(DefaultParams) do
Handler[k] = Params[k] ~= nil and Params[k] or DefaultParams[k]
end
-- if we don't have LoadSelections and SaveSelections, make them
if not Handler.LoadSelections then
Handler.LoadSelections = DefaultLoad( pref, Default, Choices, Values )
end
if not Handler.SaveSelections then
Handler.SaveSelections = DefaultSave( pref, Choices, Values )
end
return Handler
end
-- All OptionsRows for preferences are stuck in this table, accessible
-- through GetRow('name') in the namespace or ThemePrefRow('name') in
-- the global namespace. (I like to keep pollution to a minimum.)
local Rows = { }
ThemePrefsRows =
{
IsInitted = false,
Init = function( prefs )
for pref, tbl in pairs(prefs) do
Rows[pref] = CreateThemePrefRow( pref, tbl )
end
end,
GetRow = function( pref )
Trace( ("GetRow(%s), type %s"):format(pref, type(Rows[pref])) )
return Rows[pref]
end,
}
-- Global namespace alias
ThemePrefRow = ThemePrefsRows.GetRow
-- UGLY: declare this here, even though it's in the previous namespace,
-- so we can have one call to initialize both systems (ThemePrefsRow is
-- declared after ThemePrefs, so it can't actually be in that file...)
ThemePrefs.InitAll = function( prefs )
Trace( "ThemePrefs.InitAll( prefs )" )
ThemePrefs.Init( prefs, true )
ThemePrefsRows.Init( prefs )
end
--[[
ThemePrefsRows: you give it the choices, values, and params, and it'll
generate the rest; quirky behavior to be outlined below. Documentation
will be provided once this system is stabilized.
v0.5.2: Dec. 28, 2010. Throw an error for default/value type mismatches.
v0.5.1: Dec. 27, 2010. Fix Choices not necessarily being strings.
v0.5.0: Dec. 15, 2010. Initial version. Not very well tested.
vyhd wrote this for sm-ssc
--]]
-- unless overridden, these parameters will be used for the OptionsRow
local DefaultParams =
{
LayoutType = "ShowAllInRow",
SelectType = "SelectOne",
OneChoiceForAllPlayers = true,
ExportOnChange = false,
EnabledForPlayers = nil,
ReloadRowMessages = nil,
-- takes a function(self, list, pn);
-- if not used, we use the default
LoadSelections = nil,
SaveSelections = nil,
}
-- local alias to simplify error reporting
local function GetString( name )
return THEME:GetString( "ThemePrefsRows", name )
end
local function DefaultLoad( pref, default, choices, values )
return function(self, list, pn)
local val = ThemePrefs.Get( pref )
-- if our current value is here, set focus to that
for i=1, #choices do
if values[i] == val then list[i] = true return end
end
-- try the default value
for i=1, #choices do
if values[i] == default then list[i] = true return end
end
-- set to the first value and output a warning
Warn( GetString("NoDefaultInValues"):format(pref) )
list[1] = true
end
end
local function DefaultSave( pref, choices, values )
local msg = "ThemePrefChanged"
local params = { Name = pref }
return function(self, list, pn)
for i=1, #choices do
if list[i] then ThemePrefs.Set( pref, values[i] ) break end
MESSAGEMAN:Broadcast( msg, params )
end
end
end
-- This function checks for mismatches between the default value and the
-- values table passed to the ThemePrefRow, e.g. it will return false if
-- you have a boolean default and an integer value. I'm somewhat stricter
-- about types than Lua is because I don't like the unpredictability and
-- complexity of coercing values transparently in a bunch of places.
local function TypesMatch( Values, Default )
local DefaultType = type(Default)
for i, value in ipairs(Values) do
local ValueType = type(value)
if ValueType ~= DefaultType then
Warn( GetString("TypeMismatch"):format(DefaultType, i, ValueType) )
return false
end
end
return true
end
local function CreateThemePrefRow( pref, tbl )
-- can't make an option handler without options
if not tbl.Choices then return nil end
local Choices = tbl.Choices
local Default = tbl.Default
local Values = tbl.Values and tbl.Values or Choices
local Params = tbl.Params and tbl.Params or { }
-- if the choices aren't strings, make them strings now
for i, str in ipairs(Choices) do
Choices[i] = tostring( Choices[i] )
end
-- check to see that Values and Choices have the same length
if #Choices ~= #Values then
Warn( GetString("ChoicesSizeMismatch") )
return nil
end
-- check to see that everything in Values matches the type of Default
if not TypesMatch( Values, Default ) then return nil end
-- set the name and choices here; we'll do the rest below
local Handler = { Name = pref, Choices = Choices }
-- add all the keys in DefaultParams, get the value from
-- Params if it exists and DefaultParams otherwise
-- (note that we explicitly check for nil, due to bools.)
for k, _ in pairs(DefaultParams) do
Handler[k] = Params[k] ~= nil and Params[k] or DefaultParams[k]
end
-- if we don't have LoadSelections and SaveSelections, make them
if not Handler.LoadSelections then
Handler.LoadSelections = DefaultLoad( pref, Default, Choices, Values )
end
if not Handler.SaveSelections then
Handler.SaveSelections = DefaultSave( pref, Choices, Values )
end
return Handler
end
-- All OptionsRows for preferences are stuck in this table, accessible
-- through GetRow('name') in the namespace or ThemePrefRow('name') in
-- the global namespace. (I like to keep pollution to a minimum.)
local Rows = { }
ThemePrefsRows =
{
IsInitted = false,
Init = function( prefs )
for pref, tbl in pairs(prefs) do
Rows[pref] = CreateThemePrefRow( pref, tbl )
end
end,
GetRow = function( pref )
Trace( ("GetRow(%s), type %s"):format(pref, type(Rows[pref])) )
return Rows[pref]
end,
}
-- Global namespace alias
ThemePrefRow = ThemePrefsRows.GetRow
-- UGLY: declare this here, even though it's in the previous namespace,
-- so we can have one call to initialize both systems (ThemePrefsRow is
-- declared after ThemePrefs, so it can't actually be in that file...)
ThemePrefs.InitAll = function( prefs )
Trace( "ThemePrefs.InitAll( prefs )" )
ThemePrefs.Init( prefs, true )
ThemePrefsRows.Init( prefs )
end
+146 -146
View File
@@ -1,147 +1,147 @@
-- UserPreferences: User Preferences "Module"
-- Written by AJ Kelly of KKI Labs / Version 2.11-ssc
-- (modified slightly for Cerulean Skies 2's disregard of the name of the
-- themeinfo variable lol :p)
--[[
the first released version was broken.
this version aims to be simpler, and therefore work.
[changelog]
v2.11-ssc
Remove EnvUtils references; we have it in sm-ssc.
v2.1-ssc
sm-ssc version of UserPrefs. We can now assume players have certain
functionality, like RageFile:GetError().
v2.1
Added type specific GetUserPref functions.
[usage]
First, edit PrefPath to match your theme.
If you use ThemeInfo, then you shouldn't have to edit this.
If you're not using ThemeInfo, then you can replace
".. themeInfo.Name .." with the theme's folder name.
ThemeInfo is documented at http://kki.ajworld.net/wiki/ThemeInfo.lua
After that's set up, read the docs.
]]
local PrefPath = "Data/UserPrefs/".. THEME:GetThemeDisplayName() .."/"
--[[ begin internal stuff; no need to edit below this line. ]]
-- Local internal function to write envs. ___Not for themer use.___
local function WriteEnv(envName,envValue)
return setenv(envName,envValue)
end
function ReadPrefFromFile(name)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
local option
if f:Open(fullFilename,1) then
option = tostring( f:Read() )
WriteEnv(name,option)
f:destroy()
return option
else
local fError = f:GetError()
Trace( "[FileUtils] Error reading ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return nil
end
end
function WritePrefToFile(name,value)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
if f:Open(fullFilename, 2) then
f:Write( tostring(value) )
WriteEnv(name,value)
else
local fError = f:GetError()
Trace( "[FileUtils] Error writing to ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return false
end
f:destroy()
return true
end
--[[ end internal functions; still don't edit below this line ]]
function GetUserPref(name)
return ReadPrefFromFile(name)
end
function SetUserPref(name,value)
return WritePrefToFile(name,value)
end
--[[ type specific, for when you want to be lazy ]]
-- XXX: make set funcs, since I hate dealing with colors and I know
-- other themers would too.
-- GetUserPrefB: boolean
function GetUserPrefB(name)
-- this one is a bit trickier.
local pref = ReadPrefFromFile(name)
if type(pref) == "string" then
pref = string.lower(pref)
if pref == "true" or cmp == "t" then
return true
elseif pref == "false" or cmp == "f" then
return false
else
Trace("Error in GetUserPrefB(".. name ..") converting from string" )
return false
end
elseif type(pref) == "number" then
-- both 0 and -1 are false; if you want to change this,
-- feel free to remove "or pref == -1".
if pref == 0 or pref == -1 then
else
return true
end
end
end
-- GetUserPrefC: color
function GetUserPrefC(name)
-- XXX: make sure it's grabbing a string that can be turned into a color
-- and also possibly handle HSV values too.
return color( ReadPrefFromFile(name) )
end
-- GetUserPrefN: numbers (integers, floats)
function GetUserPrefN(name)
return tonumber( ReadPrefFromFile(name) )
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- UserPreferences: User Preferences "Module"
-- Written by AJ Kelly of KKI Labs / Version 2.11-ssc
-- (modified slightly for Cerulean Skies 2's disregard of the name of the
-- themeinfo variable lol :p)
--[[
the first released version was broken.
this version aims to be simpler, and therefore work.
[changelog]
v2.11-ssc
Remove EnvUtils references; we have it in sm-ssc.
v2.1-ssc
sm-ssc version of UserPrefs. We can now assume players have certain
functionality, like RageFile:GetError().
v2.1
Added type specific GetUserPref functions.
[usage]
First, edit PrefPath to match your theme.
If you use ThemeInfo, then you shouldn't have to edit this.
If you're not using ThemeInfo, then you can replace
".. themeInfo.Name .." with the theme's folder name.
ThemeInfo is documented at http://kki.ajworld.net/wiki/ThemeInfo.lua
After that's set up, read the docs.
]]
local PrefPath = "Data/UserPrefs/".. THEME:GetThemeDisplayName() .."/"
--[[ begin internal stuff; no need to edit below this line. ]]
-- Local internal function to write envs. ___Not for themer use.___
local function WriteEnv(envName,envValue)
return setenv(envName,envValue)
end
function ReadPrefFromFile(name)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
local option
if f:Open(fullFilename,1) then
option = tostring( f:Read() )
WriteEnv(name,option)
f:destroy()
return option
else
local fError = f:GetError()
Trace( "[FileUtils] Error reading ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return nil
end
end
function WritePrefToFile(name,value)
local f = RageFileUtil.CreateRageFile()
local fullFilename = PrefPath..name..".cfg"
if f:Open(fullFilename, 2) then
f:Write( tostring(value) )
WriteEnv(name,value)
else
local fError = f:GetError()
Trace( "[FileUtils] Error writing to ".. fullFilename ..": ".. fError )
f:ClearError()
f:destroy()
return false
end
f:destroy()
return true
end
--[[ end internal functions; still don't edit below this line ]]
function GetUserPref(name)
return ReadPrefFromFile(name)
end
function SetUserPref(name,value)
return WritePrefToFile(name,value)
end
--[[ type specific, for when you want to be lazy ]]
-- XXX: make set funcs, since I hate dealing with colors and I know
-- other themers would too.
-- GetUserPrefB: boolean
function GetUserPrefB(name)
-- this one is a bit trickier.
local pref = ReadPrefFromFile(name)
if type(pref) == "string" then
pref = string.lower(pref)
if pref == "true" or cmp == "t" then
return true
elseif pref == "false" or cmp == "f" then
return false
else
Trace("Error in GetUserPrefB(".. name ..") converting from string" )
return false
end
elseif type(pref) == "number" then
-- both 0 and -1 are false; if you want to change this,
-- feel free to remove "or pref == -1".
if pref == 0 or pref == -1 then
else
return true
end
end
end
-- GetUserPrefC: color
function GetUserPrefC(name)
-- XXX: make sure it's grabbing a string that can be turned into a color
-- and also possibly handle HSV values too.
return color( ReadPrefFromFile(name) )
end
-- GetUserPrefN: numbers (integers, floats)
function GetUserPrefN(name)
return tonumber( ReadPrefFromFile(name) )
end
--[[
Copyright © 2008-2009 AJ Kelly/KKI Labs
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]
+31 -31
View File
@@ -1,32 +1,32 @@
-- fileutils: quick and dirty, not user prefs oriented file io
File = {
Write = function(path,buf)
local f = RageFileUtil.CreateRageFile()
if f:Open(path, 2) then
f:Write( tostring(buf) )
f:destroy()
return true
else
Trace( "[FileUtils] Error writing to ".. path ..": ".. f:GetError() )
f:ClearError()
f:destroy()
return false
end
end,
Read = function(path)
local f = RageFileUtil.CreateRageFile()
local ret = ""
if f:Open(path, 1) then
ret = tostring( f:Read() )
f:destroy()
return ret
else
Trace( "[FileUtils] Error reading from ".. path ..": ".. f:GetError() )
f:ClearError()
f:destroy()
return nil
end
end
}
-- this code if public domain and/or has no copyright, depending on your
-- fileutils: quick and dirty, not user prefs oriented file io
File = {
Write = function(path,buf)
local f = RageFileUtil.CreateRageFile()
if f:Open(path, 2) then
f:Write( tostring(buf) )
f:destroy()
return true
else
Trace( "[FileUtils] Error writing to ".. path ..": ".. f:GetError() )
f:ClearError()
f:destroy()
return false
end
end,
Read = function(path)
local f = RageFileUtil.CreateRageFile()
local ret = ""
if f:Open(path, 1) then
ret = tostring( f:Read() )
f:destroy()
return ret
else
Trace( "[FileUtils] Error reading from ".. path ..": ".. f:GetError() )
f:ClearError()
f:destroy()
return nil
end
end
}
-- this code if public domain and/or has no copyright, depending on your
-- country's laws. I wish for you to use this code freely, without restriction.
@@ -1,26 +1,26 @@
-- supported aspect ratios; some of which I will ignore
-- only really pay attention to any ratio marked with a star;
-- I don't think anyone uses 3:4, 1:1, or 8:3.
-- (Archer added 5:4 later and I didn't account for it yet.)
AspectRatios = {
ThreeFour = 0.75, -- (576x760 at 1024x768)
OneOne = 1.0, -- 480x480 (uses Y)
FiveFour = 1.25, -- 600x480 (1280x1024 is a real use case)
FourThree = 1.33333, --* 640x480
SixteenTen = 1.6, --* 720x480
SixteenNine = 1.77778, --* 853x480
EightThree = 2.66666 -- 1280x480
}
function IsUsingWideScreen()
return GetScreenAspectRatio() >= 1.6
end
-- take and use it as you like, I don't care -aj
-- (although I should mention this file was specific to moonlight and was pretty
-- bad before some editing. -aj)
-- this one is good though:
function WideScale(AR4_3, AR16_9)
return scale( SCREEN_WIDTH, 640, 854, AR4_3, AR16_9 )
-- supported aspect ratios; some of which I will ignore
-- only really pay attention to any ratio marked with a star;
-- I don't think anyone uses 3:4, 1:1, or 8:3.
-- (Archer added 5:4 later and I didn't account for it yet.)
AspectRatios = {
ThreeFour = 0.75, -- (576x760 at 1024x768)
OneOne = 1.0, -- 480x480 (uses Y)
FiveFour = 1.25, -- 600x480 (1280x1024 is a real use case)
FourThree = 1.33333, --* 640x480
SixteenTen = 1.6, --* 720x480
SixteenNine = 1.77778, --* 853x480
EightThree = 2.66666 -- 1280x480
}
function IsUsingWideScreen()
return GetScreenAspectRatio() >= 1.6
end
-- take and use it as you like, I don't care -aj
-- (although I should mention this file was specific to moonlight and was pretty
-- bad before some editing. -aj)
-- this one is good though:
function WideScale(AR4_3, AR16_9)
return scale( SCREEN_WIDTH, 640, 854, AR4_3, AR16_9 )
end
+91 -91
View File
@@ -1,92 +1,92 @@
sm-ssc Scripts Directory: Introduction
--------------------------------------------------------------------------------
Hello, and welcome to the sm-ssc Scripts directory. You'll notice that our Lua
scripts have numbers at the beginning of them. This is to control the order of
execution.
In sm-ssc, scripts in subdirectories of Scripts/ (e.g. Scripts/01/somescript.lua)
are loaded before scripts in the root of Scripts/ (e.g. Scripts/01 base.lua).
This is important to know when making a theme for sm-ssc. It's also important
to know that StepMania 4 (as of alpha 5) will not read scripts in subdirectories.
In sm-ssc, there are five rings of script execution:
00 - Initialization
________________________________________________________________________________
01 - Base
There are three base scripts. "01 base.lua" is taken from StepMania 4's default
theme and sets up very important function overrides and the "Var" alias (for
lua.GetThreadVariable). The other two base scripts are sm-ssc specific.
"01 alias.lua" contains non-compatibility aliases. To quote the file itself:
"This is mainly here for making commands case-insensitive without needing to
clutter up the C++ code. It can also be used to add custom functions that
wouldn't otherwise belong somewhere else."
"01 compat.lua" sets up compatibility aliases for some commands. Some commands
were deprecated in sm-ssc (e.g. hidden), while others were renamed. If a problem
was solved differently in sm-ssc, the corresponding StepMania 4 functions should
live in here, and not the C++ code. (The prime example of this being
PlayerStageStats:IsFullComboW* from SM4, whereas we have
PlayerStageStats:FullComboOfScore, with the tap note score being passed in.)
________________________________________________________________________________
02 - Defaults
The "02" scripts are pretty much the same scripts you'd find in StepMania 4's
default theme. Some scripts do exhibit differences, however. The most notable
of these changes is to "02 Color.lua", which adds a color library to the old
StepMania 4 Colors script.
________________________________________________________________________________
03 - Extensions
Scripts that extend normal (StepMania 4 default theme) functionality belong
in the fourth ring. A number of these scripts come from KKI Labs (EnvUtils2,
CustomSpeedMods, UserPreferences2), while others are from other themes (HSV)
or written for sm-ssc (DateTime, Gameplay).
________________________________________________________________________________
04 - ?
FileUtils and WidescreenHelpers are in the fifth ring. To be honest, I don't
know why they were moved out here. -aj
================================================================================
previously:
SMOKE WEED '98 Scripts Directory Organization,
or "An applied case of application of prefixes to control order of execution".
Based on the original document for NCRX by Synikal, updated for SW98 by various
members of the NAKET Team.
-------------------------------------------------------------------------------
The general idea is that the order of execution in some scripts does matter.
We can use filenames in order to load certain files before others.
It is important to note that you do not always need to follow this order,
especially if certain scripts do not require any dependencies. Typically,
most scripts do not require hierarchy setup, only certain situations
require it.
Here is how we see the general hierarchy at NAKET HQ:
00 = Initialization. Things that get called at the beginning of a theme.
This is good for things that are required by everything. It's considered bad
form to execute your own code before init, but there are ways around it if you
do need to go around it.
Examples include 00 init.lua (SM4 default) and 00 themeInfo.lua (various themes).
01 = Base. After the initialization, the base layer goes on top and adds more
core functionality to StepMania themes.
Examples include 01 base.lua (SM4 default) and various 01 files in sm-ssc's
fallback theme. In sm-ssc, these are treated differently than in normal SM4;
01 files are used for aliasing/compatibility commands, which are just as
important as 01 base.lua.
----
From here on out, these aren't officially used by the normal StepMania
developers; they were invented by other themers.
02 = Extensions. Generally, these are third party extensions, such as the KKI
Labs stuff or vyhd's Genre Generator.
03 = Theme-specific. This layer came into existence with dubaiOne/moonlight.
It should be noted that this is still talking about StepMania 4 alphas, as
sm-ssc introduces loading Scripts/folderA, Scripts/folderB, etc. (just not
sm-ssc Scripts Directory: Introduction
--------------------------------------------------------------------------------
Hello, and welcome to the sm-ssc Scripts directory. You'll notice that our Lua
scripts have numbers at the beginning of them. This is to control the order of
execution.
In sm-ssc, scripts in subdirectories of Scripts/ (e.g. Scripts/01/somescript.lua)
are loaded before scripts in the root of Scripts/ (e.g. Scripts/01 base.lua).
This is important to know when making a theme for sm-ssc. It's also important
to know that StepMania 4 (as of alpha 5) will not read scripts in subdirectories.
In sm-ssc, there are five rings of script execution:
00 - Initialization
________________________________________________________________________________
01 - Base
There are three base scripts. "01 base.lua" is taken from StepMania 4's default
theme and sets up very important function overrides and the "Var" alias (for
lua.GetThreadVariable). The other two base scripts are sm-ssc specific.
"01 alias.lua" contains non-compatibility aliases. To quote the file itself:
"This is mainly here for making commands case-insensitive without needing to
clutter up the C++ code. It can also be used to add custom functions that
wouldn't otherwise belong somewhere else."
"01 compat.lua" sets up compatibility aliases for some commands. Some commands
were deprecated in sm-ssc (e.g. hidden), while others were renamed. If a problem
was solved differently in sm-ssc, the corresponding StepMania 4 functions should
live in here, and not the C++ code. (The prime example of this being
PlayerStageStats:IsFullComboW* from SM4, whereas we have
PlayerStageStats:FullComboOfScore, with the tap note score being passed in.)
________________________________________________________________________________
02 - Defaults
The "02" scripts are pretty much the same scripts you'd find in StepMania 4's
default theme. Some scripts do exhibit differences, however. The most notable
of these changes is to "02 Color.lua", which adds a color library to the old
StepMania 4 Colors script.
________________________________________________________________________________
03 - Extensions
Scripts that extend normal (StepMania 4 default theme) functionality belong
in the fourth ring. A number of these scripts come from KKI Labs (EnvUtils2,
CustomSpeedMods, UserPreferences2), while others are from other themes (HSV)
or written for sm-ssc (DateTime, Gameplay).
________________________________________________________________________________
04 - ?
FileUtils and WidescreenHelpers are in the fifth ring. To be honest, I don't
know why they were moved out here. -aj
================================================================================
previously:
SMOKE WEED '98 Scripts Directory Organization,
or "An applied case of application of prefixes to control order of execution".
Based on the original document for NCRX by Synikal, updated for SW98 by various
members of the NAKET Team.
-------------------------------------------------------------------------------
The general idea is that the order of execution in some scripts does matter.
We can use filenames in order to load certain files before others.
It is important to note that you do not always need to follow this order,
especially if certain scripts do not require any dependencies. Typically,
most scripts do not require hierarchy setup, only certain situations
require it.
Here is how we see the general hierarchy at NAKET HQ:
00 = Initialization. Things that get called at the beginning of a theme.
This is good for things that are required by everything. It's considered bad
form to execute your own code before init, but there are ways around it if you
do need to go around it.
Examples include 00 init.lua (SM4 default) and 00 themeInfo.lua (various themes).
01 = Base. After the initialization, the base layer goes on top and adds more
core functionality to StepMania themes.
Examples include 01 base.lua (SM4 default) and various 01 files in sm-ssc's
fallback theme. In sm-ssc, these are treated differently than in normal SM4;
01 files are used for aliasing/compatibility commands, which are just as
important as 01 base.lua.
----
From here on out, these aren't officially used by the normal StepMania
developers; they were invented by other themers.
02 = Extensions. Generally, these are third party extensions, such as the KKI
Labs stuff or vyhd's Genre Generator.
03 = Theme-specific. This layer came into existence with dubaiOne/moonlight.
It should be noted that this is still talking about StepMania 4 alphas, as
sm-ssc introduces loading Scripts/folderA, Scripts/folderB, etc. (just not
Scripts/folderA/folderB/ although why would you need that?)