Skip to content

Latest commit

 

History

History
358 lines (268 loc) · 17.3 KB

vdp_cursus_6.md

File metadata and controls

358 lines (268 loc) · 17.3 KB
              M S X 2 / 2 +   V D P   C U R S U S   ( 6  )
                                                           
      
      Zoals  beloofd  ga  ik  het deze  keer hebben  over sprites. 
      Voordat ik  begin met  het behandelen  van de echte sprites, 
      wil ik eerst nog even een misverstand uit de wereld helpen.
      
      
                     S O F T W A R E S P R I T E S 
      
      Misschien heeft u deze term wel eens gehoord of er iets over 
      gelezen. De doorsnee MSX'er weet wel dat er sprites bestaan, 
      maar  dat  er  verschil zou  zijn tussen  softwaresprites en 
      hardwaresprites  gaat de meesten boven de pet. En dat is ook 
      niet zo  vreemd, want  er bestaat  maar ��n soort sprites op 
      MSX,  de hardwaresprites.  Voor alle duidelijkheid: dit zijn 
      de  sprites  die je  in BASIC  aanstuurt met  PUT SPRITE  en 
      SPRITE$.
      
      Wat  zijn  die  softwaresprites  dan  wel?  Dat  zijn gewoon 
      plaatjes  die gekopieerd  worden. Die  plaatjes staan dan op 
      een onzichtbare  page en  worden met  een razendsnelle  COPY 
      opdracht  naar de  zichtbare pagina  gekopieerd. (Hoewel  ik 
      hier spreek  van 'razendsnel',  betekent dat niet dat er een 
      HMMM  (High-speed Move vraM to vraM) wordt gebruikt, dan kan 
      er geen  TPSET worden  gebruikt en  dat is  noodzakelijk bij 
      softwaresprites.  Er wordt  LMMM (Logical Move vraM to vraM) 
      gebruikt.)
      
      Softwaresprites  hebben  het voordeel  dat het  kleurgebruik 
      (zeker op SCREEN 8, op SCREEN 10 t/m 12 zijn softwaresprites 
      bijna onmogelijk)  onbeperkt is,  en dat  ze in theorie elke 
      grootte kunnen hebben. In praktijk kunnen ze natuurlijk niet 
      te  groot zijn,  want dan duurt het kopi�ren zo lang dat het 
      niet meer  mooi is.  Uiteraard kunnen  op de snelheidsduivel 
      turbo  R grotere  softwaresprites worden gebruikt, kijk maar 
      naar Seed of Dragon. 
      
      De  nadelen   zijn  ook   niet  mis:   het  is   trager  dan 
      softwaresprites,  moeilijker aan  te sturen  (je moet  alles 
      zelf doen) en het neemt meer VRAM in beslag. Bovendien is er 
      nog een  probleem: als de softwaresprite zich verplaats moet 
      het  VRAM dat  eronder zat  weer worden hersteld, dat is bij 
      gewone sprites niet nodig.
      
      Een ander  voordeel van  softwaresprites is  nog dat er geen 
      maximum  aantal  sprites  is  en  dat ze  nooit kunnen  gaan 
      knipperen,  maar  omdat  deze  problemen  alleen  bij  grote 
      aantallen  sprites voorkomen  en de softwaresprites dan veel 
      te langzaam worden is dat niet zo'n groot voordeel.
      
      Hardwaresprites  hebben tenslotte nog het voordeel dat je ze 
      heel makkelijk  stil kunt laten staan terwijl je de rest van 
      het  scherm  laat  scrollen (of  dat nu  hardwarematig (R#23 
      verticaal  / R#26  + R#27 horizontaal) of softwarematig (met 
      COPY) gaat).  Softwaresprites zou  je dan  elke keer  moeten 
      verplaatsen.
      
      De   softwaresprites   zullen   behandeld   worden   bij  de 
      toepassingen,  die  later  in de  cursus veelvuldig  aan bod 
      zullen komen. Ik ben behoorlijk afgedwaald, laten we nu maar 
      beginnen met het onderwerp van deze keer: (hardware)sprites.
      
      
                       S P R I T E   M O D E   2 
      
      Ik behandel hier alleen de zgn. SPRITE MODE 2, die in SCREEN 
      4 en  hoger wordt gebruikt. Dit is tenslotte een MSX2/2+ VDP 
      cursus, dus de MSX1 sprites slaan we over.
      
      Er zijn  32 sprites,  genummerd van  #0 tot  en met #31. Een 
      sprite  met een lager nummer heeft een hogere prioriteit. Er 
      kunnen maximaal  8 sprites  op een  horizontale lijn  worden 
      getoond. Zijn er meer dan 8 sprites op een horizontale lijn, 
      dan   worden  de  lijnen  van  de  sprites  met  de  laagste 
      prioriteit niet  getoond. Het  kan dus bijvoorbeeld gebeuren 
      dat een sprite voor de helft wegvalt.
      
      Als  de  ingekleurde  delen  van  twee sprites  elkaar raken 
      (botsen), zal bit 5 van S#0 worden geset. De co�rdinaten van 
      de  botsing  zullen  in S#3  t/m S#6  worden gezet  (zie VDP 
      cursus deel 5).
      
      Als  er negen of meer sprites op een horizontale lijn staan, 
      dan zal  bit 6  van S#0 worden geset. Bit 0-4 van S#0 zullen 
      dan het nummer bevatten van de negende sprite.
      
      Elke  horizontale lijn  van een  sprite mag  een eigen kleur 
      hebben uit het palet van 16 kleuren.
      
      De sprite  prioriteiten kunnen  worden uitgezet  door het CC 
      bit  van een  lijn te setten (zie verderop), de overlappende 
      gedeeltes van twee sprites worden dan geORd.
      
      
                    S P R I T E   R E G I S T E R S 
      
      De grootte van de sprite wordt bepaald door bit 1 van R#1.
      
          MSB   7   6   5   4   3   2   1   0   LSB
      R#1       0   BL IE0  M1  M2  0   SI MAG      Mode reg. #1
      
      SI = 1 : 16 x 16 pixels
      SI = 0 :  8 x  8 pixels
      
      De  sprite  kan op  normaal formaat  of vier  maal zo  groot 
      worden weergegeven. Dit wordt bepaald door bit 0 van R#1.
      
      MAG = 1 : vergroot
      MAG = 0 : normaal
      
      Met bit 1 van R#8 kan worden bepaald of de sprites aanstaan. 
      Als er geen sprites worden gebruikt, zet ze dan uit want dan 
      werkt  de VDP  sneller (meet  het maar  eens na, het scheelt 
      behoorlijk!).
      
          MSB   7   6   5   4   3   2   1   0   LSB
      R#8       MS  LP  TP  CB  VR  0  SPD  BW      Mode reg. #2
      
      SPD = 1 : disable sprites (zet sprites uit)
      SPD = 0 : enable  sprites (zet sprites aan)
      
      De vorm  van de  sprite staat in de Sprite Pattern Generator 
      Table.  Er kunnen  256 patronen  worden opgeslagen van elk 8 
      bytes lang  (#0 t/m #255). Het beginadres van een patroon is 
      als volgt te berekenen:
      
      <begin tabel> + <patroon nummer> * 8
      
      De  kleuren van  een sprite  staan in de Sprite Color Table. 
      Behalve de kleuren worden er ook drie attribuutbits per lijn 
      opgeslagen. 8x8  sprites vergen  8 bytes,  16x16 sprites  16 
      bytes. Het beginadres van de kleurinfo van een sprite is als 
      volgt te berekenen: (er is 1 positie per sprite, #0 t/m #31)
      
      <begin tabel> + <sprite nummer> * 16
      
      De  overige attributen  (coordinaten en patroonnummer) staan 
      in de  Sprite Attribute  Table, 4  bytes per  sprite (#0 t/m 
      #31). Het beginadres van de attributen van een sprite is als 
      volgt te berekenen:
      
      <begin tabel> + <sprite nummer> * 4
      
      N.B. al deze tabellen staan in het VRAM.
      
      
              S P R I T E   A T T R I B U T E   T A B L E 
      
      Op <begin adres> + 0 staat de Y-co�rdinaat, 0 t/m 255. Is de 
      Y coordinaat gelijk aan 216, dan worden alle sprites met een 
      lagere  prioriteit niet  getoond, inclusief  de sprite zelf. 
      Let op:  de bovenste  lijn van de sprite komt ��n lijn lager 
      dan de hier opgegeven y-co�rdinaat.
      
      Op <begin  adres> +  1 staat de X-co�rdinaat, van 0 t/m 255. 
      Let  op: ook  in SCREEN  6 en 7 wordt de horizontale as voor 
      sprites in 256 stapjes verdeeld, en niet in 512!
      
      Op  <begin adres> + 2 staat het patroonnummer. Hiermee wordt 
      aangegeven  welk  patroon  uit  de Sprite  Pattern Generator 
      Table moet  worden genomen.  Let op:  als de  sprite grootte 
      16x16  is,  dan  worden er  vier patronen  genomen voor  ��n 
      sprite.  Het maakt dan niet uit welke van de vier nummers je 
      opgeeft. Er  zijn dus  in feite  maar 64  patronen bij 16x16 
      sprites.
      
          MSB   7   6   5   4   3   2   1   0   LSB
      R#5      A14 A13 A12 A11 A10  A9  1   1    Sprite attr. tab.
      R#11      0   0   0   0   0   0  A16 A15   base adress reg.
      
      Het beginadres van de attribuuttabel is hier opgeslagen. Let 
      op:  bit A9  is altijd 1. Door deze registers te manipuleren 
      is het  mogelijk om de informatie van meer dan 32 sprites in 
      het  VRAM op  te slaan  of om  bijvoorbeeld PAGE  0 te tonen 
      terwijl de attribuuttabel ergens in PAGE 2 staat.
      
      
             P A T T E R N   G E N E R A T O R   T A B L E 
      
      In  deze  tabel staan  de bit-matrices  die de  vorm van  de 
      sprites bepalen.  Het werkt heel simpel; 0 staat voor uit en 
      1  voor aan.  Een spookje  uit Pacman zou er bijvoorbeeld zo 
      uit kunnen zien:
      
                               &B00111100
                               &B01111110
                               &B11011011
                               &B11011011
                               &B11111111
                               &B11111111
                               &B11011011
                               &B11011011
      
      Voor elk patroon worden 8 bytes gebruikt. Er zijn totaal 256 
      patronen, genummerd  van #0 t/m #255. Bij 8x8 sprites krijgt 
      elke sprite ��n patroon, een 16x16 sprite krijgt er vier.
      
          MSB   7   6   5   4   3   2   1   0   LSB
      R#6       0   0  A16 A15 A14 A13 A12 A11   Sprite patt. tab.
      
      Hier  is het  beginadres van  de tabel  opgeslagen. Door het 
      manipuleren met  dit register  kunnen bijvoorbeeld veel meer 
      dan 256 patronen gelijktijdig in het VRAM worden gezet, etc.
      
      
                  S P R I T E   C O L O R   T A B L E 
      
      Elke  horizontale lijn kan zijn eigen kleur krijgen (kleur 0 
      is altijd  transparant). Bovendien kunnen per lijn de sprite 
      prioriteit,  de botsingsdetectie  en de 'early clock' worden 
      aan- of uitgezet.
      
      Het beginadres  van deze tabel ligt altijd precies 512 bytes 
      onder  het  beginadres  van de  Sprite Attribute  Table. Per 
      Sprite   (32   stuks,   #0  t/m  #31)  worden  er  16  bytes 
      gebruikt. Dat maakt totaal 512 bytes. Elke byte is als volgt 
      opgebouwd:
      
          MSB   7   6   5   4   3   2   1   0   LSB
                EC  CC  IC  0  ----kleur------ 
      
      EC:     Early Clock, 1: verschuif lijn 32 bits naar links
      CC:     Priority Enable, 1: OR kleuren als sprites
                                  overlappen
      IC:     Collision Detect, 1: negeer botsingen
      
      Bij CC=1 worden ook de botsingen niet gedetecteerd.
      
      
                   S P R I T E   P R I O R I T E I T 
      
      De sprite prioriteit wordt uitgezet als het CC-bit gelijk is 
      aan  1. De  lijnen van een sprite waarvan CC gelijk is aan 1 
      worden alleen  getoond als  er op diezelfde horizontale lijn 
      een sprite met een lager spritenummer voorkomt.
      
      Dit  kan ook  worden gebruikt om extra kleuren te cre�ren in 
      een samengestelde  sprite (een  'sprite' die  uit een aantal 
      afzonderlijke sprites is opgebouwd). Bijvoorbeeld:
       
      888888--     ----4444     8888CC44
      888888--     ----4444     8888CC44
      888888--  +  --------  =  888888--
      888888--     11------     998888--
      888888--     11------     998888--
      --222222     11------     11222222
      -2222222     11------     13222222
      22222222     11------     33222222
      
      Op deze manier is het dus vrij eenvoudig om op een lijn drie 
      verschillende  kleuren  te  krijgen,  terwijl  je maar  twee 
      sprites gebruikt.
      
      
                      S P R I T E   B O T S I N G 
      
      Dit  hebben we ook al bij de statusregisters behandeld, maar 
      voor de  overzichtelijkheid behandelen  we het  nog maar een 
      keer.
      
      Als  CC gelijk is aan 0 en gedeeltes van een sprite die geen 
      kleur 0  hebben overlappen  elkaar, dan  wordt er een sprite 
      botsing gedetecteerd. Bit 5 van S#0 wordt dan geset. Dit bit 
      wordt weer gereset als S#0 wordt gelezen.
      
          MSB   7   6   5   4   3   2   1   0   LSB
      S#0       F   9S  C  ----9th sprite #---   Status reg. #0
      
      C  = collision,  9S =  negen sprites/regel,  9th sprite  # = 
      nummer van negende sprite.
      
      Als  MS en  LP niet  geset zijn  (R#8, muis en lichtpen, bij 
      V9958  niet  aanwezig),  dan  worden de  co�rdinaten van  de 
      botsing in de statusregisters S#3 t/m S#6 gezet:
      
          MSB   7   6   5   4   3   2   1   0   LSB
      S#3       X7  X6  X5  X4  X3  X2  X1  X0   Status reg. #3
      S#4       1   1   1   1   1   1   1   X8   Status reg. #4
      S#5       Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0   Status reg. #5
      S#6       1   1   1   1   1   1   1   Y8   Status reg. #6
      
      Van de X co�rdinaat moet nog 12 worden afgetrokken en van de 
      Y co�rdinaat 8.
      
      
                      S P R I T E   K L E U R E N 
      
      In  SCREEN 5, 7, 10, 11 en 12 zijn de kleuren van de sprites 
      gelijk aan  de kleuren  uit het  palet. In  SCREEN 8  worden 
      andere kleuren gebruikt:
      
      Kleurcode:      Groen:  Rood:   Blauw:
      ----------------------------------------------------
      0               0       0       0       transparant
      1               0       0       2       d. blauw
      2               0       3       0       d. rood
      3               0       3       2       d. magenta
      4               3       0       0       groen
      5               3       0       2       blauw/grijs
      6               3       3       0       oker
      7               3       3       2       grijs
      8               8       7       2       zalmrose
      9               0       0       7       blauw
      10              0       7       0       rood
      11              0       7       7       magenta
      12              7       0       0       l. groen
      13              7       0       7       cyaan
      14              7       7       0       geel
      15              7       7       7       wit
      ----------------------------------------------------
      
      SCREEN  6 is  ook een speciaal geval, omdat er dan maar vier 
      kleuren zijn.  Die kleuren worden ook in de sprites gebruikt 
      en het palet kan aangepast worden. Je kunt hier 'gestreepte' 
      sprites maken. De kleurcode wordt als volgt geinterpreteerd:
      
      MSB   3   2   1   0   LSB
           -even-- -oneven            Kleurcode (0-15)
      
      De bovenste  twee bits  worden gebruikt voor de kleur van de 
      oneven pixels en in de onderste twee bits staat de kleur van 
      de oneven pixels. Beide kleuren kunnen liggen tussen 0 en 3.
      
      
                       T P   E N   S P R I T E S 
      
      Bit  5 van  R#8 (TP)  geeft aan of kleur 0 transparant is of 
      dat kleur  0 gewoon  als paletkleur  kan worden gebruikt. In 
      samenhang met sprites zijn er twee situaties:
      
      TP=0:  (gedeeltes van)  sprites met  kleurcode 0 worden niet 
      getoond,  op  die  plaats  kan dan  ook geen  botsing worden 
      gedetecteerd.
      
      TP=1:  (gedeelte)  van  sprite  met  kleurcode  0 wordt  wel 
      getoond, volgens  de paletkleur  (in SCREEN 8 altijd zwart), 
      spritebotsingen worden normaal gedetecteerd.
       
      
                            T O T   S L O T 
      
      Voor  het aansturen  van sprites  is schrijven naar het VRAM 
      noodzakelijk. Lees  de procedures  daarvoor nog maar eens na 
      in  deel 1  van de cursus. Het geeft bijvoorbeeld een enorme 
      snelheidswinst  om  eerst de  VDP klaar  te zetten  voor het 
      schrijven van data vanaf een bepaald adres, en vervolgens de 
      data rechtstreeks  naar Port  #0 (port  &H98) te sturen. Bij 
      sprites  moeten er  toch vaak achterelkaar liggende adressen 
      worden beschreven.
      
      Waarschijnlijk  zal er  in VDP  Cursus deel  15 (die komt op 
      Sunrise  Magazine   #10)  een  routine  met  sprites  worden 
      behandeld.
      
      Veel succes met sprites op MSX en tot de volgende keer.
      
                                                      Stefan Boer