From 0ec0c2179e42a5c4e912cacabe2d81d9da2ba8ef Mon Sep 17 00:00:00 2001
From: whiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>
Date: Sat, 29 Aug 2009 16:26:21 +0000
Subject: 3 new lua function ScreenSing.BeatsToSeconds ScreenSing.SecondsToBeat
 (both based on cur. song bpm) ScreenSing.GetSongLines returns a table
 containing the songs line information

git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@1934 b956fd51-792f-4845-bead-9b4dfca2ff2c
---
 Lua/src/lua/ULuaScreenSing.pas | 205 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 191 insertions(+), 14 deletions(-)

(limited to 'Lua/src')

diff --git a/Lua/src/lua/ULuaScreenSing.pas b/Lua/src/lua/ULuaScreenSing.pas
index c205b65b..418d4abd 100644
--- a/Lua/src/lua/ULuaScreenSing.pas
+++ b/Lua/src/lua/ULuaScreenSing.pas
@@ -52,7 +52,19 @@ function ULuaScreenSing_GetScoreBGRect(L: Plua_State): Integer; cdecl;
     t[1..playercount] = rect of players rating bar: table(x, y, w, h) }
 function ULuaScreenSing_GetRBRect(L: Plua_State): Integer; cdecl;
 
-{ ScreenSing.GetBeat() - returns current beat of lyricstate }
+{ ScreenSing.GetBPM - no arguments
+  returns the beats per minutes of the current song in quarts }
+function ULuaScreenSing_GetBPM(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.BeatsToSeconds(Beats: float)
+  returns the time in seconds that the given number of beats (in quarts) last }
+function ULuaScreenSing_BeatsToSeconds(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.SecondsToBeats(Seconds: float)
+  returns the Beats in quarts that the given seconds last }
+function ULuaScreenSing_SecondsToBeats(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.GetBeat() - returns current beat of lyricstate (in quarts) }
 function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
 
 { finishes current song, if sing screen is not shown it will raise
@@ -60,7 +72,7 @@ function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
 function ULuaScreenSing_Finish(L: Plua_State): Integer; cdecl;
 
 { ScreenSing.GetSettings - no arguments
-  returns a table filled with the data of TScreenSing }
+  returns a table filled with the data of TScreenSing.Settings }
 function ULuaScreenSing_GetSettings(L: Plua_State): Integer; cdecl;
 
 { ScreenSing.SetSettings - arguments: Table
@@ -68,16 +80,37 @@ function ULuaScreenSing_GetSettings(L: Plua_State): Integer; cdecl;
   unequal to nil in Table }
 function ULuaScreenSing_SetSettings(L: Plua_State): Integer; cdecl;
 
+{ ScreenSing.GetSongLines - no arguments
+  returns a table filled with lines of the loaded song or
+  nil if no song is loaded (singscreen is not displayed)
+  structure of returned table:
+    array [1.."count of lines"]
+     \
+     | Start: integer - beat the line is displayed at (on top of lyrics display)
+     | Lyric: string  - full lyric of the line
+     | Notes: array [1.."count notes of this line"]
+     \
+      | Start: integer    - beat the note starts at
+      | Length: integer   - length in beats
+      | Tone: integer     - pitch that has to be sung, full range
+      | NoteType: integer - 0 for freestyle, 1 for normal, 2 for golden
+      | Text: string      - text of this fragment }
+function ULuaScreenSing_GetSongLines(L: Plua_State): Integer; cdecl;
+
 const
-  ULuaScreenSing_Lib_f: array [0..7] of lual_reg = (
+  ULuaScreenSing_Lib_f: array [0..11] of lual_reg = (
     (name:'GetScores';func:ULuaScreenSing_GetScores),
     (name:'GetRating';func:ULuaScreenSing_GetRating),
+    (name:'GetBPM';func:ULuaScreenSing_GetBPM),
+    (name:'BeatsToSeconds';func:ULuaScreenSing_BeatsToSeconds),
+    (name:'SecondsToBeats';func:ULuaScreenSing_SecondsToBeats),
     (name:'GetBeat';func:ULuaScreenSing_GetBeat),
     (name:'GetScoreBGRect';func:ULuaScreenSing_GetScoreBGRect),
     (name:'GetRBRect';func:ULuaScreenSing_GetRBRect),
     (name:'Finish';func:ULuaScreenSing_Finish),
     (name:'GetSettings';func:ULuaScreenSing_GetSettings),
-    (name:'SetSettings';func:ULuaScreenSing_SetSettings)
+    (name:'SetSettings';func:ULuaScreenSing_SetSettings),
+    (name:'GetSongLines';func:ULuaScreenSing_GetSongLines)
   );
 
 implementation
@@ -141,6 +174,73 @@ begin
   // leave table on stack, it is our result
 end;
 
+{ ScreenSing.GetBPM - no arguments
+  returns the beats per minutes of the current song in quarts }
+function ULuaScreenSing_GetBPM(L: Plua_State): Integer; cdecl;
+begin
+  lua_ClearStack(L);
+  Result := 1;
+
+  if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+    lua_PushNumber(L, 0) // in case of error
+  else if (Length(CurrentSong.BPM) = 1) then
+    lua_PushNumber(L, CurrentSong.BPM[0].BPM)
+  else
+  begin
+    // to-do: do this for songs w/ BPM changes
+    //        or drop support for BPM changes?!
+  end;
+end;
+
+{ ScreenSing.BeatsToSeconds(Beats: float)
+  returns the time in seconds that the given number of beats (in quarts) last }
+function ULuaScreenSing_BeatsToSeconds(L: Plua_State): Integer; cdecl;
+begin
+  Result := 1;
+
+  if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+    lua_PushNumber(L, 0) // in case of error
+  else if (Length(CurrentSong.BPM) = 1) then
+    lua_PushNumber(L, luaL_CheckNumber(L, 1) * 60 / CurrentSong.BPM[0].BPM)
+  else
+  begin
+    // to-do: do this for songs w/ BPM changes
+    //        or drop support for BPM changes?!
+  end;
+end;
+
+{ ScreenSing.BeatsToSeconds(Seconds: float)
+  returns the Beats in quarts that the given seconds last }
+function ULuaScreenSing_SecondsToBeats(L: Plua_State): Integer; cdecl;
+begin
+  Result := 1;
+
+  if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+    lua_PushNumber(L, 0)
+  else if (Length(CurrentSong.BPM) = 1) then
+    lua_PushNumber(L, luaL_CheckNumber(L, 1) * CurrentSong.BPM[0].BPM / 60
+  else
+  begin
+    // to-do: do this for songs w/ BPM changes
+    //        or drop support for BPM changes?!
+  end;
+end;
+
+{ ScreenSing.GetBeat() - returns current beat of lyricstate (in quarts) }
+function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
+var top: Integer;
+begin
+  //remove arguments (if any)
+  top := lua_gettop(L);
+
+  if (top > 0) then
+    lua_pop(L, top);
+
+  //push result
+  lua_pushnumber(L, LyricsState.MidBeat);
+  Result := 1; //one result
+end;
+
 { returns a table with following structure:
     t[1..playercount] = rect of players ScoreBG: table(x, y, w, h) }
 function ULuaScreenSing_GetScoreBGRect(L: Plua_State): Integer; cdecl;
@@ -294,19 +394,96 @@ begin
   ScreenSing.ApplySettings;
 end;
 
-{ ScreenSing.GetBeat() - returns current beat of lyricstate }
-function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
-var top: Integer;
+{ ScreenSing.GetSongLines - no arguments
+  returns a table filled with lines of the loaded song or
+  nil if no song is loaded (singscreen is not displayed)
+  structure of returned table:
+    array [1.."count of lines"]
+     \
+     | Start: integer - beat the line is displayed at (on top of lyrics display)
+     | Lyric: string  - full lyric of the line
+     | Notes: array [1.."count notes of this line"]
+     \
+      | Start: integer    - beat the note starts at
+      | Length: integer   - length in beats
+      | Tone: integer     - pitch that has to be sung, full range
+      | NoteType: integer - 0 for freestyle, 1 for normal, 2 for golden
+      | Text: string      - text of this fragment }
+function ULuaScreenSing_GetSongLines(L: Plua_State): Integer; cdecl;
+  var
+    I, J: Integer;
 begin
-  //remove arguments (if any)
-  top := lua_gettop(L);
+  Result := 1;
+  if (Display.CurrentScreen = @ScreenSing) and (Length(Lines) >= 1) then
+  begin
+    lua_ClearStack(L);
 
-  if (top > 0) then
-    lua_pop(L, top);
+    if not lua_CheckStack(L, 7) then
+      luaL_Error(L, PChar('can''t allocate enough stack space in ULuaScreenSing_GetSongLines'));
 
-  //push result
-  lua_pushnumber(L, LyricsState.MidBeat);
-  Result := 1; //one result
+    // lines array table
+    lua_CreateTable(L, Length(Lines[0].Line), 0);
+
+    for I := 0 to High(Lines[0].Line) do
+    with Lines[0].Line[I] do
+    begin
+      lua_pushInteger(L, I+1);
+
+      // line struct table
+      lua_CreateTable(L, 0, 3);
+
+      // line start
+      lua_PushInteger(L, Start);
+      lua_SetField(L, -2, PChar('Start'));
+
+      // line lyric
+      lua_PushString(L, PChar(Lyric));
+      lua_SetField(L, -2, PChar('Lyric'));
+
+      //line notes array table
+      lua_CreateTable(L, Length(Note), 0);
+
+      for J := 0 to High(Note) do
+      begin
+        lua_PushInteger(L, J + 1);
+
+        // note struct table
+        lua_CreateTable(L, 0, 5);
+
+        // Notes[J+1].Start
+        lua_PushInteger(L, Note[J].Start);
+        lua_SetField(L, -2, PChar('Start'));
+
+        // Notes[J+1].Length
+        lua_PushInteger(L, Note[J].Length);
+        lua_SetField(L, -2, PChar('Length'));
+
+        // Notes[J+1].Tone
+        lua_PushInteger(L, Note[J].Tone);
+        lua_SetField(L, -2, PChar('Tone'));
+
+        // Notes[J+1].NoteType
+        lua_PushInteger(L, Integer(Note[J].NoteType));
+        lua_SetField(L, -2, PChar('NoteType'));
+
+        // Notes[J+1].Text
+        lua_PushString(L, PChar(Note[J].Text));
+        lua_SetField(L, -2, PChar('Text'));
+
+        lua_SetTable(L, -3);
+      end;
+
+      lua_SetField(L, -2, PChar('Notes'));
+
+      // save line to array table
+      lua_setTable(L, -3);
+    end;
+  end
+  else
+  begin
+    lua_ClearStack(L);
+    lua_pushNil(L);
+  end;
 end;
 
 end.
\ No newline at end of file
-- 
cgit v1.2.3