lib file = <file.ssz>;
lib s = <string.ssz>;
lib sdl = <alpha/sdlplugin.ssz>;
lib consts = <consts.ssz>;
lib m = <math.ssz>;
lib tbl = <table.ssz>;
lib cfg = "config.ssz";
lib com = "common.ssz";
const int NumCharPalletes = 12;
public &SffHeader
{
public ubyte ver0, ver1, ver2, ver3;
public uint firstSpriteHeaderOffset, firstPaletteHeaderOffset;
public uint numberOfPalettes, numberOfSprites;
public bool read(&.file.File f=, uint lofs=, uint tofs=)
{
ubyte ub;
loop{
index i = 0;
%char s;
do:
if(!f.read!ubyte?(ub=)) ret false;
s .= (char)ub;
i++;
while i < 12:
if(!.s.equ(s, "ElecbyteSpr"\0)){
.com.error!self?("ElecbyteSprじゃない");
ret false;
}
}
if(!f.read!ubyte?(`ver3=)) ret false;
if(!f.read!ubyte?(`ver2=)) ret false;
if(!f.read!ubyte?(`ver1=)) ret false;
if(!f.read!ubyte?(`ver0=)) ret false;
uint dummy;
switch(`ver0){
case 0d1:
if(!f.read!uint?(dummy=)) ret false;
`numberOfPalettes = 0x0;
if(!f.read!uint?(`numberOfSprites=)) ret false;
if(!f.read!uint?(`firstSpriteHeaderOffset=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
`firstPaletteHeaderOffset = 0x0;
case 0d2:
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(`firstSpriteHeaderOffset=)) ret false;
if(!f.read!uint?(`numberOfSprites=)) ret false;
if(!f.read!uint?(`firstPaletteHeaderOffset=)) ret false;
if(!f.read!uint?(`numberOfPalettes=)) ret false;
if(!f.read!uint?(lofs=)) ret false;
if(!f.read!uint?(dummy=)) ret false;
if(!f.read!uint?(tofs=)) ret false;
default:
ret false;
}
ret true;
}
}
&PalleteList
{
%^uint palletes;
%index palidxs;
public &.tbl.IntTable!uint, index? palTable;
public void clear()
{
`palletes.new(0);
`palidxs.new(0);
`palTable.clear();
}
public ^uint newPal(index pi=)
{
`palidxs.new[#`palletes] = (pi = #`palletes);
`palletes.new[-1].new(256);
ret `palletes[-1];
}
public void setSource(index pi, ^uint pal)
{
`palidxs.new[pi] = pi;
`palletes.new[pi] = pal;
}
public ^uint get(index pi)
{
ret `palletes[`palidxs[pi]];
}
public void remap(index source, index dest)
{
`palidxs[source] = dest;
}
public void resetRemap()
{
loop{index i = 0; while; do: `palidxs[i] = i; i++; while i < #`palidxs:}
}
}
public &Sprite
{
public ^uint colorPallet;
public ^ubyte pxl;
public %byte pluginbuf;
public &.sdl.Rect rct;
public short imageGroup, imageNumber;
public index palidx = -1, link = -1;
public int rle = 0;
public void shareCopy(`self sp=)
{
`colorPallet = sp.colorPallet;
`pxl = sp.pxl;
`rct.w = sp.rct.w;
`rct.h = sp.rct.h;
`palidx = sp.palidx;
`rle = sp.rle;
}
public void copy(`self sp=)
{
`shareCopy(sp=);
`pluginbuf = sp.pluginbuf;
`rct = sp.rct;
`imageGroup = sp.imageGroup;
`imageNumber = sp.imageNumber;
`link = sp.link;
}
public ^uint getPal(&.PalleteList pl=)
{
if(#`colorPallet > 0) ret `colorPallet;
ret pl.get(`palidx);
}
public bool readHeader(&.file.File f=)
{
if(!f.read!short?(`rct.x=)) ret false;
if(!f.read!short?(`rct.y=)) ret false;
if(!f.read!short?(`imageGroup=)) ret false;
if(!f.read!short?(`imageNumber=)) ret false;
ret true;
}
public bool readPcxHeader(&.file.File f=, long offset)
{
f.seek(offset, .file.Seek::SET);
ubyte dummy, encoding, bpp;
if(!f.read!ubyte?(dummy=)) ret false;
if(!f.read!ubyte?(dummy=)) ret false;
if(!f.read!ubyte?(encoding=)) ret false;
if(!f.read!ubyte?(bpp=)) ret false;
if(bpp != 0d8){
.com.error!.self?("256色じゃない");
ret false;
}
ushort x, y, w, h;
if(!f.read!ushort?(x=)) ret false;
if(!f.read!ushort?(y=)) ret false;
if(!f.read!ushort?(w=)) ret false;
if(!f.read!ushort?(h=)) ret false;
f.seek(offset+66, .file.Seek::SET);
ushort bpl;
if(!f.read!ushort?(bpl=)) ret false;
`rct.w = w - x + 0x1;
`rct.h = h - y + 0x1;
`rle = encoding == 0x1 ? (int)bpl : 0;
ret true;
}
public bool readHeaderV2(
&.file.File f=, uint ofs=, uint siz=,
uint lofs, uint tofs, ushort idxlnked=)
{
if(!f.read!short?(`imageGroup=)) ret false;
if(!f.read!short?(`imageNumber=)) ret false;
if(!f.read!ushort?(`rct.w=)) ret false;
if(!f.read!ushort?(`rct.h=)) ret false;
if(!f.read!short?(`rct.x=)) ret false;
if(!f.read!short?(`rct.y=)) ret false;
if(!f.read!ushort?(idxlnked=)) ret false;
ubyte fmt, dummy;
if(!f.read!ubyte?(fmt=)) ret false;
`rle = -(int)fmt;
if(!f.read!ubyte?(dummy=)) ret false;
if(!f.read!uint?(ofs=)) ret false;
if(!f.read!uint?(siz=)) ret false;
ushort pali, flg;
if(!f.read!ushort?(pali=)) ret false;
`palidx = (index)pali;
if(!f.read!ushort?(flg=)) ret false;
ofs += (flg & 0d1) == 0x0 ? lofs : tofs;
ret true;
}
public bool read(
&.file.File f=, &.SffHeader sh=, long offset, uint loh, uint nsh,
^`self prev, bool palletSame=, &.PalleteList pl=, bool c00)
{
uint lenghtOfSubheader = loh;
if(nsh > (uint)offset) lenghtOfSubheader = nsh - (uint)offset;//lohを無視
if(!f.read!bool?(palletSame=)) ret false;
if(#prev == 0) palletSame = false;
if(!`readPcxHeader(f=, offset)) ret false;
f.seek(offset + 128, .file.Seek::SET);
`pxl.new((index)lenghtOfSubheader - (128+(c00||palletSame?0:768)));
f.readAry!ubyte?(`pxl);
loop{
index i = 0;
ubyte r, g, b;
if(palletSame){
if(#prev > 0) `palidx = prev~palidx;
if(`palidx < 0) pl.newPal(`palidx=);
break, break;
}
^uint pal = pl.newPal(`palidx=);
if(c00) f.seek(offset + (long)lenghtOfSubheader - 768, .file.Seek::SET);
do:
if(!f.read!ubyte?(r=)) ret false;
if(!f.read!ubyte?(g=)) ret false;
if(!f.read!ubyte?(b=)) ret false;
pal[i] = (uint)r<<0d16 | (uint)g<<0d8 | (uint)b;
i++;
while i < 256:
}
if(
!.cfg.SaveMemory
|| (index)`rct.w*(index)`rct.h
< (`rct.w >= 0d256 ? (#`pxl/256)*(index)`rct.w : #`pxl))
{
`rlePcxDecode();
}
ret true;
}
public bool readV2(&.file.File f=, long ofs, uint dsz)
{
f.seek(ofs+4, .file.Seek::SET);
`pxl.new((index)dsz);
f.readAry!ubyte?(`pxl);
if(`rle < 0) switch(-`rle){
case 2:
`rle8Decode();
case 3:
`rle5Decode();
case 4:
`lz5Decode();
default:
ret false;
}
ret true;
}
public void rlePcxDecode()
{
if(#`pxl == 0 || `rle <= 0) ret;
^/ubyte rle = `pxl;
`pxl.new((index)((uint)`rct.w * `rct.h));
loop{
int w = (int)`rct.w;
int leng = #`pxl;
index i = 0, j = 0, k = 0;
do:
loop{
int size;
ubyte d = rle[i++];
branch{
cond d >= 0xC0:
size = (int)(d & 0x3F);
d = rle[i++];
else:
size = 1;
}
while;
do:
`pxl[j] = d;
j += (int)(k < w);
if(++k == `rle){
k = 0;
size = 0;
}
while --size >= 0:
}
while j < leng:
}
`rle = 0;
}
public void rle8Decode()
{
if(#`pxl == 0) ret;
^/ubyte rle = `pxl;
`pxl.new((index)((uint)`rct.w * `rct.h));
loop{
int leng = #`pxl;
index i = 0, j = 0;
while;
do:
loop{
int size;
ubyte d = rle[i++];
branch{
cond (d&0xC0) == 0x40:
size = (int)(d & 0x3F);
d = rle[i++];
else:
size = 1;
}
while;
do:
`pxl[j++] = d;
while --size >= 0:
}
while j < leng:
}
`rle = 0;
}
public void rle5Decode()
{
if(#`pxl == 0) ret;
^/ubyte rle = `pxl;
`pxl.new((index)((uint)`rct.w * `rct.h));
loop{
int leng = #`pxl;
index i = 0, j = 0;
while;
do:
loop{
int rlen = (int)rle[i++];
int dlen = (int)(rle[i] & 0x7F);
ubyte c = rle[i++]>>0d7 != 0x0 ? rle[i++] : 0x0;
do:
`pxl[j++] = c;
while --rlen >= 0:
if(--dlen >= 0){
c = rle[i] & 0x1F;
rlen = (int)(rle[i++]>>0d5);
break, do;
}
}
while j < leng:
}
`rle = 0;
}
public void lz5Decode()
{
if(#`pxl == 0) ret;
^/ubyte rle = `pxl;
`pxl.new((index)((uint)`rct.w * `rct.h));
loop{
int leng = #`pxl;
index i = 0, j = 0;
uint s = 0x0, rbc = 0x0;
ubyte ct = rle[i++], rb = 0x0;
while;
do:
branch{
int size;
uint d;
cond (ct & 0d1<<s) != 0x0:
loop{
d = rle[i++];
branch{
cond (d&0x3F) == 0x00:
d = (d<<0d2 | rle[i++]) + 0d1;
size = (int)rle[i++] + 2;
else:
rb |= (d&0xC0) >> rbc;
rbc += 0d2;
size = (int)(d & 0x3F);
branch{
cond rbc < 0d8:
d = (uint)rle[i++] + 0x1;
else:
d = (uint)rb + 0d1;
rbc = 0x0;
rb = 0x0;
}
}
do:
`pxl[j] = `pxl[j-(index)d];
j++;
while --size >= 0:
}
else:
loop{
d = rle[i++];
branch{
cond (d&0xE0) == 0x00:
size = (int)rle[i++] + 8;
else:
size = (int)(d >> 0d5);
d &= 0x1F;
}
while;
do:
`pxl[j++] = d;
while --size >= 0:
}
}
if(++s >= 0d8){
s = 0x0;
ct = rle[i++];
}
while j < leng:
}
`rle = 0;
}
public bool loadFromSff(^/char fn, short ig, short in)
{
&.file.File f;
if(!f.open(fn, "rb")) ret false;
&.SffHeader h;
uint lofs, tofs;
if(!h.read(f=, lofs=, tofs=)) ret false;
uint shofs = h.firstSpriteHeaderOffset, misc, size;
ushort indexOfPrevious;
&.PalleteList pl;
loop{
index i = 0;
%uint newSubHeaderOffset .= shofs;
bool palletSame;
~$bool() foo = [bool(){
switch(h.ver0){
case 0d1:
if(!f.read!uint?(misc=)) ret false;
if(!f.read!uint?(size=)) ret false;
if(!`readHeader(f=)) ret false;
if(!f.read!ushort?(indexOfPrevious=)) ret false;
case 0d2:
if(
!`readHeaderV2(
f=, misc=, size=, lofs, tofs, indexOfPrevious=)) ret false;
}
ret true;
}];
^`self dummy;
while;
do:
newSubHeaderOffset .= shofs;
f.seek((long)shofs, .file.Seek::SET);
if(!foo(::)) ret false;
if(`palidx >= 0 && (`imageGroup != ig || `imageNumber != in)) continue;
loop{
uint ip = !indexOfPrevious;
while;
do:
if(ip == indexOfPrevious) ret false;
ip = indexOfPrevious;
shofs =
h.ver0 == 0d1 ? newSubHeaderOffset[(index)ip]
: h.firstSpriteHeaderOffset + ip*0d28;
f.seek((long)shofs, .file.Seek::SET);
if(!foo(::)) ret false;
while size == 0d0:
}
switch(h.ver0){
case 0d1:
if(
!`read(
f=, h=, (long)(shofs + 0d32), size,
misc, dummy, palletSame=, pl=, false)) ret false;
case 0d2:
if(!`readV2(f=, (long)misc, size)) ret false;
}
if(`imageGroup == ig && `imageNumber == in) break;
dummy.new(1);
dummy~palidx = `palidx;
continue:
shofs = h.ver0 == 0d1 ? misc : shofs + 0d28;
i++;
while i < (index)h.numberOfSprites:
ret false;
}
if(h.ver0 == 0d1){
`colorPallet = pl.get(`palidx);
`palidx = -1;
ret true;
}
loop{
uint ip;
indexOfPrevious = (uint)`palidx;
do:
ip = indexOfPrevious;
shofs = h.firstPaletteHeaderOffset + ip*0d16;
f.seek((long)shofs + 6, .file.Seek::SET);
if(!f.read!ushort?(indexOfPrevious=)) ret false;
if(!f.read!uint?(misc=)) ret false;
if(!f.read!uint?(size=)) ret false;
while size == 0d0 && ip != indexOfPrevious:
}
f.seek((long)(lofs+misc), .file.Seek::SET);
`colorPallet.new(256);
loop{
index i = 0, l = (index)size / 4;
ubyte r, g, b, dummy;
do:
if(!f.read!ubyte?(r=)) ret false;
if(!f.read!ubyte?(g=)) ret false;
if(!f.read!ubyte?(b=)) ret false;
if(!f.read!ubyte?(dummy=)) ret false;
`colorPallet[i] = (uint)r<<0d16 | (uint)g<<0d8 | (uint)b;
i++;
while i < l:
}
if(#`colorPallet == 0) `colorPallet.new(256);
`palidx = -1;
ret true;
}
public void draw(float x, float y, float xscale, float yscale, ^uint pal)
{
&.sdl.Rect tile;
tile.set(0, 0, 0d0, 0d0);
float x2 = x - xscale*(float)`rct.x;
float y2 = y - yscale*(float)`rct.y;
if(xscale < 0.0) x2 *= -1.0;
if(yscale < 0.0) y2 = -y2 + 240.0;
.sdl.screen.renderMugenZoom(
.com.scrrect=, 0.0, 0.0,
`pxl, pal, 0, `rct=, -x2*.com.WidthScale, -y2*.com.HeightScale,
tile=, xscale*.com.WidthScale, xscale*.com.WidthScale,
yscale*.com.HeightScale, 0.0, 0x0, 255, `rle, `pluginbuf=);
}
}
public &Sff
{
public &.SffHeader head;
public &.tbl.IntTable!uint, &.Sprite? spriteTable;
public &.PalleteList palList;
new()
{
`clear();
}
public void clear()
{
`spriteTable.clear();
`palList.clear();
loop{
index i = 0, foo;
^index idx;
while;
do:
`palList.newPal(foo=);
i++;
idx.new(1);
idx<> = foo;
`palList.palTable.set(0d1<<0d16 | (uint)i, idx);
while i < .NumCharPalletes:
}
}
public bool loadFile(^/char filename, bool chr)
{
&.file.File f;
if(!f.open(filename, "rb")) ret false;
`clear();
uint lofs, tofs;
if(!`head.read(f=, lofs=, tofs=)) ret false;
if(`head.ver0 != 0d1)loop{
index i = 0;
^uint pal;
ushort group, item, link, dummy;
uint ofs, siz;
^index idx;
while;
do:
f.seek((long)`head.firstPaletteHeaderOffset + 16*i, .file.Seek::SET);
if(!f.read!ushort?(group=)) ret false;
if(!f.read!ushort?(item=)) ret false;
if(!f.read!ushort?(dummy=)) ret false;
if(!f.read!ushort?(link=)) ret false;
if(!f.read!uint?(ofs=)) ret false;
if(!f.read!uint?(siz=)) ret false;
idx.new(1);
branch{
cond siz == 0x0:
pal = `palList.get((index)link);
idx<> = (index)link;
else:
f.seek((long)(lofs+ofs), .file.Seek::SET);
pal.new(256);
loop{
index i = 0, l = (index)siz / 4;
ubyte r, g, b, dummy8;
do:
if(!f.read!ubyte?(r=)) ret false;
if(!f.read!ubyte?(g=)) ret false;
if(!f.read!ubyte?(b=)) ret false;
if(!f.read!ubyte?(dummy8=)) ret false;
pal[i] = (uint)r<<0d16 | (uint)g<<0d8 | (uint)b;
i++;
while i < l:
}
idx<> = i;
}
`palList.setSource(i, pal);
`palList.palTable.set((uint)group<<0d16 | item, idx);
i++;
while i < (index)`head.numberOfPalettes:
}
uint shofs = `head.firstSpriteHeaderOffset, size;
loop{
index i = 0;
uint misc;
^&.Sprite spriteList;
spriteList.new((index)`head.numberOfSprites);
ushort indexOfPrevious;
index prev = -1;
while;
do:
f.seek((long)shofs, .file.Seek::SET);
switch(`head.ver0){
case 0d1:
if(!f.read!uint?(misc=)) ret false;
if(!f.read!uint?(size=)) ret false;
if(!spriteList[i].readHeader(f=)) ret false;
if(!f.read!ushort?(indexOfPrevious=)) ret false;
case 0d2:
if(
!spriteList[i].readHeaderV2(
f=, misc=, size=, lofs, tofs, indexOfPrevious=)) ret false;
}
branch{
bool ps;
cond size != 0d0:
switch(`head.ver0){
case 0d1:
if(
!spriteList[i].read(
f=, `head=, (long)(shofs + 0d32),
size, misc, spriteList[prev..prev+1], ps=, `palList=,
chr && spriteList[i].imageGroup == 0
&& spriteList[i].imageNumber == 0)) ret false;
case 0d2:
if(!spriteList[i].readV2(f=, (long)misc, size)) ret false;
}
prev = i;
else:
spriteList[i].shareCopy(spriteList[(index)indexOfPrevious]=);
spriteList[i].link = (index)indexOfPrevious;
}
`spriteTable.operate(
(uint)spriteList[i].imageGroup
| (uint)spriteList[i].imageNumber<<0d16,
[void(^&.Sprite s=){if(#s == 0) s = spriteList[i..i+1];}]);
shofs = `head.ver0 == 0d1 ? misc : shofs + 0d28;
i++;
while i < (index)`head.numberOfSprites:
}
ret true;
}
public ^&.Sprite getSprite(short group, short number)
{
ret `spriteTable.get((uint)group | (uint)number<<0d16);
}
public ^&.Sprite getOwnPalSprite(short group, short number)
{
^&.Sprite sp = `spriteTable.get((uint)group | (uint)number<<0d16);
if(#sp == 0) ret sp;
^&.Sprite ops.new(1);
ops~copy(sp<>=);
ops~colorPallet = .s.clone!uint?(sp~getPal(`palList=));
ret ops;
}
}
public &Anim<frame_t>
{
public ^&.Sff sff;
public ^&.Sprite spr;
public %frame_t frames;
public &.sdl.Rect tile;
public index loopstart = 0, current = 0, drawidx = 0;
public int nrepeat = -1;
public int time = 0;
public int repeatcnt = 0;
public int mask = -1;
public short salpha = -1, dalpha = 0;
public byte h = 1, v = 1;
public bool newframe = true, loopend = false;
new()
{
`tile.set(0, 0, 0d0, 0d0);
}
public void reset()
{
`current = 0;
`drawidx = 0;
`time = 0;
`repeatcnt = 0;
`newframe = true;
`loopend = false;
}
public void copy(`self a=)
{
`sff = a.sff;
`spr = a.spr;
`frames = a.frames;
`tile = a.tile;
`loopstart = a.loopstart;
`current = a.current;
`drawidx = a.drawidx;
`nrepeat = a.nrepeat;
`time = a.time;
`repeatcnt = a.repeatcnt;
`mask = a.mask;
`salpha = a.salpha;
`dalpha = a.dalpha;
`h = a.h;
`v = a.v;
`newframe = a.newframe;
`loopend = a.loopend;
}
public void setFrames(%`frame_t f, index l, int r)
{
`frames = f;
`loopstart = l;
`nrepeat = r;
}
public ^frame_t currentFrame()
{
ret `frames[`current..`current+1];
}
public int animTime()
{
if(#`frames == 0) ret 0;
if(`loopend && `time == 0) loop{
index i = `loopstart;
do:
if(i == `current) ret 0;
if(`frames[i].time != 0) break;
i++;
while i < #`frames:
}
int at = `time;
branch{
cond `frames[-1].time < 0:
at++;
loop{index j = 0; while; do:
at += `frames[j].time;
j++;
while j < `current:
}
else:
loop{
index i = `current;
if(`frames[i].time == 0) at--;
while;
do:
at -= `frames[i].time;
i++;
while i < #`frames:
}
}
ret at;
}
public int animElemTime(int elem)
{
int t;
if(elem > #`frames){
t = `animTime();
ret t > 0 ? 0 : t;
}
int e = elem - 1;
if(`loopend && `time == 0 && `current == `loopstart){
t = 0;
loop{index i = e; while; do:
t += `frames[i].time;
i++;
while i < #`frames && `frames[i].time >= 0:
}
ret t;
}
t = `time;
loop{index i = e; while; do:
t += `frames[i].time;
i++;
while i < `current && `frames[i].time >= 0:
}
loop{index i = `current; while; do:
t -= `frames[i].time;
i++;
while i < e && `frames[i].time >= 0:
}
ret t;
}
public int animElemNo(int time)
{
if(time == 0 && `loopend && `time == 0 && `current == `loopstart){
ret #`frames;
}
branch{
int t = time, oldt = 0;
cond t < 0:
loop{
index i = `current;
t += `time;
bool lp = false;
continue;
do:
t += `frames[i].time;
continue:
if(lp && `frames[i].time < 0){
ret i + 1;
}
if(t >= 0){
if(t == 0 && `loopend && i == `loopstart) ret #`frames;
ret i + 1;
}
i--;
while i >= 0 && (`current < `loopstart || i >= `loopstart):
if(t == oldt) break;
oldt = t;
lp = true;
i = #`frames - 1;
do;
}
else:
loop{
index i = `current;
t -= `frames[i].time - `time;
continue;
do:
t -= `frames[i].time;
continue:
if(t <= 0 || `frames[i].time < 0){
if(t == 0 && `loopend && i == `loopstart) ret #`frames;
ret i + 1;
}
i++;
if(i >= #`frames){
if(t == oldt) break, break;
oldt = t;
i = `loopstart;
}
while true:
}
}
ret 1;
}
public void setAnimElem(int e)
{
`current = .m.max!index?(0, e-1);
if(`current >= #`frames){
`current = `loopstart + `current % (#`frames-`loopstart);
}
`drawidx = `current;
`time = 0;
`newframe = true;
`updateSprite();
`loopend = false;
}
public void updateSprite()
{
if(#`frames == 0) ret;
if(`newframe){
`spr = `sff~getSprite(`frames[`current].group, `frames[`current].number);
}
`newframe = false;
`drawidx = `current;
}
public void action()
{
if(#`frames == 0) ret;
`updateSprite();
`frames[`current].action(`=);
}
int alphaFoo()
{
ubyte sa, da;
branch{
cond `salpha >= 0:
sa = (ubyte)`salpha;
da = (ubyte)`dalpha;
else:
sa = `frames[`drawidx].salpha;
da = `frames[`drawidx].dalpha;
}
branch{
cond sa == 0d1 && da == 0d255:
ret -2;
else:
sa = (ubyte)((int)sa * .com.brightness >> 8);
branch{
cond sa < 0d5 && da == 0d255:
ret 0;
cond sa == 0d255 && da == 0d255:
ret -1;
}
}
int alpha = (int)sa;
if((uint)sa+da < 0d254 || 0d256 < (uint)sa+da){
alpha |= (int)da << 10 | 1 << 9;
}
ret alpha;
}
^uint palFoo(^&.com.PalFX fx)
{
if(#fx == 0 || fx~time == 0) ret `spr~getPal(`sff~palList=);
ret fx~getFxPal(`spr~getPal(`sff~palList=), `alphaFoo() == -2);
}
public void draw(
&.sdl.Rect rect=, float x, float y, float cscalex, float cscaley,
float xtscale, float xbscale, float yscale, float rasterxadd,
float rx, ^&.com.PalFX fx)
{
if(#`spr == 0 || #`spr~pxl == 0) ret;
int h = `h*`frames[`drawidx].h, v = `v*`frames[`drawidx].v;
float xs = (float)h*cscalex*xtscale, ys = (float)v*cscaley*yscale;
float bs = xbscale;
.m.limRange!float?(xs=, -16000.0/.com.WidthScale, 16000.0/.com.WidthScale);
.m.limRange!float?(
ys=, -16000.0/.com.HeightScale, 16000.0/.com.HeightScale);
.m.limRange!float?(bs=, -16000.0/.com.WidthScale, 16000.0/.com.WidthScale);
float x2 =
cscalex*x - xs*(float)(`spr~rct.x - `frames[`drawidx].x) + rx;
float y2 = cscaley*y - ys*(float)(`spr~rct.y - `frames[`drawidx].y);
if(xs < 0.0){
x2 *= -1.0;
x2 += rx*2.0;
if(rx != 0.0) x2 += xs;
}
if(ys < 0.0){
y2 *= -1.0;
y2 += 240.0;
if(rx != 0.0) y2 += ys;
}
if(`tile.w == 0x1){
float tmp =
xs * ((float)`tile.x + (`tile.x > 0 ? 0.0 : (float)`spr~rct.w));
x2 -= (float)(int)(x2 / tmp) * tmp;
}
if(`tile.h == 0x1){
float tmp =
ys * ((float)`tile.y + (`tile.y > 0 ? 0.0 : (float)`spr~rct.h));
y2 -= (float)(int)(y2 / tmp) * tmp;
}
.sdl.screen.renderMugenZoom(
rect=, rx*.com.WidthScale, 0.0, `spr~pxl, `palFoo(fx), `mask, `spr~rct=,
(rx-x2)*.com.WidthScale, -y2*.com.HeightScale,
`tile=, xs*.com.WidthScale,
cscalex*bs*(float)h*.com.WidthScale, ys*.com.HeightScale,
cscalex*rasterxadd*(.com.WidthScale/.com.HeightScale),
0x0, `alphaFoo(), `spr~rle, `spr~pluginbuf=);
}
public void angleDraw(
float x, float y, float xscale, float yscale,
float angle, bool angleset, float axscl, float ayscl, ^&.com.PalFX fx)
{
if(#`spr == 0 || #`spr~pxl == 0) ret;
float rx = x + 160.0;
int h = `h*`frames[`drawidx].h;
int v = `v*`frames[`drawidx].v;
float xs = xscale * axscl, ys = yscale * ayscl;
float agl =
angle*(float)(`h * `v * (xs < 0.0 ? -1: 1) * (ys < 0.0 ? -1: 1));
uint uagl = (uint)((512.0/.m.PI)*agl + 0.5) & 0x3ff;
if(uagl == 0x0) branch{
cond angleset:
`draw(
.com.scrrect=, x+160.0 - xs*(float)(h*`frames[`drawidx].x), y,
1.0, 1.0, xs, xs, ys, 0.0, 0.0, fx);
else:
`draw(
.com.scrrect=,
x - (float)h*xscale*(axscl - 1.0)*(float)`frames[`drawidx].x, y,
1.0, 1.0, xs, xs, ys, 0.0, 160.0, fx);
comm:
ret;
}
.sdl.screen.renderMugenZoom(
.com.scrrect=, rx*.com.WidthScale,
(y+ys*(float)(v*`frames[`drawidx].y))*.com.HeightScale,
`spr~pxl, `palFoo(fx), `mask, `spr~rct=,
#xs*(float)`spr~rct.x*.com.WidthScale,
#ys*(float)`spr~rct.y*.com.HeightScale,
`tile=, xs*(float)h*.com.WidthScale,
xs*(float)h*.com.WidthScale, ys*(float)v*.com.HeightScale,
0.0, uagl, `alphaFoo(), `spr~rle, `spr~pluginbuf=);
}
public void setup(^&.Sff sff)
{
`sff = sff;
}
}