The QBasic Forum      Other Subforums, Links and Downloads
 
  << Previous Topic | Next Topic >>Return to Index  

3D world

July 12 2008 at 9:36 PM

  (Login Mikrondel)
from IP address 220.245.178.137

It's designed so that you can go cross-eyed and (hopefully) see a planet in 3D...

DECLARE SUB InitPal ()
DECLARE SUB Pal (Index AS INTEGER, Red AS INTEGER, Green AS INTEGER, Blue AS INTEGER)

DECLARE SUB InitMap (Map() AS INTEGER, W AS INTEGER)
DECLARE SUB DebugMap (Map() AS INTEGER, W AS INTEGER)
DECLARE SUB DisplayMap (Map() AS INTEGER, W AS INTEGER, T AS INTEGER, D AS INTEGER, R AS INTEGER)

DECLARE FUNCTION GetPoint% (W AS INTEGER, Level AS INTEGER, YR AS INTEGER, P AS INTEGER, Quad AS INTEGER)

CONST DEG = 1024
CONST Pi = 3.141593
CONST CX = 320
CONST CY = 240

DIM I AS INTEGER, W AS INTEGER
W = 63
DIM Map(0 TO W * 8 - 1, 0 TO W - 1) AS INTEGER

SCREEN 12

InitPal
Pal 1, 0, 2, 58
Pal 2, 6, 12, 60
Pal 3, 13, 16, 60
Pal 4, 63, 60, 45
Pal 5, 33, 31, 26
Pal 6, 20, 51, 20
Pal 7, 21, 46, 10
Pal 8, 1, 26, 2
Pal 9, 4, 20, 0
Pal 10, 24, 24, 24
Pal 11, 44, 44, 45
Pal 12, 31, 29, 21
Pal 13, 9, 42, 5
Pal 14, 2, 40, 3
Pal 15, 2, 12, 50


RANDOMIZE TIMER
PRINT "Generating map, please wait..."
InitMap Map(), W
CLS
'DebugMap Map(), W
FOR T = 0 TO 500 STEP 32
DisplayMap Map(), W, (T), DEG \ 64, 96
NEXT
SYSTEM

SUB DebugMap (Map() AS INTEGER, W AS INTEGER)
DIM I AS INTEGER, J AS INTEGER

'FOR J = 0 TO W - 1
' FOR I = 0 TO W * 8 - 1
' LINE (I * 3, J * 3)-STEP(2, 2), Map(I, J), BF
' NEXT
'NEXT

FOR S = 0 TO 3
FOR J = 0 TO W - 1
FOR I = 0 TO J * 2
LINE ((S * (W * 2 - 1) + I - J) * 3, J * 3)-STEP(2, 2), Map(S * W * 2 + I, J), BF
LINE ((S * (W * 2 - 1) + I - J) * 3, (W * 2 - J - 1) * 3)-STEP(2, 2), Map(S * W * 2 + W * 2 - I - 1, W - J - 1), BF
NEXT
NEXT
NEXT


END SUB

SUB DisplayMap (Map() AS INTEGER, W AS INTEGER, T AS INTEGER, D AS INTEGER, R AS INTEGER)

DIM V(0 TO W) AS INTEGER
DIM I AS INTEGER, X0 AS INTEGER
DIM X AS INTEGER, Y AS INTEGER
DIM S AS INTEGER, YR AS INTEGER
DIM Quad AS INTEGER, P AS INTEGER

FOR I = 0 TO W
V(I) = R * SIN(I / W / 2 * Pi)
NEXT

FOR I = 0 TO W - 1
FOR Y = V(I) TO V(I + 1) - 1
IF V(I + 1) > V(I) THEN YR = DEG \ 4 - (Y - V(I)) / (V(I + 1) - V(I)) * DEG \ 4 ELSE YR = 0
X0 = SQR(R * R - Y * Y)


FOR X = 0 TO X0 - 1

S = ATN(X / SQR(X0 * X0 - X * X)) * DEG / (Pi * 2)

P = GetPoint(W, I, YR, T - S - D, Quad)
PSET (CX + 5 + R - X, CY - Y), Map(Quad * W * 2 + P, W - I - 1)
PSET (CX + 5 + R - X, CY + Y), Map((Quad + 1) * W * 2 - P - 1, I)

P = GetPoint(W, I, YR, T + S - D, Quad)
PSET (CX + 5 + R + X, CY - Y), Map(Quad * W * 2 + P, W - I - 1)
PSET (CX + 5 + R + X, CY + Y), Map((Quad + 1) * W * 2 - P - 1, I)

P = GetPoint(W, I, YR, T - S + D, Quad)
PSET (CX - 5 - R - X, CY - Y), Map(Quad * W * 2 + P, W - I - 1)
PSET (CX - 5 - R - X, CY + Y), Map((Quad + 1) * W * 2 - P - 1, I)

P = GetPoint(W, I, YR, T + S + D, Quad)
PSET (CX - 5 - R + X, CY - Y), Map(Quad * W * 2 + P, W - I - 1)
PSET (CX - 5 - R + X, CY + Y), Map((Quad + 1) * W * 2 - P - 1, I)

NEXT


NEXT
NEXT


END SUB

FUNCTION GetPoint% (W AS INTEGER, Level AS INTEGER, YR AS INTEGER, Angle AS INTEGER, Quad AS INTEGER)

DIM T AS INTEGER, F AS INTEGER, I AS INTEGER

Angle = (Angle + DEG) MOD DEG

T = Angle MOD (DEG \ 4)
Quad = Angle \ (DEG \ 4)
F = T * (W - 1 - Level)

I = 2 * (F \ (DEG \ 4))
F = 2 * (F MOD (DEG \ 4))

GetPoint% = I - (F >= YR) - (F >= DEG \ 2 - YR)

END FUNCTION

SUB InitMap (Map() AS INTEGER, W AS INTEGER)
DIM I AS INTEGER, J AS INTEGER

DIM C AS INTEGER


FOR J = 0 TO W - 1
FOR I = 0 TO W * 8 - 1
Map(I, J) = INT(RND * 450)
NEXT
NEXT

FOR C = 1 TO 16

FOR J = 0 TO W - 1
FOR I = J AND 3 TO W * 8 - 1 STEP 4
GOSUB Blend
NEXT
NEXT
FOR J = 0 TO W - 1
FOR I = (J + 2) AND 3 TO W * 8 - 1 STEP 4
GOSUB Blend
NEXT
NEXT
FOR J = 0 TO W - 1
FOR I = (J + 3) AND 3 TO W * 8 - 1 STEP 4
GOSUB Blend
NEXT
NEXT
FOR J = 0 TO W - 1
FOR I = (J + 1) AND 3 TO W * 8 - 1 STEP 4
GOSUB Blend
NEXT
NEXT

NEXT




FOR J = 0 TO W - 1
FOR I = 0 TO W * 8 - 1
Map(I, J) = ((Map(I, J) \ 8) MOD 15) + 1
NEXT
NEXT


EXIT SUB

Blend:
T = I MOD (W * 2)
S = I \ (W * 2)

Acc = 0
N = 4
'Upper half (of sphere)
IF J * 2 >= T THEN

'Down-pointing triangles
IF T AND 1 THEN
Acc = Acc + Map(I - 1, J - 1) + Map(I - 1, J) + Map(I + 1, J)
ELSE

'Left Edge
IF T = 0 THEN
Acc = Acc + 2 * Map(((S + 3) MOD 4) * W * 2 + J * 2, J)
N = N + 1
ELSE
Acc = Acc + Map(I - 1, J)
END IF

'Right Edge
IF T = J * 2 THEN
Acc = Acc + 2 * Map(((S + 1) MOD 4) * W * 2, J)
N = N + 1
ELSE
Acc = Acc + Map(I + 1, J)
END IF

'Bottom edge
IF J = W - 1 THEN
Acc = Acc + Map(S * W * 2 + W * 2 - T - 1, 0)
ELSE
Acc = Acc + Map(I + 1, J + 1)
END IF
END IF


ELSE


'Down-pointing triangles
IF T AND 1 THEN

'Left Edge
IF T = J * 2 + 1 THEN
Acc = Acc + 2 * Map(((S + 1) MOD 4) * W * 2 + W - 1, J)
N = N + 1
ELSE
Acc = Acc + Map(I - 1, J)
END IF

'Right Edge
IF T = W * 2 - 1 THEN
Acc = Acc + 2 * Map(((S + 3) MOD 4) * W * 2 + J * 2 + 1, J)
N = N + 1
ELSE
Acc = Acc + Map(I + 1, J)
END IF

'Top Edge
IF J = 0 THEN
Acc = Acc + Map(S * W * 2 + W * 2 - T - 1, W - 1)
ELSE
Acc = Acc + Map(I - 1, J - 1)
END IF

ELSE

Acc = Acc + Map(I + 1, J + 1) + Map(I - 1, J) + Map(I + 1, J)

END IF


END IF

Map(I, J) = (Map(I, J) + Acc) \ N

RETURN
END SUB

SUB InitPal
'Fixes occasional SCREEN 12 DAC/palette issues
DIM I AS INTEGER
I = INP(&H3DA)
FOR I = 0 TO 15
OUT &H3C0, I
OUT &H3C0, I
NEXT
OUT &H3C0, 32
END SUB

SUB Pal (Index AS INTEGER, Red AS INTEGER, Green AS INTEGER, Blue AS INTEGER)
OUT &H3C8, Index
OUT &H3C9, Red
OUT &H3C9, Green
OUT &H3C9, Blue
END SUB


 
 Respond to this message   
AuthorReply


(Login PhyloGenesis)
71.102.246.240

*Very nice! Going cross-eyed actually works.

July 13 2008, 12:17 AM 

*

 
 Respond to this message   

(Login MystikShadows)
69.205.201.142

Yup it worked for me too....

July 13 2008, 2:38 AM 

Planet in the middle looks like a perfect sphere....pretty neat.

 
 Respond to this message   
qbguy
(no login)
75.0.227.216

Problem in IE7

July 13 2008, 10:12 AM 

When I try to copy it in IE7, it removes all the line breaks. I can copy it fine in Firefox (on Windows) though.

If you're trying to write copy protection, you fail.

 
 Respond to this message   

(Login burger2227)
71.60.226.47

Seems more like something YOU would do QB

July 13 2008, 11:02 AM 

I am sure Mike did not intend to have that happen. And he is way smarter than you will ever be!

 
 Respond to this message   


(Login Mikrondel)
220.245.178.140

Obviously it's part of a boycott against MS products

July 13 2008, 4:06 PM 


Seriously though, stupid N54 inserts <BR>s in a <PRE>, but leaves the regular line breaks. Since <PRE>s preserve line breaks, this means everything is double-spaced.

So I wrote myself a little utility to remove all line breaks and put <BR>s in manually, and also replace *s with an HTML escape code. But stupid IE, it turns out, displays the <BR>s but doesn't copy them out. Looks like it's time for Plan B: a Javascript routine that strips all <BR>s from within <PRE>s.

 
 Respond to this message   
qbguy
(no login)
75.0.227.216

LOL, I like that theory better than the "copy protection" one

July 13 2008, 4:13 PM 

In Firefox, it also does not monospace the output for some reason.

-----------

Test:


aoeu
idhtns


aoeu
idhtns


 
 Respond to this message   


(Login Mikrondel)
220.245.178.140

*Does this mean you're another Dvorak user?

July 13 2008, 7:18 PM 


 
 Respond to this message   

(Login The-Universe)
70.177.5.114

* Too many sand traps, water is out-of-play, and greens are too small. :(

July 13 2008, 4:16 PM 


 
 Respond to this message   

(Login qb432l)
70.52.180.252

Absolutely perfect! ...

July 17 2008, 4:42 AM 

It was well worth the trouble of making a program out of the hash that IE gave me (figuring out where all the line breaks were), but once I got it running, crossed my eyes, it was perfect! I can't believe how perfectly round the planet is.

Naturally, in DOSBox, it took a long time to generate the map and was much too slow to see the planet rotating (that would have been great!). But even with all the problems, it was worth it to see that perfect sphere (I was a little over 2 feet from the monitor when it "locked").

-Bob

 
 Respond to this message   

(Login qb432l)
70.52.182.176

For people (like me) with slower systems...

July 20 2008, 7:18 AM 

Replace the main module from "SCREEN 12" to "SYSTEM" with the following code. It generates 16 BSAVE'd files the first time you run the program, and after that just runs the animation using those files (begins instantly).

NOTE: First time you run the program, it may take awhile. Don't bail until you see the planets rotating smoothly.

-Bob

'Copy code from here ------------------------------------

DIM PlanetARRAY(1 TO 19500) AS INTEGER
SCREEN 12
InitPal
Pal 1, 0, 2, 58
Pal 2, 6, 12, 60
Pal 3, 13, 16, 60
Pal 4, 63, 60, 45
Pal 5, 33, 31, 26
Pal 6, 20, 51, 20
Pal 7, 21, 46, 10
Pal 8, 1, 26, 2
Pal 9, 4, 20, 0
Pal 10, 24, 24, 24
Pal 11, 44, 44, 45
Pal 12, 31, 29, 21
Pal 13, 9, 42, 5
Pal 14, 2, 40, 3
Pal 15, 2, 12, 50
OPEN "Planet1.BSV" FOR BINARY AS #1
IF LOF(1) = 0 THEN
CLOSE #1
PRINT "Generating map, please wait..."
InitMap Map(), W
CLS
DEF SEG = VARSEG(PlanetARRAY(1))
FOR T = 0 TO 500 STEP 32
DisplayMap Map(), W, (T), DEG \ 64, 96
GET (120, 145)-(520, 335), PlanetARRAY
FileCOUNT = FileCOUNT + 1
FileNAME$ = "Planet" + LTRIM$(STR$(FileCOUNT)) + ".BSV"
BSAVE FileNAME$, VARPTR(PlanetARRAY(1)), 39000
NEXT
DEF SEG
ELSE
CLOSE #1
END IF
DEF SEG = VARSEG(PlanetARRAY(1))
FileCOUNT = 0
DO
FileCOUNT = FileCOUNT + 1
IF FileCOUNT = 17 THEN FileCOUNT = 1
FileNAME$ = "Planet" + LTRIM$(STR$(FileCOUNT)) + ".BSV"
BLOAD FileNAME$, VARPTR(PlanetARRAY(1))
StartTIME! = TIMER
DO: LOOP UNTIL TIMER > StartTIME! + .2
WAIT &H3DA, 8: WAIT &H3DA, 8, 8
PUT (120, 145), PlanetARRAY, PSET
LOOP WHILE INKEY$ = ""
DEF SEG
SYSTEM


 
 Respond to this message   
Pete
(no login)
70.177.5.114

Bob, have you ever tired adding a Biometric Rapid Access Network to your system?

July 20 2008, 1:06 PM 

That's what I use for my slower system... B.R.A.N.

Pete




 
 Respond to this message   

(Login qb432l)
70.52.180.130

*lol - I thought you were serious, but I see this was one of your "regular" responses.

July 20 2008, 1:19 PM 

*

 
 Respond to this message   
Current Topic - 3D world
  << Previous Topic | Next Topic >>Return to Index  

Newbies usually go to www.qbasic.com and click on The QBasic Forum
Forum regulars have their own ways, which include The QBasic Community Forums