/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2024 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct ObjSubtitleStr = [ PSUBT_inst : PInstance, PSUBT_iWordTime : I, PSUBT_iMaxWords : I, PSUBT_lContent : [S r1], PSUBT_trm : Timer, PSUBT_bReading : I, PSUBT_bState : I ]mkObjSubtitleStr;; proto sendNext = fun [ObjSubtitleStr] I;; fun deleteOb(inst, obstr)= if (obstr.PSUBT_trm == nil) then nil else ( _deltimer obstr.PSUBT_trm; set obstr.PSUBT_trm = nil; ); set obstr.PSUBT_lContent = nil; 0;; fun cbTimerSubtitle(trm, obstr)= _deltimer trm; set obstr.PSUBT_trm = nil; sendNext obstr; 0;; fun sendNext(obstr)= if (obstr.PSUBT_lContent == nil) then ( if (!obstr.PSUBT_bReading) then nil else SendPluginEvent obstr.PSUBT_inst "End" nil nil; set obstr.PSUBT_bReading = 0; 0; ) else ( let hd obstr.PSUBT_lContent -> w in let strToWordList w -> lw in let (sizelist (strToWordList w)) + 1 -> nbword in //add \n when word number is large let if ((nbword - 1) > (obstr.PSUBT_iMaxWords / 2)) then let splitList lw (nbword / 2) -> [aw bw] in if (sizelist bw) > 1 then strcatn (strcatnSep aw " ")::"\n"::(strcatnSep bw " ")::nil else w else w -> w in ( if (obstr.PSUBT_bReading) then nil else SendPluginEvent obstr.PSUBT_inst "Begin" nil nil; set obstr.PSUBT_bReading = 1; SendPluginEvent obstr.PSUBT_inst "Out" w nil; set obstr.PSUBT_lContent = tl obstr.PSUBT_lContent; if (obstr.PSUBT_trm == nil) then nil else ( _deltimer obstr.PSUBT_trm; set obstr.PSUBT_trm = nil; ); set obstr.PSUBT_trm = _rfltimer _starttimer _channel obstr.PSUBT_iWordTime * nbword @cbTimerSubtitle obstr; ); 0; ); 0;; //TODO priorise comma, dot... fun setMaxWordsPerLine(lw, nbw, nw)= if (lw == nil) then nw else let 0 -> i in let "" -> line in ( while ((i < nbw) && (lw != nil)) do ( let hd lw -> w in set line = strcatn line::" "::w::nil; //keep small words "?" let hd tl lw -> nextw in if ((strlen nextw) < 3) then ( set line = strcatn line::" "::nextw::nil; set lw = tl tl lw; ) else set lw = tl lw; set i = i + 1; ); setMaxWordsPerLine lw nbw lcat nw line::nil; );; fun filterText(l, nbw, nl)= if (l == nil) then nl else let strToWordList hd l -> lw in let setMaxWordsPerLine lw nbw nil -> nw in filterText tl l nbw lcat nl nw;; fun cbSubtitle(inst, from, action, param, reply, obstr)= let filterText strToList param obstr.PSUBT_iMaxWords nil -> lcont in set obstr.PSUBT_lContent = lcat obstr.PSUBT_lContent lcont; if (!obstr.PSUBT_bState || (obstr.PSUBT_trm != nil)) then nil else ( sendNext obstr; ); 0;; fun cbStart(inst, from, action, param, reply, obstr)= if (obstr.PSUBT_bState || (obstr.PSUBT_trm != nil)) then nil else ( set obstr.PSUBT_bState = 1; sendNext obstr; ); 0;; fun cbStop(inst, from, action, param, reply, obstr)= if (obstr.PSUBT_trm == nil) then nil else ( set obstr.PSUBT_bState = 0; _deltimer obstr.PSUBT_trm; set obstr.PSUBT_trm = nil; ); 0;; fun cbClear(inst, from, action, param, reply, obstr)= set obstr.PSUBT_lContent = nil; if (!obstr.PSUBT_bReading) then nil else SendPluginEvent obstr.PSUBT_inst "End" nil nil; set obstr.PSUBT_bReading = 0; 0;; fun cbNext(inst, from, action, param, reply, obstr)= sendNext obstr; 0;; fun cbSetWordTime(inst, from, action, param, reply, obstr)= if ((atoi param) == nil) then nil else set obstr.PSUBT_iWordTime = atoi param; 0;; fun newOb(inst)= let (getPluginInstanceParam inst "text") -> text in let atoi (getPluginInstanceParam inst "wordtime") -> wordtime in let if (wordtime == nil) then 300 else wordtime -> wordtime in let atoi (getPluginInstanceParam inst "maxwords") -> maxwords in let if (maxwords == nil) then 9 else maxwords -> maxwords in let atoi (getPluginInstanceParam inst "init") -> init in let if (init == nil) then 1 else init -> init in let mkObjSubtitleStr [inst wordtime maxwords nil nil 0 init] -> obstr in ( let filterText strToList text obstr.PSUBT_iMaxWords nil -> lcont in set obstr.PSUBT_lContent = lcat obstr.PSUBT_lContent lcont; PluginRegisterAction inst "In" mkfun6 @cbSubtitle obstr; PluginRegisterAction inst "Start" mkfun6 @cbStart obstr; PluginRegisterAction inst "Stop" mkfun6 @cbStop obstr; PluginRegisterAction inst "Clear subtitle" mkfun6 @cbClear obstr; PluginRegisterAction inst "Next input" mkfun6 @cbNext obstr; PluginRegisterAction inst "Set word time" mkfun6 @cbSetWordTime obstr; if (!init) then nil else sendNext obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;