SHARE
TWEET

x86asm&qb45 raycaster/toolchain 2 maxim

a guest Jan 20th, 2020 76 in 1 day
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. DECLARE SUB Throw (msg$)
  2. DECLARE SUB SystemInit ()
  3. DECLARE SUB SystemCleanup ()
  4. DECLARE FUNCTION SoundLoad% (filename$)
  5. DECLARE SUB WorldRenderWalls ()
  6. DECLARE SUB WorldRenderSprites ()
  7. DECLARE SUB PaletteLoad (filename$)
  8. DECLARE SUB WorldInit ()
  9. DECLARE SUB InputApply ()
  10. DECLARE SUB VideoSwap ()
  11. DECLARE SUB WorldRender ()
  12. DECLARE SUB WorldLoad (filename$)
  13. DECLARE SUB ASMinitCompiler ()
  14. DECLARE SUB ASMcompile (SOURCE$, target$)
  15. DECLARE FUNCTION ASMload$ (filename$)
  16.  
  17.  
  18. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  19. '
  20. ' Include library headers and do some system configuring.
  21. ' This includes optimizing QB45's float operations.
  22. '
  23. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  24.  
  25. '$INCLUDE: 'DirectQB.bi'
  26. '$INCLUDE: 'ffix.bi'
  27. DEFINT A-Z
  28. ffix
  29. DQBfpu
  30.  
  31.  
  32.  
  33. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  34. '
  35. ' Declare global variables.
  36. '
  37. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  38.  
  39. '
  40. ' World
  41. '
  42. DIM SHARED gWorldWidth%
  43. DIM SHARED gWorldHeight%
  44. DIM SHARED gWorld%(255, 255)
  45. DIM SHARED gWorldSeg%
  46. DIM SHARED gWorldOff%
  47.  
  48. '
  49. ' Camera
  50. '
  51. DIM SHARED gPosX#
  52. DIM SHARED gPosY#
  53. DIM SHARED gDirX#
  54. DIM SHARED gDirY#
  55. DIM SHARED gPlaneX#
  56. DIM SHARED gPlaneY#
  57. gPosX# = 15
  58. gPosY# = 15
  59. gDirX# = -1
  60. gDirY# = 0
  61. gPlaneX# = 0
  62. gPlaneY# = .66
  63.  
  64. '
  65. ' Renderer
  66. '
  67. DIM SHARED gPerpDists!(319)
  68. DIM SHARED gCameraXTable#(319)
  69. FOR i% = 0 TO 319 STEP 4
  70.         gCameraXTable#(i%) = 2 * i% / 320 - 1
  71. NEXT
  72.  
  73. '
  74. ' Audio
  75. '
  76. DIM SHARED gSoundFreq%
  77. DIM SHARED gSoundChannels%
  78. DIM SHARED gSoundNum%
  79. DIM SHARED gSoundSlot%
  80. gSoundFreq% = 9035
  81. gSoundChannels% = 4
  82. gSoundNum% = 4
  83.  
  84. '
  85. ' System
  86. '
  87. DIM SHARED gMemAlloc&
  88.  
  89.  
  90.  
  91. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  92. '
  93. ' Initialize engine.
  94. '
  95. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  96.  
  97. '
  98. ' Load ASM routines
  99. '
  100. DIM SHARED gDrawCol$
  101. DIM SHARED gDrawSpr$
  102. gDrawCol$ = ASMload$("DRAWCOL.BIN")
  103. gDrawSpr$ = ASMload$("DRAWSPR.BIN")
  104.  
  105. '
  106. ' Initialize engine and load world
  107. '
  108. SystemInit
  109. WorldLoad "TEST.UMR"
  110.  
  111. '
  112. ' Load sounds
  113. '
  114. DIM SHARED gSndDrone%
  115. 'gSndDrone% = SoundLoad(".\ASSETS\SFX\LSD.WAV")
  116. gSndDrone% = SoundLoad(".\ASSETS\SFX\OM_LOOP.WAV")
  117. DQBplaySound gSndDrone%, 4, 9035, LOOPED
  118.  
  119.  
  120.  
  121. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  122. '
  123. ' Enter engine main loop.
  124. '
  125. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  126. WHILE NOT DQBkey(1)
  127.  
  128.         '
  129.         ' Render
  130.         '
  131.         WorldRenderWalls
  132.         WorldRenderSprites
  133.         VideoSwap
  134.  
  135.         '
  136.         ' Logic
  137.         '
  138.         InputApply
  139. WEND
  140.  
  141.  
  142.  
  143. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  144. '
  145. ' Stop engine gracefully.
  146. '
  147. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  148.  
  149. SystemCleanup
  150.  
  151. REM $DYNAMIC
  152. SUB ASMcompile (SOURCE$, target$)
  153.  
  154. SOURCE$ = CHR$(34) + SOURCE$ + CHR$(34)
  155. target$ = CHR$(34) + target$ + CHR$(34)
  156.  
  157. SHELL "ASM\FASM\FASM.EXE " + SOURCE$ + " " + target$
  158.  
  159. END SUB
  160.  
  161. REM $STATIC
  162. SUB ASMinitCompiler
  163. SHELL "ASM\CSDPMI5B\CWSDPMI.EXE"
  164. END SUB
  165.  
  166. FUNCTION ASMload$ (filename$)
  167.  
  168. ' Open file
  169. DIM n%
  170. n% = FREEFILE
  171. OPEN filename$ FOR BINARY AS n%
  172.  
  173. ' Read bytes
  174. ' TODO(perf): read the bytes all at once
  175. DIM code$
  176. FOR i% = 0 TO LOF(n%)
  177.         code$ = code$ + INPUT$(1, n%)
  178. NEXT
  179.  
  180. ' Close file and return
  181. CLOSE n%
  182. ASMload$ = code$
  183. END FUNCTION
  184.  
  185. REM $DYNAMIC
  186. SUB InputApply
  187.  
  188. spd# = .025 * 2.5
  189. rot# = .025 * 1.5
  190. ' TODO: Perhaps use a SIN and COS tables
  191. cosRot# = COS(rot#)
  192. sinRot# = SIN(rot#)
  193. cosMinRot# = COS(-rot#)
  194. sinMinRot# = SIN(-rot#)
  195.  
  196.  
  197. ' Walk forward
  198. IF DQBkey(72) THEN
  199.         gPosX# = gPosX# + gDirX# * spd#
  200.         gPosY# = gPosY# + gDirY# * spd#
  201. END IF
  202.  
  203. ' Walk backward
  204. IF DQBkey(80) THEN
  205.         gPosX# = gPosX# - gDirX# * spd#
  206.         gPosY# = gPosY# - gDirY# * spd#
  207. END IF
  208.  
  209. ' Turn right
  210. IF DQBkey(77) THEN
  211.         oldDirX# = gDirX#
  212.         gDirX# = oldDirX# * cosMinRot# - gDirY# * sinMinRot#
  213.         gDirY# = oldDirX# * sinMinRot# + gDirY# * cosMinRot#
  214.  
  215.         oldPlaneX# = gPlaneX#
  216.         gPlaneX# = oldPlaneX# * cosMinRot# - gPlaneY# * sinMinRot#
  217.         gPlaneY# = oldPlaneX# * sinMinRot# + gPlaneY# * cosMinRot#
  218. END IF
  219.  
  220. ' Turn left
  221. IF DQBkey(75) THEN
  222.         oldDirX# = gDirX#
  223.         gDirX# = oldDirX# * cosRot# - gDirY# * sinRot#
  224.         gDirY# = oldDirX# * sinRot# + gDirY# * cosRot#
  225.  
  226.         oldPlaneX# = gPlaneX#
  227.         gPlaneX# = oldPlaneX# * cosRot# - gPlaneY# * sinRot#
  228.         gPlaneY# = oldPlaneX# * sinRot# + gPlaneY# * cosRot#
  229. END IF
  230.  
  231. END SUB
  232.  
  233. REM $STATIC
  234. SUB PaletteLoad (filename$)
  235. n% = FREEFILE
  236. OPEN filename$ FOR BINARY AS n%
  237. OUT &H3C8, 0
  238. FOR i% = 0 TO 765
  239.         GET n%, , a%
  240.         OUT &H3C9, a%
  241. NEXT
  242. CLOSE n%
  243. END SUB
  244.  
  245. FUNCTION SoundLoad% (filename$) STATIC
  246.  
  247. '
  248. ' See if DQB has problems loading the sound.
  249. '
  250. status% = DQBloadSound(gSoundSlot% + 1, filename$)
  251. IF status% > 0 THEN
  252.         Throw "Could not load sound '" + filename$ + "': " + DQBerror$ + "."
  253.         EXIT FUNCTION
  254. END IF
  255.  
  256. '
  257. ' Mark the sound slot as used.
  258. '
  259. gSoundSlot% = gSoundSlot% + 1
  260.  
  261.  
  262. SoundLoad% = gSoundSlot%
  263. END FUNCTION
  264.  
  265. SUB SystemCleanup
  266.  
  267. '
  268. ' Cleanup DirectQB
  269. '
  270. DQBremoveKeyboard
  271. DQBremoveSB
  272. DQBclose
  273.  
  274. '
  275. ' Deallocate memory
  276. '
  277. gMemAlloc& = SETMEM(65536)
  278.  
  279. '
  280. ' Prepare screen for normal rendering
  281. '
  282. DQBinitText
  283.  
  284. END SUB
  285.  
  286. SUB SystemInit
  287.  
  288. '
  289. ' Allocate extra memory
  290. '
  291. gMemAlloc& = SETMEM(-65536)
  292.  
  293. '
  294. ' Initialize DirectQB and check for errors
  295. '
  296. status% = DQBinit(1, gSoundNum%, 0)
  297. IF status% > 0 THEN
  298.         err$ = "DQBinit failed: "
  299.         SELECT CASE status%
  300.         CASE 1: Throw err$ + "386 or better CPU not detected."
  301.         CASE 2: Throw err$ + "Unable to find an expanded memory manager."
  302.         CASE 3: Throw err$ + "Not enough free EMS memory to allocate specified number of layers."
  303.         CASE 4: Throw err$ + "Library has already been initialized."
  304.         END SELECT
  305. END IF
  306.  
  307. '
  308. ' Start sound engine
  309. '
  310. status% = DQBinstallSB(TRUE, gSoundChannels%, gSoundFreq%, &H220, AUTO, AUTO)
  311. IF status% > 0 THEN
  312.         err$ = "DQBinstallSB failed: "
  313.         SELECT CASE status%
  314.         CASE 1: Throw err$ + "No sounds were allocated by DQBinit."
  315.         CASE 2: Throw err$ + "Soundcard not found or DSP failed to reset."
  316.         CASE 3: Throw err$ + "Old soundcard not supported."
  317.         CASE 4: Throw err$ + "Specified DMA channel is not supported."
  318.         CASE 5: Throw err$ + "Autodetection failed as the BLASTER variable is not set"
  319.         CASE 6: Throw err$ + "High mixing speed not supported."
  320.         CASE 7: Throw err$ + "Not enough memory to create the volume table."
  321.         END SELECT
  322. END IF
  323.  
  324. '                                                                          
  325. ' Prepare screen for rendering
  326. '
  327. DQBinitVGA
  328. PaletteLoad "ORANGE.PAL"
  329.  
  330. '
  331. ' Start keyboard listener
  332. '
  333. DQBinstallKeyboard
  334.  
  335. '
  336. ' Initialize the matrix
  337. '
  338. WorldInit
  339.  
  340. END SUB
  341.  
  342. SUB Throw (msg$)
  343.  
  344. SystemCleanup
  345.  
  346. SCREEN 13
  347. CLS
  348. COLOR &H7: PRINT "An error occured:"
  349. COLOR &HC: PRINT msg$
  350.        
  351. SLEEP
  352.  
  353. END SUB
  354.  
  355. REM $DYNAMIC
  356. SUB VideoSwap
  357. DQBcopyLayer 1, VIDEO
  358.  
  359. END SUB
  360.  
  361. REM $STATIC
  362. SUB WorldInit
  363. gWorldSeg% = VARSEG(gWorld%(0, 0))
  364. gWorldOff% = VARPTR(gWorld%(0, 0))
  365. END SUB
  366.  
  367. REM $DYNAMIC
  368. SUB WorldLoad (filename$)
  369.  
  370. ' Open file
  371. n& = FREEFILE
  372. OPEN filename$ FOR BINARY AS n&
  373.  
  374. ' Read world width and size
  375. DIM v AS STRING * 1
  376. GET n&, , v$
  377. gWorldWidth% = ASC(v$)
  378. GET n&, , v$
  379. gWorldHeight% = ASC(v$)
  380.  
  381. ' Read tiles
  382. FOR y% = 0 TO gWorldHeight% - 1
  383. FOR x% = 0 TO gWorldWidth% - 1
  384.         GET n&, , v$
  385.         gWorld%(x%, y%) = ASC(v$)
  386. NEXT
  387. NEXT
  388.  
  389. ' Close file
  390. CLOSE n&
  391.  
  392. END SUB
  393.  
  394. REM $STATIC
  395. SUB WorldRenderSprites
  396. DEF SEG = VARSEG(gDrawSpr$)
  397.  
  398.  
  399. DEF SEG
  400. END SUB
  401.  
  402. SUB WorldRenderWalls
  403. DEF SEG = VARSEG(gDrawCol$)
  404.  
  405. ' Length of ray from current position to next X or Y-side
  406. DIM sideDistX#
  407. DIM sideDistY#
  408.  
  409. ' Perpendicular distance to wall
  410. DIM perpDist!
  411.  
  412. ' Direction to step in X or Y-direction (either +1 or -1)
  413. DIM stepX%
  414. DIM stepY%
  415.  
  416. ' Whether a wall had been hit and which side (NS or EW)
  417. DIM hit%
  418. DIM side%
  419.  
  420.  
  421. '
  422. ' Iterate through every other even column of the screen
  423. '
  424. FOR x% = 0 TO 319 STEP 4
  425.  
  426.         '
  427.         ' Calculate ray position and direction
  428.         '
  429.         cameraX# = gCameraXTable#(x%) ' X-coord in camera space
  430.         rayPosX# = gPosX#
  431.         rayPosY# = gPosY#
  432.         rayDirX# = gDirX# + gPlaneX# * cameraX#
  433.         rayDirY# = gDirY# + gPlaneY# * cameraX#
  434.  
  435.         '
  436.         ' Determine in which tile the camera is positioned
  437.         '
  438.         mapX% = INT(rayPosX#)
  439.         mapY% = INT(rayPosY#)
  440.  
  441.         '
  442.         ' Length of ray from one X or Y-side to next X or Y-side
  443.         '
  444.         deltaDistX# = SQR(1 + (rayDirY# * rayDirY#) / (rayDirX# * rayDirX#))
  445.         deltaDistY# = SQR(1 + (rayDirX# * rayDirX#) / (rayDirY# * rayDirY#))
  446.              
  447.         '
  448.         ' Reset wall hit flag
  449.         '
  450.         hit% = 0
  451.  
  452.         '
  453.         ' Calculate step and initial sideDist
  454.         '
  455.         IF rayDirX# < 0 THEN
  456.                 stepX% = -1
  457.                 sideDistX# = (rayPosX# - mapX%) * deltaDistX#
  458.         ELSE
  459.                 stepX% = 1
  460.                 sideDistX# = (mapX% + 1 - rayPosX#) * deltaDistX#
  461.         END IF
  462.         IF rayDirY# < 0 THEN
  463.                 stepY% = -1
  464.                 sideDistY# = (rayPosY# - mapY%) * deltaDistY#
  465.         ELSE
  466.                 stepY% = 1
  467.                 sideDistY# = (mapY% + 1 - rayPosY#) * deltaDistY#
  468.         END IF
  469.  
  470.         '
  471.         ' Perform DDA
  472.         '
  473.         DO
  474.                 ' Jump to next map square either in X-direction,
  475.                 ' or in Y-direction
  476.                 IF sideDistX# < sideDistY# THEN
  477.                         sideDistX# = sideDistX# + deltaDistX#
  478.                         mapX% = mapX% + stepX%
  479.                         side% = 0
  480.                 ELSE
  481.                         sideDistY# = sideDistY# + deltaDistY#
  482.                         mapY% = mapY% + stepY%
  483.                         side% = -1
  484.                 END IF
  485.  
  486.                 ' Check if the ray has hit a wall
  487.                 IF (gWorld%(mapX%, mapY%) > 0) THEN
  488.                         hit% = 1
  489.                 END IF
  490.         LOOP UNTIL hit% = 1
  491.  
  492.         '
  493.         ' Calculate distance projected on camera direction
  494.         ' (Oblique distance will give a fisheye effect)
  495.         '
  496.         IF side% = 0 THEN
  497.                 perpDist! = (mapX% - rayPosX# + (1 - stepX%) / 2) / rayDirX#
  498.         ELSE
  499.                 perpDist! = (mapY% - rayPosY# + (1 - stepY%) / 2) / rayDirY#
  500.         END IF
  501.              
  502.         '
  503.         ' Draw wall column
  504.         '
  505.         CALL ABSOLUTE(BYVAL x%, BYVAL perpDist!, BYVAL side%, SADD(gDrawCol$))
  506.        
  507.         '
  508.         ' Save column distance
  509.         '
  510.         gPerpDists!(x%) = perpDist!
  511. NEXT
  512. DEF SEG
  513.  
  514. END SUB
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top