zatzen hat geschrieben:Ich muss gestehen dass die von dir beschriebenen Vorgehensweisen für mich noch etwas hoch sind -
mein letztes ernsthaftes Spiel war ja nur Kotzman II, und da hatte ich in den Leveln selbst keine
Musik und schon gar keine Sample-Musik, sondern nur Rechenzeit-freie AdLib-Effekte.
Naja, ich sage es mal so: Wir haben alle mal irgendwann angefangen zu programmieren.
Als ich meine ersten Spiele (in BASIC auf KC85 Rechnern) gebaut habe, habe ich die Steuerung der Figuren alle mit IF-Kaskaden gemacht und die Steuerung der Spielfigur wurde von getrennten, anderen Teilen realisiert als der Rest.
Inzwischen wird das alles eher generalisierter gemacht - aber da mußte ich auch erstmal drauf kommen.
Wenn man etwas gutes gemacht hat und es funktioniert, fragt man sich immer: "Das ist so einfach - wieso bin ich da nicht früher drauf gekommen?" Aber es ist eigentlich der gleiche Effekt wie bei Erfindungen von anderen: Sind die Erfindungen erstmal gemacht, denkt man: "Eigentlich logisch, hätte jeder drauf kommen können - sogar ich." Ist man aber nicht.
Wenn man daran denkt, daß Konrad Zuse 1939 das Patent für seinen Computer (der noch nicht mal Computer hieß) angemeldet hatte - und das Ding war quasi mechanisch... und heute schon irgendwelche Kids in einen Laden gehen und sich ein Wischhändi kaufen können, das eine Leistung und Speicher hat, für die man vor 50 Jahren einen Flugzeughangar voll Elektronik hätte stopfen müssen und selbst dann wäre das Ding nicht annähernd so schnell gewesen... - na egal.
zatzen hat geschrieben:Auch die Grafik funktionierte ohne jegliches Puffern, jedes Sprite hatte einen schwarzen Rahmen
um sich herum um sich selbst wieder wegzu"radieren".
Ja, ich weiß. Du erwähntest mal dergleichen.
Auf C64 konnte man sich ja auf die Hardware-Sprites verlassen - da mußte man keinen "Hintergrund löschen". Aber es gab von diesen Sprites nur 8 und die Größe war festgelegt. Mit Tricks (die aber wieder Rechenzeit/-leistung brauchten) konnte man hier die Sprites vervielfältigen. Außerdem hat man für kleinere Objekte (Projektile) ja wieder "Zeichen" benutzt, für die man natürlich wieder den Hintergrund sichern mußte. (Fast alle C64-Spiele sind in Textmode - aber die Textmodi des C64 sind etwas Besonderes. Die kann man auch auf "Multicolor" umschalten und die Zeichenmatrizen natürlich beliebig ändern. Und die Softscroll-Register für vertikal/horizontal sind ja auch sehr nützlich.)
Auf PC habe ich auch mit Textmode-Spielen angefangen (ich konnte zuerst nichts anderes). Aber bei PC-Grafikkarten hat man keinen Rasterzeilen-IRQ (fast nie) und der Multicolor-Mode, den die ETx000 Reihe hat, ist nicht überall gegeben. (Auf diese ganzen Sachen bin ich viel später gestoßen, als ich mich etwas tiefer mit VGA-Registern beschäftigt hatte.)
Sobald ich aber auf PC "Grafikmode" konnte, war für mich klar, daß ich ebenfalls eine "Umgebung" brauche, in der ich "freibewegliche" Sprites habe und "gekachelte" Levels. Also habe ich Zeug zusammengebaut, das genau das hat. Anders würde ich gar nicht mehr anfangen wollen, Spiele zu bauen. Und ja - ich hatte mich auch für einige Jahre in die Untiefen der 3D-Programmierung gestürzt, kann inzwischen auch so DOOM[tm]-artige Levels darstellen/durchlaufen und könnte somit auch ein 3D-Spiel schreiben (wenn ich die Zeit finden würde, Levels, Texturen, Figuren... Sounds... usw. zu kreieren).
Aber ich schaffe es ja seit Monaten (Jahren) nicht einmal, meine geplanten 2D-Spiele zu machen - obwohl ich quasi inzwischen so ziemlich alles dafür da habe, was ich brauche! Alles ist immer so zu 95% fertig, könnte aber schon verwendet werden. Aber 95% ist eben nicht 100% und ich will es immer "richtig machen". Geplant sind ein Raumschiff-Shooter (Shoot'em'up) und ein Jump'n'run-Arcade. Die Ideen dafür sind schon 13 Jahre (Jump'n'run) und 20 Jahre (Shoot'em'up, damals noch als Textmode geplant!) alt! Und vor 13 Jahren hätte das vielleicht noch irgendwen interessiert, da die Spiele auch unter MS-Windows noch lauffähig gewesen wären. Heutzutage sind es nicht so sehr die wirklichen SPIELER, sondern eher alte DOS-Enthusiasten, die sich Dinge wie "DOSbox" antun, um dann so alten Kram zu spielen. Aber selbst diese spielen wohl eher den richtigen alten Kram, d.h. das Zeug was wirklich "von damals" ist - als vielleicht ein neues Spiel (von 2016), das nur mit den Techniken "von damals" gemacht wurde und auch 1991 hätte programmiert werden können.
Und die jüngere Generation ist eher dem Modus, den mein Kumpel immer "Instant Gratification" nennt: Alles muß immer gleich und sofort und ohne die geringste Mühe und Anstrengung funktionieren. Ein Gerät, wo man nur über den Bildschirm tippen und wischen muß ohne über irgendetwas nachzudenken ist quasi die "plastikgewordene Manifestation" dieser Lebensart. (Endlich hatte Apple das geschafft, was sie schon jahrzehntelang wollten: User sollen überhaupt nicht nachdenken müssen. Das "Es gibt nur einen einzigen Button"-Gerät ist Wirklichkeit.)
Und auch wenn diese Leute vielleicht auch auf diesen "Retro-Zug" aufgesprungen sind und gern Spiele "wie damals" (Jump'n'run ö.ä.) spielen wollen - so etwas Anstrengendes wie sich einen Emulator herunterzuladen und sogar selbst EINRICHTEN zu müssen, würden sie dafür nie auf sich nehmen. Das grenzt ja an Nachdenken oder gar Arbeit! Man könnte blöderweise ja etwas dabei lernen! Am Ende sogar ein klein wenig mehr wissen als absolut überlebensnotwendig! So etwas kann man denen nicht antun! Wo es doch schließlich auch Retro-Jump'n'runs auf "gar-nicht-so-retro" Systemen gibt!
Und wenn diese angeblichen "Retro-Fans" mal ein Spiel oder Tool sehen, das nicht nur "wie retro" ist (aber 3D und mit 16 Mio. Farben angestrichen), sondern ein RICHTIGES Spiel von damals sehen:
- mit 256 Farben, 16 Farben, 4 Farben, 2 Farben
- mit Sound, der 4-stimmig, 3-stimmig, sogar 1-stimmig oder gar nicht vorhanden ist
- mit einen repetativen Spielprinzip, aber wirklich schweren Levels
dann können sie meist gar nicht glauben, daß es so etwas wirklich einmal gegeben hat und daß es Leute vor den Bildschirm gefesselt hat. Das ist so wie jemand, der Mittelalter-Märkte und Mittelalter-Filme und dergleichen mag... - würde der wohl versehentlich ins wirkliche Mittelalter fallen, wäre er wohl schnellstens auf der Suche nach einer Spitzhacke - um nach neuem Plutonium für seinen DeLorean zu graben...
zatzen hat geschrieben:Grafik vor Hintergrund und die damit nötig werdende Pufferung, sowie Musik und Soundeffekte
parallel dazu sind für mich also eine neue Sache.
Naja, auf dem PC bleiben einem nicht gerade viele Möglichkeiten. Selbst wenn die eigene Grafikkarte eventuell manche Effekte beherrscht, die man gut gebrauchen könnte, so ist und war der PC doch immer ein Elektronikpuzzle, bei dem man, vor allem, was Spieleentwicklung angeht, immer am besten gefahren, wenn man hier vom "kleinsten gemeinsamen Teiler" ausgeht und erst einmal quasi nur eine "Standard-Spielkiste" voraussetzt.
Seit es Multitasking und Systeme wie Windows gibt, hat man dieses Problem kompensiert, indem man softwareseitige Treiber liefert, damit sich Hardware an keinerlei Standards mehr halten müssen.
Auf einer DOS-Kiste (zumindest, wenn es eine ist, die zum Spielen gedacht ist), kann man (meines Erachtens) inzwischen davon ausgehen, daß mindestens eine VGA-Karte, sowie irgend etwas Soundblaster 2.0-kompatibles drinsteckt (und Tastatur und vielleicht 2-Tasten-Maus). Alles andere ist schon optional und Luxus.
ICH werde damit bei meiner Art zu programmieren schon größere Probleme haben:
1.) Meine größeren Spielprojekte erfordern alle schon mind. 386er (wegen Nutzung der 32bit-Register und Segmentregister FS/GS).
2.) Eine reine ISA-VGA ist VIEL ZU LANGSAM für erträgliches Vollbild-Scrolling bei quasi komplettem Bildaufbau für jedes Frame. Erklärung: Hatte mal eine reine VGA. Im schnellsten Modus (320x200) hatte sie einen Datendurchsatz von ca. 0,5 bis 0,6 MB/sek. Was bedeutet das? Naja. Geht man mal davon aus, daß man eine recht großzügige "Anzeige" ins Bild baut, die sich nicht immer ändert und man nutzt nur ca. 60000 statt der 64000 Pixel bei 320x200 (ist jetzt einfacher für das Rechenbeispiel) dann schafft man genau 10 FPS. Da kann die CPU noch so schnell sein! Diese 10 FPS erreicht man nicht einmal ganz, weil außer dem "Schaufeln der Pixel zur Grafikkarte" ja während der Spielschleife auch noch andere Dinge passieren müssen.
Und ja: Eine langsame Grafikkarte bremst die CPU herunter bei jedem Lese-/Schreibzugriff. Wieso? Nun ja, wenn man etwas an eine Speicherstelle schreibt, "wartet" die CPU, bis das auch wirklich passiert ist.
Will sagen: Das was ich mache und in Xpyderz gemacht habe, erfordert eine Grafikkarte mit wesentlich mehr Power als eine normale VGA. Der Datendurchsatz ist ja nicht unbedingt die "Schuld" der VGA - aber so ein ISA-Port hat eben seine Grenzen...
zatzen hat geschrieben:So werde ich ersteinmal versuchen, die Rechenanforderung für ein Spiel so gering zu halten,
dass es auf 486er Maschinen quasi monolithisch funktioniert, ohne dynamische Verwaltung
von Grafik und Ton, auch wenn man dabei mögliche Performance verschenkt.
Ich verstehe nicht so ganz was Du damit meinst. Was ist die Alternative?
Ich meine: Damit in einem Spiel alles "gleichzeitig aussieht" muß ja immer im Wechsel Grafik und Ton erzeugt werden und auch die Usereingaben sollten ja zyklisch erfolgen, damit ein Spielfluß gegeben ist.
Wie hattest Du es denn in Kotzman II gelöst?
zatzen hat geschrieben:Wie gesagt, für mich ist das etwas neues und ich freue mich ersteinmal darauf, überhaupt
ein nettes kleines Spiel zu haben mit Hintergrundmusik, Soundeffekten und Grafik mit Transparenz.
Naja, das ist ja das, was wir ALLE wollen. Mir geht es ja prinzipiell auch um nichts anderes.
zatzen hat geschrieben:Auch freue ich mich, dass ich Assembler schon etwas besser beherrsche und mich damit
freier bewegen kann als früher.
Ja, es ist irgendwie ein befriedigendes/befreiendes Gefühl, wenn man irgendwann den Eindruck hat, daß man Ahnung hat von dem, was man tut. Ich kann mich auch noch an die schwierigen Anfänge erinnern - auch in BASIC, später dann in Pascal und dann auch in Assembler (bzw verschiedenen Assemblern): Zu Anfang war es oft ein haarsträubendes und zermürbendes "Ausprobieren". Ich muß zugeben, daß es Zeiten gab, wo mir eine bestimmte Formel für etwas einfach nicht einfallen wollte und dann habe ich so lange "an den Werten gedreht", bis es gepaßt hat. Aber es ist kein gutes Gefühl, wenn irgendwas "irgendwie funktioniert" und man selbst nicht nachvollziehen kann, wieso (bzw was man da angestellt hat). Ich kann es irgendwie nicht leiden, Codebereiche in meinem Programmcode zu haben, die "irgendwie gehen" und "Hauptsache nicht anfassen, damit es nicht auseinanderfällt" - aber muß leider sagen, daß es frühere Projekte von mir gibt, wo ich bestimmte Codeblöcke nie wieder anfassen will.
zatzen hat geschrieben:Auch von Vertical Retrace habe ich viel gehört über die Jahre, und klar kann es nervig sein
wenn das Bild schwabbelt, aber das lasse ich erstmal auf mich zukommen.
Naja, ruckelfreies Scrolling ist zwar schön - aber es ist auch schön, wenn es schon überhaupt erstmal scrollt.
Beim PC kann man sich ja nicht unbedingt auf eine einheitliche Wiederholfrequenz des Grafikaufbaus verlassen,
die 70Hz, die der MCGA (der beliebte Mode 13h, 320x200x256) hat, gelten für einen CRT. Auf TFT von Laptops
war der auf 60Hz eingestellt, wie jeder andere Mode. Ich weiß, daß man bei Turrican II für PC (DOS) die
Bildfrequenz sogar EINSTELLEN kann (zwischen 50 und 60 Hz in 1 Hz Schritten).
Aber weiß nicht, ob das auf allen Grafikkarten (auch neueren) noch funktionieren würde oder ob es da z.B.
bei TFT-Bildschirmen sowieso nicht geht...
Fakt ist, daß ich mich inzwischen nicht mehr auf die Bildwiederholfrequenz bei PCs verlasse, sondern das Bild
einfach refreshe, sobald Rechenleistung übrig ist und die "Spielfrequenz" noch nicht erreicht ist (man braucht
nicht 300x pro Sekunde das Bild refreshen, wenn das Spiel nur mit 50 Ticks/sek läuft).
Außerdem ist Scrolling ja an die Bewegung der Spielfigur gebunden (oder beim Raumschiffshooter automatisch
und gleichbleibend). Aber: Scrolling ist nur dann exakt ruckelfrei, wenn es genau synchron zur Bildwiederholfrequenz
des Monitors stattfindet UND nur dann flackerfrei, wenn das Umschalten zur neuen Seite in der Austastlücke (also in oder kurz nach dem Vertical Retrace, also dem Rücklauf des Rasterstrahls von rechts unten nach links oben) erfolgt.
Da der Vertical Retrace nur auf sehr wenigen Grafikkarten einen IRQ erzeugt (man sich darauf also nicht verlassen kann),
das WARTEN auf den VR aber wieder wertvolle Rechenzeit verschwendet, nutze ich das nur, wenn die Messungen ergeben,
daß die Maschine schnell genug ist und selbst dann nur zum Vermeiden des Flackerns, nicht für weiches Scrolling.
Der Grund dafür ist, daß sonst die Scrollgeschwindigkeit (und damit die Spielgeschwindigkeit!) von der eingestellten
Bildwiederholrate des Grafikmodes abhängig wäre - und das kommt für mich nicht in Frage. Somit wird Scrolling auf
meinen PC-Spielen also immer irgendwie ruckeln.
Wie man auch leicht erkennen wird, ist ein 486er selbst mit PCI-Grafikkarte "gerade mal so" in der Lage, 70 Bilder pro
Sekunde zu berechnen - eine gescheite Berechnungsroutine (in Assembler!) vorausgesetzt.
Meine Routinen schaffen die gekachelten Levels (mit 16x16-Pixel Kacheln) im 1-Ebenen-Mode GERADE MAL SO ruckelfrei zu scrollen auf meinem 486er (X5, mit 133 MHz) mit PCI-Grafikarte (mit ca. 16 MB/sek Datendurchsatz). Und auch nur, wenn ich nicht zu viele Sprites anzeige. (Ich generiere die Grafik immer gleich in die Grafikkarte hinein, ohne Zwischenpuffer im RAM.)
Mein Mehrebenen-Mode (also wo ich mehrere Levelebenen transparent hintereinander unterschiedlich scrollen lassen kann) bringt das Ganze schon an seine Grenzen und darüber hinaus. Da hat mein 486er keine vollen FPS mehr - und mein 486er ist eine wahre Mördermaschine, das Motherboard ist das schnellste das ich je erlebt habe, die CPU ist eine 486 X5 (d.h. es ist ein 486er, der schon intern mit Pentium-Technologien gefertigt ist, aber in einen 486er-Slot paßt) und die Grafikkarte ist eben PCI - und Sound macht eine SB AWE 64. Das ist aber schon lange keine "Standard DOS-Kiste" mehr - für so etwas hätte man damals[tm] und früher(C) sicher mal so eben 5000 DM auf den Tresen gelegt - so etwas hätte damals wohl keiner für ein Spiel wie mein Xpyderz getan (d.h. diese Aufrüstung) - selbst wenn er das Geld gehabt hätte.
Leute im DOSforum haben mir ja schon mitgeteilt, daß Xpyderz auf einem 386er mit VGA (was ja die Mindestanforderung dafür ist) quasi fast unspielbar in den FPS runtergeht - selbst im LowRes Modus. Tja - was soll ich dazu sagen? Ich bin eben einfach noch zu schlecht.
Ich optimiere inzwischen aber eher auf "irgendwie einen mittleren Standard erreichen". Weil ich leider alleine entwickle, muß ich irgendwann mal einen "Baukasten aus Routinen" haben (so wie ich ihn habe), aus dem ich ein Spiel zusammenbauen kann. Und meine Level-/Sprite-Routinen sind an sich recht brauchbar, um ein Spiel damit zu bauen. Die könnte ich natürlich auch immer noch weiter und weiter optimieren - und wenn ich damit fertig bin, gefällt mir vielleicht wieder etwas an meinen Soundroutinen oder Steuerroutinen nicht und dann fange ich da auch wieder mit Optimieren an...
Irgendwann wenn ich 70 bin, schreibe ich dann vielleicht das beste und performanteste DOS-Spiel, das die Welt je erlebt hat - und es gibt auf der ganzen Welt noch 8 Rechner, auf denen das Spiel laufen kann - und alleine 5 davon stehen dann bei mir zu Hause... (und die restlichen 3 in Museen über die Welt verteilt - ausgeschaltet, mit einem "Bitte nicht berühren" Schild davor...)
Aber vielleicht will ich ja irgendwann nochmal ein Spiel fertigmachen, das ich selber noch spielen kann - bevor Gicht, Arthritis, Alzheimer oder Tod mich am Spielen hindern.
zatzen hat geschrieben:Ich widme mich derzeit wieder ZVID.
Bisher waren die Schwächen noch:
1. Daten wurden den Decodier-Routinen mündchensmaß in einen Puffer vorkopiert, was die Performance
scmälerte. Das habe ich schon gefixt, die Daten werden jetzt direkt aus dem Stream verarbeitet.
2. Decodiert wird wiederum in einen (64 Byte) Zwischenpuffer, welcher dann erst an entsprechende Position
in den Zielpuffer kopiert wird. Da bin ich gerade dran, das zu ändern.
3. Bisher keine Sprungtabellen, sondern IF-Abfragen. So viele sind es aber nicht.
Naja, hier ist sowieso die Lösung "die Mitte". Tabellen brauchen Speicher, komplexer Code braucht Rechenzeit. Den bestmöglichen Mittelweg zu finden, halte ich für den gescheitesten Ansatz. Und hier ist der Mensch jedem Compiler überlegen: Der Mensch weiß ja, was das Programm tun soll - d.h. welche Art Daten es erwartet, welche Art Daten am häufigsten auftreten werden usw.
Ich selbst z.B. habe bei einem bedingten Sprung immer im Hinterkopf, wie oft die eine oder andere Alternative zutrifft.
Und ich springe dann bei der selteneren Alternative. Sprünge kosten Zeit (leeren den Prefetch-Queue usw.) und bei bedingten Sprüngen passiert das ja nur, wenn die Bedingung erfüllt ist. Da die 80x86 CPUs freundlicherweise für (fast) jede Bedingung auch für die umgekehrte Bedingung einen Befehl bereitstellen, kann man hier dann leicht die umgekehrte Bedingung wählen.
Beispiel: Innerhalb einer Schleife passieren manchmal Dinge und manchmal nicht.
SCHLEIFENANFANG
Irgendwas1
Irgendwas2
Ding_Passiert? - Nein? Dann springe zu @Weiter
Lasse_Ding_Passieren
@Weiter:
Irgendwas3
SCHLEIFENENDE (Wenn noch nicht beendet, gehe zu Schleifenanfang)
Also wird jedesmal, wenn das Ding passiert, der Teil Lasse_Ding_Passieren ausgeführt (Kostet Zeit). Und jedesmal, wenn es nicht passiert, wird darüber gesprungen (Kostet auch Zeit).
Nehmen wir aber an, das Ding passiert recht selten, muß aber trotzdem immer abgefragt werden. Dann ist das meines Erachtens die bessere Variante:
SCHLEIFENANFANG
Irgendwas1
Irgendwas2
Ding_Passiert? - Ja? Dann springe zu @Passieren
@Weiter:
Irgendwas3
SCHLEIFENENDE (Wenn noch nicht beendet, gehe zu Schleifenanfang)
bla....
@Passieren:
Lasse_Ding_Passieren
Springe zu @Weiter
Somit hat man zwar, wenn es passiert, ZWEI Sprünge, aber wenn es nicht passiert, gar keinen Sprung!
Noch besser ist, das Ganze (wenn es möglich ist) an das Schleifenende zu verlagern, also "Irgendwas3" mit an den Anfang - dann geht nämlich das:
SCHLEIFENANFANG
Irgendwas1
Irgendwas2
Irgendwas3
Ding_Passiert? - Ja? Dann springe zu @Passieren
SCHLEIFENENDE (Wenn noch nicht beendet, springe zu SCHLEIFENANFANG)
bla...
@Passieren:
Lasse_Ding_Passieren
SCHLEIFENENDE (Wenn noch nicht beendet, springe zu SCHLEIFENANFANG)
D.h. es gibt zwei Schleifenenden, damit reduziert man aber die Anzahl Sprünge.
Auch eine lustige Lösung ist das:
Springe zu SCHLEIFENANFANG
@Passieren:
Lasse_Ding_Passieren
SCHLEIFENENDE (wenn beendet, springe zu @Raus)
SCHLEIFENANFANG
Irgendwas1
Irgendwas2
Irgendwas3
Ding_Passiert? Ja, gehe zu @Passieren
SCHLEIFENENDE (wenn nicht beendet, springe zu SCHLEIFENANFANG)
@Raus:
Es sind zwar mehr Sprünge, aber außerhalb der Schleife. Innerhalb ist es immer nur 1 Sprung.
Lasse_Ding_Passieren findet (sozusagen) auch am Ende der Schleife statt, wie man sieht:
Wenn das Ding nicht passiert, wird normal das Schleifenende abgefragt und wenn noch nicht erreicht, gibt es den Sprung zum Schleifenanfang. Wenn das Ding DOCH passiert, geht der Sprung zum @Passieren und läßt das Ding passieren, fragt auch ab, ob die Schleife beendet ist, aber springt nur in dem EINEN Fall (dem seltensten, nämlich wenn die Schleife durch ist) und ansonsten nicht - d.h. in dem Fall wird auf den Schleifenende-zu-Schleifenanfang-Sprung verzichtet, weil der Anfang direkt hinter dem Lasse_Ding_Passieren liegt - somit benutzt man einfach die natürliche Abfolge der Befehle dazu, auf diesen Sprung zu verzichten. Der einzige "Stunt" der dazu nötig ist, ist, am Anfang "in die Schleife hinein" (also an SCHLEIFENANFANG) zu springen. Witzigerweise ist dieser Sprung manchmal sogar doppelt nützlich - denn wenn jemand wie ich VOR der Schleife irgendwelchen Code INNERHALB der Schleife modifiziert hat, löscht dieser anfängliche Sprung praktischerweise gleich mal den Prefetch-Queue mit...
Das sind nur so Dinge, auf die ich über die Jahre im Programmieren mit Assembler ganz alleine gekommen bin. Und ich weiß nicht genau, wie z.B. eine Hochsprache eine IF-Abfrage innerhalb einer Schleife umsetzen würde - aber ich bin mir fast sicher: SO bestimmt nicht! Das zum Thema, daß Compiler besser optimieren als Menschen...
zatzen hat geschrieben:Am meisten dürfte im Moment noch Punkt 2 ausmachen.
Ja, wie ich schon sagte: Ich neige gern dazu, gleich alles direkt in den Grafikspeicher zu hauen. Das hat Vor- und Nachteile.
Die zwei Vorteile sind:
1.) Man schreibt nicht zweimal (einmal in einen Zwischenpuffer, einmal vom Zwischenpuffer in den Grafikspeicher).
2.) Man braucht nicht extra Speicher für den Zwischenpuffer.
Die zwei Nachteile sind:
1.) Man überschreibt im Grafikspeicher teilweise Daten, die man schon geschrieben hat (z.B. wenn man Sprites zeichnet vor bereits gezeichnete Hintergründe). Das ist insofern ein Nachteil, daß Speicherzugriffe auf Grafikspeicher langsamer sind als auf normalen RAM. Wenn man das Schreiben/Überschreiben im normalen RAM macht, wird alles, was dann im RAM (Zwischenpuffer) steht, nur einmal zum Grafikspeicher übertragen, das "überschriebene" wird also nicht übertragen.
2.) Man verzichtet auf den Vorteil des schnellen Kopierens mit REP Befehlen - denn für Ort-zu-Ort-Kopieren gibt es ja diese praktischen DS:[SI] -> ES:[DI] MOVs, mit CX als Zähler und REP... Besonders nützlich natürlich bei planarem Grafikspeicher (bei Mode-X müßte man etwas tricksen).
3.) Beim direkten Schreiben in den Grafikspeicher muß man zwingend mit mindestens 2 Bildschirmseiten arbeiten - auf VGA bleibt einem dafür nur der MODE-X, der aber nicht so planar ist, sondern eine etwas komische Speicheranordnung hat (weil er ja eigentlich ein "Hack" ist). Arbeitet man mit Puffern, so kann man auch den MCGA (320x200x256 Planar) benutzen, wenn das Kopieren einigermaßen fix geht.
Wieso arbeite ich trotzdem lieber mit direktem Schreiben in Grafikspeicher?
1.) Ich will einfach nicht so viel wertvollen RAM als zusätzlichen Puffer verschwenden.
2.) Ich will nicht auf 320x200 beschränkt sein - und 360x240 geht z.B. sowieso nur mit Mode-X.
3.) Sobald höhere (VESA) Modi hinzukommen, reicht der normale Heap sowieso nicht mehr für einen Zwischenpuffer aus. Alleine der (eher seltene) 640x400 (es gibt viel öfter den 640x480) braucht schon 256000 Bytes, der 640x480 schon 307200 Byte (300 kB!) - und im RealAddressMode (16bit-Mode) wäre bei über 64kB ja dann sowieso kein "planares" Arbeiten mehr möglich durch die nötigen Segmentwechsel. Da kann man auch gleich die "Banken" in der Grafikkarte wechseln... Und irgendwann wird dann Puffer-Kopieren auch langsamer als das, was durch das "Überschreiben von schon Geschriebenen" ansonsten verlorenginge. 300 kB kopiert auch so'n 486er ja nicht "mal eben so" - zumal, wenn er es vorher auch schon in einen extra RAM geschrieben hatte.
Ja, ich weiß: Meine Programmiertechniken sind altmodisch - fast archaisch: Ich habe das alles dermaßen auf den 16bit-Mode (RealAddressMode) ausgelegt: Keinerlei Beachtung des Protected Mode, mit dem ich Zugriff auf großen planaren Speicher hätte, keinerlei Beachtung der Existenz von Speicher über 1 MB (oder 640 kB) außer per indirektem Zugriff durch HIMEM.SYS - als reinen "Lagerspeicher". Es gibt schon den reinen planaren 64bit-Mode und ich murks hier mit segmentbasiertem 16bit rum. Ist mir alles bewußt. Ich habe über die Jahre und Jahrzehnte jetzt viele Units gebaut und angehäuft, mit denen ich endlich etwas Sinnvolles machen könnte - da entscheidet sich die Industrie zum ersten Mal seit über 30 Jahren, den neuen CPU-Mode (64bit) nicht mehr abwärtskompatibel zu gestalten... Was soll ich dazu sagen?
Ich könnte natürlich "mit der Zeit gehen und immer das Neueste, was es gibt, direkt erlernen - aber ich lerne einfach zu langsam, um alles zu begreifen, und "irgendwie so halb" habe ich keine Lust. Wenn ich das machen wollte/sollte, könnte ich nur mit maschinenfernen Skripten arbeiten und ineffizienten Kram bauen, mit dem ich selbst nicht zufrieden wäre. Dann würde ich viele Spiele der Art "Tetris braucht Quadcore" schreiben, wo sich dann andere freuen, daß ich so viele Spiele rausbringe, ich selbst aber jedes meiner Erzeugnisse abgrundtief hassen würde. Mir geht und ging es ja immer eher um die Maschine - um das Programmieren an sich. Spiele sind quasi ein "Nebenprodukt" davon - auch wenn das jetzt seltsam klingt. Spiele sehe ich als eine programmiererische Herausforderung an, da sie Kenntnisse und Fähigkeiten auf vielen verschiedenen Gebieten erfordern - und dann auch noch die Fähigkeit, diese ganzen Einzelteile zu einem Gesamtwerk zu vereinigen, das insgesamt in den Speicher paßt und mit der vorhandenen Rechenleistung auskommt.
Aber aus vorhandenen Fertigteilen Spiele bauen - da entgeht mir ja das für mich Interessanteste: Die Programmierung. Wenn ich manche der vielen "Game-Maker" Spiele so sehe, die im Internet kursieren: Die verwenden eine fertige Engine, es gibt vorgefertigte Grafiken, sie brauchen nur irgendwelche Songs in MP3 oder Effekte in welchem Format auch immer nehmen, weil eine interne Engine die alle abspielen kann (macht ja nix, wenn das ganze Ding deshalb 120 MB groß wird...) das einzige, was sie selbst machen, ist die Levels zusammenzuklicken und eine lockere Geschichte drumherum zu bauen. Ja, auch das macht sicher Arbeit - aber das ist das an der ganzen Entwicklung für mich Uninteressanteste.
Vielleicht bin ich wirklich eher der Typ, der einen Game-Maker bauen sollte und den Rest anderen Leuten überlassen...
Andererseits gibt es ja bereits genügend Game-Maker - und die Sparte User, die so etwas heutzutage benutzt, hat sicher kein Interesse daran, einen Game-Maker für DOS-SPIELE haben zu wollen.
zatzen hat geschrieben:Ich habe mit ZSM diese Aninmation mit der Ente (HIT_ANY) vertont, es ist eine Bildschirmfüllende
Animation, es läuft im Grunde schnell und flüssig, aber stellenweise stottert es wenn man die
Emulation auf 386SX Niveau einstellt. Ich werde das im ZVID Thread hochladen wenn ich den Viewer
optimiert habe.
Cool. Freue mich schon darauf.