Ursprünglich hatte ich nicht vor, eine Demo bei
Chaos Constrictions 2018 zu machen , aber 2-3 Wochen vor
cc wurde mir klar, dass man nicht mit leeren Händen zu einer Demo-Party gehen konnte, und
ich beschloss, eine kurze Demo für
386 / EGA / DOS zu schreiben.
Nachdem ich in
Turbo-C unter
DOS meine
lib AnotherGraphicsLibrary kompiliert hatte , die ideal in die Beat-Plan-Struktur des
EGA- Modus passte, war ich von den Bremsen, insbesondere den
EGA- Bremsen, enttäuscht. Die Demo in der Form, in der ich ihn für diesen sehr begrenzten Zeitraum sehen möchte, war unmöglich zu machen.
Ich konnte jedoch nicht aufgeben und nichts tun. Und dann fiel mir ein, dass ich schon lange an den
ZX-Spectrum- Demowettbewerben teilnehmen wollte. Und da ich im letzten Jahr zwei
48k Reals bekommen habe, könnte es mir Spaß machen, eine Demo zu erstellen. Übrigens - für mich ist das Wichtigste beim Schreiben einer Demo das Testen im realen Leben.
Emulgatoren machen dem Prozess keine solche Freude. Es ist wirklich ein wunderbares Gefühl, wenn Sie nach der nächsten Änderung des Codes die Demo in real hochladen und sehen, wie die reale Hardware die Bytes mischt Speicherzeichnungseffekt.
Da ich nur
48k Real habe, habe ich beschlossen, eine Demo für
48k zu machen. Und aufgrund der begrenzten Zeit und des Fehlens jeglicher Entwicklungen fiel die Wahl auf die Erstellung eines
1k-Intro (Demo von nur 1 Kilobyte oder 1024 Bytes).
Das letzte Mal habe ich den
z80 asm in
EmuZWin gestoßen - einem großartigen Emulator mit integriertem Assembler. Leider
funktioniert EmuZWin nicht unter
Windows XP oder ist fehlerhaft.
Nachdem ich verschiedene Optionen geprüft hatte, stoppte ich bei einer Reihe von
Unreal + sjAsm + Notepad ++ - Programmen, die meiner Meinung nach viel
einfacher als EmuZWin sind, aber im Gegensatz dazu lebendig sind.
Während ich dieses Intro schrieb, führte ich direkt in der Quelle ein Entwicklungsprotokoll durch, auf dessen Grundlage der folgende Text geschrieben wurde:
Hallo Welt!
Was soll ich zuerst schreiben, wenn ich fast keine Erfahrung mit dem
z80 asm habe ? Richtig, die Ausgabe eines 5x5-Sprites ist für einen der Effekte bekannt oder 40x40 Pixel (ironischerweise wurde dieser unvollendete Teil in Zukunft aus dem Intro geworfen, um in 1k zu passen).
Erstaunlicherweise war es ziemlich einfach, dies mit dem vorgenerierten Zeilenadressenetikett mit
Down HL von Grund auf neu zu tun.
Oh, Indexregister, wie bequem sie sind, aber langsamer sind, verbrauchen buchstäblich Balken. Ich musste ihren Gebrauch aus einer Reihe von Orten werfen.
Noch hier bin ich ganz am Anfang auf unglaubliche
sjAsm- Pannen
gestoßen , oder besser gesagt auf die neueste Version. Der Disrealismus in
Unreal zeigte eine absolut verrückte Folge von Befehlen. Ich habe die vorletzte Version heruntergeladen - es war schon irgendwie möglich damit zu leben.

Es ist klar, dass Sie nicht genügend zuvor gezeichnete Sprites in 1k einfügen können. Deshalb habe ich beschlossen, sie dynamisch zu generieren. Und sowieso nicht, sondern mit Polygonen zeichnen.
Daher war das zweite Verfahren, das ich geschrieben habe, das Verfahren zum Zeichnen eines Dreiecks. Zum größten Teil war es eine Portierung ihres eigenen Codes, der in
C geschrieben wurde
. Mit dem einzigen globalen Unterschied zur
C- Version werden die Polygon-Scanlinien zuerst generiert und erst dann auf diesen Scanlinien gezeichnet.
Nach Hochsprachen macht es Ihnen Spaß,
jr aka goto :
.sort_me_please: ld de,(tr_x2) ld bc,(tr_x0) ld a,d cp b jr nc,.skip1 ld (tr_x2),bc ld (tr_x0),de .skip1: ld de,(tr_x1) ld bc,(tr_x0) ld a,d cp b jr nc,.skip2 ld (tr_x0),de ld (tr_x1),bc jr .sort_me_please .skip2: ld de,(tr_x2) ld bc,(tr_x1) ld a,d cp b jr nc,.skip3 ld (tr_x2),bc ld (tr_x1),de jr .sort_me_please .skip3:
Ich war ein wenig schockiert über die Tatsache, dass es
sich zu einem angemessenen Zeitpunkt herausstellte, ein funktionierendes
draw_triangle auf
z80 asm zu schreiben, das ein Polygon Pixel für Pixel und ohne Löcher beim Verbinden von Polygonen zeichnet.
Hallo Dreiecke!Partikel

Aufgrund des Vorhandenseins eines Bildschirmlinien-Etikettengenerators habe ich mit diesem Etikett eine ziemlich gekrümmte und langsame Punktausgabeprozedur geschrieben. Die Prozedur hat zwei Eintrittspunkte - nur die Umkehrung des Pixels und die Umkehrung des Pixels, indem es mit
INK +
BRIGHT + und der in einem der Register angegebenen Farbe
gefüllt wird .
Als ich einen Effekt mit Partikeln erzeugte, stellte ich fest, dass das Beispiel mit den Strukturen aus den Beispielen im
Wiki sjAsm einfach nicht funktioniert. Beim Googeln wurde ein Thema von der Website
zx-pk.ru angesprochen , auf der dieses Problem beschrieben wird, und es gibt keine Lösung - ha, gut - eine weitere Panne.
Ich beschloss, alles klar zu machen - die Koordinaten unabhängig vom Rendern durch Unterbrechung zu aktualisieren. Ja ... plus Bytes zum Generieren einer Interrupt-Tabelle.
Zu diesem Zeitpunkt gab es nur wenige Partikel, und sie passen kaum in den Rahmen - dies ist übrigens die Langsamkeit meines Verfahrens zur Ausgabe des% -Punkts.)) Die Verwendung einer gemeinsamen Tabelle mit Sprites ließ mich jedoch nicht herauswerfen und fertig machen, weil Dies sparte viel Platz, da nur ein Tabellengenerator benötigt wurde. Und meine Liebe zu Fahrrädern auch :)
Zu wenige Partikel ... haben ihre Anzahl erhöht, aber jetzt wurde das Rendering auf zwei Frames gemästet.
Testen auf Peters WS64 , den ich auf dem letzten cc bekommen und diesen Winter repariert habe :)Übrigens haben sich die Punkte bereits zu diesem Zeitpunkt in fette horizontale Punkte
2: 1 verwandelt, wie beim
Commodore 64 . Dies geschah aufgrund der anfänglich geringen Anzahl von Partikeln und meiner Unzufriedenheit mit der Tatsache, dass sie im realen Leben ziemlich unsichtbar waren. Das Problem wurde durch Ersetzen der Platte behoben
db 128,64,32,16,8,4,2,1;
auf
db 192,192,96,24,12,6,3,3;
Dies verschlechterte die Genauigkeit der Positionierung und machte den Flug ein wenig ruckartig, erhöhte aber die Sicht. Hier spielte es auch in die Hand, dass die Partikel von oben nach unten fielen - ihre Sicht war vertikal verschmiert.
Teilchen fallen übrigens jeweils mit ihrer eigenen zufälligen Geschwindigkeit, und zwei Bytes werden zum Speichern von
Y- Koordinaten verwendet.
Sprites
Ich warf das unvollendete Teil des Sprite-Teils weg und stellte fest, dass ich nicht in
1k damit passen konnte.
Außerdem gab es bereits Platzmangel, so dass ich mich an
Introspeks wunderbaren
Artikel über Packer erinnerte. Ich entschied mich für
zx7 als Packer, der etwa 110 Bytes sparte. Übrigens, vielleicht kennt jemand einen besser geeigneten Packer für ein 1k-Intro?
Chaoskonstruktionen

Da ich bereits ein Verfahren zum Ausgeben eines Polygons hatte, schien es mir eine coole Idee zu sein, das
CC- Logo in Polygone aufzuteilen und diese einzeln anzuzeigen.
Ich habe einen Testcode geschrieben, der mehrere Polygone anzeigt - alles hat wie beabsichtigt funktioniert - in Ordnung.
Um zu überprüfen, ob meine Idee in
1k passt oder nicht, wurde nach Schätzungen eine bestimmte Anzahl zufälliger Polygone generiert, eine ausreichende Anzahl für das Logo, und zur Quelle gefahren. Kompiliert und sichergestellt, dass - ausgezeichnet - Intro in dieser Form in die Grenze von 1024 Bytes passt.
Lebensfoto, erkennen Sie das Gerät auf dem Tisch? :)))Ich beschloss, das halbfertige Intro noch einmal zu testen, bereits mit Polygonen und einem Packer, der auf real hochgeladen wurde und ... zurückgesetzt wurde. Zuerst begann ich zu sündigen, dass ich vergessen hatte, den Speicher irgendwo zu initialisieren, von wo aus, wo auf dem
0x00- Emulator alles gut funktioniert, im wirklichen Leben Müll einen Reset verursacht.
Nichts ist besser, um einen Problemort zu finden, als die Halbteilungsmethode und der
Halt, den ich mir nicht einfallen lassen konnte.
Bei einem zweistündigen Reset auf Real gab es keine Möglichkeit, den Fehler zu lokalisieren ...
Wie sich herausstellte, war es nicht in meinem Code enthalten, sondern in dem mitgelieferten Sound
Enhancer auf dem Telefon, von dem ich WAVs geladen habe. Ein Verbesserer aus einem Bitstrom in einer
WAV- Datei erzeugte einen Deliriumstrom.
Sobald ich es ausschaltete, funktionierte alles magisch.
Er skizzierte das Logo im
fehlerhaften Greenpixel- Grafikeditor,
zerlegte es in eine Reihe von Dreiecken und fuhr die Koordinaten manuell zur Quelle. Nachdem ich das
Chaos Constructions- Logo vollständig ausgefüllt und im wirklichen Leben ausgeführt hatte - ich war froh -, sah es ziemlich gut aus.
Das erste Logo wird auf echt angezeigtAllerdings habe ich zufällige Polygone zu wenig gestopft, und auf dem echten Logo gab es ein Limit von 1
KB pro 150 Byte. Und dies trotz der Tatsache, dass der Partikeleffekt immer noch nicht abgeschlossen war und der Übergang zwischen den Teilen scharf war.
An diesem Tag ins Bett zu gehen, stellte sich wegen der Aufregung mit Pannen bereits um 8 Uhr morgens heraus. 8)
Und ja, ich habe versucht, die Größe zu optimieren, indem ich die Koordinaten und Scheitelpunktindizes getrennt gespeichert habe, aber der Packer mochte es nicht sehr, was die Größe nur vergrößerte.
Finale

Ich habe mir überlegt, wie man die Ausgabe des Logos diversifizieren kann. Dafür waren fast zwei weitere Pixel-Labels erforderlich:
fake_points1: db 1,2,4,8,16,32,64,128; 1 ch fake_points2: db 32,8,128,2,16,1,64,4; 2 ch normal_points: db 128,64,32,16,8,4,2,1; 3 ch
Dies führte zu einem coolen Effekt der Vergrößerung der Details beim Rendern des Logos oder dem anfänglichen Mangel an Details und einer allmählichen Erhöhung der Schärfe.
Und schließlich habe ich die endgültige Version mit allen Übergängen erstellt und eine Menge von allem weggeworfen. Dabei habe ich einen Fehler in der Prozedur zum Zeichnen eines Dreiecks gefunden. Wenn die beiden Scheitelpunkte die gleichen
Y- Koordinaten haben, wird das Dreieck schief gezeichnet (es sieht so aus, als würde man bei der Berechnung von
dx durch 0 dividieren) und mit einem temporären Hack umgangen.
Testen der endgültigen Version auf Leningrad 48Größenoptimierung
Zweistellige Zahlen sind „zusätzliche Bytes“.94 zusätzliche Bytes ...
Es ist an der Zeit, die „kulturelle“ Bewahrung / Wiederherstellung von Registern von Eingabe- / Ausgabeverfahren zu unterbinden, weit entfernt von allem, was notwendig ist, aber die Erinnerung frisst.
86 Bytes ...
Im wirklichen Leben getestet - es funktioniert! Er hat etwas mehr Speicherplatz verloren und gleichzeitig einen Fehler behoben, der durch 0 - 63 Bytes geteilt wird!
57 Bytes ...
Looping hinzugefügt.
random_store: start:
Das Schleifen erfolgt übrigens auf der Auspackebene, wie Als Entropiequelle für das
RNG wurden mehrere Bytes aus dem Initialisierungscode verwendet (um Platz zu sparen), die das
RNG im ersten Teil verdarb. Daher gibt es zum Schleifen nach dem Ende des Intro
ret ,
na ja , und dann noch ein Entpacken und Übergang zum entpackten Code ...
Es war nicht möglich, die letzten 48 Bytes loszuwerden, ich musste den Interrupt-Handler ausschalten, aber Hurra! Gefüllt! Es blieb sogar 1 zusätzliches Byte übrig.
Und da es keine Unterbrechungen gibt, kann es für Frames bewertet werden, und es ist schwierig, den Strahlquerschnitt im ersten Effekt bei einem Pixel zu sehen. Daher habe ich die Anzahl der Partikel pro Auge erhöht, wobei ein Kompromiss zwischen Geschwindigkeit und Unterhaltung besteht.
Noch härter gestochen, dumm Code und Daten von einem Ort zum anderen verschoben, um dem Packer zu helfen. Was einige Zeit gedauert hat :)
Dies gab ungefähr
10 Bytes frei, in die ich eine Parodie des Klangs steckte. Khk, khe, Ton - dies ist an einigen Stellen durch Ohr eingeführt:
ifdef UseSound ld a,d and
Ich habe den Sound nicht "genagelt", sondern eine Definition vorgenommen und so zwei Versionen des Intro mit und ohne Sound erhalten. In dem ohne Ton, in "zusätzlichen" Bytes vollgestopft
db 'e','r','r','o','r'
Ich habe
trd und
tap gesammelt und alles auf die
cc- Website hochgeladen.
Hurra - ich nehme an Demopati teil!
Nachwort
Es stellte sich als lustig mit dem Geräusch heraus, jemand auf dem Patlace sagte "klares Geräusch", jemand sah mich seltsam an und auf
Pouet fand ich Folgendes:

Und das:

Im Allgemeinen habe ich nicht verstanden, ob jemand den 10-Byte-Sound mochte oder nicht :)
Und das letzte - es ist eine Schande, dass der 1-
km- Wettbewerb dieses Jahr nicht stattgefunden hat. Die Arbeit erwies sich meiner Meinung nach als anständig, aber
es ist schwierig, mit
640 km zu konkurrieren, aber ich wollte unbedingt antreten.
Schreibe Demos, schreibe 1k!Und hier ist, was endete (ps, pass auf deine Ohren auf):
Stille Version: