Wie eine Memories-Demo in 256 Bytes passt


Einführung


Hallo! Mein Name ist HellMood und in diesem Artikel geht es um ein kleines MS DOS-Programm namens Memories. Dieses Programm hat eine Größe von 256 Bytes, gewann er in der Kategorie «PC 256 Byte» Wettbewerb Demoszene «Revision» im Jahr 2020 und auch den Publikumspreis erhielt. Sie können das Video der Programmausgabe hier und das Video mit der Reaktion des Online-Publikums und der Moderatoren hier ansehen . Laden Sie die Version herunter und hinterlassen Sie hier Kommentare. Dieser Artikel enthält eine eingehende Analyse des Programms sowie Informationen zu historischen Referenzen und Entwicklungsstadien. Der Artikel ist im Sizecoding-Wiki veröffentlicht. Sie können damit nicht nur die interne Struktur von Erinnerungen verstehen, sondern auch etwas Ähnliches erstellen. Entdecken Sie es! Wenn Sie mit der Größencodierung (Schreiben von Programmen in der gewünschten Größe) oder mit x86-Assembler noch nicht vertraut sind, wird empfohlen, mit den Grundlagen dieses Wikis zu beginnen . Die Prinzipien sind leicht zu verstehen, aber es ist nicht so einfach, Implementierungsdetails herauszufinden.

Kurze Review


In diesem Artikel werden wir über die Version sprechen, die an den Wettbewerb für DosBox gesendet wurde (256 Bytes). Das Archiv enthält auch Versionen für FreeDos und Windows XP DOS, die zum Zeitpunkt des Schreibens des Beitrags nicht auf allen Computern funktionierten. Diese alternativen Versionen wurden als Proof of Concept in das Archiv aufgenommen, um zu zeigen, dass das Programm nicht nur im Emulator funktioniert. In der Kategorie „PC 256 Bytes“ des Wettbewerbs „Revision“ von 2020 konnten „FreeDos“ oder „DosBox“ als Plattform angegeben werden (letztere in einer bestimmten Konfiguration). Wie alternative Versionen beweisen, können Sie die Version für DosBox so ändern, dass sie unter FreeDos, MS DOS, WinXP und Win98 funktioniert, aber der Artikel wird sich nicht damit befassen.

Wie auch immer, zuverlässige Versionen für alle Plattformen und Computer werden derzeit entwickelt. In Bezug auf mögliche weitere Optimierungen werde ich nur auf die an den Wettbewerb gesendete Version eingehen, obwohl ich bereits mehrere Stellen gefunden habe, an denen der Code optimiert werden kann. Da dies eine Demonstration der Geschichte kleiner Effekte ist, ist fast keiner der Codes perfekt und kann weiter reduziert werden. Um in verschiedenen Versionen nicht verwirrt zu werden, werde ich nur über die Konkurrenz sprechen.

Geschichte kleiner Effekte



Dimensionskategorien unter http://www.pouet.net

Wir, Sizcoder, begründen in Größenkategorien. Für MS DOS sind diese Kategorien 256b, 128b, 64b und 32b. Dies sind die Standards eines der größten Archive der Demoszene www.pouet.net. Es gibt keine 16b-Kategorie, jedoch können viele kleine Effekte in 16 Bytes implementiert werden. Fast alle Effekte aus „Memories“ wurden früher von mir geschrieben und optimiert, und im Grunde war ihre Implementierung ein Versuch, die vorhandene Größe des Effekts zu reduzieren oder etwas Ähnliches, aber Kleineres zu erzeugen. Mit Größenreduzierung ist hier die Reduzierung auf eine der folgenden kleineren Kategorien 2 ^ N gemeint. Wenn der Effekt beispielsweise in 33-64 Bytes implementiert wurde, wird er auf 32 Bytes oder weniger reduziert. Fast jedes Mal, wenn es mir gelang, den Effekt auf eine niedrigere Kategorie zu „senken“, schickte ich das resultierende winzige Programm an eine Veranstaltung, die der Demoszene gewidmet war, an der entfernte Teilnehmer an der Kategorie 256b teilnehmen durften, und / oder veröffentlichte das Ergebnis auf www.pouet.net. In diesem Abschnitt werde ich Ihnen die Effekte vorstellen und über deren Herkunft und Autoren sprechen.

Reihe von Schachbrettern



kasparov, 16 Bytes. Die

Quelle dieses Effekts war mein eigener „Kasparov 16b“ von 2018 ( Link ). Es scheint (Zitat aus den Versionshinweisen), dass ich "gerade dieses Board gemacht habe, es in 17 Bytes gepasst habe, aber es war nicht sehr schön, bis ich einen Trick gefunden habe ...". Zuvor war bereits ein ähnlicher Effekt in 32 Bytes implementiert: 2003 ew vom Entwickler-Headcrash. ( Link ) In diesem Fall habe ich versucht, „echte“ Schachbretter mit einem 8x8-Quadrat und erkennbaren schwarzen und weißen Quadraten sowie der korrekten Ausrichtung einzelner Schachbretter zu implementieren, dh die untere rechte Ecke (h1) sollte weiß sein. Damit dieser Effekt mit dem globalen Framework funktioniert, musste er in „Memories“ mit einer anderen Technik neu implementiert werden: Aufzeichnen auf dem Bildschirm; Außerdem wurde die Bildlaufrichtung so geändert, dass sie sich vom Effekt „Bildlauf gekippte Ebene“ unterscheidet.

Kreise zoomen


Skalierbare Kreise (zoomende Kreise) sollten als Intro von 32 Bytes an Demopati teilnehmen, aber ich habe es nie getan. Dieser Effekt hat keinen 64-Byte-Vorgänger, da in der 64b-Kategorie wesentlich komplexere Effekte möglich sind. Das Zoomen von Kreisen war das Ergebnis meines verzweifelten Versuchs, mit dem Effekt eines runden „Tunnels“ in die Kategorie 32b zu gelangen, für den mein persönlicher Datensatz noch 52 Bytes betrug („Neontube“ - 2016) ( Link ), was wiederum zu einer Optimierung des Klassikers 64 wurde -Byte-Effekt "Konstante Evolution" Entwickler Ryg / Farbrausch (2003) ( Link ). Beim Zoomen von Kreisen werden Abstand und Winkel eliminiert / ignoriert, wodurch es möglich war, in die Kategorie 32b zu fallen.

Scrolling gekipptes Flugzeug



Floorcast, eine 32-Byte-Version, eine Variation der

geneigten Scrolling-Ebene, ist eine meiner eigenen Veröffentlichungen, der 2018 Floorcast 32b. Der Effekt von „Bodenbelägen“ hat seine eigene Geschichte bei der Größencodierung und ist allmählich von 256 Bytes auf 32 Bytes gesunken. Unterschiedliche Versionen unterscheiden sich in der Anzahl der Ebenen, in einigen werden zwei Ebenen angezeigt, in anderen - nur eine. In der Version „Floorcast 32b“ habe ich mich ausdrücklich dafür entschieden, die „XOR“ -Textur aufzugeben, und in „Memories“ habe ich sie erneut verwendet und sie mit dem letzten Schliff in Form von „AND“ maskiert.

  • 2008 rain_storm Version - 256 Bytes - Link
  • 2008 Version von org_100h - 128 Bytes - Link
  • 2013 Baudsurfer Version - 86 Bytes - Link
  • 2014 Baudsurfer Version - 64 Bytes - Link
  • 2018 HellMood Version - 32 Bytes - Link

Parallaxe Schachbretter



Projektbeschreibung, 32 Bytes

Ich habe 2018 Parallaxenschachbretter als 32-Byte-Projektbeschreibungseffekt veröffentlicht. Darin habe ich versucht, die Größe von "Follow the light" ( Link ) von "Digimind" (2006) oder meiner eigenen "Lucy" (2014) ( Link ) auf 32 Bytes zu reduzieren . Sehr nützliche Inspirationsquellen waren Paralaxa von Rrrolas (32 Bytes, 2007, Link ) und Byteropolis von Sensenstahl (2013) ( Link)) Die Rrrolas-Rendering-Technik war meiner endgültigen Entscheidung sehr nahe. Der Code wurde geändert, um die Position der Ebenen zu korrigieren, die Dreiecke durch Schachbretter zu ersetzen und die Farben zu verbessern. Erinnerungen verwendeten das Farbschema der Digimind-Version. Zusätzlich wurde der Effekt maximal modifiziert, um Verformungen zu reduzieren.

Sierpinski Rotozoomer



Colpinski, 16 Bytes


rotastisch, 32 Bytes

Es besteht aus zwei Effekten: Rotozoomer und Sierpinski-Effekt als Textur. Der Sierpinski-Effekt basiert auf meinem eigenen Colpinski 16b 2013-Effekt ( Link ), bei dem ich mit der frag-Funktion fsqrt das maximal mögliche Ergebnis erzielt habe. Dieser Effekt hat keinen Vorgänger, da er direkt durch Kombinieren von X und Y implementiert werden kann, anstatt ein iteriertes Funktionssystem oder zellulare Automaten zu verwenden. "Rotation and Scaling" (Rotozoomer) wurde von mir 2017 als 32b-Intro "rotastic" ( Link ) veröffentlicht. Es basiert auf den Ideen von "ryg" des Entwicklers Farbrausch (51 Bytes, 2002, Link ) und "Gargaj" der Gruppe "Conspiracy". "(49 Bytes, 2002, Link ).

Raycast gebogener Tunnel



In eine neue Ära, 64-Bit-Version Der

Raycast-Tunnel wurde zu einer modifizierten Version meiner eigenen 64-Byte-Version „In eine neue Ära“ (2018, Link ). Die ursprünglichen Farben wurden durch die Farben der Standardpalette ersetzt, die Geometrie und die entsprechenden Berechnungen wurden geringfügig geändert, sodass der Tiefeneffekt nicht zur Berechnung der Texturwerte verwendet wurde. Eine separate Version dieses Effekts ist 50 Byte groß. Die Hauptinspirationsquellen für die Erstellung der 64-Byte-Version waren zwei 128-Byte-Intros: „Spongy“ von „TBC“ (2009, Link ) und „Wolf128“ von Baudsurfer (2014, Link ), und ich habe den Algorithmus selbst entwickelt.

Ozean Nacht zu Tag



Ocean, Version 64b

Der Ocean-Effekt basiert auf meiner eigenen 64-Byte-Version von „Ocean“ 2016 ( Link ). Eine separate Generation der Farben und Musik des Originals wurde ausgeschnitten. Beide Generatoren waren nicht mit dem Haupt-Memories-Framework kompatibel, ohne jede Menge zusätzlicher Bytes zu verwenden. Der besondere Effekt von "Dawn" ist auf die Gesamtimplementierung der Framework-Struktur zurückzuführen. Ich werde im nächsten Kapitel darüber sprechen.

Fading-Effekt


Der Übergang zwischen den beiden Effekten ist an sich ein Effekt, der keine Vorgänger hat. Es ist vielmehr eine Idee, die sich über mehrere Jahre entwickelt hat und vielleicht von vielen anderen auf ähnliche Weise umgesetzt wurde. Kurz gesagt, bei der Berechnung des Rahmens wird die Position jedes Pixels zufällig ausgewählt, und die Zeit, die bestimmt, welcher Effekt verwendet werden soll, wird um diesen Randomisierungswert verschoben, der zuvor reduziert wurde. Auf diese Weise können Sie eine Standard-VGA-Palette (Bild, Quelle) verwenden, anstatt eigene Farben für ein reibungsloses Mischen zu erstellen, was Platz spart.

Der Rahmen meines "winzigen Megademos"


Um mehrere kleine Effekte zu einem „Megademo“ zu kombinieren, sollten sie dieselbe Technik verwenden und höchstens keine Annahmen treffen (in Bezug auf den Inhalt des Speichers und der Register). Sie müssen auch dieselben Zeitwerte verwenden und entsprechend der Gesamtzeit arbeiten. Es hat ziemlich lange gedauert, einzelne für das Framework geeignete Effekte vorzubereiten, und zunächst viel zusätzlichen Platz. Es sollte beachtet werden, dass einige der beeindruckendsten Effekte (gemessen an der Reaktion der Zuschauer und den Ansichten in sozialen Netzwerken) aufgrund der RIESIGEN übermäßigen Nutzung des Speichers nicht in die Demo aufgenommen werden konnten. Nachdem alle Effekte behoben waren, konnte ich über häufig wiederholte Berechnungen nachdenken, die ein paar weitere Bytes einsparen würden.Das Framework führt die folgenden Aktionen aus:

  • 320 x 200 256


  • 35 FPS
  • ESC
    • ESC,


org 100h
s:
	mov al,0x13				; set AL to mode 320*200 in 256 colors
	int 0x10	 			; call BIOS to set mode
	xchg bp,ax				; set timing value to 0x13 
	push 0xa000-10			; write the screen adress to register ES
	pop es					; works in conjunction with Rrrola trick
	mov ax,0x251c			; parameter for changing timer interrupt
	mov dl,timer			; adress of timer routine, assume DH=1
	int 0x21				; install timer routine
top:
	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table
	call bx					; call the effect
	stosb					; write the return value and advance
	inc di					; triple interlace trick for after
	inc di					; effect and smoothing the animation
	jnz top					; repeat until the frame is complete
	mov al,tempo			; set AL to divider for timer
	out 40h,al				; set timing (dual pass)
	in al,0x60				; read keyboard
	dec al					; quit on ESC
	jnz top					; otherwise repeat loop
sounds: db 0xc3, 11, 0x93; 0xc3 is MIDI/RET; fx2-s is used as volume
table: 	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s


Reihe von Schachbrettern



Reihe von Schachbrettern

Der einfachste Effekt, um damit zu beginnen. Nach dem vorübergehenden Verschieben der Zeichenfolge wird das klassische XOR-Muster angewendet. Um den Eindruck eines Schachbrettgitters zu erwecken, werden alle bis auf zwei Bits farblich festgelegt. Der eigentliche Trick besteht darin, an den „guten“ Ort der Palette zu wechseln. Der Teil des Rahmens, der als schwarz wahrgenommen wird, ist eigentlich nicht schwarz, sondern der dunkle Teil der Standard-VGA-Palette . Diese Verschiebung ermöglicht es Ihnen, den dunklen und hellen Zellen das Gefühl eines alten Schachbretts zu geben.

	xchg dx,ax		; get XY into AX
	sub ax,bp		; subtract time from row
	xor al,ah		; XOR pattern (x xor y)
	or al,0xDB		; pattern for array of boards
	add al,13h		; shift to good palette spot

Kreise zoomen



Zoomen von Kreisen

Der Abstand D vom Punkt (X, Y) zur Mitte (0,0) beträgt sqrt (X² + Y²). Das Framework bewirkt zunächst, dass DL die zentrierte Koordinate X enthält und DH = Y im Code zentriert werden muss. Um die Quadratwurzel-Berechnungsoperation in x86 auszuführen, ist ziemlich viel Code erforderlich, aber tatsächlich kann er weggelassen werden. Bei sorgfältiger Farbauswahl scheint das Gefühl, Kreise ohne Quadratwurzel zusammenzuführen, ziemlich überzeugend.

	mov al,dh		; get Y in AL
	sub al,100		; align Y vertically
	imul al			; AL = Y²
	xchg dx,ax		; Y²/256 in DH, X in AL
	imul al			; AL = X²
	add dh,ah		; DH = (X² + Y²)/256
	mov al,dh		; AL = (X² + Y²)/256
	add ax,bp		; offset color by time
	and al,8+16		; select special rings

Scrolling gekipptes Flugzeug



Scrollen der geneigten Ebene

Dieser Effekt wird wie folgt implementiert: Um die Entfernung zu simulieren, wird zunächst eine große Konstante durch die Zeilennummer Y geteilt. Dann wird der erhaltene Wert zweimal verwendet: a) multipliziert mit dem zentrierten Wert von X und b) versetzt mit der aktuellen Zeit. Diese Ergebnisse werden dann unter Verwendung des XOR-Musters kombiniert, aus dem ein spezielles Muster ausgewählt wird.

	mov ax,0x1329	; initialize with constant
	add dh,al		; preventing divide overflow
	div dh			; reverse divide AL = C/Y'
	xchg dx,ax		; DL = C/Y', AL = X
	imul dl			; AH = CX/Y'
	sub dx,bp		; DL = C/Y'-T 	
	xor ah,dl		; AH = (CX/Y') ^ (C/Y'-T)
	mov al,ah		; move to AL
	and al,4+8+16	; select special pattern

Parallaxe Schachbretter



Parallaxenprüfplatten

Dies ist eine Art Reykasting (emittierende Strahlen) mit dynamischer Geometrie. Jede Ebene der Objekte wird aufgrund der 16-Bit-Multiplikation mit einem Vorzeichen horizontal und aufgrund der Operation der impliziten Logik mit der Spaltennummer vertikal geteilt. Zusätzlich wird eine indirekte Verzerrung angewendet, um die Kanten des resultierenden Netzes zu verbinden (4 "feste" Bereiche, 4 "transparente" Bereiche abwechselnd). Wenn der Strahl einen der durchgezogenen Bereiche kreuzt, wird die Farbe zur Iterationszahl (+ Palettenversatz in Graustufen), und wenn nicht, verschiebt sich die Ebene zum Bildschirmzeiger. Danach wird der Vorgang wiederholt, bis die maximale Anzahl von Iterationen erreicht ist.

	mov cx,bp		; set inital point to time
	mov bx,-16		; limit to 16 iterations
fx3L:
	add cx,di		; offset point by screenpointer
	mov ax,819		; magic, related to Rrrola constant
	imul cx			; get X',Y' in DX
	ror dx,1		; set carry flag on "hit"
	inc bx			; increment iteration count
	ja fx3L			; loop until "hit" or "iter=max"
	lea ax,[bx+31]	; map value to standard gray scale

Sierpinski Rotozoomer



sierpinski rotozoomer


Grafik 1 / cos (atan (x)), erstellt mit www.google.com

Zum Drehen mit Skalierung sind normalerweise trigonometrische Funktionen oder deren gute Näherungswerte erforderlich. Schauen wir uns die übliche 2D-Rotationsgleichung an und interpretieren sie auf besondere Weise, um die Trigonometrie in Berechnungen zu beseitigen:

x' = x*cos(a) - y*sin(a)
y' = x*sin(a) + y*cos(a)

Wenn wir Skalierung hinzufügen, sieht es folgendermaßen aus:

x' = z * (x*cos(a) - y*sin(a))
y' = z * (x*sin(a) + y*cos(a))

Nehmen wir nun an, wir definieren z nicht selbst und setzen 1 / cos (a) aus Klammern:

x' = 1/cos(a) * (x - y*tan(a))
y' = 1/cos(a) * (x*tan(a) + y)

Jetzt ersetzen wir tan (a) durch eine Zeitvariable, da die Tangentenfunktion gegen 180 ° gegen unendlich tendiert:

x' = 1/cos(atan(T)) * (x - y*T)
y' = 1/cos(atan(T)) * (x*T + y)

Wenn uns die fehlende Möglichkeit zur Einstellung des Skalierungsfaktors nicht wichtig ist und wir den Winkel nicht direkt steuern, können wir jetzt ohne Verwendung trigonometrischer Funktionen von -180 ° auf + 180 ° drehen. Infolgedessen stellt sich heraus, dass der Skalierungsfaktor an die Zeit T gebunden ist. Die Funktion für den Koeffizienten wird im Bild gezeigt, wodurch die Skalierung von einer Infinitesimalzahl auf eins (die ursprüngliche Größe) und zurück auf Infinitesimal erfolgt. Eine ganze Menge Bytes wurden aufgewendet, um diesen Effekt zu dekorieren, Zeitversätze zu korrigieren, Animationen zu beschleunigen, die Pixel von Sierpinskis Dreiecken zu vergrößern und wunderschöne Farben zu erstellen, aber ich denke, es hat sich gelohnt.

	lea cx,[bp-2048]; center time to pass zero
	sal cx,3		; speed up by factor 8!
	movzx ax,dh		; get X into AL
	movsx dx,dl		; get Y int DL
	mov bx,ax		; save X in BX
	imul bx,cx		; BX = X*T
	add bh,dl		; BH = X*T/256+Y
	imul dx,cx		; DX = Y*T
	sub al,dh		; AL = X-Y*T/256
	and al,bh		; AL = (X-Y*T/256)&(X*T/256+Y)
	and al,252		; thicker sierpinski
	salc			; set pixel value to black
	jnz fx4q		; leave black if not sierpinski
	mov al,0x2A		; otherwise: a nice orange
	fx4q:

Raycast gebogener Tunnel



Raycast gebogener Tunnel

Dies ist eine Art Tunnel mit Rakasting von "in eine neue Ära" (siehe oben). Eine detaillierte Beschreibung dieses Effekts für ein ähnliches Essence-Programm wurde auf reddit veröffentlicht. Ich habe einzigartige Farben entfernt, die Neigungsrichtung geändert und die Geometrie geschlossen, um die Leistung auf älteren Computern und in DosBox zu verbessern.

	mov cl,-9		; start with depth 9 (moves backwards)
	fx5L: 
	push dx			; save DX, destroyed inside the loop
		mov al,dh	; Get Y into AL
		sub al,100	; Centering Y has to be done "manually".
		imul cl		; Multiply AL=Y by the current distance, to get a projection(1)
		xchg ax,dx	; Get X into AL, while saving the result in DX (DH)
		add al,cl	; add distance to projection, (bend to the right)
		imul cl		; Multiply AL=X by the current distance, to get a projection(2)
		mov al,dh	; Get projection(1) in AL
		xor al,ah	; combine with projection(2)
		add al,4	; center the walls around 0
		test al,-8	; check if the wall is hit
	pop dx			; restore DX
	loopz fx5L		; repeat until "hit" or "iter=max"
	sub cx,bp		; offset depth by time
	xor al,cl		; XOR pattern for texture 
	aam 6			; irregular pattern with MOD 6
	add al,20		; offset into grayscale palette

Ozean Nacht zu Tag



Ozeannacht


oceanday

Der Ocean Effect ist ein hervorragendes Beispiel für „Zufall“.. Wenn wir den Wert als Ganzzahl in die FPU laden und als Gleitkomma speichern und ihn dann erneut als Ganzzahl interpretieren, erhalten wir ein großartiges Muster. Wenn Sie dies mit der inversen Teilung kombinieren, erhalten Sie einen schönen Welleneffekt. Es arbeitet eng mit dem DX-Register zusammen, das an der von uns benötigten Position eine Vorzeichenumkehr aufweist, sodass wir den Himmel leicht vom Meer trennen können. Der letzte Schliff ist jedoch die Farbe. Entsprechend der Struktur des globalen Frameworks wird der Wert von AL am Eingang der Funktion bestimmt, er enthält die Adresse des Effekts. Wenn Sie den Code ein wenig mischen, können Sie die Himmelsfarbe "frei" erhalten, ohne Anweisungen zu verwenden, genau wie die Farbe des "Übergangs zum Tag", der auch die Adresse des Effekts ist. Und das ist kein glücklicher Zufall. In anderen Versionen als der DosBox-VersionDie Farbe des Himmels kann aus diesem Grund variieren.

	sub dh,120			; check if pixel is in the sky
	js fx6q				; quit if that's the case
	mov [bx+si],dx		; move XY to a memory location
	fild word [bx+si]	; read memory location as integer
	fidivr dword [bx+si]; reverse divide by constant
	fstp dword [bx+si-1]; store result as floating point
	mov ax,[bx+si]		; get the result into AX
	add ax,bp			; modify color by time
	and al,128			; threshold into two bands
	dec ax				; beautify colors to blue/black

Fading-Effekt


Der Einfachheit halber ist der Effekt vom globalen Rahmen isoliert. Tatsächlich erzeugt es eine Pseudozufallszahl aus dem Bildschirmzeiger und führt dann einen Zeitversatz um seinen skalierten Wert durch, wonach es den gewünschten Effekt verursacht.

	mov ax,0xcccd			; load magic Rrrola constant
	mul di					; transform screen pointer to X, Y
	add al,ah				; use transformation garbage as
	xor ah,ah				; pseudorandom value and clear AH
	add ax,bp				; add time value to random value
	shr ax,9				; divide by 512 (basically the speed)
	and al,15				; filter effect number
	xchg bx,ax				; move effect number to BX
	mov bh,1				; reset BH to align with start of code
	mov bl,[byte bx+table]	; read the effect address from the table

MIDI-Musik


Dieser Codeabschnitt erhöht den Zeitwert und erzeugt einen Sound. Durch Auswahl von Kanal 3 können wir die Anweisung „Werkzeugkanal ändern“ als „RET“ wiederverwenden. Durch Verschieben des Effektcodes können Sie einen geeigneten Wert für das Volume erstellen, wodurch ein weiteres Byte gespeichert wird. Es ist zu beachten, dass dieser Teil des Codes nur funktioniert, wenn sich das MIDI-Gerät bereits im UART-Modus befindet. Andernfalls müssen Sie weitere drei Bytes ausgeben. Viele der Zuschauer und Organisatoren sagten mir, dass die Melodie ein bisschen wie Mike Oldfields Incantations ist , aber sie wurde mit einer sehr einfachen Technik erstellt. Seit Hypnoteye 2015 habe ich mit prozeduralem MIDI experimentiert und schließlich ein kleines MIDI-Framework (64 Bytes) veröffentlicht.. Das Hauptprinzip seiner Arbeit besteht darin, mit einer festen Tonhöhe in den Tonraum zu springen und hohe Werte in niedrigere umzuwandeln (durch Division Modulo). Durch einfache Kombinationen von Schrittweite und Modwert können interessante Effekte erzielt werden. Mit Stepwidth = 3 erhalten Sie beispielsweise einen kontinuierlich anhaltenden reduzierten Moll-Akkord und Stepwidth = 4 oder Stepwidth = 6 - Tritonaleffekte. Mit einem gut gewählten Modwert können diese Muster Sequenzen erzeugen. Ich habe keine richtige theoretische Analyse durchgeführt, sondern einfach den Raum der Töne erkundet und interessante Klänge festgestellt.

sounds: db 0xc3, 11, 0x93, fx2-s
...
		inc bp				; increment timing value
		test bp, 7			; play a note every 8th step
		jnz nomuse			; quit if in between
		mov dx,0x330		; port number for MIDI
		mov si,sounds		; adress for sound data
		outsb				; change instrument of channel 3
		outsb				; to vibraphone
		outsb				; play a note on channel 3
		imul ax,bp,-19*32*4	; the magic melody constant
		shr ax,10			; scale down and implicit "and 63"
		add al,22			; pitch base is 22
		out dx,al			; play THIS note on channel 3
		outsb				; play it with THIS volume

Vollständiger Release-Code


; "memories" by HellMood/DESiRE
; the tiny megademo, 256 byte msdos intro
; shown in April 2020 @ REVISION
;
;   (= WILL BE COMMENTED IN DETAIL LATER =)
;
; create : nasm.exe memories.asm -fbin -o memories.com
; CHOOSE YOUR TARGET PLATFORM (compo version is dosbox)
; be sure to use the dosbox.conf from this archive!
; only ONE of the defines should be active!
%define dosbox			; size : 256 bytes
;%define freedos		; size : 230 bytes
;%define winxpdos		; size : 263 bytes

; DON'T TOUCH THESE UNLESS YOU KNOW WHAT YOU'RE DOING
%ifdef winxpdos
	%define music
	%define switch_uart
	%define safe_dx
	%define safe_segment
%endif
%ifdef freedos
	%define safe_dx
%endif
%ifdef dosbox
	%define music
	;%define safe_dx ; sometimes needed
%endif

; GLOBAL PARAMETERS, TUNE WITH CARE!
%define volume 127	; not used on dosbox (optimization)
%define instrument 11
%define scale_mod -19*32*4; 
%define time_mask 7
%define targetFPS 35
%define tempo 1193182/256/targetFPS		
%define sierp_color 0x2A
%define tunnel_base_color 20
%define tunnel_pattern 6
%define tilt_plate_pattern 4+8+16
%define circles_pattern 8+16

org 100h
s:
%ifdef freedos
	mov fs,ax
	mov [fs:0x46c],ax
%endif
	mov al,0x13
	int 0x10	 
	xchg bp,ax
	push 0xa000-10
	pop es
%ifndef freedos
	mov ax,0x251c
	%ifdef safe_dx	
		mov dx,timer	
	%else ; assume DH=1, mostly true on DosBox
		mov dl,timer
	%endif
	int 0x21
%endif
top:
%ifdef freedos
	mov bp,[fs:0x46c]
%endif	
	mov ax,0xcccd
	mul di
	add al,ah
	xor ah,ah
	add ax,bp
	shr ax,9
	and al,15
	xchg bx,ax
	mov bh,1
	mov bl,[byte bx+table]
	call bx
	stosb
	inc di
	inc di
	jnz top
	mov al,tempo
	out 40h,al
	in al,0x60
	dec al
	jnz top
sounds:
	db 0xc3	; is MIDI/RET
%ifdef music
	db instrument,0x93
	%ifdef switch_uart
		db volume		; without switch, volume is in table
		db 0x3f 
	%endif
%endif
table: ; first index is volume, change order with care!		    					
	db fx2-s,fx1-s,fx0-s,fx3-s,fx4-s,fx5-s,fx6-s,sounds-s,stop-s
stop:
	pop ax
	ret
timer:
%ifndef freedos
	%ifdef safe_segment
		push cs
		pop ds
	%endif
		inc bp
	%ifdef music	
		test bp, time_mask
		jnz nomuse
		mov dx,0x330
		mov si,sounds
		outsb
		outsb
		outsb
		imul ax,bp,scale_mod
		shr ax,10
		add al,22
		out dx,al
		outsb
		%ifdef switch_uart
			inc dx
			outsb
		%endif
	%endif
nomuse:
	iret
%endif	
fx0: ; tilted plane, scrolling
	mov ax,0x1329
	add dh,al
	div dh
	xchg dx,ax
	imul dl
	sub dx,bp
	xor ah,dl
	mov al,ah
	and al,tilt_plate_pattern
ret
fx2: ; board of chessboards
	xchg dx,ax
	sub ax,bp
	xor al,ah
	or al,0xDB
	add al,13h
ret
fx1: ; circles, zooming
	mov al,dh
	sub al,100
	imul al
	xchg dx,ax
	imul al
	add dh,ah
	mov al,dh
	add ax,bp
	and al,circles_pattern
ret
fx3: ; parallax checkerboards
	mov cx,bp
	mov bx,-16
fx3L:
	add cx,di
	mov ax,819
	imul cx	 
	ror dx,1	 
	inc bx	 
	ja fx3L
	lea ax,[bx+31]	 
ret
fx4: ; sierpinski rotozoomer	
	lea cx,[bp-2048]
	sal cx,3
	movzx ax,dh
	movsx dx,dl
	mov bx,ax
	imul bx,cx
	add bh,dl
	imul dx,cx
	sub al,dh
	and al,bh
	and al,0b11111100
	salc				; VERY slow on dosbox, but ok
	jnz fx4q
	mov al,sierp_color
	fx4q:
ret
fx5: ; raycast bent tunnel
	mov cl,-9
	fx5L: 
	push dx
		mov al,dh
		sub al,100
		imul cl
		xchg ax,dx	
		add al,cl
		imul cl
		mov al,dh
		xor al,ah
		add al,4
		test al,-8
	pop dx
	loopz fx5L
	sub cx,bp
	xor al,cl
	aam tunnel_pattern; VERY slow on dosbox, but ok
	add al,tunnel_base_color
ret
fx6: ; ocean night / to day sky
	sub dh,120
	js fx6q
	mov [bx+si],dx
	fild word [bx+si]
	fidivr dword [bx+si]
	fstp dword [bx+si-1]
	mov ax,[bx+si]
	add ax,bp
	and al,128
	dec ax
fx6q:
ret

Bonus - NFO / ASCII
                                                             art : hammerfist
         ∂#MW%e                              _d$Ng,
         'B,  ∂b                   _jM@$QZb,cQ"  )@
  ,edRB$b,l@   Wk,yGR$KM&$b,     ,dP"     Wl ]bsd%UR8BG6&$@DSyG#ZKM&$b,
,dP      "T%L  'MGF      "*∂R_   Tg    "*4Zk,#I  YP   W"    7P      "*∂R
4M   gd@    ^   ∂@   d@b   dQ$#@Z@R3L_    "*GMj  'W      ,gd$   d@b   9Q$#%b
W#,  `M          Wb  `*  _4P   `Qk  *#N8L   `H5   @b   'QR7YK   `*  _4F"   Qk
`6@L             dML            '@          ,BK   'M    ∂B  *b,            '#L
  ^QBb,_     _,4&M∞∂@=,_       _dGL       _gQKM    GL    @k  'Mg,_         _dG,
    "*BN5W$2#MNP"   "*G3WRM8&B5P"`Y@QNW3Z5P" ∂#$W8BRM3XZN87    "*GW38M%EBDW5P"`


                              p r e s e n t s

            4
           d@,
         _& `Wl
      _,aP   "#baedM$#@@K JP*"?ML
 ,ad@$#P"         ,d@NEWVB"     X,aQPYb,_
V@Mm,_          ,d@MW#BW'      EMP"   '¶R ,ngBP^fML
 ¶M@N@y        Y#BNW#M"       J9"      `MQ9"      "MgRBq  ,QBMg,
  VN#P` ,d@@    `WM@^                   7f         ¶F` 7kY"   ^G  _.eQNE1.
   ]B _G@MWN$,   `P                     '     4b       QP      ¶w@F*^  ^Qb
   ]O@NRM#W@MNB,         ;                    ^`      j        JP^       Yl
  J#NRNWM@#BcT"^        ,A  _J                     _q@                   `X
 '¶WM#B@WdY`,7        _G#YN#PM                 _,gG"                      M,
  *BN#WP"  dK       ,Q@NRMB"]9       ,      _,M@Q*                        #A
   "U^      V@h,   iNBW#NT  J'      J9     s@QN"         _;               'D,
             ¶RMBv&NMQR@9  .W      .K'     "9`         ,6BA   _JL          ]l
              Y#NE@W#NRP   #[      `¶8               _d@MW#B_jW#W          BN
               "GQ@MR#W    QL_      *B            _,p#NBW#NQMG@WY          3Q
                  "Y@F     ,XW@M%im,_Yb_     _,g5@#MW@QMNE@E@NRMB         ,WM
                    `  _,gP*"#REM#GB@N#MQbnd@N#M@MW#R8QSB^'WQERM@        ;4NB,
                     ,GYKL    ¶E#B8R8QSB@M@#BM#W@MNB"`_  ,  "^` N       ,dW@Ql
                   _Q`'W`*t    '¶@GS#MBQ#E@W#NQBW[     'LvQ_   ,K    _dNABGM#N
                  ,F   '          `^WAB@QGE9*"9^*@L    jP7FY,  ¶h,_.jWM#BR#GBM,
                 J;    ,   _                  '       '   "LL  YxE#B8R8QSBNW@W;
                AP   _,Ag6^          _   J                  ¶A  `"Q#M@MW#R8E#P
               j@   `"XQW[            'LvK,_      'L_,/      @t    Y#NE@WNR"
              :M/     9^*@L           jP7F"       _PYKL     _,A;     ¶RSNQ"
              dKL     '     `        '   "L      "`'W`*t   `"XQb      `W^
              Q`8t            'L_,/         ,   _   '        9^Q
             ,W               _PYKL       _,Ag6^             ' W,     _ ,#N&
             !N  _   J       "`'W`*t     `"XQW[       _  J     N!_JG9^RwQ' *t
             `W,  'LvK,_        '        _gGB8@L   _   'LvK,_ ,WgB'    V    7L
         _.,gm&@B&wBZF"                j@'`  "WL _gML  jZd7Yb lN"          dBWl
      ,g&QB*"^`    `"*G@g, .gR&k,_   ,N"      '@QF  ¶k;gMF  *QvQ     jQ, ,@N@B#,
   .eQF*`              `Yb@"  "*6Qg,gF     ,   7     XMN"    'MNB,    ^¶QWSER@N;
 ,gP"           qy,      W'       ^Q'     &L      ,g@W'       `QMEL     `"WBNWP
g7              ¶9      ,X         M?     9"   _q8MSK           ¶EMt       *@K
Vh   _,m#L             _AH        le         ,GBDNE9^A,          *@F        NMg
 ¶L,qQ@ND           _.m@Bl        We      ,gM@B8#Q'   ¶h_                   lWE,
  W9NHW@`          JWM#B@]        @e     4WR@NGF^      'QL                  dRWl
   VMd*            "@BE@PM        'N      *UP"           VW,               JRSB;
  ,@F       j       `¶WK W,        ¶t                     XNt            _A@E#N
_JP       ,6&         "GLdM         XD,               _.g8NMA@k,_    _,gG#NMGR;
"Z      .JRER           'VMi     _jNB#W&_         _,j@E@W#Nl ¶MBGMNQGNQMG@QBW9
 ¶h   ,G@NRMBl            `"   ,d#R@M$F ¶Mg,_.gp&@@NEWVBWBMG  *QMN8R8SBN$E@WF
  Vb dW#R8QSRb,                 *YM@EQ,_ 'MENBW#NQMG#B@R@MW#l   "BM@QNENRQG'
   *WGS#MBMNEYL                    `^"*8M@Q@NRM#W@BWSNW@QBF"`     `^*@QBF^ [HFT]
    ^M@MW#Q9 ^Wt                           `^¶RQ@W8NQGP*`
     ¶Q#@P     Vk                            lA `"^`
      Y"       `MA                           J#,
                *R@,                        ,MQl
                 Y#Wk,                      GWM8L
                  W8RQSt,_                 AQ@MR#,
                  `@M@#SB@Mbm.,_          QNBW#NW
                    ¶QB8R8SBN$WNRM@#GNtwg@NMQR@B'
                     *MBQ#8R8QS@NE@WNBW#NQMG@NR;
                      `WGS#MBQ#R8QSB@NE@W#NQBW9
                        *OMW@QMNE@E@NRMW@QMB@*
                          `^"YQW@Q#SB#NE@EGP
                               `^"*8R@GBQF`


All Articles