Exemplo n.º 1
0
 def draw_step(self, x0, y0, sx, sy, plot, goback):
     """ Make a DRAW step, drawing a line and reurning if requested. """
     scale = self.draw_scale
     rotate = self.draw_angle
     aspect = self.screen.mode.pixel_aspect
     yfac = aspect[1] / (1.*aspect[0])
     x1 = (scale*sx) / 4
     y1 = (scale*sy) / 4
     if rotate == 0 or rotate == 360:
         pass
     elif rotate == 90:
         x1, y1 = int(y1*yfac), -int(x1//yfac)
     elif rotate == 180:
         x1, y1 = -x1, -y1
     elif rotate == 270:
         x1, y1 = -int(y1*yfac), int(x1//yfac)
     else:
         fx, fy = fp.Single.from_int(x1), fp.Single.from_int(y1)
         phi = fp.mul(fp.Single.from_int(rotate), deg_to_rad)
         sinr, cosr = fp.sin(phi), fp.cos(phi)
         fxfac = fp.div(fp.Single.from_int(aspect[0]), fp.Single.from_int(aspect[1]))
         fx, fy = fp.add(fp.mul(cosr,fx), fp.div(fp.mul(sinr,fy), fxfac)), fp.mul(fp.sub(fp.mul(cosr,fy), fxfac), fp.mul(sinr,fx))
         x1, y1 = fx.round_to_int(), fy.round_to_int()
     y1 += y0
     x1 += x0
     if plot:
         self.draw_line(x0, y0, x1, y1, self.last_attr)
     self.last_point = x1, y1
     if goback:
         self.last_point = x0, y0
Exemplo n.º 2
0
 def draw_step(self, x0, y0, sx, sy, plot, goback):
     """ Make a DRAW step, drawing a line and reurning if requested. """
     scale = self.draw_scale
     rotate = self.draw_angle
     aspect = self.screen.mode.pixel_aspect
     yfac = aspect[1] / (1. * aspect[0])
     x1 = (scale * sx) / 4
     y1 = (scale * sy) / 4
     if rotate == 0 or rotate == 360:
         pass
     elif rotate == 90:
         x1, y1 = int(y1 * yfac), -int(x1 // yfac)
     elif rotate == 180:
         x1, y1 = -x1, -y1
     elif rotate == 270:
         x1, y1 = -int(y1 * yfac), int(x1 // yfac)
     else:
         fx, fy = fp.Single.from_int(x1), fp.Single.from_int(y1)
         phi = fp.mul(fp.Single.from_int(rotate), deg_to_rad)
         sinr, cosr = fp.sin(phi), fp.cos(phi)
         fxfac = fp.div(fp.Single.from_int(aspect[0]),
                        fp.Single.from_int(aspect[1]))
         fx, fy = fp.add(fp.mul(cosr, fx),
                         fp.div(fp.mul(sinr, fy), fxfac)), fp.mul(
                             fp.sub(fp.mul(cosr, fy), fxfac),
                             fp.mul(sinr, fx))
         x1, y1 = fx.round_to_int(), fy.round_to_int()
     y1 += y0
     x1 += x0
     if plot:
         self.draw_line(x0, y0, x1, y1, self.last_attr)
     self.last_point = x1, y1
     if goback:
         self.last_point = x0, y0
Exemplo n.º 3
0
def value_operator(op, left, right):
    """ Get value of binary operator expression. """
    if op == tk.O_CARET:
        return vcaret(left, right)
    elif op == tk.O_TIMES:
        return vtimes(left, right)
    elif op == tk.O_DIV:
        return vdiv(left, right)
    elif op == tk.O_INTDIV:
        return fp.pack(
            fp.div(
                fp.unpack(vartypes.pass_single_keep(left)).ifloor(),
                fp.unpack(vartypes.pass_single_keep(
                    right)).ifloor()).apply_carry().ifloor())
    elif op == tk.MOD:
        numerator = vartypes.pass_int_unpack(right)
        if numerator == 0:
            # simulate division by zero
            return fp.pack(
                fp.div(
                    fp.unpack(vartypes.pass_single_keep(left)).ifloor(),
                    fp.unpack(
                        vartypes.pass_single_keep(right)).ifloor()).ifloor())
        return vartypes.pack_int(vartypes.pass_int_unpack(left) % numerator)
    elif op == tk.O_PLUS:
        return vplus(left, right)
    elif op == tk.O_MINUS:
        return vartypes.number_add(left, vartypes.number_neg(right))
    elif op == tk.O_GT:
        return vartypes.bool_to_int_keep(vartypes.gt(left, right))
    elif op == tk.O_EQ:
        return vartypes.bool_to_int_keep(vartypes.equals(left, right))
    elif op == tk.O_LT:
        return vartypes.bool_to_int_keep(not (
            vartypes.gt(left, right) or vartypes.equals(left, right)))
    elif op == tk.O_GT + tk.O_EQ:
        return vartypes.bool_to_int_keep(
            vartypes.gt(left, right) or vartypes.equals(left, right))
    elif op == tk.O_LT + tk.O_EQ:
        return vartypes.bool_to_int_keep(not vartypes.gt(left, right))
    elif op == tk.O_LT + tk.O_GT:
        return vartypes.bool_to_int_keep(not vartypes.equals(left, right))
    elif op == tk.AND:
        return vartypes.twoscomp_to_int(
            vartypes.pass_twoscomp(left) & vartypes.pass_twoscomp(right))
    elif op == tk.OR:
        return vartypes.twoscomp_to_int(
            vartypes.pass_twoscomp(left) | vartypes.pass_twoscomp(right))
    elif op == tk.XOR:
        return vartypes.twoscomp_to_int(
            vartypes.pass_twoscomp(left) ^ vartypes.pass_twoscomp(right))
    elif op == tk.EQV:
        return vartypes.twoscomp_to_int(~(vartypes.pass_twoscomp(left)
                                          ^ vartypes.pass_twoscomp(right)))
    elif op == tk.IMP:
        return vartypes.twoscomp_to_int((~vartypes.pass_twoscomp(left))
                                        | vartypes.pass_twoscomp(right))
    else:
        raise error.RunError(error.STX)
Exemplo n.º 4
0
 def get_window_logical(self, x, y):
     """ Convert physical to logical coordinates. """
     x, y = fp.Single.from_int(x), fp.Single.from_int(y)
     if self.window:
         scalex, scaley, offsetx, offsety = self.window
         return (fp.div(fp.sub(x, offsetx), scalex), fp.div(fp.sub(y, offsety), scaley))
     else:
         return x, y
Exemplo n.º 5
0
 def get_window_logical(self, x, y):
     """ Convert physical to logical coordinates. """
     x, y = fp.Single.from_int(x), fp.Single.from_int(y)
     if self.window:
         scalex, scaley, offsetx, offsety = self.window
         return (fp.div(fp.sub(x, offsetx),
                        scalex), fp.div(fp.sub(y, offsety), scaley))
     else:
         return x, y
Exemplo n.º 6
0
def vdiv(left, right):
    """ Left/right. """
    if left[0] == '#' or right[0] == '#':
        return fp.pack(
            fp.div(fp.unpack(vartypes.pass_double_keep(left)),
                   fp.unpack(vartypes.pass_double_keep(right))))
    else:
        return fp.pack(
            fp.div(fp.unpack(vartypes.pass_single_keep(left)),
                   fp.unpack(vartypes.pass_single_keep(right))))
Exemplo n.º 7
0
 def circle(self, lcoord, r, start, stop, c, aspect):
     """ Draw a circle, ellipse, arc or sector (CIRCLE). """
     x0, y0 = self.view_coords(*self.get_window_physical(*lcoord))
     c = self.get_attr_index(c)
     if aspect == None:
         aspect = fp.div(
             fp.Single.from_int(self.screen.mode.pixel_aspect[0]),
             fp.Single.from_int(self.screen.mode.pixel_aspect[1]),
         )
     if aspect.equals(aspect.one):
         rx, _ = self.get_window_scale(r, fp.Single.zero)
         ry = rx
     elif aspect.gt(aspect.one):
         _, ry = self.get_window_scale(fp.Single.zero, r)
         rx = fp.div(r, aspect).round_to_int()
     else:
         rx, _ = self.get_window_scale(r, fp.Single.zero)
         ry = fp.mul(r, aspect).round_to_int()
     start_octant, start_coord, start_line = -1, -1, False
     if start:
         start = fp.unpack(vartypes.pass_single_keep(start))
         start_octant, start_coord, start_line = get_octant(start, rx, ry)
     stop_octant, stop_coord, stop_line = -1, -1, False
     if stop:
         stop = fp.unpack(vartypes.pass_single_keep(stop))
         stop_octant, stop_coord, stop_line = get_octant(stop, rx, ry)
     if aspect.equals(aspect.one):
         self.draw_circle(x0, y0, rx, c, start_octant, start_coord, start_line, stop_octant, stop_coord, stop_line)
     else:
         startx, starty, stopx, stopy = -1, -1, -1, -1
         if start != None:
             startx = abs(fp.mul(fp.Single.from_int(rx), fp.cos(start)).round_to_int())
             starty = abs(fp.mul(fp.Single.from_int(ry), fp.sin(start)).round_to_int())
         if stop != None:
             stopx = abs(fp.mul(fp.Single.from_int(rx), fp.cos(stop)).round_to_int())
             stopy = abs(fp.mul(fp.Single.from_int(ry), fp.sin(stop)).round_to_int())
         self.draw_ellipse(
             x0,
             y0,
             rx,
             ry,
             c,
             start_octant / 2,
             startx,
             starty,
             start_line,
             stop_octant / 2,
             stopx,
             stopy,
             stop_line,
         )
     self.last_attr = c
     self.last_point = x0, y0
Exemplo n.º 8
0
 def circle(self, lcoord, r, start, stop, c, aspect):
     """ Draw a circle, ellipse, arc or sector (CIRCLE). """
     x0, y0 = self.view_coords(*self.get_window_physical(*lcoord))
     c = self.get_attr_index(c)
     if aspect is None:
         aspect = fp.div(
             fp.Single.from_int(self.screen.mode.pixel_aspect[0]),
             fp.Single.from_int(self.screen.mode.pixel_aspect[1]))
     if aspect.equals(aspect.one):
         rx, _ = self.get_window_scale(r, fp.Single.zero)
         ry = rx
     elif aspect.gt(aspect.one):
         _, ry = self.get_window_scale(fp.Single.zero, r)
         rx = fp.div(r, aspect).round_to_int()
     else:
         rx, _ = self.get_window_scale(r, fp.Single.zero)
         ry = fp.mul(r, aspect).round_to_int()
     start_octant, start_coord, start_line = -1, -1, False
     if start:
         start = fp.unpack(vartypes.pass_single_keep(start))
         start_octant, start_coord, start_line = get_octant(start, rx, ry)
     stop_octant, stop_coord, stop_line = -1, -1, False
     if stop:
         stop = fp.unpack(vartypes.pass_single_keep(stop))
         stop_octant, stop_coord, stop_line = get_octant(stop, rx, ry)
     if aspect.equals(aspect.one):
         self.draw_circle(x0, y0, rx, c, start_octant, start_coord,
                          start_line, stop_octant, stop_coord, stop_line)
     else:
         startx, starty, stopx, stopy = -1, -1, -1, -1
         if start is not None:
             startx = abs(
                 fp.mul(fp.Single.from_int(rx),
                        fp.cos(start)).round_to_int())
             starty = abs(
                 fp.mul(fp.Single.from_int(ry),
                        fp.sin(start)).round_to_int())
         if stop is not None:
             stopx = abs(
                 fp.mul(fp.Single.from_int(rx),
                        fp.cos(stop)).round_to_int())
             stopy = abs(
                 fp.mul(fp.Single.from_int(ry),
                        fp.sin(stop)).round_to_int())
         self.draw_ellipse(x0, y0, rx, ry, c, start_octant / 2, startx,
                           starty, start_line, stop_octant / 2, stopx,
                           stopy, stop_line)
     self.last_attr = c
     self.last_point = x0, y0
Exemplo n.º 9
0
def value_operator(op, left, right):
    """ Get value of binary operator expression. """
    if op == tk.O_CARET:
        return vcaret(left, right)
    elif op == tk.O_TIMES:
        return vtimes(left, right)
    elif op == tk.O_DIV:
        return vdiv(left, right)
    elif op == tk.O_INTDIV:
        return fp.pack(fp.div(fp.unpack(vartypes.pass_single_keep(left)).ifloor(),
                fp.unpack(vartypes.pass_single_keep(right)).ifloor()).apply_carry().ifloor())
    elif op == tk.MOD:
        numerator = vartypes.pass_int_unpack(right)
        if numerator == 0:
            # simulate division by zero
            return fp.pack(fp.div(fp.unpack(vartypes.pass_single_keep(left)).ifloor(),
                    fp.unpack(vartypes.pass_single_keep(right)).ifloor()).ifloor())
        return vartypes.pack_int(vartypes.pass_int_unpack(left) % numerator)
    elif op == tk.O_PLUS:
        return vplus(left, right)
    elif op == tk.O_MINUS:
        return vartypes.number_add(left, vartypes.number_neg(right))
    elif op == tk.O_GT:
        return vartypes.bool_to_int_keep(vartypes.gt(left,right))
    elif op == tk.O_EQ:
        return vartypes.bool_to_int_keep(vartypes.equals(left, right))
    elif op == tk.O_LT:
        return vartypes.bool_to_int_keep(not(vartypes.gt(left,right) or vartypes.equals(left, right)))
    elif op == tk.O_GT + tk.O_EQ:
        return vartypes.bool_to_int_keep(vartypes.gt(left,right) or vartypes.equals(left, right))
    elif op == tk.O_LT + tk.O_EQ:
        return vartypes.bool_to_int_keep(not vartypes.gt(left,right))
    elif op == tk.O_LT + tk.O_GT:
        return vartypes.bool_to_int_keep(not vartypes.equals(left, right))
    elif op == tk.AND:
        return vartypes.twoscomp_to_int( vartypes.pass_twoscomp(left) & vartypes.pass_twoscomp(right) )
    elif op == tk.OR:
        return vartypes.twoscomp_to_int( vartypes.pass_twoscomp(left) | vartypes.pass_twoscomp(right) )
    elif op == tk.XOR:
        return vartypes.twoscomp_to_int( vartypes.pass_twoscomp(left) ^ vartypes.pass_twoscomp(right) )
    elif op == tk.EQV:
        return vartypes.twoscomp_to_int( ~(vartypes.pass_twoscomp(left) ^ vartypes.pass_twoscomp(right)) )
    elif op == tk.IMP:
        return vartypes.twoscomp_to_int( (~vartypes.pass_twoscomp(left)) | vartypes.pass_twoscomp(right) )
    else:
        raise error.RunError(error.STX)
Exemplo n.º 10
0
 def set_window(self, fx0, fy0, fx1, fy1, cartesian=True):
     """ Set the logical coordinate window (WINDOW). """
     if fy0.gt(fy1):
         fy0, fy1 = fy1, fy0
     if fx0.gt(fx1):
         fx0, fx1 = fx1, fx0
     if cartesian:
         fy0, fy1 = fy1, fy0
     left, top, right, bottom = self.get_view()
     x0, y0 = fp.Single.zero, fp.Single.zero
     x1, y1 = fp.Single.from_int(right-left), fp.Single.from_int(bottom-top)
     scalex = fp.div(fp.sub(x1, x0), fp.sub(fx1,fx0))
     scaley = fp.div(fp.sub(y1, y0), fp.sub(fy1,fy0))
     offsetx = fp.sub(x0, fp.mul(fx0,scalex))
     offsety = fp.sub(y0, fp.mul(fy0,scaley))
     self.window = scalex, scaley, offsetx, offsety
     self.window_bounds = fx0, fy0, fx1, fy1, cartesian
Exemplo n.º 11
0
 def set_window(self, fx0, fy0, fx1, fy1, cartesian=True):
     """ Set the logical coordinate window (WINDOW). """
     if fy0.gt(fy1):
         fy0, fy1 = fy1, fy0
     if fx0.gt(fx1):
         fx0, fx1 = fx1, fx0
     if cartesian:
         fy0, fy1 = fy1, fy0
     left, top, right, bottom = self.get_view()
     x0, y0 = fp.Single.zero, fp.Single.zero
     x1, y1 = fp.Single.from_int(right - left), fp.Single.from_int(bottom -
                                                                   top)
     scalex = fp.div(fp.sub(x1, x0), fp.sub(fx1, fx0))
     scaley = fp.div(fp.sub(y1, y0), fp.sub(fy1, fy0))
     offsetx = fp.sub(x0, fp.mul(fx0, scalex))
     offsety = fp.sub(y0, fp.mul(fy0, scaley))
     self.window = scalex, scaley, offsetx, offsety
     self.window_bounds = fx0, fy0, fx1, fy1, cartesian
Exemplo n.º 12
0
def get_random_int(n):
    """ Get a value from the random number generator (int argument). """
    if n < 0:
        n = -n
        while n < 2**23:
            n *= 2
        state.basic_state.rnd_seed = n
    if n != 0:
        state.basic_state.rnd_seed = (state.basic_state.rnd_seed*rnd_a + rnd_c) % rnd_period
    # rnd_seed/rnd_period
    return fp.pack(fp.div(fp.Single.from_int(state.basic_state.rnd_seed), fp.Single.from_int(rnd_period)))
Exemplo n.º 13
0
def get_random_int(n):
    """ Get a value from the random number generator (int argument). """
    if n < 0:
        n = -n
        while n < 2**23:
            n *= 2
        state.basic_state.rnd_seed = n
    if n != 0:
        state.basic_state.rnd_seed = (state.basic_state.rnd_seed * rnd_a +
                                      rnd_c) % rnd_period
    # rnd_seed/rnd_period
    return fp.pack(
        fp.div(fp.Single.from_int(state.basic_state.rnd_seed),
               fp.Single.from_int(rnd_period)))
Exemplo n.º 14
0
def format_float_fixed(expr, decimals, force_dot):
    """ Put a float in fixed-point representation. """
    unrounded = mul(expr, pow_int(expr.ten, decimals)) # expr * 10**decimals
    num = unrounded.copy().iround()
    # find exponent
    exp10 = 1
    pow10 = pow_int(expr.ten, exp10) # pow10 = 10L**exp10
    while num.gt(pow10) or num.equals(pow10): # while pow10 <= num:
        pow10.imul10() # pow10 *= 10
        exp10 += 1
    work_digits = exp10 + 1
    diff = 0
    if exp10 > expr.digits:
        diff = exp10 - expr.digits
        num = div(unrounded, pow_int(expr.ten, diff)).iround()  # unrounded / 10**diff
        work_digits -= diff
    num = num.trunc_to_int()
    # argument work_digits-1 means we're getting work_digits==exp10+1-diff digits
    # fill up with zeros
    digitstr = get_digits(num, work_digits-1, remove_trailing=False) + ('0' * diff)
    return decimal_notation(digitstr, work_digits-1-1-decimals+diff, '', force_dot)
Exemplo n.º 15
0
def format_float_fixed(expr, decimals, force_dot):
    """ Put a float in fixed-point representation. """
    unrounded = mul(expr, pow_int(expr.ten, decimals))  # expr * 10**decimals
    num = unrounded.copy().iround()
    # find exponent
    exp10 = 1
    pow10 = pow_int(expr.ten, exp10)  # pow10 = 10L**exp10
    while num.gt(pow10) or num.equals(pow10):  # while pow10 <= num:
        pow10.imul10()  # pow10 *= 10
        exp10 += 1
    work_digits = exp10 + 1
    diff = 0
    if exp10 > expr.digits:
        diff = exp10 - expr.digits
        num = div(unrounded, pow_int(expr.ten,
                                     diff)).iround()  # unrounded / 10**diff
        work_digits -= diff
    num = num.trunc_to_int()
    # argument work_digits-1 means we're getting work_digits==exp10+1-diff digits
    # fill up with zeros
    digitstr = get_digits(num, work_digits - 1,
                          remove_trailing=False) + ('0' * diff)
    return decimal_notation(digitstr, work_digits - 1 - 1 - decimals + diff,
                            '', force_dot)
Exemplo n.º 16
0
def value_timer(ins):
    """ TIMER: get clock ticks since midnight. """
    # precision of GWBASIC TIMER is about 1/20 of a second
    return fp.pack(
        fp.div(fp.Single.from_int(timedate.timer_milliseconds() / 50),
               fp.Single.from_int(20)))
Exemplo n.º 17
0
try:
    import numpy
except ImportError:
    numpy = None

import error
import fp
import state
import vartypes
import util
import draw_and_play
# FIXME: circular import
import backend

# degree-to-radian conversion factor
deg_to_rad = fp.div(fp.Single.twopi, fp.Single.from_int(360))


class Drawing(object):
    """ Manage graphics drawing. """
    def __init__(self, screen):
        self.screen = screen
        self.unset_window()
        self.unset_view()
        self.reset()

    def reset(self):
        """ Reset graphics state. """
        if self.screen.mode.is_text_mode:
            return
        self.last_point = self.get_view_mid()
Exemplo n.º 18
0
def number_divide(left, right):
    """ Left/right. """
    if left[0] == '#' or right[0] == '#':
        return fp.pack( fp.div(fp.unpack(vartypes.pass_double(left)), fp.unpack(vartypes.pass_double(right))) )
    else:
        return fp.pack( fp.div(fp.unpack(vartypes.pass_single(left)), fp.unpack(vartypes.pass_single(right))) )
Exemplo n.º 19
0
try:
    import numpy
except ImportError:
    numpy = None

import error
import fp
import state
import vartypes
import util
import draw_and_play
import backend

# degree-to-radian conversion factor
deg_to_rad = fp.div(fp.Single.twopi, fp.Single.from_int(360))


class Drawing(object):
    """ Manage graphics drawing. """

    def __init__(self, screen):
        self.screen = screen
        self.unset_window()
        self.unset_view()
        self.reset()

    def reset(self):
        """ Reset graphics state. """
        if self.screen.mode.is_text_mode:
            return
Exemplo n.º 20
0
def value_timer(ins):
    """ TIMER: get clock ticks since midnight. """
    # precision of GWBASIC TIMER is about 1/20 of a second
    return fp.pack(fp.div( fp.Single.from_int(timedate.timer_milliseconds()/50), fp.Single.from_int(20)))
Exemplo n.º 21
0
def vdiv(left, right):
    """ Left/right. """
    if left[0] == '#' or right[0] == '#':
        return fp.pack( fp.div(fp.unpack(vartypes.pass_double_keep(left)), fp.unpack(vartypes.pass_double_keep(right))) )
    else:
        return fp.pack( fp.div(fp.unpack(vartypes.pass_single_keep(left)), fp.unpack(vartypes.pass_single_keep(right))) )