Free Hero Mesh

Check-in [1e022e6c6d]
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:Complete the implementation of the dependent picture editor.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1e022e6c6d4743dd37d7beb0357bb37a2e1c3457
User & Date: user on 2021-04-14 02:58:56
Other Links: manifest | tags
Context
2021-04-14
21:41
Improve the information about requirements for compiling Free Hero Mesh. check-in: 84f3f11f61 user: user tags: trunk
02:58
Complete the implementation of the dependent picture editor. check-in: 1e022e6c6d user: user tags: trunk
2021-04-13
23:36
Start to implement the dependent picture editor; currently, colour filters and shift filters cannot be edited yet. check-in: a5c2814f64 user: user tags: trunk
Changes

Modified picedit.c from [3926c90496] to [9f72395624].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  Uint8 size[32];
  Uint8 nshift;
} ShiftFilter;

typedef struct {
  Uint8 code;
  // 0-7 = flip/rotations
  // 8-10 = change colours (8 is *->* *->* *->*; 9 is \->*->*->*->/; 10 is *<->* *<->* *<->*)
  // 11 = overlay
  // 12-15 = shift (up, down, right, left)
  union {
    ColorFilter color;
    OverlayFilter overlay;
    ShiftFilter shift;
  };







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  Uint8 size[32];
  Uint8 nshift;
} ShiftFilter;

typedef struct {
  Uint8 code;
  // 0-7 = flip/rotations
  // 8-10 = change colours (8 is *->* *->* *->*; 9 is *->*->*->*->*; 10 is *<->* *<->* *<->*)
  // 11 = overlay
  // 12-15 = shift (up, down, right, left)
  union {
    ColorFilter color;
    OverlayFilter overlay;
    ShiftFilter shift;
  };
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    j=pict[i]->size;
    if(pict[i]->meth==15) fread(pict[i]->data+j,j,j,fp),pict[i]->meth=0; else uncompress_picture(fp,pict[i]);
    if(pict[i]->meth) load_rotate(pict[i]);
  }
  fclose(fp);
}

static inline void show_cursor_xy(int x,int y,int xx,int yy) {
  char buf[64];
  if(x>=0 && xx>=0) snprintf(buf,64,"[%d,%d]:(%d,%d) %+d%+d%63s",xx,yy,x,y,x-xx,y-yy,"");
  else if(x>=0) snprintf(buf,64,"(%d,%d)%63s",x,y,"");
  else if(xx>=0) snprintf(buf,64,"[%d,%d]%63s",xx,yy,"");
  else snprintf(buf,64,"%63s","");
  SDL_LockSurface(screen);
  draw_text(0,32,buf,0xF0,0xF9);
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
}







|

|
|







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    j=pict[i]->size;
    if(pict[i]->meth==15) fread(pict[i]->data+j,j,j,fp),pict[i]->meth=0; else uncompress_picture(fp,pict[i]);
    if(pict[i]->meth) load_rotate(pict[i]);
  }
  fclose(fp);
}

static inline void show_cursor_xy(int x,int y,int xx,int yy,const Picture*p) {
  char buf[64];
  if(x>=0 && xx>=0) snprintf(buf,64,"[%d,%d]:(%d,%d)=%d %+d%+d%63s",xx,yy,x,y,p->data[(y+1)*p->size+x],x-xx,y-yy,"");
  else if(x>=0) snprintf(buf,64,"(%d,%d)=%d%63s",x,y,p->data[(y+1)*p->size+x],"");
  else if(xx>=0) snprintf(buf,64,"[%d,%d]%63s",xx,yy,"");
  else snprintf(buf,64,"%63s","");
  SDL_LockSurface(screen);
  draw_text(0,32,buf,0xF0,0xF9);
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
}
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
          set_cursor(XC_tcross);
          if(ev.motion.state && !t) {
            if(ev.motion.state&SDL_BUTTON(2)) break;
            pict[sel]->data[(y+1)*pict[sel]->size+x]=(ev.motion.state&SDL_BUTTON(1)?cc:0);
            goto redraw;
          }
        }
        show_cursor_xy(x,y,xx,yy);
        break;
      case SDL_MOUSEBUTTONDOWN:
        if(ev.button.x>=screen->w-161 && ev.button.x<screen->w-1 && ev.button.y>=40 && ev.button.y<200) {
          x=(ev.button.x+161-screen->w)/10;
          y=(ev.button.y-40)/10;
          i=y*16+x;
          pick:







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
          set_cursor(XC_tcross);
          if(ev.motion.state && !t) {
            if(ev.motion.state&SDL_BUTTON(2)) break;
            pict[sel]->data[(y+1)*pict[sel]->size+x]=(ev.motion.state&SDL_BUTTON(1)?cc:0);
            goto redraw;
          }
        }
        show_cursor_xy(x,y,xx,yy,pict[sel]);
        break;
      case SDL_MOUSEBUTTONDOWN:
        if(ev.button.x>=screen->w-161 && ev.button.x<screen->w-1 && ev.button.y>=40 && ev.button.y<200) {
          x=(ev.button.x+161-screen->w)/10;
          y=(ev.button.y-40)/10;
          i=y*16+x;
          pick:
1016
1017
1018
1019
1020
1021
1022



1023


1024
1025


1026
1027






1028
1029
1030
1031
1032
1033






















1034
1035





1036
1037
1038
1039
1040
1041
1042
1043
1044




1045
1046
1047
1048
1049







1050
1051
1052
1053
1054
1055
1056











1057















1058
1059
1060
1061
1062
1063
1064
  dp->filters[c].code=f;
  return 1;
}

static void edit_color_filter(ColorFilter*f) {
  SDL_Rect r;
  SDL_Event ev;



  redraw:


  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_LockSurface(screen);


  SDL_FillRect(screen,&r,0xF0);
  //TODO






  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
  while(SDL_WaitEvent(&ev)) switch(ev.type) {
    case SDL_QUIT: exit(0); return;
    case SDL_KEYDOWN:
      switch(ev.key.keysym.sym) {






















        case SDLK_ESCAPE: return;
        //TODO





      }
      goto redraw;
    case SDL_VIDEOEXPOSE: goto redraw;
  }
}

static void edit_shift_filter(ShiftFilter*f) {
  SDL_Rect r;
  SDL_Event ev;




  redraw:
  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_LockSurface(screen);
  SDL_FillRect(screen,&r,0xF0);
  //TODO







  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
  while(SDL_WaitEvent(&ev)) switch(ev.type) {
    case SDL_QUIT: exit(0); return;
    case SDL_KEYDOWN:
      switch(ev.key.keysym.sym) {
        case SDLK_ESCAPE: return;











        //TODO















      }
      goto redraw;
    case SDL_VIDEOEXPOSE: goto redraw;
  }
}

static void edit_dependent_picture(DependentPicture*dp,const char*name) {







>
>
>

>
>

|
>
>
|
<
>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>









>
>
>
>




|
>
>
>
>
>
>
>







>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
  dp->filters[c].code=f;
  return 1;
}

static void edit_color_filter(ColorFilter*f) {
  SDL_Rect r;
  SDL_Event ev;
  char buf[8];
  int i;
  Uint8 c=0;
  redraw:
  if(c>=f->ncolors) c=0;
  SDL_LockSurface(screen);
  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_FillRect(screen,&r,0xF0);
  if(c<f->ncolors) {
    r.w=12;
    SDL_FillRect(screen,&r,f->colors[c]);

  }
  draw_text(16,0,"<ESC> Exit  <\x18\x19\x1A\x1B> Cursor  <-/+> Adjust  <INS> Append  <DEL> Delete",0xF0,0xFB);
  for(i=0;i<f->ncolors;i++) {
    snprintf(buf,8,"%c%3d%c",c==i?'<':' ',f->colors[i],c==i?'>':' ');
    draw_text((i&1)*50+20,((i&~1)<<2)+12,buf,0xF0,c==i?0xFF:0xF7);
  }
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
  while(SDL_WaitEvent(&ev)) switch(ev.type) {
    case SDL_QUIT: exit(0); return;
    case SDL_KEYDOWN:
      switch(ev.key.keysym.sym) {
        case SDLK_ESCAPE: case SDLK_RETURN: case SDLK_KP_ENTER: return;
        case SDLK_LEFT: case SDLK_KP4: case SDLK_h: c--; break;
        case SDLK_RIGHT: case SDLK_KP6: case SDLK_l: case SDLK_TAB: c++; break;
        case SDLK_UP: case SDLK_KP8: case SDLK_k: c-=2; break;
        case SDLK_DOWN: case SDLK_KP2: case SDLK_j: c+=2; break;
        case SDLK_HOME: case SDLK_KP7: c=0; break;
        case SDLK_END: case SDLK_KP1: c=f->ncolors-1; break;
        case SDLK_INSERT: case SDLK_KP0:
          if(f->ncolors==64) break;
          f->colors[c=f->ncolors++]=0;
          break;
        case SDLK_DELETE: case SDLK_KP_PERIOD:
          if(!f->ncolors) break;
          f->ncolors--;
          c=f->ncolors-1;
          break;
        case SDLK_KP_PLUS: case SDLK_PLUS: case SDLK_EQUALS:
          f->colors[c]+=ev.key.keysym.mod&KMOD_SHIFT?16:1;
          break;
        case SDLK_KP_MINUS: case SDLK_MINUS: case SDLK_UNDERSCORE:
          f->colors[c]-=ev.key.keysym.mod&KMOD_SHIFT?16:1;
          break;
        case SDLK_SPACE:

          f->colors[c]=0;
          break;
        case SDLK_0 ... SDLK_9:
          f->colors[c]=10*f->colors[c]+ev.key.keysym.sym-SDLK_0;
          break;
      }
      goto redraw;
    case SDL_VIDEOEXPOSE: goto redraw;
  }
}

static void edit_shift_filter(ShiftFilter*f) {
  SDL_Rect r;
  SDL_Event ev;
  const char*s;
  char buf[32];
  int i;
  Uint8 c=0;
  redraw:
  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_LockSurface(screen);
  SDL_FillRect(screen,&r,0xF0);
  draw_text(0,0,"<ESC> Exit  <\x18/\x19> Cursor  <SP> Edit  <INS> Insert  <DEL> Delete",0xF0,0xFB);
  if(c>f->nshift+1) c=f->nshift+1;
  for(i=0;i<f->nshift;i++) {
    snprintf(buf,32,"%c %d: %d",c==i?0x1A:0xFA,f->size[i],f->shift[i]);
    draw_text(4,(i+2)<<3,buf,0xF0,c==i?0xFF:0xF7);
  }
  snprintf(buf,32,"%c <End>",c==i?0x1A:0xFA);
  draw_text(4,(i+2)<<3,buf,0xF0,c==i?0xFF:0xF7);
  SDL_UnlockSurface(screen);
  SDL_Flip(screen);
  while(SDL_WaitEvent(&ev)) switch(ev.type) {
    case SDL_QUIT: exit(0); return;
    case SDL_KEYDOWN:
      switch(ev.key.keysym.sym) {
        case SDLK_ESCAPE: return;
        case SDLK_HOME: case SDLK_KP7: c=0; break;
        case SDLK_END: case SDLK_KP1: c=f->nshift; break;
        case SDLK_UP: case SDLK_KP8: case SDLK_k: c--; break;
        case SDLK_DOWN: case SDLK_KP2: case SDLK_j: c++; break;
        case SDLK_INSERT: case SDLK_KP0:
          if(f->nshift==64) break;
          if(c<f->nshift) {
            memmove(f->shift+c+1,f->shift+c,63-c);
            memmove(f->size+c+1,f->size+c,63-c);
          }
          f->nshift++;
          //fallthru
        case SDLK_SPACE:
          if(c>=f->nshift) break;
          if((s=screen_prompt("Size?")) && (i=strtol(s,0,10)) && (s=screen_prompt("Shift?")) && *s) {
            f->size[c]=i;
            f->shift[c]=strtol(s,0,10)&127;
          }
          break;
        case SDLK_DELETE: case SDLK_KP_PERIOD:
          if(c>=f->nshift) break;
          if(c<f->nshift-1) {
            memmove(f->shift+c,f->shift+c+1,63-c);
            memmove(f->size+c,f->size+c+1,63-c);
          }
          f->nshift--;
          break;
      }
      goto redraw;
    case SDL_VIDEOEXPOSE: goto redraw;
  }
}

static void edit_dependent_picture(DependentPicture*dp,const char*name) {
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
  set_cursor(XC_arrow);
  redraw:
  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_LockSurface(screen);
  SDL_FillRect(screen,&r,0xF0);
  draw_text(0,0,"Dependent Image:",0xF0,0xF7);
  draw_text(136,0,name,0xF0,0xF5);
  draw_text(0,8,"<ESC> Exit  <\x18/\x19> Cursor  <SP> Edit  <INS> Append  <DEL> Delete",0xF0,0xFB);
  draw_text(0,16,c<0?"\x1A":"\xFA",0xF0,c<0?0xFA:0xF2);
  draw_text(16,16,"Base:",0xF0,0xF7);
  draw_text(64,16,dp->basename,0xF0,0xFE);
  for(i=0,y=24;i<dp->nfilters;i++) {
    draw_text(0,y,c==i?"\x1A":"\xFA",0xF0,c==i?0xFA:0xF2);
    switch(j=dp->filters[i].code) {
      case 0 ... 7:







|







1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
  set_cursor(XC_arrow);
  redraw:
  r.x=r.y=0; r.w=screen->w; r.h=screen->h;
  SDL_LockSurface(screen);
  SDL_FillRect(screen,&r,0xF0);
  draw_text(0,0,"Dependent Image:",0xF0,0xF7);
  draw_text(136,0,name,0xF0,0xF5);
  draw_text(0,8,"<ESC> Exit  <\x18/\x19> Cursor  <SP> Edit  <INS> Insert  <DEL> Delete",0xF0,0xFB);
  draw_text(0,16,c<0?"\x1A":"\xFA",0xF0,c<0?0xFA:0xF2);
  draw_text(16,16,"Base:",0xF0,0xF7);
  draw_text(64,16,dp->basename,0xF0,0xFE);
  for(i=0,y=24;i<dp->nfilters;i++) {
    draw_text(0,y,c==i?"\x1A":"\xFA",0xF0,c==i?0xFA:0xF2);
    switch(j=dp->filters[i].code) {
      case 0 ... 7:

Modified picedit.doc from [fdf1601d98] to [861f280ac9].

169
170
171
172
173
174
175


176





















177
Filled ellipse (S)
  Click the left button on one corner of the bounding rectangle of the
  ellipse, and then click the middle or right button on the other side.


=== Dependent pictures ===



(Not implemented yet.)





























>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
Filled ellipse (S)
  Click the left button on one corner of the bounding rectangle of the
  ellipse, and then click the middle or right button on the other side.


=== Dependent pictures ===

A depedent picture depends on one or more independent pictures. It
consists of any combination of the following items, in any order:

* Base: This one must come first, and is the independent picture which
will be used as the base; all other filters are applied to alter it.

* Flip/rotation: Flip/rotate the picture. "Identity" also belongs to this
category, but ahs no effect.

* Replace colors: A list of pairs of colours. The first of each pair is
the old colour, and next the colour to replace it with.

* Advance colours: A list of colours; change each colour mentioned in the
list into the next colour in the list after that one.

* Exchange colours: A list of pairs of colours; each colour is changed to
the other colour in the pair.

* Overlay: Paste the specified independent picture over the current
picture, showing through wherever it is transparent.

* Shift: Shift the picture. Specify the sizes and shift amounts in the
format "size: shift"; each size also affects all multiples of that size,
in which case the shift amoutn is also multiplied by the same amount.