Free Hero Mesh

Check-in [88e748ef6d]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Add init_screen() and starting the type defintions for classes, and fix the picture loader to work with zoomed pictures
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 88e748ef6d7c33409447ac1cda4bbbc43eeed3b9
User & Date: user on 2018-04-06 21:00:00
Other Links: manifest | tags
Context
2018-04-08
23:31
Types, bug fixes, and test mode check-in: 3df78ec087 user: user tags: trunk
2018-04-06
21:00
Add init_screen() and starting the type defintions for classes, and fix the picture loader to work with zoomed pictures check-in: 88e748ef6d user: user tags: trunk
2018-04-02
23:54
Fix a mistake check-in: 1e31248216 user: user tags: trunk
Changes

Modified heromesh.h from [81301118dc] to [89443417d7].

14
15
16
17
18
19
20








































extern SDL_Surface*screen;
extern Uint16 picture_size;

void draw_picture(int x,int y,Uint16 img);
void draw_text(int x,int y,const unsigned char*t,int bg,int fg);
void load_pictures(void);
















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
extern SDL_Surface*screen;
extern Uint16 picture_size;

void draw_picture(int x,int y,Uint16 img);
void draw_text(int x,int y,const unsigned char*t,int bg,int fg);
void load_pictures(void);

// class.c

#define CF_PLAYER 0x01
#define CF_INPUT 0x02
#define CF_COMPATIBLE 0x04
#define CF_QUIZ 0x08
#define CF_NOCLASS1 0x40 // if only the name has been loaded so far, from the .class file
#define CF_NOCLASS2 0x80 // if only the name has been loaded so far, from the CLASS.DEF lump

#define OF_INVISIBLE 0x0001
#define OF_VISUALONLY 0x0002
#define OF_STEALTHY 0x0004
#define OF_BUSY 0x0008
#define OF_USERSTATE 0x0010
#define OF_USERSIGNAL 0x0020
#define OF_MOVED 0x0040
#define OF_DONE 0x0080
#define OF_KEYCLEARED 0x0100
#define OF_DESTROYED 0x0200

typedef struct {
  const char*name;
  const char*edithelp;
  const char*gamehelp;
  Uint16*codes;
  Uint16*messages; // use 0xFFFF if no such message block
  Uint16*images; // high bit is set if available to editor
  Sint32 height,weight,climb,density,volume,strength,arrivals,departures;
  Sint32 temperature,misc4,misc5,misc6,misc7;
  Uint16 uservars,oflags;
  Uint16 sharp[4];
  Uint16 hard[4];
  Uint8 cflags,shape,shovable;
} Class;

extern Class*classes[0x4000]; // 0 isn't used
extern const char*messages[0x4000];
extern int max_animation;
extern Sint32 max_volume;

Modified main.c from [9e50e0dd98] to [6d5db62424].

293
294
295
296
297
298
299
300
301
302
303
304
305
306
    globalclassname=strrchr(basefilename,'/');
    globalclassname=globalclassname?globalclassname+1:basefilename;
  }
  load_options();
  if(argc>2) read_options(argc-2,argv+2);
  *optionquery=xrm_make_quark(globalclassname,0)?:xrm_anyq;
  init_sql();
  
  //set_cursor(XC_arrow);
  
  //atexit(SDL_Quit);
  
  return 0;
}







|
<
<
<



293
294
295
296
297
298
299
300



301
302
303
    globalclassname=strrchr(basefilename,'/');
    globalclassname=globalclassname?globalclassname+1:basefilename;
  }
  load_options();
  if(argc>2) read_options(argc-2,argv+2);
  *optionquery=xrm_make_quark(globalclassname,0)?:xrm_anyq;
  init_sql();
  init_screen();



  
  return 0;
}

Deleted notes version [edd6349237].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Some notes


=== File formats ===

Each puzzle set in Free Hero Mesh is stored as four files:
*.xclass (Hamster archive) - Pictures and user sounds
*.class (Text) - Class definitions (attributes and codes)
*.level (Hamster archive) - Levels
*.solution (Hamster archive) - Solutions to levels

An idea is to use either Hamster archive or SQLite for the .level and
.solution files. I decided to use Hamster archive, but here are some of
the advantages and disadvantages of each approach:

Advantages of using Hamster archive:
* It is a simple file format.
* You can use the "har" program to extract and alter lumps.
* There will be less bugs because it is simpler than SQLite.

Disadvantages of using Hamster archive:
* It is necessary to rewrite the entire file when it changes.
* It is necessary to read the entire file to find the lumps.

Advantages of using SQLite:
* You can read parts of the file at a time.
* You can alter records without having to rewrite everything.
* SQL can now be used for user queries and user scripts.
* You can use sqlite3 command shell to deal with the file.

Disadvantages of using SQLite:
* There will be extra overhead due to b-trees and other stuff.
* It may be necessary to deal with untrusted database schemas (unsure).
* Now SQLite must be included in this program.

Another way would be a hybrid approach. Another file containing the user
session data is a SQLite database, which is recreated if it was deleted or
if the level or solution file is newer than it, and stores an index.

Advantages of hybrid:
* It is only necessary to create an index once.
* SQL can now be used for user queries and user scripts.
* User session data can be recorded.

Disadvantages of hybrid:
* SQLite must be included in this program.
* Level/solution files must still be rewritten entirely when it changes.

Hero Mesh will rewrite the puzzle set file only on exit, so it is possible
to do the similar thing in this case, by using the session database. A way
of incrementally storing and then "vacuuming" the file may also work.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































Modified picture.c from [c46d8e64e4] to [a53d3b6194].

157
158
159
160
161
162
163
164
165
166
167
168
169
170

171









172
173
174
175
176
177

178
179
180
181
182

183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
    if(t==2) c=fgetc(fp);
    if(t==3) c=p-curpic>=size?p[-size]:0;
    *p++=c;
  }
}

static void load_one_picture(FILE*fp,Uint16 img,int alt) {
  int i,j,k,pitch,which,meth,size;
  Uint8 buf[32];
  Uint8*pix;
  *buf=fgetc(fp);
  j=*buf&15;
  fread(buf+1,1,j+(j>>1),fp);
  k=0;

  for(i=1;i<=j;i++) if(buf[i]==picture_size) ++k;









  alt%=k;
  for(i=1;i<=j;i++) if(buf[i]==picture_size && !alt--) break;
  which=i;
  i=1;
  while(which--) load_one_picture_sub(fp,size=buf[i],meth=(i==1?*buf>>4:buf[(*buf&15)+1+((i-2)>>1)]>>(i&1?4:0))&15),i++;
  if(meth==5 || meth==6) meth^=3;

  SDL_LockSurface(picts);
  pitch=picts->pitch;
  pix=picts->pixels+((img&15)+pitch*(img>>4))*picture_size;
  if(meth==15) meth=0;
  for(i=0;i<size;i++) {

    for(j=0;j<size;j++) {
      if(meth&1) j=size-j-1;
      if(meth&2) i=size-i-1;
      *pix++=curpic[meth&4?j*size+i:i*size+j];
      if(meth&1) j=size-j-1;
      if(meth&2) i=size-i-1;
    }
    pix+=pitch-size;

  }
  SDL_UnlockSurface(picts);
}

void load_pictures(void) {
  sqlite3_stmt*st=0;
  FILE*fp;







|






>

>
>
>
>
>
>
>
>
>

|




>



<

>
|
|
|
|
|
|
|
|
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    if(t==2) c=fgetc(fp);
    if(t==3) c=p-curpic>=size?p[-size]:0;
    *p++=c;
  }
}

static void load_one_picture(FILE*fp,Uint16 img,int alt) {
  int h,i,j,k,pitch,which,meth,size,psize,zoom;
  Uint8 buf[32];
  Uint8*pix;
  *buf=fgetc(fp);
  j=*buf&15;
  fread(buf+1,1,j+(j>>1),fp);
  k=0;
  zoom=1;
  for(i=1;i<=j;i++) if(buf[i]==picture_size) ++k;
  if(k) {
    psize=picture_size;
  } else {
    for(zoom=2;zoom<=picture_size;zoom++) if(!(picture_size%zoom)) {
      psize=picture_size/zoom;
      for(i=1;i<=j;i++) if(buf[i]==psize) ++k;
      if(k) break;
    }
  }
  alt%=k;
  for(i=1;i<=j;i++) if(buf[i]==psize && !alt--) break;
  which=i;
  i=1;
  while(which--) load_one_picture_sub(fp,size=buf[i],meth=(i==1?*buf>>4:buf[(*buf&15)+1+((i-2)>>1)]>>(i&1?4:0))&15),i++;
  if(meth==5 || meth==6) meth^=3;
  if(meth==15) meth=0;
  SDL_LockSurface(picts);
  pitch=picts->pitch;
  pix=picts->pixels+((img&15)+pitch*(img>>4))*picture_size;

  for(i=0;i<size;i++) {
    for(h=0;h<zoom;h++) {
      for(j=0;j<size;j++) {
        if(meth&1) j=size-j-1;
        if(meth&2) i=size-i-1;
        for(k=0;k<zoom;k++) *pix++=curpic[meth&4?j*size+i:i*size+j];
        if(meth&1) j=size-j-1;
        if(meth&2) i=size-i-1;
      }
      pix+=pitch-picture_size;
    }
  }
  SDL_UnlockSurface(picts);
}

void load_pictures(void) {
  sqlite3_stmt*st=0;
  FILE*fp;
283
284
285
286
287
288
289

























  }
  sqlite3_finalize(st);
  fclose(fp);
  sqlite3_exec(userdb,"COMMIT;",0,0,0);
  SDL_SetColorKey(picts,SDL_SRCCOLORKEY|SDL_RLEACCEL,0);
}

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  }
  sqlite3_finalize(st);
  fclose(fp);
  sqlite3_exec(userdb,"COMMIT;",0,0,0);
  SDL_SetColorKey(picts,SDL_SRCCOLORKEY|SDL_RLEACCEL,0);
}

void init_screen(void) {
  const char*v;
  int w,h,i;
  optionquery[1]=Q_screenWidth;
  w=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"800",0,10);
  optionquery[1]=Q_screenHeight;
  h=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"600",0,10);
  optionquery[1]=Q_screenFlags;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
  if(SDL_Init(SDL_INIT_VIDEO|(strchr(v,'z')?SDL_INIT_NOPARACHUTE:0))) fatal("Error initializing SDL: %s\n",SDL_GetError());
  atexit(SDL_Quit);
  i=0;
  while(*v) switch(*v++) {
    case 'd': i|=SDL_DOUBLEBUF; break;
    case 'f': i|=SDL_FULLSCREEN; break;
    case 'h': i|=SDL_HWSURFACE; break;
    case 'n': i|=SDL_NOFRAME; break;
    case 'p': i|=SDL_HWPALETTE; break;
    case 'r': i|=SDL_RESIZABLE; break;
    case 'y': i|=SDL_ASYNCBLIT; break;
  }
  if(!(i&SDL_HWSURFACE)) i|=SDL_SWSURFACE;
  screen=SDL_SetVideoMode(w,h,8,i);
  if(!screen) fatal("Failed to initialize screen mode: %s\n",SDL_GetError());
}