Dos Batch Raycast - Maze3D/Explorer3D Beta

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#46 Post by foxidrive » 22 Mar 2016 17:12

Ta, I updated my last post einstein.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#47 Post by einstein1969 » 23 Mar 2016 15:07

The mathematic behind the DDA algorithm is well explain in this site:

www.scratchapixel.com/lessons/advanced-rendering/introduction-acceleration-structure/grid

einstein1969

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#48 Post by einstein1969 » 03 Apr 2016 04:22

I have released a new version @ viewtopic.php?f=3&t=5824.

Code: Select all

:: ver. 0.5.3   2016-04-03 einstein1969
::  - Disabled parallel processing for a cuncurrent access problem see:
::    http://www.dostips.com/forum/viewtopic.php?f=3&t=7053
On a multicore(4 processor) machine the output is scramble:


I have track a problem on parallel processing, see http://www.dostips.com/forum/viewtopic.php?f=3&t=7053

In the while I have disabled "parallel processing" by setting the variable "proc" to 1 insteat of NUMBER_OF_PROCESSORS. :(

The new version 0.5.3 is avaible.
Attachments
imm_zio.png
imm_zio.png (19.04 KiB) Viewed 965 times
Last edited by einstein1969 on 20 May 2023 06:41, edited 1 time in total.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#49 Post by dbenham » 03 Apr 2016 11:21

I tried to investigate the muti-process issue at viewtopic.php?f=3&t=7053&p=46045#p46045

I thought I had a solution - simply introduce a delay before each compute engine process attempts to execute the temporary job script. I tried with a FOR /L loop.

Code: Select all

  set ^"computeEngineBegin=for /l %%. in () do if exist "^!job^!" ( (for /l %%$ in (1 1 10000) do (call )) ^& call "^!job^!"^"

I intentionally introduced a much longer delay than I thought would be necessary. It slowed the demo to a crawl (0.3 fps) :!:
But I still got erroneous output once I reached a certain point in the map. So there must be something else going on.

I did some more experiments without the delay, and it seemed like the output was fine until I reached a particular point. If I followed the same moves each time, then the error seemed to occur at the same point each time. The error did not seem to be random.

So now I am wondering if there is some edge case logic error that we are missing. But I certainly can't find a logic issue :? :evil:


Dave Benham

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#50 Post by einstein1969 » 06 Apr 2016 07:33

I did some more experiments without the delay, and it seemed like the output was fine until I reached a particular point.


Can you paste the Map with user position (at error point) like this?:

Code: Select all

██████████   ██████████
█        █   █        █  ███
█        █████        █ █   █
█                  █  ██     █
█   >                         █
█    █   █████                █
█    █   █   █     █  ██     █
█    █   █   █    ██  █ █   █
█    █   █   █        █  ███
██████████   ██████████
PlayerX/Y:40000/50000 OldplayerX/Y:40000/50000
FAST: Angle:0 GridX/Y:4/5 StepX/Y=9999/0 wait=0 FPS:2.56

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#51 Post by einstein1969 » 06 Apr 2016 09:01

@dbenham

I have included the new algorithm and eliminated old methods and nice output and I created a 0.4.1b
This is smaller code.
Can you implement in this way 0.4.2 the new idea for the problem in concurrent access?
Than I include in 0.5.x

Code: Select all

:::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Dos Batch Raycast BETA  by Francesco Poscetti aka einstein1969
::
:: This type of Engine 3D is used by  Wolfentein 3D,
:: Rise Of The Triad, DOOM, Duke Nukem 3D, etc.
::
:: Ref: http://www.dostips.com/forum/viewtopic.php?f=3&t=5824
::
:: Thanks to Aacini, foxidrive, dbenham, penpen
::
:: Tested on Windows 7
::
:: Changelog
::
:: ver. 0.4.1b   preview new algorithm and eliminated old methods
::
:: ver. 0.4.1   2015-08-30  dbenham
::  - Limit number of processes to maximum of 8
::  - Move Transpose inside of :raycast
::  - Optionally use Aacini's CursorPos.exe to eliminate screen flicker
::    Implementation is the same as for SNAKE.BAT
::    Code is available at http://goo.gl/hr6Kkn
::
:: ver. 0.4     2015-08-30  dbenham
::  - Many minor optimizations:
::      - consolidate and minimize SET /A statements
::      - main loop is now an endless FOR /L loop running in a child process
::      - reduce CALLs and rearrange code to minimize CALL distance
::      - remove dynamic title
::  - Nearly instantaneous drawing of 2D map
::  - Player character now indicates orientation
::  - Implemented parallel processing of ray cast partitions based on NUMBER_OF_PROCESSORS
::  - "Z" now toggles between Old and New rendering algorithm
::  - "Q" quits the program
::  - New (fast) rendering now 2-3 times faster on quad-core machine (4-5 frames per second)
::  - Old (slow) rendering now 4+ times faster on quad-core machine  (1-2 frames per second)
::
:: ver. 0.3     jeb  2015-08-25
::  - Improved speed by inlining the Sinus calculation (~15% on reference system)
::  - Improved speed by direct calculating the next gridX/Y coordinates (~60%)
::
:: ver. 0.2     20/08/2015  einstein1969
::  - Not clear the screen until next.
::  - Added moviment on left/right and key "K" "L" for rotate.
::  - Fixed bug on calculate distance
::  - Added partial clipping on Z (Distance)
::
:: ver. 0.1     04/07/2015  einstein1969
::  - New faster algorithm. Not optimizated for now.
::  - Use transpose trick of penpen
::  - Use new set of character for better visualize and fast antialiasing.
::  - Detect when a player slamming against the wall.
::  - You can use WASD for move!
::  - You can view the player in the MAP.
::  - You can modify the MAP more easily.
::
:: Ver. 0.01b   10/08/2014  einstein1969
::  - Added temporary dir and use swapout mechanism for manage env.
::
:: Ver. 0.01a   09/08/2014  einstein1969
::  - Initial version + some fixes
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::

@echo off
if "%~1" neq "" goto %1

setlocal EnableDelayedExpansion
mode 80,80
color 0F
cls
echo Loading...
for /f %%i in ('forfiles /m "%~nx0" /c "cmd /c echo 0x07"') do set "BEL=%%i"
set "preserve= TMP BEL COMSPEC NUMBER_OF_PROCESSORS preserve "
for /f "delims==" %%v in ('set') do if "!preserve: %%v =!" equ "!preserve!" set "%%v="
set "preserve="
set "SS=°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"
set "SC=/////////////////////////////////////////////////////////////////////////////////////////////"
set "S2=±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±"
set "S_=úúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúú"
set "SP=_____________________________________________________________________________________________"
set /a "PI=(35500000/113+5)/10, PI_div_2=(35500000/113/2+5)/10, PIx2=2*PI, PI32=PI+PI_div_2"
set "SIN=(a - a*a/1920*a/312500 + a*a/1920*a/15625*a/15625*a/2560000 - a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000)"
set "SIN(x)=(a=(x)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %SIN%)"
set SIN=
set /a y=1, MapsizeX=23, MapsizeY=10, MapWidth=MapSizeX+1, MapsizeX-=1

:: Load the Map grid. 1/2=wall 0=empty 9=player position
for %%D in (
"1212121212...2121212121"
"2........1...1........2"
"1........21212....121.1"
"2..................1..2"
"1...9.................1"
"2....1...12121........2"
"1....2...2...2.....1..1"
"1....1...1...1....12..2"
"2....2...2...2........1"
"1212212121...1212121212"
) do (
  set Map[!y!]=%%~D
  for %%Y in (!y!) do for /L %%X in (0,1,!MapSizeX!) do (
    if "!Map[%%Y]:~%%X,1!" equ "9" (
      set /A nx=%%X+1
      for %%Z in (!nx!) do set Map[!y!]=!Map[%%Y]:~0,%%X!.!Map[%%Y]:~%%Z!
      set /A Playerx = %%X, Playery = !y!
    )
  )
  set /a y+=1
)
set nx=
set y=
set /a MulPlayer=10000, Mul1=25, MaxIter1=500, MaxIter2=50, MM=MulPlayer*Mul1, M10=MM*10
set /a Playerx*=MulPlayer, Playery*=MulPlayer, OldPlayerx=Playerx, OldPlayery=Playery, angle1=0, oldSys=0

:: Initialize and launch child compute engines
set "base=%tmp%\%~nx0"
2>nul del "%base%*_job.bat"
set ^"computeEngineBegin=for /l %%. in () do if exist "^!job^!" ( call "^!job^!"^"
set ^"computeEngineEnd=del "^!job^!")^"
set /a proc=NUMBER_OF_PROCESSORS, childCnt=proc-1
if %proc% gtr 8 set /a proc=8
for /l %%N in (1 1 !childCnt!) do (
  set "file=%base%%%N.render"
  set "job=%base%%%N_job.bat"
  >nul 2>nul <nul start "" /b "%comspec%" /d /v:on /c "%~f0" :computeEngine
)

:: Initialize main compute engine
set "file=%base%!proc!.render"
set "files="
for /l %%N in (1 1 !proc!) do set files=!files! "%base%%%N.render"
set "computeEngineBegin="
set "computeEngineEnd="

:: Prepare the map for display
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE
set "map="
for /l %%Y in (1,1,!MapsizeY!) do (
  for /l %%X in (0,1,!MapsizeX!) do (
    if "!Map[%%Y]:~%%X,1!" geq "1" (
      set "map=!map!Û"
    ) else (
      set "map=!map! "
    )
  )
  set "map=!map!!LF!"
)

:: Define player characters:
for %%# in (
  "345   0  15  >"
  " 30  45  60  \"
  " 75  90 105  v"
  "120 135 150  /"
  "165 180 195  <"
  "210 225 240  \"
  "255 270 285  ^"
  "300 315 330  /"
) do for /f "tokens=1-4" %%A in (%%#) do (
  set "P%%A=%%D"
  set "P%%B=%%D"
  set "P%%C=%%D"
)

:: Define some screen management variables and macros
if exist "%~dp0CursorPos.exe" (
  set "cls=CursorPos 0 0"
) else (
  set "cls=cls"
)
set "space=            "

:: Launch the main loop
"%COMSPEC%" /d /v:on /c "%~f0" :mainLoop
exit /b

:mainLoop
for /l %%. in () do (
  set /a gridX=Playerx/MulPlayer, gridy=Playery/MulPlayer
  for %%X in (!gridx!) do for %%Y in (!gridy!) do if "!Map[%%Y]:~%%X,1!" geq "1" (
    set /A Playerx = OldPlayerx, Playery = OldPlayery
    set /P ".=%BEL%"<nul
  ) else (
   
    set /A "StepY=%SIN(x):x=!Angle1! * PI / 180%, StepX=%SIN(x):x=PI_div_2-!Angle1! * PI / 180%"
    set /a "angle1=(angle1+360)%%360"

    call :raycast

    %= Draw Map =%
    set /a "pos=(PlayerY/MulPlayer-1)*mapWidth+PlayerX/MulPlayer, pos2=pos+1"
    for /f "tokens=1-3" %%1 in ("!pos! !pos2! !angle1!") do echo !map:~0,%%1!!P%%3!!map:~%%2,-1!

    echo Playerx:!Playerx! Playery:!playery! oldplayerx:!oldpl.x! oldpl.y=!oldplayery!%space%
    echo Angle:!angle1! gridx:!gridx! gridy:!gridy! StepX=!StepX! StepY=!StepY! wait=!wait!%space%
    set /A OldPlayerx=Playerx, OldPlayery=Playery
  )
  "%COMSPEC%\..\choice.exe" /N /C wksladqu >nul
  if errorlevel 8 (
    %= U - Redraw =%
    (call )
  ) else if errorlevel 7 (
    %= Q - Quit =%
    for /l %%N in (1 1 !childCnt!) do >"%base%%%N_job.bat.tmp" echo del "%%~f0"^&exit
    ren "%base%*_job.bat.tmp" *.
    for /l %%. in () do if not exist "%base%*_job.bat" del "%base%*.render"&exit
  ) else if errorlevel 6 (
    %= D - Right =%
    set /A "PlayerX=PlayerX-StepY/2, PlayerY=PlayerY+StepX/2"
  ) else if errorlevel 5 (
    %= A - Left =%
    set /A "PlayerX=PlayerX+StepY/2, PlayerY=PlayerY-StepX/2"
  ) else if errorlevel 4 (
    %= L - Rotate Right =%
    set /A angle1+=15
  ) else if errorlevel 3 (
    %= S - Down - Backward =%
    set /A "PlayerX=PlayerX-StepX/2, PlayerY=PlayerY-StepY/2"
  ) else if errorlevel 2 (
    %= K - Rotate Left =%
    set /A angle1-=15
  ) else if errorlevel 1 (
    %= W - Up - Forward =%
    set /A "PlayerX=PlayerX+StepX/2, PlayerY=PlayerY+StepY/2"
  )
)


:raycast

  :: Save start time
  set "t1=!time: =0!"

  :: Create jobs
  set /a from=angle1-32, to=angle1+32, chunk=65/proc, end=from+chunk-1
  for /l %%N in (1 1 %childCnt%) do (
    >"%base%%%N_job.bat.tmp" echo set /a "from=!from!, to=!end!, angle1=!angle1!, playerX=!playerX!, playerY=!playerY!"
    set /a from+=chunk, end+=chunk
    ren "%base%%%N_job.bat.tmp" *.
  )

  setlocal
  :computeEngine
  %computeEngineBegin%
  >"%file%" (
    for /L %%Z in (!from!,1,!to!) do (

      set /A "Z=%%Z, aStepY=%SIN(x):x=Z * 31416 / 180%"
      set /A "aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
      set/A  "A=%Angle1%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"

        set /A $X=%PlayerX%/10000, $Y=%PlayerY%/10000

        if !aStepX! equ 0 (
          set /A $tx=Dtx=100000000, $SX=0
        ) else if !aStepX! lss 0 (
                     set /A "$tx=($X*10000-PlayerX)*10000/aStepX, Dtx=-10000*10000/aStepX, $SX=-1"
              ) else set /A "$tx=(($X+1)*10000-PlayerX)*10000/aStepX, Dtx=10000*10000/aStepX, $SX=1"
        if !aStepY! equ 0 (
          set /A $ty=Dty=100000000, $SY=0
        ) else if !aStepY! lss 0 (
                     set /A "$ty=($Y*10000-PlayerY)*10000/aStepY, Dty=-10000*10000/aStepY, $SY=-1"
              ) else set /A "$ty=(($Y+1)*10000-PlayerY)*10000/aStepY, Dty=10000*10000/aStepY, $SY=1"

        set "$B=" & set /A "Distance=21*10000" & rem max valore altrimenti overflow in distance*corr

        for /L %%£ in (1,1,3) do if not defined $B for /L %%? in (1,1,7) do if not defined $B (

          if !$tx! lss !$ty! (
            set /A $tx+=Dtx, $X+=$SX
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$tx-Dtx, Side=0, $B=!Map[%%Y]:~%%X,1!
            )
          ) else (
            set /A $ty+=Dty, $Y+=$SY
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$ty-Dty, Side=1, $B=!Map[%%Y]:~%%X,1!
            )
          )
       )
       if not defined $B set "$B=1"

       set /A "distance=350/((((k=(Distance*corr))/%Mulplayer%+555)/1000)+1), len=distance*2, st=(50-len)/2"
       set /A C=$B

      %= 2D-clipping =%
      if !st! lss 1 set st=1
      if !st! gtr 50 set st=50
      for /f "tokens=1,2" %%X in ("!st! !len!") do (
        if !C! equ 1 (
            echo -!S_:~0,%%X!Û!SS:~0,%%Y!Û!SP:~0,%%X!-
        ) else  echo -!S_:~0,%%X!Û!S2:~0,%%Y!Û!SP:~0,%%X!-
      )
    )
  )
  %computeEngineEnd%
  endlocal

  set /a wait=0
  :waitForJobCompletion
  if exist "%base%*_job.bat" (
    set /a wait+=1
    goto :waitForJobCompletion
  )

  :: Transpose and display results
  setlocal
  set /a LineN=0
  for /f usebackq^ delims^=^ eol^= %%A in (%files%) do (
    set /A LineN+=1
    set "N!LineN!=%%A"
  )
  set /a "MaxN=LineN-1"
  set "transposedLine="
  for /l %%m in (1, 1, !LineN!) do set "transposedLine=!transposedLine!^!%%^A%%m:~%%n,1^!"
  set /a MaxN=53
  %cls%
  for %%A in (N) do for /L %%n in (0, 1, !MaxN!) do echo(^|%transposedLine%^|
  endlocal

  :: Compute and display rendering time
  for /f "tokens=1-8 delims=:.," %%a in ("!t1!:!time: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31)&8640000"
  echo Time Elapsed:!a!0ms%space%
exit /b

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#52 Post by einstein1969 » 18 Apr 2016 11:30

I have initied to rewrite the code becouse is not possible get over 5-6 FPS with current algorithm.
The pseudo code that I had written was recursive but with the help of user Scara95 @Html.it forum is now iterative.

Code: Select all

subroutine raypacket (from, to)
   stack calls
   push(calls, (from, to))
   while not empty(calls) do
     (from, to) = pop(calls)
     if from = to then raytraverse(from)  //simple problem
     if from-to=1 then raytraverse(to); raytraverse(from); // simple problem
     else
      destination1=raytraverse(from)
      destination2=raytraverse(to)
      if destination1=destination2 then
        if from - to > 1 then linear_interpolate_distance(from,to)
      else begin
        push(calls, (from+(to-from)/2+1,to))
        push(calls, (from,from+(to-from)/2))
      end
     end
   end


I hope to get my goal soon.

Cornbeetle
Posts: 31
Joined: 23 Nov 2015 09:34

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#53 Post by Cornbeetle » 05 Oct 2016 17:11

Does anyone know if this has been tested (and works) in Windows 10? I tried to launch it today but it immediately crashes!

Thanks!

ShadowThief
Expert
Posts: 1160
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#54 Post by ShadowThief » 05 Oct 2016 17:33

Cornbeetle wrote:Does anyone know if this has been tested (and works) in Windows 10? I tried to launch it today but it immediately crashes!

Thanks!

The code in the first post absolutely works in Windows 10 and runs perfectly. Run it from a command prompt instead of double-clicking on it to see what error you're getting.

Cornbeetle
Posts: 31
Joined: 23 Nov 2015 09:34

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#55 Post by Cornbeetle » 05 Oct 2016 17:55

ShadowThief wrote:
Cornbeetle wrote:Does anyone know if this has been tested (and works) in Windows 10? I tried to launch it today but it immediately crashes!

Thanks!

The code in the first post absolutely works in Windows 10 and runs perfectly. Run it from a command prompt instead of double-clicking on it to see what error you're getting.


So it looks like it was erroring out due to the filename (which I renamed) having a parenthesis in it. After removing the parenthesis it works fine.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#56 Post by einstein1969 » 26 Oct 2016 08:31

I found another trick for speedup the algorithm.

The output of the screen is symmetric on the X or Y. It is possible calculate only half number of lines. In this mode we can get 50ms off or more on the traslate procedure.

I can't implement because I'm getting a depressive status and my mind not work. Sorry :(

Francesco.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#57 Post by einstein1969 » 31 Jan 2017 13:05

I have forgot the password of my laptop :cry: :twisted: but I have recovered the last develop of raypacket method.

Anyone know a method for recovery a lost password on windows seven? Use a private message for help me. TIA

This is not finished. But is the way to traverse for finish the develop.
ricorsiva.cmd:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

mode 70,700

:: fare le procedure che usano fixed point variabili, esempio invece che 10000 usare 1000 come UNO.
:: Usare simmetria per ridurre a metà la transpose
:: credit to penpen for a problem on set/A

:: clear the env for fast SET
set "preserve= TMP COMSPEC NUMBER_OF_PROCESSORS preserve "
for /f "delims==" %%v in ('set') do if "!preserve: %%v =!" equ "!preserve!" set "%%v="
set "preserve="

:: Trigonometric PI=31416
set "SIN=(a - a*a/1920*a/312500 + a*a/1920*a/15625*a/15625*a/2560000 - a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000)"
set "SIN(x)=(a=(x)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %SIN%)"
set SIN=

:: define map
set   MAP[1]=1212121212...2121212121
set   MAP[2]=2........1...1........2
set   MAP[3]=1........2...2........1
set   MAP[4]=2........12121.....1..2
set   MAP[5]=1.....................1
set   MAP[6]=2....1...12121........2
set   MAP[7]=1....2...2...2.....1..1
set   MAP[8]=2....1...1...1....12..2
set   MAP[9]=1....2...2...2........1
set  MAP[10]=2121212121...1212121212

:: define player position in MAP coordinate. Moltiply by 10000 because I use FIXED POINT math, 10000 is ONE.
:: Angle is player angle visual.
:: GridX=3 GridY=5
set /A Playerx=3*10000, PlayerY=5*10000, Angle=0

::define characters to print
set "SS=°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"
set "S_=úúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúú"
set "S2=±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±"
set "SP=__________________________"
rem set "SC=///////////////////////////////////////////////////"

:: Do whole round
for /l %%. in (1,1,360) do (
   call :raycast PlayerX PlayerY Angle
   set /A Angle+=1
)

exit /b

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:raycast
  set/A  from=Angle-32, to=Angle+32

rem old method
set t1=%time: =0%

(
  for /L %%Z in (!from!,1,!to!) do (

      set /A "Z=%%Z, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
      set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"

rem Prepare DDA

      rem questa set va fuori dal ciclo? No, perche poi $X, $Y cambiano. Forse e meglio settare due variabili GridX e GridY
      set /A $X=PlayerX/10000, $Y=PlayerY/10000

        if !aStepX! equ 0 (
          set /A $tx=Dtx=100000000, $SX=0
        ) else if !aStepX! lss 0 (
                     set /A "$tx=($X*10000-PlayerX)*10000/aStepX, Dtx=-10000*10000/aStepX, $SX=-1"
              ) else set /A "$tx=(($X+1)*10000-PlayerX)*10000/aStepX, Dtx=10000*10000/aStepX, $SX=1"
        if !aStepY! equ 0 (
          set /A $ty=Dty=100000000, $SY=0
        ) else if !aStepY! lss 0 (
                     set /A "$ty=($Y*10000-PlayerY)*10000/aStepY, Dty=-10000*10000/aStepY, $SY=-1"
              ) else set /A "$ty=(($Y+1)*10000-PlayerY)*10000/aStepY, Dty=10000*10000/aStepY, $SY=1"

        set "$B="
        set /A "Distance=21*10000" & rem max value else overflow in distance*corr

rem raytraverse
        for /L %%£ in (1,1,3) do if not defined $B for /L %%? in (1,1,7) do if not defined $B (
          if !$tx! lss !$ty! (
            set /A $tx+=Dtx, $X+=$SX
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$tx-Dtx, Side=0, $B=!Map[%%Y]:~%%X,1!
            )
          ) else (
            set /A $ty+=Dty, $Y+=$SY
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$ty-Dty, Side=1, $B=!Map[%%Y]:~%%X,1!
            )
          )
       )
       if not defined $B set "$B=1" & rem title A:%%Z D:!Distance!& pause>nul
       set /A "distance=350/((((k=(Distance*corr))/10000+555)/1000)+1), len=distance*2, st=(50-len)/2"
       set /A C=$B

rem prepare_output

      %= 2D-clipping =%
      if !st! lss 1 (set st=1) else if !st! gtr 50 set st=50
      for /f "tokens=1,2" %%X in ("!st! !len!") do (
        if !C! equ 1 (
          rem calcolare qui la lunghezza della linea che e' 50+numero caratteri fissi. ad ora sono circa 66
          rem inserire 65 nella parte di visualizzazione al posto del MaxN
            echo -!S_:~0,%%X!°±²Û²±°!SS:~0,%%Y!°±²Û²±°!SP:~0,%%X!-
       ) else (
          echo -!S_:~0,%%X!°±²Û²±°!S2:~0,%%Y!°±²Û²±°!SP:~0,%%X!-
        )
      )

  )
) >text.render.txt

rem transpose

  :: Transpose and display results
  setlocal
  set /A LineN=0
  for /f usebackq^ delims^=^ eol^= %%A in (text.render.txt) do (
    set /A LineN+=1
    set "N!LineN!=%%A"
  )

  set "transposedLine="
  rem APA
  for /L %%m in (1, 1, !LineN!) do set "transposedLine=!transposedLine!^!N%%m:~%%n,1^!"

  cls
  echo(
  for /L %%n in (0, 1, !LineN!) do echo( ^|%transposedLine%^|
  endlocal

  for /F "tokens=1-8 delims=:.," %%a in ("!t1!:!time: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31)&8640000"
  echo Time elapsed:!a!0ms

  pause

rem new method
rem calcolare le distanze invece che le stringhe dei muri. Così è più veloce. fare prove

  call :raypacket !from! !to!

  pause

exit/b


:raypacket
 rem stack calls
 set /A c=0 & :: empty stack
 rem push(calls, (from, to))
 set /A c+=1
 set calls[%c%].1=!from!
 set calls[%c%].2=!to!
 set Break=
 rem 65=Field of View 0..64
 rem simulate while not empty(calls) do
 rem echo qui0
 For /L %%N in (0,1,64) do if not defined Break (
  rem (from, to) = pop(calls)
  set /A from=calls[!c!].1, to=calls[!c!].2, c-=1
  rem if from = to then raytraverse(from)  //simple problem
  if !from! equ !to! (
      rem echo qui1
      rem TODO check if already traverse
      set /A "Z=from, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
      set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"
      call :new_prepareDDA_raytraverse
      set /A ray[!from:-=_!].dist=distance, ray[!from:-=_!].side=side, ray[!from:-=_!].C=$B
  ) else (
    rem echo qui2
    set /A diff=from-to
    if !diff! equ 1 (
      rem echo qui3
      rem TODO check if already traverse
      set /A "Z=from, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
      set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"
      call :new_prepareDDA_raytraverse
      set /A ray[!from:-=_!].dist=distance, ray[!from:-=_!].side=side, ray[!from:-=_!].C=$B
      set from+=1

      rem TODO check if already traverse
      set /A "Z=from, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
      set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"
      call :new_prepareDDA_raytraverse
      set /A ray[!from:-=_!].dist=distance, ray[!from:-=_!].side=side, ray[!from:-=_!].C=$B
    ) else (
        rem echo qui4
        rem destination1=raytraverse(from)
        rem TODO check if already traverse
        set /A "Z=from, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
        set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"
        call :new_prepareDDA_raytraverse
        set /A ray[!from:-=_!].dist=distance, ray[!from:-=_!].side=side, ray[!from:-=_!].C=!$B!
        set dest1=!side! !$X! !$Y!
        rem destination2=raytraverse(to)
        rem TODO check if already traverse
        set /A "Z=to, aStepY=%SIN(x):x=Z * 31416 / 180%, aStepX=%SIN(x):x=15708-(Z * 31416 / 180)%"
        set /A "A=%Angle%, corr=%SIN(x):x=15708-(Z-A) * 31416 / 180%"
        call :new_prepareDDA_raytraverse
        set /A ray[!to:-=_!].dist=distance, ray[!to:-=_!].side=side, ray[!to:-=_!].C=$B
        set dest2=!side! !$X! !$Y!
        rem if destination1=destination2 then
        if "!dest1!"=="!dest2!" (
            echo qui5
            rem linear_interpolate_distance(from,to)
            rem https://en.wikipedia.org/wiki/Linear_interpolation
            set /A x0=from, x1=to, y0=ray[!from:-=_!].dist, y1=ray[!to:-=_!].dist
            for /l %%x in (!x0!,1,!x1!) do set /A "ray[%%x].dist=y0+(y1-y0)*(%%x-x0)/(x1-x0)"
        ) else (
          echo qui6
          rem push(calls, (from+(to-from)/2+1,to))
          rem push(calls, (from,from+(to-from)/2))
        )
    )
  )
  if !c! equ 0 set Break=True
 )
set ray
exit /b

:new_prepareDDA_raytraverse
rem echo dentro

      rem questa riga seguente col set va fuori dal ciclo? No, perche poi $X, $Y cambiano. Forse e meglio settare due variabili GridX e GridY
      set /A $X=PlayerX/10000, $Y=PlayerY/10000

        if !aStepX! equ 0 (
          set /A $tx=Dtx=100000000, $SX=0
        ) else if !aStepX! lss 0 (
                     set /A "$tx=($X*10000-PlayerX)*10000/aStepX, Dtx=-10000*10000/aStepX, $SX=-1"
              ) else set /A "$tx=(($X+1)*10000-PlayerX)*10000/aStepX, Dtx=10000*10000/aStepX, $SX=1"
        if !aStepY! equ 0 (
          set /A $ty=Dty=100000000, $SY=0
        ) else if !aStepY! lss 0 (
                     set /A "$ty=($Y*10000-PlayerY)*10000/aStepY, Dty=-10000*10000/aStepY, $SY=-1"
              ) else set /A "$ty=(($Y+1)*10000-PlayerY)*10000/aStepY, Dty=10000*10000/aStepY, $SY=1"

        set "$B="
        set /A "Distance=21*10000" & rem max value else overflow in distance*corr

:: raytraverse

        for /L %%£ in (1,1,3) do if not defined $B for /L %%? in (1,1,7) do if not defined $B (
          if !$tx! lss !$ty! (
            set /A $tx+=Dtx, $X+=$SX
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$tx-Dtx, Side=0, $B=!Map[%%Y]:~%%X,1!
            )
          ) else (
            set /A $ty+=Dty, $Y+=$SY
            for /f "tokens=1,2" %%X in ("!$X! !$Y!") do if "!Map[%%Y]:~%%X,1!" geq "1" (
              set /A Distance=$ty-Dty, Side=1, $B=!Map[%%Y]:~%%X,1!
            )
          )
       )
       if not defined $B set "$B=1" & rem title A:%%Z D:!Distance!& pause>nul
       set /A "distance=350/((((k=(Distance*corr))/10000+555)/1000)+1)

rem echo fine

exit/b


Francesco

npocmaka_
Posts: 512
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#58 Post by npocmaka_ » 31 Jan 2017 13:35

Glad to see you back :)

I've tried the last code but I get this:

Code: Select all

%£ was unexpected at this time.


Will try to see where it comes from.

I think it from here :

Code: Select all

rem raytraverse
        for /L %%£ in (1,1,3) do if not defined $B for /L %%? in (1,1,7) do if not defined $B (

npocmaka_
Posts: 512
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#59 Post by npocmaka_ » 31 Jan 2017 13:44

and on every key stroke the ray array is printed... (there's set ray on line 225)

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Raycast - Maze3D/Explorer3D Beta

#60 Post by einstein1969 » 01 Feb 2017 09:39

npocmaka_ wrote:Glad to see you back :)

I've tried the last code but I get this:

Code: Select all

%£ was unexpected at this time.



On my system this error is not show...

The "set ray" is a debug line. The code is not finished! Sorry :cry:

Francesco

Post Reply