|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 18:37 Titel: POKE & Grafiken |
|
|
Hallo QB Profis
Ich arbeite zur Zeit mit Fraktalen und habe dazu auch schon einiges an Code gefunden.
Das Problem ist allerdings, dass ich gar kein QBASIC-Programmierer bin
und mich erst seit heute mit dieser Sprache beschäftige.
Mittlerweile verstehe ich das Programm so weit, dass ich weis, an welche Speicheradressen es welche Werte schreibt.
Jedoch wäre es hilfreich, wenn jemand hier weis, wie QBASIC das intern verarbeitet,
sodass man diese Adressen irgendwie in Koordinaten umwandeln kann.
Denn dann könnte ich zum Beispiel die Funktion SetPixel aus GDI verwenden.
Schon mal danke im Voraus.
MfG, James |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 25.08.2012, 19:13 Titel: Re: POKE & Grafiken |
|
|
Hi James,
willkommen im Forum!
James1337 hat Folgendes geschrieben: | Mittlerweile verstehe ich das Programm so weit, dass ich weis, an welche Speicheradressen es welche Werte schreibt.
Jedoch wäre es hilfreich, wenn jemand hier weis, wie QBASIC das intern verarbeitet,
sodass man diese Adressen irgendwie in Koordinaten umwandeln kann.
Denn dann könnte ich zum Beispiel die Funktion SetPixel aus GDI verwenden. |
QBasic ist 16-Bit-DOS-Software und läuft unter modernen MS-Betriebssystemen wie Windows XP / Vista / 7 nur noch emuliert in ntvdm ab. Auf 64-Bit-Systemen ist gar keine Ausführung mehr möglich (außer mit Emulatoren wie DOSBox).
Da QBasic keine Windows-Software ist und auch QuickBASIC nur DOS-Anwendungen erzeugt, ist es generell nicht möglich, aus QB heraus auf WinAPI-Funktionen bzw. GDI/GDI+ zuzugreifen.
Als QBasic im Jahr 1992 herausgegeben wurde (Die Software ist tatsächlich schon 20 Jahre alt!), gab es noch kein 32-Bit-Windows und auch hardwareseitig hat sich seit dem viel getan... Zu dieser Zeit waren die Anwendungen noch 16-bittig und es gab auch CPU-Erweiterungen wie MMX noch nicht.
Mit FreeBASIC hingegen könntest du echte 32-Bit-Anwendungen erzeugen, die nativ unter Windows und Linux ablaufen und könntest somit unter Windows auch alle WinAPI-Funktionen verwenden - egal, ob für Socketprogrammierung mit Winsock oder Grafikprogrammierung mit GDI+, DirectX oder OpenGL. Des Weiteren lässt sich mit FreeBASIC die aktuelle PC-Hardware ausnutzen: FreeBASIC-Programme können beispielsweise von SSE-Unterstützung moderner CPUs profitieren und Arbeitsspeicher im Gigabyte-Bereich verwenden, während QB-Programme auf unter 1 MB (!!) limitiert sind. Von daher würde ich sehr empfehlen, nicht QB zu lernen, sondern direkt mit FreeBASIC einzusteigen. Du erhältst dadurch eine viel bessere Performance und Unterstützung aktueller Hard- und Software-Plattformen.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 19:40 Titel: |
|
|
Tut mir leid, falls ich mich ungenau ausgedrückt habe.
Das Fraktal schreibt mit POKE (soweit ich diesen Befehl richtig verstanden habe) bestimmte Werte an bestimmte Adressen. Es geht mir nur darum, aus diesen Daten irgendwie die Koordinaten zu berechnen, an denen QBASIC dann letzten Endes zeichnet. Diese Umrechnung brauche ich, um den Code von QB in eine andere Sprache zu portieren, ich will also nicht GDI-Funktionen aus QB aufrufen.
Trotzdem danke für die schnelle Antwort. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4648 Wohnort: ~/
|
Verfasst am: 25.08.2012, 19:51 Titel: |
|
|
Ohne Garantie auf Verwendbarkeit:
http://www.freebasic-portal.de/befehlsreferenz/interne-pixelformate-464.html erklärt ziemlich weit unten glaube ich auch das QB-Grafikpufferformat.
("Version 1 (veraltet)"; müsste identisch mit QB sein) _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 25.08.2012, 20:02 Titel: |
|
|
Der Grafikspeicher ist linear Zeile für Zeile aufgebaut, d.h. um einen Pixel zu setzen läuft das über POKE y * bildschirmbreite + x, farbe, bzw um die Koordinate zurückzurechnen: y = adresse \ bildschirmbreite, x = adresse mod bildschirmbreite. Im SCREEN 13 wäre die bildschirmbreite z.B. 320. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 20:09 Titel: |
|
|
@nemored, Jojo
Vielen Dank, das werde ich gleich mal versuchen. |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 955 Wohnort: Austria
|
Verfasst am: 25.08.2012, 20:27 Titel: |
|
|
Für die meisten Grafik-Modi findest du den Grafikspeicher and Offset &HA000 im Speicher gemappt.
Für Screen 13 wäre das z.B. dann:
Code: | DEF SEG = &HA000
POKE yPos * 320 + xPos, farbe |
wobei xPos und yPos für screen 13 im Bereich von 0 bis 319 bzw. 0 bis 199 und farbe von 0 bis 255.
Für Screen-Modi, die mehrere planes verwenden, musst du zuätzlich noch zwischen diesen wechseln. Für Screen 12 (640x480, 16 farben) z.B. mit 4 Planes:
Code: |
DEF SEG = &HA000
farbe = 5
FOR i = 0 TO 3
OUT &H3C4, 2
OUT &H3C5, 2^i
POKE yPos * 80 + xPos, farbe AND 2^i
NEXT
DEF SEG |
[Nicht Ausprobiert! Keine Gewähr auf Korrektheit!]
Hier ist es etwas komplizierter; du musst dich etwas mit Bitarithmetik auseinandersetzen. Denn an einer Adresse setzt du hier mehrere pixel gleichzeitig und die endgültige farbe ergibt sich aus der kombination aller 4 planes.
Ich würde dir aber allgemein nahelegen dich nicht mit dem aus heutiger Sicht völlig veraltetem QBASIC abzumühen, wenn es bereits FreeBASIC gibt, dass (außer in Ausnahmefällen) die gleiche Syntax hat und leistungsfähiger, moderner und einfacher ist und - am wichtigsten: die damit erzeugten Programmen auf heutigen Computern überhaupt laufen.
EDIT: Screen 12 Code korrigiert: Bit Plane auswählen war fehlerhaft. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Zuletzt bearbeitet von St_W am 25.08.2012, 20:59, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2514 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 25.08.2012, 20:38 Titel: |
|
|
Warum ist Windows unter anderem so erfolgreich geworden? Weil Treiber hardwarespezifische Details der Grafikkarte (beim Drucker, Soundkarte, Netzwerkkarte usw. genauso!) gegenüber der Anwendersoftware "verbergen" d.h. sinnvoll abstrahieren, so dass der Anwendungsprogrammierer auf einheitliche APIs zurückgreifen kann. FreeBasic profitiert logischerweise auch von dieser Abstrahierung, daher funktionieren SCREEN-Fähigkeiten auf jedem PC unabhängig, ob eine Grafikkarte von ATI, Nvidia oder sonst einem Hersteller drin läuft. Es muss lediglich der passende Grafiktreiber (Windows) bzw. X11-Server (Linux) installiert sein.
QBasic stammt dagegen noch aus einer Zeit vor dieser Abstrahierung mit Treibern, wie im MS-DOS-Zeitalter typisch. Damals war es beispielsweise üblich, dass Grafikkarten-Hersteller spezielle Treiber für Mainstream-Anwendungen wie AutoCAD, MS Word 5.0 usw. mitgeliefert hatten, weil die Anwendungsprogrammierer direkt auf die Hardware zurückgreifen mussten.
Zwar stellten die Grafikbefehle in QB und SCREEN an und für sich auch schon eine recht gute Abstrahierung der Grafikkarte dar, denn PSET, LINE, CIRCLE usw. sparten auf jeden Fall direktes Herumhantieren mit POKE wie seinerzeit beim Commodore 64 üblich. Ansonsten die direkt in Intel 8088-Assembler geschriebenen Programme arbeiteten natürlich wie auf dem C 64 und verwendeten das BIOS höchsten für den gewünschten Vidoemodus aktivieren, POKEten aber ihre Bitmap-Daten direkt in die Videokarte hinein (Pixel setzen und lesen sind im BIOS das Höchste der Gefüge). Der VESA-Standard versuchte dies übrigens für alle SuperVGA-Videomodi zu vereinheitlichen (Artikel), was aber aufgrund fehlerhafter VESA-BIOS-Implementierungen mehr schlecht als recht funktioniert hat.
Zum Fraktalprogramm zurück: Zum einen von mir ein paar Beispiele:
http://www.dreael.ch/Deutsch/Download/Apfelmaennchen.html
Ansonsten ist dies ein typischer Fall, einen alten (Legacy) Code in eine aktuelle Form zu bringen. Um Dir besser helfen zu können am besten diesen alten Code einmal hier ins Forum posten. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
minx
Anmeldungsdatum: 25.08.2012 Beiträge: 11
|
Verfasst am: 25.08.2012, 20:40 Titel: Tag |
|
|
Guten tag!
Ich bin minx, und arbeite mit James an dem Projekt. Es ist nicht so, dass ich/wir uns mit dieser "veralteten" Sprache auseinander setzen wollen, wir wollen nur ein Programm in den (mächtigen) BASIC-Dialekt AutoIt (autoit.de) zu portieren.
Also wir haben ein Fenster, welches wie das BASIC Programm 320x240px groß ist. Die Zeichenfunktion mit dem Port von POKE ist jetzt schon umgesetzt, allerdings fehlt die Farbberechnung. Denn bei uns sind die Farbwerte anders formatiert (z.B. 0xFFFFFF).
Nun wird von dem orig. Programm die Farbe mit PALETTE gesetzt. Unbrauchbar, denn bei uns steht die Farbe einfach in einer Variable, z.B. "$Color".
Im Original:
Code: | IF n < 18001 THEN rands(n) = RND * 32 ELSE IF n < 21601 THEN sins(n - 18000) = 256 * SIN((n - 18000) * .0349) ELSE IF n < 21729 THEN PALETTE n - 21601, ((n - 21601) \ 2) * 65793 ELSE PALETTE 255 - (n - 21729), ((n - 21729) \ 2) * 65793 |
In AutoIt wäre das, aber halt unvollständig:
Code: | IF $n < 18001 THEN
$rands[$n] = Random() * 32
ELSEIF $n < 21601 THEN
$sins[$n - 18000] = 256 * SIN(($n - 18000) * .0349)
ELSEIF $n < 21729 THEN
PALETTE $n - 21601, (($n - 21601) \ 2) * 65793
ELSE
PALETTE 255 - ($n - 21729), (($n - 21729) \ 2) * 65793
EndIf |
Danke für eure Hilfe.
Zuletzt bearbeitet von minx am 25.08.2012, 20:41, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 20:41 Titel: |
|
|
Auch danke dafür St_W. Wir verwenden (zum Glück) SCREEN 13.
Es ist ja nett, dass ihr mit alle FreeBASIC ans Herz legt, aber (leider) ist der Code den wir portieren wollen mit QBASIC geschrieben, also kann ich da leider nicht viel machen.
Ich konnte durch eure Hilfe zumindest schon mal die POKE-Funktion in meine UDF implementieren.
Der Code sieht übrigens wie folgt aus (wobei uns Zeile 6 momentan noch Sorgen bereitet): Code: | DEFINT A-Z
SCREEN 13
DIM SHARED sins(3600) AS INTEGER
DIM SHARED rands(18000) AS INTEGER
FOR n = 0 TO 21856
IF n < 18001 THEN rands(n) = RND * 32 ELSE IF n < 21601 THEN sins(n - 18000) = 256 * SIN((n - 18000) * .0349) ELSE IF n < 21729 THEN PALETTE n - 21601, ((n - 21601) \ 2) * 65793 ELSE PALETTE 255 - (n - 21729), ((n - 21729) \ 2) * 65793
NEXT n
DEF SEG = &HA000
DO
f = (f + 2) MOD 180
f2 = (f2 + 2) MOD 50
p& = 0
FOR r = 0 TO 199
FOR c = 0 TO 319
POKE p& + c, sins(r + f) + sins(c + f) + sins(r + c) + rands(f2 * r + c)
NEXT c
p& = p& + 320
NEXT r
LOOP UNTIL INKEY$ <> "" |
MfG, James
Zuletzt bearbeitet von James1337 am 25.08.2012, 20:53, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2514 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 25.08.2012, 20:52 Titel: |
|
|
Ohne viel Kommentar:
http://beilagen.dreael.ch/QB/JAMES2.BAS
d.h. der POKE lässt sich durch ein PSET ziemlich problemlos eliminieren. Animationseffekt (hat allerdings nichts mit der Mandelbrotmenge zu tun!) läuft auch mit PSET eigentlich von der Performance her ohne Probleme (Test auf Pentium III/1 GHz mit QBasic 1.1 von MS-DOS 6.22). _________________ Teste die PC-Sicherheit mit www.sec-check.net
Zuletzt bearbeitet von dreael am 25.08.2012, 20:53, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 955 Wohnort: Austria
|
Verfasst am: 25.08.2012, 20:53 Titel: |
|
|
FreeBasic bietet ja eh einen QBASIC Kompatibilätsmodus, mit dem der meiste Code 1:1 übernommen werden kann. Problematisch ist nur hardwarenaher Code (wie z.B. der direkte zugriff auf den Grafikspeicher mit POKE, wie gerade eben besprochen), der geändert werden muss. In FreeBASIC kann man das jedoch in ähnlich einfacher weise mit direktem Speicherzugriff lösen oder mittels PSET, das um vielfache schneller ist als in QB.
Was ich eigentlich sagen wollte: Es empfiehlt sich - soweit ich weiß - ein nach der Schleife auszuführen um die Basisadresse wieder zurückzusetzen, um mögliche Nebenwirkungen zu vermeiden; hab ich oben vergessen für Screen 13. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 20:57 Titel: |
|
|
Danke, aber da ich POKE mittlerweile sowieso schon implementiert habe (und glaube, dass die Angaben von Jojo stimmen),
besteht für mich kein Grund es durch PSET zu ersetzen.
Und selbst wenn doch, da wir jetzt beide Funktionen verwenden könen, ist das egal.
Das Problem ist vielmehr die Funktionsweise/Portierung von PALETTE.
MfG, James |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 955 Wohnort: Austria
|
Verfasst am: 25.08.2012, 21:03 Titel: |
|
|
Ich hoffe ich bin nicht zu aufdringlich, aber PALETTE gibts genauso unter FreeBASIC
Edit: Sorry, hab beim überfliegen des Threads offenbar das eigentliche Vorhaben (AutoIt) überlesen. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Zuletzt bearbeitet von St_W am 26.08.2012, 11:48, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 25.08.2012, 21:07 Titel: |
|
|
PALETTE weist jeder der 256 indizierten farben (0-255) einen RGB-Wert zu - ganz ähnlich den 32-Bit-Farbcodes, die du bereits kennst. Allerdings ist die Präzision dafür in QB wesentlich niedriger - 6 bit pro Farbkanal statt 8.
PALETTE x, y weißt dann dem Paletteneintrag x den echten Farbwert y zu. Diesen müsste man so zurückrechnen können:
R = y mod 64 ' R-Anteil als Zahl zwischen 0 und 63
G = (y \ 256) mod 64 ' G-Anteil (dito)
B = (y \ 65536) mod 64 ' B-Anteil (dito)
256 und 65536 ist keine Tippfehler - denn die Farbanteile werden tatsächlich byteweise gespeichert, d.h. "zwischendrin" gibt es viele "nicht existierende" Farbcodes (64 ist z.B. kein zulässiger Farbcode).
St_W: Inzwischen sollte doch klar sein, dass er nicht mit FB arbeitet, oder? Und in FB (zumindest unter -lang fb) tut PALETTE nicht dasselbe wie in QB. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Zuletzt bearbeitet von Jojo am 25.08.2012, 21:10, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
James1337
Anmeldungsdatum: 25.08.2012 Beiträge: 6
|
Verfasst am: 25.08.2012, 21:09 Titel: |
|
|
Merci beaucoup! Ich werde das sofort mal versuchen so umzusetzen. |
|
Nach oben |
|
|
minx
Anmeldungsdatum: 25.08.2012 Beiträge: 11
|
Verfasst am: 25.08.2012, 21:21 Titel: |
|
|
Danke Jojo!
Also müsste das mit unseren Farben so gehe:
Wenn:
Code: | $R = Mod($y, 64)
$G = Mod(($y \ 256), 64)
$B = Mod(($y \ 65536),64) |
Dann:
Code: | $Hexfarbe="0x" & hex($r*4) & hex($g*4) & hex($b*4) |
Müsste funktionieren... |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 25.08.2012, 21:39 Titel: |
|
|
wenn dieser hex-befehl auch einstellige hexzahlen zu zwei stellen erweitert, sollte das so hinhauen, ja...
Es kommt jetzt nur noch auf die Implementierung an.
Ich würde die 256 Palette-Einträge zu Beginn in einem Array speichern (sozusagen den Palette-Befehl emulieren) und dann jeweils bei SetPixel dann den passenden Array-Eintrag abrufen. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
minx
Anmeldungsdatum: 25.08.2012 Beiträge: 11
|
Verfasst am: 25.08.2012, 21:49 Titel: |
|
|
Jop. Hex() macht aus 0-255, 00-FF.
Das mit dem Array ist ne gute Idee, mal probieren... |
|
Nach oben |
|
|
minx
Anmeldungsdatum: 25.08.2012 Beiträge: 11
|
Verfasst am: 25.08.2012, 22:18 Titel: |
|
|
Hi nochmal. Ich wollte nochmal verkünden, das wir es jetzt hinbekommen haben!
Eine Frage habe ich aber noch. Ich besitze Qb4.5. Ich möchte per Kommandozeile eine Datei (.bas) kompilieren.
Ich kann mit BC.exe erfolgreich die OBJ Datei erzeugen, aber wie geht es dann weiter?
Vielen Dank! |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|