DOOM like raycaster

Previous topic - Next topic

Kitty Hello

Code (glbasic) Select
// Types
TYPE TDLineType
    x1
    y1
    x2
    y2
    c
ENDTYPE

// GLOBALS
GLOBAL math_intersect_x
GLOBAL math_intersect_y
GLOBAL TDLine[] AS TDLineType
GLOBAL i, tmax, distance, sintab[], costab[], px, py

// PreDIM
DIM sintab[360]
DIM costab[360]

// Create the sine and cosine tables
FOR t = 0 TO 359
    sintab[t] = SIN(t)
    costab[t] = COS(t)
NEXT

// Read IN some map data
LOCAL linedata[]
    DIMDATA linedata[], 4, _
                        75,50,100,75,RGB(255,0,0), _
                        100,75,75,100,RGB(0,255,0), _
                        75,100,50,75,RGB(0,0,255), _
                        50,75,75,50,RGB(255,255,0)
tmax = linedata[0]
FOR t = 0 TO tmax-1
LOCAL line AS TDLineType
    line.x1 = linedata[1+t*5]
    line.y1 = linedata[2+t*5]
    line.x2 = linedata[3+t*5]
    line.y2 = linedata[4+t*5]
    line.c  = linedata[5+t*5]
    // just store the number of lines needed
    // it's 2007, don't use static arrays, PLEASE!
    DIMPUSH TDLine[], line
NEXT


// Player startpoint
px=75; py=75


// Should go into some sub..... but this is just a tech demo
LOCAL drawx, drawa, drawa2, angle, t2, foundcolor
LOCAL fx, fy, cx, cy
WHILE TRUE
    // Draw main routine
    DRAWRECT 0,  0,320,120, RGB(0x80, 0x80, 0xff)
    DRAWRECT 0,120,320,120, RGB(0x80, 0x80, 0x80)
   
    drawx = 0
    FOR drawa = -31 TO 32 STEP .25
        // Get the angle into some positive area
        t2 = MOD(drawa+angle +360, 360)
        drawa2 = MOD(drawa+360, 360)

        // Get some endpoints for our test line
        fx = px+sintab[t2]*200
        fy = py+costab[t2]*200
        // Just when we cast our ray into the void
        distance = 500
       
        // Check every line.
        // Better way would be checking just the lines the player can see, for that i would need to dissect the Doom source
        // and see how Mr Carmack did this.
        FOREACH line IN TDLine[]
            IF math_intersect(px,py,fx,fy,line.x1,line.y1,line.x2,line.y2)
                LOCAL dx, dy
                dx = px-math_intersect_x
                dy = py-math_intersect_y
                distance = SQR(dx*dx+dy*dy)

                // Undo the fishbowl effect
                distance = 500/(distance*costab[drawa2])
       
                // Draw the line
                DRAWLINE drawx, 128-distance, drawx, 128+distance, line.c
               BREAK
            ENDIF
        NEXT
        INC drawx, 1
    NEXT
    SHOWSCREEN
   
    // Debug info
    PRINT angle, px, py
   
    // Your usual keyboard stuff
    IF KEY(30) // a
        DEC angle, 5
        IF angle < 0 THEN INC angle, 360
    ENDIF
   
    IF KEY(32) // d
        INC angle, 5
        IF angle > 359 THEN DEC angle, 360
    ENDIF
   
    IF KEY(17) // w
        INC px, sintab[angle]
        INC py, costab[angle]
    ENDIF

    IF KEY(31) // s
        DEC px, sintab[angle]
        DEC py, costab[angle]
    ENDIF
WEND


// Checks IF two lines intersect.
// Got this from http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ and translated it from C++ to FB
// to GLBasic
FUNCTION math_intersect: x1,y1,x2,y2,x3,y3,x4,y4
LOCAL denom, nume_a, nume_b, ua, ub
LOCAL y43=y4-y3, x21=x2-x1, x43=x4-x3,y21=y2-y1
LOCAL x13=x1-x3, y13=y1-y3
    denom = y43*x21 - x43*y21
    nume_a = x43*y13 - y43*x13
    nume_b = x21*y13 - y21*x13

    IF denom=0
        // IF nume_a=0 AND nume_b=0 then RETURN FALSE
        RETURN FALSE
    ENDIF
 
    ua = nume_a / denom
    ub = nume_b / denom
    IF ua>=0 AND ua<=1 AND ub>=0 AND ub<=1
        math_intersect_x = x1+ua*x21
        math_intersect_y = y1+ua*y21
        RETURN TRUE
    ENDIF
RETURN FALSE
ENDFUNCTION

Sebe

Will you improve that and build into GLBasic (maybe the 2D version) with extended command set? I always was (and still am) a raycast-game fan. I remember as if it was yesterday when I first played Doom... Back than, that were the days when a few talented guys could make the new blockbuster...

Kitty Hello

Never will I build in such a crap. You can link it to any of your projects, if you want, though.
Would be nice to see what frame rates you can get on a GP2X, though.

Sebe

:( Well, I will try to build a function out of your techdemo. It's a nice start