Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 07:57 28 Feb 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PicoMiteVGA DEMO

     Page 11 of 11    
Author Message
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5723
Posted: 08:18am 22 Feb 2026
Copy link to clipboard 
Print this post

Hi javavi,

Wauw. This is beautifull. I did not have VGA system at hand, so I converted it to Game*Mite (any color LCD would do). But this is amazing. It feels like we could convert the whole of the universe into a few lines of MMBasic. Thank you. Between your demo's there are some real gems, pure diamond, and this is one of them.

dim cmap(15)'MODE 2
cMap(1)=RGB(Red)
cMap(2)=RGB(Yellow)
cMap(3)=RGB(White)
'Map set

For N=0 To 239
For M=0 To 319
X=0:Y=-.1:Z=3
U=(M-159.5)/160:V=(N-117.5)/160
W=1/Sqr(U*U+V*V+1):U=U*W:V=V*W
I=Sgn(U):G=1
Do
E=X-I:F=Y-I:P=U*E+V*F-W*Z
D=P*P-E*E-F*F-Z*Z+1
If D>0 Then
 T=-P-Sqr(D)
 If T>0 Then
  X=X+T*U:Y=Y+T*V:Z=Z-T*W:E=X-I:F=Y-I:G=Z
  P=2*(U*E+V*F-W*G):U=U-P*E:V=V-P*F:W=W+P*G:I=-I
  Loop
 EndIf
EndIf
If V<0 Then
 P=(Y+2)/V:V=-V*((Int(X-U*P)+Int(Z-W*P)And 1)/2+.3)+.2
EndIf
Color cMap(3-(48*Sqr(V)+(7*(M+4*N))Mod 16)\16)
Pixel M,240-N
Next
Next


Volhout
PicomiteVGA PETSCII ROBOTS
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1374
Posted: 10:24am 22 Feb 2026
Copy link to clipboard 
Print this post

Fascinating. I have no idea how the programme works, but Harms version also runs smoothly in mode 7 under mmbasic for Windows.
Here in 640x480 Picomite HDMI Mode 3 or CMM2/MMBASIC4Windows Mode 1
cls:Mode 1' Mode 3 PICO HDMI
dim cmap(15)
cMap(1)=RGB(Red)
cMap(2)=RGB(Yellow)
cMap(3)=RGB(White)
For N=0 To 479
   For M=0 To 639
       X=0:Y=-.1:Z=3
       U=(M-319.5)/320 : V=(N-237.5)/320
       W=1/Sqr(U*U+V*V+1):U=U*W:V=V*W
       I=Sgn(U):G=1
       Do
           E=X-I:F=Y-I:P=U*E+V*F-W*Z
           D=P*P-E*E-F*F-Z*Z+1
           If D>0 Then
               T=-P-Sqr(D)
               If T>0 Then
                   X=X+T*U:Y=Y+T*V:Z=Z-T*W:E=X-I:F=Y-I:G=Z
                   P=2*(U*E+V*F-W*G):U=U-P*E:V=V-P*F:W=W+P*G:I=-I
                   Loop
               End If
           End If
           If V<0 Then
               P=(Y+2)/V:V=-V*((Int(X-U*P)+Int(Z-W*P)And 1)/2+.3)+.2
           EndIf
           Color cMap(3-(48*Sqr(V)+(7*(M+4*N))Mod 16)\16)
           Pixel M,480-N
   Next
Next




Cheers
Martin
Edited 2026-02-22 20:45 by Martin H.
'no comment
 
JanVolk
Guru

Joined: 28/01/2023
Location: Netherlands
Posts: 322
Posted: 11:10am 22 Feb 2026
Copy link to clipboard 
Print this post

And also on the RP2040-GEEK.

' - RP2040-GEEK -
'MODE 2
Dim cmap(15)
cMap(1)=RGB(Red)
cMap(2)=RGB(Yellow)
cMap(3)=RGB(White)
'Map set

For N=0 To 134  '239->134 'ILI9341=320x240 ST7789_135=240x135
For M=0 To 239  '319->239
X=0:Y=-.1:Z=3
U=(M-119.5)/120:V=(N-67)/120 '159.5->119.5 117.5->67 160->120
W=1/Sqr(U*U+V*V+1):U=U*W:V=V*W
I=Sgn(U):G=1
Do
E=X-I:F=Y-I:P=U*E+V*F-W*Z
D=P*P-E*E-F*F-Z*Z+1
If D>0 Then
T=-P-Sqr(D)
If T>0 Then
 X=X+T*U:Y=Y+T*V:Z=Z-T*W:E=X-I:F=Y-I:G=Z
 P=2*(U*E+V*F-W*G):U=U-P*E:V=V-P*F:W=W+P*G:I=-I
 Loop
EndIf
EndIf
If V<0 Then
P=(Y+2)/V:V=-V*((Int(X-U*P)+Int(Z-W*P)And 1)/2+.3)+.2
EndIf
Color cMap(3-(48*Sqr(V)+(7*(M+4*N))Mod 16)\16)
Pixel M,135-N '240->135
Next
Next


Jan.
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1726
Posted: 01:18pm 27 Feb 2026
Copy link to clipboard 
Print this post

Hi Martin(/Harm/Vadim),
I hope you don't mind that I modified your code. I was playing around with it a bit (along with AI, since I don't really understand the code ;-)).
My goal was to explore the possibilities for speed optimization in pure BASIC.
For a faster speed (now 44 seconds on 640x480 display), I halved the resolution (using double pixels)!

MODE 3:CLS :Map RESET:Timer =0
Dim Float x,y,z,u,v,w,e,f,p,d,t,uo,vo,tp,v2,xi,zi,i3=1/320
Dim Integer m,n,k,o,c,uc=320,vc=240
Dim Integer G(15)=(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
Colour Map G(),G()
For n=0 To 479:vo=(n-vc)*i3:v2=vo*vo+1:o=28*n
For m=1 To 640 Step 2
x=0:y=-.1:z=3.8:uo=(m-uc)*i3:w=1/Sqr(uo*uo+v2):u=uo*w:v=vo*w:i=Sgn(u)
Do
 e=x-i:f=y-i:p=u*e+v*f-w*z:d=p*p-e*e-f*f-z*z+1:If d<=0 Then Exit Do
 t=-p-Sqr(d):If t<0 Then Exit Do
 Inc x,t*u:Inc y,t*v:Inc z,-t*w:e=x-i
 p=2*(u*e+v*(y-i)-w*z):Inc u,-p*e:Inc v,-p*(y-i):Inc w,p*z:i=-i
Loop
If v<0 Then
 tp=(y+2)/v:xi=x-u*tp:zi=z-w*tp
 k=((xi+4096)+Int(zi+4096))And 1
 c=10-k*10
Else
 c=Int(14-v*25+((7*m+o)Mod 16)\2)
EndIf
c=c*(c>0 And c<15)+15*(c>=15)
Line m,480-n,m+1,480-n,,G(c):Next
Next
Print Timer


Variable ListVariable List

+----------+---------+-------------------------------------------------------------+
| Variable | Type    | Description                                         |
+----------+---------+-------------------------------------------------------------+
| x, y, z  | Float   | Current position of the ray in 3D world space.              |
| u, v, w  | Float   | Direction components (X, Y, Z) of the ray, normalized to 1. |
| e, f     | Float   | Distance vectors from current ray position to sphere center.|
| p        | Float   | Auxiliary variable for dot product and reflection math.     |
| d        | Float   | Discriminant to check for sphere hits (d > 0).              |
| t        | Float   | Calculated distance to the sphere surface hit point.        |
| uo, vo   | Float   | Screen coordinates mapped to the normalized viewport plane. |
| tp       | Float   | Distance from current ray position to the floor (y = -2).   |
| v2       | Float   | Pre-calculated vo^2 + 1 for faster ray normalization.       |
| xi, zi   | Float   | Exact X and Z coordinates of the hit point on the floor.    |
| i3       | Float   | Pre-calculated constant 1/320 to avoid divisions.           |
| m, n     | Integer | Loop counters for horizontal pixels and vertical lines.     |
| k        | Integer | Grid state (0 or 1) from the checkerboard formula.          |
| o        | Integer | Offset used for the pseudo-dithered sky pattern.            |
| c        | Integer | Final color index (0-15) after logic and clamping.          |
| uc, vc   | Integer | Screen center constants (320, 240).                         |
| G()      | Array   | Palette array for mapping to MMBasic color indices.         |
| i        | Float   | Sign factor to switch between sphere positions (1 or -1).   |
+----------+---------+-------------------------------------------------------------+


Functional Block Description

1. Initialization & Setup (Lines 1-8)
The code sets the display MODE 3 and resets the color Map. It initializes
all necessary variables and the G() array, which maps indices 0-15 to
the system's color palette.

2. Ray Normalization & Viewport Mapping (Lines 9-11)
Inside the nested loops, the code converts screen pixels (m, n) into
3D ray slopes (uo, vo). Line 11 is critical: it calculates the unit
vector components (u, v, w) using the Pythagorean normalization
formula to prepare for accurate physical reflections.

3. Reflection Loop (Lines 12-17)
The Do...Loop handles the ray-sphere intersections.

Lines 13-14: Calculate the discriminant 'd' and distance 't' to
check if a sphere is hit.

Lines 15-16: If hit, the position is updated (Inc x, y, z) and
the ray's direction (u, v, w) is mathematically reflected.

Line 17: Toggles 'i' to check the other sphere in the next iteration.

4. Floor and Horizon Logic (Lines 18-23)

Floor (Lines 19-21): If the ray points down (v < 0), the floor
intersection (tp) and checkerboard coordinates (xi, zi) are calculated.
Your optimized '10-k*10' logic assigns colors without 'If' branches.

Sky (Lines 22-23): If the ray points up, a dithered gradient color
is calculated based on the vertical slope.

5. Boolean Clamping & Output (Lines 25-26)

Line 25: The high-performance Boolean expression clamps 'c' between
0 and 15 without using the slower 'If' or 'Min/Max' commands.

Line 26: The 'Line' command outputs a 2-pixel segment to the screen.





Regards
Michael
causality ≠ correlation ≠ coincidence
 
     Page 11 of 11    
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026