s98.cpp
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- filelength
- S98
- Open
- Dump
- NextData
- Loop
#include "s98.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int filelength(int fd)
/* [<][>][^][v][top][bottom][index][help] */
{
off_t save;
int ret;
save = lseek(fd, 0, SEEK_CUR);
ret = lseek(fd, 0, SEEK_END);
lseek(fd, save, SEEK_SET);
return ret;
}
S98::~S98()
/* [<][>][^][v][top][bottom][index][help] */
{
delete[] Data;
}
int S98::Open(string thefilename)
/* [<][>][^][v][top][bottom][index][help] */
{
int fd;
fd = ::open(thefilename.c_str(), O_RDONLY);
if(fd < 0) return -1;
filename = thefilename;
size = filelength(fd);
if(size <= sizeof(Header)) return -1;
Data = new unsigned char[size - sizeof(Header)]; // XXX exception
::read(fd, reinterpret_cast<char*>(&Header), sizeof(Header));
::read(fd, Data, size - sizeof(Header));
if(strncmp(Header.Magic, "S98", 3)) return -1;
if(Header.Timer == 0) Header.Timer = 10;
if(Header.NamePtr != 0) Header.NamePtr -= sizeof(Header);
Header.DataPtr -= sizeof(Header);
if(Header.LoopPtr != 0) Header.LoopPtr -= sizeof(Header);
pointer = Header.DataPtr;
::close(fd);
return 0;
}
void S98::Dump()
/* [<][>][^][v][top][bottom][index][help] */
{
fprintf(stderr, "Filename: %s\n", filename.c_str());
fprintf(stderr, "Length: %d\n", size);
fprintf(stderr, "Format: %c\n", static_cast<int> (Header.Format[0]));
fprintf(stderr, "Timer: %d\n" , Header.Timer);
fprintf(stderr, "Compressed: %d\n", Header.Compress);
fprintf(stderr, "Name: ");
if(Header.NamePtr != 0) {
fprintf(stderr, reinterpret_cast<char*>(&Data[Header.NamePtr]));
} else {
fprintf(stderr, "noname");
}
fprintf(stderr, "\n");
}
// 0 = ok, 1 = end, -1 = ng
int S98::NextData()
/* [<][>][^][v][top][bottom][index][help] */
{
unsigned char* p;
int n, s, i;
p = &Data[pointer];
if(pointer + sizeof(Header) >= size) return -1;
switch(*p){
case 0x00: // OPN(A) MASTER
opnareg.DoProc(static_cast<unsigned int>(p[1]),
static_cast<unsigned int>(p[2]));
pointer += 3;
break;
case 0x01: // OPN(A) SLAVE
opnareg.DoProc(0x100 | static_cast<unsigned int>(p[1]),
static_cast<unsigned int>(p[2]));
pointer += 3;
break;
case 0xff: // WAIT SYNC(1)
waitsync.DoProc(1 * Header.Timer);
++pointer;
break;
case 0xfe: // WAIT SYNC(n)
n = s = 0; i = 0;
do{
++i;
n |= (p[i] & 0x7f) << s;
s += 7;
} while(p[i] & 0x80);
n += 2;
pointer += i + 1;
waitsync.DoProc(Header.Timer * n);
break;
case 0xfd: // END/LOOP
++pointer;
return 1;
default:
return -1;
break;
}
return 0;
}
int S98::Loop()
/* [<][>][^][v][top][bottom][index][help] */
{
if(Header.LoopPtr != 0){
pointer = Header.LoopPtr;
return 1;
}
return 0;
}