home *** CD-ROM | disk | FTP | other *** search
-
-
- $VER: Developer.deu V2.17 (18.07.1995)
- Copyright 1995 by Delirium Softdesign
- (Peter Kunath and Frank Riffel)
-
- DeliTracker Development Documentation
-
-
- 1.ÜBERBLICK
-
- 2.PLAYER
- 2.1 Normale Player
- 2.2 Custom Module
- 2.3 Interrupts
-
- 3.GENIES
- 3.1 Generic Kind
- 3.2 Converter
- 3.3 Decruncher
- 3.4 NotePlayer
-
- 4.TAGS
-
- 5.DELITRACKER SUPPORT FUNKTIONEN
-
-
- 1.ÜBERBLICK
-
- DeliTracker kann mit externen Programmodulen erweitert werden. Diese
- sehen vom DOS aus betrachtet genauso aus wie normale Objectfiles, mit
- dem Unterschied allerdings, daß sie am Anfang des ersten Hunks eine
- spezielle Struktur besitzen. Wenn DeliTracker ein solches Programmodul
- nachlädt, wertet er diese Struktur aus. Sie besteht aus drei Teilen:
- Einem Longword mit Code, zwei Longwords als Identifier und als letztes
- einem Pointer auf ein Tagarray. Das erste Longword enthält normalerweise
- moveq #-1,d0 gefolgt von einem rts Befehl. Dies soll einen Absturz
- verhindern, wenn ein Player oder Genie irrtümlich vom Benutzer gestartet
- wird. Um ein Programm zu erzeugen, das auch ohne DeliTracker lauffähig
- ist, muß in das erste Longword in einen bra.w geändert werden, der dann
- den eigentlichen Startupcode anspringt. Um die charakteristische Struktur
- zu erzeugen sollte das PLAYERHEADER Macro aus 'deliplayer.i' verwendet
- werden. Es hat zwei Parameter: einen Pointer auf ein Tagarray und
- optional einen Pointer auf den Startupcode.
-
- PLAYERHEADER <tagarray>,[startup]
-
- tagarray Pointer auf ein Tag Array, das mit TAG_DONE
- abgeschlossen sein muß.
- startup Pointer auf einen optionalen Startupcode. Nur
- notwendig, wenn das Programmodul auch ohne
- DeliTracker lauffähig sein soll. Diese Option
- kann z.B. für Debug-Zwecke verwendet werden.
- Bemerkung: Wenn der Startupcode angesprungen
- wird, muß die gesamte Initialisierung etc. ohne
- DeliTracker durchgeführt werden. In den meisten
- Fällen macht die Startup Option wenig Sinn und
- wird deshalb auch kaum benutzt.
-
- Die Tagliste enthält dabei alle Informationen, die DeliTracker wissen
- muß. Wir verwenden ein Tagarray deshalb, weil es sehr flexibel und leicht
- erweiterbar ist. Zusätzlich können die externen Programmodule noch die
- GlobalStructure sowie die eingebauten Supportfunktionen benutzen. Im
- Moment unterscheidet DeliTracker zwei verschiedene Typen von externen
- Programmodulen:
-
- 1) Player, um Module zu identifizieren und zu spielen
-
- 2) Genies können viele andere Dinge machen. Unter anderem Module
- konvertieren, Dateien entpacken oder Informationen anzeigen.
-
- Beide Arten können synchron oder asynchron laufen. Unter synchron
- versteht man, daß der Player oder das Genie nicht als eigener Prozess
- läuft. DeliTracker benutzt in diesem Fall echte Funktionsaufrufe (jsr)
- zur Kommunikation. Im asynchronen Modus startet DeliTracker den Player
- oder das Genie als eigenen Prozess und verwendet dann Messages um
- Funktionen der externen Programmodule aufzurufen. Im allgemeinen laufen
- Genies asynchron und Player synchron. Wenn ein Player oder ein Genie
- asynchron läuft, dann muss man es durch Senden eines CTRL-C Signals an
- den Prozeß beenden können. Offensichtlich sind DeliPlayer und DeliGenies
- also sehr ähnlich. Sie werden von DeliTracker auch ziemlich gleich
- verwaltet, wenn auch in zwei verschiedenen Listen. Jedes externe
- Programmodul bei dem ein DTP_CustomPlayer, DTP_Check1 oder DTP_Check2
- Tag benutzt wird, ist ein Player. Der Rest sind Genies.
-
- Wenn eine GUI vorhanden ist, sollten normalerweise folgende Menüpunkte
- zur Verfügung stehen:
-
- Project
- About A ? Kurzinformation über das Programmodul
- ==============
- Save Prefs A S Speichern der aktuellen Einstellungen
- ==============
- Hide A H GUI verbergen
- ==============
- Quit A Q Genie beenden (ebenso wie CTRL-C)
-
- Settings
- Activate A A Aktiviert das Fenster beim Öffnen des GUI
- Popup A P Öffnet das GUI nach dem Laden
- ==============
- Other settings Hier können je nach Bedarf weitere
- ·············· Einstellungen folgen.
-
- Ein paar Anmerkungen:
-
- Bevor man einen DeliPlayer schreibt, sollte man sich die mitgelieferten
- Beispielsourcen genau durchlesen. Um einen besseren Überblick davon zu
- bekommen, wann und in welcher Reihenfolge DeliTracker die Funktionen des
- Players aufruft, kann man den 'Testplayer.s' Source benutzen. Wenn eine
- Konfigurationsdatei abgespeichert werden kann, sollte sie nicht nach
- ENV:, sondern in das DeliTracker Konfiguartionsverzeichnis abgespeichert
- werden. Der Pfad des Konfiguartionsverzeichnisses kann steht in der ENV-
- Vaiable 'DeliConfig'. Falls diese nicht vorhanden ist, sollte stattdessen
- 'PROGDIR:DeliConfig' zum Abspeichern benutzt werden. Ein Player sollte
- außerdem den Zustand der LED (Lowpass-Filter) unbeeinflußt lassen, da im
- Optionfenster eine entsprechende Funktion existiert. Wenn von DeliTracker
- eine Funktion des Players aufgerufen wird (außer bei den Interrupt-
- Funktionen DTP_Interrupt und DTP_NoteSignal), enthält das Register a5
- einen Pointer auf die Globale Struktur (Base). Da DeliTracker vor Aufruf
- einer Routine (außer bei DTP_Interrupt und DTP_NoteSignal) alle Register
- sichert, dürfen diese verändert werden.
-
-
- 2.PLAYERS
-
- Es ist relativ einfach, eine Replayroutine an DeliTracker anzupassen.
- Alles was Sie tun müssen ist ein wenig Interfacecode zu schreiben. Dies
- ist im allgemeinen recht einfach, denn DeliTracker stellt ihnen viele
- hilfreiche Routinen zur Verfügung. Um ein neues Soundsystem anzupassen,
- benötigen Sie zum einen den Quellcode oder ein linkbares Objektfile der
- Replayroutine, zum anderen sollten mindestens ca. 5 Module zum Testen der
- Funktionstüchtigkeit des Players vorhanden sein. Ganz am Anfang eines
- Players muß die charakteristische Struktur stehen. DeliTracker unter-
- scheidet dann zwei Arten von Playern: normale Player und Custom Module.
-
- 2.1 Normale Player
-
- Normale Player identifizieren und spielen Module. Sie müssen immer eine
- Check Routine besitzen. Der schematische Aufbau eines normalen Players
- ist folgendermassen:
-
- { Playerheader } Kennzeichnet das Object als Player.
- { TagArray } Beschreibung, was der Player kann.
- { Interfacecode } Playername/Registerumsetzung/Checkcode u.ä.
- { Replaycode } Eigentlicher Musikabspielcode.
- { evtl. Daten } und Daten
-
- Damit der Player die einzelnen Module unterscheiden kann, befindet sich
- in jedem Player eine Erkennungsroutine, die auf ein zugehöriges Modul
- testet und DeliTracker mitteilt, ob der Player dieses Modul spielen
- kann oder nicht. Diese Routine prüft auf Stellen im Modul, die bei allen
- Modulen eines Formats gleich sind. So z.B. auf 'M.K.' bei Offset $438
- in ProTracker-Modulen. Nur auf einige wenige Sprungbefehle zu Prüfen
- reicht im allgemeinen nicht aus, da viele Modulformate mit eingebauter
- Abspielroutine Sprungbefehle am Anfang haben und der Player möglicher-
- weise das falsche Modul erkennen könnte, was in den meisten Fällen zum
- Absturz führt! Deshalb sollte die Check Routine auch eingehend getestet
- werden. Es gibt zwei Typen von Check Funktionen, genau eine davon muß
- der Player verwenden.
-
- a) DTP_Check1: Diese Check Funktion wird aufgerufen, wenn DeliTracker
- 1K des Files geladen hat. Der Vorteil ist, daß sich auch Player
- realisieren lassen, die das Modul selbst nachladen. Der Nachteil ist,
- daß der Player dann nicht von den Entpackroutinen in DeliTracker
- profitiert. Meistens ist es deshalb schwerer, einen solchen Player zu
- schreiben. Man sollte diesen Typ nur für Härtefälle verwenden, z.B.
- wenn das Modul vom Player selbst geladen werden muß.
-
- b) DTP_Check2: Diese Check Routine wird aufgerufen, wenn das Modul
- geladen und ggf. entpackt ist. Da ein Player mit dieser Check Funktion
- im allgemeinen leichter zu schreiben ist, sollte im Normalfall diese
- Check Routine verwendet werden.
-
- Egal welche Checkfunktion verwendet wird, wenn der Player das Modul
- erkannt hat, muß er in d0.l=0 zurückliefern, wenn nicht d0.l<>0.
-
-
- 2.2 Custom Module
-
- Custom Module sind keine Module im herkömmlichen Sinn, sondern
- besondere Player, die ein Modul beinhalten. Sie haben auch keine
- Check Funktion, stattdessen muß der DTP_CustomPlayer Tag bzw. das
- CUSTOM Flag (in DTP_Flags) verwendet werden. Mit diesem Interface
- kann man auch die ausgefallensten Moduleformate an DeliTracker
- anpassen. Sollten jedoch mehrere Module dieses Typs existieren, ist
- es in jedem Fall ratsam, einen richtigen Player zu schreiben.
-
- { Playerheader } Kennzeichnet das Object als Player.
- { TagArray } Beschreibung, was der Player kann.
- { Interfacecode } Routinen zur Registerumsetzung u.ä.
- { Replaycode } Eigentlicher Musikabspielcode.
- { evtl. Daten } und Daten
- { SOUND DATEN } Das eigentliche Modul
-
-
- 2.3 Interrupts
-
- Hier gibt es eine Einteilung in zwei verschiedene Typen.
-
- a) Player die den DeliTracker Interrupt verwenden
-
- Vorteil: Der Player ist vom Videomodus unabhängig.
- Besitzt automatisch die Faster/Slower Funktion.
- Kein Aufwand für den Interrupt (Code + Interruptstruktur).
- Automatisch kompatibel zum serial.device.
- Nachteil: Der Interrupt kommt nicht synchron zum VBlank. (Dies führt
- nur in den seltensten Fällen zu Problemen.)
-
- b) Player die ihren eigenen Interrupt erzeugen.
-
- Vorteil: Es können andere Interruptquellen benutzt werden
- (z.B. AudioIRQ).
- Nachteil: Erhöhter Aufwand, bei VBlank nicht mehr unabhängig vom
- Videomodus.
-
- Wenn ein eigener Timerinterrupt verwendet wird, sollte die CIAB
- (wg. OS2.0) und die entsprechenden Resourcefunktionen verwendet werden.
- Außerdem ist es sehr sinnvoll die Replayroutine nicht direkt im CIA-B
- TimerInterrupt laufen zu lassen, sondern im Timerinterrupt einen
- Soft-Interrupt mittels Cause() zu generieren. In diesem SoftInt kann
- man dann die eigentliche Replayroutine ablaufen lassen. Das hat den
- Vorteil, daß man wesentlich kompatibler zum serial.device ist. Dies
- liegt daran, daß SoftInt eine niedrigere Priorität als der der RBF
- (Read Buffer Full) Interrupt hat d.h. erst wird der serielle Port
- bedient, dann erst die Replayroutine. Es wird davor gewarnt, direkt
- in die Interruptvektoren zu schreiben! Vom Betriebssystem werden dafür
- die Funktionen AddIntServer() und SetIntVector() zur Verfügung
- gestellt.
-
-
- 3.GENIES
-
- Die Funktionalität von DeliTracker kann mit Hilfe von Genies auf viele
- verschiedene Arten erweitert werden. Im Moment existieren vier
- grundsätzlich verschiedene Einsatzgebiete für Genies: die Ausgabe von
- Noten (nicht zu verwechseln mit Playern), das Entpacken und Konvertieren
- von Modulen und schließlich das Analysieren des aktuellen Moduls.
-
- 3.1 Generic Kind
-
- Diese Art von Genies ist nicht auf spezielle Aufgaben beschrängt. Es
- kann z.B. diverse Informationen über das Modul anzeigen. Natürlich
- darf weder das Modul noch die Globale Struktur zur Gewinnung dieser
- Informationen verändert werden. Überlicherweise benutzt dieser Genie-
- Typ DTP_InitPlay/DTP_EndPlay um zu erfahren, wann ein neues Modul
- gespielt wird, zusätzlich evtl. auch noch DTP_StartInt/DTP_StopInt.
-
- 3.2 Converter
-
- Diese Genies verändern ein Modul. So kann man z.B. das Format des
- Moduls oder seine Länge ändern. Für diese Aufgabe gibt es einen
- speziellen Tag, nämlich DTP_Convert. Er enthält die Adresse der
- Convert-Funktion.
-
- 3.3 Decruncher
-
- Diese Art von Genies erweitert die dtg_LoadFile() Funktion von
- DeliTracker. Da sich dieses Interface noch ändern wird, ist es im
- Moment noch nicht dokumentiert.
-
- 3.4 Noteplayer
-
- Diese Genies haben die Aufgabe, 'Noten' ggf. zu konvertieren und sie
- auf der jeweiligen Audiohardware auszugeben. Dieses Interface ist zur
- Zeit noch Änderungen unterworfen und deshalb noch nicht dokumentiert.
-
-
- 4. TAGS
-
- Außer den SystemTags (TAG_DONE, TAG_IGNORE, TAG_MORE, TAG_SKIP) dürfen
- folgende Tags verwendet werden:
-
- DTP_CustomPlayer (BOOL) - dieser Tag deklariert einen Player als
- Customplayer.
- Bei Verwendung dieses Tags sind folgende Tags dann
- bedeutungslos: DTP_PlayerVersion
- DTP_PlayerName
- DTP_Creator
- DTP_Check1
- DTP_Check2
- DTP_ExtLoad
- DTP_Config
- DTP_UserConfig
-
- DTP_RequestDTVersion (WORD) - damit kann man sicherstellen, daß
- mindestens eine bestimmte Version von DeliTracker
- vorhanden ist. Dieser Tag muß angegeben werden, wenn
- bei den DeliTrackerGlobals neue Funktionspointer
- hinzugekommen sind und diese vom Player benutzt werden.
- ti_Data ist dabei die Playerrevision.
-
- DTP_RequestKickVersion (ULONG) - wenn dieser Tag angegeben ist, wird
- der Player nur noch von von DeliTracker geladen, wenn
- mindestens die angeforderte Kickstart Version vorhanden
- ist.
-
- DTP_PlayerVersion (ULONG) - Tag, der die Versionsnummer (high word) und
- die Revisionsnummer (low word) des Players enthält. Bei
- zwei Playern mit dem gleichen Playernamen wird derjenige
- mit der größeren Revisionsnummer geladen.
-
- DTP_PlayerName (STRPTR) - ti_Data enthält den Pointer auf den Namen des
- Players. Dieser String kann zwar beliebig lang sein aber
- zur Zeit werden nur die ersten 24 Zeichen angezeigt. Dieser
- Tag muß existieren!
-
- DTP_Creator (STRPTR) - Pointer auf den Namen des Autors. Dieser wird im
- Playerfenster im Playerinfofeld angezeigt. Der String
- kann $A als Zeilenumbruch enthalten.
-
- DTP_Check1 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
- aufgerufen wird, wenn 1024 Bytes des Moduls geladen sind.
- Wird das Modul erkannt, liefert sie d0=0, ansonsten d0<>0.
-
- DTP_Check2 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
- aufgerufen wird, wenn das komplette Modul geladen und evtl.
- entpackt ist. Wird das Modul erkannt, liefert sie d0=0,
- ansonsten d0<>0.
-
- DTP_ExtLoad (FPTR) - Pointer auf eine optionale Laderoutine für Module.
- Ist kein Fehler aufgetreten, wird d0=0 zurückgegeben, sonst
- d0<>0. Hinweis: Achten Sie darauf, daß im Fehlerfall alle
- allocierten Ressourcen (Memory, Locks, ...) wieder
- freigegeben werden, da dann keine weiteren Playerfunktionen
- mehr angesprungen werden.
-
- DTP_Interrupt (FPTR) - Pointer auf eine Interruptroutine, die mittels
- eines Timerinterrupts standardmäßig alle 1/50 sec
- aufgerufen wird. Dies ist die Standardmethode, um mit der
- richtigen Abspielgeschwindigkeit im PAL/NTSC/Productivity
- Videomodus zu spielen. Wenn keine DTP_Faster/DTP_Slower
- Tags angegeben sind, übernimmt DeliTracker dies durch
- Verändern der Interruptfrequenz. Dieser Tag kann auch nicht
- existieren, dann müssen aber DTP_StartInt/DTP_StopInt
- vorhanden sein !
-
- DTP_Stop (FPTR) - Pointer auf eine optionale Stoproutine. Wenn dieser Tag
- nicht vorhanden ist, verfährt DeliTracker folgendermaßen:
- Interrupt stoppen (DTP_StopInt)
- Sound Cleanup (DTP_EndSnd)
- Song initialisieren (DTP_InitSnd)
- Ansonsten hat diese Routine die Aufgabe, einen evtl.
- spielenden Song anzuhalten und so zu initialisieren, daß
- dieser beim nächsten Starten des Interrupts von Anfang an
- zu spielen beginnt.
-
- DTP_Config (FPTR) - Pointer auf eine optionale Initialisierungsroutine.
- Diese wird nur einmal unmittelbar nach dem Laden des
- Players aufgerufen. Mögliche Anwendungen: Laden einer
- playerspezifischen Konfigurationsdatei. Ist kein Fehler
- aufgetreten, muss d0=0 zurückgegeben werden, sonst
- d0<>0. Hinweis: Im Fehlerfall wird der Player von
- DeliTracker wieder entfernt!
-
- DTP_UserConfig (FPTR) - Pointer auf eine optionale Initialisierungs-
- routine. Diese wird nur dann aufgerufen, wenn der User den
- Player im Setupfenster anwählt und das 'Config' Gadget
- drückt. Mögliche Anwendungen: Öffnen eines Fensters zum
- Setzen weiterer Optionen wie z.B. Instrumentenpfad und
- Abspeichern einer playerspezifischen Konfigurationsdatei.
-
- DTP_SubSongRange (FPTR) - Überholt, bitte DTP_NewSubSongRange benützen!
- Dieser Tag sollte angegeben werden, wenn der Player
- MultiModule unterstützt. ti_Data zeigt dabei auf eine
- Routine, die als Returnwert in d0 die minimale und
- in d1 die maximale Subsongnummer zurückgeben muß.
- Hinweis: Wenn möglich sollte dieser Tag (evtl. zusammen
- mit DTP_SubSongTest) anstelle von DTP_NextSong/DTP_PrevSong
- verwendet werden.
-
- DTP_InitPlayer (FPTR) - Pointer auf eine optionale Initialsierungs-
- routine, die aufgerufen wird, wenn ein Modul erfolgreich
- geladen wurde. Tritt kein Fehler auf, liefert sie d0=0,
- ansonsten d0<>0. Hier muß die Allocation der Audiokanäle
- stattfinden! (DeliTracker stellt dafür eine eigene Routine
- zur Verfügung) Falls der Player Multi-Module unterstützt,
- muß hier dtg_SndNum(a5) auf die erste Subsongnummer gesetzt
- werden. Falls eine Routine für DTP_SubSongRange existiert,
- macht DeliTracker das automatisch (d.h. die Initialisierung
- von dtg_SndNum(a5) kann weggelassen werden).
-
- DTP_EndPlayer (FPTR) - Pointer auf eine optionale Cleanuproutine, die
- aufgerufen wird, wenn das Modul aus dem Speicher entfernt
- wird. Hier muß die Freigabe der Audiokanäle stattfinden!
- (DeliTracker stellt dafür eine eigene Routine zur
- Verfügung)
-
- DTP_InitSound (FPTR) - Pointer auf eine optionale Initialsierungsroutine.
- Diese muß das Modul initialisieren, so daß beim Starten des
- Interrupts der Song von Anfang an zu spielen beginnt.
-
- DTP_EndSound (FPTR) - Pointer auf eine optionale Cleanuproutine. Diese
- kann z.B. die Lautstärkeregister und die Audio-DMA
- rücksetzen.
-
- DTP_StartInt (FPTR) - Pointer auf eine Initialsierungsroutine, die
- existieren muß, wenn DTP_Interrupt nicht vorhanden ist.
- In diesem Fall muß hier der Sound gestartet werden.
-
- DTP_StopInt (FPTR) - Pointer auf eine Cleanuproutine, die existieren muß,
- wenn DTP_Interrupt nicht vorhanden ist. In diesem Fall muß
- hier der Sound gestoppt werden.
-
- DTP_Volume (FPTR) - Pointer auf eine Funktion, welche die Lautstärke neu
- setzt. Die Funktion wird aufgerufen, wenn die Volume neu
- gesetzt wird (Slider, ARexx) und beim Initialisieren des
- Moduls vor DTP_InitSnd. Die Mastervolume steht in
- dtg_SndVol(a5). Die Mastervolume ist dabei der maximale
- Volumewert. Die effektive Volume errechnet sich also
- durch: VOL_eff = (( dtg_Volume(a5) * modulevolume )>>6)
- Näheres siehe Beispielsourcen.
-
- DTP_Balance (FPTR) - Pointer auf eine Funktion, welche die Balance neu
- setzt. Die Funktion wird aufgerufen, wenn die Balance neu
- gesetzt wird (Slider, ARexx) und beim Initialisieren des
- Moduls vor DTP_InitSnd. Die Balance für die linken Kanäle
- steht in dtg_SndLBal(a5), für die rechten Kanäle in
- dtg_SndRBal(a5). Hinweis: Alle Player die Balance unterstützen
- können auch Volume! Man verwendet dann die gleiche Routine
- zum Setzen der Volume&Balance. Die linke Volume errechnet
- sich wie folgt: (( dtg_Volume(a5) * dtg_SndLBal(a5) )>>6)
- Entsprechendes gilt für rechts.
-
- DTP_Faster (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
- beschleunigt.
-
- DTP_Slower (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
- verlangsamt.
-
- DTP_NextPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
- um eins erhöht.
-
- DTP_PrevPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
- um eins erniedrigt.
-
- DTP_NextSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
- den nächsten Subsong setzt und diesen spielt.
- (Falls vorhanden)
-
- DTP_PrevSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
- den vorhergehenden Subsong setzt und diesen spielt.
- (Falls vorhanden)
-
- ;--- tags in revision 14 or higher (distributed as Release 1.35) ---
-
- DTP_SubSongTest (FPTR) - Dieser Tag wird nur ausgewertet, wenn schon der
- Tag DTP_SubSongRange angegeben wurde. ti_Data zeigt dabei
- auf eine Routine, die als Returnwert in d0 einen Boolschen
- Wert zurückliefert. Dieser gibt an, ob der SubSong mit
- Nummer dtg_SndNum(a5) gültig ist (d0=0) oder nicht (d0<>0).
- Dieser Tag ist nur bei den Playern nötig, bei denen nicht
- jeder SubSong (innerhalb der durch DTP_SubSongRange
- festgelegten Grenzen) benutzt ist.
-
- ;--- tags in revision 16 or higher (distributed as Release 2.01) ---
-
- DTP_NewSubSongRange (APTR) - erweiterter Ersatz für DTP_SubSongRange.
- Dieser Tag sollte angegeben werden, wenn der Player
- MultiModule unterstützt. ti_Data zeigt dabei auf ein
- Array mit drei WORDs: Das erste Word enthält die Nummer
- des Subsongs, der als erstes gespielt werden soll. Das
- zweite enthält die minimale und das dritte die maximale
- Subsong Nummer. In den meisten Fällen ist das erste und
- das zweite WORD identisch.
-
- DTP_DeliBase (APTR) - die Adresse eines Pointers, wo DeliTracker einen
- Pointer auf die DeliGlobals ablegt.
-
- DTP_Flags (ULONG) - enthält verschiedene Flags.
- Derzeit sind folgende Flags definiert:
- PLYF_CUSTOM - der Player ist ein Customplayer
- PLYF_SONGEND - dieser Player unterstützt Songend
- PLYF_ANYMEM - die Moduldaten dieses Players brauchen
- nicht im ChipMem abgelegt werden.
-
- DTP_CheckLen (ULONG) - Länge des Check Codes. Dieser Tag darf nur benutzt
- werden, wenn der Checkcode PC-relativ und reentrant ist!
- Wenn der Tag benutzt wird, lagert DeliTracker den Player in
- LowMem-Situationen aus. Bei Playern, die als Process laufen,
- ist dieser Tag ohne Wirkung.
-
- DTP_Description (APTR) - Pointer auf einen String mit einer Beschreibung,
- was der Player bzw. das Genie tut und welche besonderen
- Fähigkeiten es hat. Dieser String kann $A als Zeilenumbruch
- enthalten.
-
- DTP_Decrunch (FPTR) - private, still under development!
-
- DTP_Convert (FPTR) - Pointer auf eine Routine zum Konvertieren eines
- Moduls. Diese Routine wird aufgerufen, wenn das Modul
- geladen und ggf. entpackt ist. Sie dient dazu, das Modul
- in ein neues Format umzukonvertieren. Die Konvertier-
- Routine funktioniert üblicherweise folgendermassen:
- 1) Ausgangs-Format erkennen
- 2) Speicher für Ziel-Format mit dtg_AllocListData()
- belegen
- 3) Das Modul vom Ausgangsformat ins Zielformat
- konvertieren
- Diese Routine muß NULL zurückliefern, wenn das Modul
- erfolgreich konvertiert wurde (success), ansonsten -1
- (error). Auf gar keinen Fall darf das Ausgangs-Modul von
- der Konvertier-Funktion verändert werden!
- Bemerkung: für temporäre Speicher-Allocationen sollte man
- die entsprechenden Exec-Funktionen benutzen, der Speicher
- für das Ziel-Modul muß aber in jedem Fall mit der Support
- Funktion dtg_AllocListData() belegt werden!
-
- DTP_NotePlayer (APTR) - private, still under development!
-
- DTP_NoteStruct (APTR) - private, still under development!
-
- DTP_NoteInfo (APTR) - private, still under development!
-
- DTP_NoteSignal (FPTR) - private, still under development!
-
- DTP_Process (FPTR) - Pointer auf einen Code, der als Prozess gestartet
- werden soll. Wenn dieser Tag verwendet wird, startet
- DeliTracker den Player bzw. das Genie als eigenen Prozess.
-
- DTP_Priority (BYTE) - Priorität des zu startenden Prozesses. Nur in
- Verbindung mit DTP_Process sinnvoll. Wenn dieser Tag nicht
- angegeben wird, wird der Prozess mit der gleichen Prioriät
- wie DeliTracker gestartet.
-
- DTP_StackSize (ULONG) - Stack-Größe des zu startenden Prozesses. Nur in
- Verbindung mit DTP_Process sinnvoll. Wenn dieser Tag nicht
- angegeben wird, wird die Stackgröße auf 4096 Bytes gesetzt.
-
- DTP_MsgPort (APTR) - Adresse eines Pointer, wo DeliTracker die Adresse
- des Ports ablegt, an den dann die Messages geschickt
- werden. Nur in Verbindung mit DTP_Process sinnvoll.
-
- DTP_Appear (FPTR) - Pointer auf eine Routine die die GUI des Players bzw.
- Genies öffnet/aktiviert. Als Returnwert muß der alte
- Windowzustand (<>0 wenn das Fenster auf war, ansonsten 0)
- zurückgeliefert werden. Bemerkung: Stellen Sie sicher, daß
- die GUI auf dem richtigen Screen geöffnet wird! (benützen
- Sie dazu die dtg_LockPubScreen() und dtg_UnLockPubScreen()
- Funktionen).
-
- DTP_Disappear (FPTR) - Pointer auf eine Routine, die die GUI schliesst.
- Diese Routine muss den alten Windowzustand (<>0 wenn das
- Fenster auf war, ansonsten 0) zurückgeliefern.
-
- DTP_ModuleName (APTR) - Adresse eines Pointers, der auf den tatsächlichen
- Namen des Moduls zeigt (dieser String muß mit NULL
- abgeschlossen sein). Dieser Tag ist nur für Player sinnvoll
- und wird nach InitPlay() ausgewertet.
-
- DTP_FormatName (APTR) - Adresse eines Pointers, der auf den Namen des
- urspünglichen Modulformats zeigt (dieser String muß mit
- NULL abgeschlossen sein). Dieser Tag ist nur für Genies
- sinnvoll und wird nach der Convert() Funktion ausgewertet.
-
- DTP_AuthorName (APTR) - not implemented yet!
-
- ;--- tags in revision 17 or higher (distributed as Release 2.07) ---
-
- DTP_InitNote (FPTR) - private, still under development!
-
- DTP_PlayTime (APTR) - not implemented yet!
-
-
-
- 5.DELITRACKER SUPPORT FUNKTIONEN
-
- DeliTracker stellt zur Erleichterung der Playeranpassung einige
- Funktionen zur Verfügung. Eine Funktion wird wie folgt aufgerufen:
-
- move.l dtg_XXX(a5),a0
- jsr (a0)
-
- Alle folgenden Funktionen außer dtg_SongEnd, dtg_SetTimer und
- dtp_NotePlayer verwenden d0/d1/a0/a1 als Scratchregister. In a5 muß bei
- allen Aufrufen (außer bei dtg_SongEnd, dtg_SetTimer und dtp_NotePlayer)
- der Pointer auf die Base stehen. Derzeit existieren folgende Funktionen:
-
- dtg_GetListData
-
- SYNOPSIS
- memory size = dtg_GetListData(number)
- A0 D0 D0.l
-
- FUNCTION
- Liefert Adresse und Länge eines mit LoadFile() geladenen
- Files.
-
- INPUTS
- number - Nummer eines Files beginnend mit 0 für das vom
- User selektierte File.
-
- RESULT
- memory - ein Pointer auf die Startadresse des Files im
- Speicher oder NULL im Fehlerfall.
- size - Länge des Files in Bytes bzw. 0 im Fehlerfall.
-
-
- dtg_LoadFile
-
- SYNOPSIS
- success = dtg_LoadFile(name)
-
- FUNCTION
- Lädt und entpackt ggf. das angegebene File ins Chip-
- Memory. (Hinweis: diese Funktion ergänzt automatisch,
- falls das File mit dem angegebenen Namen nicht geöffnet
- werden konnte '.pp','.im' und '.xpk')
-
- INPUTS
- name - der Filename steht in einem internen Buffer (seine
- Adresse steht in dtg_PathArray)
-
- RESULT
- success - alles ok d0.l=0, sonst d0.l<>0.
-
-
- dtg_CopyDir
-
- SYNOPSIS
- dtg_CopyDir()
-
- FUNCTION
- Kopiert das Directory des von User angewählten Files an das
- Ende des Strings, auf den dtg_PathArray(a5) zeigt.
-
-
- dtg_CopyFile
-
- SYNOPSIS
- dtg_CopyFile()
-
- FUNCTION
- Kopiert den Filenamen des von User angewählten Files an das
- Ende des Strings, auf den dtg_PathArray(a5) zeigt.
-
-
- dtg_CopyString
-
- SYNOPSIS
- dtg_CopyString(string)
- A0
-
- FUNCTION
- Kopiert den String, auf den das Register a0 zeigt, an das
- Ende des Strings, auf den dtg_PathArray(a5) zeigt.
-
- INPUTS
- string - der Pointer auf den anzuhängenden String steht
- in a0
-
-
- dtg_AudioAlloc
-
- SYNOPSIS
- success = dtg_AudioAlloc()
-
- FUNCTION
- Belegt alle Audiokanäle.
-
- RESULT
- success - alles ok d0.l=0, sonst d0.l<>0.
-
-
- dtg_AudioFree
-
- SYNOPSIS
- dtg_AudioFree()
-
- FUNCTION
- Gibt die mit dtg_AudioAlloc belegten Audiokanäle wieder
- frei.
-
-
- dtg_StartInt
-
- SYNOPSIS
- dtg_StartInt()
-
- FUNCTION
- Startet den Soundinterrupt. (Falls er nicht schon läuft.)
- Falls DTP_Interrupt existiert, startet DeliTracker einen
- Timerinterrupt, ansonsten wird DTP_StartInt aufgerufen.
-
-
- dtg_StopInt
-
- SYNOPSIS
- dtg_StopInt()
-
- FUNCTION
- Stoppt den Soundinterrupt. (Falls er nicht schon angehalten
- ist.) Falls DTP_Interrupt existiert, stoppt DeliTracker
- seinen Timerinterrupt, ansonsten wird DTP_StopInt
- aufgerufen.
-
-
- dtg_SongEnd
-
- SYNOPSIS
- dtg_SongEnd()
-
- FUNCTION
- Signalisiert DeliTracker, daß das Modul einmal komplett
- gespielt wurde. Diese Funktion verändert keine Register
- und darf auch von Interrupts aufgerufen werden.
-
-
- dtg_CutSuffix
-
- SYNOPSIS
- dtg_CutSuffix()
-
- FUNCTION
- Entfernt am Ende des Strings, auf den dtg_PathArray(a5)
- zeigt ggf. die Endung '.pp', '.im' oder '.xpk'
-
-
- ;------ extensions in revision 14 (distributed as Release 1.34)
-
- dtg_SetTimer
-
- SYNOPSIS
- dtg_SetTimer()
-
- FUNCTION
- Programmiert den CIA-Timer mit dem Wert, der sich in
- dtg_Timer(a5) befindet. Diese Funktion verändert keine
- Register und darf auch von Interrupts aufgerufen werden.
-
-
- ;------ extensions in revision 15 (distributed as Release 1.37)
-
- dtg_WaitAudioDMA
-
- SYNOPSIS
- dtg_WaitAudioDMA()
-
- FUNCTION
- Diese Funktion wartet eine bestimmte Zeit lang. Die
- Zeitspanne sollte für die Audio Hardware normalerweise
- groß genug sein, um neue Werte zu laden. Dieser Aufruf ist
- nur erlaubt, wenn der interne Timer-Interrupt benutzt wird.
- Er kann anstelle der üblichen dbra oder Rasterline
- Warteschleifen benutzt werden. Diese Funktion verändert
- keine Register.
-
- BUGS
- Wenn der Player auch Periods unterstützt, die viel größer
- als 1000 sind, wird evtl. nicht lange genug gewartet.
-
-
- ;------ extensions in revision 16 (distributed as release 2.01)
-
- dtg_LockScreen
-
- SYNOPSIS
- screen = dtg_LockScreen()
- D0
-
- FUNCTION
- Lockt den Screen auf dem DeliTracker läuft (ist immer
- ein Pubscreen).
-
- RESULT
- Pointer auf den Screen in d0 oder NULL im Fehlerfall.
-
-
- dtg_UnlockScreen
-
- SYNOPSIS
- dtg_UnlockScreen()
-
- FUNCTION
- Diese Function unlockt den Screen, auf dem DeliTracker
- läuft. Hinweis: diese Funktion keinesfalls öfters aufrufen
- als dtg_LockScreen()!).
-
-
- dtg_NotePlayer
-
- SYNOPSIS
- dtg_NotePlayer()
-
-
- FUNCTION
- Dieser Aufruf spielt die Noten, die in der aktuellen
- NoteStruct Struktur angegeben sind. Die Funktion darf
- nicht aufgerufen werden, wenn der aktive Player keine
- NotePlayer Structur hat.
- Hinweis: Dieser Aufruf sichert alle Register und darf
- sogar von Interrupts aufgerufen werden, solange das
- Interrupt Level 4 oder kleiner ist.
-
- INPUTS
- aktuelle NoteStruct.
-
-
- dtg_AllocListData
-
- SYNOPSIS
- memory = dtg_AllocListData(byteSize,Flags)
- D0 D0.l D1.l
-
-
- FUNCTION
- Dies ist die Funktion, um Modul-spezifischen Speicher von
- Playern oder Genies aus zu belegen. Es gibt die Möglichkeit
- anzugeben, ob die Allocation im Chipmem oder Publicmem
- gemacht werden soll. Wenn die Allocation erfolgreich war,
- merkt DeliTracker sich den Memblock und man kann mit der
- Funktion dtg_GetListData() die Adresse und die Größe des
- Blocks erfahren.
-
-
- INPUTS
- byteSize - Größe des gewünschten Blocks in Bytes.
-
- Flags - die Flags werden an AllocMem() weitergereicht.
-
- RESULT
- Ein Pointer auf den allocierten Memoryblock wird in d0
- zurückgeliefert. Wenn nicht genug freier Speicher vorhanden
- ist, um die Anforderung zu erfüllen, wird Null
- zurückgegeben. Der Pointer muß auf jeden Fall getestet
- werden und darf nur benutzt werden, wenn er ungleich Null
- ist.
-
-
- dtg_FreeListData
-
- SYNOPSIS
- dtg_FreeListData(memoryBlock)
- A1
-
- FUNCTION
- Gibt einen Speicherblock frei, der mit AllocListData(),
- allociert wurde.
-
- INPUTS
- memoryBlock - Pointer auf den Speicherblock, darf auch
- NULL sein.
-
-