En tiedä, onko tämän asian kovinkin moni huomannut, tai onko tämä peräti jossain Help-tiedostossa yleisesti selitetty, mutta tällaisen asian huomasin, että QB:n DRAW-käsky saattaa myös muokata graafisessa näyttötilassa tekstimuistia, mikäli DRAW:lla piirretään vastaava ASCII-merkki.
Vertaa esim. näitä koodinpätkiä.
Tässä suoraan PRINT:llä kirjoitetaan kohtaan (8,17) merkki 196, eli vaakaviiva:
SCREEN 13 LOCATE 8, 17 PRINT CHR$(196) LOCATE 1, 1: PRINT SCREEN(8, 17) 'varmistetaan, mitä muistiin tuli
Tässä vastaavanlainen vaakaviiva taas piirrettään DRAW-käskyllä:
SCREEN 13 DRAW "bm128,60 r7" LOCATE 1, 1: PRINT SCREEN(8, 17) 'varmistetaan, mitä muistiin tuli
Itse huomasin tämän, kun tein funktiota, joka kirjoittaa tekstin laatikkoon (eräänlainen MsgBox siis), ja osaa myös pilkkoa sanat eri riveille, alkoi bugittaa. Minua tämä ainakin häiritsee, ja on vaikea keksiä tähän mitään apukeinoa käyttämättä purkkavirityksiä. En kyllä usko, että kellään olisi tähän mitään sen kummempaa neuvoa, mutta ajattelin nyt pistää asian esille.
Mitä ihmeen tekstimuistia? Entä jospa SCREEN-käsky vertaakin graafisissa näyttötiloissa ko. kohdassa olevaa kuvaan, kaikkien eri merkkien kuviin ja jos löytää sopivan niin palauttaa sen. En kylläkään ole ennemmin ajatellut koko asiaa. Mitä SCREEN palauttaa jos kyseisessä kohdassa on vaikkapa epämääräistä sotkua?
Ei SCREEN-funktio katsokaan, mitä pikseleitä on näytöllä, vaan sen palauttama merkki tulee tekstimuistista. Sinne kaikki teksti aina tallentuu, tosin graafisessa tilassa QB:n PRINT tietysti myös tulostaa tekstin näytölle pikseleinä. Tekstitilassa taas kun ei grafiikkaa saa, niin merkit, jotka näkyvät tulevat suoraan tekstimuistista, ja ne näytetään sitten ASCII-merkkeinä. Ellen aivan väärin muista niin tekstimuistin segmentti alkaa kohdasta &HB800.
lainaus:
Ei SCREEN-funktio katsokaan, mitä pikseleitä on näytöllä, vaan sen palauttama merkki tulee tekstimuistista.
Mistäs näin päättelit? En minä ainakaan pikaisella silmäyksellä qb :n helpistä tuollaisesta löytänyt minkäänlaista mainintaa.
lainaus:
Sinne kaikki teksti aina tallentuu, tosin graafisessa tilassa QB:n PRINT tietysti myös tulostaa tekstin näytölle pikseleinä.
Mitä varten se teksti turhaan sinne tekstibufferiinkin tallettuisi (grafiikkatiloissa)?
Ei se nyt ainakaan kuulosta järkevältä, että qb kävisi jokaisen pikselin piirron jälkeen tarkistamassa, että onkohan sinne näytölle sattunut ilmestymään jonkin merkin kuva, jonka (siis merkin, ei kuvan) voisi sitten kopioida tekstipuskuriin.
tn kirjoitti:
Mistäs näin päättelit? En minä ainakaan pikaisella silmäyksellä qb :n helpistä tuollaisesta löytänyt minkäänlaista mainintaa.
Mistäkö päättelin? No tekstitilassa ainakin totta kai kaikki tallentuu tekstipuskuriin, ja graafisessa tilassa QB:n PRINT kirjoittaa sekä tekstimuistiin että näyttömuistiin, jotta teksti tulisi myös pikseleinä näytölle. Ja jos nyt et usko minua, niin kokeile ihmeessä ajaa nuo koodinpätkät. Pistin ne ihan demonstroimaan tätä asiaa, ja ne todistavat sen minusta aika hyvin.
tn kirjoitti:
Ei se nyt ainakaan kuulosta järkevältä, että qb kävisi jokaisen pikselin piirron jälkeen tarkistamassa, että onkohan sinne näytölle sattunut ilmestymään jonkin merkin kuva, jonka (siis merkin, ei kuvan) voisi sitten kopioida tekstipuskuriin.
Ei tunnu minustakaan järkevältä, ja lisäksi se on haitallinen ominaisuus, mutta totta se vain on, joten kokeile vain noita koodeja, jos et usko.
SCREEN 13 DEF SEG = &HB800 POKE 0, 65 'laitetaan tekstibufferiin ruudun vasempaan ylänurkkaan merkki A LOCATE 5, 5 PRINT SCREEN(1, 1); " eli "; CHR$(SCREEN(1, 1)) 'toimii tekstitilassa, mutta 'ei grafiikkatilassa
Miksei ylläoleva koodi osaakkaan hakea merkkiä tekstibufferista grafiikkatilassa?
SCREEN 13 LOCATE 1, 1 PRINT "A" 'tulostetaan A ruudun vasempaan yläkulmaan DEF SEG = &HB800 LOCATE 5, 5 PRINT PEEK(0); " eli "; CHR$(PEEK(0)) 'haetaan merkki tekstibufferin 'vasemmasta yläkylmasta
Mitä? Vaikka ruudulle tulostettiinkin, niin miksei tekstibufferiin ilmestynyt mitään?
Kumpikin esimerkki toimii täysin tekstitilassa. Ja minä kyllä kokeilin jo niitä koodeja.
Grafiikkatilassa teksti vain piirretään näytölle, merkkejä ei panna talteen mihinkään erilliseen muistiin. Tämän takia SCREEN-funktion täytyy käydä läpi koko merkistö näytöllä olevan merkin selvittämiseksi. Merkkejä voi piirtää vaikka DRAW-komennolla, ja SCREEN-funktio silti tunnistaa ne, kunhan pikselit ovat juuri oikeat.
QBasicin ohjeessa on asiaan liittyvä huomautus:
QB:n ohje kirjoitti:
Note: In graphics screen modes, if the pattern on the screen at the given character location does not exactly match any pattern in the current ASCII character set, the SCREEN function returns the ASCII code for a space.
Eli:
Suomentaja kirjoitti:
Huomautus: Grafiikkatiloissa SCREEN-funktio palauttaa välilyönnin ASCII-koodin, jos annetussa kohdassa näytöllä oleva kuvio ei vastaa yhdenkään merkin kuviota senhetkisessä ASCII-merkistössä.
Tekstimuisti, joka alkaa yleensä segmentistä &HB800, on siis käytössä ainoastaan tekstitilassa. Grafiikkatilassa PRINT-komento ei kajoa tekstimuistiin, vaan piirtää merkit suoraan näytölle.
No noinhan se tosiaan näyttääkin olevan. Olen aina luullut, että PRINT kirjoittaa sekä teksti- että näyttömuistiin, ja että SCREEN tarkistaa tekstimuistista. Mutta pikseleistähän se näemmä tosiaan näkyy sen tarkistavan, ja jos pikselit eivät muodosta mitään merkkiä, se näyttää palauttavan välilyönnin ASCII-koodin. Mutta jos näin kerran on, niin sitten saan kyllä tuon funktion bugittamisen pois helpolla tavalla.
Joissain tapauksissa ikävää kuitenkin tuo, että tarkistetaan pikseleistä. Niistähän ei voi tietää, mikä on tausta- ja mikä tekstin väriä. Esim.
SCREEN 13 COLOR 0 PRINT CHR$(219) COLOR 15 PRINT SCREEN(1, 1)
Tulostetaan merkki 219, mutta SCREEN palauttaa kuitenkin 32, koska merkki tulostettiin mustalla.
Aihe on jo aika vanha, joten et voi enää vastata siihen.