Zur Druckansicht wechseln Visit the English version of this page

www.jb-electronics.de » Programmieren » Schnelleres PSET in freeBASIC

Schnelleres PSET in freeBASIC

Gerade wenn man in freeBASIC arbeitet und dabei viele Einzelpunkte gezeichnet werden müssen, fällt die Langsamkeit der PSET-Routine auf. Abhilfe schafft eine kleine Routine, die mit dem - eigentlich antiquierten - Befehl POKE arbeitet.

Diese Routine schreibt den Pixel direkt in den Bildschirmspeicher, denn freeBASIC liefert dessen Adresse mit der Funktion screenptr zurück. Der Datentyp des (Farb-)Wertes, der in den Speicher geschrieben werden soll, hängt natürlich von der verwendeten Farbtiefe ab. Bis 8bpp reicht noch der Datentyp UBYTE, doch spätestens bei 24bpp sollte man sich mit INTEGER anfreunden.

Die Adresse im Speicher ergibt sich - da selbiger linear aufgebaut ist - aus der Summe des Produktes der y-Koordinate mit der x-Breite und der x-Koordinaten. Wem das jetzt zu kompliziert war, hier eine Gleichung:

Adresse im Speicher = Adresse des Speichers + y-Koordinate * x-Breite + x-Koordinate

So kommt man zu folgender Routine (diese ist für eine Auflösung von 640x480x24bpp):

sub SetPixelFast (PosX as integer, PosY as integer, Farbe as integer, Dest as integer ptr)
  poke integer, Dest + (PosY * 640) + PosX, Farbe
end sub

Anhand obiger Informationen sollte es kein Problem sein, diese Routine für andere Grafikmodi umzuschreiben. Hier ein Beispielcode, der den Zeitunterschied misst:

option explicit
declare sub SetPixelFast (PosX as integer, PosY as integer, Farbe as integer, Dest as integer ptr)

randomize timer
screen 18, 32

dim as long Count
dim as double Zeit1, Zeit2
dim as double Dif1, Dif2

cls
Zeit1 = timer
for Count = 1 to 10000000 step 1
  pset (100, 100), &hffffff
next Count
Zeit2 = timer
Dif1 = Zeit2 - Zeit1

cls
Zeit1 = timer
for Count = 1 to 10000000 step 1
  SetPixelFast(100, 100, &hffffff, screenptr)
next Count
Zeit2 = timer
Dif2 = Zeit2 - Zeit1

cls
print "Zeit Version PSET: ";
print using "#.##########"; Dif1;
print " Sekunden."
print
print "Zeit Version SetPixelFast: ";
print using "#.##########"; Dif2;
print " Sekunden."
print
print "Zeitunterschied: ";
print using "#.##########"; Dif1 - Dif2;
print " Sekunden!"

getkey
end

sub SetPixelFast (PosX as integer, PosY as integer, Farbe as integer, Dest as integer ptr)
  poke integer, Dest + (PosY * 640) + PosX, Farbe
end sub

Der Zeitunterschied ist enorm und beträgt auf meinem Rechner nahezu 2.5 Sekunden. Bei einem meiner Programme brachte diese Routine eine Verbesserung der FPS-Rate von 55 Bildern pro Sekunde zu 85 Bildern pro Sekunde. Gerade bei Spielen ist diese Routine - so meine ich jedenfalls - unglaublich nützlich.

Doch auch der Nachteil dieser Routine sei nicht verschwiegen: Sollte sich eine Pixelangabe eigentlich außerhalb des Bildschirms befinden, erscheint der Pixel bei dieser Routine trotzdem links auf dem Bildschirm. Es stimmt natürlich - man könnte eine solche if-Abfrage einbauen:

if not ((PosX < 0) or (PosX > 639) or (PosY < 0) or (PosY > 479)) then

Doch darunter würde die Ausführgeschwindigkeit leiden, und die Routine wäre deutlich langsamer. Beim obigen Test zum Beispiel zeigte sich bei mir ein Anstieg der Zeit um ca. eine Zehntelsekunde. Es bleibt also jedem selbst überlassen, ob und wie er diese Routine benutzt.

Nachtrag:

An Stelle des folgenden Codes

poke integer, Dest + (PosY * 640) + PosX, Farbe

ist es eigentlich besser, Folgendes zu verwenden:

Dest[PosY * 640 + PosX] = Farbe

Dadurch kann die Ausführgeschwindigkeit noch ein kleines bisschen erhöht werden, da die Verwendung von POKE eigentlich noch aus der DOS-Zeit stammt und daher von freeBASIC nicht direkt unterstützt wird. Besser ist es - siehe oben - einen zeitgemäßen Pointer zu verwenden.

Nach oben

show print layout Die deutsche Version der Seite besuchen

www.jb-electronics.de » Programming » A faster PSET in freeBASIC

A faster PSET in freeBASIC

My apologies...

There is no English translation of this page available yet. It will take some more time for me to translate the whole website.

If you have a particular interest in this page getting translated as fast as possible, please contact me; I will see what I can do. Please click here for the German version.

Top the top