388 lines
8.8 KiB
C++
388 lines
8.8 KiB
C++
#include "SCENE.h"
|
|
#include "Subtitles.h"
|
|
|
|
|
|
int nbSubfiles = 0;
|
|
int maxSubfiles = 16;
|
|
Subfile* subfiles = (Subfile*)ZeroAlloc(maxSubfiles*sizeof(Subfile));
|
|
|
|
|
|
void SaveSubtitle(char * filename, char* dest)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
FILE* file = CC_fopen(dest, "wt");
|
|
if (!file) return;
|
|
for(int j=0; j<subfile->count; j++)
|
|
{
|
|
fprintf(file, "%d\n", j+1);
|
|
int fh, fm, fs, fml, th, tm, ts, tml;
|
|
float from = subfile->subtitles[j].from;
|
|
float to = subfile->subtitles[j].to;
|
|
fh = floor(from/3600);
|
|
th = floor(to/3600);
|
|
fm = floor((from-fh*3600)/60);
|
|
tm = floor((to-th*3600)/60);
|
|
fs = floor(from-fh*3600-fm*60);
|
|
ts = floor(to-th*3600-tm*60);
|
|
fml = (int)((from - (int)(from))*1000);
|
|
if ((int)(from*10000)%10==9) fml++;
|
|
tml = (int)((to - (int)(to))*1000);
|
|
if ((int)(to*10000)%10==9) tml++;
|
|
fprintf(file, "%d%d:%d%d:%d%d,%3d --> %d%d:%d%d:%d%d,%3d\n", fh/10, fh%10, fm/10, fm%10, fs/10, fs%10, fml, th/10, th%10, tm/10, tm%10, ts/10, ts%10, tml);
|
|
if (*subfile->subtitles[j].newText)
|
|
fprintf(file, "%s\n\n", subfile->subtitles[j].newText);
|
|
else
|
|
fprintf(file, "%s\n\n", subfile->subtitles[j].text);
|
|
}
|
|
CC_fclose(file);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SetSubtitle(char * filename, char* text, float time)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
for(int j=0; j<subfile->count; j++)
|
|
{
|
|
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
|
|
strcpy(subfile->subtitles[j].newText, text);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool SetNewSubtitle(char * filename, char* text, float from, float to)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
for(int j=0; j<subfile->count; j++)
|
|
{
|
|
if (subfile->subtitles[j].from == from &&
|
|
subfile->subtitles[j].to == to)
|
|
{
|
|
strcpy(subfile->subtitles[j].newText, text);
|
|
return true;
|
|
}
|
|
if ((from>subfile->subtitles[j].from && from<subfile->subtitles[j].to) ||
|
|
(to>subfile->subtitles[j].from && to<subfile->subtitles[j].to))
|
|
return false;
|
|
}
|
|
if (subfile->maxSub <= subfile->count)
|
|
{
|
|
subfile->subtitles = (Subtitle*)CC_realloc(subfile->subtitles, 2*subfile->maxSub*sizeof(Subtitle));
|
|
memset(subfile->subtitles + subfile->maxSub, 0, subfile->maxSub*sizeof(Subtitle));
|
|
subfile->maxSub *= 2;
|
|
}
|
|
subfile->subtitles[subfile->count].from = from;
|
|
subfile->subtitles[subfile->count].to = to;
|
|
strcpy(subfile->subtitles[subfile->count].text, text);
|
|
subfile->count++;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
char * GetSubtitle(char * filename, float time)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
for(int j=0; j<subfile->count; j++)
|
|
{
|
|
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
|
|
{
|
|
if (*subfile->subtitles[j].newText)
|
|
return subfile->subtitles[j].newText;
|
|
else
|
|
return subfile->subtitles[j].text;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int GetSubtitleIndex(char * filename, float time)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
for(int j=0; j<subfile->count; j++)
|
|
{
|
|
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
|
|
{
|
|
return j;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
char * GetSubtitleByIndex(char * filename, int index)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
if (index < subfile->count)
|
|
{
|
|
if (*subfile->subtitles[index].newText)
|
|
return subfile->subtitles[index].newText;
|
|
else
|
|
return subfile->subtitles[index].text;
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void LoadSubtitle(char* filename)
|
|
{
|
|
if(filename==0) return;
|
|
FILE* file = CC_fopen(filename,"rt");
|
|
|
|
Subfile* subfile = 0;
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
subfile = subfiles+i;
|
|
if (subfile->subtitles)
|
|
{
|
|
CC_free(subfile->subtitles);
|
|
subfile->maxSub = initMaxSub;
|
|
subfile->subtitles = (Subtitle*)ZeroAlloc(subfile->maxSub*sizeof(Subtitle));
|
|
subfile->count = 0;
|
|
}
|
|
if (subfile->filename)
|
|
{
|
|
CC_free(subfile->filename);
|
|
subfile->filename = 0;
|
|
}
|
|
i = nbSubfiles;
|
|
}
|
|
}
|
|
if (subfile==0)
|
|
{
|
|
if(nbSubfiles==maxSubfiles)
|
|
{
|
|
maxSubfiles*=2;
|
|
subfiles = (Subfile*)CC_realloc(subfiles,maxSubfiles*sizeof(Subfile));
|
|
}
|
|
subfile = subfiles+nbSubfiles;
|
|
nbSubfiles++;
|
|
subfile->maxSub = initMaxSub;
|
|
subfile->subtitles = (Subtitle*)ZeroAlloc(subfile->maxSub*sizeof(Subtitle));
|
|
subfile->count = 0;
|
|
subfile->filename = 0;
|
|
}
|
|
|
|
subfile->filename = (char*)ZeroAlloc(strlen(filename)+1);
|
|
strcpy(subfile->filename, filename);
|
|
|
|
if(!file) return;
|
|
int fileLen = lengthOfFile(filename);
|
|
char* contents = (char*)ZeroAlloc(fileLen);
|
|
long int pos = 0;
|
|
char c;
|
|
bool read;
|
|
do
|
|
{
|
|
read = fread(&c, 1, 1, file);
|
|
if(read)
|
|
contents[pos++] = c;
|
|
}while(read);
|
|
CC_fclose(file);
|
|
contents[pos] = 0;
|
|
|
|
long int lastPos = 0;
|
|
pos = 0;
|
|
char line[1024];
|
|
int fh, fm, fs, fml, th, tm, ts, tml;
|
|
fh= fm= fs= fml= th= tm= ts= tml= 0;
|
|
do
|
|
{
|
|
if(subfile->count==subfile->maxSub)
|
|
{
|
|
subfile->maxSub*=2;
|
|
subfile->subtitles = (Subtitle*)CC_realloc(subfile->subtitles,subfile->maxSub*sizeof(Subtitle));
|
|
}
|
|
|
|
while(contents[pos]!='\n') pos++;
|
|
pos++;
|
|
lastPos = pos;
|
|
|
|
while(contents[pos]!='\n') pos++;
|
|
strncpy(line, contents+lastPos, pos-lastPos);
|
|
line[pos-lastPos] = 0;
|
|
sscanf(line, "%d:%d:%d,%d --> %d:%d:%d,%d", &fh, &fm, &fs, &fml, &th, &tm, &ts, &tml);
|
|
subfile->subtitles[subfile->count].from = fh*3600 + fm*60 + fs + fml/1000.0;
|
|
subfile->subtitles[subfile->count].to = th*3600 + tm*60 + ts + tml/1000.0;
|
|
|
|
int textSize = 0;
|
|
memset(subfile->subtitles[subfile->count].text, 0, 1024);
|
|
memset(subfile->subtitles[subfile->count].newText, 0, 1024);
|
|
do
|
|
{
|
|
pos++;
|
|
lastPos = pos;
|
|
while(pos < fileLen && contents[pos]!='\n') pos++;
|
|
if(lastPos!=pos)
|
|
{
|
|
int lineSize = pos-lastPos+1;
|
|
textSize+=lineSize;
|
|
if (textSize<1024)
|
|
{
|
|
strncat(subfile->subtitles[subfile->count].text, contents+lastPos, lineSize);
|
|
}
|
|
}
|
|
}while (lastPos!=pos);
|
|
if (*subfile->subtitles[subfile->count].text)
|
|
{
|
|
subfile->subtitles[subfile->count].text[textSize-1] = 0;
|
|
}
|
|
pos++;
|
|
lastPos = pos;
|
|
subfile->count++;
|
|
}while(contents[pos] && pos < fileLen);
|
|
}
|
|
|
|
|
|
void DestroySubtitle(char* filename)
|
|
{
|
|
for(int i=0; i<nbSubfiles; i++)
|
|
{
|
|
if (strcmp(subfiles[i].filename, filename)==0)
|
|
{
|
|
Subfile* subfile = subfiles+i;
|
|
CC_free(subfile->subtitles);
|
|
memset(subfile, 0, sizeof(Subfile));
|
|
for (int j=i+1; j<nbSubfiles; j++)
|
|
{
|
|
subfiles[j-1] = subfiles[j];
|
|
}
|
|
nbSubfiles--;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
u32 ReadLine(FILE *F,char *LineFeed);
|
|
|
|
float ProcessLine(char *subFile, char *line, char *text, float prevTime, int unit, float timePerUnit)
|
|
{
|
|
char *ptrText = strstr(line, ";text");
|
|
char *unitText;
|
|
float newTime;
|
|
if (!ptrText) return prevTime;
|
|
|
|
*ptrText = 0;
|
|
ptrText += 7;
|
|
|
|
unitText = strchr(line, '/');
|
|
if (unitText)
|
|
{
|
|
*unitText = 0;
|
|
newTime = (float) unit * atof(line) / atof(unitText+1) * timePerUnit + prevTime;
|
|
} else
|
|
{
|
|
newTime = atoi(line) * timePerUnit + prevTime;
|
|
}
|
|
SetNewSubtitle(subFile, text, prevTime, newTime - 0.001);
|
|
strcpy(text, ptrText);
|
|
text[strlen(text)-1] = 0;
|
|
|
|
return newTime;
|
|
}
|
|
|
|
//void MidiTextToSubtitle(char *txtFile, char *subFile);
|
|
//MidiTextToSubtitle("aaabb.txt", "aaabb.sub");
|
|
//SaveSubtitle("aaabb.sub", "aaabb.sub");
|
|
|
|
|
|
|
|
void MidiTextToSubtitle(char *txtFile, char *subFile)
|
|
{
|
|
char line[2048];
|
|
char text[1024] = " ";
|
|
int mode = 0;
|
|
int unit;
|
|
float timePerUnit;
|
|
float prevTime = 0;
|
|
FILE *F;
|
|
|
|
LoadSubtitle(subFile);
|
|
F = CC_fopen(txtFile, "rt");
|
|
|
|
while (ReadLine(F,line))
|
|
{
|
|
// use only
|
|
switch (mode)
|
|
{
|
|
case 0: // nothing
|
|
if (!strncmp(line, "mthd", 4))
|
|
mode = 1;
|
|
if (!strncmp(line, "mtrk", 4))
|
|
mode = 2;
|
|
break;
|
|
case 1: // in track
|
|
if (!strncmp(line, "end mthd", 8))
|
|
mode = 0;
|
|
if (strstr(line, "unit"))
|
|
{
|
|
strcpy(line, strstr(line, "unit") + 5);
|
|
*strchr(line, ' ') = 0;
|
|
unit = atoi(line) * 4;
|
|
}
|
|
break;
|
|
case 2: // nothing
|
|
if (!strncmp(line, "end mtrk", 8))
|
|
mode = 0;
|
|
if (strstr(line, "beats "))
|
|
{
|
|
float beatsPerMinute;
|
|
char *beatPtr = strstr(line, "beats ") + 6;
|
|
*strchr(beatPtr, ' ') = 0;
|
|
beatsPerMinute = atof(beatPtr);
|
|
timePerUnit = 60.0/(beatsPerMinute*unit) * 4;
|
|
}
|
|
if (strstr(line, "trackname \"Words\""))
|
|
mode = 3;
|
|
break;
|
|
case 3: // in TEXT track
|
|
if (!strncmp(line, "end mtrk", 8))
|
|
return;
|
|
prevTime = ProcessLine(subFile, line, text, prevTime, unit, timePerUnit);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|