Allgemeine Hex- und ASM-Fragen

geschrieben am 23.10.2016 15:02:41
( Link )
Zitat von RPG Hacker:
Du solltest ganz leicht rausfinden können, welche zwei Patches sich da beißen. Macht erstmal nur den Gravity-Patch auf eine cleane ROM, haue danach nacheinaner alle anderen Patches drauf und starte die ROM jedes mal kurz. Sobald der Bug auftritt, weißt du, welcher Patch das Problem verursacht.


Also jetzt bin ich mit meienem Latein dann auch so langsam am Ende. Habe das bei einer frischen Rom gemacht und bekomme entweder nen black screen (könnte am free space liegen, aber mitlerweile reichts mir dann langsam ) oder es passiert das Gravity in jedem Level aktiviert ist.

Alle Patches funktionieren soweit in Kombination; aber bei deinem + Gravity randaliert die Rom.
Wenn ich den Hppatch zuerst reinhaue ist bei mir Gravity in jedem Level aktiviert egal was passiert. Wenn ich erst den anderen Patch installiere und dann deinen, bekomme ich nen Blackscreen. ( Vielleicht wegen Freespace? Kann ich mir aber nicht vorstellen sonst würde es ja auch nicht bei Halls of Asgard funktionieren. Testrom ist auch auf 4 Mb erweitert also von daher müsste es eigentlich klappen + beide Patches haben unterschiedliche Freespace Adressen soweit ich weiß.)

Ich denke nach wie vor das es mit dem Rückstoß zusammenhängt bei Halls of Asgard, warum jetzt bei der Testrom Gravity immer aktiv ist in kombi mit deinem Patch; weiß ich ehrlich gesagt nicht. xD ( selbst wenn man jetzt nicht zurückgestoßen wird oder einen Pilz aufsammelt )
>we live in a society
geschrieben am 23.10.2016 15:12:28
( Link )
Das ist sehr gut möglich und auch plausibel. Einen leichten Fix wird es dafür dann aber nicht geben, da es ja nicht einfach nur eine gemeinsame Adresse ist, die gehijackt wird. Man muss dann beide Patches sehr gut kennen um nachvollziehen zu können, wodurch genau das Problem verursacht wird, damit man es fixen kann. Ein Rezept gibt es dafür leider nicht, eine andere Lösung fällt mir nicht ein.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 04.11.2016 21:10:28
( Link )
Ich bin schon wieder auf ein Problem gestoßen was mich an den Rand des Wahnsinns treibt.
Das Problem liegt an meinen Shatterblöcken, die brechen wenn Mario mit einem gewissen Speed dagegen rennt.
Der Punkt ist: Wenn Mario groß ist, hat Smw die Eigenschaft den unteren Block zu favorisieren, wie als würde Mario immer noch klein sein

Es gab jemanden der mal das gleiche Problem hatte wie ich: https://www.smwcentral.net/?p=viewthread&t=51417
Trotz zahlreicher Lösungsansätze konnte das Kernproblem nicht behoben werden.

Das Komische ist, das dieses Problem volkommen zufällig auftritt. Manchmal gehen beide Blöcke kaputt und manchmal nicht.
Die Blöcke Verhalten sich ja wie $130 und werden dann mit $02 ersetzt. Ich hab mir halt gedacht: gut wenn man halt durch den ersten Block ausgebremst wird (warum auch immer), dann ersetze ich halt das ganze mit etwas nicht soliden und schaue testweise was geschieht; was passiert? Genau! Es geht wieder nur der untere Block kaputt, obwohl der Player mit vollem Speed durchbrettert.

Auch ob der Player ausgebremst wird oder nicht, ist bei einzelnen Blöcken komplett zufällig. Den Speedcap runter zu setzten bringt leider auch nichts. (ist momentan auf $25 )

Impact Blockcode:
Code

!BREAKSPEED = $25 ; Geschwindigkeit mit der das ganze bricht
db $42
JMP Return : JMP MarioSide : JMP MarioCorner : JMP Return : JMP Return : JMP Return : JMP Return : JMP Return

MarioSide:
LDA $7B
BPL NoUnsign ;Ja Nein?
EOR #$FF ;2 complement
INC A

MarioCorner:
LDA $7B
BPL NoUnsign ;Ja Nein?
EOR #$FF ;2 complement
INC A


NoUnsign:
CMP #!BREAKSPEED ;brechtest
BCC Return ;return if speed not reached

PHB ;preserve current bank
LDA #$02 ;push 02
PHA
PLB ;bank = 02
LDA #$00 ;normales brechen
JSL $028663 ;blockbrechen
PLB ;restore bank

LDA #$02 ;block zum generieren
STA $9C
JSL $00BEB0 ;generiere

Return:
RTL


Die Turnblocks brechen ja auch wenn ein Chuck z.B dagegen rennt. Also müsste es auch mit Mario's Sprite gehen in der Theorie.
Der einzige Unterschied ist ja das Mario entweder 16x32 ist oder 16x16.
Vielleicht kann man das ganze ja beheben, wenn man noch eine Überprüfungsroutine reinschreibt in den Impactblock mit $00EB79 ($00EB79=interaction field), ob der Player wirklich groß ist oder nicht. Denke aber nicht das dies hier die Lösung ist.

Pls halp!
>we live in a society
geschrieben am 05.11.2016 13:31:49
( Link )
Ein paar Gedanken dazu.

1) Vielleicht solltest du sicherheitshalber auch noch MarioBelow und MarioAbove hinzufügen? Vielleicht wird bei einem der Blöcke ja im entscheidenden Moment manchmal nur eine Kollision von unten erkannt oder sowas. Es wäre auf jeden Fall die sicherere Variante, alle Kollisionen abzudecken, denke ich.

2) Mir ist aufgefallen, dass am Ende von MarioSide überhaupt kein Branch-Befehl steht oder sowas. Das heißt wenn MarioSide zutrifft, wird auch MarioCorner immer ausgeführt. Das dürfte in diesem Fall das Ergebnis nicht beeinflussen, da beide Code-Blöcke als allererstes $7B laden, aber sobald du den Code mal änderst, könnte das natürlich durchaus zu Problemen führen, und so oder so ist es auf jeden Fall verschwendete Performance, den gleichen Code zweimal auszuführen, wenn die erste Ausführung überhaupt keinen Effekt hat. Du solltest deswegen ans Ende von MarioSide noch ein "BRA NoUnsign" packen.

3) Die einzige Möglichkeit, das Problem wirklich zuverlässig zu lösen, scheint mir ein Timer zu sein. Das wird vermutlich einen Patch oder ein Generator Sprite erfordern, ich glaube der Code von Blöcken wird nicht jedes Frame ausgeführt. Was ich machen würde ist folgendes:
  • Mache einen Patch, der jeden Frame Marios Geschwindigkeit abfragt, ähnlich wie hier im Block-Code.

  • Wenn Marios Geschwindigkeit einen bestimmten Schwellenwert überschreitet (in diesem Fall $25), dann initialisere eine Timer-Variable mit einem von dir definierten Toleranz-Wert, zum Beispiel 5 (das ganze versteht sich als eine Anzahl von Frames).

  • Wenn Marios Geschwindigkeit den Schwellenwert im aktuellen Frame NICHT überschreitet, dann lass diese Timer-Variable um 1 runterzählen (außer, sie ist bereits 0).

  • Nun zum Block-Code selbst. In dem fragst du Marios Geschwindigkeit jetzt schlichtweg gar nicht mehr ab. Stattdessen fragst du nur noch diese Timer-Variable ab. Ist ihr Wert größer 0, dann zerbricht der Block. Ist der Wert nicht größer 0, zerbricht der Block nicht.

Das Ergebnis des ganzen: Selbst wenn du durch den einen Block im vorherigen Frame bereits ausgebremst wurdest, würde der andere Block, solange du ihn noch berührst, trotzdem zerbrechen, weil die Timer-Variable noch nicht 0 wäre. Klar, das ganze würde dafür sorgen, dass in ein paar Rand-Fällen Blöcke auch zerbrechen würden, wenn man bereits langsamer laufen würde. Das dürfte aber kaum auffallen, weil das Zeitfenster dafür so kurz ist (eben nur ein paar Frames), und außerdem dürfte das das Spielgefühl eher sogar verbessern, nehme ich an.

Bemerkung: Diese Lösung basiert auf der Annahme, dass die Kollision mit Blöcken immer vom Spiel abgefragt wird, und nicht nur dann, wenn man auch eine Geschwindigkeit != 0 im aktuellen Frame hat. Ich weiß ehrlich gesagt nicht, wie das Spiel Kollisionen abfragt, deswegen kann ich nicht zu 100% garantieren, dass diese Lösung auch funktioniert. Falls das Spiel aber MarioSide usw. auch ausführt, wenn man sich gerade nicht bewegt, sollte meine Lösung so funktionieren.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 06.11.2016 14:14:24
( Link )
@RpgHacker

Alles klar! Danke für die Hilfe wie immer! Ich probiere das mal die nächsten Tage aus und schau ob das klappt!
>we live in a society
geschrieben am 01.01.2018 20:12:37
( Link )
Hey,
ich habe mir einen Custom Block runtergeladen -> SMB3 P-Switch, meine Frage (Ich kenne mich mit ASM nicht aus) kann man den Block so umschreiben, dass wenn der P-Switch-Timer ausläuft der Custom block wieder respawnt? Also der P-Switch wieder betätigt werden kann?
Hier ist mal der Code:
Code
;SMB3 P-Switch
;by Mirumo

db $42
JMP MarioBelow : JMP MarioAbove : JMP MarioSide : JMP SpriteV : JMP SpriteH : JMP MarioCape : JMP MarioFireBall
JMP MarioAbove : JMP Return : JMP Return

!FLAT_TILE = $0303 ;Flat P-Switch Map16
!PSwitchTime = $FF
!Colour = $14AD ; Blue = $14AD, silver = $14AE

if !Colour == $14AD
print "A SMB3 P-Switch block."
else
print "A SMB3 silver P-Switch block."
endif

MarioAbove:
LDA #$20
STA $1887
LDA #$0E
STA $1DFB
LDA #$0B
STA $1DF9
LDA #!PSwitchTime ; \ Timer
STA !Colour ; /

REP #$10
LDX.w #!FLAT_TILE
%change_map16()
SEP #$10
Return:
MarioBelow:
MarioSide:
SpriteV:
SpriteH:
MarioCape:
MarioFireBall:
RTL
Bin dabei meinen ersten Hack zu erstellen!
"Otto's Adventure"

Fortschritt:
Welt 1: Komplett
Welt 2: Erstes Level angefangen °-°
Overworld:
Welt 1: Komplett
Welt 2: Komplett
Welt 3: Komplett
Welt 4: 95%
geschrieben am 02.01.2018 22:48:18
( Link )
Eher weniger - Blöcke tun nur was, wenn man sie berührt. Dass sie von selbst merken, wenn der Timer abläuft, geht nicht.

Vielleicht gibt's auf SMWC einen Sprite in der Richtung.