Πώς ένας δακτύλιος στοχεύει τον παίκτη
Η επίθεση της Elly ζητά έναν στοχευμένο δακτύλιο με αρχικό πλήθος 16. Μια βοηθητική συνάρτηση υπολογίζει την κατεύθυνση κάθε βολίδας. Ο ίδιος δακτύλιος μπορεί να έχει σταθερή κατεύθυνση ή να στρέφεται προς τον παίκτη.
Χρησιμοποιήστε το REA για να βρείτε πώς το TH04 δημιουργεί έναν δακτύλιο βολίδων και τον στοχεύει στον παίκτη. Εξηγήστε τον υπολογισμό και δείξτε τον κώδικα.
Παράδειγμα προτροπής, με το αρχικό εκτελέσιμο και το τοπικό αντίγραφο της ανακατασκευής διαθέσιμα τοπικά.
Το TH04 αποθηκεύει μια πλήρη δεξιόστροφη περιστροφή σε 256 μονάδες γωνίας. Για 16 βολίδες, κάθε δείκτης προσθέτει 16 μονάδες: 0, 16, 32, …, 240. Η πρόσθεση της κατεύθυνσης του παίκτη περιστρέφει αυτές τις θέσεις μαζί.
Το πρότυπο βολής στον ανακτημένο πηγαίο κώδικα
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
Αυτές οι γραμμές επιλέγουν τον σχηματισμό πριν από τη ρύθμιση της δυσκολίας και της απόδοσης. Διαβάστε τον πηγαίο κώδικα της επίθεσης.
Τι επιστρέφει το REA
Εξετάζουμε την bullet_velocity_and_angle_set(), τη συνάρτηση που ορίζει το διάνυσμα ταχύτητας και τη γωνία κάθε βολίδας. Το REA επιστρέφει τις εντολές, τον ψευδοκώδικα και τις αναφορές της. Τρία μέρη αυτού του αποτελέσματος εξηγούν τον σχηματισμό.
-
Ελέγξτε την εικόνα DOS πριν διαβάσετε τον κώδικά της
Βοηθός → REAopen_binary {"path": "MAIN.EXE"} inspect_native_load_image {}REA → βοηθός · επιλεγμένα πεδίαstatus: "verified" format: "dos-mz" load_segment: 4096 header_bytes: 6144 module_bytes: 150114Ο έλεγχος συνδέει τον φορτωμένο κώδικα και τις εγγραφές μετεγκατάστασης με το παρεχόμενο εκτελέσιμο. Η παραπάνω διαδρομή συντομεύεται για την εμφάνιση.
-
Διαβάστε τον πολλαπλασιασμό και τη διαίρεση του δακτυλίου
Βοηθός → REA ·analyze_function{"procedure": "0x2cfc8"}REA → βοηθός · απόσπασμα εντολών0x2d0eb: MOV AX, SI 0x2d0ed: SHL AX, 0x8 0x2d0f0: MOV DL, byte ptr [0x53af] 0x2d0f9: IDIV BXΟ
SIκρατά τον δείκτη της βολίδας. Η ολίσθηση τον πολλαπλασιάζει επί 256 και έπειτα η διαίρεση χρησιμοποιεί το πλήθος που διαβάζεται από τοDS:53AF. Ο συντηρούμενος πηγαίος κώδικας ονομάζει αυτό το πεδίοbullet_template.count. Η πλήρης ακολουθία εμφανίζεται παρακάτω. -
Βρείτε πού ο σχηματισμός στρέφεται προς τον παίκτη
Ίδιο αποτέλεσμα συνάρτησης · απόσπασμα στόχευσης0x2d190: SUB AX, word ptr [0x53a6] 0x2d198: SUB AX, word ptr [0x53a4] 0x2d19d: CALLF 0x1000:1da8 0x2d1a2: ADD word ptr [BP + -0x2], AXΑντίστοιχος συντηρούμενος κώδικας C++group_angle_offset += iatan2( player_pos.cur.y - bullet_template.origin.y, player_pos.cur.x - bullet_template.origin.x );Οι τελεστέοι των εντολών αποκαλύπτουν δύο διαφορές συντεταγμένων και μια βοηθητική συνάρτηση κατεύθυνσης. Η επιστρεφόμενη τιμή της προστίθεται στη σχετική γωνία του δακτυλίου. Τα ονόματα του πηγαίου κώδικα κάνουν αυτές τις διευθύνσεις ευανάγνωστες· το REA επιτρέπει στον βοηθό να ελέγξει τις αρχικές πράξεις πίσω από αυτές.
Από assembly σε ευανάγνωστο κώδικα C++
Επιλέξτε ένα βήμα για να αντιστοιχίσετε τις αρχικές εντολές με τον υπολογισμό γωνίας. Αυτή η σύνοψη ακολουθεί τη διαδρομή του στοχευμένου δακτυλίου· ο πλήρης πηγαίος κώδικας χειρίζεται επίσης βεντάλιες βολίδων, στοίβες και τυχαίους σχηματισμούς.
0x2cfcf: MOV SI, word ptr [BP + 0x4]
0x2d0eb: MOV AX, SI
0x2d0ed: SHL AX, 0x8
0x2d0f0: MOV DL, byte ptr [0x53af]
0x2d0f4: MOV DH, 0x0
0x2d0f6: PUSH DX
0x2d0f7: CWD
0x2d0f8: POP BX
0x2d0f9: IDIV BX
0x2d0fb: MOV word ptr [BP + -0x2], AX
0x2d18d: MOV AX, [0x4650]
0x2d190: SUB AX, word ptr [0x53a6]
0x2d194: PUSH AX
0x2d195: MOV AX, [0x464e]
0x2d198: SUB AX, word ptr [0x53a4]
0x2d19c: PUSH AX
0x2d19d: CALLF 0x1000:1da8
0x2d1a2: ADD word ptr [BP + -0x2], AX
0x2d1b9: MOV AL, byte ptr [BP + -0x2]
0x2d1bc: ADD AL, byte ptr [0x53ad]
0x2d1c0: MOV [0xbcc8], AL
unsigned char aimed_ring_angle(
int index, int count,
int player_direction,
unsigned char rotation)
{
int angle = index;
angle = (angle * 256) / count;
angle += player_direction;
angle += rotation;
return (unsigned char)angle;
}
01 · Διαβάστε τον δείκτη της βολίδας. Το όρισμα της στοίβας φορτώνεται στον SI. Σε δακτύλιο 16 βολίδων, αυτός ο δείκτης μέλους κυμαίνεται από 0 έως 15.
02 · Κατανείμετε τις κατευθύνσεις σε μια πλήρη περιστροφή. Η SHL AX,8 πολλαπλασιάζει επί 256. Το πλήθος επεκτείνεται με μηδενικά σε μια λέξη και έπειτα η IDIV διαιρεί το γινόμενο με αυτό το πλήθος. Για πλήθος 16, κάθε δείκτης προχωρά κατά 16 μονάδες γωνίας.
03 · Προσθέστε την κατεύθυνση του παίκτη. Οι δύο αφαιρέσεις σχηματίζουν συντεταγμένες παίκτη μείον αρχής. Η βοηθητική συνάρτηση κατεύθυνσης επιστρέφει μια γωνία στον AX· η πρόσθεσή της στρέφει ολόκληρο τον δακτύλιο προς τον παίκτη.
04 · Προσθέστε την περιστροφή του σχηματισμού. Η ADD AL,[0x53ad] προσθέτει τη γωνία του προτύπου. Το αρχικό πρότυπο της Elly την ορίζει σε μηδέν· άλλοι σχηματισμοί μπορούν να χρησιμοποιούν την ίδια βοηθητική συνάρτηση με περιστροφή.
05 · Κρατήστε την τελική γωνία σε ένα byte. Η αποθήκευση γράφει τον AL στο πεδίο γωνίας δημιουργίας. Οι τιμές επανέρχονται στο μηδέν μετά το 255, όπως και η μετατροπή σε μη προσημασμένο byte. Ο περιβάλλων πηγαίος κώδικας μετατρέπει επίσης αυτή τη γωνία και το μέτρο ταχύτητας σε διάνυσμα ταχύτητας.
Ο κώδικας assembly επιλέγει τον κλάδο στοχευμένου δακτυλίου, τον υπολογισμό στόχευσης και την τελική αποθήκευση. Ο παραπάνω κώδικας C++ είναι μια ευανάγνωστη σύνοψη. Οι παρακάτω έλεγχοι μεταγλώττισης αφορούν τον συντηρούμενο πηγαίο κώδικα στο συνδεδεμένο έργο.
Διαβάστε τον συντηρούμενο πηγαίο κώδικα δακτυλίου και στόχευσης
angle_offset = (i * BULLET_ANGLE_FULL_TURN) / count;
if (i >= (count - 1)) {
group_complete = true;
}
goto aim_or_no_aim;
aim:
group_angle_offset += iatan2(
(player_pos.cur.y - bullet_template.origin.y),
(player_pos.cur.x - bullet_template.origin.x)
);
no_aim:
vector2_near(
bullet_template.velocity,
(group_angle_offset + bullet_template.angle),
speed
);
bullet_spawn_angle = (group_angle_offset + bullet_template.angle);
Μακροεντολή δακτυλίου · Πηγαίος κώδικας στόχευσης και διανύσματος ταχύτητας · Αναπαράσταση γωνίας
Έλεγχος του συντηρούμενου πηγαίου κώδικα
Οι καταγεγραμμένοι έλεγχοι του έργου TH04 μεταγλωττίζουν τον κώδικα δημιουργίας βολίδων, μαζί με αυτή τη βοηθητική συνάρτηση, με τη συγκεκριμένη αλυσίδα εργαλείων Turbo C++ 4.0J.
2,139 ίδια byte
Ο μεταγλωττισμένος κώδικας δημιουργίας βολίδων συμφωνεί με ένα τμήμα 2,139 byte του αρχικού εκτελέσιμου.
Δύο καθαρές μεταγλωττίσεις
Δύο ξεχωριστές μεταγλωττίσεις παράγουν τα ίδια byte που συμφωνούν με το πρωτότυπο. Οι καταγεγραμμένοι κατακερματισμοί εισόδου συμφωνούν με τον συντηρούμενο πηγαίο κώδικα που εμφανίζεται εδώ.
Καταγράφηκε στις 3 Οκτωβρίου 2026. Διαβάστε τους ελέγχους μεταγλώττισης.
Ταυτότητα στόχου και πεδίο ανάλυσης
| Αρχικός στόχος | MAIN.EXE, 156,258 byte, DOS MZ |
|---|---|
| Σημείο εισόδου βοηθητικής συνάρτησης | 0x2cfc8 στη φορτωμένη εικόνα του REA |
| Μετατόπιση στο αρχικό αρχείο |
0x1e7c8, επιστρέφεται από την address_to_file_offset
|
| Καταγεγραμμένη εξέταση κώδικα | REA 4.1.0 · 7 Οκτωβρίου 2026 |
Οι έλεγχοι μεταγλώττισης καλύπτουν ολόκληρο το τμήμα κώδικα προσθήκης βολίδων, μαζί με αυτή τη βοηθητική συνάρτηση. Συγκρίνουν επίσης τη συνεισφορά του στο MAP και την επικαλυπτόμενη μετεγκατάσταση.
Το REA επαλήθευσε τη στατική εικόνα φόρτωσης DOS στο τμήμα φόρτωσης 0x1000. Οι διευθύνσεις του περιγράφουν αυτή την εικόνα ανάλυσης. Το αποτέλεσμα συνάρτησης αναφέρει 503 byte σώματος σε δύο περιοχές μέσα σε έκταση 517 byte· οι παραπάνω επιλεγμένες εντολές βρίσκονται μέσα σε αυτές τις αναφερόμενες περιοχές.
Τα ονόματα του πηγαίου κώδικα και οι έλεγχοι μεταγλώττισης προέρχονται από το ορόσημο TH04 0d72e980. Προηγούμενες παρατηρήσεις ανακατασκευής χρησιμοποίησαν τα script ανάλυσης του ίδιου του έργου· αυτή η σελίδα προσθέτει μια νέα εξέταση REA του ίδιου αρχικού στόχου. Η ταυτότητα του παρεχόμενου παιχνιδιού καθορίζεται από το δηλωτικό του αποθετηρίου του, ενώ η ανεξάρτητη τεκμηρίωση προέλευσης ενός ανέπαφου αντιγράφου παραμένει ανοικτή.
Το σχήμα απεικονίζει τον υπολογισμό γωνίας. Ο χειρισμός του πλήρους παιχνιδιού, ο χρονισμός και η συμπεριφορά του υλικού PC-98 έχουν ξεχωριστούς ελέγχους κατά την εκτέλεση στο έργο ανακατασκευής.
Η πλήρης ανακατασκευή του TH04
Το έργο μεταγλωττίζει τα τέσσερα προϊόντα DOS του παιχνιδιού από συντηρούμενο κώδικα C++ και assembly. Πέρα από τη δημιουργία βολίδων, ο πηγαίος κώδικας καλύπτει στάδια, αρχηγούς, απόδοση γραφικών, είσοδο, μενού, φινάλε και χειρισμό βαθμολογίας.
Εξερευνήστε το αποθετήριο TH04
- Πηγαίος κώδικας δημιουργίας βολίδωνΗ πλήρης βοηθητική συνάρτηση, άλλοι τύποι σχηματισμών και ρύθμιση προτύπων.
- Οδηγός μεταγλώττισης και εκτέλεσης DOSΜεταγλωττίστε τον πηγαίο κώδικα και δοκιμάστε τον στη ροή εξομοιωτή PC-98 του έργου.
- Τρέχουσα κατάσταση του έργουΕπαλήθευση DOS και η ξεχωριστή μεταφορά σε εγγενή κώδικα x64.