Code Ausführung ist durcheinader bei Superscalar CPU
-
Was mich wundert, warum gibt die Playstation mehrfach diese Ausgabe aus:
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
if(!_itr->arest)
{
std::cout << "gameObjectPtr address: " << gameObjectPtr << " this address: " << this << std::endl;Klar, weil post_interaction schon von falschen Instanz aufgerufen wurde, da ist arest 0
Aber hier, ist was nicht in Ordung, dass muss ich mal abklären:
const uint8_t ITR_Len = thisFrame.D->numOfItr;
for(uint8_t i=0; i<ITR_Len; i++)Itr ist bei dem Zweienten Charakter immer 0, weil der macht ja nix und steht nur rum.
Esseiden, beim aufrufen der hit Funktion überschrieb ich die Adresse der Instanz, Übertrieben gesagt this=... .
Ich rufe ja hier hit auf: gameObjectPtr->hit_impl(itr, this, &vol))
hit ist eine Methode von Charakter, daher die virtuelle Funktion:
In Charakter.h habe ichfloat hit_impl(const Itr *itr, Charakter *thisChar, const Volume *vol) override { return hit(itr, thisChar, vol); }
Wenn ich return hit(itr, this, vol); schreibe, haue ich mich direkt selbst, nicht erst bei einer Combo.
Wahrscheinlich doch ein vTable Problem oder der Compiler kann mit this nicht umgehen.
Wer Spaß hat, kann sich noch durch die hit Funktion hangeln, aber das Problem muss schon beiaufrufen, bzw vor dem aufrufen passieren.float Charakter::hit(const Itr *itr, Charakter *att,const Volume *vol) { Charakter *that = this; util utility; if(!that->itr_vrest_test(att->engineID)) { return false; } bool accepthit = false; bool defended = false; float ef_dvx = 0; ef_dvy = 0; float inj = 0; auto falldown = [&](){ if(itr->dvy == 0) { ef_dvy = GC._default.fall.dvy; } that->health.fall = 0; that->bdyBox.vy = 0; const bool _front = (att->bdyBox.x > that->bdyBox.x) == (that->bdyBox.dir == '>'); if((itr->dvx != 0 && itr->bdefend >= 0) && (_front && itr->dvx < 0 && itr->bdefend >= 60)) { that->setFrame(186,21); } else if(_front) { that->setFrame(180,21); } else if(!_front) { that->setFrame(186,21); } };//lambda fall down auto fall = [&](){ if(itr->fall != 0) { health.fall += itr->fall; }else{ health.fall += GC._default.fall.value; } const uint16_t _fall = health.fall; if(that->getState() == 13) { falldown(); } else if(that->bdyBox.y < 0 || that->bdyBox.vy < 0) { falldown(); } else if(that->health.hp - inj <= 0) { falldown(); } else if(_fall > 0 && _fall <= 20) { that->setFrame(220,20); } else if(_fall > 20 && _fall <=30) { that->setFrame(222,20); } else if(_fall > 30 && _fall <= 40) { that->setFrame(224,20); } else if(_fall > 40 && _fall <= 60) { that->setFrame(226,20); } else if(GC.fall.KO < _fall) { falldown(); } };// lambda Fall if(that->getState() == 10) //beeing caught { if(that->catching && that->catching->_char->caught_cpointhurtable()) { accepthit = true; fall(); } if(catching && catching->_char->caught_cpointhurtable() == 0 && catching->_char->engineID != att->engineID) { // I am unhurtable as defined by catcher, // and I am hit by attacker other than catcher } else { accepthit = true; inj += abs(itr->injury); if(itr->injury > 0) { that->effect_create(0, GC.effect.duration); int16_t tar; if(itr->vaction != 0) { tar = itr->vaction; } else { tar = (att->bdyBox.x > that->bdyBox.x) == (that->bdyBox.dir == '>') ? that->thisFrame.D->cpoint.fronthurtact : that->thisFrame.D->cpoint.backhurtact; } that->setFrame(tar, 20); } } } else if(that->getState() == 14) { //lying } else if(that->getState() == 19 && att->getState() == 3000) { //firerun return false; } else if(itr->kind < 0 || itr->kind == 0 || itr->kind == 4 || itr->kind == 9) //normal, falling, reflectif shiled { accepthit = true; const bool compen = bdyBox.y == 0 ? 1 : 0; const int8_t attdir = att->bdyBox.vx == 0 ? att->dirh() : (att->bdyBox.vx > 0 ? 1 : -1); if(itr->dvx != 0) { ef_dvx = attdir * (itr->dvx - compen); } else { ef_dvx = 0; } if(itr->dvy != 0) { ef_dvy = itr->dvy; } else { ef_dvy = 0; } const uint8_t effectnum = itr->effect >= 0 ? itr->effect : GC._default.effect.num; if(that->getState() == 13 && effectnum == 30) // frozen characters are immune to effect 30 'weak ice' { return false; } if((that->getState() == 18 || that->getState() == 19) && (effectnum == 20 || effectnum == 21)) //burning and firerun characters are immune to effect 20/21 'weak fire' { return false; } if(that->getState() == 7 && (att->bdyBox.x > bdyBox.x) == (bdyBox.dir == '>')) // defend ; // attacked in front { if(itr->injury != 0) { inj += GC.defend.injury.factor * itr->injury; } if(itr->bdefend >= 0) { health.bdefend += itr->bdefend; } if(that->health.bdefend > GC.defend.break_limit) { that->setFrame(112,20); } else { that->setFrame(110,20); } if(ef_dvx) { ef_dvx += (ef_dvx > 0 ? -1 : 1) * utility.lookup_abs(GC.defend.absorb, ef_dvx); } ef_dvy = 0; if(that->health.hp - inj <= 0) { falldown(); } else { defended = true; } } else //end defend { //TODO hold obj if(itr->injury != 0) { inj += itr->injury; } health.bdefend = 45; fall(); } uint8_t vanish = GC.effect.duration - 1; switch(getNext()) { case 111: { vanish = 3; break; } case 112: { vanish = 4; break; } } that->effect_create(effectnum, vanish, ef_dvx, ef_dvy); //TODO Posteffec }//TODO itr-kind 15 & itr.kind 16 if(accepthit) { that->_itr->attacker = att; } that->injury(inj); if(accepthit) { return inj; } else { return 0; } }
Das Problem ist ja, das sich beide Chakrakter KO hauen aber nur bei ienr Kombo.
Das beduet das der Zeiger in der vTabel zum zeitunkt x noch falsch ist.
Sehe ich das richtg?
-
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Wenn ich return hit(itr, this, vol); schreibe
Ich habe das noch mal gecheckt return hit(itr, this, vol); geht auch und macht genau das selbe Problem.
Bei einer Combo treffe ich mich selbst.Es gibt ja bei der Playstation einige Restriktionen die zu beachten sind. Was mir im klassischen C(fast alles auf der Ps2 ist in c geschrieben) aufgefallen ist, dass an jedem struct attribute((packed)) hängt.
attribute((packed)) geht in c++ nicht, da müsste ich das linker File neu schreiben. Ich bin bei dem Makefile schon fast gestorben
Dann wird sehr viel mit semaphores gearbeitet und mutex wird auch oft verwendet mit und ohne Zusammenhang der Semaphores.__sync() habe ich auch schon mal gesehen, das ist auch so ein Speicher voodoo.
Es gibt zwei potentiell Probleme die ich jetzt Atok sehe. Entweder kann er "this" nicht verarbeiten, aufgrund von aggresiven Optimierungen ( die ich aus habe ).
Oder er kann die vTable nicht verarbeiten.Eine Idee habe ich noch.
Ich mache die Engine klasse als Basis Klasse für LivingObject.
Dann kann ich in über eine Virtuelle Funktion alle abgeleiteten Klassen ansprechen.
Damit ist dann die Engine Klasse teil der vTable.
Ist aber auch erst mal nur graue Theorie.
-
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Es gibt ja bei der Playstation einige Restriktionen die zu beachten sind. Was mir im klassischen C(fast alles auf der Ps2 ist in c geschrieben) aufgefallen ist, dass an jedem struct attribute((packed)) hängt.
attribute((packed)) geht in c++ nicht, da müsste ich das linker File neu schreiben. Ich bin bei dem Makefile schon fast gestorbenSicher? Ich habe damit zumindest bei GCC bisher keine Probleme gehabt. Da geht's in C++ sogar mit C++11-Attributen:
struct [[gnu::packed]] A { ... }
. Ist da der C++-Compiler vielleicht ein anderer als der C-Compiler? Oder vielleicht stand das Attribut auch nur an der falschen Stelle? Das gehört nachstruct
/class
. Was gibt's denn da für ne Fehlermeldung?Mit nem Linker-Skript hat man soweit ich weiß eh keinen Einfluss auf diese interne Struktur von Objekten. Da kann man nur festlegen, wo die Objekte als ganzes letztendlich hin sollen (im Speicher oder in der Executable).
Und sorry dass ich mit deinem Hauptproblem auch keinen Geistesblitz habe. Ich weiß nur, dass die PS2 wegen ihrer besonderen Architektur zwar sehr leistungsfähig für ihre Generation, aber eine echte Herausforderung zu programmieren war. Das riecht ein bisschen als müsse man die Hardware schon sehr intim kennen, um da das Problem zu finden
-
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Normaler weise wird bei einer Kombo if(!_itr->arest) gesetzt und über einen Timer abgebaut
Was meinst du mit Timer? Interrupt von einem Hardware-Timer?
Und hast du mehrere Threads laufen?bei Superscalar CPU
Alle modernen CPUs sind superscalar. Man hat bloss aufgehört das Wort zu verwenden, weil es mittlerweile Standard ist. Daran liegt es also schonmal nicht.
Falls du unions oder verbotene Pointer-casts verwendest (also z.B. nen
int*
zu nemshort*
casten und dann dereferenzieren) könntest du versuchen mit-fno-strict-aliasing
zu bauen.Was man theoretisch auch nicht ausschliessen kann sind Compiler-Bugs. Soweit ich weiss erfordert der MIPS R5900 dass die Instruktionen vom Compiler schon passend "angeordnet" werden, so dass Abhängigkeiten/Ausführungszeiten berücksichtigt wurden. Wenn der Compiler das nicht macht, dann kann es sein dass der generierte Code auf einem Emulator funktioniert, aber auf echter Hardware dann leider nicht.
Also vielleicht mal nen anderen Compiler versuchen. Mach dich schlau was der "beste" Compiler für PS2 ist.
-
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Das habe ich mir auch schon gedacht, aber ich Blicks nicht was hier passiert. Wenn man gdb nutzen könnte, könnte man mit dem Debugger den Code schrittweise durchgehen.
Kann man aber leider nicht, da dies dein Timing komplett stören würde.
Mein Gedanke zielt in folgende Richtung:
Du nutzt eine PS2 welche sich vermutlich anders verhält als ein Standard PC. Du sagst dass das Problem bei einem Combo auftritt. Hau mich bitte nicht, aber Spielen ist nicht so mein Ding. Ein Combo war doch eine schnelle Kombination von Tastenkombinationen bzw. Schlägen. In Endeffekt eine schnelle Folge von Tastenevents.
Von daher wäre es interresant zu wissen welche Events da auftreten. Deswegen würde ich da einen Logger einsetzen um dies genau nachzuverfolgen.
Folgende Fragen würde ich klären:
- Wie schnell kommen die Events?
- Wie lange dauert die Bearbeitung?
- Wie reagiert deine Eventbehandlung unter Volllast?
-
@Finnegan sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Sicher?
Da kommt ganz normal error: 'packed' was not declared in this scope
@hustbaer sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Was meinst du mit Timer? Interrupt von einem Hardware-Timer?
Und hast du mehrere Threads laufen?Nein, ich habe keine Threads am laufen.
Nein ,keine Hardware Timer. Timing über die game loop. arest steht für attack rest. Quasi die Ausdauer.
Nach einer Kombo wird arest gesetzt (für this, also den attacker) weil Ausdauer verbraucht wurde.Da aber post_interaction schon aus dem falschen Kontext her aufgerufen wurde und this schon auf den falchen Speicher zeigt, setzt er arest auch auf den angegriffen Charakter. Daher feuert cout mehrmals.
Allerdings hat der angegriffene Charakter keine ITR's (Interaktionen) daher darf er hier:
void Charakter::post_interaction() { const uint8_t ITR_Len = thisFrame.D->numOfItr; for(uint8_t i=0; i<ITR_Len; i++) {
Schon gar nicht rein gehen.
Der erste aufruf von if(attacked(gameObjectPtr->hit_impl(itr, &vol)))
passt noch
Danach sind alle Werte von den angegriffenen Charakter auch die der Angreift.Was noch passt, die Kobo geht von frame 70 bis Frame 73, danach muss auf frame 0 Gesprungen werden.
Frame 72 setzt arest.
Er springt aber nicht auf frame 0 weil zuvor in hit that->setFrame(180,21); aufgerufen wurde. Weil hit auch schon aus dem falschen Kontext aufgerufen wurde weil post_interaktion schon an falscher stelle ist.
Das heißt beide Charakter bekommen zum Zeitpunkt x that->setFrame(180,21); aufgebrummt.Aber warum nur bei einer Combo???????
@Quiche-Lorraine sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Ein Combo war doch eine schnelle Kombination von Tastenkombinationen bzw. Schlägen. In Endeffekt eine schnelle Folge von Tastenevents.
Ja richtig, eine Combo ist ein folge von Tastenkombinationen, die in der Richtigen zeit eingegeben werden müssen.
Zum meinem jetzigen Zeitpunk habe ich nur zwei Kobo's: rennen angriff und drei mal Attacke, beides führt zu Frame 70.die Kombo wird ausgewertet kurz vor der Transition in Funktion transit:
void LivingObject::transit() { if(childController) { combo_impl(); } if(effect.timein < 0 && effect.stuck) { //stuck } else { //trans; trans(this); } effect.timein--; if(effect.timein < 0 && effect.stuck) { //stuck } else { state_update(-9); } } combo_impl(); ist wider eine virtuelle Funktion: ```cpp void combo_impl() override { combo_update(); }
und ```cpp void Charakter::combo_update() { uint16_t K = 0; if(comboBuffer) { K = comboBuffer->combo; } if(comboBuffer->combo && comboBuffer->combo == 67) //67 jump-att { K = 6; } int16_t tar1 = call(this, thisFrame.D->state, -3, K); int16_t tar2 = 0; if(tar1 <= 0) { tar2 = generic(this, -3, K); } call(this, thisFrame.D->state, -4, 0); generic(this, -4, K); if(comboBuffer->combo && comboBuffer->combo == 67) //67 jump-att { if(tar1 || tar2) { comboBuffer->combo = 7; } } else { if(tar1 > 0 || tar2 > 0 || K == 1 || K == 2 || K ==3 || K==4 ) { comboBuffer->combo = 0; } } }
in combo_update wird wiederum generic aufgerufen und generic ruft post_interaction auf.
int16_t Char_States::generic(Charakter *basePtr,int8_t e, uint16_t K) { switch(e) { case -1: //frame { if(basePtr->thisFrame.D->mp != 0) { if(mainCharFrames[basePtr->uID][basePtr->thisFrame.PN]->next == basePtr->thisFrame.N) { if(basePtr->thisFrame.D->mp < 0) { if(!Engine::getInstance().F6_mode) { basePtr->health.mp += basePtr->thisFrame.D->mp; } basePtr->health.mp_usage -= basePtr->thisFrame.D->mp; if(basePtr->health.mp < 0) { basePtr->health.mp = 0; basePtr->setFrame(basePtr->thisFrame.D->hit_d); } } } else { const int16_t dmp = basePtr->thisFrame.D->mp % 1000; const int16_t dhp = floor(basePtr->thisFrame.D->mp / 1000) * 10;//frame.d.Mp correct?? if(!Engine::getInstance().F6_mode) { basePtr->health.mp -= dmp; } basePtr->health.mp_usage += dmp; basePtr->injury(dhp); } } //todo Opoint(); }//frame break; case -5: //TU { if(!basePtr->state_update(-100)) { basePtr->post_interaction(); } if (basePtr->bdyBox.y == 0 && basePtr->bdyBox.vy == 0 && basePtr->thisFrame.N == 212 && basePtr->thisFrame.PN != 211) { basePtr->setFrame(999); } else if (basePtr->bdyBox.y == 0 && basePtr->bdyBox.vy > 0) // fell onto ground { int16_t result = basePtr->state_update(-11); if (result > 0) { basePtr->setFrame(result, 15); } else { basePtr->bdyBox.vy = 0; // set to zero basePtr->linear_friction( utility.lookup_abs(GC.friction.fell, basePtr->bdyBox.vx), utility.lookup_abs(GC.friction.fell, basePtr->bdyBox.vz) ); } } else if (basePtr->bdyBox.y + basePtr->bdyBox.vy >= 0 && basePtr->bdyBox.vy > 0) // predict falling onto the ground { int16_t result = basePtr->state_update(-12); if (result > 0) { basePtr->setFrame(result, 15); } else { if (basePtr->getState() == 13) // frozen { ; // do nothing } else if (basePtr->thisFrame.N == 212) // jumping { basePtr->setFrame(215, 15); // crouch } else { basePtr->setFrame(219, 15); // crouch2 } } } // basePtr->health recover // http://lf2.wikia.com/wiki/Health_and_mana if (Engine::getInstance().timeT % 12 == 0) { if (basePtr->health.hp >= 0 && basePtr->health.hp < basePtr->health.hp_bound) { basePtr->health.hp++; } } if (basePtr->health.hp >= 0 && basePtr->effect.heal && basePtr->effect.heal > 0) { if (Engine::getInstance().timeT % unsigned(basePtr->heal_speed) == 0) { if (basePtr->health.hp + basePtr->heal_speed <= basePtr->health.hp_bound) { basePtr->health.hp += basePtr->heal_speed; } basePtr->effect.heal -= basePtr->heal_speed; } } if (Engine::getInstance().timeT % 3 == 0) { if (basePtr->health.mp < basePtr->health.mp_full) { basePtr->health.mp += 1 + floor((basePtr->health.hp_full - (basePtr->health.hp < basePtr->health.hp_full ? basePtr->health.hp : basePtr->health.hp_full)) / 100); } } // recovery if (basePtr->health.fall > 0) { basePtr->health.fall += GC.recover.fall; } if (basePtr->health.bdefend > 0) { basePtr->health.bdefend += GC.recover.bdefend; } basePtr->comboBuffer->timeout--; if(basePtr->comboBuffer->timeout == 0) { if(K == 5 || K == 6 || K == 7 || K == 11 || K == 22 ) { basePtr->comboBuffer->combo = 0; } } }//TU break; case -9 : //transit { basePtr->dynamics(); } break; } return 0; }//generic
Die gesamte state machine umfasst über 100 states. das ist ein Riesen Baum an switch und if's.
In der generic Funktion wird auch Energie hinzugefügt basePtr->health.hp += basePtr->heal_speed;
wie zuvoor erwähnt wirkt sich eien ineraktion auf beide Charaktere aus.Villeicht gibt es auch ein Problem mit Mehrfachvererbung
class Charakter : public LivingObject, protected Char_States. Weil, health ist ein struct in LivingObject.
-
Ich fange bald an zu weinen...
Ich finde das Problem einfach nichtDie Engine klasse als Basisklasse für alle LivingObjects einzurichten geht nicht, da verhedder ich mich in Zirkulären Abhängigkeiten.
Zudem ist es tatsächlich so, das die "falling Frames" ein itr tag haben
Das heißt, er geht auch für den Gegner Charakter hier rein:void Charakter::post_interaction() { const uint8_t ITR_Len = thisFrame.D->numOfItr; for(uint8_t i=0; i<ITR_Len; i++) {
itr_arest_update(itr); wird korrekt gesetzt trotzdem spuckt die Playstaion bzw pcsx2 mehrmals:
std::cout << "gameObjectPtr address: " << gameObjectPtr << " this address: " << this << std::endl;
aus.Der Verdacht verhärtet sich, das es was mit dem Controller zu tun haben muss.
Die combo wird ausgewertet in combo_update(). hier wird auch nochmals generic aufgerufen, was auch post_interaktion aufruft.if(tar1 <= 0) { tar2 = generic(this, -3, K); } call(this, thisFrame.D->state, -4, 0); generic(this, -4, K);
Allerdings mit dem event -4 oder -3. Post Interaktion ist event -5
Nicht das er in genric eventuell eine break; Anweisung überspringt.Es gibt nur zwei Sachen die unterschiedlich sind vom PC zu Playstation.Der PC rendert via SDL2 und die Playstation via GS und der PC hat als Eingabegerät eine Tastatur, die Playstation eine Controller.
Ich begreife nicht wie der Controller, die events beeinflussen könnte.
Der Combodecoder erkennt die Eingaben egal ob Tastatur oder Controller und wenn eine Combo erkannt wurde wird sie an die Charakter Instanz übergebenen. Dafür gebe ich den Zeiger der Charakter Instanz an den Combodecoder
Der Zeiger aber auch nur dann übergeben, wenn es sich um eine Charakter Instanz handelt die von einer Person gesteuert wird.
-
Nochmal: ich denke es ist durchaus möglich dass der Compiler schuld ist.
-
@hustbaer sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Nochmal: ich denke es ist durchaus möglich dass der Compiler schuld ist.
Das wäre übel, weil es gibt keine alternative. Die EE hat eine von MIPS speziell angepasste Architektur.
entweder den Algorithmus umbauen oder in klassischen c style programmieren.
Zudem habe ich Tage damit verbracht Vektor Assamlber code zu schreiben für die Sprite's zu rendern.Irgend einen Grund wird es schon haben, weshalb kaum jemand die PS2 in C++ programmiert.
Fakt ist aber das Ereignis, dass sich zwei Charakter gegenseitig zu Boden hauen gibt es, z.b wenn zwei Charakter aufeinander zu rennen und zur selben zeit Attacke drücken.
Wird hier erklärt:
https://project-f.github.io/F.LF/docs/match.html
und hier:
https://project-f.github.io/F.LF/docs/processing.htmlIch habe heute nun noch mal die Controller eingaben angeschaut und mit Tastatur verglichen. Da ist das Problem auch nicht. Zudem habe ich überall das Schlüsselwort virtual entfernt, damit der Compiler keine vtable erzeugt.
Kein erfolgEr macht an der stelle wo in post_interaction die query Funktion aufruft einen Versatz in der game loop.
in emit_event muss die Schleife ein pause machen, wenn in query durch alle gamobjeckte gelaufen wird.
Hier passiert Unfug.Man müsste irwo was mit thread's machen bzw mit mutex. Ich weiß allerdings nicht wo/wie.
@Quiche-Lorraine sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Wie reagiert deine Software wenn du z.B. ein kleines Delay an gewissen Stellen (z.B. bei deinem std::cout << "gameObjectPtr address: "...) einbaust?
Also z.B. folgendes:
std::cout << "gameObjectPtr address: " << gameObjectPtr << " this address: " << this << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1));Habe ich ausprobiert, passiert nichts. Auch nicht mit milliseconds 100.
-
Also, dass es sich um ein Compiler Problem handelt, über die Brücke gehe ich nicht.
Ich habe vorhin noch mal in die post_interaction Funktion eine Ausgabe hinzugefügt. Und zwar zuerst, wer ruft den die Funktion auf und was gibt die query Funktion zurück + den index des vectors.
Der PC gibt aus:
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0
gameObjectPtr: 0x5555561ec1d8 t: 0
gameObjectPtr:0x5555561ec1d8 thisPtr: 0x5555561ec0c0
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0
gameObjectPtr: 0x5555561ec1d8 t: 0
Aufruf von: 0x5555561ec0c0
gameObjectPtr: 0x5555561ec1d8 t: 0
Aufruf von: 0x5555561ec0c0
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0
Aufruf von: 0x5555561ec1d8
Aufruf von: 0x5555561ec0c0Der gameObjectPtr: 0x5555561ec1d8 ist immer gleich
Die Playstation spuckt ausAufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
gameObjectPtr: 0x317430 t: 0
gameObjectPtr address: 0x317430 this address: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
gameObjectPtr: 0x317430 t: 0
Aufruf von: 0x317100
gameObjectPtr: 0x317430 t: 0
Aufruf von: 0x317100
Aufruf von: 0x317430
gameObjectPtr: 0x317100 t: 0
gameObjectPtr address: 0x317100 this address: 0x317430
Aufruf von: 0x317430
gameObjectPtr: 0x317100 t: 0
gameObjectPtr address: 0x317100 this address: 0x317430
Aufruf von: 0x317430
gameObjectPtr: 0x317100 t: 0
gameObjectPtr address: 0x317100 this address: 0x317430
Aufruf von: 0x317430
gameObjectPtr: 0x317100 t: 0
gameObjectPtr address: 0x317100 this address: 0x317430
Aufruf von: 0x317430
gameObjectPtr: 0x317100 t: 0
gameObjectPtr address: 0x317100 this address: 0x317430
Aufruf von: 0x317430
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
Aufruf von: 0x317430Warum ist gameObjectPtr: 0x317430 t: 0 und später gameObjectPtr: 0x317100 t: 0
Das bedeute ja, das sich während der Laufzeit die Zeiger der Instanzen in dem vector geändert haben.
for (auto& go : gameObjects)Ich kann mich jetzt aber auch schon wieder täuschen, weil wenn query schon von der falschen Instanz aufgerufen wurde.....
Ich Grübel gerade darüber nach weshalb nur bei einer Combo das Problem auf tritt.
Fakt ist, der Comodecoder erkennt eine korrekt eingegeben Combo, combo_update gibt diese an die state's weiter.
die kombo wird durch den Frame animator automatisch ausgeführt, insgesamt drei frames. PC und Playstation handeln bis hierhin noch gleich :
gameObjectPtr: 0x317430 t: 0
gameObjectPtr address: 0x317430 this address: 0x317100
Aufruf von: 0x317430
Aufruf von: 0x317100
gameObjectPtr: 0x317430 t: 0
Aufruf von: 0x317100
gameObjectPtr: 0x317430 t: 0Der vierte Rückgabewert gameObjectPtr: 0x317100 t: 0
Den gibt es beim PC nicht.Das hat irwas mit den Strukturen zu tun, die ich in Livingobjeckt benutze.
Ohne DEV Tool ist es fast unmöglich herauszufinden was die EE im Hintergrund treibt.
-
@D_Key sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Man müsste irwo was mit thread's machen bzw mit mutex. Ich weiß allerdings nicht wo/wie.
Wenn du noch keine Threads verwendest, wozu willst du dann Mutexen verwenden?
Und Threads zu verwenden wird die Sache nicht besser machen. Du musst erstmal den Fehler finden.Das wäre übel, weil es gibt keine alternative.
Welchen Compiler verwendest du denn? Ich habe gelesen dass der Compiler der Wahl GCC 3 ist.
-
Beim beobachten dieses Threads ist mir ein Fall aus der Vergangenheit eingefallen.
Es gab vor ca. 30 Jahren in unserer C++ Applikation einen ungewöhnliches Verhalten. Im Debuglauf haben wir dann nach langem Suchen herausgefunden, dass aus einer Funktion nicht an die Stelle des Funktionsaufrufs zurückgesprungen wurde, sondern irgend wo hin.
Nach dem einer unserer Entwickler mit sehr guten C Kenntnissen hinzugezogen wurde, hat dieser festgestellt, dass in den Tiefen eine C-Funktion mit einem falschen, zu großem Wert als Parameter aufgerufen wurde, welcher nunmehr den Stack kompromittiert hatte und somit eine Rücksprungadressen nicht mehr gültig war.
Hat also folgerichtig den Stack während des Debuglaufes beobachtet, wo ich zugeben muss, dass ich nicht mal wusste, wie das geht.
Dieser Fall trat meines Wissens nur in der 32 oder 64 Bit auf, was ich aber nicht mehr so genau weiß.
-
Guten Abend allerseits, ich habe das Problem gefunden.
Es war nun doch die virtuelle Funktion, bzw er aufruf derer.Ich hatte es ja schon mal selber angemerkt.
Das ist:float hit_impl(const Itr *itr, Charakter* that, const Volume *vol) override { return hit(itr, that, vol); }
ist andere als:
float hit_impl(const Itr *itr, const Volume *vol) override { return hit(itr, this, vol); }
Beim Aufruf von hit_impl in post_interaction wird hit_impl von dem Rückgabe Instanz aus query ausgeführt .
Mann muss den Zeiger mit an die Virtuelle Funktion überreichen , sonnt kommt es zu einer Überschneidung.
Ich hatte das zwar schon mal ausprobiert, aber anscheint nicht make clean im Vorfeld ausgeführt. Sonder nur make.@hustbaer sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Welchen Compiler verwendest du denn? Ich habe gelesen dass der Compiler der Wahl GCC 3 ist.
COLLECT_GCC=mips64r5900el-ps2-elf-g++
COLLECT_LTO_WRAPPER=/usr/local/ps2dev/ee/libexec/gcc/mips64r5900el-ps2-elf/14.1.0/lto-wrapper
Target: mips64r5900el-ps2-elf
Configured with: ../configure --quiet --prefix=/usr/local/ps2dev/ee --target=mips64r5900el-ps2-elf --enable-languages=c,c++ --with-float=hard --with-sysroot=/usr/local/ps2dev/ee/mips64r5900el-ps2-elf --with-native-system-header-dir=/include --with-newlib --disable-libssp --disable-multilib --disable-nls --disable-tls --enable-cxx-flags=-G0 --enable-threads=posix --silent
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.1.0 (GCC)https://github.com/ps2dev/ps2sdk
Ah, hier steht gcc 3.2.3 (iop) https://github.com/ps2dev/ps2toolchain
Der IOP ist der Playstation 1 Prozessor. Im PS2 Spiel Modus wird dieser zu Southbridge umkonfiguriert und handhabt alle Angesteckten Geräte usb, controller, usw.
Siehe Seite 14:
https://gamingdoc.org/wp-content/plugins/pdfjs-viewer-shortcode/pdfjs/web/viewer.php?file=https://gamingdoc.org/wp-content/uploads/2021/03/sony-ps2-scph-30000r_series_service_manual_gh-013_gh-014.pdf&attachment_id=&dButton=true&pButton=true&oButton=false&sButton=true@Helmut-Jakoby sagte in Code Ausführung ist durcheinader bei Superscalar CPU:
Funktion nicht an die Stelle des Funktionsaufrufs zurückgesprungen wurde, sondern irgend wo hin.
Sachen gibt's
Jetzt mache ich erst mal eine Pause. Dümmer geworden bin ich nicht bei der Suche nachdem Problem aber war schon Nervig.