VCSROL will nicht so wie ich will


VCSROL will nicht so wie ich will

von FlorianD » Mo 19. Jul 2010, 23:56
Hi,

gibt es bei VSCROL (54277) irgendwelche Falltüren zu beachten? Wert setzen nur im/vor/nach dem VBI oder sowas?
Ich versuche ein V/H Scrolling hinzukriegen, Hor geht ohne Probleme, Ver ging, aber nun nicht mehr. Ich habe "nichts" an den Codeteilen geändert. Wenn ich eine Endlosschleife laufen lasse und dabei den Wert ändere, scrollt es. Nicht aber in meiner normalen Schleife, die den Stick abfragt und dann grob und feinscrolling ausführt.

Grüße,
Florian

Re: VCSROL will nicht so wie ich will

von Dietrich » Di 20. Jul 2010, 00:02
Da müsstest Du uns schon den Code zeigen ...

Re: VCSROL will nicht so wie ich will

von FlorianD » Di 20. Jul 2010, 23:13
hier ist der Code, da steckt irgendwo ein MASSIVER Denkfehler drin, und ich seh den Wald vor lauter Zwergen nicht mehr. Oder so.
Code: Alles auswählen
SET $0E=$4002 ; fang bei 4002 an, stellt sicher dass wir keine 4k oder 1k grenze streifen mit Bilddaten oder Displaylist
SET $491=$4002

INCLUDE "D1:LEVEL.ACT"  ; hier sind nur die Bilddaten des Levels drin. 36 Zeilen a 40 Zeichen = 2 Screens breit und 3 hoch in GR.2

PROC DLIST=*()   ; die Daten der DisplayList als Code Block
[$60 $70
$77 $00 $00 $77 $00 $00 $77 $00 $00
$77 $00 $00 $77 $00 $00 $77 $00 $00
$77 $00 $00 $77 $00 $00 $77 $00 $00
$77 $00 $00 $77 $00 $00 $57 $00 $00
$00
$42 $00 $00
$41 $00 $00]
;RETURN

PROC SZ=*()  ; Die Statuszeile am unteren Bildrand als interne Codes (hier fehlen die "Herzchen" stattdessen habe ich "§" reingemacht)
 BYTE ARRAY S="§,)6%3§@@@§(%!,4(§§§§§§§§§§§§§§+++§§§§§§"
RETURN

PROC SETPOS(CARD X,CARD Y)
 CARD POINTER P
 CARD I,C,D
 BYTE J
 ;       setzt den Bildausschnitt
 C=LEVEL-2 ; setzt c auf die Adresse von Level (ohne das -2 geht es nicht genau, weiss nicht warum)
 P=DLIST ; pointer auf die Display list DLIST ist 7 Leerzeilen 8 Leerzeilen, 1Bildzeile(GR.2)
 FOR I=0 TO 11 DO
  P=P+3    ; 3 vor auf die erste Adresse am 4 Byte
  D=0 ;diese schleife "multipliziert ohne *" also y+1 mal 40 addieren
  FOR J=1 TO Y+I DO
   D=D+40
  OD
  P^=C+X+D   ; ((Y+I)*40)   und über den pointer in die adresse setzen. funzt auch alles
 OD     
RETURN
 
PROC WAIT(BYTE I) ; tut i * 1/50 sek warten
 BYTE CLK=20
 ;
 CLK=0
 DO
  UNTIL CLK>I
 OD
RETURN


PROC MAIN()
 CARD POINTER PTR
 BYTE POINTER XTR
 CARD X,Y,C
 CARD DLPTR=560
 CARD HSCROL=54276,VSCROL=54277,
      WSYNC=54282,COLPF1=708
 BYTE DX,DY,I,CONSOL=53279
 ;           
 PTR=DLIST+40
 PTR^=(SZ+1) ;ADR FUER STATUTSZEIL SETZ
 PTR=PTR+3
 PTR^=DLIST ;RUECKSPRUNGADR DER DLI SETZEN

 DLPTR=DLIST       ; DLI einschalten

 COLPF1=2  ; farbe setzen auf grau
 
 X=10 Y=12 ; startpos des Screens, "die mitte"
 SETPOS(X,Y) ; screen setzen

 DX=0 ; finescroll x=y=0
 DY=0           
 VSCROL=DY
 HSCROL=DX

 DO
  I=STICK(0)
  IF I<>15 THEN ; wenn Stick bewegt

   IF I=14 AND Y>0 THEN ;UP
    DY=DY+1
    IF DY=16 THEN
     DY=0
     Y=Y-1
    FI
   FI

   IF I=13 AND Y<24 THEN ;DN
    IF DY=0 THEN
     DY=15
     Y=Y+1
    ELSE
     DY=DY-1
    FI
   FI

   IF I=11 AND X>0 THEN ;LF
    DX=DX+1
    IF DX=8 THEN
     DX=0
     X=X-1
    FI
   FI

   IF I=7 AND X<21 THEN ;RT
    IF DX=0 THEN
     DX=7
     X=X+1
    ELSE
     DX=DX-1
    FI
   FI
   ;alle richtungen abgefragt, eine war es, weil ja stick<>15
  ;also bild neu setzen
   VSCROL=DY
   HSCROL=DX
   SETPOS(X,Y)
  ELSE                   
   ;
   IF CONSOL=6 THEN ; wenn man den Stick nicht rührt, kann man START drücken und dann scrollt es langsam. warum tut es das hier, aber oben in der schleife nicht?!?!??
    DY=DY+1
    VSCROL=DY
    IF DY=16 THEN
     DY=0
    FI
    WAIT(1)
   FI
   ;
  FI
 OD
RETURN

Re: VCSROL will nicht so wie ich will

von eda70 » Mi 21. Jul 2010, 10:39
Ich kenn mich zu wenig mit dem Finescrolling aus...
Unten benuzt du setpos und x und y nicht. Vieleicht liegt es daran.
Vielleicht kann v und h-scroll nicht "wirken" weil es von setpos überschrieben wird?
C=LEVEL-2 ; setzt c auf die Adresse von Level (ohne das -2 geht es nicht genau, weiss nicht warum)
Kann das an der Standard-Randeinstellung liegen?

Re: VCSROL will nicht so wie ich will

von FlorianD » Mi 21. Jul 2010, 11:15
@eda: bei GR.2 gibt es keinen Standardrand wie in GR.0

Re: VCSROL will nicht so wie ich will

von Dietrich » Mi 21. Jul 2010, 21:06
Oha, das sieht ja schon fast wie Assembler aus - besonders die coole Multiplikation mit 40 ;-)

FlorianD hat geschrieben:alle richtungen abgefragt, eine war es, weil ja stick<>15

Nö, wenn man den Stick schräg hält, greift keine der Abfragen. Also besser die Bits testen (in ACTION wahrscheinlich I&1, I&2, I&4, I&8). Hat auch den Vorteil, dass Du dich diagonal bewegen kannst.

FlorianD hat geschrieben:wenn man den Stick nicht rührt, kann man START drücken und dann scrollt es langsam. warum tut es das hier, aber oben in der schleife nicht?!?!??

Bau mal oben hinter DO einen WAIT(0) in die Schleife ein. Oder wenn's langsamer sein soll WAIT(1).

Re: VCSROL will nicht so wie ich will

von FlorianD » Mi 21. Jul 2010, 22:21
Dietrich hat geschrieben:
FlorianD hat geschrieben:alle richtungen abgefragt, eine war es, weil ja stick<>15

Nö, wenn man den Stick schräg hält, greift keine der Abfragen. Also besser die Bits testen (in ACTION wahrscheinlich I&1, I&2, I&4, I&8). Hat auch den Vorteil, dass Du dich diagonal bewegen kannst.

FlorianD hat geschrieben:wenn man den Stick nicht rührt, kann man START drücken und dann scrollt es langsam. warum tut es das hier, aber oben in der schleife nicht?!?!??

Bau mal oben hinter DO einen WAIT(0) in die Schleife ein. Oder wenn's langsamer sein soll WAIT(1).

Hi, das hilft leider auch nichts. Was wäre der Sinn gewesen?

Re: VCSROL will nicht so wie ich will

von Dietrich » Mi 21. Jul 2010, 22:44
Wenn Du ohne Pause durch die Schleife hetzt, änderst Du VSCROL und HSCROL schneller als der Bildschirm dies anzeigen kann. Also musst Du mindestens 1 Vertical Blank nach jedem Scroll warten, bis das Ergebnis sichtbar wird. Das tut WAIT(0) - WAIT(1) wartet bis zum übernächsten VBlank, was das Scrollen langsamer macht.

Dann weiß ich auch nicht weiter. Dir bleibt nichts übrig, als mal ein paar Checks zu machen, ob der Code auch wirklich richtig durchlaufen wird. Der Code unten bei CONSOL sieht auch anders aus als oben (einmal zählt VSCROL von 0 bis 15, einmal von 1 bis 16) Kopiere z.B. den CONSOL-Codeteil innerhalb des IF nach oben und entferne VSCROL=DY, HSCROL=DX, SETPOS(X,Y) - der Teil wird ja unten auch nicht durchlaufen. Oder mach statt der Joystickabfrage IF I=13 oben eine Abfrage auf CONSOL=6 und ohne die Y-Begrenzung. Dann wirst Du das Problem schon finden.

Re: VCSROL will nicht so wie ich will

von FlorianD » Do 22. Jul 2010, 00:32
Ich *glaube* ich habe es. Nach einigem Ausprobieren schien es so als ob HSCROl auch VSCOL beeinflussen würde. Je nachdem, wo im Code die Zeilen standen, ergab sich "funktioniert" oder "geht nicht".
Code: Alles auswählen
DY=DY+1
VSCROL=DY
If DY=16 THEN
...
FI

reagierte anders als
Code: Alles auswählen
DY=DY+1
If DY=16 THEN
...
FI
VSCROL=DY

auch wenn der IF Block gar nicht durchlaufen wurde.

Im "DE RE ATARI" (deutsch) stand dann auf S.67/68, dass der ANTIC "verwirrt" würde, wenn er gerade am Bild malen wäre, und man daher die HSCROL und VSCROL nur im VBI ändern sollte.
Das muss ich nun mal irgendwie umsetzen. Morgen mehr.

Leider kann ich nicht zur Fujiama kommen, würde echt gerne und mit Euch zusammen programmieren. Aber ich habe eine lange geplante Auslandsreise mit der Familie. Andermal dann! Auf jeden Fall wünsche ich Euch viel Spass!!!

Re: VCSROL will nicht so wie ich will

von Jac » Fr 23. Jul 2010, 11:59
Hi,

Wenn man den Werte in VSCROLL innerhalb einer V-scroll-area ändert, wird's hakelig. Der ANTIC fängt dann an Zeilen wegzulassen oder zu verdoppelt, weil der Scanline-Counter dann den Wert in VSCROLL "verpasst". So funktionieren die Software Modes GR. 9++ und 40x40 Zeichen. Daher den VSCROLL werte immer außerhalb der Area setzen (z.B. VBI oder DLI). So lange Du die Joystick-Abfrage nicht drin hattest, war das durch "WAIT(1)" gegeben. Jetzt ist da mehr Code und Zeilenstrahl ist schon weiter. Ersetze doch mal VSCROLL durch $D01A. Dann wirst Du sehen wo der Zeilenstrahl ist, wenn das Setzen stattfindet.

Re: VCSROL will nicht so wie ich will

von Jac » Fr 23. Jul 2010, 15:26
Nachtrag: Damit kannst Du das ganze evtl. auf einfache Weise fixen:

Code: Alles auswählen
WAIT(1); Erst warten bis Zeilenstrahl oben
VSCROL=DY
HSCROL=DX


Das ist auch die Antwort, warum es im ELSE mit START funktioniert.

Re: VCSROL will nicht so wie ich will

von eda70 » Fr 23. Jul 2010, 16:39
Dietrich hat geschrieben:Nö, wenn man den Stick schräg hält, greift keine der Abfragen. Also besser die Bits testen (in ACTION wahrscheinlich I&1, I&2, I&4, I&8). Hat auch den Vorteil, dass Du dich diagonal bewegen kannst.

Um die IF-Quälerei bei der Joystickabfrage zu umgehen, hier der Versuch zweier Funktionen, die direkt mit dem Abfragewert aus Stick0... aufgerufen werden können und -1, 0, 1 zurückgeben.
Code: Alles auswählen
Int FUNC HSTICK(INT joyq)
  joyq==RSH 2
  IF joyq >1 then
    joyq==-3
  FI
RETURN (joyq)

Int FUNC VSTICK(INT joyq)
  joyq==&$F3
  IF joyq >1 then
    joyq==-3
  FI
RETURN (joyq)
Kann man das noch weiter optimieren?

Re: VCSROL will nicht so wie ich will

von Jac » Fr 23. Jul 2010, 19:26
Das schnellste in ASM ist LSR:
x=xpos; y = ypos

Code: Alles auswählen
lda $d300; oder Schattenregister
lsr
bcc dir1
inx
dir1:
lsr
bcc dir2
dex
dir2:
lsr
bcc dir3
iny
dir3:
lsr
bcc dir4
dey
dir4:
rts

Vermutlich habe ich hierbei links/rechts/oben/unten vertauscht, aber es geht ja im die Idee. Weis auch nicht, ob/wie das in ACTION effizient umzusetzen ist. Kann ACTION nicht ASM inlining?

Re: VCSROL will nicht so wie ich will

von eda70 » Fr 23. Jul 2010, 20:15
:D Ja, das habe ich mir schon gedacht, dass es mit ASM noch schneller geht. Und ja, man kann in Action auch ASM einbauen. Meine Frage zielte aber eher auf die Action!-Bordmittel :)

Re: VCSROL will nicht so wie ich will

von Dietrich » Fr 23. Jul 2010, 23:10
FlorianD hat geschrieben:Im "DE RE ATARI" (deutsch) stand dann auf S.67/68, dass der ANTIC "verwirrt" würde, wenn er gerade am Bild malen wäre, und man daher die HSCROL und VSCROL nur im VBI ändern sollte.
Das muss ich nun mal irgendwie umsetzen. Morgen mehr.

Richtig! Aber Du musst es nicht unbedingt im VBI machen. Mache einfach meinen vorgeschlagenen WAIT(0) direkt vor Setzen von HSCROL und VSCROL, dann kann nichts passieren, da der ANTIC nach dem abgewarteten VBI mehr als 7000 Takte später erst mit der DLIST loslegt. (Offenbar ist die Schleife insgesamt länger als 7000 Takte, so dass beim Setzen von HSCROL und VSCROL schon der ANTIC den Scrollbereich zeichnet, wenn Du WAIT(0) ganz am Schleifenanfang setzt.)

Gruß Dietrich (der schon lange nicht mehr Finescrolling programmiert hat)

Re: VCSROL will nicht so wie ich will

von cas » So 25. Jul 2010, 21:49
eda70 hat geschrieben::D Ja, das habe ich mir schon gedacht, dass es mit ASM noch schneller geht. Und ja, man kann in Action auch ASM einbauen. Meine Frage zielte aber eher auf die Action!-Bordmittel :)


Ohne IF THEN, stattdessen mit Bit-Manipulation und boolscher Logic sollte es schneller gehen. Dann generiert ACTION! Code der warscheinlich an ASM heranreicht.

Re: VCSROL will nicht so wie ich will

von eda70 » Do 27. Jan 2011, 12:44
cas hat geschrieben:Ohne IF THEN, stattdessen mit Bit-Manipulation und boolscher Logic sollte es schneller gehen. Dann generiert ACTION! Code der warscheinlich an ASM heranreicht.

Noch mal drüber nach gedacht.
Hier das Ergebnis:
Code: Alles auswählen
Int FUNC HSTICK(INT joyq)
  INT aw 
 
  joyq==RSH 2
  aw=joyq &$FD
  joyq== RSH 1
  aw=aw-joyq
RETURN (aw)

Int FUNC VSTICK(INT joyq)
  INT aw

  joyq ==&$F3
  aw=joyq &$FD
  joyq== RSH 1
  aw=aw-joyq
RETURN (aw)


...und hier das ganze auf die Spitze getrieben (mir war danach) :)
Code: Alles auswählen
;liefert +1 rechts -1 links und 0 für center
INT FUNC HSTICK=*(BYTE joyq)
[ $A2 $00 $A0 $00 $4A $4A $18 $4A
  $B0 $02 $CA $88 $4A $B0 $01 $E8
  $86 $A0 $84 $A1 $60 ]

;liefert +1 unten -1 oben und 0 für center
INT FUNC VSTICK=*(BYTE joyq)
[ $A2 $00 $A0 $00 $29 $F3 $18 $4A
  $B0 $02 $CA $88 $4A $B0 $01 $E8
  $86 $A0 $84 $A1 $60 ]

Der Rückgabewert von Funktionen wird in Action! via $A0 und $A1 transportiert.