home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / graphics / conversion / makepcx / source / c / pcxwimp < prev   
Encoding:
Text File  |  1991-12-08  |  17.1 KB  |  738 lines

  1. /*******************************************************************************
  2.  
  3. c.pcxwimp
  4.  
  5.     
  6. WIMP front-end to MAKEPCX routine
  7.  
  8. (c) Daniel Pead, 1991
  9.  
  10. This software may be freely copied.
  11.  
  12. $Header$
  13.  
  14. $Log$
  15.  
  16. *******************************************************************************/
  17.  
  18. #include "wimp.h"
  19. #include "wimpt.h"
  20. #include "win.h"
  21. #include "event.h"
  22. #include "baricon.h"
  23. #include "res.h"
  24. #include "resspr.h"
  25. #include "menu.h"
  26. #include "template.h"
  27. #include "dbox.h"
  28. #include "werr.h"
  29. #include "flex.h"
  30. #include "heap.h"
  31. #include "trace.h"
  32. #include "xferrecv.h"
  33. #include "xfersend.h"
  34. #include "saveas.h"
  35. #include "colourtran.h"
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include "h.makepcx"
  39. #include "bbc.h"
  40.  
  41. #define ICN_DUMMY    0 
  42. #define ICN_SPNAME    1
  43. #define ICN_UP        2
  44. #define ICN_DOWN    3
  45. #define    ICN_NUMBER    4
  46. #define ICN_MAXNO    5
  47. #define ICN_PVIEW    6
  48. #define ICN_CONV    7
  49. #define ICN_SPAL    8    /* Palette option icons must ... */
  50. #define ICN_DPAL    9 
  51. #define ICN_RPAL    10 
  52. #define ICN_APAL    11  /* ... be between here, in sequence */
  53.  
  54.  
  55. #define ICN_VER     4
  56.  
  57. #define MEN_INFO    1
  58. #define MEN_QUIT    2
  59.  
  60. #define MAX_OPEN     4
  61.  
  62.  
  63. /* Palette option codes */
  64.  
  65. #define DEFAULT_PAL 1    /* Default for sprites withour palette */
  66. #define PAL_SPRITE    0    /* Use sprite's own palette     */
  67. #define PAL_DESK    1    /* Use desktop palette             */
  68. #define PAL_RGB        2    /* Use 8-colour RGB palette     */
  69. #define PAL_A256    3    /* Use Acorn 256 colour palette */        
  70. #define PAL_MAX        4
  71.  
  72. /* Details of the "Preview" sprite - a scaled version of the current sprite */
  73.  
  74. #define PV_SP_SIZE 5120
  75. #define PV_SP_W 176
  76. #define PV_SP_H 53
  77.  
  78. /* The icon bar menu */
  79.  
  80. static menu bar_menu;
  81.  
  82.  
  83. /* Structure holding the details of one instance of a MakePCX window */
  84.     
  85. typedef struct {
  86.     dbox pcx_dbox;
  87.     wimp_w pcx_dbox_handle;
  88.     sprite_area * sp_area_p;    /* Pointer to sprite area */
  89.     sprite_ptr    sp_p;            /* Pointer to sprite      */
  90.     int sp_number;                /* Sprite number           */
  91.     int sp_attrib;                /* Bits per pixel. if bit 8 set- has pallette */
  92.     int palette;                /* Palette options          */
  93.     union {
  94.         char d[5120];
  95.         sprite_area sa;
  96.     } preview_sp;    
  97.     char sprite_filename[PV_SP_SIZE];
  98. } inst_t;
  99.  
  100. /* Standard error pointer type */
  101.  
  102. os_error * oserr_p;
  103.  
  104. /* The "About this program" dialogue box */
  105.  
  106. dbox info_dbox;
  107.  
  108. /* Version string */
  109.  
  110. char version[] = "Version 0.20";
  111.  
  112. /* Prototypes... */
  113.  
  114. static void remove_inst(inst_t * inst_p );
  115. static int makepcx_init(void);
  116. BOOL pcx_save ( char * filename, void * handle );
  117. static void bar_icon_event ( wimp_i icon );
  118. static void bar_menu_event ( void * handle, char * item );
  119. static void bar_load_event ( wimp_eventstr * event, void *handle );
  120. static void pcx_dbox_event ( dbox d, void * handle );
  121. static BOOL pcx_dbox_raw_event ( dbox d, wimp_eventstr * event,void * handle );
  122. void load_sprite_file(void);
  123. static void new_sprite_selected(inst_t * insp_p, sprite_ptr new_sp_p, int number);
  124. void set_palette_options(inst_t * inst_p);
  125. void get_palette_options(inst_t * inst_p);
  126.  
  127. /*******************************************************************************
  128.  
  129.     Main WIMP polling loop
  130.  
  131. *******************************************************************************/
  132.  
  133.  
  134. int main()
  135. {
  136.     if ( makepcx_init() )
  137.         while (1) event_process();
  138.     return 0;
  139. }
  140.  
  141. /*******************************************************************************
  142.  
  143.     Error actions for RISC-OS, CLIB and program errors respectively
  144.  
  145. *******************************************************************************/
  146.  
  147. void do_os_error ( os_error * oserr)
  148. {
  149.     wimpt_noerr(oserr);
  150. }
  151.  
  152. void do_c_error ( int c_err )
  153. {
  154.     werr ( TRUE, "CLIB Error %x : %s\n", c_err, strerror(c_err) );
  155. }
  156.  
  157. void do_error ( char * string, int param )
  158. {
  159.     werr( TRUE, string, param );
  160. }
  161.  
  162.  
  163. /*******************************************************************************
  164.  
  165.     Initialise the application - setup the WIMP etc
  166.  
  167. *******************************************************************************/
  168.  
  169. int makepcx_init(void)
  170. {
  171.     
  172.     wimpt_init("MakePCX");
  173.     flex_init();
  174.     heap_init(TRUE);
  175.     res_init("MakePCX");
  176.     resspr_init();
  177.     template_init();
  178.     dbox_init();
  179.  
  180.     /* Install application on icon bar */
  181.     
  182.     baricon( "!MakePCX", (int)resspr_area(), bar_icon_event );
  183.  
  184.     /* Catch file load events */
  185.  
  186.     win_register_event_handler ( win_ICONBARLOAD, bar_load_event, (void *) 42 );
  187.         
  188.     /* About program dialogue box */
  189.     
  190.     if ( !(info_dbox = dbox_new("ProgInfo")) ) return FALSE;
  191.  
  192.     dbox_setfield ( info_dbox, ICN_VER, version ); 
  193.  
  194.     /* Menu on icon bar */
  195.     
  196.     if ( !(bar_menu = menu_new("MakePCX",">Info,Quit")) ) return FALSE;
  197.  
  198.     if ( !event_attachmenu(win_ICONBAR, bar_menu, bar_menu_event, 0) )
  199.         return FALSE;
  200.  
  201.     return TRUE;
  202.  
  203. }
  204.  
  205.  
  206. /*******************************************************************************
  207.  
  208.     The usual WIMP event handlers
  209.  
  210. *******************************************************************************/
  211.  
  212. static void bar_icon_event ( wimp_i icon )
  213. {
  214.     icon=icon;
  215. }
  216.  
  217.     
  218. static void bar_menu_event ( void * handle, char * item )
  219. {
  220.     handle=handle;
  221.  
  222.     switch ( item[0] )
  223.     {
  224.         case MEN_INFO :
  225.             dbox_show(info_dbox);
  226.             (void) dbox_fillin(info_dbox);
  227.             dbox_hide(info_dbox);
  228.             break;
  229.             
  230.         case MEN_QUIT :
  231.             exit(0);
  232.         default:
  233.             break;
  234.     }
  235. }
  236.  
  237. static void bar_load_event ( wimp_eventstr * event, void *handle )
  238. {
  239.     handle = handle;
  240.  
  241.     tracef0(">>> Iconbar Load Event <<<");
  242.     
  243.     if ( !(event->e == wimp_ESEND || event->e == wimp_ESENDWANTACK) ) return;
  244.  
  245.     switch ( event->data.msg.hdr.action )
  246.     {
  247.         case wimp_MDATASAVE :
  248.             tracef0(">>> DATASAVE <<<");
  249.             strcpy(event->data.msg.data.datasaveok.name,"<Wimp$Scrap>");
  250.             event->data.msg.data.datasaveok.estsize = -1;
  251.             event->data.msg.hdr.my_ref=event->data.msg.hdr.your_ref;
  252.             event->data.msg.hdr.size=sizeof(wimp_msgstr);
  253.             event->data.msg.hdr.action = wimp_MDATASAVEOK;
  254.             wimp_sendmessage ( wimp_MDATASAVEOK, &event->data.msg,
  255.                 event->data.msg.hdr.task );
  256.             break;
  257.  
  258.         case wimp_MDATALOAD:
  259.             tracef0(">>> DATALOAD <<<");
  260.             load_sprite_file();
  261.             break;
  262.     }
  263. }
  264.             
  265.                 
  266.  
  267. static void pcx_dbox_event ( dbox d, void * handle )
  268. {
  269.     inst_t * inst_p;
  270.     dbox_field field;
  271.  
  272.     inst_p = (inst_t * ) handle;
  273.     
  274.     field = dbox_get ( d );
  275.  
  276.     switch ( field )
  277.     {
  278.         case ICN_CONV:
  279.             saveas ( PCX_TYPE, sp_h(inst_p->sp_p).name, 0, pcx_save,
  280.                     NULL, NULL, (void *) inst_p );
  281.             break;
  282.  
  283.         case ICN_UP:
  284.             if ( inst_p->sp_number < inst_p->sp_area_p->number )
  285.             {
  286.                 inst_p->sp_number++;
  287.                 inst_p->sp_p = sprite_find ( inst_p->sp_area_p, inst_p->sp_number, NULL, NULL );
  288.                 new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
  289.             }
  290.             break;
  291.  
  292.         case ICN_DOWN:
  293.             if ( inst_p->sp_number > 1 )
  294.             {
  295.                 inst_p->sp_number--;
  296.                 inst_p->sp_p = sprite_find ( inst_p->sp_area_p, inst_p->sp_number, NULL, NULL );
  297.                 new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
  298.             }
  299.             break;
  300.  
  301.         case dbox_CLOSE:
  302.             remove_inst(inst_p);
  303.             break;
  304.             
  305.         default: break;
  306.     }
  307. }
  308.  
  309. /*******************************************************************************
  310.  
  311.     This is to detect changes to the sprite name/number editable fields which
  312.     would not normally cause an action.                                    
  313.  
  314. *******************************************************************************/
  315.  
  316. static BOOL pcx_dbox_raw_event ( dbox d, wimp_eventstr * event, void * handle )
  317. {
  318.     inst_t * inst_p;
  319.     sprite_ptr new_sp_p;
  320.     int new_sp_n;
  321.     char new_name[16];
  322.     wimp_i icon = 0;
  323.     int press = 0;
  324.  
  325.     inst_p = (inst_t *) handle;
  326.     d = d;
  327.  
  328.     /* Check for mouse click and return pressed */
  329.     /* & decide which icon it happened for  */
  330.     
  331.     switch ( event -> e )
  332.     {
  333.         case wimp_EKEY :
  334.             icon = event->data.key.c.i;
  335.             press = ( event->data.key.chcode == 13 );
  336.             break;
  337.  
  338.         case wimp_EBUT :
  339.             icon = event->data.but.m.i;
  340.             press = ( event->data.but.b & (wimp_BCLICKLEFT | wimp_BCLICKRIGHT) );
  341.             break;
  342.  
  343.         default : press = 0;
  344.     }
  345.  
  346.     if ( !press ) return FALSE; /* Nothing to do here */
  347.  
  348.     switch ( icon )
  349.     {
  350.         case ICN_SPNAME:
  351.             dbox_getfield ( inst_p->pcx_dbox, ICN_SPNAME, new_name, 16 );
  352.             new_sp_p = sprite_find ( inst_p->sp_area_p, 0, new_name, & new_sp_n );
  353.             if ( !new_sp_p )
  354.                 /* Not found - Quick way of re-setting dbox */
  355.                 new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number); 
  356.             else
  357.                 /* Re-set dialogue box */
  358.                 new_sprite_selected(inst_p, new_sp_p, new_sp_n);                             
  359.  
  360.  
  361.             break;        
  362.  
  363.         case ICN_NUMBER:
  364.             new_sp_n = dbox_getnumeric ( inst_p->pcx_dbox, ICN_NUMBER );
  365.             new_sp_p = sprite_find ( inst_p->sp_area_p, new_sp_n, NULL, NULL );
  366.             if ( !new_sp_p )
  367.                 /* Not found - Quick way of re-setting dbox */
  368.                 new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number); 
  369.             else
  370.                 /* Re-set dialogue box */
  371.                 new_sprite_selected(inst_p, new_sp_p, new_sp_n); 
  372.  
  373.             break;
  374.  
  375.         default : return FALSE;
  376.     }
  377.     return FALSE; 
  378. }    
  379.  
  380. /*******************************************************************************
  381.  
  382.     Extract the palette options from the dialogue box
  383.  
  384. *******************************************************************************/
  385.  
  386. void get_palette_options(inst_t * inst_p)
  387. {
  388.     int i;
  389.  
  390.     inst_p->palette = 0;
  391.  
  392.     for ( i = 0; i < PAL_MAX; i++ )
  393.         if ( dbox_getnumeric ( inst_p->pcx_dbox, ICN_SPAL+i ) )
  394.             inst_p->palette = i;
  395. }
  396.  
  397. /*******************************************************************************
  398.  
  399.     Set up the available & default palette options in the dialogue box
  400.  
  401. *******************************************************************************/
  402.     
  403. void set_palette_options(inst_t * inst_p)
  404. {
  405.     int i;
  406.  
  407.     int pal, bpp;
  408.  
  409.     char enable[PAL_MAX];
  410.     
  411.     pal = inst_p->sp_attrib & 0x100;
  412.     bpp = inst_p->sp_attrib & 0x0ff;
  413.  
  414.     if ( bpp > 4 )
  415.     {
  416.         
  417.         for ( i=0; i<PAL_MAX; enable[i++]=0 );
  418.  
  419.         inst_p->palette = PAL_A256;
  420.     }
  421.     else
  422.     {
  423.         for ( i=0; i<PAL_MAX; enable[i++]=1 );
  424.         
  425.         /* Disable 256 colour option */
  426.  
  427.         enable[PAL_A256] = 0;
  428.         if ( inst_p->palette == PAL_A256 ) inst_p->palette = PAL_SPRITE; 
  429.         
  430.         if (!pal)
  431.         {
  432.             if (inst_p->palette == PAL_SPRITE) inst_p->palette = DEFAULT_PAL;
  433.             enable[PAL_SPRITE] = 0;
  434.         }
  435.     }    
  436.  
  437.     for ( i = 0; i < PAL_MAX; i++ )
  438.     {
  439.         if ( enable[i] )
  440.             dbox_unfadefield ( inst_p->pcx_dbox, ICN_SPAL+i );
  441.         else
  442.             dbox_fadefield ( inst_p->pcx_dbox, ICN_SPAL+i );
  443.  
  444.         dbox_setnumeric ( inst_p->pcx_dbox, ICN_SPAL + i, i == inst_p->palette );
  445.     }
  446. }
  447.  
  448. /*******************************************************************************
  449.  
  450.     Load in a sprite file
  451.  
  452. *******************************************************************************/
  453.     
  454. void load_sprite_file()
  455. {
  456.     char * filename;
  457.     int filetype;
  458.     int sp_area_len;
  459.     char buffer[256];
  460.     inst_t * inst_p;
  461.     int sprites_loaded;
  462.     
  463.     sprites_loaded = FALSE;
  464.  
  465.     /* Create a data structure for this file */
  466.  
  467.     inst_p = (inst_t *) heap_alloc(sizeof(inst_t));
  468.  
  469.     if ( !inst_p )
  470.     {
  471.         do_error ( "No room for sprite file!", 0 );
  472.         return;
  473.     }
  474.  
  475.     memset ( inst_p, 0, sizeof(inst_t) );
  476.  
  477.     /* Create the preview sprite */
  478.     
  479.     sprite_area_initialise ( &(inst_p->preview_sp.sa), PV_SP_SIZE );
  480.  
  481.     wimpt_noerr( sprite_create( &(inst_p->preview_sp.sa), "preview", 0, PV_SP_W, PV_SP_H, 12) );
  482.     
  483.     /* Produce a new converter dialogue box */
  484.     
  485.     if ( !(inst_p->pcx_dbox = dbox_new("pcx_dbox")) )
  486.     {
  487.         remove_inst(inst_p);
  488.         return;
  489.     }
  490.  
  491.     /* Assign handler - handle is pointer to the data structure */
  492.     
  493.     dbox_eventhandler ( inst_p->pcx_dbox, pcx_dbox_event, (void *) inst_p );
  494.     dbox_raw_eventhandler ( inst_p->pcx_dbox,
  495.         (dbox_raw_handler_proc) pcx_dbox_raw_event, (void *) inst_p );
  496.  
  497.     inst_p->pcx_dbox_handle = dbox_syshandle ( inst_p->pcx_dbox );
  498.  
  499.     /* Now proceed with load operation */
  500.     
  501.     filetype = xferrecv_checkinsert(&filename);
  502.  
  503.     tracef2(">>> Loading %s type %x <<<\n",(int) filename, filetype);
  504.     
  505.     if ( filetype != 0xFF9 )
  506.         werr ( 0, "Only RISC_OS Sprite Files, please!");
  507.     else
  508.     {
  509.          
  510.         filetype = finfo ( filename, &sp_area_len );
  511.         sp_area_len+=4;
  512.  
  513.         /* Allocate memory for sprite file */
  514.  
  515.         inst_p->sp_area_p = (sprite_area *) heap_alloc ( sp_area_len );
  516.  
  517.         if ( !inst_p->sp_area_p )
  518.             werr (0,"No room for sprites (need %d bytes)",sp_area_len);
  519.         else
  520.         {
  521.             sprite_area_initialise ( inst_p->sp_area_p, sp_area_len );
  522.  
  523.             /* Load in sprite file */
  524.     
  525.             if ( oserr_p = sprite_area_load ( inst_p->sp_area_p, filename ) )
  526.                 wimpt_complain(oserr_p);
  527.             else
  528.                 sprites_loaded = TRUE;
  529.  
  530.         }
  531.     }
  532.     xferrecv_insertfileok();
  533.  
  534.     
  535.     if (!sprites_loaded)
  536.         remove_inst ( inst_p );
  537.     else
  538.     {
  539.         inst_p->sp_number = 1;
  540.  
  541.         inst_p->sp_p = sprite_find ( inst_p->sp_area_p, 1, NULL, NULL );
  542.         if ( !inst_p->sp_p ) do_error ("Empty sprite file!\n",0);
  543.  
  544.         sprintf(buffer,"of %d",inst_p->sp_area_p->number);
  545.         dbox_setfield ( inst_p->pcx_dbox, ICN_MAXNO, buffer );
  546.  
  547.         strncpy ( inst_p->sprite_filename, filename, 255 );
  548.  
  549.         new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
  550.  
  551.         sprintf(buffer, "MakePCX: %28s",filename);
  552.         win_settitle ( inst_p->pcx_dbox_handle, buffer );
  553.         
  554.         dbox_showstatic ( inst_p->pcx_dbox );
  555.  
  556.     }
  557. }
  558.  
  559. /*******************************************************************************
  560.  
  561.     A new sprite has been selected from the file: update the dbox, change
  562.     the palette options, create the preview sprite etc.
  563.  
  564. *******************************************************************************/
  565.     
  566. static void new_sprite_selected(inst_t * inst_p,
  567.         sprite_ptr new_sp_p, int new_sp_n)
  568. {
  569.     wimp_icreate pv_icon_cr;
  570.     wimp_i i_created;
  571.     wimp_redrawstr redraw;
  572.     sprite_ptr pv_sp_p;
  573.     sprite_id pv_sp_id, sp_id;
  574.     sprite_factors scaling = { 1000,1000,1000,1000 };
  575.     sprite_pixtrans pixtrans[256];
  576.     wimp_paletteword source_pal[256];
  577.     wimp_palettestr dest_palstr;
  578.     wimp_paletteword * pal_p;
  579.     wimp_paletteword * spal_p;
  580.     sprite_info sp_info;
  581.     sprite_state state;
  582.         
  583.     /* Set pointers & numbers to new values */
  584.     
  585.     inst_p->sp_p = new_sp_p;
  586.     inst_p->sp_number = new_sp_n;
  587.  
  588.     /* Get bpp and palette attributes */
  589.  
  590.     inst_p->sp_attrib = get_bpp_and_pal ( inst_p->sp_area_p, new_sp_p );
  591.     
  592.     /* Need to twiddle the picture-preview icon */
  593.  
  594.     pv_sp_p = (sprite_ptr) (inst_p->preview_sp.d + inst_p->preview_sp.sa.sproff);
  595.     pv_sp_id.s.addr = pv_sp_p;
  596.     pv_sp_id.tag = sprite_id_addr;
  597.  
  598.     sp_id.s.addr = new_sp_p;
  599.     sp_id.tag = sprite_id_addr;
  600.     
  601.     /* Get size */
  602.     
  603.     wimpt_noerr ( sprite_readsize ( inst_p->sp_area_p, &sp_id, &sp_info ) );
  604.     
  605.     /* Get full, possibly 256 colour, pixtrans */
  606.     
  607.     /* First, munge palette into correct format */
  608.  
  609.     if ( sp_h(new_sp_p).image > sizeof(sprite_header) )
  610.     {
  611.         spal_p = source_pal; 
  612.         for ( pal_p = (wimp_paletteword *) (((char *)new_sp_p) + sizeof(sprite_header));
  613.               pal_p < (wimp_paletteword *) (((char *)new_sp_p) + sp_h(new_sp_p).image);
  614.               pal_p+=2
  615.         )
  616.             *spal_p++ = *pal_p;
  617.         spal_p = source_pal;
  618.     } else {
  619.         /* No source pal */
  620.         spal_p = NULL;
  621.     }
  622.  
  623.     /* Build the translation table */
  624.  
  625.     wimp_readpalette ( &dest_palstr );
  626.     
  627.     wimpt_noerr ( colourtran_select_table (
  628.         sp_h(new_sp_p).mode, spal_p,
  629.         12, dest_palstr.c, (void *)pixtrans
  630.     ));
  631.     
  632.     /* Now, scale the sprite to fit preview area */
  633.  
  634.     if ( sp_info.height > PV_SP_H )
  635.         scaling.ydiv = (sp_info.height*1000)/PV_SP_H;
  636.  
  637.     if ( sp_info.width > PV_SP_W )
  638.         scaling.xdiv = (sp_info.width*1000)/PV_SP_W;
  639.  
  640.     /* Preserve aspect ratio */
  641.  
  642.     if ( scaling.xdiv > scaling.ydiv )
  643.         scaling.ydiv = scaling.xdiv;
  644.     else
  645.         scaling.xdiv = scaling.ydiv;
  646.  
  647.     sp_info.height = (sp_info.height * scaling.ymag)/scaling.ydiv;
  648.     sp_info.width = (sp_info.width * scaling.xmag)/scaling.xdiv;
  649.     
  650.  
  651.     /* Now plot to the preview sprite */
  652.  
  653.  
  654.     sprite_outputtosprite ( &(inst_p->preview_sp.sa), &pv_sp_id, NULL, &state);
  655.  
  656.     bbc_clg();
  657.  
  658.     sprite_put_scaled ( inst_p->sp_area_p, &sp_id, 0,
  659.         (PV_SP_W - sp_info.width), (PV_SP_H-sp_info.height)*2,
  660.         &scaling, pixtrans);
  661.  
  662.     sprite_restorestate ( state );
  663.  
  664.     /* Now create icon in window using this sprite */    
  665.  
  666.     wimpt_noerr ( wimp_get_icon_info ( inst_p->pcx_dbox_handle, ICN_PVIEW, &pv_icon_cr.i) );
  667.  
  668.     wimpt_noerr ( wimp_delete_icon ( inst_p->pcx_dbox_handle, ICN_PVIEW) );
  669.  
  670.     pv_icon_cr.w = inst_p->pcx_dbox_handle;
  671.  
  672.     pv_icon_cr.i.flags = wimp_ISPRITE + wimp_IBORDER + wimp_IHCENTRE +
  673.             wimp_IVCENTRE + wimp_INDIRECT;
  674.     pv_icon_cr.i.data.indirectsprite.name = (char *) pv_sp_p;
  675.     pv_icon_cr.i.data.indirectsprite.spritearea = inst_p->preview_sp.d;
  676.     pv_icon_cr.i.data.indirectsprite.nameisname = FALSE;
  677.     
  678.     wimpt_noerr ( wimp_create_icon ( &pv_icon_cr, &i_created ) );
  679.  
  680.     /* Redraw icon area of window */
  681.  
  682.     redraw.w = inst_p->pcx_dbox_handle;
  683.     redraw.box = pv_icon_cr.i.box;
  684.  
  685.     wimpt_noerr ( wimp_force_redraw ( &redraw ) );
  686.  
  687.     dbox_setfield ( inst_p->pcx_dbox, ICN_SPNAME, sp_h(inst_p->sp_p).name );
  688.     dbox_setnumeric ( inst_p->pcx_dbox, ICN_NUMBER, new_sp_n );
  689.     
  690.     set_palette_options ( inst_p );
  691.     
  692. }
  693.  
  694. /*******************************************************************************
  695.  
  696.     Remove one sprite file & it's dialogue box
  697.  
  698. *******************************************************************************/
  699.  
  700. static void remove_inst(inst_t * inst_p)
  701. {
  702.     if ( inst_p->pcx_dbox_handle ) dbox_dispose ( &(inst_p->pcx_dbox) );
  703.     if ( inst_p->sp_area_p ) heap_free ( inst_p->sp_area_p );
  704.     heap_free ( inst_p );
  705. }
  706.  
  707. /*******************************************************************************
  708.  
  709.     Write a PCX file out to disc (this is where the conversion happens)
  710.  
  711. *******************************************************************************/
  712.     
  713. BOOL pcx_save ( char * filename, void * handle )
  714. {
  715.     inst_t * inst_p = ( inst_t * ) handle;
  716.     FILE * pcxfile;
  717.  
  718.     /* Set up palette defaults */
  719.  
  720.     get_palette_options(inst_p);
  721.     
  722.     default_pal_type = 1;
  723.     if ( inst_p->palette == 2 ) default_pal_type = 0;
  724.  
  725.     if ( inst_p->palette ) force_pal = TRUE; else force_pal = FALSE;
  726.     
  727.     pcxfile = fopen ( filename, "wb" );
  728.  
  729.     if ( !pcxfile ) return FALSE;
  730.  
  731.     make_pcx ( inst_p->sp_area_p, inst_p->sp_p, pcxfile );
  732.  
  733.     fclose ( pcxfile );
  734.     settype ( filename, PCX_TYPE );
  735.  
  736.     return TRUE;
  737. }
  738.