Enterprise Forever
:HUN => VIDEO: => Topic started by: endi on 2019.April.13. 23:57:10
-
Elkezdtem basic-ben írni egy rendszert karakteres (főleg gracha) módhoz. Poke-okkal műxik és zzzippel fordítható lesz. De a lényeg az lenne ha valaki majd átírná asm-ba (egyszerű lesz), mert én már nem akarok gépi kóddal foglalkozni. De direkt úgy írom meg basic-ben is hogy könnyen átírható legyen.
A lényeg, azaz ilyen funkciók lesznek:
-gracha képernyőt kirajzolja (pálya rajzoló).
-kirak egy 2x2-es "sprite"-ot (gracha elem).
-kirak nagyobb sprite-ot egy háttér bufferből, ami egy gracha képernyő (megadható a sprite mérete).
-visszarajzolja a gracha pálya 2x2-es vagy más megadott méretű részét.
-gracha pálya betöltés.
-gracha háttér képernyő betöltés (lényegében egy másik pálya). ide rajzolhatjuk a sprite-okat, akármekkorát is.
-olyan sprite rajzoló, ami egyszerre rajzol ki sok sprite-ot. ez azért szükséges, mert gyorsabb lesz tőle, mintha basicből vezérelnék egyenként a sprite rutint. tehát basicben csak meg kell adni mondjuk 8 sprite koordinátáit és sprite számát (hogy melyikeket rajzolja ki), meghívjuk ezt a rutint és kirajzolja őket egyszerre.
-valami scroll dolog. egyelőre valszeg ez csak annyi lesz hogy a pálya kirajzoló megadott eltolással tudja kirakni a pályát.
-dupla bufferes kirajzolás, azaz egy háttér bufferbe rajzol mindent, azután azt megjeleníti. esetleges villogások elkerülésére.
-mindenféle automatikus raszter színező rutinok, hogy aki nem akar vagy nem tud gracha editorban színezni, annak is legyenek szép színei. :)
-valamiféle ütközésvizsgálat: ez lehet sprite-ok közötti és a pályával.
-valami particle rendszer (sok karakter gépi kóddal való mozgatása, pl robbanás).
-dupla buffer: a videolapot 2x-es magasságúra nyitom, és így dupla bufferként használható. így teljesen megszűntethető minden villogás.
Elvileg mivel ügye karakteres képernyő, ez olyan gyors lehet, hogy akár úgy is megfelelő sebességű lesz, ha az egész képernyőt folyton visszarajzoljuk és rárajzolunk 8-10 "sprite"-ot.
A lényeg pedig az lenne hogy ezzel a rendszerrel könnyen lehessen basic-ben látványosabb játékokat csinálni.
Gépi kódra majd akkor kell átírni, ha kiforrott az egész.
-
itt egy mínusz egyedik verzió. kimásol a képre valami memóriát, majd rárajzol egy nagy sprite-ot.
látható hogy zzzippelve a poke se elég gyors ehhez, de majd gépi kódban. :) és úgy villogni se fog!
na meg az se szükséges minden játéktípusnál, hogy az egész képernyőt mindig újra kirajzoljuk. de akarok majd kísérletezni scrollos játékkal. tök jó lesz basic-ben ilyeneket csinálni. :)
-
jól hangzik :)
-
az első hozzászólást frissítem ha új ötlet van, vagy ha valami elkészült
-
meg tudná valaki írni nekem a betöltést?
allocate-al lefoglalt memóriában akarok betölteni. 42*24*2 bájthoz szerintem nem kéne szegmenst foglalni :)
a formátum amit binárisan ment az editor:
pálya:
24 sor, 42 bájt per sor
színek soronként:
24 sor, 8 bájt soronként
definiált karakterek:
1 bájt a karakter kód, 9 bájt per karakter a definíció, és 20*4 karakter van elmentve (mivel 2x2-es blokkokból áll és 20 ilyen 2x2-es elem van. a pálya nem ezekből épül hanem simán csak 24*42 karakterből, ez a 2x2-es dolog csak az editálást segíti az editorban).
-
úgy értem asm-ban :)
jó tudom, csak pár sor... de már nem emlékszem az exos dolgokra, és van akinek kisujjában van ma is:)
-
Egyből a karaktermapbe, karakterkészletbe, és az LPT-be a megfelelő dolgokat?
-
Egyből a karaktermapbe, karakterkészletbe, és az LPT-be a megfelelő dolgokat?
hát ez se ártana igen, de egyelőre csak a pályára gondoltam, hogy allocate-al lefoglalt címre betölteni.
de a többi is jöhet :)
-
Nekem egyszerűbb a videómemóriába, mivel nem tudom, hogy az allocate-tel lefoglalt cím hol van :D
-
mivel nem tudom, hogy az allocate-tel lefoglalt cím hol van :D
Azt vagy hívásnál lehet átadni, és akkor a HL-ben lesz, vagy pedig a megfelelő helyen CODE változó=, és aztán a változó értékét bepókolni a töltő kódba a megfelelő helyen.
-
Azt vagy hívásnál lehet átadni, és akkor a HL-ben lesz, vagy pedig a megfelelő helyen CODE változó=, és aztán a változó értékét bepókolni a töltő kódba a megfelelő helyen.
igen, valami ilyen dereng nekem is :)
-
Nekem egyszerűbb a videómemóriába, mivel nem tudom, hogy az allocate-tel lefoglalt cím hol van :D
az azért nem jó, mert háttér bufferben kell lennie a pályának, mert azt fogjuk átmásolni a videomembe amikor szükség van rá, pl sprite mögötti terület újrarajzolásánál.
pont ez lenne a lényege a rendszernek!
-
A HL szimpatikusabb is :)
push hl
xor a
ld de,filename
exos 1
jr nz,unsucc
pop de
ld bc,24*42+24*8+20*4*9
exos 6
unsucc
xor a
exos 3
ret
filename dbl "file"
-
már csak az a kérdés hogy több címet vagy file név címét hogy lehet átadni a basic code hex utasításba?
-
mondjuk lehet hogy kéne egy külön topik arra hogy "asm basic-ben"...
-
Hi
As a comment to your discussion about sprites in a BASIC environment... I recently wrote some code in pure BASIC to see if I could make a reasonably good sprite in BASIC without resorting to MC code. I was also looking at using attribute mode in BASIC. So I combined the two things in the included test program. The end result, after compiling it with ZZZIP, was actually kind of useful with nearly 10 fps in a double buffer display using two video pages, which surprised me a bit.
You can fly the sprite in all directions using the cursor keys, and stop the program using the ESC key. It will only fly as far as the borders and then reduce the speed in the current direction to 0. Acceleration is done by repeatedly pressing a cursor key. Max speed is 4 pixels in any direction.
Just load the image and press START.
Of course you cannot run many sprites this way, unless they are very thin in height. You have to plot each scan-line in a cell (in attribute mode anyway). So the current sprite, which is 9 scanlines high and 2 cells wide, requires 18 spokes. The two video pages used are cleared before each update, which also takes some time, especially if you want a large page display. Therefore I limited it to 20 x 10.
You can avoid clearing the displays constantly, if you systematically erase the cells you used from the previous sprite plotting. In this case it requires another 18 spokes. So if you use this method, it slows the system severely, if you have more than 2-3 sprites. The good news is then, that you do not have to redraw the background, except where you erased the plots.
In flew the sprite from left to right (160 pixels( in about 18 seconds in 1 pixel steps in the ZZZip version. In BASIC it is about 5-6 times slower.
regards
Jesper
-
Wonderful demo! pixel perfect.
I wonder if it can be put on a machine code library or an engine, then it will be more usable.
-
Hi
Well, the code was a sort of 'proof of concept' to test if it is possible to make reasonable sprites in BASIC, and within limits this seems to be the case.
The main trick for speeding up the code is to avoid arrays if possible and to precalculate everything once before using the results in the main loop and plot routine. Common sense really, and it improves the speed by about 50%! You also have to rewrite a few address specifications to get them to work with ZZZIP. All peeking and poking is done using speek/spoke. This minimizes the limitations from ZZZIPs integer code and results in very fast code in ZZZIP.
The code around line 7000 is just there in case you want to implement some code to react to specific events. In the code example below, there are no such events, but you might implement a collision check or whatever, and put it there.
Anyway, here is the BASIC code, if you feel like trying it out.
regards
Jesper
1 PROGRAM "spr_test.bas"
2 !
5 TEXT 80
10 NUMERIC GFX1(1 TO 9) , OFFX1 (1 TO 9,0 TO 8) , OFFX2 (1 TO 9,0 TO 8)
20 NUMERIC OX,OY,ODX,ODY,OHGT,OWID
30 NUMERIC I,J,CL,ZX,ZY,M1,M2,CH,KOX,DWID,DHGT,SP
40 NUMERIC LPTLOW,LPTHIGH,LPT,LBLOCK
50 NUMERIC LD1LOW,LD1HIGH,LD1(1 TO 2),LD1PAGE(1 TO 2)
60 NUMERIC LD2LOW,LD2HIGH,LD2(1 TO 2),LD2PAGE(1 TO 2)
65 STRING T$*1,ESC$*1,LEFT$*1,RIGHT$*1,UP$*1,DOWN$*1,T1$
70 LET WID=20:LET HGT=10:LET LBLOCK=15
80 LET ODX=1:LET ODY=0:LET OHGT=9:LET OWID=8:LET SP=4
81 LET OX=1:LET OY=1
99 !
100 CALL INIT_VARS
110 CALL INIT_VPAGES
998 LET T1$=TIME$
999 !
1000 DO
1005 IF GET_EVENT THEN CALL EVENT_HANDLER
1010 LET T$=INKEY$
1012 IF T$<>"" THEN
1015 SELECT T$
1020 CASE ESC$
1021 PRINT T1$,TIME$
1025 EXIT DO
1030 CASE LEFT$
1035 LET ODX=MAX(ODX-1,-SP)
1040 CASE RIGHT$
1045 LET ODX=MIN(ODX+1,SP)
1050 CASE UP$
1055 LET ODY=MAX(ODY-1,-SP)
1057 CASE DOWN$
1060 LET ODY=MIN(ODY+1,SP)
1065 END SELECT
1070 END IF
1075 DISPLAY #CH:AT LBLOCK FROM 1 TO HGT
1080 LET CH=1-(CH=1)
1090 CALL PLOT_OBJ
1095 LOOP
1105 END
1199 !
6000 DEF PLOT_OBJ
6001 CLEAR #CH
6005 LET ZX=MIN(DWID-OWID+1,MAX(1,OX+ODX))
6010 LET ZY=MIN(DHGT-OHGT+1,MAX(1,OY+ODY))
6015 LET OX=ZX:LET OY=ZY
6016 IF OY>(DHGT-OHGT) OR OY=1 THEN LET ODY=0
6017 IF OX>(DWID-OWID) OR OX=1 THEN LET ODX=0
6020 LET CL=IP((OX-1)/8)+WID*ZY-WID
6021 LET KOX=MOD(OX-1,8)
6022 FOR K=1 TO OHGT
6023 LET CLX=LD2(CH)+CL+(K-1)*WID
6025 LET M1=OFFX1(K,KOX)
6027 LET M2=OFFX2(K,KOX)
6035 SPOKE LD2PAGE(CH),CLX,M1
6040 SPOKE LD2PAGE(CH),CLX+1,M2
6045 NEXT
6050 END DEF
6099 !
6100 DEF GETLPT
6105 LET LPTLOW=SPEEK(255,16372)
6110 LET LPTHIGH=SPEEK(255,16373)
6115 LET LPT=LPTLOW+MOD(LPTHIGH*128+LPTHIGH*128,16384)
6120 END DEF
6199 !
6200 DEF GETLD1
6205 LET LD1LOW=SPEEK(255,LPT+16*LBLOCK+4)
6210 LET LD1HIGH=SPEEK(255,LPT+16*LBLOCK+5)
6215 LET LD1PAGE(CH)=252+IP((LD1HIGH*128)/8192)
6220 LET LD1(CH)=LD1LOW+MOD(LD1HIGH*128+LD1HIGH*128,16384)
6225 END DEF
6299 !
6300 DEF GETLD2
6305 LET LD2LOW=SPEEK(255,LPT+16*LBLOCK+6)
6310 LET LD2HIGH=SPEEK(255,LPT+16*LBLOCK+7)
6315 LET LD2PAGE(CH)=252+IP((LD2HIGH*128)/8192)
6320 LET LD2(CH)=LD2LOW+MOD(LD2HIGH*128+LD2HIGH*128,16384)
6325 END DEF
6399 !
7000 DEF GET_EVENT
7005 LET GET_EVENT=0
7010 END DEF
7099 !
7100 DEF EVENT_HANDLER
7105 PRINT "Event! ";
7110 END DEF
8099 !
9000 DEF INIT_VARS
9005 RESTORE 9500
9010 FOR I=1 TO 9
9015 READ GFX1(I)
9020 NEXT
9025 FOR I=1 TO OHGT
9030 FOR J=0 TO 8
9033 LET OFFX1(I,J)=IP(GFX1(I)/2^J)
9036 LET OFFX2(I,8-J)=MOD(GFX1(I)*2^J-(2^(8-J)-1)*256,256)
9040 NEXT
9045 NEXT
9050 LET ESC$=CHR$(27):LET LEFT$=CHR$(184):LET RIGHT$=CHR$(188):LET UP$=CHR$(176):LET DOWN$=CHR$(180)
9055 LET DWID=WID*8:LET DHGT=HGT*9
9090 END DEF
9099 !
9100 DEF INIT_VPAGES
9105 SET VIDEO MODE 15
9110 SET VIDEO COLOUR 0
9115 SET VIDEO X WID
9120 SET VIDEO Y HGT
9125 OPEN #1:"VIDEO:"
9130 OPEN #2:"VIDEO:"
9133 CALL GETLPT
9135 FOR CH=1 TO 2
9140 SET #CH:PALETTE RED,GREEN,YELLOW,BLUE,MAGENTA,WHITE,BLACK,243
9145 SET #CH:BIAS 168
9150 DISPLAY #CH:AT LBLOCK FROM 1 TO HGT
9155 CALL GETLD1:CALL GETLD2
9160 NEXT
9165 LET CH=1
9170 SET STATUS OFF
9175 CLEAR SCREEN
9180 END DEF
9199 !
9500 DATA 255,129,129,129,129,129,129,129,255
-
már csak az a kérdés hogy több címet vagy file név címét hogy lehet átadni a basic code hex utasításba?
hm, rájöttem hogy egyszerűen a csatornát basic-ben kell megnyitni, és a dolog meg van oldva :)
-
JSP, your program is cool, I always wanted to make a pixel-moving basic game.
-
Hi
Yes, thanks to the support in BASIC for the NICK chip and its ability to have multiple video pages, you can do a buffered display to avoid flickering. This is still kind of slow in pure BASIC, but practical with the aid of ZZZIP because spokes and speeks execute so darn fast.
The first program used attribute mode, which is not the best choice speedwise. I am currently testing a similar approach using LORES or HIRES pixel mode. And it looks very promising. A pure ZZZIP compiled plot test of an object made of 3 scan-lines reached at least 50 FPS. But of course that is without any game logic like testing for keyboard etc.
Maybe I should start another topic, since this appears to be of interest to others, and further discussion will sort of hi-jack the original topic, that we are hooked in to, which is not polite :)
regards
Jesper
-
This is a proper thread for your programs and intentions.... but it is in Hungarian language.
There is a convention(not a law) here that says, if you answer in English to an Hungarian thread, please add also a translation.... Don't worry, a google translation can serve here.
But sometimes the technical texts are not correctly processed, so please, better start the same thread on the English side.
-
yes, the pixel modes is an other story.
I think this "gracha" mode will work with good speed with zzzip+asm.
But I will use some of your code, for example to get proper nick addresses :)
-
még nem csináltam semmit, de továbbra se adtam fel, meg fogom csinálni. jó lesz ez :)
de ha esetleg nem világos valakinek, írok még arról hogy mire lesz képes ez a rendszer:
-gracha editorban csinált pályát betölti, és előtte sprite-okat tudunk mozgatni úgy, hogy a hátteret nem törlik le, és azzal se kell foglalkoznunk hogy a hátteret visszarajzoljuk, ezeket automatikusan megcsinálja a rendszer.
-elvileg nagyon sok sprite-ot (2x2 karakter blokk) tudunk kezelni, mondjuk 30-40-et is! ezek kirajzolása gépi kóddal nagyon gyors. persze a koordináták változtatását basic-ból kell megoldani, de elvileg az se lassít sokat.
-
nem felejtettem ám el ezt :)
-
hm most nézem, hogy egy gracha képernyő 1008+192 byte csak. valamiért 4k-ra emlékeztem :D
a karakter adat is csak 800byte, mert nem ment minden karaktert, csak amik 2x2-es blokkokban vannak.
szóval basicből allocate-el akár 2-3 ilyen képernyőt is simán le lehet majd foglalni.