Ejemplo n.º 1
0
def f_dbstr_addptr(dst, number):
    """Print number as string to dst.

    :param dst: Destination address (Not EPD player)
    :param number: DWORD to print

    :returns: dst + strlen(itoa(number))
    """
    bw1.seekoffset(dst)
    ch = [0] * 8

    # Get digits
    for i in range(8):
        number, ch[i] = c.f_div(number, 16)

    # print digits
    for i in range(7, -1, -1):
        if cs.EUDIf()(ch[i] <= 9):
            bw1.writebyte(ch[i] + b'0'[0])
        if cs.EUDElse()():
            bw1.writebyte(ch[i] + (b'A'[0] - 10))
        cs.EUDEndIf()
        dst += 1

    bw1.writebyte(0)  # EOS
    bw1.flushdword()

    return dst
Ejemplo n.º 2
0
def EUDNot(cond):
    """ !cond

    :param conds: Condition to negate
    """

    v = c.EUDVariable()
    if cs.EUDIf()(cond):
        v << 0
    if cs.EUDElse()():
        v << 1
    cs.EUDEndIf()
    return v
Ejemplo n.º 3
0
def f_randomize():
    global _seed

    # Store switch 1
    sw1 = c.EUDVariable()
    if cs.EUDIf()(c.Switch("Switch 1", c.Set)):
        sw1 << c.EncodeSwitchAction(c.Set)
    if cs.EUDElse()():
        sw1 << c.EncodeSwitchAction(c.Clear)
    cs.EUDEndIf()

    _seed << 0
    dseed = c.EUDVariable()
    dseed << 1

    if cs.EUDLoopN()(32):
        cs.DoActions(c.SetSwitch("Switch 1", c.Random))
        if cs.EUDIf()(c.Switch("Switch 1", c.Set)):
            _seed += dseed
        cs.EUDEndIf()
        dseed += dseed
    cs.EUDEndLoopN()

    cs.DoActions(c.SetSwitch("Switch 1", sw1))
Ejemplo n.º 4
0
def EUDOr(cond1, *conds):
    """ cond1 || cond2 || ... || condn

    .. warning:: Short circuiting is not supported

    :param conds: List of conditions
    """

    v = c.EUDVariable()
    if cs.EUDIf()(cond1):
        v << 1
    for cond in conds:
        if cs.EUDElseIf()(cond):
            v << 1
    if cs.EUDElse()():
        v << 0
    cs.EUDEndIf()
    return v
Ejemplo n.º 5
0
def f_playerexist(player):
    """Check if player has not left the game.

    :returns: 1 if player exists, 0 if not.
    """
    pts = 0x51A280

    cs.EUDSwitch(player)
    for p in range(8):
        if cs.EUDSwitchCase()(p):
            if cs.EUDIf()(c.Memory(pts + p * 12 + 8, c.Exactly,
                                   ~(pts + p * 12 + 4))):
                c.EUDReturn(0)
            if cs.EUDElse()():
                c.EUDReturn(1)
            cs.EUDEndIf()

    if cs.EUDSwitchDefault()():
        c.EUDReturn(0)
    cs.EUDEndSwitch()
Ejemplo n.º 6
0
def EUDBinaryMin(cond, minv=0, maxv=0xFFFFFFFF):
    """ Find minimum x satisfying cond(x) using binary search

    :param cond: Test condition
    :param minv: Minimum value in domain
    :param maxv: Maximum value in domain

    Cond should be binary classifier, meaning that for some N
        for all x < N, cond(x) is false.
        for all x >= N, cond(x) is true
    Then EUDBinaryMin will find such N

    .. note:: If none of the value satisfies condition, then this
        function will return maxv.
    """
    x = c.EUDVariable()
    x << maxv

    if isinstance(minv, int) and isinstance(maxv, int):
        r = maxv - minv
        if r == 0:
            return minv

    else:
        r = None

    for i in range(31, -1, -1):
        if r and 2**i > r:
            continue

        if cs.EUDIf()([x >= 2**i]):
            cs.DoActions(x.SubtractNumber(2**i))
            if cs.EUDIfNot()([x >= minv, cond(x)]):
                cs.DoActions(x.AddNumber(2**i))
            cs.EUDEndIf()
        cs.EUDEndIf()

    return x
Ejemplo n.º 7
0
def f_atan2(y, x):
    signflags = c.EUDVariable()
    signflags << 0

    # Check x sign
    if cs.EUDIf()(x >= 0x80000000):
        x << -x
        signflags += 1  # set xsign
    cs.EUDEndIf()

    # Check y sign
    if cs.EUDIf()(y >= 0x80000000):
        y << -y
        signflags += 2  # set ysign
    cs.EUDEndIf()

    # Check x/y order
    if cs.EUDIf()(y >= x):
        z = c.EUDVariable()
        # Swap x, y so that y <= x
        z << x
        x << y
        y << z
        signflags += 4  # set xyabscmp
    cs.EUDEndIf()

    # To prevent overflow, we limit values of y and x.
    # atan value is maximized when x = y, then atan_value = 45 * x**3
    # 45 * x**3 <= 0xFFFFFFFF : x <= 456.99....
    if cs.EUDIf()(x >= 400):
        # Normalize below 400
        divn = x // 400 + 1
        x //= divn
        y //= divn
    cs.EUDEndIf()

    # Calculate arctan value
    # arctan(z) ~= z * (45 - (z-1) * (14 + 4*z)), 0 <= z <= 1
    # arctan(y/x) ~= y/x * (45 - (y-x)/x * (14x + 4y)/x))
    # arctan(y/x) ~= y * (45*x*x - (y-x)(14x+4y)) / (x*x*x)
    t1 = x * x
    t2 = y * (45 * t1 - (y - x) * (14 * x + 4 * y))
    t3 = x * t1
    atan_value = t2 // t3

    # Translate angles by sign flags
    #
    #      |  0 |  1 | xsign          |  0 |  1 | xsign
    # -----+----+----+-----      -----+----+----+-----
    #   0  |  0+|180-|             0  | 90-| 90+|
    # -----+----+----+           -----+----+----+
    #   1  |360-|180+|             1  |270+|270-|
    # -----+----+----+           -----+----+----+
    # ysign|      xyabscmp=0     ysign|      xyabscmp=1

    cs.EUDSwitch(signflags)
    cs.EUDSwitchCase()(0)  # xsign, ysign, xyabscmp = 0, 0, 0
    c.EUDReturn(atan_value)
    cs.EUDSwitchCase()(1)  # xsign, ysign, xyabscmp = 1, 0, 0
    c.EUDReturn(180 - atan_value)
    cs.EUDSwitchCase()(2)  # xsign, ysign, xyabscmp = 0, 1, 0
    c.EUDReturn(360 - atan_value)
    cs.EUDSwitchCase()(3)  # xsign, ysign, xyabscmp = 1, 1, 0
    c.EUDReturn(180 + atan_value)
    cs.EUDSwitchCase()(4)  # xsign, ysign, xyabscmp = 0, 0, 1
    c.EUDReturn(90 - atan_value)
    cs.EUDSwitchCase()(5)  # xsign, ysign, xyabscmp = 1, 0, 1
    c.EUDReturn(90 + atan_value)
    cs.EUDSwitchCase()(6)  # xsign, ysign, xyabscmp = 0, 1, 1
    c.EUDReturn(270 + atan_value)
    cs.EUDSwitchCase()(7)  # xsign, ysign, xyabscmp = 1, 1, 1
    c.EUDReturn(270 - atan_value)
    cs.EUDEndSwitch()
Ejemplo n.º 8
0
def f_lengthdir(length, angle):
    # sin, cos table
    clist = []
    slist = []

    for i in range(91):
        cosv = math.floor(math.cos(math.pi / 180 * i) * 65536 + 0.5)
        sinv = math.floor(math.sin(math.pi / 180 * i) * 65536 + 0.5)
        clist.append(ut.i2b4(cosv))
        slist.append(ut.i2b4(sinv))

    cdb = c.Db(b''.join(clist))
    sdb = c.Db(b''.join(slist))

    # MAIN LOGIC

    if cs.EUDIf()(angle >= 360):
        angle << c.f_div(angle, 360)[1]
    cs.EUDEndIf()

    ldir_x, ldir_y = c.EUDVariable(), c.EUDVariable()  # cos, sin * 65536
    # sign of cos, sin
    csign, ssign = c.EUDLightVariable(), c.EUDLightVariable()
    tableangle = c.EUDVariable()

    # get cos, sin from table
    if cs.EUDIf()(angle <= 89):
        tableangle << angle
        csign << 1
        ssign << 1

    if cs.EUDElseIf()(angle <= 179):
        tableangle << 180 - angle
        csign << -1
        ssign << 1

    if cs.EUDElseIf()(angle <= 269):
        tableangle << angle - 180
        csign << -1
        ssign << -1

    if cs.EUDElse()():
        tableangle << 360 - angle
        csign << 1
        ssign << -1

    cs.EUDEndIf()

    tablecos = f_dwread_epd(ut.EPD(cdb) + tableangle)
    tablesin = f_dwread_epd(ut.EPD(sdb) + tableangle)

    # calculate lengthdir
    ldir_x << c.f_div(c.f_mul(tablecos, length), 65536)[0]
    ldir_y << c.f_div(c.f_mul(tablesin, length), 65536)[0]

    # restore sign of cos, sin
    if cs.EUDIf()(csign == -1):
        ldir_x << 0xFFFFFFFF - ldir_x + 1
    cs.EUDEndIf()

    if cs.EUDIf()(ssign == -1):
        ldir_y << 0xFFFFFFFF - ldir_y + 1
    cs.EUDEndIf()

    return ldir_x, ldir_y