Well I finished working on this for tonight and the scroller is now half implimented.
Some thoughts of what is going on here. I had an idea to have a vertical scroll, first steps are to create a kind of image buffer that the scroll can be drawn on, then this image buffer can be drawn to the screen in an interesting way.
Main overhead in this technique would actually have been copying the whole texture and moving it inside the buffer.
Effectively the best way to do this is by simulating a "block move" ie. copying all the data at once, instead we just have an offset variable that we change so we start at a different point in the bank each frame (remember to define enough extra space to have one letter offscreen :-P)
Result, well, the intro is now starting to slow down and needs optimisation.
However the engine to do the scroll is implimented (with a simple texture for now).
Optimisation will take place tomorrow, it's the chessfield that needs speeding up :-) I believe that it will be easy to squeeze about another 35 % out of this program and maybe it will finish up in 800 X 600.
Enough of that anyway, here's the source and exe is attached.
'
' New S!P Intro
' By Shockwave!
'
' Huge thanks to Rbraz I have used Tinyptc Ext and also his image code!
' ---------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' SETUP;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#INCLUDE "TINYPTC_EXT.BI"
#INCLUDE "WINDOWS.BI"
OPTION STATIC
OPTION EXPLICIT
CONST XRES = 640
CONST YRES = 480
DIM SHARED AS INTEGER HALFX = XRES / 2
DIM SHARED AS INTEGER HALFY = YRES / 2
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' VARIABLE DECLARATION;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DIM SHARED AS UINTEGER BUFFER ( XRES * YRES ):' SCREEN BUFFER
DIM SHARED AS INTEGER CHESS_RES = 20:' CHESSFIELD DENSITY
DIM SHARED AS DOUBLE CXP ( CHESS_RES , CHESS_RES ):' CHESSFIELD X
DIM SHARED AS DOUBLE CYP ( CHESS_RES , CHESS_RES ):' CHESSFIELD Y
DIM SHARED AS DOUBLE CZP ( CHESS_RES , CHESS_RES ):' CHESSFIELD Z
DIM SHARED AS DOUBLE BOARDOFFS:' CHESSFIELD SCROLL VAR
DIM SHARED AS INTEGER CLICKS,CLICK:' USED TO CREATE PATTERN OFFSET
CLICKS=0
DIM SHARED AS INTEGER BPL ( 512,YRES*4 ):' PALETTE (COPPERLIST)
DIM SHARED AS DOUBLE TIMER_SNAPSHOT:' TO STORE A SNAPSHOT OF THE TIMER
DIM SHARED AS DOUBLE GADD:' USED TO MAKE SINE VALUES ETC
DIM SHARED AS INTEGER SCROLL (32*(YRES+32)):' SCROLL BUFFER (HOLDS SCROLLTEXT IMAGE)
DIM SHARED AS INTEGER SCROLLPOS=0:' SCROLL OFFSET VARIABLE
dim shared AS INTEGER COPOFF :' COPPERLIST SCROLL OFFSET
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' SUBROUTINE DECLARATION;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DECLARE SUB GENERATE_TEXTURES():' TO CREATE TEXTURE MAPS
DECLARE SUB SETBOARDPALETTE():' TO CREATE COPPERLIST FOR BOARD
DECLARE SUB CHESS_SET ():' TO CREATE CHESSBOARD 3D OBJECT
DECLARE SUB CHESS_DRAW():' TO DRAW CHESSBOARD
DECLARE SUB TRIANGLE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
DECLARE SUB DRAWSCROLL():' TO DRAW AND UPDATE THE SCROLLER
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' OPEN SCREEN;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTC_ALLOWCLOSE(0)
PTC_SETDIALOG(0,"RUN IN FULLSCREEN MODE?",0,0)
IF (PTC_OPEN("((S!P))",XRES,YRES)=0) THEN
END-1
END IF
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' PRECALCULATION;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GENERATE_TEXTURES()
SETBOARDPALETTE()
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' MAIN LOOP;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WHILE(GETASYNCKEYSTATE(VK_ESCAPE)<>-32767)
GADD=GADD+1
TIMER_SNAPSHOT=TIMER
COPOFF=(HALFY*2)+1+((HALFY*2)*SIN(TIMER_SNAPSHOT))
CHESS_SET ()
CHESS_DRAW()
DRAWSCROLL()
PTC_UPDATE@BUFFER(0)
ERASE BUFFER
WEND
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' CLEAN UP AND EXIT;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PTC_CLOSE
END
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' THIS SUBROUTINE DRAWS THE SCROLLTEXT TO THE SCREEN LINEAR INTERPOLATED BETWEEN
' A SET OF POINTS DRAWN DOWN THE SCREEN TO "STRETCH" THE LETTERS.
' ALSO OF NOTE IS THE FACT THAT IT SCROLLS WITHOUT ACTUALLY SHIFTING ANY OF THE
' VALUES IN THE SCROLL BUFFER, IT SIMPLY USES AN OFFSET VARIABLE.
' THIS IS FAIRLY OPTIMISED, MORE CAN BE DONE.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB DRAWSCROLL()
dim as integer CUNT,CUNT2
CUNT = 40*SIN(TIMER_SNAPSHOT*3)
CUNT2= 30*SIN(TIMER_SNAPSHOT*2)
DIM AS INTEGER Y,X,x1,x2
DIM AS DOUBLE SV
DIM AS DOUBLE INTER,STRT
FOR Y=0 TO YRES-1
SV=((CUNT*COS((Y+TIMER_SNAPSHOT+GADD)/27))+(CUNT2*SIN((Y-GADD)/21)))
X2=(HALFX+SV)+70:' GENERATE POINT B
X1=(HALFX-SV)-70:' GENERATE POINT A
STRT = SCROLLPOS*32:' PUT STRT AT CORRECT POINT IN SCROLL IMAGE
INTER = 31 / (x2-x1):' WORK OUT INTERPOLATION VALUE
'-----------------------------------------------------------------------
' DRAW ONE HORIZONTAL LINE OF THE SCROLL
'-----------------------------------------------------------------------
FOR X=X1 TO X2
BUFFER(X+(Y*XRES)) = SCROLL(STRT)
STRT=STRT+INTER
NEXT
'-----------------------------------------------------------------------
' ADVANCE SCROLL POINTER, IF AT END OF BANK - 1 LETTER, RESET IT :-p
'-----------------------------------------------------------------------
SCROLLPOS=SCROLLPOS+1
IF SCROLLPOS>=YRES THEN SCROLLPOS=SCROLLPOS-YRES
NEXT
'-----------------------------------------------------------------------
' SCROLL WITHOUT COPYING ANY DATA :-P
'-----------------------------------------------------------------------
SCROLLPOS=SCROLLPOS+2
IF SCROLLPOS>=YRES THEN SCROLLPOS=SCROLLPOS-YRES
END SUB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' JUST MAKE A SIMPLE TEXTURE MAP AND STORE IT IN THE SCROLL BUFFER, LATER WE WILL
' USE THIS TO MAKE A NICER TEXTURE MAP TO COLOUR OUR SCROLL.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB GENERATE_TEXTURES()
DIM AS INTEGER X,Y
FOR Y=0 TO YRES+31
FOR X=0 TO 32
SCROLL(X+(Y*32)) = RGB((X*4) XOR (Y*4) , (X*4) XOR (Y*4),X XOR Y)
NEXT
NEXT
END SUB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' HERE WE CREATE THE COPPERLIST FOR THE CHESSBOARD.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB SETBOARDPALETTE()
DIM AS INTEGER Z,Y
DIM AS DOUBLE X
X=0
FOR Z=0 TO 512
FOR Y=0 TO YRES*4
BPL (Z,Y) = RGB(int(X+1+((X*SIN((Y+10)/180)))),int(X+1+((X*SIN((Y+10)/170)))),int(X+1+((X*SIN((Y+30)/170)))))
NEXT
IF X<125 THEN X=X+(Z/700)
NEXT
END SUB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' SET UP CHESS BOARD;
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB CHESS_SET()
dim cunt as integer
CUNT = 400*SIN(TIMER_SNAPSHOT*3)
DIM AS INTEGER Z , Y
DIM AS DOUBLE STRTZ , STRTY , CADD , AZP , AYP
CADD = ( 14000 / CHESS_RES )
STRTZ = .1
STRTY = -6500
AZP = STRTZ
AYP = STRTY
FOR Z=1 TO CHESS_RES
AYP=STRTY
FOR Y=1 TO CHESS_RES
CXP ( Y , Z ) = 1000+CUNT*sin((y+TIMER_SNAPSHOT)/3)
CYP ( Y , Z ) = AYP
CZP ( Y , Z ) = AZP
AYP = AYP + CADD
NEXT
AZP = AZP + 1
NEXT
END SUB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' DRAW CHESS BOARD.. THIS IS THE SLOW BIT!!!! NEEDS OPTIMISING.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SUB CHESS_DRAW()
DIM AS INTEGER Z , Y
DIM AS INTEGER TX , TY
DIM AS INTEGER TX1 , TY1
DIM AS INTEGER TX2 , TY2
DIM AS INTEGER TX3 , TY3
DIM AS INTEGER TX4 , TY4
DIM AS INTEGER CLICKED,CVLC
CLICKED=CLICKS
CVLC=(250-(BOARDOFFS*10))
FOR Z=1 TO CHESS_RES -1
CLICK=CLICKED
CLICKED=CLICKED+1
IF CLICKED>1 THEN CLICKED=0
FOR Y=1 TO CHESS_RES -1
TX1 = ( CXP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFX
TY1 = ( CYP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFY
TX2 = ( CXP ( Y+1 , Z ) / (CZP ( Y+1 , Z )+BOARDOFFS) ) + HALFX
TY2 = ( CYP ( Y+1 , Z ) / (CZP ( Y+1 , Z )+BOARDOFFS) ) + HALFY
TX3 = ( CXP ( Y+1 , Z+1 ) / (CZP ( Y+1 , Z+1 )+BOARDOFFS) ) + HALFX
TY3 = ( CYP ( Y+1 , Z+1 ) / (CZP ( Y+1 , Z+1 )+BOARDOFFS) ) + HALFY
TX4 = ( CXP ( Y , Z+1 ) / (CZP ( Y , Z+1 )+BOARDOFFS) ) + HALFX
TY4 = ( CYP ( Y , Z+1 ) / (CZP ( Y , Z+1 )+BOARDOFFS) ) + HALFY
IF CLICK=1 THEN
TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3 , CVLC*1.7 )
TRIANGLE(TX1,TY1,TX4,TY4,TX3,TY3 , CVLC*1.7 )
else
TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3 , CVLC*1.9 )
TRIANGLE(TX1,TY1,TX4,TY4,TX3,TY3 , CVLC*1.9 )
END IF
TX1 = ( -CXP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFX
TY1 = ( CYP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFY
TX2 = ( -CXP ( Y+1 , Z ) / (CZP ( Y+1 , Z )+BOARDOFFS) ) + HALFX
TY2 = ( CYP ( Y+1 , Z ) / (CZP ( Y+1 , Z )+BOARDOFFS) ) + HALFY
TX3 = ( -CXP ( Y+1 , Z+1 ) / (CZP ( Y+1 , Z+1 )+BOARDOFFS) ) + HALFX
TY3 = ( CYP ( Y+1 , Z+1 ) / (CZP ( Y+1 , Z+1 )+BOARDOFFS) ) + HALFY
TX4 = ( -CXP ( Y , Z+1 ) / (CZP ( Y , Z+1 )+BOARDOFFS) ) + HALFX
TY4 = ( CYP ( Y , Z+1 ) / (CZP ( Y , Z+1 )+BOARDOFFS) ) + HALFY
IF CLICK=1 THEN
TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3 , CVLC*1.7 )
TRIANGLE(TX1,TY1,TX4,TY4,TX3,TY3 , CVLC*1.7 )
else
TRIANGLE(TX1,TY1,TX2,TY2,TX3,TY3 , CVLC*1.9 )
TRIANGLE(TX1,TY1,TX4,TY4,TX3,TY3 , CVLC*1.9 )
END IF
CLICK=CLICK+1
IF CLICK>1 THEN CLICK=0
'IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
' BUFFER ( TX + ( TY*XRES ) ) = &HFFFFFF
' END IF
NEXT
CVLC=CVLC-13
NEXT
FOR Z=1 TO CHESS_RES
FOR Y=1 TO CHESS_RES
TX = ( CXP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFX
TY = ( CYP ( Y , Z ) / (CZP ( Y , Z )+BOARDOFFS) ) + HALFY
IF TX>0 AND TX<XRES AND TY>0 AND TY<YRES THEN
' BUFFER ( TX + ( TY*XRES ) ) = &HFFFFFF
END IF
NEXT
NEXT
BOARDOFFS=BOARDOFFS+.1
IF BOARDOFFS>1 THEN
BOARDOFFS=BOARDOFFS-1
CLICKS=CLICKS-1
IF CLICKS<0 THEN CLICKS=1
END IF
END SUB
SUB TRIANGLE(BYVAL X1 AS INTEGER , BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER , BYVAL Y2 AS INTEGER , BYVAL X3 AS INTEGER, BYVAL Y3 AS INTEGER , BYVAL TC AS INTEGER)
'-------------------------------------------------------------------------
' FLAT TRIANGLE RENDERER WITH ASSEMBLY LANGUAGE RASTERISING BY SHOCKWAVE ^ DBF ^ S!P 2006.
'-------------------------------------------------------------------------
'-------------------------------------------------------------------------
' WE NEED TO SORT THESE POINTS INTO ORDER FROM TOP TO BOTTOM, AN EXCHANGE SORT IS OK.
' AS WE ONLY HAVE GOT 3 POINTS TO ARRANGE.
'-------------------------------------------------------------------------
DIM AS INTEGER TEMPX,TEMPY,LO,LI
DIM AS INTEGER PX(3)
DIM AS INTEGER PY(3)
DIM TFLAG AS INTEGER
dim pp as uinteger PTR
DIM AS INTEGER IL1,IL2,SLICE,TTC
TFLAG=0
PX(1)= X1
PX(2)= X2
PX(3)= X3
PY(1)= Y1
PY(2)= Y2
PY(3)= Y3
FOR LO = 1 TO 2
FOR LI =1 TO 2
IF PY(LI+1) <= PY(LI) THEN
TEMPX = PX(LI) : TEMPY = PY(LI)
PX(LI) = PX(LI+1)
PY(LI) = PY(LI+1)
PX(LI+1) = TEMPX
PY(LI+1) = TEMPY
END IF
NEXT LI
NEXT LO
' BOOT OUT INVISIBLE TRIANGLES!
IF PX(1)<0 AND PX(2)<0 AND PX(3)< 0 THEN TFLAG=1
IF PX(1)>XRES AND PX(2)>XRES AND PX(3)>XRES THEN TFLAG=1
IF PY(1)>YRES AND PY(2)>YRES AND PY(3)>YRES THEN TFLAG=1
DIM AS DOUBLE XP1,XP2:' SCREEN POSITIONS.
DIM AS DOUBLE XI1,XI2:' INTERPOLATIONS.
'***
'*** REGULAR TRIANGLE (Y1<Y2 Y2<Y3)
'***
IF PY(1)<PY(2) AND PY(2)<PY(3) or (PY(2) = PY(3)) THEN
TFLAG=1
XP1 = PX(1)
XP2 = PX(1)
XI1 = (PX(1)-PX(2)) / (PY(2) - PY(1))
XI2 = (PX(1)-PX(3)) / (PY(3) - PY(1))
FOR LO = PY(1) TO PY(2)-1
IF LO>=0 AND LO<YRES THEN
IF XP1<=XP2 THEN
IL1=XP1
IL2=XP2
ELSE
IL1=XP2
IL2=XP1
END IF
IF IL2>XRES THEN IL2=XRES
IF IL1<0 THEN IL1=0
SLICE = IL2-IL1
IF SLICE>0 THEN
TTC = BPL (TC,LO+COPOFF)
PP = @BUFFER(IL1+(LO*XRES))
asm
mov eax,dword ptr[TTC]
mov ecx, [slice]
mov edi, [PP]
rep stosd
end asm
END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT
XI1 = (PX(2)-PX(3)) / (PY(3) - PY(2))
XP1 = PX(2)
FOR LO = PY(2) TO PY(3)
IF LO>=0 AND LO<YRES THEN
IF XP1<=XP2 THEN
IL1=XP1
IL2=XP2
ELSE
IL1=XP2
IL2=XP1
END IF
IF IL2>XRES THEN IL2=XRES
IF IL1<0 THEN IL1=0
SLICE = IL2-IL1
IF SLICE>0 THEN
TTC = BPL (TC,LO+COPOFF)
PP = @BUFFER(IL1+(LO*XRES))
asm
mov eax,dword ptr[TTC]
mov ecx, [slice]
mov edi, [PP]
rep stosd
end asm
END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT
END IF
'***
'*** FLAT TOPPED TRIANGLE Y1=Y2
'***
IF TFLAG=0 AND PY(1) = PY(2) THEN
TFLAG=1
XP1 = PX(1)
XP2 = PX(2)
XI1 = (PX(1)-PX(3)) / (PY(3) - PY(1))
XI2 = (PX(2)-PX(3)) / (PY(3) - PY(2))
FOR LO = PY(1) TO PY(3)
IF LO>=0 AND LO<YRES THEN
IF XP1<=XP2 THEN
IL1=XP1
IL2=XP2
ELSE
IL1=XP2
IL2=XP1
END IF
IF IL2>XRES THEN IL2=XRES
IF IL1<0 THEN IL1=0
SLICE = IL2-IL1
IF SLICE>0 THEN
TTC = BPL (TC,LO+COPOFF)
PP = @BUFFER(IL1+(LO*XRES))
asm
mov eax,dword ptr[TTC]
mov ecx, [slice]
mov edi, [PP]
rep stosd
end asm
END IF
END IF
XP1=XP1-XI1
XP2=XP2-XI2
NEXT
END IF
END SUB