Compare commits
10 Commits
a26dab0809
...
f49a71b581
| Author | SHA1 | Date | |
|---|---|---|---|
|
f49a71b581
|
|||
|
|
e405dc66e4 | ||
|
|
3eae20517a | ||
|
|
c235687096 | ||
|
|
c3801f1477 | ||
|
|
ad67a5d187 | ||
|
|
5995fcb7b4 | ||
|
|
57ef38a037 | ||
|
|
374d635f8a | ||
|
|
b620f82a2a |
@@ -57,6 +57,8 @@ DEF SORTTEST
|
||||
RSORT B$
|
||||
ASSERT__ B$[3]=="0","RSORT2"
|
||||
SORTTEST2
|
||||
STABLESORTTEST
|
||||
STABLERSORTTEST
|
||||
END
|
||||
DEF SORTTEST2
|
||||
DIM A[10]
|
||||
@@ -70,6 +72,39 @@ DEF SORTTEST2
|
||||
ASSERT__ A[8]==-1,"RSORT"
|
||||
ASSERT__ B[8]==12345,"RSORT"
|
||||
END
|
||||
DEF STABLESORTTEST
|
||||
DIM A[0],B[0]
|
||||
PUSH A,2:PUSH B,3
|
||||
PUSH A,3:PUSH B,4
|
||||
PUSH A,1:PUSH B,1
|
||||
PUSH A,1:PUSH B,2
|
||||
SORT A,B
|
||||
ASSERT__ A[0]==1,"STABLESORT"
|
||||
ASSERT__ A[1]==1,"STABLESORT"
|
||||
ASSERT__ A[2]==2,"STABLESORT"
|
||||
ASSERT__ A[3]==3,"STABLESORT"
|
||||
ASSERT__ B[0]==1,"STABLESORT"
|
||||
ASSERT__ B[1]==2,"STABLESORT"
|
||||
ASSERT__ B[2]==3,"STABLESORT"
|
||||
ASSERT__ B[3]==4,"STABLESORT"
|
||||
END
|
||||
|
||||
DEF STABLERSORTTEST
|
||||
DIM A[0],B[0]
|
||||
PUSH A,2:PUSH B,3
|
||||
PUSH A,3:PUSH B,4
|
||||
PUSH A,1:PUSH B,1
|
||||
PUSH A,1:PUSH B,2
|
||||
RSORT A,B
|
||||
ASSERT__ A[0]==3,"STABLESORT"
|
||||
ASSERT__ A[1]==2,"STABLESORT"
|
||||
ASSERT__ A[2]==1,"STABLESORT"
|
||||
ASSERT__ A[3]==1,"STABLESORT"
|
||||
ASSERT__ B[0]==4,"STABLESORT"
|
||||
ASSERT__ B[1]==3,"STABLESORT"
|
||||
ASSERT__ B[2]==2,"STABLESORT"
|
||||
ASSERT__ B[3]==1,"STABLESORT"
|
||||
END
|
||||
?"SORTTEST"
|
||||
SORTTEST
|
||||
?"SWAPTEST"
|
||||
|
||||
@@ -9,6 +9,7 @@ import std.uni;
|
||||
import std.utf;
|
||||
import std.conv;
|
||||
import std.stdio;
|
||||
import undead.string;
|
||||
static import std.algorithm;
|
||||
struct Trace
|
||||
{
|
||||
@@ -744,6 +745,11 @@ class PopG : Code
|
||||
vm.currentSlot.global[var] = Value(cast(int)v.doubleValue);
|
||||
return;
|
||||
}
|
||||
if (g.isNonStringArray && v.isNonStringArray)
|
||||
{
|
||||
vm.currentSlot.global[var] = v;
|
||||
return;
|
||||
}
|
||||
if(g.type == ValueType.Void)
|
||||
{
|
||||
vm.currentSlot.global[var] = v;
|
||||
@@ -816,6 +822,11 @@ class PopL : Code
|
||||
vm.stack[vm.bp + var] = Value(cast(int)v.doubleValue);
|
||||
return;
|
||||
}
|
||||
if (g.isNonStringArray && v.isNonStringArray)
|
||||
{
|
||||
vm.stack[vm.bp + var] = v;
|
||||
return;
|
||||
}
|
||||
if(g.type == ValueType.Void)
|
||||
{
|
||||
vm.stack[vm.bp + var] = v;
|
||||
|
||||
242
SMILEBASIC/bg.d
242
SMILEBASIC/bg.d
@@ -1,6 +1,7 @@
|
||||
module otya.smilebasic.bg;
|
||||
import otya.smilebasic.petitcomputer;
|
||||
import otya.smilebasic.error;
|
||||
import otya.smilebasic.sprite;
|
||||
import derelict.sdl2.sdl;
|
||||
import derelict.opengl3.gl;
|
||||
|
||||
@@ -34,6 +35,7 @@ class BG
|
||||
int chipWidth = 16;
|
||||
int chipHeight = 16;
|
||||
int display;
|
||||
int bgcolor;
|
||||
this(PetitComputer pc)
|
||||
{
|
||||
chip[] = BGChip(0);
|
||||
@@ -44,16 +46,23 @@ class BG
|
||||
scaley = 1;
|
||||
r = 0;
|
||||
show = true;
|
||||
bgcolor = 0xffffffff;
|
||||
initBGAnimationTable();
|
||||
}
|
||||
void render(int display, float disw, float dish)
|
||||
{
|
||||
animation();
|
||||
if (!show)
|
||||
return;
|
||||
float aspect = disw / dish;
|
||||
disw /= 2;
|
||||
dish /= 2;
|
||||
float z = offsetz;
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
{
|
||||
ubyte r, g, b, a;
|
||||
petitcom.RGBRead(bgcolor, r, g, b, a);
|
||||
glColor4ub(r, g, b, 255);
|
||||
}
|
||||
petitcom.chRenderingDisplay(display, clipx, clipx, clipx2 - clipx + 1, clipy2 - clipy + 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
@@ -207,12 +216,30 @@ class BG
|
||||
if(x > x2) swap(x, x2);
|
||||
if(y > y2) swap(y, y2);
|
||||
for(; y <= y2; y++)
|
||||
chip[x + y * width .. x2 + y * width] = BGChip(id);
|
||||
chip[x + y * width .. x2 + y * width + 1] = BGChip(id);
|
||||
/*for(int i = x; i <= x2; i++)
|
||||
{
|
||||
chip[i + y * width].i = id;
|
||||
}*/
|
||||
}
|
||||
void fill(int x, int y, int x2, int y2, ushort[] screendata)
|
||||
{
|
||||
import std.algorithm;
|
||||
if(x > x2) swap(x, x2);
|
||||
if(y > y2) swap(y, y2);
|
||||
int index = 0;
|
||||
if (screendata.length == 0)
|
||||
{
|
||||
fill(x, y, x2, y2, 0);
|
||||
return;
|
||||
}
|
||||
for(; y <= y2; y++)
|
||||
for(int i = x; i <= x2; i++)
|
||||
{
|
||||
chip[i + y * width] = BGChip(screendata[index] & 4095);
|
||||
index = (index + 1) % cast(int)screendata.length;
|
||||
}
|
||||
}
|
||||
int get(int x, int y, int flag)
|
||||
{
|
||||
if (flag)
|
||||
@@ -260,4 +287,215 @@ class BG
|
||||
}
|
||||
import otya.smilebasic.vm;
|
||||
Callback callback;
|
||||
public void color(int color)
|
||||
{
|
||||
this.bgcolor = color;
|
||||
}
|
||||
public int color()
|
||||
{
|
||||
return this.bgcolor;
|
||||
}
|
||||
bool isAnim;
|
||||
SpriteAnimData[][SpriteAnimTarget.V + 1] anim;
|
||||
int[SpriteAnimTarget.V + 1] animindex;
|
||||
int[SpriteAnimTarget.V + 1] animloop;
|
||||
int[SpriteAnimTarget.V + 1] animloopcnt;
|
||||
void setAnimation(SpriteAnimData[] anim, SpriteAnimTarget sat, int loop)
|
||||
{
|
||||
this.anim[sat] = null;
|
||||
if(loop < 0)
|
||||
{
|
||||
throw new IllegalFunctionCall("BGANIM");
|
||||
}
|
||||
animloop[sat] = loop;
|
||||
animloopcnt[sat] = 0;
|
||||
animindex[sat] = 0;
|
||||
this.anim[sat] = anim;
|
||||
isAnim = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void bganim(wstring target, double[] data)
|
||||
{
|
||||
static import std.uni;
|
||||
bool relative = false;
|
||||
if(target[$ - 1..$] == "+")
|
||||
{
|
||||
target = target[0..$-1];
|
||||
relative = true;
|
||||
}
|
||||
target = std.uni.toUpper(target);
|
||||
if (!(target in bgAnimTarget))
|
||||
throw new IllegalFunctionCall("BGANIM");
|
||||
auto tgete = bgAnimTarget[target];
|
||||
bganim(tgete | (relative ? SpriteAnimTarget.relative : cast(SpriteAnimTarget)0), data);
|
||||
|
||||
}
|
||||
SpriteAnimTarget[wstring] bgAnimTarget;
|
||||
void initBGAnimationTable()
|
||||
{
|
||||
bgAnimTarget = [
|
||||
"XY": SpriteAnimTarget.XY,
|
||||
"Z": SpriteAnimTarget.Z,
|
||||
"R": SpriteAnimTarget.R,
|
||||
"S": SpriteAnimTarget.S,
|
||||
"C": SpriteAnimTarget.C,
|
||||
"V": SpriteAnimTarget.V,
|
||||
];
|
||||
}
|
||||
SpriteAnimTarget getBGAnimTarget(wstring target)
|
||||
{
|
||||
bool relative = false;
|
||||
if(target[$ - 1..$] == "+")
|
||||
{
|
||||
target = target[0..$-1];
|
||||
relative = true;
|
||||
}
|
||||
return bgAnimTarget[target] | (relative ? SpriteAnimTarget.relative : cast(SpriteAnimTarget)0);
|
||||
}
|
||||
void animation(SpriteAnimData* data, SpriteAnimTarget target)
|
||||
{
|
||||
if (!animationEnabled)
|
||||
return;
|
||||
auto frame = data.elapse;
|
||||
if(frame == 1)
|
||||
{
|
||||
if(!data.interpolation)
|
||||
{
|
||||
switch(target)
|
||||
{
|
||||
case SpriteAnimTarget.XY:
|
||||
offsetx = cast(int)data.data.x;
|
||||
offsety = cast(int)data.data.y;
|
||||
break;
|
||||
case SpriteAnimTarget.Z:
|
||||
offsetz = cast(int)data.data.z;
|
||||
break;
|
||||
case SpriteAnimTarget.R:
|
||||
r = data.data.r;
|
||||
break;
|
||||
case SpriteAnimTarget.S:
|
||||
scalex = data.data.scalex;
|
||||
scaley = data.data.scaley;
|
||||
break;
|
||||
case SpriteAnimTarget.C:
|
||||
break;
|
||||
case SpriteAnimTarget.V:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(data.interpolation)
|
||||
{
|
||||
//線形補完する奴
|
||||
switch(target)
|
||||
{
|
||||
case SpriteAnimTarget.XY:
|
||||
offsetx = cast(int)(data.old.x + ((data.data.x - data.old.x) / data.frame) * frame);
|
||||
offsety = cast(int)(data.old.y + ((data.data.y - data.old.y) / data.frame) * frame);
|
||||
break;
|
||||
case SpriteAnimTarget.Z:
|
||||
offsetz = cast(int)(data.old.z + ((data.data.z - data.old.z) / data.frame) * frame);
|
||||
break;
|
||||
case SpriteAnimTarget.R:
|
||||
r = data.old.r + ((data.data.r - data.old.r) / data.frame) * frame;
|
||||
break;
|
||||
case SpriteAnimTarget.S:
|
||||
scalex = data.old.scalex + ((data.data.scalex - data.old.scalex) / data.frame) * frame;
|
||||
scaley = data.old.scaley + ((data.data.scaley - data.old.scaley) / data.frame) * frame;
|
||||
break;
|
||||
case SpriteAnimTarget.C:
|
||||
break;
|
||||
case SpriteAnimTarget.V:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void animation()
|
||||
{
|
||||
if (!animationEnabled)
|
||||
return;
|
||||
foreach(i, ref d; anim)
|
||||
{
|
||||
if(!d) continue;//未定義
|
||||
SpriteAnimTarget target = cast(SpriteAnimTarget)i;
|
||||
int index = animindex[i];
|
||||
SpriteAnimData* data = &d[index];
|
||||
data.elapse = data.elapse + 1;
|
||||
auto frame = data.elapse;
|
||||
animation(data, target);
|
||||
if(frame >= data.frame)
|
||||
{
|
||||
animindex[i] = (animindex[i] + 1) % cast(int)d.length;
|
||||
data.elapse = 0;
|
||||
if(animloop[i] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(!animindex[i])
|
||||
{
|
||||
animloop[i]++;
|
||||
if(animloop[i] >= animloopcnt[i])
|
||||
{
|
||||
anim[i] = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool animationEnabled = true;
|
||||
void bganim(SpriteAnimTarget target, double[] data)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
bool relative;
|
||||
if(SpriteAnimTarget.relative & target)
|
||||
{
|
||||
relative = true;
|
||||
target ^= SpriteAnimTarget.relative;
|
||||
}
|
||||
int animcount = cast(int)data.length / ((target == SpriteAnimTarget.XY || target == SpriteAnimTarget.UV) ? 3 : 2);
|
||||
SpriteAnimData[] animdata = new SpriteAnimData[animcount];
|
||||
int j;
|
||||
int loop = 1;
|
||||
SpriteAnimData* old;
|
||||
for(int i = 0; i < data.length;)
|
||||
{
|
||||
i = animdata[j].load(i, this, target, data, old, relative);
|
||||
old = &animdata[j++];
|
||||
if(data.length - i == 1)
|
||||
{
|
||||
//loop
|
||||
loop = cast(int)data[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAnimation(animdata, target, loop);
|
||||
if(animdata[0].frame == 1)
|
||||
{
|
||||
animindex[target]++;
|
||||
animation(&animdata[0], target);
|
||||
if(animcount == 1)
|
||||
{
|
||||
if(loop > 1 || loop == 0)
|
||||
{
|
||||
animindex[target] = 0;
|
||||
animloopcnt[target]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim[target] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import std.stdio;
|
||||
import std.ascii;
|
||||
import std.range;
|
||||
import std.string;
|
||||
import undead.string;
|
||||
import std.algorithm;
|
||||
import otya.smilebasic.error;
|
||||
import otya.smilebasic.type;
|
||||
@@ -1790,6 +1791,54 @@ class BuiltinFunction
|
||||
if(args[1].isNumber)
|
||||
p.sprite.spanim(no, cast(SpriteAnimTarget)(args[1].castInteger), animdata);
|
||||
}
|
||||
|
||||
static void BGANIM(PetitComputer p, Value[] va_args)
|
||||
{
|
||||
//TODO:配列
|
||||
auto args = retro(va_args);
|
||||
int no = args[0].castInteger;
|
||||
if (!p.isValidLayer(no))
|
||||
{
|
||||
throw new OutOfRange(smilebasicFunctionName, 1);
|
||||
}
|
||||
double[] animdata;
|
||||
if(args[2].isString)
|
||||
{
|
||||
VM vm = p.vm;
|
||||
vm.restoreData(args[2].castDString);
|
||||
int keyframe = vm.readData.castInteger;
|
||||
auto target = p.getBG(no).getBGAnimTarget(args[1].castDString);
|
||||
int item = 2;
|
||||
if((target & 7) == SpriteAnimTarget.XY || (target & 7) == SpriteAnimTarget.UV) item++;
|
||||
animdata = new double[item * keyframe + 1];
|
||||
int j;
|
||||
for(int i = 0; i < keyframe; i++)
|
||||
{
|
||||
animdata[j] = vm.readData.castDouble;
|
||||
animdata[j + 1] = vm.readData.castDouble;
|
||||
if(item == 3)
|
||||
animdata[j + 2] = vm.readData.castDouble;
|
||||
j += item;
|
||||
}
|
||||
if(args.length > 3)
|
||||
animdata[j] = args[3].castInteger;
|
||||
else
|
||||
animdata[j] = 1;//loop count
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
animdata = new double[args.length - 2];
|
||||
foreach(a; args[2..$])
|
||||
{
|
||||
animdata[i++] = a.castDouble;
|
||||
}
|
||||
}
|
||||
if(args[1].isString)
|
||||
p.getBG(no).bganim(args[1].castDString, animdata);
|
||||
if(args[1].isNumber)
|
||||
p.getBG(no).bganim(cast(SpriteAnimTarget)(args[1].castInteger), animdata);
|
||||
}
|
||||
static void SPDEF(PetitComputer p, int id, out int U, out int V)
|
||||
{
|
||||
if (!p.sprite.isValidDef(id))
|
||||
@@ -2292,6 +2341,30 @@ class BuiltinFunction
|
||||
{
|
||||
p.sprite.spstop();
|
||||
}
|
||||
static void SPHITINFO(PetitComputer p, out double tm)
|
||||
{
|
||||
tm = p.sprite.spriteHitInfo.time;
|
||||
}
|
||||
static void SPHITINFO(PetitComputer p, out double tm, out double x1, out double y1, out double x2, out double y2)
|
||||
{
|
||||
tm = p.sprite.spriteHitInfo.time;
|
||||
x1 = p.sprite.spriteHitInfo.x1;
|
||||
y1 = p.sprite.spriteHitInfo.y1;
|
||||
x2 = p.sprite.spriteHitInfo.x2;
|
||||
y2 = p.sprite.spriteHitInfo.y2;
|
||||
}
|
||||
static void SPHITINFO(PetitComputer p, out double tm, out double x1, out double y1, out double vx1, out double vy1, out double x2, out double y2, out double vx2, out double vy2)
|
||||
{
|
||||
tm = p.sprite.spriteHitInfo.time;
|
||||
x1 = p.sprite.spriteHitInfo.x1;
|
||||
y1 = p.sprite.spriteHitInfo.y1;
|
||||
x2 = p.sprite.spriteHitInfo.x2;
|
||||
y2 = p.sprite.spriteHitInfo.y2;
|
||||
vx1 = p.sprite.spriteHitInfo.vx1;
|
||||
vy1 = p.sprite.spriteHitInfo.vy1;
|
||||
vx2 = p.sprite.spriteHitInfo.vx2;
|
||||
vy2 = p.sprite.spriteHitInfo.vy2;
|
||||
}
|
||||
static void BGMSTOP(PetitComputer p)
|
||||
{
|
||||
writeln("NOTIMPL:BGMSTOP");
|
||||
@@ -2584,13 +2657,40 @@ class BuiltinFunction
|
||||
}
|
||||
return p.getBG(layer).rot;
|
||||
}
|
||||
static void BGFILL(PetitComputer p, int layer, int x, int y, int x2, int y2, int screendata)
|
||||
static void BGFILL(PetitComputer p, int layer, int x, int y, int x2, int y2, Value sd)
|
||||
{
|
||||
if (!p.isValidLayer(layer))
|
||||
{
|
||||
throw new OutOfRange("BGFILL", 1);
|
||||
}
|
||||
p.getBG(layer).fill(x, y, x2, y2, screendata);
|
||||
if (sd.type == ValueType.String)
|
||||
{
|
||||
wstring screendata = sd.castDString;
|
||||
if (screendata.length % 4 != 0)
|
||||
{
|
||||
throw new IllegalFunctionCall("BGFILL", 6);
|
||||
}
|
||||
ushort[] screendatas = new ushort[screendata.length / 4];
|
||||
for (int i = 0; i < screendata.length; i += 4)
|
||||
{
|
||||
ushort a;
|
||||
auto b = screendata[i..i + 4];
|
||||
if (!tryParse(b, 16, a))
|
||||
{
|
||||
throw new IllegalFunctionCall("BGFILL", 6);
|
||||
}
|
||||
screendatas[i / 4] = a;
|
||||
}
|
||||
p.getBG(layer).fill(x, y, x2, y2, screendatas);
|
||||
}
|
||||
else if (sd.isNumber)
|
||||
{
|
||||
p.getBG(layer).fill(x, y, x2, y2, sd.castInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TypeMismatch("BGFILL", 6);
|
||||
}
|
||||
}
|
||||
static void BGPAGE(PetitComputer p, int page)
|
||||
{
|
||||
@@ -2731,6 +2831,22 @@ class BuiltinFunction
|
||||
throw new IllegalFunctionCall("BGUNC"/*, 2*/);
|
||||
p.getBG(layer).callback = callback;
|
||||
}
|
||||
static void BGCOLOR(PetitComputer p, int layer, int color)
|
||||
{
|
||||
if (!p.isValidLayer(layer))
|
||||
{
|
||||
throw new OutOfRange("BGFUNC", 1);
|
||||
}
|
||||
p.getBG(layer).color = color;
|
||||
}
|
||||
static int BGCOLOR(PetitComputer p, int layer)
|
||||
{
|
||||
if (!p.isValidLayer(layer))
|
||||
{
|
||||
throw new OutOfRange("BGFUNC", 1);
|
||||
}
|
||||
return p.getBG(layer).color;
|
||||
}
|
||||
static void EFCON()
|
||||
{
|
||||
}
|
||||
@@ -3475,42 +3591,32 @@ class BuiltinFunction
|
||||
}
|
||||
static void RSORT(Value[] arg)
|
||||
{
|
||||
SORT(arg);
|
||||
|
||||
import std.range;
|
||||
int start, count;
|
||||
auto args = getSortArgument(arg, start, count);
|
||||
import std.algorithm;
|
||||
|
||||
int[] iarray;
|
||||
double[] darray;
|
||||
Array!wchar[] sarray;
|
||||
if (args[0].type == ValueType.IntegerArray)
|
||||
foreach (a; args)
|
||||
{
|
||||
iarray = args[0].integerArray.array[start..start + count];
|
||||
}
|
||||
if (args[0].type == ValueType.DoubleArray)
|
||||
{
|
||||
darray = args[0].doubleArray.array[start..start + count];
|
||||
}
|
||||
if (args[0].type == ValueType.StringArray)
|
||||
{
|
||||
sarray = args[0].stringArray.array[start..start + count];
|
||||
}
|
||||
if (args.length > 1)
|
||||
{
|
||||
mixin(sortGenerator!(8, "\"a[0]>b[0]\""));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args[0].type == ValueType.IntegerArray)
|
||||
if (a.type == ValueType.IntegerArray)
|
||||
{
|
||||
sort!("a > b", SwapStrategy.stable)(iarray);
|
||||
iarray = a.integerArray.array[start..start + count];
|
||||
reverse(iarray);
|
||||
}
|
||||
if (args[0].type == ValueType.DoubleArray)
|
||||
if (a.type == ValueType.DoubleArray)
|
||||
{
|
||||
sort!("a > b", SwapStrategy.stable)(darray);
|
||||
darray = a.doubleArray.array[start..start + count];
|
||||
reverse(darray);
|
||||
}
|
||||
if (args[0].type == ValueType.StringArray)
|
||||
if (a.type == ValueType.StringArray)
|
||||
{
|
||||
sort!("a > b", SwapStrategy.stable)(sarray);
|
||||
sarray = a.stringArray.array[start..start + count];
|
||||
reverse(sarray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import derelict.sdl2.image;
|
||||
import derelict.opengl3.gl;
|
||||
import otya.smilebasic.petitcomputer;
|
||||
import std.string;
|
||||
import undead.string;
|
||||
import std.stdio;
|
||||
import std.file;
|
||||
import std.conv;
|
||||
|
||||
@@ -12,6 +12,7 @@ static import std.algorithm;
|
||||
import core.stdc.stdio;
|
||||
import core.sync.mutex;
|
||||
import core.sync.condition;
|
||||
import core.thread;
|
||||
static import core.stdc.string;
|
||||
import otya.smilebasic.sprite;
|
||||
import otya.smilebasic.error;
|
||||
@@ -704,8 +705,8 @@ class PetitComputer
|
||||
return;
|
||||
}
|
||||
import std.algorithm : clamp, min, max;
|
||||
short stickx = SDL_GameControllerGetAxis(controller, x).clamp(-short.max, short.max);
|
||||
short sticky = SDL_GameControllerGetAxis(controller, y).clamp(-short.max, short.max);
|
||||
short stickx = SDL_GameControllerGetAxis(controller, x).clamp(cast(short)-short.max, short.max);
|
||||
short sticky = SDL_GameControllerGetAxis(controller, y).clamp(cast(short)-short.max, short.max);
|
||||
s.internalX = stickx / (short.max / Stick.max);
|
||||
s.internalY = -sticky / (short.max / Stick.max);
|
||||
stick(id, s);
|
||||
@@ -1330,7 +1331,8 @@ class PetitComputer
|
||||
for(int i = 0; !quit && maincntRender == oldmaincnt && !waitFlag && running; i++)
|
||||
{
|
||||
version (traceVM)
|
||||
std.stdio.stderr.writefln("%04X:%s", vm.pc, vm.getCurrent.toString(vm));
|
||||
if (vm.pc < vm.currentSlot.code.length)
|
||||
std.stdio.stderr.writefln("%04X:%s", vm.pc, vm.getCurrent.toString(vm));
|
||||
version (dumpStackVM)
|
||||
vm.dumpStack();
|
||||
auto b = vm.runStep();
|
||||
|
||||
@@ -95,7 +95,7 @@ struct SpriteAnimData
|
||||
case SpriteAnimTarget.XY:
|
||||
this.data.x = cast(int)data[i++];
|
||||
this.data.y = cast(int)data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.x += sprite.x;
|
||||
this.data.y += sprite.y;
|
||||
@@ -105,7 +105,7 @@ struct SpriteAnimData
|
||||
break;
|
||||
case SpriteAnimTarget.Z:
|
||||
this.data.z = cast(int)data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.z += sprite.z;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ struct SpriteAnimData
|
||||
case SpriteAnimTarget.UV:
|
||||
this.data.u = cast(int)data[i++];
|
||||
this.data.v = cast(int)data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.u += sprite.u;
|
||||
this.data.v += sprite.v;
|
||||
@@ -124,7 +124,7 @@ struct SpriteAnimData
|
||||
break;
|
||||
case SpriteAnimTarget.I:
|
||||
this.data.i = cast(int)data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.i += sprite.defno;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ struct SpriteAnimData
|
||||
break;
|
||||
case SpriteAnimTarget.R:
|
||||
this.data.r = data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.r += sprite.r;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ struct SpriteAnimData
|
||||
case SpriteAnimTarget.S:
|
||||
this.data.scalex = data[i++];
|
||||
this.data.scaley = data[i++];
|
||||
if (!old && relative)
|
||||
if (relative)
|
||||
{
|
||||
this.data.scalex += sprite.scalex;
|
||||
this.data.scaley += sprite.scaley;
|
||||
@@ -160,6 +160,73 @@ struct SpriteAnimData
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
import otya.smilebasic.bg;
|
||||
int load(int i, BG bg, SpriteAnimTarget target, double[] data, SpriteAnimData* old, bool r)
|
||||
{
|
||||
relative = r;
|
||||
this.frame = cast(int)data[i];
|
||||
if(this.frame < 0)
|
||||
{
|
||||
this.frame = -this.frame;
|
||||
interpolation = true;
|
||||
}
|
||||
if(this.frame == 0)
|
||||
{
|
||||
throw new IllegalFunctionCall("BGANIM");
|
||||
}
|
||||
i++;
|
||||
switch(target)
|
||||
{
|
||||
case SpriteAnimTarget.XY:
|
||||
this.data.x = cast(int)data[i++];
|
||||
this.data.y = cast(int)data[i++];
|
||||
if (relative)
|
||||
{
|
||||
this.data.x += bg.offsetx;
|
||||
this.data.y += bg.offsety;
|
||||
}
|
||||
this.old.x = old ? old.data.x : bg.offsetx;
|
||||
this.old.y = old ? old.data.y : bg.offsety;
|
||||
break;
|
||||
case SpriteAnimTarget.Z:
|
||||
this.data.z = cast(int)data[i++];
|
||||
if (relative)
|
||||
{
|
||||
this.data.z += bg.offsetz;
|
||||
}
|
||||
this.old.z = old ? old.data.z : bg.offsetz;
|
||||
break;
|
||||
case SpriteAnimTarget.R:
|
||||
this.data.r = data[i++];
|
||||
if (relative)
|
||||
{
|
||||
this.data.r += bg.r;
|
||||
}
|
||||
this.old.r = old ? old.data.r : bg.r;
|
||||
break;
|
||||
case SpriteAnimTarget.S:
|
||||
this.data.scalex = data[i++];
|
||||
this.data.scaley = data[i++];
|
||||
if (relative)
|
||||
{
|
||||
this.data.scalex += bg.scalex;
|
||||
this.data.scaley += bg.scaley;
|
||||
}
|
||||
this.old.scalex = old ? old.data.scalex : bg.scalex;
|
||||
this.old.scaley = old ? old.data.scaley : bg.scaley;
|
||||
break;
|
||||
case SpriteAnimTarget.C:
|
||||
this.data.c = cast(uint)data[i++];
|
||||
break;
|
||||
case SpriteAnimTarget.V:
|
||||
this.data.var = data[i++];
|
||||
break;
|
||||
default:
|
||||
throw new IllegalFunctionCall("BGANIM");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
struct SpriteDef
|
||||
{
|
||||
@@ -175,6 +242,9 @@ struct SpriteCollision
|
||||
short sy;
|
||||
ushort w;
|
||||
ushort h;
|
||||
double vx = 0;
|
||||
double vy = 0;
|
||||
|
||||
bool detection(ref SpriteData sp)
|
||||
{
|
||||
if(sp.define && sp.col.mask & mask)
|
||||
@@ -328,6 +398,18 @@ struct SpriteData
|
||||
SpriteCollision col;
|
||||
bool enableCol;
|
||||
}
|
||||
struct SpriteHitInfo
|
||||
{
|
||||
double time;
|
||||
double x1 = 0;
|
||||
double y1 = 0;
|
||||
double vx1 = 0;
|
||||
double vy1 = 0;
|
||||
double x2 = 0;
|
||||
double y2 = 0;
|
||||
double vx2 = 0;
|
||||
double vy2 = 0;
|
||||
}
|
||||
class Sprite
|
||||
{
|
||||
SpriteDef[] defSPDEFTable;
|
||||
@@ -1146,6 +1228,7 @@ class Sprite
|
||||
end = spid(end);
|
||||
return sphitsp2(id, start, end);
|
||||
}
|
||||
SpriteHitInfo spriteHitInfo;
|
||||
int sphitsp2(int id, int start, int end)
|
||||
{
|
||||
if (!sprites[id].enableCol)
|
||||
@@ -1156,7 +1239,19 @@ class Sprite
|
||||
{
|
||||
if(id == start) continue;
|
||||
if(sprites[start].enableCol && sprites[id].col.detection(sprites[start]))
|
||||
{
|
||||
spriteHitInfo.time = 0;
|
||||
spriteHitInfo.x1 = sprites[id].x;
|
||||
spriteHitInfo.y1 = sprites[id].y;
|
||||
spriteHitInfo.vx1 = sprites[id].col.vx;
|
||||
spriteHitInfo.vy1 = sprites[id].col.vy;
|
||||
spriteHitInfo.x2 = sprites[start].x;
|
||||
spriteHitInfo.y2 = sprites[start].y;
|
||||
spriteHitInfo.vx2 = sprites[start].col.vx;
|
||||
spriteHitInfo.vy2 = sprites[start].col.vy;
|
||||
|
||||
return start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -184,6 +184,11 @@ struct Value
|
||||
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray ||
|
||||
this.type == ValueType.StringArray || this.type == ValueType.String;
|
||||
}
|
||||
bool isNonStringArray()
|
||||
{
|
||||
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray ||
|
||||
this.type == ValueType.StringArray;
|
||||
}
|
||||
bool isNumberArray()
|
||||
{
|
||||
return this.type == ValueType.IntegerArray || this.type == ValueType.DoubleArray;
|
||||
|
||||
35
dub.json
35
dub.json
@@ -1,14 +1,27 @@
|
||||
{
|
||||
"name": "otyasmilebasic",
|
||||
"dependencies": {
|
||||
"derelict-sdl2": "1.9.7",
|
||||
"derelict-gl3": "1.0.15"
|
||||
},
|
||||
"sourcePaths": ["SMILEBASIC/"],
|
||||
"importPaths": ["SMILEBASIC/"],
|
||||
"targetType": "executable",
|
||||
"buildRequirements": ["allowWarnings"],
|
||||
"buildRequirements": [
|
||||
"allowWarnings"
|
||||
],
|
||||
"targetPath": "out",
|
||||
"name": "otyasmilebasic",
|
||||
"copyFiles": [
|
||||
"SMILEBASIC/TEST.txt",
|
||||
"SMILEBASIC/resources/*.txt",
|
||||
"SMILEBASIC/spdef.csv",
|
||||
"SMILEBASIC/dialogresource",
|
||||
"SDL_GameControllerDB/gamecontrollerdb.txt"
|
||||
],
|
||||
"sourcePaths": [
|
||||
"SMILEBASIC/"
|
||||
],
|
||||
"dependencies": {
|
||||
"derelict-gl3": "1.0.15",
|
||||
"derelict-sdl2": "1.9.7",
|
||||
"undead": "~>1.2.0"
|
||||
},
|
||||
"targetType": "executable",
|
||||
"workingDirectory": "out",
|
||||
"copyFiles": ["SMILEBASIC/TEST.txt", "SMILEBASIC/resources/*.txt", "SMILEBASIC/spdef.csv", "SMILEBASIC/dialogresource", "SDL_GameControllerDB/gamecontrollerdb.txt"]
|
||||
}
|
||||
"importPaths": [
|
||||
"SMILEBASIC/"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user