Ejemplo n.º 1
0
void stdint_summary() {
    printf("Summary of types in stdint.h\n");
    printf("|  Types   |Size(B)|    MAX   |    MIN    |\n");
    printf("----------------------------------------\n");
    printf("|%9s |%6ld |%9d |%10d |\n","int8_t",size(8),max(8),min(8));
    printf("|%9s |%6ld |%9d |%10d |\n","uint8_t",usize(8),umax(8),0);
    printf("|%9s |%6ld |%9d |%10d |\n","int16_t",size(16),max(16),min(16));
    printf("|%9s |%6ld |%9d |%10d |\n","uint16_t",usize(16),umax(16),0);
    printf("|%9s |%6ld | %.2e | %.2e |\n","int32_t",size(32),(double)max(32),(double)min(32));
    printf("|%9s |%6ld | %.2e | %9.2e |\n","uint32_t",usize(32),(double)umax(32),(double)0);
    printf("|%9s |%6ld | %.2e | %.2e |\n","int64_t",size(64),(double)max(64),(double)min(64));
    printf("|%9s |%6ld | %.2e | %9.2e |\n","uint64_t",usize(64),(double)umax(64),(double)0);
    
}
Ejemplo n.º 2
0
static void computeOrientation(const cv::Mat& image,
                               std::vector<cv::KeyPoint>& keypoints,
							   int halfPatchSize)
{
        std::vector<int> umax(halfPatchSize + 2);
        int v, v0, vmax = cvFloor(halfPatchSize * sqrt(2.f) / 2 + 1);  
        int vmin = cvCeil(halfPatchSize * sqrt(2.f) / 2);  
        for (v = 0; v <= vmax; ++v)  
            umax[v] = cvRound(sqrt((double)halfPatchSize * halfPatchSize - v * v));  
                  
        // Make sure we are symmetric  
        for (v = halfPatchSize, v0 = 0; v >= vmin; --v)  
        {  
            while (umax[v0] == umax[v0 + 1])  
               ++v0;  
               umax[v] = v0;  
               ++v0;  
        }  

	// Process each keypoint
    for (std::vector<cv::KeyPoint>::iterator keypoint = keypoints.begin(),
		keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
	{
		keypoint->angle = IC_Angle(image, halfPatchSize, keypoint->pt, umax);
	}
}
Ejemplo n.º 3
0
//==============================================================================
double LRBSpline2D::evalBasisFunc(double u, 
				  double v) const
//==============================================================================
{
  bool u_on_end = (u == umax());
  bool v_on_end = (v == vmax());

  return 
    B(degree(XFIXED), u, &kvec(XFIXED)[0], mesh_->knotsBegin(XFIXED), u_on_end)*
    B(degree(YFIXED), v, &kvec(YFIXED)[0], mesh_->knotsBegin(YFIXED), v_on_end);
}
Ejemplo n.º 4
0
//==============================================================================
bool LRBSpline2D::overlaps(double domain[]) const
//==============================================================================
{
  // Does it make sense to include equality?
  if (domain[0] >= umax())
    return false;
  if (domain[1] <= umin())
    return false;
  if (domain[2] >= vmax())
    return false;
  if (domain[3] <= vmin())
    return false;
  
  return true;
}
Ejemplo n.º 5
0
//==============================================================================
bool LRBSpline2D::overlaps(Element2D *el) const
//==============================================================================
{
  // Does it make sense to include equality?
  if (el->umin() >= umax())
    return false;
  if (el->umax() <= umin())
    return false;
  if (el->vmin() >= vmax())
    return false;
  if (el->vmax() <= vmin())
    return false;
  
  return true;
}
Ejemplo n.º 6
0
void check_branch_relocation( void* fromArg, void* toArg, int32 countArg) {
  inst_t *from = (inst_t*)fromArg, *to = (inst_t*)toArg;
  int32 count = countArg / sizeof(inst_t);
  
  if ( umax((uint32)from, (uint32)to)  <  umin((uint32)from + count, (uint32) to + count))
   return; // overlapping, too hard to check
  
  for ( int32 i = 0;  i < count;  ++i) {
    inst_t* f = (inst_t*)get_target_of_branch_instruction(&from[i]);
    inst_t* t = (inst_t*)get_target_of_branch_instruction(&  to[i]);

         if (f == NULL)                      ;
    else if (from <= f  &&  f < from+count)  f += to - from;

    if (f != t)
      fatal2("check_branch_relocation: branch at 0x%x moved to 0x%x but is wrong", 
             &from[i], &to[i]);
  }
}
Ejemplo n.º 7
0
void GrMouseSetSpeed(int spmult, int spdiv)
{
    MOUINFO->spmult = umin(16, umax(1, spmult));
    MOUINFO->spdiv  = umin(16, umax(1, spdiv));
}
Ejemplo n.º 8
0
static void
declareLocalVariables(
    struct KgenContext *ctx,
    const BlasGenSettings *gset,
    Tile* parTile,
    TrsmExtraParams * extraParams)
{
    char tmp[1024];
    const SubproblemDim *dims = gset->subdims;
    const char* parTileTypeName = NULL;
    bool trb = isMatrixAccessColMaj(CLBLAS_TRSM, gset->kextra->flags,
                                   MATRIX_B);
    unsigned int locWidth;
    unsigned int tsize;
    unsigned int parTileSize;
    unsigned int l1Pans;
    unsigned int step;

    kgenAddStmt(ctx,
                 "const int lid = get_local_id(0);\n"
                 "const int gid = get_group_id(0);\n"
                 "GPtr uA, uB;\n"
                 "uint coordA, coordB;\n"
                 "uint m0 = 0, k0, m1;\n");

    if (isMatrixUpper(gset->kextra->flags)) {
        sprintf(tmp, "uint currM = (M - 1) / %lu * %lu;\n",
                dims[0].y, dims[0].y);
        kgenAddStmt(ctx, tmp);
    }

    /*
     * Declare private blocks.
     * The region 'b' stores in different time tiles of both
     * the input matrices and the result
     */

    declareTileStorages(ctx, gset);

    *parTile = gset->tileBX;

    if (extraParams->ldsUse) {
        tsize = dtypeSize(gset->kextra->dtype);
        l1Pans = (unsigned int)(dims[0].x / dims[1].x);

        parTile->vecLen = (trb) ? (unsigned int)dims[1].x
                                : (unsigned int)dims[1].bwidth;
        parTile->vecLen = umin(parTile->vecLen, sizeof(cl_float4) / tsize);
        parTile->trans = trb;

       /*
        * Allocate enough space in the local area to fit several tiles
        * at the stage1 (according to the unrolled factor) and one tile
        * at the stage2
        */

        locWidth = (unsigned int)dims[1].bwidth * extraParams->unrollingFactor;
        if (extraParams->ldsUse & LDS_USE_DIAGONAL) {
            locWidth = umax(locWidth, (unsigned int)dims[1].y);
        }
        if (trb) {
            parTile->nrRows = locWidth;
            parTile->nrCols = (unsigned int)dims[0].x;
            step = (unsigned int)dims[1].x / parTile->vecLen;
        }
        else {
            parTile->nrRows = (unsigned int)dims[0].x;
            parTile->nrCols = locWidth;
            step = (unsigned int)dims[1].x * locWidth / parTile->vecLen;
        }

        parTileSize = tileVectorsNum(parTile);

        getVectorTypeName(gset->kextra->dtype, parTile->vecLen,
                          &parTileTypeName, NULL);

        sprintf(tmp, "__local %s tmpB[%i];\n"
                     "LPtr lB;\n"
                     "LPtr lBMain = {(__local float*)(tmpB + lid %% %u * %u)};\n",
                parTileTypeName, parTileSize, l1Pans, step);
        kgenAddStmt(ctx, tmp);

        if (useSkewedFetchB(gset)) {
            kgenPrintf(ctx, "const uint skewX = lid %% %u %% %lu;\n",
                       l1Pans, gset->subdims[1].x);
        }
    }

    kgenAddBlankLine(ctx);
}
Ejemplo n.º 9
0
cap_pair elf_loader_mem(Elf_Env *env, void *p, size_t *minaddr, size_t *maxaddr, size_t *entry) {
	char *addr = (char *)p;
	size_t lowaddr = (size_t)(-1);
	Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;
	if(!elf_check_supported(env, hdr)) {
		ERROR("ELF File cannot be loaded");
		return NULL_PAIR;
	}

	Elf64_Addr e_entry = hdr->e_entry;
	TRACE("e_entry:%lX e_phnum:%d e_shnum:%d", hdr->e_entry, hdr->e_phnum, hdr->e_shnum);

	size_t allocsize = 0;
	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		TRACE("SGMT: type:%X flags:%X offset:%lX vaddr:%lX filesz:%lX memsz:%lX align:%lX",
			  seg->p_type, seg->p_flags, seg->p_offset, seg->p_vaddr,
			  seg->p_filesz, seg->p_memsz, seg->p_align);
		if(seg->p_filesz > seg->p_memsz) {
			ERROR("Section is larger in file than in memory");
			return NULL_PAIR;
		}
		if(seg->p_type == PT_LOAD) {
			size_t bound = seg->p_vaddr + seg->p_memsz;
			allocsize = umax(allocsize, bound);
			lowaddr = umin(lowaddr, seg->p_vaddr);
			TRACE("lowaddr:%lx allocsize:%lx bound:%lx", lowaddr, allocsize, bound);
		} else if(seg->p_type == PT_GNUSTACK || seg->p_type == PT_PHDR || seg->p_type == PT_GNURELRO) {
            /* Ignore these headers */
		} else {
			ERROR("Unknown section");
			return NULL_PAIR;
		}
	}

	cap_pair pair = env->alloc(allocsize);
	char *prgmp = pair.data;
	if(!prgmp) {
		ERROR("alloc failed");
		return NULL_PAIR;
	}

	TRACE("Allocated %lx bytes of target memory", allocsize);
	ENV_PRINT_CAP(env, prgmp);

	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		if(seg->p_type == 1) {
			TRACE("memcpy: [%lx %lx] <-- [%lx %lx] (%lx bytes)",
				  seg->p_vaddr, seg->p_vaddr + seg->p_filesz,
				  seg->p_offset, seg->p_offset + seg->p_filesz,
				  seg->p_filesz);
			env->memcpy(prgmp+seg->p_vaddr, addr + seg->p_offset, seg->p_filesz);
		}
	}
	env->free(addr);

	if(minaddr)	*minaddr = lowaddr;
	if(maxaddr)	*maxaddr = allocsize;
	if(entry)	*entry   = e_entry;

	return pair;
}
Ejemplo n.º 10
0
/****************************************************************************
**
**  Name: IsSpurInBand
**
**  Description:    Checks to see if a spur will be present within the IF's
**                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
**
**                    ma   mb                                     mc   md
**                  <--+-+-+-------------------+-------------------+-+-+-->
**                     |   ^                   0                   ^   |
**                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
**                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
**
**                  Note that some equations are doubled to prevent round-off
**                  problems when calculating fIFBW/2
**
**  Parameters:     pAS_Info - Avoid Spurs information block
**                  fm       - If spur, amount f_IF1 has to move negative
**                  fp       - If spur, amount f_IF1 has to move positive
**
**  Global:         None
**
**  Returns:        1 if an LO spur would be present, otherwise 0.
**
**  Dependencies:   None.  
**
**  Revision History:
**
**   SCR      Date      Author  Description
**  -------------------------------------------------------------------------
**   N/A   11-28-2002    DAD    Implemented algorithm from applied patent 
**
****************************************************************************/
static UData_t IsSpurInBand(MT_AvoidSpursData_t* pAS_Info, 
                            UData_t* fm, 
                            UData_t* fp)
{
    /*
    **  Calculate LO frequency settings.
    */
    UData_t n, n0;
    const UData_t f_LO1 = pAS_Info->f_LO1;
    const UData_t f_LO2 = pAS_Info->f_LO2;
    const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw/2;
    const UData_t c = d - pAS_Info->f_out_bw;
    const UData_t f = pAS_Info->f_zif_bw/2;
    const UData_t f_Scale = (f_LO1 / (MAX_UDATA/2 / pAS_Info->maxH1)) + 1;
    SData_t f_nsLO1, f_nsLO2;
    SData_t f_Spur;
    UData_t ma, mb, mc, md, me, mf;
    UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale;
    UData_t index;

    MT_AvoidSpursData_t *adj;

    *fm = 0;

    /*
    ** For each edge (d, c & f), calculate a scale, based on the gcd
    ** of f_LO1, f_LO2 and the edge value.  Use the larger of this
    ** gcd-based scale factor or f_Scale.
    */
    lo_gcd = gcd(f_LO1, f_LO2);
    gd_Scale = umax((UData_t) gcd(lo_gcd, d), f_Scale);
    gc_Scale = umax((UData_t) gcd(lo_gcd, c), f_Scale);
    gf_Scale = umax((UData_t) gcd(lo_gcd, f), f_Scale);

    n0 = ceil(f_LO2 - d, f_LO1 - f_LO2);

    //  Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic
    for (n=n0; n<=pAS_Info->maxH1; ++n)
    {
        md = (n*(f_LO1/gd_Scale) - (d/gd_Scale)) / (f_LO2/gd_Scale);

        //  If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present
        if (md >= pAS_Info->maxH1)
            break;

        ma = (n*(f_LO1/gd_Scale) + (d/gd_Scale)) / (f_LO2/gd_Scale);

        //  If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic
        if (md == ma)
            continue;

        mc = (n*(f_LO1/gc_Scale) - (c/gc_Scale)) / (f_LO2/gc_Scale);
        if (mc != md)
        {
            f_nsLO1 = (SData_t) (n*(f_LO1/gc_Scale));
            f_nsLO2 = (SData_t) (mc*(f_LO2/gc_Scale));
            f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - mc*(f_LO2 % gc_Scale);

            *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1;
            *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1;
            return 1;
        }

        //  Location of Zero-IF-spur to be checked
        me = (n*(f_LO1/gf_Scale) + (f/gf_Scale)) / (f_LO2/gf_Scale);
        mf = (n*(f_LO1/gf_Scale) - (f/gf_Scale)) / (f_LO2/gf_Scale);
        if (me != mf)
        {
            f_nsLO1 = n*(f_LO1/gf_Scale);
            f_nsLO2 = me*(f_LO2/gf_Scale);
            f_Spur = (gf_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gf_Scale) - me*(f_LO2 % gf_Scale);

            *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1;
            *fm = (((SData_t) f - f_Spur) / (me - n)) + 1;
            return 1;
        }

        mb = (n*(f_LO1/gc_Scale) + (c/gc_Scale)) / (f_LO2/gc_Scale);
        if (ma != mb)
        {
            f_nsLO1 = n*(f_LO1/gc_Scale);
            f_nsLO2 = ma*(f_LO2/gc_Scale);
            f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - ma*(f_LO2 % gc_Scale);

            *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1;
            *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1;
            return 1;
        }
    }

    //  If no spur found, see if there are more tuners on the same board
    for (index = 0; index < TunerCount; ++index)
    {
        adj = TunerList[index];
        if (pAS_Info == adj)    /* skip over our own data, don't process it */
            continue;

        //  Look for LO-related spurs from the adjacent tuner generated into my IF output
        if (IsSpurInAdjTunerBand(1,                   //  check my IF output
                                 pAS_Info->f_LO1,     //  my fLO1
                                 adj->f_LO1,          //  the other tuner's fLO1
                                 pAS_Info->f_LO2,     //  my fLO2
                                 pAS_Info->f_out,     //  my fOut
                                 pAS_Info->f_out_bw,  //  my output IF bandiwdth
                                 pAS_Info->f_zif_bw,  //  my Zero-IF bandwidth
                                 pAS_Info->maxH2,
                                 fp,                  //  minimum amount to move LO's positive
                                 fm))                 //  miminum amount to move LO's negative
            return 1;
        //  Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output
        if (IsSpurInAdjTunerBand(0,             //  check his IF output
                                 pAS_Info->f_LO1,     //  my fLO1
                                 adj->f_LO1,          //  the other tuner's fLO1
                                 adj->f_LO2,          //  the other tuner's fLO2
                                 adj->f_out,          //  the other tuner's fOut
                                 adj->f_out_bw,       //  the other tuner's output IF bandiwdth
                                 pAS_Info->f_zif_bw,  //  the other tuner's Zero-IF bandwidth
                                 adj->maxH2,
                                 fp,                  //  minimum amount to move LO's positive
                                 fm))                 //  miminum amount to move LO's negative
            return 1;
    }
    // No spurs found
    return 0;
}
Ejemplo n.º 11
0
Archivo: pe.c Proyecto: HarryR/sanos
static int pe_write(struct pe_info *pe) {
  int i;
  int fd;
  FILE *op;
  FILE *stubfile;
  char *stub;
  int stub_size;
  DWORD file_offset, r;
  Section *s;

  if (pe->stub) {
    stubfile = fopen(pe->stub, "rb");
    if (stubfile == NULL) {
      error_noabort("could not read '%s': %s", pe->stub, strerror(errno));
      return 1;
    }
    fseek(stubfile, 0, SEEK_END);
    stub_size = ftell(stubfile);
    fseek(stubfile, 0, SEEK_SET);
    if (stub_size < sizeof(IMAGE_DOS_HEADER)) {
      error_noabort("invalid stub (%d bytes): %s", stub_size, pe->stub);
      return 1;
    }
    stub = tcc_malloc(stub_size);
    if (fread(stub, 1, stub_size, stubfile) != stub_size) {
      error_noabort("error reading stub '%s': %s", pe->stub, strerror(errno));
      return 1;
    }
    fclose(stubfile);
  } else {
    stub_size = DOSSTUB_SIZE + sizeof(IMAGE_DOS_HEADER);
    stub = tcc_malloc(stub_size);
    memcpy(stub, &pe_doshdr, sizeof(IMAGE_DOS_HEADER));
    memcpy(stub + sizeof(IMAGE_DOS_HEADER), pe_dosstub, DOSSTUB_SIZE);
  }
  ((PIMAGE_DOS_HEADER) stub)->e_lfanew = stub_size;

  fd = open(pe->filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0777);
  if (fd < 0) {
    error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
    return 1;
  }
  op = fdopen(fd, "wb");

  pe->sizeofheaders = 
    pe_file_align(pe,
      stub_size +
      sizeof(DWORD) + 
      sizeof(IMAGE_FILE_HEADER) +
      sizeof(IMAGE_OPTIONAL_HEADER) +
      pe->sec_count * sizeof (IMAGE_SECTION_HEADER));

  file_offset = pe->sizeofheaders;
  pe_fpad(op, file_offset, 0);

  if (verbose == 2) {
    printf("------------------------------------\n  virt   file   size  ord section" "\n");
  }

  for (i = 0; i < pe->sec_count; ++i) {
    struct section_info *si = pe->sec_info + i;
    const char *sh_name = si->name;
    unsigned long addr = si->sh_addr - pe->imagebase;
    unsigned long size = si->sh_size;
    IMAGE_SECTION_HEADER *psh = &si->ish;

    if (verbose == 2) {
      printf("%6lx %6lx %6lx %4d %s\n", addr, file_offset, size, si->ord, sh_name);
    }

    switch (si->cls) {
      case sec_text:
        pe_opthdr.BaseOfCode = addr;
        pe_opthdr.SizeOfCode += size;
        pe_opthdr.AddressOfEntryPoint = ((Elf32_Sym *) symtab_section->data)[pe->start_sym_index].st_value - pe->imagebase;
        break;

      case sec_data:
        pe_opthdr.BaseOfData = addr;
        pe_opthdr.SizeOfInitializedData += size;
        break;

      case sec_bss:
        pe_opthdr.SizeOfUninitializedData += size;
        break;

      case sec_reloc:
        pe_set_datadir(IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
        break;

      case sec_rsrc:
        pe_set_datadir(IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
        break;

      case sec_stab:
        break;
    }

    if (pe->thunk == pe->s1->sections[si->ord]) {
      if (pe->imp_size) {
        pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IMPORT, pe->imp_offs + addr, pe->imp_size);
        pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IAT, pe->iat_offs + addr, pe->iat_size);
      }
      if (pe->exp_size) {
        pe_set_datadir(IMAGE_DIRECTORY_ENTRY_EXPORT, pe->exp_offs + addr, pe->exp_size);
      }
    }

    strcpy((char *) psh->Name, sh_name);
    psh->Characteristics = pe_sec_flags[si->cls];
    psh->VirtualAddress = addr;
    psh->Misc.VirtualSize = size;
    pe_opthdr.SizeOfImage = umax(pe_virtual_align(size + addr), pe_opthdr.SizeOfImage); 

    if (si->sh_size) {
      psh->PointerToRawData = r = file_offset;
      for (s = si->first; s; s = s->next) {
        if (s->sh_type != SHT_NOBITS) {
          file_offset = align(file_offset, s->sh_addralign);
          pe_fpad(op, file_offset, si->cls == sec_text ? 0x90 : 0x00);
          fwrite(s->data, 1, s->data_offset, op);
          file_offset += s->data_offset;
        }
      }
      file_offset = pe_file_align(pe, file_offset);
      psh->SizeOfRawData = file_offset - r;
      pe_fpad(op, file_offset, 0);
    }
  }

  pe_filehdr.TimeDateStamp = time(NULL);
  pe_filehdr.NumberOfSections = pe->sec_count;
  pe_filehdr.Characteristics = do_debug ? 0x0102 : 0x030E;
  pe_opthdr.SizeOfHeaders = pe->sizeofheaders;
  pe_opthdr.ImageBase = pe->imagebase;
  pe_opthdr.FileAlignment = pe->filealign;
  if (pe->type == PE_DLL) {
    pe_filehdr.Characteristics = do_debug ? 0x2102 : 0x230E;
  } else if (pe->type != PE_GUI) {
    pe_opthdr.Subsystem = 3;
  }
  if (!pe->reloc) pe_filehdr.Characteristics |= 1;
  if (pe->s1->noshare) pe_filehdr.Characteristics |= 0x4000;

  fseek(op, 0, SEEK_SET);
  fwrite(stub,  1, stub_size, op);
  fwrite(&pe_ntsig,  1, sizeof pe_ntsig, op);
  fwrite(&pe_filehdr,  1, sizeof pe_filehdr, op);
  fwrite(&pe_opthdr,  1, sizeof pe_opthdr, op);
  for (i = 0; i < pe->sec_count; ++i) {
    fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op);
  }
  fclose(op);

  if (verbose == 2) {
    printf("------------------------------------\n");
  }
  if (verbose) {
    printf("<- %s (%lu bytes)\n", pe->filename, file_offset);
  }

  tcc_free(stub);
  return 0;
}
Ejemplo n.º 12
0
std::vector<RealGradient>
CNSFVMinmaxSlopeLimiting::limitElementSlope() const
{
  const Elem * elem = _current_elem;

  /// current element id
  dof_id_type _elementID = elem->id();

  /// current element centroid coordinte
  Point ecent = elem->centroid();

  /// number of sides surrounding an element
  unsigned int nside = elem->n_sides();

  /// number of conserved variables
  unsigned int nvars = 5;

  /// vector for the centroid of the sides surrounding an element
  std::vector<Point> scent(nside, Point(0., 0., 0.));

  /// vector for the limited gradients of the conserved variables
  std::vector<RealGradient> ugrad(nvars, RealGradient(0., 0., 0.));

  /// a flag to indicate the boundary side of the current cell
  bool bflag = false;

  /// initialize local minimum variable values
  std::vector<Real> umin(nvars, 0.);
  /// initialize local maximum variable values
  std::vector<Real> umax(nvars, 0.);
  /// initialize local cache for element variable values
  std::vector<Real> uelem(nvars, 0.);
  /// initialize local cache for reconstructed element gradients
  std::vector<RealGradient> rugrad(nvars, RealGradient(0., 0., 0.));
  /// initialize local cache for element slope limitor values
  std::vector<std::vector<Real>> limit(nside + 1, std::vector<Real>(nvars, 1.));

  Real dij = 0.;

  uelem = _rslope.getElementAverageValue(_elementID);

  for (unsigned int iv = 0; iv < nvars; iv++)
  {
    umin[iv] = uelem[iv];
    umax[iv] = uelem[iv];
  }

  /// loop over the sides to find the min and max cell-average values

  for (unsigned int is = 0; is < nside; is++)
  {
    const Elem * neighbor = elem->neighbor_ptr(is);

    if (neighbor != nullptr && this->hasBlocks(neighbor->subdomain_id()))
    {
      dof_id_type _neighborID = neighbor->id();
      uelem = _rslope.getElementAverageValue(_neighborID);
      scent[is] = _rslope.getSideCentroid(_elementID, _neighborID);
    }
    else
    {
      uelem = _rslope.getBoundaryAverageValue(_elementID, is);
      scent[is] = _rslope.getBoundarySideCentroid(_elementID, is);
    }

    for (unsigned int iv = 0; iv < nvars; iv++)
    {
      if (uelem[iv] < umin[iv])
        umin[iv] = uelem[iv];
      if (uelem[iv] > umax[iv])
        umax[iv] = uelem[iv];
    }
  }

  /// loop over the sides to compute the limiter values

  rugrad = _rslope.getElementSlope(_elementID);
  uelem = _rslope.getElementAverageValue(_elementID);

  for (unsigned int is = 0; is < nside; is++)
  {
    for (unsigned int iv = 0; iv < nvars; iv++)
    {
      dij = (scent[is] - ecent) * rugrad[iv];

      if (dij > 0.)
        limit[is + 1][iv] = std::min(1., (umax[iv] - uelem[iv]) / dij);
      else if (dij < 0.)
        limit[is + 1][iv] = std::min(1., (umin[iv] - uelem[iv]) / dij);
    }
  }

  /// loop over the sides to get the final limiter of this cell

  for (unsigned int is = 0; is < nside; is++)
  {
    for (unsigned int iv = 0; iv < nvars; iv++)
    {
      if (limit[0][iv] > limit[is + 1][iv])
        limit[0][iv] = limit[is + 1][iv];
    }
  }

  /// get the limited slope of this cell

  if (!_include_bc && bflag)
  {
    for (unsigned int iv = 0; iv < nvars; iv++)
      ugrad[iv] = RealGradient(0., 0., 0.);
  }
  else
  {
    for (unsigned int iv = 0; iv < nvars; iv++)
      ugrad[iv] = rugrad[iv] * limit[0][iv];
  }

  return ugrad;
}
Ejemplo n.º 13
0
// global memory based kernel generator
static ssize_t
generator(
   char *buf,
   size_t buflen,
   const struct SubproblemDim *subdims,
   const struct PGranularity *pgran,
   void *extra)
{
    struct KgenContext *ctx;
    CLBLASKernExtra *kextra = (CLBLASKernExtra*)extra;
    KernelExtraFlags kflags = kextra->flags;
    bool upper = ((kflags & KEXTRA_UPPER_TRIANG) != 0) ^
                  ((kflags & KEXTRA_COLUMN_MAJOR) != 0);
    char tmp[2048];
    const char *typeName;
    DataType dtype = kextra->dtype;
    BlasGenSettings gset, tgset, lset, gset1;
    CLBLASKernExtra kextraTmp;
    TileMulOpts mulOpts, tmulOpts;
    KernelVarNames *vnames = &gset.varNames;
    ssize_t ret;
    size_t vecLen = kextra->vecLen;
    const char *outTypeName;
    bool b;
    TilePostFetchPrivate pfPriv;
    struct symvPrivate priv;
    size_t wgSize;
    bool tailM = (kflags & KEXTRA_TAILS_M) != 0;
    bool tailK = (kflags & KEXTRA_TAILS_K) != 0;
    bool tra = (kflags & KEXTRA_COLUMN_MAJOR) != 0;
    bool rowMaj = !isMatrixAccessColMaj(CLBLAS_SYMV, kflags, MATRIX_A);
    bool isComplex = isComplexType(dtype);
    Tile tileb;
    const char *gid = "get_group_id(0)";
    const char *lid = "get_local_id(0)";
    bool isHoriz = subdims[1].bwidth >= subdims[1].y;
    unsigned int bStep = subdims[0].bwidth / subdims[1].bwidth;
    unsigned int cLocal;
    unsigned int nPlans;

    wgSize = (subdims[0].y / subdims[1].y) *
            (subdims[0].bwidth / subdims[1].bwidth);
    assert(pgran->wgSize[0] == wgSize);
    assert(subdims[0].x == 1);
    assert(subdims[1].x == 1);

    memset(&gset, 0, sizeof(gset));
    memset(&mulOpts, 0, sizeof(mulOpts));
    memset(&pfPriv, 0, sizeof(pfPriv));
    memset(&priv, 0, sizeof(priv));
    ctx = createKgenContext(buf, buflen, true);
    if (ctx == NULL) {
        return -ENOMEM;
    }

    // at first, generate needed declarations
    b = isDoubleBasedType(dtype);
    kgenDeclareUptrs(ctx, b);

    typeName = dtypeBuiltinType(dtype);

    declareSymvKernel(ctx, dtype, pgran, kflags);

    ret = kgenBeginFuncBody(ctx);
    /* 1D work space. Matrix is divided among wi, each calculates it's own
     * part of vector y */

    kgenAddStmt(ctx, "#define M actualN\n");
    memcpy(gset.subdims, subdims, sizeof(gset.subdims));
    gset.subdims[0].itemX = gset.subdims[0].x = 1;
    gset.subdims[1].itemX = gset.subdims[1].x = 1;
    gset.subdims[0].bwidth = gset.subdims[1].bwidth;
    gset.flags |= BGF_WHOLE_A | BGF_UPTRS;

    gset.kextra = kextra;
    gset.pgran = pgran;

    initDefaultTiles(&gset, CLBLAS_SYMV, 0, PRIV_STORAGE_VARIABLE_SET);
    gset.tileA.vecLen = umin(8u, tra ? gset.tileA.nrCols : gset.tileA.nrRows);

    if (isComplex) {
         gset.tileCY.vecLen = 1;
    }
    declareTileStorages(ctx, &gset);
    genZeroTile(ctx, &gset.tileCY);
    getVectorTypeName(dtype, gset.tileCY.vecLen, &outTypeName, NULL);
    cLocal = wgSize / bStep;
    nPlans = gset.tileCY.nrRows / gset.tileCY.vecLen;

    sprintf(tmp, "__local %s localRes[%u][%u];\n",
                outTypeName, pgran->wgSize[0], nPlans);
    kgenAddStmt(ctx, tmp);
    sprintf(tmp, "uint coordA = (%s * %u + %s / %u) * %lu + startN;\n",
                 gid, cLocal, lid, bStep, subdims[1].y);
    kgenAddStmt(ctx, tmp);
    sprintf(tmp, "uint n = coordA;\n");
    kgenAddStmt(ctx, tmp);
    sprintf(tmp, "uint k0 = (%s %% %u) * %lu;\n",
                 lid,  bStep, subdims[1].bwidth);
    kgenAddStmt(ctx, tmp);
    kgenAddStmt(ctx, "actualN += startN;\n");

    kgenAddBlankLine(ctx);

    kgenBeginBranch(ctx,"if (coordA < actualN && k0 < N)");

    genIncPointers(ctx, kflags);
    sprintf(tmp,
            "const GPtr Ag = {(__global %s*)A};\n"
            "const GPtr Xg = {(__global %s*)X};\n",
            typeName, typeName);
    kgenAddStmt(ctx, tmp);

    kgenAddBlankLine(ctx);

    kgenAddStmt(ctx, "uint k = k0;\n");

    if (tailK) {
        sprintf(tmp, "uint Ntail = N %% %lu;\n", subdims[1].bwidth);
        kgenAddStmt(ctx, tmp);
        sprintf(tmp, "uint Ktail = N %% %lu;\n\n", subdims[1].y);
        kgenAddStmt(ctx, tmp);
        kgenBeginBranch(ctx, "if (n + Ktail < N)");
        kgenAddStmt(ctx, "N -= Ntail;\n");
        kgenAddBlankLine(ctx);
    }

    mulOpts.flags |= TILEMUL_OPTIMIZE_COORD_CALC;
    if (tailM) {
        vnames->sizeM = "N";
    }

    vnames->A = "Ag";
    vnames->B = "Xg";
    vnames->coordA = "coordA";
    vnames->coordB = ""; //should not be used for vector
    vnames->k = "k";
    vnames->lda = "lda";
    vnames->sizeK = "N";
    vnames->sizeM = "N";

    mulOpts.flags |= TILEMUL_NOT_FETCH_B | TILEMUL_TRB | TILEMUL_NOT_INC_K;
    if ((kflags & KEXTRA_CONJUGATE_A) != 0) {
        mulOpts.flags |= TILEMUL_CONJA;
    }
    if ((kflags & KEXTRA_ENABLE_MAD) != 0) {
        mulOpts.core = TILEMUL_MAD;
    }
    else {
        mulOpts.core = TILEMUL_MULADD;
    }
    mulOpts.memA = CLMEM_GLOBAL_MEMORY;
    mulOpts.memB = CLMEM_GLOBAL_MEMORY;

    if (rowMaj) {
        mulOpts.flags |= TILEMUL_BW_STRIDE;
    }

    if (upper) {
        kgenAddStmt(ctx, "// k loop over column from the beginning of the column till the diagonal\n");
    }
    else {
        kgenAddStmt(ctx, "// k loop over row from the beginning of the row till the diagonal\n");
    }
    sprintf(tmp, "for (; k < n/%lu*%lu; k += %lu)",
        subdims[1].bwidth, subdims[1].bwidth, bStep*subdims[1].bwidth);
    kgenBeginBranch(ctx, tmp);

    genFetchX(ctx, &gset.tileBX, gset.kextra->vecLen, dtype, vnames,
            mulOpts.flags, kflags);

    upper ^= rowMaj;
    tra ^= rowMaj;
    if (upper ^ rowMaj && tra) {
        mulOpts.flags |= TILEMUL_TRA;
    }
    gset.tileA.trans ^= !upper;
    tgset = gset;
    tmulOpts = mulOpts;

    ret = tileMulGen(ctx, &gset, &mulOpts);
    if (ret != 0) {
        return ret;
    }
    kgenEndBranch(ctx, NULL); /* k loop */

    if (tailK)
    {
            kextraTmp = *kextra;
            gset1 = gset;

            kextraTmp.vecLen = 1;
            gset1.kextra = &kextraTmp;

            gset1.subdims[0].bwidth = gset1.subdims[1].bwidth = 1;

            gset1.tileBX.nrRows = 1;
            gset1.tileA.nrCols = 1;
            kextraTmp.vecLenA = 1;
    }


    if (isHoriz)
    {
        lset = gset;
        lset.subdims[0].bwidth = lset.subdims[1].bwidth =
            lset.subdims[1].y = umin(subdims[1].bwidth, subdims[1].y);
        lset.tileA.nrCols = lset.tileA.nrRows =
            lset.tileBX.nrRows = lset.subdims[1].y;

        kgenAddStmt(ctx, "// the diagonal\n");
        kgenBeginBranch(ctx, "if (k <= n)");
        kgenAddStmt(ctx, "uint k1 = k;\n");

        if (subdims[1].bwidth != subdims[1].y) {
            kgenAddStmt(ctx, "// the pred diagonal\n");
            sprintf(tmp, "for (; k < n; k += %lu)", lset.subdims[1].bwidth);
            kgenBeginBranch(ctx, tmp);

            genFetchX(ctx, &lset.tileBX, lset.subdims[1].bwidth, dtype, vnames,
                    mulOpts.flags, kflags);

            ret = tileMulGen(ctx, &lset, &mulOpts);
            if (ret != 0) {
                return ret;
            }
            kgenEndBranch(ctx, NULL); /* k loop */
        }

        initTile(&tileb, "b", lset.subdims[1].bwidth, lset.subdims[1].bwidth,
            lset.subdims[1].bwidth, lset.tileA.dtype, PRIV_STORAGE_VARIABLE_SET,
            lset.tileA.trans, lset.tileA.packed);
        declareOneTileStorage(ctx, &tileb);

        genFetchX(ctx, &lset.tileBX, lset.subdims[1].bwidth, dtype, vnames,
                mulOpts.flags, kflags);

        priv.mulOpts = &mulOpts;
        priv.pfPriv = &pfPriv;
        priv.tilea = lset.tileA;
        priv.diag = false;

        pfPriv.funcID = CLBLAS_SYMV;
        pfPriv.gset = &lset;
        lset.tileA = tileb;
        mulOpts.postFetch = genPostFetchMirror;
        mulOpts.postFetchPriv = &priv;

        ret = tileMulGen(ctx, &lset, &mulOpts);
        if (ret != 0) {
            return ret;
        }

        if (upper ^ rowMaj && tra) {
            mulOpts.flags &= ~TILEMUL_TRA;
        }
        else {
            mulOpts.flags |= TILEMUL_TRA;
        }
        gset.tileA.trans = lset.tileA.trans ^= true;
        mulOpts.postFetch = NULL;
        mulOpts.postFetchPriv = NULL;

        if (subdims[1].bwidth != subdims[1].y) {
            size_t width = umax(subdims[1].bwidth, subdims[1].y);
            kgenAddStmt(ctx, "// the post diagonal\n");
            if (tailK) {
                kgenBeginBranch(ctx, "if(k < N)");
            }
            sprintf(tmp, "for (k += %lu; k < n/%lu*%lu+%lu; k += %lu)",
                    lset.subdims[1].bwidth,
                    width, width, width,
                    lset.subdims[1].bwidth);
            kgenBeginBranch(ctx, tmp);

            genFetchX(ctx, &lset.tileBX, lset.subdims[1].bwidth, dtype, vnames,
                    mulOpts.flags, kflags);

            ret = tileMulGen(ctx, &lset, &mulOpts);
            if (ret != 0) {
                return ret;
            }
            kgenEndBranch(ctx, NULL); /* k loop */

            if (tailK) {
                kgenEndBranch(ctx, NULL);
                kgenBeginBranch(ctx, "else");
                /* Handle tail along vector X */

                kgenAddStmt(ctx, "N += Ntail;\n");

                mulOpts.flags |= TILEMUL_GLOBAL_CYCLIC_A;
#if 1
                sprintf(tmp, "for (k += %lu; k < actualN; k++)",
                    lset.subdims[1].bwidth);
                kgenBeginBranch(ctx, tmp);

                gset1.tileA.trans = gset.tileA.trans;

                genFetchX(ctx, &gset1.tileBX, gset1.kextra->vecLen, dtype, vnames,
                          mulOpts.flags, kflags);
                ret = tileMulGen(ctx, &gset1, &mulOpts);
                if (ret != 0) {
                    return ret;
                }
                kgenEndBranch(ctx, NULL); /* k loop for tails along vector X */
#else
                mulOpts.flags |= TILEMUL_SKEW_B | TILEMUL_NOT_INC_K;
                genFetchX(ctx, &gset.tileBX, gset.kextra->vecLen, dtype, vnames,
                          mulOpts.flags, kflags);
                ret = tileMulGen(ctx, &gset, &mulOpts);
                if (ret != 0) {
                    return ret;
                }
#endif

                mulOpts.flags &= ~TILEMUL_GLOBAL_CYCLIC_A;
                kgenEndBranch(ctx, NULL);
            }
        }

        sprintf(tmp, "k = k1 + %lu;\n", bStep*subdims[1].bwidth);
        kgenAddStmt(ctx, tmp);
        kgenEndBranch(ctx, NULL);
    }
    else
    {

        kgenAddStmt(ctx, "// the diagonal\n");
        sprintf(tmp, "if (k <= (n  + (get_local_id(0)%%%lu)*%lu))",
            subdims[1].y/subdims[1].bwidth, subdims[1].bwidth);
        kgenBeginBranch(ctx, tmp);

        genFetchX(ctx, &gset.tileBX, gset.subdims[1].bwidth, dtype, vnames,
                    mulOpts.flags, kflags);

        kgenBeginBranch(ctx, NULL);

        priv.mulOpts = &mulOpts;
        priv.pfPriv = &pfPriv;
        priv.diag = true;

        pfPriv.funcID = CLBLAS_SYMV;
        pfPriv.gset = &gset;
        mulOpts.postFetch = genPostFetchVertDiag;
        mulOpts.postFetchPriv = &priv;

        ret = tileMulGen(ctx, &gset, &mulOpts);
        if (ret != 0) {
            return ret;
        }
        kgenEndBranch(ctx, NULL);

        if (upper ^ rowMaj && tra) {
            mulOpts.flags &= ~TILEMUL_TRA;
        }
        else {
            mulOpts.flags |= TILEMUL_TRA;
        }
        gset.tileA.trans ^= true;
        lset = gset;

        sprintf(tmp, "n += (get_local_id(0)%%%lu)*%lu;\n",
            subdims[1].y/subdims[1].bwidth, subdims[1].bwidth);
        kgenAddStmt(ctx, tmp);
        kgenBeginBranch(ctx, NULL);

        priv.diag = false;
        ret = tileMulGen(ctx, &gset, &mulOpts);
        if (ret != 0) {
            return ret;
        }
        kgenEndBranch(ctx, NULL);

        mulOpts.postFetch = NULL;
        mulOpts.postFetchPriv = NULL;

        sprintf(tmp, "k += %lu;\n", bStep*subdims[1].bwidth);
        kgenAddStmt(ctx, tmp);
        kgenEndBranch(ctx, NULL); /* if */
    }

    if (upper) {
        kgenAddStmt(ctx, "// k loop over row from the diagonal till the right\n");
    }
    else {
        kgenAddStmt(ctx, "// k loop over column from the diagonal till the bottom\n");
    }
    sprintf(tmp, "for (; k < N; k += %lu)", bStep*subdims[1].bwidth);
    kgenBeginBranch(ctx, tmp);

    genFetchX(ctx, &gset.tileBX, gset.kextra->vecLen, dtype, vnames,
            mulOpts.flags, kflags);

    ret = tileMulGen(ctx, &gset, &mulOpts);
    if (ret != 0) {
        return ret;
    }
    kgenEndBranch(ctx, NULL); /* k loop */

    if (tailK) {
        /* Handle tail along vector X */
        kgenAddStmt(ctx, "N += Ntail;\n");

        mulOpts.flags |= TILEMUL_GLOBAL_CYCLIC_A;
#if 1
        sprintf(tmp, "for (; k < N; k++)");
        kgenBeginBranch(ctx, tmp);

        gset1.tileA.trans = gset.tileA.trans;

        genFetchX(ctx, &gset1.tileBX, gset1.kextra->vecLen, dtype, vnames,
                  mulOpts.flags, kflags);
        ret = tileMulGen(ctx, &gset1, &mulOpts);
        if (ret != 0) {
            return ret;
        }
        kgenEndBranch(ctx, NULL); /* k loop for tails along vector X */
#else
        mulOpts.flags |= TILEMUL_SKEW_B | TILEMUL_NOT_INC_K;
        genFetchX(ctx, &gset.tileBX, gset.kextra->vecLen, dtype, vnames,
                  mulOpts.flags, kflags);
        ret = tileMulGen(ctx, &gset, &mulOpts);
        if (ret != 0) {
            return ret;
        }
#endif

        kgenEndBranch(ctx, NULL);

        kgenBeginBranch(ctx, "else");

        sprintf(tmp, "for (; k < N; k += %lu)", bStep*subdims[1].bwidth);
        kgenBeginBranch(ctx, tmp);

        tmulOpts.flags |= TILEMUL_SKEW_B | TILEMUL_GLOBAL_CYCLIC_A;
        genFetchX(ctx, &tgset.tileBX, tgset.kextra->vecLen, dtype, vnames,
                tmulOpts.flags, kflags);

        priv.mulOpts = &tmulOpts;
        priv.pfPriv = &pfPriv;
        pfPriv.gset = &tgset;
        priv.diag = false;

        pfPriv.funcID = CLBLAS_SYMV;
        tmulOpts.postFetch = genPostFetchDiag;
        tmulOpts.postFetchPriv = &priv;

        ret = tileMulGen(ctx, &tgset, &tmulOpts);
        if (ret != 0) {
            return ret;
        }

        if (isHoriz) {
            sprintf(tmp, "if (k + %lu > N) break;\n", subdims[1].bwidth);
        }
        else {
            sprintf(tmp, "if (k + %lu > N + (get_local_id(0)%%%lu)*%lu) break;\n",
                subdims[1].y, subdims[1].y/subdims[1].bwidth, subdims[1].bwidth);
        }
        kgenAddStmt(ctx, tmp);

        kgenEndBranch(ctx, NULL); /* k loop */

        kgenBeginBranch(ctx, "if (k < N)");
        if (isHoriz) {
            kgenAddStmt(ctx, "k = n;\n");
        }
        else {
            sprintf(tmp, "n += (get_local_id(0)%%%lu)*%lu;\n",
                subdims[1].y/subdims[1].bwidth, subdims[1].bwidth);
            kgenAddStmt(ctx, tmp);
        }

        genFetchX(ctx, &lset.tileBX, lset.kextra->vecLen, dtype, vnames,
                tmulOpts.flags, kflags);

        priv.mulOpts = &tmulOpts;
        priv.pfPriv = &pfPriv;
        priv.diag = true;

        pfPriv.funcID = CLBLAS_SYMV;
        pfPriv.gset = &lset;
        tmulOpts.postFetch = genPostFetchDiag;
        tmulOpts.postFetchPriv = &priv;

        if (!isHoriz) {
            if (upper ^ rowMaj && tra) {
                tmulOpts.flags &= ~TILEMUL_TRA;
            }
            else {
                tmulOpts.flags |= TILEMUL_TRA;
            }
            kgenAddStmt(ctx, "Ktail = N - n;\n");
            priv.coord = true;
        }
        else {
            priv.coord = false;
        }
        tmulOpts.flags |= TILEMUL_SKEW_B | TILEMUL_GLOBAL_CYCLIC_A | TILEMUL_GLOBAL_CYCLIC_K;


        ret = tileMulGen(ctx, &lset, &tmulOpts);
        if (ret != 0) {
            return ret;
        }

        kgenEndBranch(ctx, NULL);

        kgenEndBranch(ctx, NULL);
    }


    if (!isMatrixAccessColMaj(CLBLAS_GEMV, kflags, MATRIX_A)) {
        mulOpts.flags &= ~TILEMUL_BW_STRIDE;
    }

    kgenEndBranch(ctx,NULL);

    genStoreLocalResult(ctx, &gset.tileCY, lid);

    kgenAddBarrier(ctx, CLK_LOCAL_MEM_FENCE);
    kgenAddBlankLine(ctx);

    sprintf(tmp, "if ((%s %% %u) == 0 && coordA < actualN && k0 < N)", lid, bStep);
    kgenBeginBranch(ctx, tmp);

    genAddLocalResult(ctx, &gset.tileCY, lid, bStep, 1);

    /* write back the results */
    /* y := alpha*A*x + beta*y */
    sprintf(tmp,"(%s - startN)", vnames->coordA);
    setResultPos(ctx, kflags, tmp);

    updateResultVectorTiled(ctx, kflags, vecLen, &gset.tileCY);

    kgenEndBranch(ctx, NULL);

    kgenEndFuncBody(ctx);
    ret = kgenAddBlankLine(ctx);
    if (!ret) {
        ret = (ssize_t)kgenSourceSize(ctx) + 1;
    }

    destroyKgenContext(ctx);
    return (ret < 0) ? -EOVERFLOW : ret;
}
Ejemplo n.º 14
0
int main()
{
	char* names[] = {
		"nul/20",
		"item1",
		"second item",
		"the third one",
		"item4",
		"item5",
		"item6",
		"item7",
		"item8",
		"item9",
		"item10",
		"item11",
		"item12",
		"item13",
		"item14",
		"item15",
		"item16",
		"item17",
		"item18",
		"item19",
		"item20",
		"item21",
		"item22",
		"item23",
		"item24",
		"item25",
		"item26",
		"item27",
		"item28",
		"item29"
	};

	int nbitems = 30;
	uint8_t owneditem[nbitems];
	for (int i=0; i<nbitems; i++) owneditem[i] = 0;

	sf2d_init();
	sf2d_set_clear_color(RGBA8(255, 255, 255, 255));
	sf2d_set_vblank_wait(0);

	// Font loading
	sftd_init();
	sftd_font* font = sftd_load_font_mem(FreeSans_ttf, FreeSans_ttf_size);

	int fontSize = 20;

	int row = 0;
	int nbrow = 10;
	int firstrow = 0;

#define LONG_TIMEOUT 500
#define SHORT_TIMEOUT_MAX 100
#define SHORT_TIMEOUT_MIN 20

	u64 oldTime = osGetTime();
	u64 timer = 0;
	u64 timeout = LONG_TIMEOUT;

	while (aptMainLoop()) {

		hidScanInput();
		if (hidKeysDown() & KEY_START) break;

		if ((hidKeysHeld() & KEY_UP) && timer == 0) row--;
		if (row == -1) {
			row++;
			firstrow--;
			if (firstrow == -1) {
				row = nbrow-1;
				firstrow = nbitems-nbrow;
			}
		}

		if ((hidKeysHeld() & KEY_DOWN) && timer == 0) row++;
		if (row == nbrow) {
			row--;
			firstrow++;
			if (firstrow+nbrow == nbitems+1) {
				firstrow = 0;
				row = 0;
			}
		}

		int index = firstrow+row;
		owneditem[index] += 100;
		if (hidKeysDown() & KEY_LEFT) owneditem[index]--;
		if (hidKeysDown() & KEY_RIGHT) owneditem[index]++;
		owneditem[index] %= 100;

		// use osGetTime to have key repetition
		u64 newTime = osGetTime();
		u64 delay = newTime-oldTime;
		oldTime = newTime;
		if (hidKeysHeld()) {
			timer += delay;
			if (timer>timeout) {
				timer = 0;
				if (timeout == LONG_TIMEOUT) {
					timeout = SHORT_TIMEOUT_MAX;
				} else {
					timeout = umax(timeout-2, SHORT_TIMEOUT_MIN);
				}
			}
		} else {
			timer = 0;
			timeout = LONG_TIMEOUT;
		}

		sf2d_start_frame(GFX_TOP, GFX_LEFT);
		{
			for (int i=0; i<nbrow; i++) {
				unsigned int color = RGBA8(0, 0, 0, 255);
				if (i == row) {
					sf2d_draw_rectangle(0, i*fontSize, 400, fontSize, RGBA8(0, 0, 0, 255));
					color = RGBA8(255, 255, 255, 255);
				}
				sftd_draw_textf(font, 010, i*fontSize, color, fontSize, names[firstrow+i]);
				sftd_draw_textf(font, 210, i*fontSize, color, fontSize, "%i", owneditem[firstrow+i]);
			}
		}
		sf2d_end_frame();

		sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
		{
			sftd_draw_textf(font, 0, 20, RGBA8(0, 255, 0, 255), 20, "Press START to exit");
			sftd_draw_textf(font, 0, 40, RGBA8(0, 255, 0, 255), 20, "Timeout: %i", timeout);
		}
		sf2d_end_frame();

		sf2d_swapbuffers();
	}

	sftd_free_font(font);
	sftd_fini();

	sf2d_fini();
	return 0;
}
Ejemplo n.º 15
0
void GrMouseSetAccel(int thresh, int accel)
{
    MOUINFO->thresh = umin(64, umax(1, thresh));
    MOUINFO->accel  = umin(16, umax(1, accel));
}
Ejemplo n.º 16
0
int
DjVuPalette::compute_palette(int maxcolors, int minboxsize)
{
  if (!hist)
    G_THROW( ERR_MSG("DjVuPalette.no_color") );
  if (maxcolors<1 || maxcolors>MAXPALETTESIZE)
    G_THROW( ERR_MSG("DjVuPalette.many_colors") );
  
  // Paul Heckbert: "Color Image Quantization for Frame Buffer Display", 
  // SIGGRAPH '82 Proceedings, page 297.  (also in ppmquant)
  
  // Collect histogram colors
  int sum = 0;
  int ncolors = 0;
  GTArray<PData> pdata;
  { // extra nesting for windows
    for (GPosition p = *hist; p; ++p)
    {
      pdata.touch(ncolors);
      PData &data = pdata[ncolors++];
      int k = hist->key(p);
      data.p[0] = (k>>16) & 0xff;
      data.p[1] = (k>>8) & 0xff;
      data.p[2] = (k) & 0xff;
      data.w = (*hist)[p];
      sum += data.w;
    }
  }
  // Create first box
  GList<PBox> boxes;
  PBox newbox;
  newbox.data = pdata;
  newbox.colors = ncolors;
  newbox.boxsize = 256;
  newbox.sum = sum;
  boxes.append(newbox);
  // Repeat spliting boxes
  while (boxes.size() < maxcolors)
    {
      // Find suitable box
      GPosition p;
      for (p=boxes; p; ++p)
        if (boxes[p].colors>=2 && boxes[p].boxsize>minboxsize) 
          break;
      if (! p)
        break;
      // Find box boundaries
      PBox &splitbox = boxes[p];
      unsigned char pmax[3];
      unsigned char pmin[3];
      pmax[0] = pmin[0] = splitbox.data->p[0];
      pmax[1] = pmin[1] = splitbox.data->p[1];
      pmax[2] = pmin[2] = splitbox.data->p[2];
      { // extra nesting for windows
        for (int j=1; j<splitbox.colors; j++)
        {
          pmax[0] = umax(pmax[0], splitbox.data[j].p[0]);
          pmax[1] = umax(pmax[1], splitbox.data[j].p[1]);
          pmax[2] = umax(pmax[2], splitbox.data[j].p[2]);
          pmin[0] = umin(pmin[0], splitbox.data[j].p[0]);
          pmin[1] = umin(pmin[1], splitbox.data[j].p[1]);
          pmin[2] = umin(pmin[2], splitbox.data[j].p[2]);
        }
      }
      // Determine split direction and sort
      int bl = pmax[0]-pmin[0]; 
      int gl = pmax[1]-pmin[1];
      int rl = pmax[2]-pmin[2];
      splitbox.boxsize = (bl>gl ? (rl>bl ? rl : bl) : (rl>gl ? rl : gl));
      if (splitbox.boxsize <= minboxsize)
        continue;
      if (gl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), gcomp);
      else if (rl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), rcomp);
      else
        qsort(splitbox.data, splitbox.colors, sizeof(PData), bcomp);
      // Find median
      int lowercolors = 0;
      int lowersum = 0;
      while (lowercolors<splitbox.colors-1 && lowersum+lowersum<splitbox.sum)
        lowersum += splitbox.data[lowercolors++].w;
      // Compute new boxes
      newbox.data = splitbox.data + lowercolors;
      newbox.colors = splitbox.colors - lowercolors;
      newbox.sum = splitbox.sum - lowersum;
      splitbox.colors = lowercolors;
      splitbox.sum = lowersum;
      // Insert boxes at proper location
      GPosition q;
      for (q=p; q; ++q)
        if (boxes[q].sum < newbox.sum)
          break;
      boxes.insert_before(q, newbox);
      for (q=p; q; ++q)
        if (boxes[q].sum < splitbox.sum)
          break;
      boxes.insert_before(q, boxes, p);
    }
  // Fill palette array
  ncolors = 0;
  palette.empty();
  palette.resize(0,boxes.size()-1);
  { // extra nesting for windows
    for (GPosition p=boxes; p; ++p)
    {
      PBox &box = boxes[p];
      // Compute box representative color
      float bsum = 0;
      float gsum = 0;
      float rsum = 0;
      for (int j=0; j<box.colors; j++)
        {
          float w = (float)box.data[j].w;
          bsum += box.data[j].p[0] * w;
          gsum += box.data[j].p[1] * w;
          rsum += box.data[j].p[2] * w;
        }
      PColor &color = palette[ncolors++];
      color.p[0] = (unsigned char) fmin(255, bsum/box.sum);
      color.p[1] = (unsigned char) fmin(255, gsum/box.sum);
      color.p[2] = (unsigned char) fmin(255, rsum/box.sum);
      color.p[3] = ( color.p[0]*BMUL + color.p[1]*GMUL + color.p[2]*RMUL) / SMUL;
    }
  }
  // Save dominant color
  PColor dcolor = palette[0];
  // Sort palette colors in luminance order
  qsort((PColor*)palette, ncolors, sizeof(PColor), lcomp);
  // Clear invalid data
  colordata.empty();
  delete pmap;
  pmap = 0;
  // Return dominant color
  return color_to_index_slow(dcolor.p);
}
Ejemplo n.º 17
0
/*----------------------------------------------------------------------------*/
ST_FN int pe_write(struct pe_info *pe)
{
    int i;
    FILE *op;
    DWORD file_offset, r;

    op = fopen(pe->filename, "wb");
    if (NULL == op) {
        error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
        return 1;
    }

    pe->sizeofheaders = pe_file_align(
        sizeof pe_header
        + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
        );

    file_offset = pe->sizeofheaders;
    pe_fpad(op, file_offset);

    if (2 == pe->s1->verbose)
        printf("-------------------------------"
               "\n  virt   file   size  section" "\n");

    for (i = 0; i < pe->sec_count; ++i) {
        struct section_info *si = pe->sec_info + i;
        const char *sh_name = si->name;
        unsigned long addr = si->sh_addr - pe->imagebase;
        unsigned long size = si->sh_size;
        IMAGE_SECTION_HEADER *psh = &si->ish;

        if (2 == pe->s1->verbose)
            printf("%6lx %6lx %6lx  %s\n",
                addr, file_offset, size, sh_name);

        switch (si->cls) {
            case sec_text:
                pe_header.opthdr.BaseOfCode = addr;
                pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
                break;

            case sec_data:
                pe_header.opthdr.BaseOfData = addr;
                break;

            case sec_bss:
                break;

            case sec_reloc:
                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
                break;

            case sec_rsrc:
                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
                break;

            case sec_stab:
                break;
        }

        if (pe->thunk == pe->s1->sections[si->ord]) {
            if (pe->imp_size) {
                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IMPORT,
                    pe->imp_offs + addr, pe->imp_size);
                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IAT,
                    pe->iat_offs + addr, pe->iat_size);
            }
            if (pe->exp_size) {
                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_EXPORT,
                    pe->exp_offs + addr, pe->exp_size);
            }
        }

        strcpy((char*)psh->Name, sh_name);

        psh->Characteristics = pe_sec_flags[si->cls];
        psh->VirtualAddress = addr;
        psh->Misc.VirtualSize = size;
        pe_header.opthdr.SizeOfImage =
            umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage); 

        if (si->data_size) {
            psh->PointerToRawData = r = file_offset;
            fwrite(si->data, 1, si->data_size, op);
            file_offset = pe_file_align(file_offset + si->data_size);
            psh->SizeOfRawData = file_offset - r;
            pe_fpad(op, file_offset);
        }
    }

    // pe_header.filehdr.TimeDateStamp = time(NULL);
    pe_header.filehdr.NumberOfSections = pe->sec_count;
    pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
    pe_header.opthdr.ImageBase = pe->imagebase;
    if (PE_DLL == pe->type)
        pe_header.filehdr.Characteristics = 0x230E;
    else if (PE_GUI != pe->type)
        pe_header.opthdr.Subsystem = 3;

    fseek(op, SEEK_SET, 0);
    fwrite(&pe_header,  1, sizeof pe_header, op);
    for (i = 0; i < pe->sec_count; ++i)
        fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op);
    fclose (op);

    if (2 == pe->s1->verbose)
        printf("-------------------------------\n");
    if (pe->s1->verbose)
        printf("<- %s (%lu bytes)\n", pe->filename, file_offset);

    return 0;
}
Ejemplo n.º 18
0
bool CorrectionEngine::correct(const std::string& str, std::string& results, double& freq) const
{
    if (str.size() >= 20)
        return false;

    std::string userQuery = str;
    try
    {
        ilplib::knlp::Normalize::normalize(userQuery);
    }
    catch(...)
    {
    }
    izenelib::util::UString uself(userQuery, izenelib::util::UString::UTF_8);
    if (uself.length() <= 1)
        return false;

    if (udef_->search(userQuery, results))
    {
        return true;
    }

    if (filter_->isFilter(userQuery))
    {
        return false;
    }
    std::vector<std::string> pinyin;
    bool isUserQueryHasChinese = false;
    if (NULL != pyConverter_)
    {
        isUserQueryHasChinese = (*pyConverter_)(userQuery, pinyin);
    }

    UserQuery self(userQuery, 0);
    FreqStringVector candidates;
     
    // from pinyin
    double factor = 100;
    boost::unordered_map<std::string, bool> accurate;
    for (std::size_t i = 0; i < pinyin.size(); i++)
    {
        UserQueryList uqList;
        pinyin_->search(pinyin[i], uqList);
        accurate[pinyin[i]] = true;
//std::cout<<pinyin[i]<<"\t-------------\n";
        UserQueryList::iterator it = uqList.begin();
        for (; it != uqList.end(); it++)
        {
            if (it->userQuery() != self.userQuery())
            {
                if (!UQCateEngine::getInstance().cateEqual(self.userQuery(), it->userQuery(), 10))
                    continue;
                double s = factorForPinYin(self.userQuery(), it->userQuery());
//std::cout<<it->userQuery()<<" : "<<it->freq()<<" : "<<s<<"\n";
                candidates.push_back(FreqString(it->userQuery(), it->freq() * factor * s));
            }
        }
    }
   
    // from approximate pinyin
    pinyin.clear();
    bool isUserQueryPinYin = false;
    if ((NULL != pyApproximator_) && (candidates.empty() || (!isUserQueryHasChinese)))
    {
        isUserQueryPinYin = (*pyApproximator_)(userQuery, pinyin);
        factor = 50;
        for (std::size_t i = 0; i < pinyin.size(); i++)
        {
            UserQueryList uqList;
            if (accurate.end() != accurate.find(pinyin[i]))
                continue;
            pinyin_->search(pinyin[i], uqList);
//std::cout<<pinyin[i]<<"\t-------------\n";
            UserQueryList::iterator it = uqList.begin();
            for (; it != uqList.end(); it++)
            {
                if (it->userQuery() != self.userQuery())
                {
                    if (!UQCateEngine::getInstance().cateEqual(self.userQuery(), it->userQuery(), 100))
                        continue;
                    double s = factorForPinYin(self.userQuery(), it->userQuery());
//std::cout<<it->userQuery()<<" : "<<it->freq()<<" : "<<s<<"\n";
                    candidates.push_back(FreqString(it->userQuery(), it->freq() * factor * s));
                }
            }
        }
    }
    pinyin.clear();
    accurate.clear();

    // from prefix
    factor = 1;
    UserQueryList uqList;
    prefix_->search(userQuery, uqList);
    UserQueryList::iterator it = uqList.begin();
//std::cout<<"PREFIX::\t-----------\n";
    for (; it != uqList.end(); it++)
    {
        if (it->userQuery() == self.userQuery())
        {
            self.setFreq(self.freq() + it->freq());
        }
        else
        {
            if (!UQCateEngine::getInstance().cateEqual(self.userQuery(), it->userQuery(), 100))
                continue;
            double s = factorForPrefix(self.userQuery(), it->userQuery());
//std::cout<<it->userQuery()<<" : "<<s<<"\n";
            candidates.push_back(FreqString(it->userQuery(), it->freq() * factor * s));
        }
    }
    
    if (candidates.empty())
        return false;

    factor = 1000;
    double s = isUserQueryPinYin ? 0.1 : 1;
    self.setFreq(self.freq() * factor * s);
    if (self.freq() < 1e-2)
    {
        self.setFreq(100);
    }

    FreqString max = StringUtil::max(candidates);
    const double selfFreq = self.freq();
    const double maxFreq = max.getFreq();
    izenelib::util::UString umax(max.getString(), izenelib::util::UString::UTF_8);
    if (umax.length() <= 1)
        return false;
    
//std::cout<<self.freq()<<"\t:\t"<<max.getFreq()<<"\n";
//std::cout<<self.userQuery()<<"\t:\t"<<max.getString()<<"\n";
    if (2.4 * selfFreq < maxFreq)
    {
        results = max.getString();
        freq = maxFreq / selfFreq;
        return true;
    }
    return false;
}
Ejemplo n.º 19
0
/*
 * Hit one guy with a projectile.
 * Handles use of missile weapons (wield = missile weapon)
 * or thrown items/weapons
 */
ch_ret projectile_hit( char_data * ch, char_data * victim, obj_data * wield, obj_data * projectile, short dist )
{
   int vic_ac, thac0, plusris, diceroll, prof_bonus, prof_gsn = -1, proj_bonus, dt, pchance;
   double dam = 0;
   ch_ret retcode;

   if( !projectile )
      return rNONE;

   if( projectile->item_type == ITEM_PROJECTILE || projectile->item_type == ITEM_WEAPON )
   {
      dt = TYPE_HIT + projectile->value[3];
      if( wield )
         proj_bonus = number_range( wield->value[1], wield->value[2] );
      else
         proj_bonus = 0;
   }
   else
   {
      dt = TYPE_UNDEFINED;
      proj_bonus = 0;
   }

   /*
    * Can't beat a dead char!
    */
   if( victim->position == POS_DEAD || victim->char_died(  ) )
   {
      projectile->extract(  );
      return rVICT_DIED;
   }

   if( wield )
      prof_bonus = weapon_prof_bonus_check( ch, wield, prof_gsn );
   else
      prof_bonus = 0;

   if( dt == TYPE_UNDEFINED )
   {
      dt = TYPE_HIT;
      if( wield && wield->item_type == ITEM_MISSILE_WEAPON )
         dt += wield->value[3];
   }

   thac0 = calc_thac0( ch, victim, dist );

   vic_ac = umax( -19, ( victim->GET_AC(  ) / 10 ) );

   /*
    * if you can't see what's coming... 
    */
   if( !victim->can_see_obj( projectile, false ) )
      vic_ac += 1;
   if( !ch->can_see( victim, false ) )
      vic_ac -= 4;

   /*
    * Weapon proficiency bonus 
    */
   vic_ac += prof_bonus;

   /*
    * The moment of excitement!
    */
   while( ( diceroll = number_bits( 5 ) ) >= 20 )
      ;

   if( diceroll == 0 || ( diceroll != 19 && diceroll < thac0 - vic_ac ) )
   {
      /*
       * Miss. 
       */
      if( prof_gsn != -1 )
         ch->learn_from_failure( prof_gsn );

      /*
       * Do something with the projectile 
       */
      if( number_percent(  ) < 50 )
         projectile->extract(  );
      else
      {
         if( projectile->carried_by )
            projectile->from_char(  );
         projectile->to_room( victim->in_room, victim );
      }
      damage( ch, victim, 0, dt );
      return rNONE;
   }

   /*
    * Hit.
    * Calc damage.
    */

   pchance = number_range( 1, 10 );

   switch ( pchance )
   {
      case 1:
      case 2:
      case 3: /* Hit in the arm */
         dam = number_range( projectile->value[1], projectile->value[2] ) + proj_bonus;
         break;

      case 4:
      case 5:
      case 6: /* Hit in the leg */
         dam = number_range( ( 2 * projectile->value[1] ), ( 2 * projectile->value[2] ) ) + proj_bonus;
         break;

      default:
      case 7:
      case 8:
      case 9:
      case 10:   /* Hit in the chest */
         dam = number_range( ( 3 * projectile->value[1] ), ( 3 * projectile->value[2] ) ) + proj_bonus;
         break;
   }

   /*
    * Bonuses.
    */
   dam += ch->GET_DAMROLL(  );

   if( prof_bonus )
      dam += prof_bonus / 4;

   /*
    * Calculate Damage Modifiers from Victim's Fighting Style
    */
   if( victim->position == POS_BERSERK )
      dam = 1.2 * dam;
   else if( victim->position == POS_AGGRESSIVE )
      dam = 1.1 * dam;
   else if( victim->position == POS_DEFENSIVE )
      dam = .85 * dam;
   else if( victim->position == POS_EVASIVE )
      dam = .8 * dam;

   if( !ch->isnpc(  ) && ch->pcdata->learned[gsn_enhanced_damage] > 0 && number_percent(  ) < ch->pcdata->learned[gsn_enhanced_damage] )
      dam += ( int )( dam * ch->LEARNED( gsn_enhanced_damage ) / 120 );
   else
      ch->learn_from_failure( gsn_enhanced_damage );

   if( !victim->IS_AWAKE(  ) )
      dam *= 2;

   if( dam <= 0 )
      dam = 1;

   plusris = 0;

   if( projectile->extra_flags.test( ITEM_MAGIC ) )
      dam = ris_damage( victim, dam, RIS_MAGIC );
   else
      dam = ris_damage( victim, dam, RIS_NONMAGIC );

   /*
    * Handle PLUS1 - PLUS6 ris bits vs. weapon hitroll   -Thoric
    */
   if( wield )
      plusris = wield->hitroll(  );

   /*
    * check for RIS_PLUSx - Thoric 
    */
   if( dam )
   {
      int x, res, imm, sus, mod;

      if( plusris )
         plusris = RIS_PLUS1 << UMIN( plusris, 7 );

      /*
       * initialize values to handle a zero plusris 
       */
      imm = res = -1;
      sus = 1;

      /*
       * find high ris 
       *//*
       * FIXME: Absorb handling needs to be included
       */
      for( x = RIS_PLUS1; x <= RIS_PLUS6; ++x )
      {
         if( victim->has_immune( x ) )
            imm = x;
         if( victim->has_resist( x ) )
            res = x;
         if( victim->has_suscep( x ) )
            sus = x;
      }
      mod = 10;
      if( imm >= plusris )
         mod -= 10;
      if( res >= plusris )
         mod -= 2;
      if( sus <= plusris )
         mod += 2;

      /*
       * check if immune 
       */
      if( mod <= 0 )
         dam = -1;
      if( mod != 10 )
         dam = ( dam * mod ) / 10;
   }

   /*
    * immune to damage 
    */
   if( dam == -1 )
   {
      if( dt >= 0 && dt < num_skills )
      {
         skill_type *skill = skill_table[dt];
         bool found = false;

         if( skill->imm_char && skill->imm_char[0] != '\0' )
         {
            act( AT_HIT, skill->imm_char, ch, nullptr, victim, TO_CHAR );
            found = true;
         }
         if( skill->imm_vict && skill->imm_vict[0] != '\0' )
         {
            act( AT_HITME, skill->imm_vict, ch, nullptr, victim, TO_VICT );
            found = true;
         }
         if( skill->imm_room && skill->imm_room[0] != '\0' )
         {
            act( AT_ACTION, skill->imm_room, ch, nullptr, victim, TO_NOTVICT );
            found = true;
         }
         if( found )
         {
            if( number_percent(  ) < 50 )
               projectile->extract(  );
            else
            {
               if( projectile->carried_by )
                  projectile->from_char(  );
               projectile->to_room( victim->in_room, victim );
            }
            return rNONE;
         }
      }
      dam = 0;
   }
   if( ( retcode = damage( ch, victim, dam, dt ) ) != rNONE )
   {
      if( projectile->value[5] == PROJ_STONE )
         projectile->extract(  );
      else
      {
         if( victim->char_died(  ) )
         {
            projectile->extract(  );
            return rVICT_DIED;
         }
         projectile->from_char(  );
         projectile->to_char( victim );
         projectile->extra_flags.set( ITEM_LODGED );

         switch ( pchance )
         {
            case 1:
            case 2:
            case 3: /* Hit in the arm */
               projectile->wear_flags.set( ITEM_LODGE_ARM );
               wear_obj( victim, projectile, true, get_wflag( "lodge_arm" ) );
               break;

            case 4:
            case 5:
            case 6: /* Hit in the leg */
               projectile->wear_flags.set( ITEM_LODGE_LEG );
               wear_obj( victim, projectile, true, get_wflag( "lodge_leg" ) );
               break;

            default:
            case 7:
            case 8:
            case 9:
            case 10:   /* Hit in the chest */
               projectile->wear_flags.set( ITEM_LODGE_RIB );
               wear_obj( victim, projectile, true, get_wflag( "lodge_rib" ) );
               break;
         }
      }
      return retcode;
   }
   if( ch->char_died(  ) )
   {
      projectile->extract(  );
      return rCHAR_DIED;
   }
   if( victim->char_died(  ) )
   {
      projectile->extract(  );
      return rVICT_DIED;
   }

   retcode = rNONE;
   if( dam == 0 )
   {
      if( number_percent(  ) < 50 )
         projectile->extract(  );
      else
      {
         if( projectile->carried_by )
            projectile->from_char(  );
         projectile->to_room( victim->in_room, victim );
      }
      return retcode;
   }

   /*
    * weapon spells -Thoric 
    */
   if( wield && !victim->has_immune( RIS_MAGIC ) && !victim->in_room->flags.test( ROOM_NO_MAGIC ) )
   {
      list < affect_data * >::iterator paf;

      for( paf = wield->pIndexData->affects.begin(  ); paf != wield->pIndexData->affects.end(  ); ++paf )
      {
         affect_data *af = *paf;

         if( af->location == APPLY_WEAPONSPELL && IS_VALID_SN( af->modifier ) && skill_table[af->modifier]->spell_fun )
            retcode = ( *skill_table[af->modifier]->spell_fun ) ( af->modifier, 7, ch, victim );
      }
      if( retcode != rNONE || ch->char_died(  ) || victim->char_died(  ) )
      {
         projectile->extract(  );
         return retcode;
      }

      for( paf = wield->affects.begin(  ); paf != wield->affects.end(  ); ++paf )
      {
         affect_data *af = *paf;

         if( af->location == APPLY_WEAPONSPELL && IS_VALID_SN( af->modifier ) && skill_table[af->modifier]->spell_fun )
            retcode = ( *skill_table[af->modifier]->spell_fun ) ( af->modifier, 7, ch, victim );
      }
      if( retcode != rNONE || ch->char_died(  ) || victim->char_died(  ) )
      {
         projectile->extract(  );
         return retcode;
      }
   }
   projectile->extract(  );
   return retcode;
}