- scriptified cht_Give and cht_Take and made them virtual function of PlayerPawn so that this can be better configured for mods that want other options in here.

- improved the class pointer to string cast to print the actual type it describes and not the class pointer's own type.
- fixed: The 'is' operator created non-working code when checking the inheritance of a class pointer, it only worked for objects.
This commit is contained in:
Christoph Oelckers 2017-01-17 17:31:54 +01:00
commit 14f2c39e58
21 changed files with 559 additions and 461 deletions

View file

@ -401,7 +401,7 @@ begin:
OP(MOVEA):
{
ASSERTA(a); ASSERTA(B);
int b = B;
b = B;
reg.a[a] = reg.a[b];
reg.atag[a] = reg.atag[b];
NEXTOP;
@ -409,7 +409,7 @@ begin:
OP(MOVEV2):
{
ASSERTF(a); ASSERTF(B);
int b = B;
b = B;
reg.f[a] = reg.f[b];
reg.f[a + 1] = reg.f[b + 1];
NEXTOP;
@ -417,7 +417,7 @@ begin:
OP(MOVEV3):
{
ASSERTF(a); ASSERTF(B);
int b = B;
b = B;
reg.f[a] = reg.f[b];
reg.f[a + 1] = reg.f[b + 1];
reg.f[a + 2] = reg.f[b + 2];
@ -435,6 +435,18 @@ begin:
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(DYNCASTC_R) :
ASSERTA(a); ASSERTA(B); ASSERTA(C);
b = B;
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(DYNCASTC_K) :
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
b = B;
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(CAST):
if (C == CAST_I2F)
{
@ -1746,9 +1758,21 @@ static void DoCast(const VMRegisters &reg, const VMFrame *f, int a, int b, int c
break;
case CAST_P2S:
{
ASSERTS(a); ASSERTA(b);
reg.s[a].Format("%s<%p>", reg.atag[b] == ATAG_OBJECT ? (reg.a[b] == nullptr? "Object" : ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars() ) : "Pointer", reg.a[b]);
break;
if (reg.a[b] == nullptr) reg.s[a] = "null";
else if (reg.atag[b] == ATAG_OBJECT)
{
auto op = static_cast<DObject*>(reg.a[b]);
if (op->IsKindOf(RUNTIME_CLASS(PClass))) reg.s[a].Format("Class<%s>", static_cast<PClass*>(op)->TypeName.GetChars());
else reg.s[a].Format("Object<%p>", ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars());
}
else
{
reg.s[a].Format("%s<%p>", "Pointer", reg.a[b]);
}
break;
}
case CAST_S2I:
ASSERTD(a); ASSERTS(b);

View file

@ -86,6 +86,8 @@ xx(CAST, cast, CAST, NOP, 0, 0), // xA = xB, conversion specified by C
xx(CASTB, castb, CAST, NOP, 0, 0), // xA = !!xB, type specified by C
xx(DYNCAST_R, dyncast, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB);
xx(DYNCAST_K, dyncast, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
xx(DYNCASTC_R, dyncastc, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB); for class types
xx(DYNCASTC_K, dyncastc, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
// Control flow.
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++