about summary refs log tree commit diff stats
path: root/translate_mu_debug
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-05-24 22:55:57 -0700
committerKartik Agaram <vc@akkartik.com>2020-05-24 22:55:57 -0700
commit3ec4bae2614e3c7c7553e1e1f51031cf82fc6e57 (patch)
tree38bab4dbb1b6eefc890e1de41dd8cdad0cbc0085 /translate_mu_debug
parentfe6d099b78b1ab9a0868791bec5cf3ea92361d6f (diff)
downloadmu-3ec4bae2614e3c7c7553e1e1f51031cf82fc6e57.tar.gz
6400
Diffstat (limited to 'translate_mu_debug')
-rwxr-xr-xtranslate_mu_debug8
1 files changed, 8 insertions, 0 deletions
diff --git a/translate_mu_debug b/translate_mu_debug
new file mode 100755
index 00000000..3c014535
--- /dev/null
+++ b/translate_mu_debug
@@ -0,0 +1,8 @@
+#!/bin/sh
+# Translate Mu programs with debug information on Linux.
+
+set -e
+
+cat $*          |apps/mu      > a.subx
+
+./translate_subx_debug init.linux [0-9]*.subx mu-init.subx a.subx
n140'>140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
# Draw a second-degree bezier curve using 3 control points.
#
# http://members.chello.at/easyfilter/bresenham.html says that this algorithm
# works only if "the gradient does not change sign". Either:
#   x0 >= x1 >= x2
# or:
#   x0 <= x1 <= x2
# Similarly for y0, y1 and y2.
#
# This seems superficially similar to the notions of convex and concave, but I
# think it isn't. I think it's purely a property of the frame of reference.
# Rotating the axes can make the gradient change sign or stop changing sign
# even as 3 points preserve fixed relative bearings to each other.
fn draw-monotonic-bezier screen: (addr screen), x0: int, y0: int, x1: int, y1: int, x2: int, y2: int, color: int {
  var xx: int
  var yy: int
  var xy: int
  var sx: int
  var sy: int
  # sx = x2-x1
  var tmp/eax: int <- copy x2
  tmp <- subtract x1
  copy-to sx, tmp
  # sy = y2-y1
  tmp <- copy y2
  tmp <- subtract y1
  copy-to sy, tmp
  # xx = x0-x1
  tmp <- copy x0
  tmp <- subtract x1
  copy-to xx, tmp
  # yy = y0-y1
  tmp <- copy y0
  tmp <- subtract y1
  copy-to yy, tmp
  # cur = xx*sy - yy*sx
  var cur-f/xmm4: float <- convert xx
  {
    var sy-f/xmm1: float <- convert sy
    cur-f <- multiply sy-f
    var tmp2-f/xmm1: float <- convert yy
    var sx-f/xmm2: float <- convert sx
    tmp2-f <- multiply sx-f
    cur-f <- subtract tmp2-f
  }
  # if (xx*sx > 0) abort
  {
    tmp <- copy xx
    tmp <- multiply sx
    compare tmp, 0
    break-if-<=
    abort "bezier: gradient of x changes sign"
  }
  # if (yy*sy > 0) abort
  {
    tmp <- copy yy
    tmp <- multiply sy
    compare tmp, 0
    break-if-<=
    abort "bezier: gradient of y changes sign"
  }
  # swap P0 and P2 if necessary
  {
    # dist1 = sx*sx + sy*sy
    var dist1/ecx: int <- copy sx
    {
      dist1 <- multiply sx
      {
        break-if-not-overflow
        abort "bezier: overflow 1"
      }
      tmp <- copy sy
      tmp <- multiply sy
      {
        break-if-not-overflow
        abort "bezier: overflow 2"
      }
      dist1 <- add tmp
    }
    # dist2 = xx*xx + yy*yy
    var dist2/edx: int <- copy xx
    {
      dist2 <- multiply xx
      {
        break-if-not-overflow
        abort "bezier: overflow 3"
      }
      tmp <- copy yy
      tmp <- multiply yy
      {
        break-if-not-overflow
        abort "bezier: overflow 4"
      }
      dist2 <- add tmp
    }
    # if (dist1 <= dist2) break
    compare dist1, dist2
    break-if-<=
    # swap x0 and x2
    tmp <- copy x0
    copy-to x2, tmp
    tmp <- copy sx
    tmp <- add x1
    copy-to x0, tmp
    # swap y0 and y2
    tmp <- copy y0
    copy-to y2, tmp
    tmp <- copy sy
    tmp <- add y1
    copy-to y0, tmp
    # cur = -cur
    var negative-1/eax: int <- copy -1
    var negative-1-f/xmm1: float <- convert negative-1
    cur-f <- multiply negative-1-f
  }
  var x/ecx: int <- copy x0
  var y/edx: int <- copy y0
  var zero-f: float
  # plot a curved part if necessary
  $draw-monotonic-bezier:curve: {
    compare cur-f, zero-f
    break-if-=
    # xx += sx
    tmp <- copy sx
    add-to xx, tmp
    # sx = sgn(x2-x)
    tmp <- copy x2
    tmp <- subtract x
    tmp <- sgn tmp
    copy-to sx, tmp
    # xx *= sx
    tmp <- copy sx
    tmp <- multiply xx
    copy-to xx, tmp
    # yy += sy
    tmp <- copy sy
    add-to yy, tmp
    # sy = sgn(y2-y)
    tmp <- copy y2
    tmp <- subtract y
    tmp <- sgn tmp
    copy-to sy, tmp
    # yy *= sy
    tmp <- copy sy
    tmp <- multiply yy
    copy-to yy, tmp
    # xy = 2*xx*xy
    tmp <- copy xx
    tmp <- multiply yy
    {
      break-if-not-overflow
      abort "bezier: overflow 5"
    }
    tmp <- shift-left 1
    {
      break-if-not-overflow
      abort "bezier: overflow 6"
    }
    copy-to xy, tmp
    # xx *= xx
    tmp <- copy xx
    tmp <- multiply tmp
    {
      break-if-not-overflow
      abort "bezier: overflow 7"
    }
    copy-to xx, tmp
    # yy *= yy
    tmp <- copy yy
    tmp <- multiply tmp
    {
      break-if-not-overflow
      abort "bezier: overflow 7"
    }
    copy-to yy, tmp
    # if (cur*sx*sy < 0) negative curvature
    {
      var tmp-f/xmm0: float <- copy cur-f
      var sx-f/xmm1: float <- convert sx
      tmp-f <- multiply sx-f
      var sy-f/xmm1: float <- convert sy
      tmp-f <- multiply sy-f
      compare tmp-f, zero-f
      break-if-float>=
      #
      negate xx
      negate yy
      negate xy
      # cur = -cur
      var negative-1/eax: int <- copy -1
      var negative-1-f/xmm1: float <- convert negative-1
      cur-f <- multiply negative-1-f
    }
    var four/ebx: int <- copy 4
    var dx-f/xmm5: float <- convert four
    var dy-f/xmm6: float <- convert four
    # dx = 4*sy*cur*(x1-x0) + xx - xy
    {
      var tmp/xmm0: float <- convert sy
      dx-f <- multiply tmp
      dx-f <- multiply cur-f
      tmp <- convert x1
      var tmp2/xmm3: float <- convert x
      tmp <- subtract tmp2
      dx-f <- multiply tmp
      tmp <- convert xx
      dx-f <- add tmp
      tmp <- convert xy
      dx-f <- subtract tmp
    }
    # dy-f = 4*sx*cur*(y0-y1) + yy - xy
    {
      var tmp/xmm0: float <- convert sx
      dy-f <- multiply tmp
      dy-f <- multiply cur-f
      tmp <- convert y
      var tmp2/xmm3: float <- convert y1
      tmp <- subtract tmp2
      dy-f <- multiply tmp
      tmp <- convert yy
      dy-f <- add tmp
      tmp <- convert xy
      dy-f <- subtract tmp
    }
    # xx += xx
    tmp <- copy xx
    add-to xx, tmp
    # yy += yy
    tmp <- copy yy
    add-to yy, tmp
    # err = dx+dy+xy
    var err-f/xmm7: float <- copy dx-f
    err-f <- add dy-f
    var xy-f/xmm0: float <- convert xy
    err-f <- add xy-f
    #
    $draw-monotonic-bezier:loop: {
      pixel screen, x, y, color
      # if (x == x2 && y == y2) return
      {
        compare x, x2
        break-if-!=
        compare y, y2
        break-if-!=
        return
      }
      # perform-y-step? = (2*err < dx)
      var perform-y-step?/eax: boolean <- copy 0/false
      var two-err-f/xmm0: float <- copy err-f
      {
        var two/ebx: int <- copy 2
        var two-f/xmm1: float <- convert two
        two-err-f <- multiply two-f
        compare two-err-f, dx-f
        break-if-float>=
        perform-y-step? <- copy 1/true
      }
      # if (2*err > dy)
      {
        compare two-err-f, dy-f
        break-if-float<=
        # x += sx
        x <- add sx
        # dx -= xy
        var xy-f/xmm0: float <- convert xy
        dx-f <- subtract xy-f
        # dy += yy
        var yy-f/xmm0: float <- convert yy
        dy-f <- add yy-f
        # err += dy
        err-f <- add dy-f
      }
      # if perform-y-step?
      {
        compare perform-y-step?, 0/false
        break-if-=
        # y += sy
        y <- add sy
        # dy -= xy
        var xy-f/xmm0: float <- convert xy
        dy-f <- subtract xy-f
        # dx += xx
        var xx-f/xmm0: float <- convert xx
        dx-f <- add xx-f
        # err += dx
        err-f <- add dx-f
      }
      # if (dy < dx) loop
      compare dy-f, dx-f
      loop-if-float<
    }
  }
  # plot the remaining straight line
  draw-line screen, x y, x2 y2, color
}

# 0 <= u <= 1
fn bezier-point u: float, x0: int, x1: int, x2: int -> _/eax: int {
  var one/eax: int <- copy 1
  var u-prime/xmm0: float <- convert one
  u-prime <- subtract u
  var result/xmm1: float <- convert x0
  result <- multiply u-prime
  result <- multiply u-prime
  var term2/xmm2: float <- convert x1
  term2 <- multiply u
  term2 <- multiply u-prime
  result <- add term2
  result <- add term2
  var term3/xmm2: float <- convert x2
  term3 <- multiply u
  term3 <- multiply u
  result <- add term3
  var result/eax: int <- convert result
  return result
}