Proper raycast examples (now with textures :)

Share your advanced PureBasic knowledge/code with the community.
Anonymous

Post by Anonymous »

Yes , i know for z-buffer.

For drawing Skybox, you can use another datasection

ex :

Code: Select all

DataSection
Skybox:
Data.b 1,1,1
Data.b 2,0,2
Data.b 3,3,3
EndDataSection


you render this in first in pixel buffer ( change the world scalling )
and after , you draw you world.

ps:Happy new year everyone. :wink:
Godai
Enthusiast
Enthusiast
Posts: 171
Joined: Thu Oct 05, 2006 8:13 pm

Post by Godai »

Software z-buffer is not the way to go. For objects and strips we can do an 1-d z-buffer later. One for each vertical line we render. It's a neat trick with a fullblown software z-buffer, but theres too many pixels to process (width*height) and not needed for raycasting.
We also need to add som precalculation of stuff + do direct pixel access instead of plot. I hope I can get around to doing that soon. Otherwise you guys feel free to have a crack at it :)
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

In linux direct screen access is easy.

Code: Select all

global *Screen.sdl_Surface = ScreenID()
holds a pointer to the screen data. Then this is a procedure I wrote a while ago to draw a pixel directly to the surface.

Code: Select all


Procedure Set_Pixel_(*surface.SDL_Surface, x, y, color)
;sets a pixel on a sdl surface, assums that color is in the correct format

;don't fall off the screen.
If x < *surface\w And x > -1 And y < *surface\h And y > -1
    bpp = *surface\format\BytesPerPixel

    w = *surface\w
    PokeB(*surface\pixels + ( (y * w + x) * bpp ) + 0, PeekB(@color + 0) ) 
    PokeB(*surface\pixels + ( (y * w + x) * bpp ) + 1, PeekB(@color + 1) ) 
    PokeB(*surface\pixels + ( (y * w + x) * bpp ) + 2, PeekB(@color + 2) ) 

EndIf
EndProcedure
The only problem I encountered was the little/big endian problem... My solution:

Code: Select all

OpenLibrary(0, "libSDL.so")
    Global gf_SDL_MapRGBA = GetFunction(0, "SDL_MapRGBA")

Procedure.q SDL_MapRGB(*Format.SDL_PixelFormat, r, g, b)
     ProcedureReturn(CallCFunctionFast(gf_SDL_MapRGBA, *format, r, g, b))
EndProcedure

Structure Structure_RGB
    r.b
    g.b
    b.b
EndStructure

Global RGB_fix.Structure_RGB

Procedure FixRGB()

    r = SDL_MapRGB(*Screen\format, 1, 2, 3)
    
    For a = 0 To 2
        ;Red
        If PeekB(@r + a) = 1
            RGB_fix\r = a
        EndIf
        ;Green
        If PeekB(@r + a) = 2
            RGB_fix\g = a
        EndIf
        ;Blue
        If PeekB(@r + a) = 3
            RGB_fix\b = a
        EndIf   
    Next
    
    
EndProcedure   

Procedure.l RGBf(r.b, g.b, b.b)
;FixRGB() needs to be called once before this, to work correctly.
;Takes the rgb and makes them into a long w/ the correct SDL Format.
rgb_.l
PokeB(@rgb_ + RGB_fix\r, r)
PokeB(@rgb_ + RGB_fix\g, g)
PokeB(@rgb_ + RGB_fix\b, b)


ProcedureReturn rgb_

EndProcedure
FixRGB only has to be called once, then I can use the RGBf() instead of RGB() to create the correct color.

I assume that DirectX has a similar structure. so hope this helps.[/code]
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

Added strafe (side stepping left and right) use < and > to move side to side

Code: Select all

;step right?
 If KeyboardPushed(#PB_Key_Period)
    If worldMap(Int(posX + planeX * moveSpeed), Int(posY)) = 0
      posX = posX + ( planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX), Int(posY +  planeY * moveSpeed)) = 0
      posY = posY + ( planeY * moveSpeed)
    EndIf 
 EndIf
 
 ;step left?
 If KeyboardPushed(#PB_Key_Comma)
     If worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = 0
      posX = posX - (planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = 0
      posY = posY - (planeY * moveSpeed)
    EndIf 
 EndIf

User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

I get an OUT OF DATA error when I attempt tp run the textured version. It has to do with the world map!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

How do I figure out what direction the wall being drawn is facing (north south east or west)?

@Rook Zimbabwe Depending on what version of PB you have you either need Read.b worldMap(x, y) or simply Read worldMap(x, y) when loading the world map.
Godai
Enthusiast
Enthusiast
Posts: 171
Joined: Thu Oct 05, 2006 8:13 pm

Post by Godai »

Ahh yes. Please use read.b in these examples as they are for the latest PB version :)
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

Here's what I have done sofar, variable image height (multiples of 32), Direct screen access - should work on all OSs (haven't tested on windows). Use mouse to look, keyboard to move. and a skybox.

Here is a link to the images used in this example, place them in the same directory as the source file

Code: Select all

; Raycasting example: has variable image height and direct screen access.

; Some general stuff
Global mapWidth.l = 24
Global mapHeight.l = 24
Global screenWidth.l =320
Global screenHeight.l = 200
Global texWidth.l = 64
Global texHeight.l = 64

Global Dim PixelZ.d (screenWidth, screenHeight) ;Pixel Z buffer
Global *Screen.l    ;Pointer to screen pixel data
Global BPP.b  ;screen bytes per pixel

;Structure that holds Sprite info
Structure Structure_Graphics
    Sprite.l    ;pb sprite
    *Pointer.l  ;pointer to pixel data
    Width.l  ;Width of the graphic (not necessary as of yet, because all widths in this example are 64 pixels)
    Height.l  ;Height of the graphic (very necessary for variable heights)
EndStructure

Global Dim gfx.Structure_Graphics(0)
Global gfx_count.l = 0  ;# of items in our gfx structured array


Procedure.f FindAngle(X.f, Y.f)
If 0 < X.f
    ;Calculate the gradient of the line joining A and B.
    gradient.f=(-Y.f)/(X.f)
    ;Calculate the angle in radians.
    angleRads.f = ATan(gradient)
    ;Convert to degrees if required.
    angleDegs.f = 180*angleRads/#PI


If angleDegs < 0 : angleDegs + 360 : EndIf
ProcedureReturn angleDegs 

ElseIf 0 > X.f

;Calculate the gradient of the line joining A and B.
gradient.f=(Y.f)/(-X.f)
;Calculate the angle in radians.
angleRads.f = ATan(gradient)
;Convert to degrees if required.
angleDegs.f = (180*angleRads/#PI) + 180

If angleDegs < 0 : angleDegs + 360 : EndIf
ProcedureReturn angleDegs

Else ; X is 0
If 0 > Y.f
  ProcedureReturn 90
Else 
  ProcedureReturn 270
EndIf  
EndIf
EndProcedure

Procedure Set_Pixel_(*surface.l, w, x, y, color)
;sets pixel data in a buffer (*surface), assums that color is in the correct format
;(w) width of image is needed to determin correct position.
;Global BPP already needs to be set elsewhere.
    PokeB(*surface + ( (y * w + x) * bpp ) + 0, PeekB(@color + 0) ) 
    PokeB(*surface + ( (y * w + x) * bpp ) + 1, PeekB(@color + 1) ) 
    PokeB(*surface + ( (y * w + x) * bpp ) + 2, PeekB(@color + 2) ) 
    ;PokeB(*surface +( (y * w + x) * bpp ) + 3, PeekB(@color + 3) )  ;not using alpha

EndProcedure

Procedure.l Get_Pixel_(*surface.l, w, x, y)
;returns a color (long) from pixel data
;*surface is the pointer to pixel data.
;(w) width of image is needed to determin correct position.
;Global BPP already needs to be set elsewhere.
    retColor.l
    PokeB(@retColor.l + 0, PeekB(*surface + ((y * w + x) * BPP) + 0))
    PokeB(@retColor.l + 1, PeekB(*surface + ((y * w + x) * BPP) + 1))
    PokeB(@retColor.l + 2, PeekB(*surface + ((y * w + x) * BPP) + 2))
    ;PokeB(@retColor.l + 3, PeekB(*surface + ((y * w + x) * BPP) + 3))  ;not using alpha

ProcedureReturn retColor
EndProcedure

Structure Structure_RGB
    r.b
    g.b
    b.b
    a.b ;alpha
EndStructure

Global RGB_fix.Structure_RGB


Procedure.l RGBf(r.b, g.b, b.b)
rgb_.l
PokeB(@rgb_ + RGB_fix\r, r)
PokeB(@rgb_ + RGB_fix\g, g)
PokeB(@rgb_ + RGB_fix\b, b)


ProcedureReturn rgb_

EndProcedure

Procedure.l LoadGraphic(FileName.s, Type.b)
gfx_count + 1
ReDim gfx.Structure_Graphics(gfx_count)

gfx(gfx_count)\Sprite = LoadSprite(#PB_Any, FileName.s)
StartDrawing(SpriteOutput(gfx(gfx_count)\Sprite))
    gfx(gfx_count)\Pointer = DrawingBuffer()    ;get the pointer to sprite data
StopDrawing()
gfx(gfx_count)\Width = SpriteWidth(gfx(gfx_count)\Sprite)
gfx(gfx_count)\Height = SpriteHeight(gfx(gfx_count)\Sprite)

EndProcedure

; Map container
Global Dim worldMap.b(mapWidth, mapHeight)

; Texture
Global Dim tex.l(texWidth,texWidth)

; Declare render funcs
Declare RenderTexturedWalls()

; Read map
Global x.l = 0
Global y.l = 0
For y.l = 0 To mapHeight-1
  For x.l = 0 To mapWidth-1
    Read.b worldMap(x, y)
  Next x
Next y

InitKeyboard() : InitSprite() : InitMouse()

;OpenWindow(0, 0, 0, screenWidth , screenHeight, "Raycast Example #2", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
;OpenWindowedScreen(WindowID(0), 0, 0, screenWidth, screenHeight, 0, 0, 0)
OpenScreen(screenWidth, screenHeight, 24, "")

;We only need to call StartDrawing(ScreenOutput()) once to grab the pointer to the drawing buffer.
; That address never changes while the program is running and we'll have it forever.
StartDrawing(ScreenOutput())
    ;grab a pointer to the screen data
    *Screen = DrawingBuffer()
    ;fix endian problem and get ScreenBPP   (on my computer the pixel format is BBGGRR, but incase yours is different...)
    Select DrawingBufferPixelFormat()
        Case #PB_PixelFormat_24Bits_RGB  ; 3 bytes per pixel (RRGGBB)
            RGB_fix\R = 0 : RGB_fix\G = 1 : RGB_fix\B = 2
            BPP = 3
        Case #PB_PixelFormat_24Bits_BGR  ; 3 bytes per pixel (BBGGRR)
            RGB_fix\B = 0 : RGB_fix\G = 1 : RGB_fix\R = 2
            BPP = 3
        Case #PB_PixelFormat_32Bits_RGB  ; 4 bytes per pixel (RRGGBB)
            RGB_fix\R = 0 : RGB_fix\G = 1 : RGB_fix\B = 2
            BPP = 4
        Case #PB_PixelFormat_32Bits_BGR  ; 4 bytes per pixel (BBGGRR)
            RGB_fix\B = 0 : RGB_fix\G = 1 : RGB_fix\R = 2
            BPP = 4
    EndSelect        
StopDrawing()
    

;LOAD TEXTURES HERE
LoadGraphic("greystone.bmp", 0) ;1
LoadGraphic("gen2.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("gen1.bmp", 0)          ;5 is a 64x128 image
   
; Start position
Global posX.f = 22
Global posY.f = 12

; Initial direction vector
Global dirX.f = -1
Global dirY.f = 0

; 2D camera plane
Global planeX.f = 0
Global planeY.f = 0.66

; Frame timing
Global time.f = 0
Global oldTime.f = 0

;my skybox images are each 320x100
sky1 = LoadSprite(#PB_Any, "sky1.bmp")
sky2 = LoadSprite(#PB_Any, "sky2.bmp")
sky3 = LoadSprite(#PB_Any, "sky3.bmp")
sky4 = LoadSprite(#PB_Any, "sky4.bmp")

; Main loop
Repeat
 Dim PixelZ.d(screenWidth, screenHeight)
  ; Pump window events
  ;Global Event.l = WindowEvent()
 
    ClearScreen(RGB(50, 50, 50))
    skyoff = -(FindAngle(planeX*1000, planeY*1000) * 3.55)
    DisplaySprite(sky4, skyoff - 320, 0)
    DisplaySprite(sky1, skyoff , 0)
    DisplaySprite(sky2, skyoff + 320, 0)
    DisplaySprite(sky3, skyoff + 640, 0)
    DisplaySprite(sky4, skyoff + 960, 0)
    DisplaySprite(sky1, skyoff + 1280, 0)
    
    ; Render textured walls
    RenderTexturedWalls()
 
; Flip buffers
  FlipBuffers()
 
  ; Check keyboard + timed movement
  ExamineKeyboard()
  ExamineMouse()
   
  ; Calculate frame timing
  oldTime = time;
  time = ElapsedMilliseconds();
  Global frameTime.f = (time - oldTime) / 1000.0
 
  ; Set FPS in title bar (wonky in PB. Dunno why. Works in C++/Flash version ;)
  ;SetWindowTitle(0, "Raycast Example #1 (FPS: " + Str(Int(1.0 / frameTime)) + ")")

  ; Calculate speed modifiers (constant values are squares/second and radians/second)
  Global moveSpeed.f = frameTime * 5.0
  ;Global rotSpeed.f = frameTime * 3.0
  Global rotSpeed.f = -MouseDeltaX() / 15 * frameTime
 
 ;some debug stuff
 If KeyboardPushed(#PB_Key_Space)
    ;Debug "X: " + StrF(posX) + " Y: " + StrF(posY)
    ;Debug "pX: " + StrF(planeX) + " pY: " + StrF(planeY)
    ;Debug "A: " + StrF(FindAngle(planeX*1000, planeY*1000))
    Debug MouseDeltaX()
 EndIf
 
 ;step right?
 If KeyboardPushed(#PB_Key_Right)
    If worldMap(Int(posX + planeX * moveSpeed), Int(posY)) = 0
      posX = posX + ( planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX), Int(posY +  planeY * moveSpeed)) = 0
      posY = posY + ( planeY * moveSpeed)
    EndIf 
 EndIf
 
 ;step left?
 If KeyboardPushed(#PB_Key_Left)
     If worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = 0
      posX = posX - (planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = 0
      posY = posY - (planeY * moveSpeed)
    EndIf 
 EndIf
 
  ; Move forward?
  If KeyboardPushed(#PB_Key_Up)  
    
    If worldMap(Int(posX + dirX * moveSpeed), Int(posY)) = 0
      posX = posX + (dirX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX), Int(posY + dirY * moveSpeed)) = 0
      posY = posY + (dirY * moveSpeed)
    EndIf
 
  EndIf
 
  ; Move back?
  If KeyboardPushed(#PB_Key_Down)
 
    If worldMap(Int(posX - dirX * moveSpeed),Int(posY)) = 0
      posX = posX - (dirX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX),Int(posY - dirY * moveSpeed)) = 0
      posY = posY - (dirY * moveSpeed)
    EndIf
 
  EndIf
 
  ; Rotate right? (Both camera and camera plane needs to be rotated)
  ;If KeyboardPushed(#PB_Key_Right)
  If MouseDeltaX() <> 0
    
    Global oldDirX.f = dirX
    dirX = dirX * Cos(rotSpeed) - dirY * Sin(rotSpeed)
    dirY = oldDirX * Sin(rotSpeed) + dirY * Cos(rotSpeed)
    Global oldPlaneX.f = planeX
    planeX = planeX * Cos(rotSpeed) - planeY * Sin(rotSpeed)
    planeY = oldPlaneX * Sin(rotSpeed) + planeY * Cos(rotSpeed)
   
  EndIf
 
 
 
 
Until  KeyboardPushed(#PB_Key_Escape)


; Render textured walls
Procedure RenderTexturedWalls()

  ; Misc vars
  Protected x.l = 0
 
  ; Draw some boxes
  ;Box(0,0,screenWidth, screenHeight/2, RGB(10,10,255))
  
 
  ; Render wall strips for each vertical screen row (640 in this case. 320 in good old Wolfenstein)
  For x.l = 0 To screenWidth-1
 
      ; Calculate ray position and direction
      Protected cameraX.f = 2 * x / screenWidth-1
      Protected rayPosX.f = posX
      Protected rayPosY.f = posY
      Protected rayDirX.f = dirX + planeX * cameraX
      Protected rayDirY.f = dirY + planeY * cameraX
     
      ; Determine map tile we're in
      Protected mapX.l = Int(rayPosX)
      Protected mapY.l = Int(rayPosY)
     
      ; Length of ray from current position to next x or y-side
      Protected sideDistX.f = 0
      Protected sideDistY.f = 0
           
      ; Length of ray from one x or y-side to next x or y-side
      Protected deltaDistX.f = Sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
      Protected deltaDistY.f = Sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
      Protected perpWallDist.f

      ; What direction to step in x or y-direction (either +1 or -1)
      Protected stepX.l
      Protected stepY.l

      ; Was a wall hit, and if so which side
      Protected hit.l = 0
      Protected side.l

      ; Calculate step and initial sideDist
      If rayDirX < 0
     
        stepX = -1
        sideDistX = (rayPosX - mapX) * deltaDistX
       
      Else
     
        stepX = 1
        sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX
       
      EndIf
     
      If (rayDirY < 0)
     
        stepY = -1
        sideDistY = (rayPosY - mapY) * deltaDistY
       
      Else
     
        stepY = 1
        sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY
       
      EndIf

      ; Perform DDA algorithm for true hit detection
      While hit = 0
       
        ; Jump to next map square depending on direction
        If sideDistX < sideDistY
       
          sideDistX = sideDistX + deltaDistX
          mapX = mapX + stepX
          side = 0
       
        Else
       
          sideDistY = sideDistY + deltaDistY
          mapY = mapY + stepY
          side = 1
         
        EndIf
       
        ; See if ray has hit a wall
        If MapX < 0 Or MapX > mapWidth Or MapY < 0 Or MapY > mapHeight
            hit = 1
        Else
            
        If worldMap(mapX, mapY) > 0
            ;hit = 1
            ; Calculate distance projected onto camera direction (includes fisheye removal)
            If side = 0
                perpWallDist = Abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
            Else
                perpWallDist = Abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
            EndIf
            ; Calculate height of line to draw onto screen
                           
            Protected lineHeight.l = Abs(Int(screenHeight / perpWallDist))  * (gfx(worldMap(mapX, mapY))\Height / 64)
            Protected halves.d = gfx(worldMap(mapX, mapY))\Height / 32
            
            ; Calculate lowest and highest pixel for current line strip
            Protected drawStart.l = (-lineHeight * ( (halves-1) / halves) + screenHeight / 2)
            If drawStart < 0
                drawStart = 0
            EndIf
            
            Protected drawEnd.l = (lineHeight * (1 / halves) + screenHeight / 2) 
            If drawEnd >= screenHeight
                drawEnd = screenHeight - 1
            EndIf
            
            ; Determine exact point where wall was hit for texture generation
            Protected wallX.f
            If side = 1
                wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
            Else
                wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
            EndIf
            
            wallX = wallX - Int(wallX); What no floor? Also added abs because of this. Line should be 'wallX = wallX - Floor(wallX)'
            wallX = Abs(wallX) ; Should not be here, but since we got no floor :)
       
            ; Calculate x coordinate on the texture
            Protected texX.l = Int(wallX * texWidth);
            If side = 0 And rayDirX > 0
                texX = texWidth - texX - 1
            EndIf
            
            If side = 1 And rayDirY < 0
                texX = texWidth - texX - 1
            EndIf
     
            ; Render textured strip
            Protected y.l = 0
            For y = drawStart To drawEnd - 1
                If PixelZ(x, y)  > perpWallDist Or PixelZ(x, y) = 0
                    Protected d.l = y * 256 - screenHeight *128 + lineHeight * 128 ;Avoid floats
                    Protected texY.l = ((d * gfx(worldMap(mapX, mapY))\height) / (lineHeight)) / 256 
                    color = Get_Pixel_(gfx(worldMap(mapX, mapY))\Pointer, gfx(worldMap(mapx, mapy))\width, texX, texY+((halves-2)*16))
       
                    If color <> 16711935
                        ; Again shift to darken color depending on side
                        If side = 1
                            color = (color >> 1) & 8355711
                        EndIf
                        ; Draw pixel
       
                        Light = ((perpWallDist*255)/25)
                        If Light < 0 : Light = 0 : EndIf
                        If Light > 255 : Light = 255 : EndIf
                        Factor.f = (255 - Light)/255
       
                        Red_ = Red(color) *Factor
                        Green_ = Green(color)*Factor
                        Blue_ = Blue(color)*Factor
                    
                        
                        Set_Pixel_(*screen, screenWidth, x, y, color)
                        PixelZ(x, y) = perpWallDist
                    Else
                        If worldMap(mapX, mapY) <> 1
                            Hit = 0
                            
                        EndIf    
                    EndIf
               EndIf    
            
                
            Next
        EndIf  
        EndIf 
      Wend
  Next

EndProcedure

; Map data
DataSection

  Data.b  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,4,4,4,4,4,4,4,0,0,0,0,0,2,5,1,2,0,0,0,0,0,1
  Data.b  1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

EndDataSection
I still haven't figured out how to determine which side of the wall is currently being drawn, I'd like to allow different images per side. Also trying to figure out how to crouch down.
Please let me know how well (if at all) this works in windows.
Godai
Enthusiast
Enthusiast
Posts: 171
Joined: Thu Oct 05, 2006 8:13 pm

Post by Godai »

Invalid memory access on windows in line 146: StartDrawing(ScreenOutput())
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

I don't understand why that line would give you an error, unless your computer can't do a 320x200 screen. Try changing it to windowed mode instead of fullscreen... or try changing screenWidth and screenHeight to 640x480 (the size you originally had)... the skybox won't work right then, because it's too small, but that's the only explanation I can think of. With SDL, if the screen size is invalid for fullscreen mode, then the next size up will be used to hold the requested size.
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

now with floor and ceiling tiles, just make a new bmp 64x64 and call it grass1.bmp (i'm too lazy to upload my graphic at the moment.


Code: Select all

; Raycasting example: has variable image height and direct screen access.

; Some general stuff
Global mapWidth.l = 24
Global mapHeight.l = 24
Global screenWidth.l =320
Global screenHeight.l = 200
Global texWidth.l = 64
Global texHeight.l = 64

Global Dim PixelZ.d (screenWidth, screenHeight) ;Pixel Z buffer
Global *Screen.l    ;Pointer to screen pixel data
Global BPP.b  ;screen bytes per pixel

;Structure that holds Sprite info
Structure Structure_Graphics
    Sprite.l    ;pb sprite
    *Pointer.l  ;pointer to pixel data
    Width.l  ;Width of the graphic (not necessary as of yet, because all widths in this example are 64 pixels)
    Height.l  ;Height of the graphic (very necessary for variable heights)
EndStructure

Global Dim gfx.Structure_Graphics(0)
Global gfx_count.l = -1  ;# of items in our gfx structured array


Procedure.f FindAngle(X.f, Y.f)
If 0 < X.f
    ;Calculate the gradient of the line joining A and B.
    gradient.f=(-Y.f)/(X.f)
    ;Calculate the angle in radians.
    angleRads.f = ATan(gradient)
    ;Convert to degrees if required.
    angleDegs.f = 180*angleRads/#PI


If angleDegs < 0 : angleDegs + 360 : EndIf
ProcedureReturn angleDegs 

ElseIf 0 > X.f

;Calculate the gradient of the line joining A and B.
gradient.f=(Y.f)/(-X.f)
;Calculate the angle in radians.
angleRads.f = ATan(gradient)
;Convert to degrees if required.
angleDegs.f = (180*angleRads/#PI) + 180

If angleDegs < 0 : angleDegs + 360 : EndIf
ProcedureReturn angleDegs

Else ; X is 0
If 0 > Y.f
  ProcedureReturn 90
Else 
  ProcedureReturn 270
EndIf  
EndIf
EndProcedure

Procedure Set_Pixel_(*surface.l, w, x, y, color)
;sets pixel data in a buffer (*surface), assums that color is in the correct format
;(w) width of image is needed to determin correct position.
;Global BPP already needs to be set elsewhere.
    PokeB(*surface + ( (y * w + x) * bpp ) + 0, PeekB(@color + 0) ) 
    PokeB(*surface + ( (y * w + x) * bpp ) + 1, PeekB(@color + 1) ) 
    PokeB(*surface + ( (y * w + x) * bpp ) + 2, PeekB(@color + 2) ) 
    ;PokeB(*surface +( (y * w + x) * bpp ) + 3, PeekB(@color + 3) )  ;not using alpha

EndProcedure

Procedure.l Get_Pixel_(*surface.l, w, x, y)
;returns a color (long) from pixel data
;*surface is the pointer to pixel data.
;(w) width of image is needed to determin correct position.
;Global BPP already needs to be set elsewhere.
    retColor.l
    PokeB(@retColor.l + 0, PeekB(*surface + ((y * w + x) * BPP) + 0))
    PokeB(@retColor.l + 1, PeekB(*surface + ((y * w + x) * BPP) + 1))
    PokeB(@retColor.l + 2, PeekB(*surface + ((y * w + x) * BPP) + 2))
    ;PokeB(@retColor.l + 3, PeekB(*surface + ((y * w + x) * BPP) + 3))  ;not using alpha

ProcedureReturn retColor
EndProcedure

Structure Structure_RGB
    r.b
    g.b
    b.b
    a.b ;alpha
EndStructure

Global RGB_fix.Structure_RGB


Procedure.l RGBf(r.b, g.b, b.b)
rgb_.l
PokeB(@rgb_ + RGB_fix\r, r)
PokeB(@rgb_ + RGB_fix\g, g)
PokeB(@rgb_ + RGB_fix\b, b)


ProcedureReturn rgb_

EndProcedure

Procedure.l LoadGraphic(FileName.s, Type.b)
gfx_count + 1
ReDim gfx.Structure_Graphics(gfx_count)

gfx(gfx_count)\Sprite = LoadSprite(#PB_Any, FileName.s)
StartDrawing(SpriteOutput(gfx(gfx_count)\Sprite))
    gfx(gfx_count)\Pointer = DrawingBuffer()    ;get the pointer to sprite data
StopDrawing()
gfx(gfx_count)\Width = SpriteWidth(gfx(gfx_count)\Sprite)
gfx(gfx_count)\Height = SpriteHeight(gfx(gfx_count)\Sprite)

EndProcedure

; Map container
Global Dim worldMap.b(mapWidth, mapHeight)

; Texture
Global Dim tex.l(texWidth,texWidth)

; Declare render funcs
Declare RenderTexturedWalls()

; Read map
Global x.l = 0
Global y.l = 0
For y.l = 0 To mapHeight-1
  For x.l = 0 To mapWidth-1
    Read.b worldMap(x, y)
  Next x
Next y

InitKeyboard() : InitSprite() : InitMouse()

OpenWindow(0, 0, 0, screenWidth , screenHeight, "Raycast Example #2", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, screenWidth, screenHeight, 0, 0, 0)
;OpenScreen(screenWidth, screenHeight, 32, "")

;We only need to call StartDrawing(ScreenOutput()) once to grab the pointer to the drawing buffer.
; That address never changes while the program is running and we'll have it forever.
StartDrawing(ScreenOutput())
    ;grab a pointer to the screen data
    *Screen = DrawingBuffer()
    ;fix endian problem and get ScreenBPP   (on my computer the pixel format is BBGGRR, but incase yours is different...)
    Select DrawingBufferPixelFormat()
        Case #PB_PixelFormat_24Bits_RGB  ; 3 bytes per pixel (RRGGBB)
            RGB_fix\R = 0 : RGB_fix\G = 1 : RGB_fix\B = 2
            BPP = 3
        Case #PB_PixelFormat_24Bits_BGR  ; 3 bytes per pixel (BBGGRR)
            RGB_fix\B = 0 : RGB_fix\G = 1 : RGB_fix\R = 2
            BPP = 3
        Case #PB_PixelFormat_32Bits_RGB  ; 4 bytes per pixel (RRGGBB)
            RGB_fix\R = 0 : RGB_fix\G = 1 : RGB_fix\B = 2
            BPP = 4
        Case #PB_PixelFormat_32Bits_BGR  ; 4 bytes per pixel (BBGGRR)
            RGB_fix\B = 0 : RGB_fix\G = 1 : RGB_fix\R = 2
            BPP = 4
    EndSelect        
StopDrawing()
    

;LOAD TEXTURES HERE
LoadGraphic("grass1.bmp", 0)
LoadGraphic("greystone.bmp", 0) ;1
LoadGraphic("gen2.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("gen1.bmp", 0)          ;5 is a 64x128 image
   
; Start position
Global posX.f = 22
Global posY.f = 12

; Initial direction vector
Global dirX.f = -1
Global dirY.f = 0

; 2D camera plane
Global planeX.f = 0
Global planeY.f = 0.66

; Frame timing
Global time.f = 0
Global oldTime.f = 0

;my skybox images are each 320x100
sky1 = LoadSprite(#PB_Any, "sky1.bmp")
sky2 = LoadSprite(#PB_Any, "sky2.bmp")
sky3 = LoadSprite(#PB_Any, "sky3.bmp")
sky4 = LoadSprite(#PB_Any, "sky4.bmp")

; Main loop
Repeat
 Dim PixelZ.d(screenWidth, screenHeight)
  ; Pump window events
  ;Global Event.l = WindowEvent()
 
    ClearScreen(RGB(50, 50, 50))
    skyoff = -(FindAngle(planeX*1000, planeY*1000) * 3.55)
    DisplaySprite(sky4, skyoff - 320, 0)
    DisplaySprite(sky1, skyoff , 0)
    DisplaySprite(sky2, skyoff + 320, 0)
    DisplaySprite(sky3, skyoff + 640, 0)
    DisplaySprite(sky4, skyoff + 960, 0)
    DisplaySprite(sky1, skyoff + 1280, 0)
    
    ; Render textured walls
    RenderTexturedWalls()
 
; Flip buffers
  FlipBuffers()
 
  ; Check keyboard + timed movement
  ExamineKeyboard()
  ExamineMouse()
   
  ; Calculate frame timing
  oldTime = time;
  time = ElapsedMilliseconds();
  Global frameTime.f = (time - oldTime) / 1000.0
 
  ; Set FPS in title bar (wonky in PB. Dunno why. Works in C++/Flash version ;)
  ;SetWindowTitle(0, "Raycast Example #1 (FPS: " + Str(Int(1.0 / frameTime)) + ")")

  ; Calculate speed modifiers (constant values are squares/second and radians/second)
  Global moveSpeed.f = frameTime * 5.0
  ;Global rotSpeed.f = frameTime * 3.0
  Global rotSpeed.f = -MouseDeltaX() / 15 * frameTime
 
 ;some debug stuff
 If KeyboardPushed(#PB_Key_Space)
    ;Debug "X: " + StrF(posX) + " Y: " + StrF(posY)
    ;Debug "pX: " + StrF(planeX) + " pY: " + StrF(planeY)
    ;Debug "A: " + StrF(FindAngle(planeX*1000, planeY*1000))
    Debug MouseDeltaX()
 EndIf
 
 ;step right?
 If KeyboardPushed(#PB_Key_Right)
    If worldMap(Int(posX + planeX * moveSpeed), Int(posY)) = 0
      posX = posX + ( planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX), Int(posY +  planeY * moveSpeed)) = 0
      posY = posY + ( planeY * moveSpeed)
    EndIf 
 EndIf
 
 ;step left?
 If KeyboardPushed(#PB_Key_Left)
     If worldMap(Int(posX - planeX * moveSpeed),Int(posY)) = 0
      posX = posX - (planeX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX),Int(posY - planeY * moveSpeed)) = 0
      posY = posY - (planeY * moveSpeed)
    EndIf 
 EndIf
 
  ; Move forward?
  If KeyboardPushed(#PB_Key_Up)  
    
    If worldMap(Int(posX + dirX * moveSpeed), Int(posY)) = 0
      posX = posX + (dirX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX), Int(posY + dirY * moveSpeed)) = 0
      posY = posY + (dirY * moveSpeed)
    EndIf
 
  EndIf
 
  ; Move back?
  If KeyboardPushed(#PB_Key_Down)
 
    If worldMap(Int(posX - dirX * moveSpeed),Int(posY)) = 0
      posX = posX - (dirX * moveSpeed)
    EndIf
   
    If worldMap(Int(posX),Int(posY - dirY * moveSpeed)) = 0
      posY = posY - (dirY * moveSpeed)
    EndIf
 
  EndIf
 
  ; Rotate right? (Both camera and camera plane needs to be rotated)
  ;If KeyboardPushed(#PB_Key_Right)
  If MouseDeltaX() <> 0
    
    Global oldDirX.f = dirX
    dirX = dirX * Cos(rotSpeed) - dirY * Sin(rotSpeed)
    dirY = oldDirX * Sin(rotSpeed) + dirY * Cos(rotSpeed)
    Global oldPlaneX.f = planeX
    planeX = planeX * Cos(rotSpeed) - planeY * Sin(rotSpeed)
    planeY = oldPlaneX * Sin(rotSpeed) + planeY * Cos(rotSpeed)
   
  EndIf
 
 
 
 
Until  KeyboardPushed(#PB_Key_Escape)


; Render textured walls
Procedure RenderTexturedWalls()

  ; Misc vars
  Protected x.l = 0
 
  ; Draw some boxes
  ;Box(0,0,screenWidth, screenHeight/2, RGB(10,10,255))
  
 
  ; Render wall strips for each vertical screen row (640 in this case. 320 in good old Wolfenstein)
  For x.l = 0 To screenWidth-1
 
      ; Calculate ray position and direction
      Protected cameraX.f = 2 * x / screenWidth-1
      Protected rayPosX.f = posX
      Protected rayPosY.f = posY
      Protected rayDirX.f = dirX + planeX * cameraX
      Protected rayDirY.f = dirY + planeY * cameraX
     
      ; Determine map tile we're in
      Protected mapX.l = Int(rayPosX)
      Protected mapY.l = Int(rayPosY)
     
      ; Length of ray from current position to next x or y-side
      Protected sideDistX.f = 0
      Protected sideDistY.f = 0
           
      ; Length of ray from one x or y-side to next x or y-side
      Protected deltaDistX.f = Sqr(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
      Protected deltaDistY.f = Sqr(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
      Protected perpWallDist.f

      ; What direction to step in x or y-direction (either +1 or -1)
      Protected stepX.l
      Protected stepY.l

      ; Was a wall hit, and if so which side
      Protected hit.l = 0
      Protected side.l

      ; Calculate step and initial sideDist
      If rayDirX < 0
     
        stepX = -1
        sideDistX = (rayPosX - mapX) * deltaDistX
       
      Else
     
        stepX = 1
        sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX
       
      EndIf
     
      If (rayDirY < 0)
     
        stepY = -1
        sideDistY = (rayPosY - mapY) * deltaDistY
       
      Else
     
        stepY = 1
        sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY
       
      EndIf

      ; Perform DDA algorithm for true hit detection
      While hit = 0
       
        ; Jump to next map square depending on direction
        If sideDistX < sideDistY
       
          sideDistX = sideDistX + deltaDistX
          mapX = mapX + stepX
          side = 0
       
        Else
       
          sideDistY = sideDistY + deltaDistY
          mapY = mapY + stepY
          side = 1
         
        EndIf
       
        ; See if ray has hit a wall
        If MapX < 0 Or MapX > mapWidth Or MapY < 0 Or MapY > mapHeight
            hit = 1
        Else
            
        If worldMap(mapX, mapY) > 0
            ;hit = 1
            ; Calculate distance projected onto camera direction (includes fisheye removal)
            If side = 0
                perpWallDist = Abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
            Else
                perpWallDist = Abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
            EndIf
            ; Calculate height of line to draw onto screen
                           
            Protected lineHeight.l = Abs(Int(screenHeight / perpWallDist))  * (gfx(worldMap(mapX, mapY))\Height / 64)
            Protected halves.d = gfx(worldMap(mapX, mapY))\Height / 32
            
            ; Calculate lowest and highest pixel for current line strip
            Protected drawStart.l = (-lineHeight * ( (halves-1) / halves) + (screenHeight / 2) )
            If drawStart < 0
                drawStart = 0
            EndIf
            
            Protected drawEnd.l = (lineHeight * (1 / halves) + (screenHeight / 2) )
            If drawEnd >= screenHeight
                drawEnd = screenHeight - 1
            EndIf
            
            ; Determine exact point where wall was hit for texture generation
            Protected wallX.f
            If side = 1
                wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
            Else
                wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
            EndIf
            
            wallX = wallX - Int(wallX); What no floor? Also added abs because of this. Line should be 'wallX = wallX - Floor(wallX)'
            wallX = Abs(wallX) ; Should not be here, but since we got no floor :)
       
            ; Calculate x coordinate on the texture
            Protected texX.l = Int(wallX * texWidth);
            If side = 0 And rayDirX > 0
                texX = texWidth - texX - 1
            EndIf
            
            If side = 1 And rayDirY < 0
                texX = texWidth - texX - 1
            EndIf
     
            ; Render textured strip
            Protected y.l = 0
            For y = drawStart To drawEnd - 1
                If PixelZ(x, y)  > perpWallDist Or PixelZ(x, y) = 0
                    Protected d.l = y * 256 - screenHeight *128 + lineHeight * 128 ;Avoid floats
                    Protected texY.l = ((d * gfx(worldMap(mapX, mapY))\height) / (lineHeight)) / 256 
                    color = Get_Pixel_(gfx(worldMap(mapX, mapY))\Pointer, gfx(worldMap(mapx, mapy))\width, texX, texY+((halves-2)*16))
       
                    If color <> 16711935
                        ; Again shift to darken color depending on side
                        If side = 1
                            color = (color >> 1) & 8355711
                        EndIf
                        ; Draw pixel
       
                        Light = ((perpWallDist*255)/20)
                        If Light < 0 : Light = 0 : EndIf
                        If Light > 255 : Light = 255 : EndIf
                        Factor.f = (255 - Light)/255
       
                        Red_ = Red(color) *Factor
                        Green_ = Green(color)*Factor
                        Blue_ = Blue(color)*Factor
                    
                        color = RGB(red_, green_, blue_)
                        Set_Pixel_(*screen, screenWidth, x, y, color)
                        PixelZ(x, y) = perpWallDist
                    Else
                        If worldMap(mapX, mapY) <> 1
                            Hit = 0
                            
                        EndIf    
                    EndIf
               EndIf    
            
                
            Next
            
;            //FLOOR CASTING
        Protected floorXWall.d, floorYWall.d    ;x, y position of the floor textel at the bottom of the wall
;
;      //4 different wall directions possible
        If side = 0 And rayDirX > 0
            floorXWall = mapX
            floorYWall = mapY + wallX
        ElseIf side = 0 And rayDirX < 0
            floorXWall = mapX + 1.0
            floorYWall = mapY + wallX
        ElseIf side = 1 And rayDirY > 0
            floorXWall = mapX + wallX
            floorYWall = mapY
        Else
            floorXWall = mapX + wallX
            floorYWall = mapY + 1.0
        EndIf
        
        Protected distWall.d, distPlayer.d, currentDist.d
        distWall = perpWallDist
        distPlayer = 0
        
        If drawEnd < 0 : drawEnd = screenHeight : EndIf
        
        For y = drawEnd + 1 To screenHeight
            currentDist = screenHeight / (2 * y - screenHeight)
            weight.d = (currentDist - distPlayer) / (distWall - distPlayer)
                
            currentFloorX.d = weight * floorXWall + (1 - weight) * posX
            currentFloorY.d = weight * floorYWall + (1 - weight) * posY
                
            floorTexX.l = Int(currentFloorX * texWidth) % texWidth
            floorTexY.l = Int(currentFloorY * texHeight) % texHeight
                If PixelZ(x, y) = 0
                    color = Get_Pixel_(gfx(0)\Pointer, gfx(0)\Width, floorTexX, floorTexY)
                    Set_Pixel_(*screen, screenWidth, x, y, color)
                    ;PixelZ(x, y) = 0.0001  ;set this to a low # so we don't draw the same pixel again.
                EndIf
                ;I am not using ceilings here because of variable wall height, but if you'd like to:
                ;If PixelZ(x, screenHeight-y) = 0
                ;    color = Get_Pixel_(gfx(0)\Pointer, gfx(0)\Width, floorTexX, floorTexY)
                ;    Set_Pixel_(*screen, screenWidth, x, screenHeight - y, color)
                ;    ;PixelZ(x, screenHeight-y) = 0.0001  ;set this to a low # so we don't draw the same pixel again.
                ;EndIf      
        Next
;  End of floors casting
            
        EndIf  
        EndIf 
      Wend
      
  Next

EndProcedure

; Map data
DataSection

  Data.b  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,4,4,4,4,4,4,4,0,0,0,0,0,2,5,1,2,0,0,0,0,0,1
  Data.b  1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  Data.b  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

EndDataSection
Godai
Enthusiast
Enthusiast
Posts: 171
Joined: Thu Oct 05, 2006 8:13 pm

Post by Godai »

GBeebe wrote:I don't understand why that line would give you an error, unless your computer can't do a 320x200 screen. Try changing it to windowed mode instead of fullscreen... or try changing screenWidth and screenHeight to 640x480 (the size you originally had)... the skybox won't work right then, because it's too small, but that's the only explanation I can think of. With SDL, if the screen size is invalid for fullscreen mode, then the next size up will be used to hold the requested size.
Changing to windowed mode simply crashes it in the Get_Pixel_ function instead.
GBeebe
Enthusiast
Enthusiast
Posts: 263
Joined: Sat Oct 09, 2004 6:52 pm
Location: Franklin, PA - USA
Contact:

Post by GBeebe »

I don't know what to say. I tested my code on a windows XP machine and got no errors, but I did get some horrible visual glitches, like floor tiles not fitting and everything drawn to the buffer gets erased and i can see them being drawn on the screen, as if the buffer is live and doesn't wait for flipbuffers().

I guess I shouldn't expect native PB code to work the same on different OSs.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Cool this TEAM who born 8)
The Raycast TEAM.
KCC see all the episode with interest :D
It's good to see how an old game is build step by step :D
Like usually i serve at anything, but you know you are at least a spectator :D
GBeebe wrote:@Cpl.Bator That's super slow on my machine.
For me it's very very slow.
With big jerk picture by picture

Just for info, I have tried tour code and i have an error "ReadData error no more data" at line 28

Code: Select all

  Read worldMap(x, y) 
Congratulation at all :D
ImageThe happiness is a road...
Not a destination
Godai
Enthusiast
Enthusiast
Posts: 171
Joined: Thu Oct 05, 2006 8:13 pm

Post by Godai »

Maybe we should move it a step back and do a raycast lib include file?

Or cleanup the source so it's similar to the first, but with walls, floors, cielings + depth fog? That way we are sure it works across all platforms and people can use this page to optimize/change the base code base?

As of now, the last post fails to run on 3 windows systems Ive tested on so it's broken IMO.
And please post in lastes PB version code and use read.b!!!! :)

Thanks
Post Reply