def iter_body(cp): tmpl = Template(iter_body_code, 'iter_body') NWARPS = NTHREADS / 32 # TODO: detect this properly and use it chaos_used = False vars = globals() vars.update(locals()) return tmpl.substitute(vars)
def precalc_camera(cam): # Maxima code to check my logic: # matrix([1,0,0.5*width + g],[0,1,0.5*height+g],[0,0,1]) # . matrix([width * scale,0,0], [0,width * scale,0], [0,0,1]) # . matrix([cosr,-sinr,0], [sinr,cosr,0], [0,0,1]) # . matrix([1,0,-cenx],[0,1,-ceny],[0,0,1]) # . matrix([X],[Y],[1]); cam._code( Template( r""" float rot = {{cam.rotation}} * M_PI / 180.0f; float rotsin = sin(rot), rotcos = cos(rot); float cenx = {{cam.center.x}}, ceny = {{cam.center.y}}; float scale = {{cam.scale}} * acc_size.width; {{cam._set('xx')}} = scale * rotcos; {{cam._set('xy')}} = scale * -rotsin; {{cam._set('xo')}} = scale * (rotsin * ceny - rotcos * cenx) + 0.5f * acc_size.awidth; {{cam._set('yx')}} = scale * rotsin; {{cam._set('yy')}} = scale * rotcos; {{cam._set('yo')}} = scale * -(rotsin * cenx + rotcos * ceny) + 0.5f * acc_size.aheight; """, 'precalc_camera').substitute(cam=cam))
def precalc_chaos(cp): cp._code( Template(""" float sum, rsum; {{for p in cp.xforms}} sum = 0.0f; {{for n in cp.xforms}} float den_{{p}}_{{n}} = {{cp.xforms[n].weight}} * {{cp.xforms[p].chaos[n]}}; sum += den_{{p}}_{{n}}; {{endfor}} rsum = 1.0f / sum; sum = 0.0f; {{for n in cp.xforms.keys()[:-1]}} sum += den_{{p}}_{{n}} * rsum; {{cp._set('chaos_%s_%s' % (p, n))}} = sum; {{endfor}} {{endfor}} """, name='precalc_chaos').substitute(cp=cp))
def apply_affine(names, packer): x, y, xo, yo = names.split() return Template( """ {{xo}} = {{packer.xx}} * {{x}} + {{packer.xy}} * {{y}} + {{packer.xo}}; {{yo}} = {{packer.yx}} * {{x}} + {{packer.yy}} * {{y}} + {{packer.yo}}; """, 'apply_affine').substitute(locals())
def get_door_status(self): print("判断是否开门") jt.window_capture(self.dt_name) zb1 = tl.template(self.blue, self.dt_name, 0.0001) if zb1[0] != 0: print('已开门') return True else: print('未开门') return False
def attack_boss(self): for i in range(100): time.sleep(1) jt.window_capture(self.dt_name) zb = tl.template(self.copper, self.dt_name, 0.0000001) if zb[0] != 0: print('打boss完成') return True elif i == 99: print('打boss失败') return False self.daguai()
def guomen(self, menFangXiang): print('执行过门') if self.get_door_status(): if int(menFangXiang) == 8: key_input('w', 1) elif int(menFangXiang) == 6: key_input('d', 1) elif int(menFangXiang) == 2: key_input('s', 1) elif int(menFangXiang) == 4: key_input('a', 1) else: print('错误:', menFangXiang) return else: print('未开门') return False # # for i in range(100): # jt.window_capture(self.dt_name) # zb = tl.template(self.blue, self.dt_name, 0.00001) # zb2 = tl.template(self.blue, self.dt_name, 0.00001) # zb3 = tl.template(self.blue, self.dt_name, 0.00001) # zb[0] = zb[0] + zb2[0] + zb3[0] # if zb[0] == 0: # print('已过门') # break # elif i == 19: # print('过门失败') # return False for i in range(20): time.sleep(1) jt.window_capture(self.dt_name) zb = tl.template(self.blue, self.dt_name, 0.00001) if zb[0] == 0: print('开图成功') if int(menFangXiang) == 8: key_input('w', 1) elif int(menFangXiang) == 6: key_input('d', 1) elif int(menFangXiang) == 2: key_input('s', 1) elif int(menFangXiang) == 4: key_input('a', 1) return True elif i == 19: print('开图失败') return False
def precalc_xf_affine(px): px._code( Template( r""" float pri = {{px.angle}} * M_PI / 180.0f; float spr = {{px.spread}} * M_PI / 180.0f; float magx = {{px.magnitude.x}}; float magy = {{px.magnitude.y}}; {{px._set('xx')}} = magx * cos(pri-spr); {{px._set('yx')}} = -magx * sin(pri-spr); {{px._set('xy')}} = -magy * cos(pri+spr); {{px._set('yy')}} = magy * sin(pri+spr); {{px._set('xo')}} = {{px.offset.x}}; {{px._set('yo')}} = -{{px.offset.y}}; """, 'precalc_xf_affine').substitute(px=px))
def daguai(self, threshold=0.001): sleep(1) # print('status=1; 开始打怪') while True: jt.window_capture(self.dt_name) zb = tl.template(xt_name=self.xt_name, dt_name=self.dt_name, threshold=threshold) if zb[0] != 0: print('有怪', '打怪') mouse_move(zb[0] + 25, zb[1] + 25) a.status = True else: print('没怪了') a.status = False break return self
def precalc_densities(cp): # This pattern recurs a few times for precalc segments. Unfortunately, # namespace stuff means it's not easy to functionalize this boilerplate cp._code( Template(r""" float sum = 0.0f; {{for n in cp.xforms}} float den_{{n}} = {{cp.xforms[n].weight}}; sum += den_{{n}}; {{endfor}} float rsum = 1.0f / sum; sum = 0.0f; {{for n in cp.xforms.keys()[:-1]}} sum += den_{{n}} * rsum; {{cp._set('den_' + n)}} = sum; {{endfor}} """, name='precalc_densities').substitute(cp=cp))
def iter_xf_body(cp, xfid, px): tmpl = Template(iter_xf_body_code, 'apply_xf_' + xfid) g = dict(globals()) g.update(locals()) return tmpl.substitute(g)
flushatomlib = devlib(defs=Template( r''' __global__ void flush_atom(uint64_t out_ptr, uint64_t atom_ptr, int nbins) { int i = (blockIdx.y * gridDim.x + blockIdx.x) * blockDim.x + threadIdx.x; if (i >= nbins) return; asm volatile ({{crep(""" { .reg .u32 off, hi, lo, d, y, u, v; .reg .u64 val, ptr; .reg .f32 yf, uf, vf, df, yg, ug, vg, dg; // TODO: use explicit movs to handle this shl.b32 off, %0, 3; cvt.u64.u32 ptr, off; add.u64 ptr, ptr, %1; ld.global.v2.u32 {lo, hi}, [ptr]; shl.b32 off, %0, 4; cvt.u64.u32 ptr, off; add.u64 ptr, ptr, %2; ld.global.v4.f32 {yg,ug,vg,dg}, [ptr]; shr.u32 d, hi, 22; bfe.u32 y, hi, 4, 18; bfe.u32 u, lo, 18, 14; bfi.b32 u, hi, u, 14, 4; and.b32 v, lo, ((1<<18)-1); cvt.rn.f32.u32 yf, y; cvt.rn.f32.u32 uf, u; cvt.rn.f32.u32 vf, v; cvt.rn.f32.u32 df, d; fma.rn.ftz.f32 yg, yf, (1.0/255.0), yg; fma.rn.ftz.f32 ug, uf, (1.0/255.0), ug; fma.rn.ftz.f32 vg, vf, (1.0/255.0), vg; add.rn.ftz.f32 dg, df, dg; st.global.v4.f32 [ptr], {yg,ug,vg,dg}; } """)}} :: "r"(i), "l"(atom_ptr), "l"(out_ptr)); } ''', 'flush_atom').substitute())
def iter_xf_body(cp, xfid, px): tmpl = Template(iter_xf_body_code, 'apply_xf_'+xfid) g = dict(globals()) g.update(locals()) return tmpl.substitute(g)
class GenomePacker(object): """ Packs a genome for use in iteration. """ def __init__(self, tname, ptr_name, spec): """ Create a new DataPacker. ``tname`` is the name of the structure typedef that will be emitted via this object's ``decls`` property. """ self.tname, self.ptr_name, self.spec = tname, ptr_name, spec # We could do this in the order that things are requested, but we want # to be able to treat the direct stuff as a list so this function # doesn't unroll any more than it has to. So we separate things into # direct requests, and those that need precalculation. self.packed_direct = _OrderedSet() # Feel kind of bad about this, but it's just under the threshold of # being worth refactoring to be agnostic to interpolation types self.packed_direct_mag = _OrderedSet() self.genome_precalc = _OrderedSet() self.packed_precalc = _OrderedSet() self.precalc_code = [] self._len = None self.decls = None self.defs = None self.packed = None self.genome = None self.search_rounds = util.DEFAULT_SEARCH_ROUNDS def __len__(self): """Length in elements. (*4 for length in bytes.)""" assert self._len is not None, 'len() called before finalize()' return self._len def view(self, val={}): """Create a DataPacker view. See DataPackerView class for details.""" return PackerWrapper(val, self.spec, packer=self) def _require(self, spec, path): """ Called to indicate that the named parameter from the original genome must be available during interpolation. """ if spec.interp == 'mag': self.packed_direct_mag.add(path) else: self.packed_direct.add(path) return self.devname(path) def _require_pre(self, spec, path): i = self.genome_precalc.add(path) << self.search_rounds func = 'catmull_rom_mag' if spec.interp == 'mag' else 'catmull_rom' return '%s(×[%d], &knots[%d], time)' % (func, i, i) def _pre_alloc(self, path): self.packed_precalc.add(path) return '%s->%s' % (self.ptr_name, '_'.join(path)) def devname(self, path): return '%s.%s' % (self.ptr_name, '_'.join(path)) def finalize(self): """ Create the code to render this genome. """ # At the risk of packing a few things more than once, we don't # uniquify the overall precalc order, sparing us the need to implement # recursive code generation direct = list(self.packed_direct) + list(self.packed_direct_mag) self.packed = direct + list(self.packed_precalc) self.genome = direct + list(self.genome_precalc) self._len = len(self.packed) decls = self._decls.substitute(**self.__dict__) defs = self._defs.substitute(**self.__dict__) return devlib(deps=[catmullromlib], decls=decls, defs=defs) def pack(self, gnm, pool=None): """ Return a packed copy of the genome ready for uploading to the GPU, as two float32 NDArrays for the knot times and values. """ width = 1 << self.search_rounds if pool: times = pool.allocate((len(self.genome), width), 'f4') knots = pool.allocate((len(self.genome), width), 'f4') else: times, knots = np.empty((2, len(self.genome), width), 'f4') times.fill(1e9) # TODO: do a nicer job of finding the value of scale scale = gnm.get('time', {}).get('duration', 1) for idx, path in enumerate(self.genome): attr = gnm for name in path: if name not in attr: attr = resolve_spec(specs.anim, path).default break attr = attr[name] attr = SplineEval.normalize(attr, scale) times[idx,:len(attr[0])] = attr[0] knots[idx,:len(attr[1])] = attr[1] return times, knots _defs = Template(r""" __global__ void interp_{{tname}}( {{tname}}* {{ptr_name}}, const float *times, const float *knots, float tstart, float tstep, int maxid) { int id = gtid(); if (id >= maxid) return; {{ptr_name}} = &{{ptr_name}}[id]; float time = tstart + id * tstep; float *outf = reinterpret_cast<float*>({{ptr_name}}); {{py:lpd = len(packed_direct)}} {{py:lpdm = len(packed_direct_mag)}} // TODO: unroll pragma? for (int i = 0; i < {{lpd}}; i++) { int j = i << {{search_rounds}}; outf[i] = catmull_rom(×[j], &knots[j], time); } for (int i = {{lpd}}; i < {{lpd+lpdm}}; i++) { int j = i << {{search_rounds}}; outf[i] = catmull_rom_mag(×[j], &knots[j], time); } // Advance 'times' and 'knots' to the purely generated sections, so that // the pregenerated statements emitted by _require_pre are correct. times = ×[{{(lpd+lpdm)<<search_rounds}}]; knots = &knots[{{(lpd+lpdm)<<search_rounds}}]; {{for hunk in precalc_code}} { {{hunk}} } {{endfor}} } """) _decls = Template(r""" typedef struct { {{for path in packed}} float {{'_'.join(path)}}; {{endfor}} } {{tname}}; """)
def getZB(self): jt.window_capture(self.dt_name) juese_zb = tl.template(self.juese_name, self.dt_name, 0.1) return juese_zb