<Someone>'s new files.
This commit is contained in:
181
win/gem/gr_rect.c
Normal file
181
win/gem/gr_rect.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/* SCCS Id: @(#)gr_rect.c 3.4 2001/12/10 */
|
||||
/* Copyright (c) Christian Bressler, 2001 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
/* This is an almost exact copy of qt_clust.cpp */
|
||||
/* gr_rect.c */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include "gr_rect.h"
|
||||
dirty_rect *new_dirty_rect(int size){
|
||||
dirty_rect *new=NULL;
|
||||
if(size>0){
|
||||
new=(dirty_rect *)calloc(1L,sizeof(dirty_rect));
|
||||
if(new){
|
||||
new->rects=(GRECT *)calloc((long)size,sizeof(GRECT));
|
||||
if(new->rects==NULL){
|
||||
free(new);
|
||||
return(NULL);
|
||||
}
|
||||
new->max=size;
|
||||
}
|
||||
}
|
||||
return(new);
|
||||
}
|
||||
void delete_dirty_rect(dirty_rect *this){
|
||||
if(this==NULL)
|
||||
return;
|
||||
if(this->rects)
|
||||
free(this->rects);
|
||||
/* In case the Pointer is reused wrongly */
|
||||
this->rects=NULL;
|
||||
this->max=0;
|
||||
this->used=0;
|
||||
free(this);
|
||||
}
|
||||
static int gc_inside(GRECT *frame,GRECT *test);
|
||||
static int gc_touch(GRECT *frame,GRECT *test);
|
||||
static void gc_combine(GRECT *frame,GRECT *test);
|
||||
static long gc_area(GRECT *area);
|
||||
int add_dirty_rect(dirty_rect *dr,GRECT *area){
|
||||
int cursor;
|
||||
long lowestcost=9999999L;
|
||||
int cheapest=-1;
|
||||
int cheapestmerge1=-1;
|
||||
int cheapestmerge2=-1;
|
||||
int merge1;
|
||||
int merge2;
|
||||
for (cursor=0; cursor<dr->used; cursor++) {
|
||||
if (gc_inside(&dr->rects[cursor],area)) {
|
||||
/* Wholly contained already. */
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
for (cursor=0; cursor<dr->used; cursor++) {
|
||||
if (gc_touch(&dr->rects[cursor],area)) {
|
||||
GRECT larger=dr->rects[cursor];
|
||||
long cost;
|
||||
gc_combine(&larger,area);
|
||||
cost=gc_area(&larger)-gc_area(&dr->rects[cursor]);
|
||||
if (cost < lowestcost) {
|
||||
int bad=FALSE,c;
|
||||
for (c=0; c<dr->used && !bad; c++) {
|
||||
bad=gc_touch(&dr->rects[c],&larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapest=cursor;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cheapest>=0) {
|
||||
gc_combine(&dr->rects[cheapest],area);
|
||||
return(TRUE);
|
||||
}
|
||||
if (dr->used < dr->max) {
|
||||
dr->rects[dr->used++]=*area;
|
||||
return(TRUE);
|
||||
}
|
||||
// Do cheapest of:
|
||||
// add to closest cluster
|
||||
// do cheapest cluster merge, add to new cluster
|
||||
lowestcost=9999999L;
|
||||
cheapest=-1;
|
||||
for (cursor=0; cursor<dr->used; cursor++) {
|
||||
GRECT larger=dr->rects[cursor];
|
||||
long cost;
|
||||
gc_combine(&larger,area);
|
||||
cost=gc_area(&larger)-gc_area(&dr->rects[cursor]);
|
||||
if (cost < lowestcost) {
|
||||
int bad=FALSE, c;
|
||||
for (c=0; c<dr->used && !bad; c++) {
|
||||
bad=gc_touch(&dr->rects[c],&larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapest=cursor;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
// XXX could make an heuristic guess as to whether we
|
||||
// XXX need to bother looking for a cheap merge.
|
||||
for (merge1=0; merge1<dr->used; merge1++) {
|
||||
for (merge2=0; merge2<dr->used; merge2++) {
|
||||
if (merge1!=merge2) {
|
||||
GRECT larger=dr->rects[merge1];
|
||||
long cost;
|
||||
gc_combine(&larger,&dr->rects[merge2]);
|
||||
cost=gc_area(&larger)-gc_area(&dr->rects[merge1])-gc_area(&dr->rects[merge2]);
|
||||
if (cost < lowestcost) {
|
||||
int bad=FALSE, c;
|
||||
for (c=0; c<dr->used && !bad; c++) {
|
||||
bad=gc_touch(&dr->rects[c],&larger) && c!=cursor;
|
||||
}
|
||||
if (!bad) {
|
||||
cheapestmerge1=merge1;
|
||||
cheapestmerge2=merge2;
|
||||
lowestcost=cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cheapestmerge1>=0) {
|
||||
gc_combine(&dr->rects[cheapestmerge1],&dr->rects[cheapestmerge2]);
|
||||
dr->rects[cheapestmerge2]=dr->rects[dr->used-1];
|
||||
dr->rects[dr->used-1]=*area;
|
||||
} else {
|
||||
gc_combine(&dr->rects[cheapest],area);
|
||||
}
|
||||
// NB: clusters do not intersect (or intersection will
|
||||
// overwrite). This is a result of the above algorithm,
|
||||
// given the assumption that (x,y) are ordered topleft
|
||||
// to bottomright.
|
||||
return(TRUE);
|
||||
}
|
||||
int get_dirty_rect(dirty_rect* dr,GRECT *area){
|
||||
if(dr==NULL || area==NULL || dr->rects==NULL || dr->used<=0 || dr->max<=0)
|
||||
return(FALSE);
|
||||
*area=dr->rects[--dr->used];
|
||||
return(TRUE);
|
||||
}
|
||||
int clear_dirty_rect(dirty_rect *dr){
|
||||
if(dr)
|
||||
dr->used=0;
|
||||
return(TRUE);
|
||||
}
|
||||
int resize_dirty_rect(dirty_rect *dr,int new_size){
|
||||
return(FALSE);
|
||||
}
|
||||
static int gc_inside(GRECT *frame,GRECT *test){
|
||||
if(frame && test && frame->g_x<=test->g_x && frame->g_y<=test->g_y &&
|
||||
frame->g_x+frame->g_w>=test->g_x+test->g_w &&
|
||||
frame->g_y+frame->g_h>=test->g_y+test->g_h
|
||||
)
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
static int gc_touch(GRECT *frame,GRECT *test){
|
||||
GRECT tmp={test->g_x-1,test->g_y-1,test->g_w+2,test->g_h+2};
|
||||
return(rc_intersect(frame,&tmp));
|
||||
}
|
||||
static void gc_combine(GRECT *frame,GRECT *test){
|
||||
if(!frame || !test)
|
||||
return;
|
||||
if(frame->g_x>test->g_x){
|
||||
frame->g_w+=frame->g_x-test->g_x;
|
||||
frame->g_x=test->g_x;
|
||||
}
|
||||
if(frame->g_y>test->g_y){
|
||||
frame->g_h+=frame->g_y-test->g_y;
|
||||
frame->g_y=test->g_y;
|
||||
}
|
||||
if(frame->g_x+frame->g_w<test->g_x+test->g_w)
|
||||
frame->g_w=test->g_x+test->g_w-frame->g_x;
|
||||
if(frame->g_y+frame->g_h<test->g_y+test->g_h)
|
||||
frame->g_h=test->g_y+test->g_h-frame->g_y;
|
||||
}
|
||||
static long gc_area(GRECT *area){
|
||||
return((long)area->g_h*(long)area->g_w);
|
||||
}
|
||||
14
win/gem/gr_rect.h
Normal file
14
win/gem/gr_rect.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* gr_rect.h */
|
||||
#include <e_gem.h>
|
||||
/********** structs **********/
|
||||
typedef struct {
|
||||
GRECT *rects;
|
||||
int max,used;
|
||||
} dirty_rect;
|
||||
/********* functions ************/
|
||||
dirty_rect *new_dirty_rect(int size);
|
||||
void delete_dirty_rect(dirty_rect *this);
|
||||
int add_dirty_rect(dirty_rect *dr,GRECT *area);
|
||||
int get_dirty_rect(dirty_rect* dr,GRECT *area);
|
||||
int clear_dirty_rect(dirty_rect *dr);
|
||||
int resize_dirty_rect(dirty_rect *dr,int new_size);
|
||||
164
win/gem/xpm2img.c
Normal file
164
win/gem/xpm2img.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/* SCCS Id: @(#)xpm2img.c 3.4 2002/03/17 */
|
||||
/* Copyright (c) Christian Bressler 2002 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
/* This is mainly a reworked tile2bmp.c + xpm2iff.c -- Marvin */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "bitmfile.h"
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
void get_color(unsigned int colind, struct RGB *rgb);
|
||||
void get_pixel(int x, int y, unsigned int *colind);
|
||||
char *xpmgetline();
|
||||
unsigned int **Bild_daten;
|
||||
/* translation table from xpm characters to RGB and colormap slots */
|
||||
struct Ttable {
|
||||
char flag;
|
||||
struct RGB col;
|
||||
int slot; /* output colortable index */
|
||||
}ttable[256];
|
||||
struct RGB *ColorMap;
|
||||
int num_colors = 0;
|
||||
int width=0, height=0;
|
||||
int initflag;
|
||||
FILE *fp;
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int row, col, planeno;
|
||||
int farben, planes;
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: tile2img infile.xpm outfile.img\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
initflag = 0;
|
||||
fp = fopen(argv[2],"wb");
|
||||
if (!fp) {
|
||||
printf("Error creating IMG-file %s, aborting.\n",argv[2]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(fp);
|
||||
if(fopen_xpm_file(argv[1],"r")!=TRUE){
|
||||
printf("Error reading xpm-file %s, aborting.\n",argv[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
Bild_daten=(unsigned int **)malloc((long)height*sizeof(unsigned int *));
|
||||
for(i=0;i<height;i++)
|
||||
Bild_daten[i]=(unsigned int *)malloc((long)width*sizeof(unsigned int));
|
||||
for(row = 0;row<height;row++){
|
||||
char *xb = xpmgetline();
|
||||
int plane_offset;
|
||||
if(xb==0){
|
||||
printf("Error to few lines in xpm-file %s, aborting.\n",argv[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for(col = 0;col<width;col++){
|
||||
int color = xb[col];
|
||||
if(!ttable[color].flag)
|
||||
fprintf(stderr, "Bad image data\n");
|
||||
Bild_daten[row][col]= ttable[color].slot;
|
||||
}
|
||||
}
|
||||
if(num_colors>256){
|
||||
fprintf(stderr,"ERROR: zuviele Farben\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}else if(num_colors>16){
|
||||
farben=256;
|
||||
planes=8;
|
||||
}else if(num_colors>2){
|
||||
farben=16;
|
||||
planes=4;
|
||||
}else{
|
||||
farben=2;
|
||||
planes=1;
|
||||
}
|
||||
bitmap_to_file(XIMG, width, height, 372, 372, planes, farben, argv[2], get_color, get_pixel );
|
||||
exit(EXIT_SUCCESS);
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
void get_color(unsigned int colind, struct RGB *rgb){
|
||||
rgb->r=(1000L*(long)ColorMap[colind].r)/0xFF;
|
||||
rgb->g=(1000L*(long)ColorMap[colind].g)/0xFF;
|
||||
rgb->b=(1000L*(long)ColorMap[colind].b)/0xFF;
|
||||
}
|
||||
void get_pixel(int x, int y, unsigned int *colind){
|
||||
*colind=Bild_daten[y][x];
|
||||
}
|
||||
FILE *xpmfh = 0;
|
||||
char initbuf[200];
|
||||
char *xpmbuf = initbuf;
|
||||
/* version 1. Reads the raw xpm file, NOT the compiled version. This is
|
||||
* not a particularly good idea but I don't have time to do the right thing
|
||||
* at this point, even if I was absolutely sure what that was. */
|
||||
fopen_xpm_file(const char *fn, const char *mode){
|
||||
int temp;
|
||||
char *xb;
|
||||
if(strcmp(mode, "r"))return FALSE; /* no choice now */
|
||||
if(xpmfh)return FALSE; /* one file at a time */
|
||||
xpmfh = fopen(fn, mode);
|
||||
if(!xpmfh)return FALSE; /* I'm hard to please */
|
||||
/* read the header */
|
||||
xb = xpmgetline();
|
||||
if(xb == 0)return FALSE;
|
||||
if(4 != sscanf(xb,"%d %d %d %d",
|
||||
&width, &height,&num_colors, &temp))
|
||||
return FALSE; /* bad header */
|
||||
/* replace the original buffer with one big enough for
|
||||
* the real data
|
||||
*/
|
||||
/* XXX */
|
||||
xpmbuf = malloc(width * 2);
|
||||
if(!xpmbuf){
|
||||
fprintf(stderr,"ERROR: Can't allocate line buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
if(temp != 1)return FALSE; /* limitation of this code */
|
||||
{
|
||||
/* read the colormap and translation table */
|
||||
int ccount = -1;
|
||||
ColorMap = (struct RGB *)malloc((long)num_colors*sizeof(struct RGB));
|
||||
while(ccount++ < (num_colors-1)){
|
||||
char index;
|
||||
int r, g, b;
|
||||
xb = xpmgetline();
|
||||
if(xb==0)return FALSE;
|
||||
if(4 != sscanf(xb,"%c c #%2x%2x%2x",&index,&r,&g,&b)){
|
||||
fprintf(stderr,"Bad color entry: %s\n",xb);
|
||||
return FALSE;
|
||||
}
|
||||
ttable[index].flag = 1; /* this color is valid */
|
||||
ttable[index].col.r = r;
|
||||
ttable[index].col.g = g;
|
||||
ttable[index].col.b = b;
|
||||
ttable[index].slot = ccount;
|
||||
ColorMap[ccount].r=r;
|
||||
ColorMap[ccount].g=g;
|
||||
ColorMap[ccount].b=b;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/* This deserves better. Don't read it too closely - you'll get ill. */
|
||||
#define bufsz 2048
|
||||
char buf[bufsz];
|
||||
char *
|
||||
xpmgetline(){
|
||||
char *bp;
|
||||
do {
|
||||
if(fgets(buf, bufsz, xpmfh) == 0)return 0;
|
||||
} while(buf[0] != '"');
|
||||
/* strip off the trailing <",> if any */
|
||||
for(bp = buf;*bp;bp++);
|
||||
bp--;
|
||||
while(isspace(*bp))bp--;
|
||||
if(*bp==',')bp--;
|
||||
if(*bp=='"')bp--;
|
||||
bp++;
|
||||
*bp = '\0';
|
||||
return &buf[1];
|
||||
}
|
||||
Reference in New Issue
Block a user