List where pinballs would exit a grid of bumpers from different entrance points Inspired by this lumosity mini game, Pinball Recall

We start with a rectangular grid (viewed from above) with several bumpers as follows. Entrances/exits are numbered counter-clockwise starting from the leftmost of the bottom of the grid, as number 0.

   24 23 22 21 20 19 18 17 16 15
25  .  .  .  .  .  /  .  .  .  . 14
26  .  .  .  .  .  .  .  .  .  . 13
27  .  /  \  .  .  \  .  .  \  . 12
28  .  .  .  .  .  .  .  .  .  . 11
29  .  .  .  .  .  .  /  .  .  . 10
    0  1  2  3  4  5  6  7  8  9


Pinballs can be fired from each entrance into the grid at a direction perpendicular to the grid wall, e.g. in the above example:


0 to 9: fired upwards
10 to 14: fired to the left
15 to 24: fired downwards
24 to 29: fired to the right


The pinballs will move in a straight line until they reach an exit, or a bumper, in which case the ball will bounce off the bumper and change direction. So in above diagram,


from 0, ball goes straight to 24
from 1, ball goes up to / and bounces off to reach \, then bounces off again and ends up at 2
from 10, ball goes left to / and bounces off to 6


Inputs

Program shall receive the grid width and height.
Then program receives the bumper orientation (represented as / or \) followed by coordinates, which also start from 0 from bottom left, e.g.

 4  .  .  .  .  .  .  .  .  .  .
 3  .  .  .  .  .  .  .  .  .  .
 2  .  .  .  .  .  .  .  .  .  .
 1  .  .  .  .  .  .  .  .  .  .
 0  .  .  .  .  .  .  .  .  .  .
    0  1  2  3  4  5  6  7  8  9


"done" keyword used to indicate end of input

edit: as suggested by ngn, program may receive list of bumper coordinates instead so the "done" keyword is not needed

Output

Program should print out the exit locations of a pinball if they are fired from 0 to the last entrance of grid, in above case, 0 to 29

Sample input and output

Input

10 5
/ 1 2 / 5 4 / 6 0 \ 2 2 \ 5 2 \ 8 2
done


Output

24 2 1 21 20 22 10 17 14 15 6 28 16 26 8 9 12 7 29 25 4 3 5 27 0 19 13 23 11 18


Leaderboard (as of 20Oct2019)


Neil, Charcoal, 133 bytes
Arnauld, JavaScript (ES6), 212 bytes
Embodiment of Ignorance, C# (Visual C# Interactive Compiler), 277 bytes
Chas Brown, Python 2, 290 bytes


edit: FryAmTheEggman points out a similar question to try
JavaScript (ES6),  218 215 213  212 bytes
Takes input as (w,h,o) where \$o\$ is an object whose keys are the coordinates of the bumpers in 'x,y' format and whose values are either '/' or '\'.

(w,h,o)=&gt;(A=[...Array(w+h&lt;&lt;1)].map((_,n)=&gt;(p=n-w)&lt;0?[n,-1,3]:p&lt;h?[w,p]:(p-=w)&lt;h?[h+~p,h,1]:[-1,2*h+~p,2])).map(g=([x,y,d])=&gt;A.every(([X,Y])=&gt;X-x|Y-y&amp;&amp;++i,(c=o[[x+=~-d%2,y+=~-~-d%2]])?d^=c&lt;{}||3:i=0)?g([x,y,d]):i)

Try it online!
Commented
We first create an array \$A[\:]\$ of tuples \$[x, y, d]\$ where \$(x, y)\$ is the starting position along the borders of the playfield and \$d\$ is the initial direction.
( A = [...Array(w + h &lt;&lt; 1)]  // create an array A[] of (w + h) * 2 items
  .map((_, n) =&gt;              // for each item at position n in A[]:
    (p = n - w) &lt; 0 ?         //   set p = n - w; if this is the bottom side:
      [n, -1, 3]              //     start at (n, -1) in direction 3
    :                         //   else:
      p &lt; h ?                 //     if this is the right side:
        [w, p]                //       start at (w, p) in direction 0 (implicit)
      :                       //     else:
        (p -= w) &lt; h ?        //       subtract w from p; if this is the top side:
          [h + ~p, h, 1]      //         start at (h + ~p, h) in direction 1
        :                     //       else (left side):
          [-1, 2 * h + ~p, 2] //         start at (-1, 2 * h + ~p) in direction 2
  )                           // end of map()
)                             //

We then simulate the trajectory of the ball, starting at each position defined above, until it reaches another starting position.
.map(g = ([x, y, d]) =&gt;       // for each tuple [x, y, d] in A[]:
  A.every(([X, Y]) =&gt;         //   for each tuple [X, Y] in A[]:
    X - x | Y - y             //     break if (x, y) = (X, Y)
    &amp;&amp; ++i,                   //     otherwise, increment i
    ( c =                     //     define c as
        o[[                   //       the bumper character at
          x += ~-d % 2,       //         (x, y), once updated according to d
          y += ~-~-d % 2      //         (0 = West, 1 = South, 2 = East, 3 = North)
        ]]                    //
    ) ?                       //     if c is set:
      d ^= c &lt; {} || 3        //       XOR d with 1 (for '/') or 3 (for '\')
    :                         //     else:
      i = 0                   //       initialize i to 0
  ) ?                         //   end of every(); if truthy:
    g([x, y, d])              //     do a recursive call to move the ball further
  :                           //   else:
    i                         //     we've reached a starting position: yield i
)                             // end of map()