From 92f17580846c88108aab023092c23e6bcdcf2f75 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Fri, 14 Aug 2015 23:45:02 +0800 Subject: SMELT is finally finished! Add the SMELT library for future use. Add .gitignore. --- extensions/smanim.cpp | 196 +++++++++++++++++++++++++++++++++++++++++ extensions/smbmfont.cpp | 218 ++++++++++++++++++++++++++++++++++++++++++++++ extensions/smdatapack.cpp | 176 +++++++++++++++++++++++++++++++++++++ extensions/smentity.cpp | 191 ++++++++++++++++++++++++++++++++++++++++ extensions/smgrid.cpp | 112 ++++++++++++++++++++++++ extensions/smttfont.cpp | 145 ++++++++++++++++++++++++++++++ 6 files changed, 1038 insertions(+) create mode 100644 extensions/smanim.cpp create mode 100644 extensions/smbmfont.cpp create mode 100644 extensions/smdatapack.cpp create mode 100644 extensions/smentity.cpp create mode 100644 extensions/smgrid.cpp create mode 100644 extensions/smttfont.cpp (limited to 'extensions') diff --git a/extensions/smanim.cpp b/extensions/smanim.cpp new file mode 100644 index 0000000..c418c4e --- /dev/null +++ b/extensions/smanim.cpp @@ -0,0 +1,196 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * Animation implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * This library is developed for the BLR series games. + */ +#include "smanim.hpp" +#include +#include +#define METAWARN printf("metafile warning at line %d",lc) +void smAnmFile::parseMeta(char* meta,DWORD size) +{ + char* cp=meta; + bool inAnim=false; + int lc=0; + smAnmInfo cur; + while(cp-meta<=size) + { + int cc=0; + for(;*(cp+cc)!='\n';++cc); + char line[65]; + strncpy(cp,line,cc);line[cc-1]='\0'; + cp+=cc+1;++lc; + if(inAnim&&line[0]!='F'&&line[0]!='E'){METAWARN;continue;} + if(line[0]=='E') + { + if(!inAnim)METAWARN; + else{inAnim=false;am[std::string(cur.name)]=cur;} + } + if(line[0]=='A') + { + if(inAnim)METAWARN; + else + { + inAnim=true; + int cn=0;while(line[cn+2]!=',')++cn; + cur.name=new char[cn];strncpy(cur.name,line+2,cn); + cur.name[cn-1]='\0';cur.mode=0;cur.fc=0; + if(!strcmp(line+3+cn,"loop"))cur.mode=1; + if(!strcmp(line+3+cn,"bidi"))cur.mode=2; + } + } + if(line[0]=='F') + { + if(!inAnim)METAWARN; + else + { + int cn=0;while(line[cn+2]!=',')++cn; + cur.frames[cur.fc].path=new char[cn]; + cur.frames[cur.fc].name=NULL; + strncpy(cur.frames[cur.fc].path,line+2,cn); + cur.frames[cur.fc].path[cn-1]='\0'; + sscanf(line+3+cn,"%d,%d,%d,%d,%d",&cur.frames[cur.fc].rect.x, + &cur.frames[cur.fc].rect.y,&cur.frames[cur.fc].rect.w,&cur.frames[cur.fc].rect.h, + &cur.framedur[cur.fc]); + if(xm.find(std::string(cur.frames[cur.fc].path))!=xm.end()) + cur.frames[cur.fc].tex=xm[std::string(cur.frames[cur.fc].path)]; + else + { + char *texct=anm.getFilePtr(cur.frames[cur.fc].path); + DWORD texsz=anm.getFileSize(cur.frames[cur.fc].path); + cur.frames[cur.fc].tex=xm[std::string(cur.frames[cur.fc].path)] + =sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(cur.frames[cur.fc].path); + } + ++cur.fc; + } + } + if(line[0]=='S') + { + smTexInfo t; + int cn=0;while(line[cn+2]!=',')++cn; + t.name=new char[cn];strncpy(t.name,line+2,cn); + t.name[cn-1]='\0'; + int cn2=0;while(line[cn+3+cn2]!=',')++cn2; + t.path=new char[cn2];strncpy(t.path,line+3+cn,cn2); + t.path[cn2-1]='\0'; + sscanf(line+4+cn+cn2,"%d,%d,%d,%d",&t.rect.x,&t.rect.y,&t.rect.w,&t.rect.h); + tm[std::string(t.name)]=t; + if(xm.find(std::string(t.path))!=xm.end()) + t.tex=xm[std::string(t.path)]; + else + { + char *texct=anm.getFilePtr(t.path); + DWORD texsz=anm.getFileSize(t.path); + t.tex=xm[std::string(t.path)] + =sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(t.path); + } + } + if(line[0]=='I') + { + char* mptr=anm.getFilePtr(line+2); + DWORD msez=anm.getFileSize(line+2); + parseMeta(mptr,msez); + anm.releaseFilePtr(line+2); + } + } +} +bool smAnmFile::loadAnmFromMemory(char* ptr,DWORD size) +{ + sm=smGetInterface(SMELT_APILEVEL); + anm.openDtpFromMemory(ptr,size); + xm.clear();tm.clear();am.clear(); + char* mptr=anm.getFilePtr("content.meta"); + DWORD msez=anm.getFileSize("content.meta"); + parseMeta(mptr,msez); + anm.releaseFilePtr("content.meta"); +} +void smAnmFile::close() +{ + anm.closeDtp(); + for(std::map::iterator i=tm.begin();i!=tm.end();++i) + {delete i->second.name;delete i->second.path;} + tm.clear(); + for(std::map::iterator i=am.begin();i!=am.end();++i) + { + delete i->second.name; + for(int j=0;jsecond.fc;++j) + delete i->second.frames[j].path; + } + am.clear(); + for(std::map::iterator i=xm.begin();i!=xm.end();++i) + sm->smTextureFree(i->second); + xm.clear(); + sm->smRelease(); +} +smTexInfo* smAnmFile::getTextureInfo(const char* name) +{return &tm.at(name);} +smAnmInfo* smAnmFile::getAnimationInfo(const char* name) +{return &am.at(name);} + +smAnimation2D::smAnimation2D(smAnmInfo a):smEntity2D(a.frames[0].tex,a.frames[0].rect) +{ + ai=a;cf=mf=r=0; + for(int i=0;imf)cf=mf;} + if(ai.mode==1){cf+=f;if(cf>mf)cf-=mf;} + if(ai.mode==2) + { + if(r){cf-=f;if(cf<0)r=0,cf=-cf;} + else{cf+=f;if(cf>mf)r=1,cf=2*mf-cf;} + } + int l=0,r=ai.framedur[0],ff=0; + for(int i=0;il&&cf<=r){ff=i;break;} + l+=ai.framedur[i];r+=ai.framedur[i+1]; + } + setTexture(ai.frames[ff].tex); + setTextureRectv(ai.frames[ff].rect); +} +void smAnimation2D::resetAnim() +{ + cf=mf=r=0; + setTexture(ai.frames[0].tex); + setTextureRectv(ai.frames[0].rect); +} + +smAnimation3D::smAnimation3D(smAnmInfo a):smEntity3D(a.frames[0].tex,a.frames[0].rect) +{ + ai=a;cf=mf=r=0; + for(int i=0;imf)cf=mf;} + if(ai.mode==1){cf+=f;if(cf>mf)cf-=mf;} + if(ai.mode==2) + { + if(r){cf-=f;if(cf<0)r=0,cf=-cf;} + else{cf+=f;if(cf>mf)r=1,cf=2*mf-cf;} + } + int l=0,r=ai.framedur[0],ff=0; + for(int i=0;il&&cf<=r){ff=i;break;} + l+=ai.framedur[i];r+=ai.framedur[i+1]; + } + setTexture(ai.frames[ff].tex); + setTextureRectv(ai.frames[ff].rect); +} +void smAnimation3D::resetAnim() +{ + cf=mf=r=0; + setTexture(ai.frames[0].tex); + setTextureRectv(ai.frames[0].rect); +} diff --git a/extensions/smbmfont.cpp b/extensions/smbmfont.cpp new file mode 100644 index 0000000..598c7eb --- /dev/null +++ b/extensions/smbmfont.cpp @@ -0,0 +1,218 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * Bitmap font support implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * This library is developed for the BLR series games. + */ +#include "smbmfont.hpp" +#include +#include +#include + +SMELT *smBMFont::sm=NULL; +SMELT *smBMFontw::sm=NULL; + +void smBMFont::parseMeta(char* meta,DWORD size) +{ + char* cp=meta; + char line[65]; + int cc,cod,pa,pb;smTexRect rct; + while(cp-meta<=size) + { + cc=0; + for(;*(cp+cc)!='\n'&&cp+cc-meta<=size;++cc); + strncpy(line,cp,cc);if(line[cc]=='\n')line[cc]='\0'; + cp+=cc+1; + char* tp=strchr(line,','); + if(tp)*tp='\0';else continue; + sscanf(tp+1,"%d,%f,%f,%f,%f,%d,%d",&cod,&rct.x,&rct.y,&rct.w,&rct.h,&pb,&pa); + if(cod>=0&&cod<256) + { + if(xm.find(std::string(line))==xm.end()) + { + char* texct=anm.getFilePtr(line); + DWORD texsz=anm.getFileSize(line); + xm[std::string(line)]=sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(line); + } + chars[cod]=new smEntity2D(xm[std::string(line)],rct); + pdb[cod]=pb;pda[cod]=pa;if(hadv::iterator i=xm.begin();i!=xm.end();++i) + sm->smTextureFree(i->second); + xm.clear(); + sm->smRelease(); +} +void smBMFont::render(float x,float y,float z,int align,float *rw,const char* text) +{ + float width=0,cw=0,ofs=x; + const char* t=text; + while(*t) + { + cw=0; + for(;*t&&*t!='\n';++t) + { + if(chars[(int)*t]) + cw+=chars[(int)*t]->_w()+pdb[(int)*t]+pda[(int)*t]; + } + if(cw>width)width=cw; + while(*t=='\n')++t; + } + width*=sc; + if(rw)*rw=width; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + while(*text) + { + if(*text=='\n') + { + y+=hadv*sc;ofs=x; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + } + else + { + if(chars[(int)*text]) + { + ofs+=pdb[(int)*text]*sc; + chars[(int)*text]->setZ(z); + chars[(int)*text]->setColor(color); + chars[(int)*text]->setBlend(b); + chars[(int)*text]->render(ofs,y,0,sc); + ofs+=(chars[(int)*text]->_w()+pda[(int)*text])*sc; + } + } + ++text; + } +} +void smBMFont::printf(float x,float y,float z,int align,float *rw,const char* format,...) +{ + char buf[1024]; + va_list vl; + va_start(vl,format); + vsnprintf(buf,sizeof(buf)-1,format,vl); + va_end(vl); + buf[sizeof(buf)-1]='\0'; + render(x,y,z,align,rw,buf); +} + +void smBMFontw::parseMeta(char* meta,DWORD size) +{ + char* cp=meta; + char line[65]; + int cc,cod,pa,pb;smTexRect rct; + while(cp-meta<=size) + { + cc=0; + for(;*(cp+cc)!='\n'&&cp+cc-meta<=size;++cc); + strncpy(line,cp,cc);if(line[cc]=='\n')line[cc]='\0'; + cp+=cc+1; + char* tp=strchr(line,','); + if(tp)*tp='\0';else continue; + sscanf(tp+1,"%d,%f,%f,%f,%f,%d,%d",&cod,&rct.x,&rct.y,&rct.w,&rct.h,&pb,&pa); + if(cod>=WCHAR_MIN&&cod<=WCHAR_MAX) + { + if(xm.find(std::string(line))==xm.end()) + { + char* texct=anm.getFilePtr(line); + DWORD texsz=anm.getFileSize(line); + xm[std::string(line)]=sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(line); + } + chars[cod]=new smEntity2D(xm.find(std::string(line))->second,rct); + pdb[cod]=pb;pda[cod]=pa;if(hadv::iterator i=chars.begin();i!=chars.end();++i)if(i->second){delete i->second;i->second=NULL;} + for(std::map::iterator i=xm.begin();i!=xm.end();++i) + sm->smTextureFree(i->second); + xm.clear();chars.clear();pdb.clear();pda.clear(); + sm->smRelease(); +} +void smBMFontw::render(float x,float y,float z,int align,float *rw,const wchar_t* text) +{ + float width=0,cw=0,ofs=x; + const wchar_t* t=text; + while(*t) + { + cw=0; + for(;*t&&*t!='\n';++t) + { + if(chars[*t]) + cw+=chars[*t]->_w()+pdb[*t]+pda[*t]; + } + if(cw>width)width=cw; + while(*t=='\n')++t; + } + width*=sc; + if(rw)*rw=width; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + while(*text) + { + if(*text=='\n') + { + y+=hadv*sc;ofs=x; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + } + else + { + if(chars[*text]) + { + ofs+=pdb[*text]*sc; + chars[*text]->setZ(z); + chars[*text]->setColor(color); + chars[*text]->setBlend(b); + chars[*text]->render(ofs,y,0,sc); + ofs+=(chars[*text]->_w()+pda[*text])*sc; + } + } + ++text; + } +} +void smBMFontw::printf(float x,float y,float z,int align,float *rw,const wchar_t* format,...) +{ + wchar_t buf[1024]; + va_list vl; + va_start(vl,format); + vswprintf(buf,sizeof(buf)-1,format,vl); + va_end(vl); + buf[sizeof(buf)-1]='\0'; + render(x,y,z,align,rw,buf); +} diff --git a/extensions/smdatapack.cpp b/extensions/smdatapack.cpp new file mode 100644 index 0000000..b707d39 --- /dev/null +++ b/extensions/smdatapack.cpp @@ -0,0 +1,176 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * DaTaPack format support implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * This library is developed for the BLR series games. + */ +#include "smdatapack.hpp" +#include +#include +#define gzgetDWORD(f) ((gzgetc(f)<<24)|(gzgetc(f)<<16)|(gzgetc(f)<<8)|(gzgetc(f)))&0xFFFFFFFF +#define gch ((*(cp++))&0xFF) +#define mmgetDWORD ((gch<<24)|(gch<<16)|(gch<<8)|(gch))&0xFFFFFFFF +#define gzputDWORD(f,a) gzputc(f,a>>24);gzputc(f,(a>>16)&0xFF);gzputc(f,(a>>8)&0xFF);gzputc(f,a&0xFF); +bool smDtpFileR::openDtp(const char* path) +{ + file=gzopen(path,"r"); + if(!file)return false;enmemory=false;msize=0; + if(gzgetc(file)!='D')return false; + if(gzgetc(file)!='T')return false; + if(gzgetc(file)!='P')return false; + fcnt=gzgetc(file); + for(int i=0;i::iterator i=m.begin();i!=m.end();++i) + { + delete[] i->second.path;i->second.path=NULL; + if(i->second.data){delete[] i->second.data;i->second.data=NULL;} + i->second.size=i->second.offset=i->second.crc=0; + } + fcnt=0; + m.clear();if(!enmemory){gzclose(file);file=0;} +} +char* smDtpFileR::getFirstFile(){return m.begin()->second.path;} +char* smDtpFileR::getLastFile(){return (--m.end())->second.path;} +char* smDtpFileR::getNextFile(const char* path) +{ + std::map::iterator i=m.find(std::string(path)); + if(i==m.end()||(++i)==m.end())return NULL; + return i->second.path; +} +char* smDtpFileR::getPrevFile(const char* path) +{ + std::map::iterator i=m.find(std::string(path)); + if(i==m.end()||i==m.begin())return NULL;--i; + return i->second.path; +} +char* smDtpFileR::getFilePtr(const char* path) +{ + std::string fns(path); + if(m.at(fns).data)return m.at(fns).data; + else + { + if(!m.at(fns).size){printf("error: empty file.\n");return NULL;} + if(!enmemory) + gzseek(file,m[fns].offset,SEEK_SET); + else + cp=bp+m[fns].offset; + m[fns].data=new char[m[fns].size]; + if(!enmemory) + { + int r=gzread(file,m[fns].data,m[fns].size); + if(rmsize){delete[] m[fns].data;printf("error: file size mismatch.\n");return m[fns].data=NULL;} + memcpy(m[fns].data,cp,m[fns].size); + } + DWORD crc=crc32(0,(Bytef*)m[fns].data,m[fns].size); + if(crc!=m[fns].crc) + {delete[] m[fns].data;printf("error: crc mismatch.\n");return m[fns].data=NULL;} + return m[fns].data; + } +} +void smDtpFileR::releaseFilePtr(const char* path) +{ + std::string fns(path); + if(m[fns].data) + { + delete[] m[fns].data; + m[fns].data=NULL; + } +} +DWORD smDtpFileR::getFileSize(const char* path) +{return m[std::string(path)].size;} + +smDtpFileW::smDtpFileW(){fcnt=0;} +bool smDtpFileW::addFile(const char* path,const char* realpath) +{ + FILE *pFile;DWORD size,rsize; + pFile=fopen(realpath,"rb"); + if(!pFile)return false; + fseek(pFile,0,SEEK_END);size=ftell(pFile);rewind(pFile); + if(!size)return false;files[fcnt].data=NULL; + files[fcnt].data=new char[size]; + if(!files[fcnt].data)return false; + files[fcnt].path=new char[strlen(path)+1]; + strcpy(files[fcnt].path,path); + rsize=fread(files[fcnt].data,1,size,pFile); + if(rsize!=size) + { + delete[] files[fcnt].data;files[fcnt].data=NULL; + delete[] files[fcnt].path;files[fcnt].path=NULL; + return false; + } + files[fcnt].size=size; + files[fcnt].crc=crc32(0,(Bytef*)files[fcnt].data,files[fcnt].size); + ++fcnt; + fclose(pFile); + return true; +} +bool smDtpFileW::writeDtp(const char* path) +{ + gzFile file=gzopen(path,"w"); + gzputs(file,"DTP");gzputc(file,fcnt); + int metasize=4; + for(int i=0;i +#include +SMELT *smEntity2D::sm=NULL; +SMELT *smEntity3D::sm=NULL; + +smEntity2D::smEntity2D(SMTEX tex,float _x,float _y,float _w,float _h) +{ + sm=smGetInterface(SMELT_APILEVEL); + tx=_x;ty=_y;w=_w;h=_h; + if(tex) + { + texw=sm->smTextureGetWidth(tex); + texh=sm->smTextureGetHeight(tex); + }else texw=texh=1.; + ctrx=ctry=0;quad.tex=tex; + quad.v[0].tx=_x/texw;quad.v[0].ty=_y/texh; + quad.v[1].tx=(_x+_w)/texw;quad.v[1].ty=_y/texh; + quad.v[2].tx=(_x+_w)/texw;quad.v[2].ty=(_y+_h)/texh; + quad.v[3].tx=_x/texw;quad.v[3].ty=(_y+_h)/texh; + for(int i=0;i<4;++i){quad.v[i].z=.5f;quad.v[i].col=0xFFFFFFFF;} + quad.blend=BLEND_ALPHABLEND; +} +smEntity2D::smEntity2D(SMTEX tex,smTexRect rect) +{ + sm=smGetInterface(SMELT_APILEVEL); + tx=rect.x;ty=rect.y;w=rect.w;h=rect.h; + if(tex) + { + texw=sm->smTextureGetWidth(tex); + texh=sm->smTextureGetHeight(tex); + }else texw=texh=1.; + ctrx=ctry=0;quad.tex=tex; + quad.v[0].tx=rect.x/texw;quad.v[0].ty=rect.y/texh; + quad.v[1].tx=(rect.x+rect.w)/texw;quad.v[1].ty=rect.y/texh; + quad.v[2].tx=(rect.x+rect.w)/texw;quad.v[2].ty=(rect.y+rect.h)/texh; + quad.v[3].tx=rect.x/texw;quad.v[3].ty=(rect.y+rect.h)/texh; + for(int i=0;i<4;++i){quad.v[i].z=.5f;quad.v[i].col=0xFFFFFFFF;} + quad.blend=BLEND_ALPHABLEND; +} +smEntity2D::smEntity2D(const smEntity2D ©) +{ + memcpy(this,©,sizeof(smEntity2D)); + sm=smGetInterface(SMELT_APILEVEL); +} +void smEntity2D::render(float x,float y,float rot,float wsc,float hsc) +{ + if(hscsmRenderQuad(&quad); +} +void smEntity2D::setTexture(SMTEX tex) +{ + float ntw,nth; + if(tex) + { + ntw=sm->smTextureGetWidth(tex); + nth=sm->smTextureGetHeight(tex); + }else ntw=nth=1.; + quad.tex=tex; + if(ntw!=texw||nth!=texh) + { + float tx1=quad.v[0].tx*texw,ty1=quad.v[0].ty*texh; + float tx2=quad.v[2].tx*texw,ty2=quad.v[2].ty*texh; + texw=ntw;texh=nth; + tx1/=texw;ty1/=texh;tx2/=texw;ty2/=texh; + quad.v[0].tx=tx1;quad.v[0].ty=ty1; + quad.v[1].tx=tx2;quad.v[1].ty=ty1; + quad.v[2].tx=tx2;quad.v[2].ty=ty2; + quad.v[3].tx=tx1;quad.v[3].ty=ty2; + } +} +void smEntity2D::setTextureRect4f(float _x,float _y,float _w,float _h) +{ + tx=_x;ty=_y;w=_w;h=_h; + quad.v[0].tx=_x/texw;quad.v[0].ty=_y/texh; + quad.v[1].tx=(_x+_w)/texw;quad.v[1].ty=_y/texh; + quad.v[2].tx=(_x+_w)/texw;quad.v[2].ty=(_y+_h)/texh; + quad.v[3].tx=_x/texw;quad.v[3].ty=(_y+_h)/texh; +} +void smEntity2D::setTextureRectv(smTexRect rect){setTextureRect4f(rect.x,rect.y,rect.w,rect.h);} +void smEntity2D::setColor(DWORD col,int v) +{ + if(v>=0&&v<4)quad.v[v].col=col; + else for(int i=0;i<4;++i)quad.v[i].col=col; +} +void smEntity2D::setZ(float z,int v) +{ + if(v>=0&&v<4)quad.v[v].z=z; + else for(int i=0;i<4;++i)quad.v[i].z=z; +} +void smEntity2D::setBlend(int blend){quad.blend=blend;} +void smEntity2D::setCentre(float x,float y){ctrx=x;ctry=y;} + +smEntity3D::smEntity3D(SMTEX tex,float _x,float _y,float _w,float _h) +{ + sm=smGetInterface(SMELT_APILEVEL); + tx=_x;ty=_y;w=_w;h=_h; + if(tex) + { + texw=sm->smTextureGetWidth(tex); + texh=sm->smTextureGetHeight(tex); + }else texw=texh=1.; + ctrx=ctry=0;quad.tex=tex; + quad.v[0].tx=_x/texw;quad.v[0].ty=_y/texh; + quad.v[1].tx=(_x+_w)/texw;quad.v[1].ty=_y/texh; + quad.v[2].tx=(_x+_w)/texw;quad.v[2].ty=(_y+_h)/texh; + quad.v[3].tx=_x/texw;quad.v[3].ty=(_y+_h)/texh; + for(int i=0;i<4;++i){quad.v[i].z=.5f;quad.v[i].col=0xFFFFFFFF;} + quad.blend=BLEND_ALPHABLEND; +} +smEntity3D::smEntity3D(const smEntity3D ©) +{ + memcpy(this,©,sizeof(smEntity3D)); + sm=smGetInterface(SMELT_APILEVEL); +} +void smEntity3D::render9f(float x,float y,float z,float ra,float rx,float ry,float rz,float wsc,float hsc) +{ + if(hscsmRenderQuad(&quad); +} +void smEntity3D::renderfv(float* pos,float* rot,float* scale) +{ + render9f(pos[0],pos[1],pos[2],rot[0],rot[1],rot[2],rot[3],scale[0],scale[1]); +} +void smEntity3D::setTexture(SMTEX tex) +{ + float ntw,nth; + if(tex) + { + ntw=sm->smTextureGetWidth(tex); + nth=sm->smTextureGetHeight(tex); + }else ntw=nth=1.; + quad.tex=tex; + if(ntw!=texw||nth!=texh) + { + float tx1=quad.v[0].tx*texw,ty1=quad.v[0].ty*texh; + float tx2=quad.v[2].tx*texw,ty2=quad.v[2].ty*texh; + texw=ntw;texh=nth; + tx1/=texw;ty1/=texh;tx2/=texw;ty2/=texh; + quad.v[0].tx=tx1;quad.v[0].ty=ty1; + quad.v[1].tx=tx2;quad.v[1].ty=ty1; + quad.v[2].tx=tx2;quad.v[2].ty=ty2; + quad.v[3].tx=tx1;quad.v[3].ty=ty2; + } +} +void smEntity3D::setTextureRect4f(float _x,float _y,float _w,float _h) +{ + tx=_x;ty=_y;w=_w;h=_h; + quad.v[0].tx=_x/texw;quad.v[0].ty=_y/texh; + quad.v[1].tx=(_x+_w)/texw;quad.v[1].ty=_y/texh; + quad.v[2].tx=(_x+_w)/texw;quad.v[2].ty=(_y+_h)/texh; + quad.v[3].tx=_x/texw;quad.v[3].ty=(_y+_h)/texh; +} +void smEntity3D::setTextureRectv(smTexRect rect){setTextureRect4f(rect.x,rect.y,rect.w,rect.h);} +void smEntity3D::setColor(DWORD col,int v) +{ + if(v>=0&&v<4)quad.v[v].col=col; + else for(int i=0;i<4;++i)quad.v[i].col=col; +} +void smEntity3D::setBlend(int blend){quad.blend=blend;} +void smEntity3D::setCentre(float x,float y){ctrx=x;ctry=y;} diff --git a/extensions/smgrid.cpp b/extensions/smgrid.cpp new file mode 100644 index 0000000..292a717 --- /dev/null +++ b/extensions/smgrid.cpp @@ -0,0 +1,112 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * Distortion grid implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * + */ +#include "smgrid.hpp" +#include +SMELT *smGrid::sm=0; +smGrid::smGrid(int _cc,int _rc) +{ + sm=smGetInterface(SMELT_APILEVEL); + cc=_cc;rc=_rc;cw=ch=.0; + quad.tex=0;quad.blend=BLEND_ALPHABLEND; + pos=new smVertex[cc*rc]; + for(int i=0;ismRelease();} +smGrid& smGrid::operator =(const smGrid ©) +{ + if(this!=©) + { + sm=smGetInterface(SMELT_APILEVEL); + cc=copy.cc;rc=copy.rc;cw=copy.cw;ch=copy.ch; + quad=copy.quad;tx=copy.tx;ty=copy.ty;w=copy.w;h=copy.h; + delete[] pos;pos=new smVertex[cc*rc]; + memcpy(pos,copy.pos,sizeof(smVertex)*cc*rc); + } + return *this; +} +void smGrid::setTexture(SMTEX tex){quad.tex=tex;} +void smGrid::setTextureRect4f(float _x,float _y,float _w,float _h) +{ + float tw,th; + tx=_x;ty=_y;w=_w;h=_h; + if(quad.tex) + { + tw=(float)sm->smTextureGetWidth(quad.tex); + th=(float)sm->smTextureGetHeight(quad.tex); + } + else tw=w,th=h; + cw=w/(cc-1);ch=h/(rc-1); + for(int i=0;ismRenderQuad(&quad); + } +} diff --git a/extensions/smttfont.cpp b/extensions/smttfont.cpp new file mode 100644 index 0000000..9a37183 --- /dev/null +++ b/extensions/smttfont.cpp @@ -0,0 +1,145 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * Truetype font support implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * This library is developed for the BLR series games. + */ +#include "smttfont.hpp" + +SMELT *smTTChar::sm=NULL; + +void smTTChar::free(){if(quad.tex){sm->smTextureFree(quad.tex);quad.tex=0;sm->smRelease();}} +bool smTTChar::setChar(wchar_t c,FT_Face ttface) +{ + if(!sm)sm=smGetInterface(SMELT_APILEVEL); + FT_GlyphSlot slot=ttface->glyph; + FT_UInt glyph_index=FT_Get_Char_Index(ttface,c); + if(FT_Load_Glyph(ttface,glyph_index,FT_LOAD_DEFAULT))return false; + if(FT_Render_Glyph(ttface->glyph,FT_RENDER_MODE_NORMAL))return false; + _w=slot->advance.x>>6;_h=slot->advance.y?slot->advance.y>>6:slot->bitmap.rows;_h=(int)(_h*1.5); + rw=slot->bitmap.width;rh=slot->bitmap.rows; + xofs=slot->bitmap_left;yofs=slot->bitmap.rows-slot->bitmap_top; + quad.tex=sm->smTextureCreate(rw?rw:1,rh?rh:1); + DWORD* px=sm->smTextureLock(quad.tex,0,0,rw?rw:1,rh?rh:1,false); + memset(px,0,sizeof(DWORD)*(rw?rw:1)*(rh?rh:1)); + int ptr=0; + for(int i=0;ibitmap.buffer[ptr],255,255,255); +#else + px[(rh-i-1)*rw+j]=ARGB(slot->bitmap.buffer[ptr],255,255,255); +#endif + ++ptr; + } + sm->smTexutreUnlock(quad.tex); + quad.blend=BLEND_ALPHABLEND; + quad.v[0].tx=0;quad.v[0].ty=0;quad.v[1].tx=1;quad.v[1].ty=0; + quad.v[2].tx=1;quad.v[2].ty=1;quad.v[3].tx=0;quad.v[3].ty=1; + return true; +} +void smTTChar::render(float x,float y,DWORD col) +{ + for(int i=0;i<4;++i)quad.v[i].col=col,quad.v[i].z=.5; + quad.v[0].x=x+xofs;quad.v[0].y=y-rh+yofs; + quad.v[1].x=x+rw+xofs;quad.v[1].y=y-rh+yofs; + quad.v[2].x=x+rw+xofs;quad.v[2].y=y+yofs; + quad.v[3].x=x+xofs;quad.v[3].y=y+yofs; + sm->smRenderQuad(&quad); +} + +bool smTTFont::loadTTF(const char* path,int pt) +{ + if(FT_Init_FreeType(&ftlib))return false; + if(FT_New_Face(ftlib,path,0,&ttface))return false; + if(FT_Set_Char_Size(ttface,0,pt*64,96,96))return false; + chars.clear(); + return true; +} +bool smTTFont::loadTTFFromMemory(char* ptr,DWORD size,int pt) +{ + if(FT_Init_FreeType(&ftlib))return false; + if(FT_New_Memory_Face(ftlib,(const FT_Byte*)ptr,(FT_Long)size,0,&ttface))return false; + if(FT_Set_Char_Size(ttface,0,pt*64,96,96))return false; + chars.clear(); + return true; +} +void smTTFont::releaseTTF() +{ + FT_Done_Face(ttface); + FT_Done_FreeType(ftlib); +} +void smTTFont::updateString(const wchar_t *format,...) +{ + memset(buf,0,sizeof(buf)); + va_list vl; + va_start(vl,format); + vswprintf(buf,1024,format,vl); + va_end(vl); + buf[1024]='\0'; + w=h=0;float lh=0; + for(int i=0;buf[i]!='\0';++i) + { + if(chars.find(buf[i])==chars.end()&&buf[i]!=L'\n') + if(!chars[buf[i]].setChar(buf[i],ttface)) + chars.erase(chars.find(buf[i])); + if(chars.find(buf[i])!=chars.end()) + { + w+=chars[buf[i]].w(); + if(chars[buf[i]].h()>lh)lh=chars[buf[i]].h(); + } + if(buf[i]==L'\n')h+=lh,lh=0; + } + h+=lh; +} +void smTTFont::render(float x,float y,DWORD col,int align) +{ + float curx,cury,lh; + if(align==ALIGN_LEFT) + { + curx=x;cury=y;lh=0; + for(int i=0;buf[i]!=L'\0';++i) + { + if(buf[i]!=L'\n') + { + if(chars.find(buf[i])!=chars.end()) + { + chars[buf[i]].render(curx,cury,col); + curx+=chars[buf[i]].w(); + lh=chars[buf[i]].h()>lh?chars[buf[i]].h():lh; + } + } + else cury+=lh,lh=0,curx=x; + } + } + if(align==ALIGN_RIGHT) + { + curx=x;cury=y;lh=0; + for(int i=wcslen(buf)-1;i>=0;--i) + { + if(buf[i]!=L'\n') + { + if(chars.find(buf[i])!=chars.end()) + { + chars[buf[i]].render(curx,cury,col); + curx-=chars[buf[i]].w(); + lh=chars[buf[i]].h()>lh?chars[buf[i]].h():lh; + } + } + else cury-=lh,lh=0,curx=x; + } + } +} +DWORD smTTFont::getCacheSize(){return chars.size();} +void smTTFont::clearCache() +{ + for(std::map::iterator i=chars.begin();i!=chars.end();++i) + i->second.free(); + chars.clear(); +} -- cgit v1.2.3