
On many Windows it's only 32-bit (or 16)

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
Structure Structure_Sprite
x.d
y.d
index.l
distance.d
EndStructure
Global NewList spr.Structure_Sprite()
;Global spr_count.l = -1
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)
ProcedureReturn gfx_count
EndProcedure
Procedure.l LoadSpr(x.d, y.d, image)
;spr_count + 1
;ReDim spr.Structure_Sprite(spr_count)
AddElement(spr())
spr()\x = x
spr()\y = y
spr()\index = image
ProcedureReturn ListIndex(spr())
EndProcedure
; Map container
Global Dim worldMap.b(mapWidth, mapHeight)
Global Dim floorMap.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
;floors ;cause i don't want every floor tile to be the same.
For y.l = 0 To mapHeight-1
For x.l = 0 To mapWidth-1
Read.b floorMap(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("grass1.bmp", 0)
LoadGraphic("colorstone.bmp", 0) ;1
LoadGraphic("gen2.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("greystone.bmp", 0)
LoadGraphic("gen1.bmp", 0) ;5 is a 64x128 image
a = LoadGraphic("sprite.bmp", 0)
LoadSpr(16.5, 15.5, a)
; 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(0)
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)/5) ;!
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)
Protected currentFloorX.d = weight * floorXWall + (1 - weight) * posX
Protected currentFloorY.d = weight * floorYWall + (1 - weight) * posY
If floorMap(Int(currentFloorX), Int(currentFloorY)) <> 0
a = floorMap(Int(currentFloorX), Int(currentFloorY)) - 1
floorTexX.l = Int(currentFloorX * texWidth) % texWidth
floorTexY.l = Int(currentFloorY * texHeight) % texHeight
If PixelZ(x, y) = 0
color = Get_Pixel_(gfx(a)\Pointer, gfx(a)\Width, floorTexX, floorTexY)
Light = ((currentDist*255)/5) ;!
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) = 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
EndIf
Next
; End of floors casting
EndIf
EndIf
Wend
Next
; //SPRITE CASTING
; //sort sprites from far To close
; For(int i = 0; i < numSprites; i++)
ForEach spr()
; {
; spriteOrder[i] = i;
; spriteDistance[i] = ((posX - sprite[i].x) * (posX - sprite[i].x) + (posY - sprite[i].y) * (posY - sprite[i].y)); //sqrt not taken, unneeded
spr()\Distance = ((posX - spr()\x)*(posX - spr()\x) + (posY - spr()\y)*(posY - spr()\y))
; }
Next
; combSort(spriteOrder, spriteDistance, numSprites);
SortStructuredList(spr(), #PB_Sort_Ascending, OffsetOf(Structure_Sprite\distance), #PB_Sort_Double)
; //after sorting the sprites, do the projection And draw them
; For(int i = 0; i < numSprites; i++)
ForEach spr()
; {
; //translate sprite position To relative To camera
; double spriteX = sprite[spriteOrder[i]].x - posX;
spriteX.d = spr()\x - posX
; double spriteY = sprite[spriteOrder[i]].y - posY;
spriteY.d = spr()\y - posY
;
; //transform sprite With the inverse camera matrix
; // [ planeX dirX ] -1 [ dirY -dirX ]
; // [ ] = 1/(planeX*dirY-dirX*planeY) * [ ]
; // [ planeY dirY ] [ -planeY planeX ]
;
; double invDet = 1.0 / (planeX * dirY - dirX * planeY); //required for correct matrix multiplication
invDet.d = 1.0 / (planeX * dirY - dirX * planeY)
;
; double transformX = invDet * (dirY * spriteX - dirX * spriteY);
transformX.d = invDet * (dirY * spriteX - dirX * spriteY)
; double transformY = invDet * (-planeY * spriteX + planeX * spriteY); //this is actually the depth inside the screen, that what Z is in 3D
transformY.d = invDet * (-planeY * spriteX + planeX * spriteY)
;
; int spriteScreenX = Int((w / 2) * (1 + transformX / transformY));
spriteScreenX = Int((screenWidth / 2) * (1 + transformX / transformY))
;
; //calculate height of the sprite on screen
; int spriteHeight = Abs(Int(h / (transformY))); //using "transformY" instead of the real distance prevents fisheye
spriteHeight = Abs(Int(screenHeight / (transformY)))
; //calculate lowest And highest pixel To fill in current stripe
; int drawStartY = -spriteHeight / 2 + h / 2;
drawStartY = -spriteHeight / 2 + screenHeight / 2
; If(drawStartY < 0) drawStartY = 0;
If drawStartY < 0 : drawStartY = 0 : EndIf
; int drawEndY = spriteHeight / 2 + h / 2;
drawEndY = SpriteHeight / 2 + screenHeight / 2
; If(drawEndY >= h) drawEndY = h - 1;
If drawEndY => screenHeight : drawEndY = screenHeight - 1 :EndIf
;
; //calculate width of the sprite
; int spriteWidth = Abs( Int (h / (transformY)));
SpriteWidth = Abs(Int(screenHeight / (transformY)))
; int drawStartX = -spriteWidth / 2 + spriteScreenX;
drawStartX = -SpriteWidth / 2 + spriteScreenX
; If(drawStartX < 0) drawStartX = 0;
If drawStartX < 0 : drawStartX = 0 : EndIf
; int drawEndX = spriteWidth / 2 + spriteScreenX;
drawEndX = SpriteWidth / 2 + spritescreenX
; If(drawEndX >= w) drawEndX = w - 1;
If drawEndX => screenWidth : drawEndX = screenWidth - 1 : EndIf
;
; //loop through every vertical stripe of the sprite on screen
; For(int stripe = drawStartX; stripe < drawEndX; stripe++)
For stripe = drawStartX To drawEndX - 1
; {
; int texX = Int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * texWidth / spriteWidth) / 256;
texX = Int(256 * (stripe - ( -SpriteWidth / 2 + spritescreenX)) * texWidth / SpriteWidth) / 256
; //the conditions in the If are:
; //1) it's in front of camera plane so you don't see things behind you
; //2) it's on the screen (left)
; //3) it's on the screen (right)
; //4) ZBuffer, With perpendicular distance
; If(transformY > 0 && stripe > 0 && stripe < w && transformY < ZBuffer[stripe])
If transformY > 0 And stripe > 0 And stripe < screenWidth
; For(int y = drawStartY; y < drawEndY; y++) //for every pixel of the current stripe
For y = drawStartY To drawEndY - 1
If PixelZ(stripe, y) > transformY Or PixelZ(stripe, y) = 0
; {
; int d = (y) * 256 - h * 128 + spriteHeight * 128; //256 and 128 factors to avoid floats
d = y * 256 - screenHeight * 128 + SpriteHeight * 128
; int texY = ((d * texHeight) / spriteHeight) / 256;
texY = ((d * texHeight) / SpriteHeight) / 256
; Uint32 color = texture[sprite[spriteOrder[i]].texture][texWidth * texY + texX]; //get current color from the texture
color = Get_Pixel_(gfx(spr()\index)\Pointer, texWidth, TexX, TexY)
; If((color & 0x00FFFFFF) != 0) buffer[stripe][y] = color; //paint pixel if it isn't black, black is the invisible color
If color <> 16711935
Light = ((transformY*255)/5) ;!
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, stripe, y, color)
EndIf
EndIf
Next
EndIf
Next
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,0,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,0,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
;floors
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
EndDataSection
I have a similar issue with the latest and linr 178... I think it is the same command.Invalid memory access on windows in line 146: StartDrawing(ScreenOutput())
Code: Select all
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.
PokeL(*surface + ( (y * w + x) * bpp ) + 0, color)
EndProcedure
Global retColor.l
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.
ProcedureReturn PeekL(*surface + ((y * w + x) * BPP) )
EndProcedure