home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
-
- c.pcxwimp
-
-
- WIMP front-end to MAKEPCX routine
-
- (c) Daniel Pead, 1991
-
- This software may be freely copied.
-
- $Header$
-
- $Log$
-
- *******************************************************************************/
-
- #include "wimp.h"
- #include "wimpt.h"
- #include "win.h"
- #include "event.h"
- #include "baricon.h"
- #include "res.h"
- #include "resspr.h"
- #include "menu.h"
- #include "template.h"
- #include "dbox.h"
- #include "werr.h"
- #include "flex.h"
- #include "heap.h"
- #include "trace.h"
- #include "xferrecv.h"
- #include "xfersend.h"
- #include "saveas.h"
- #include "colourtran.h"
- #include <stdlib.h>
- #include <string.h>
- #include "h.makepcx"
- #include "bbc.h"
-
- #define ICN_DUMMY 0
- #define ICN_SPNAME 1
- #define ICN_UP 2
- #define ICN_DOWN 3
- #define ICN_NUMBER 4
- #define ICN_MAXNO 5
- #define ICN_PVIEW 6
- #define ICN_CONV 7
- #define ICN_SPAL 8 /* Palette option icons must ... */
- #define ICN_DPAL 9
- #define ICN_RPAL 10
- #define ICN_APAL 11 /* ... be between here, in sequence */
-
-
- #define ICN_VER 4
-
- #define MEN_INFO 1
- #define MEN_QUIT 2
-
- #define MAX_OPEN 4
-
-
- /* Palette option codes */
-
- #define DEFAULT_PAL 1 /* Default for sprites withour palette */
- #define PAL_SPRITE 0 /* Use sprite's own palette */
- #define PAL_DESK 1 /* Use desktop palette */
- #define PAL_RGB 2 /* Use 8-colour RGB palette */
- #define PAL_A256 3 /* Use Acorn 256 colour palette */
- #define PAL_MAX 4
-
- /* Details of the "Preview" sprite - a scaled version of the current sprite */
-
- #define PV_SP_SIZE 5120
- #define PV_SP_W 176
- #define PV_SP_H 53
-
- /* The icon bar menu */
-
- static menu bar_menu;
-
-
- /* Structure holding the details of one instance of a MakePCX window */
-
- typedef struct {
- dbox pcx_dbox;
- wimp_w pcx_dbox_handle;
- sprite_area * sp_area_p; /* Pointer to sprite area */
- sprite_ptr sp_p; /* Pointer to sprite */
- int sp_number; /* Sprite number */
- int sp_attrib; /* Bits per pixel. if bit 8 set- has pallette */
- int palette; /* Palette options */
- union {
- char d[5120];
- sprite_area sa;
- } preview_sp;
- char sprite_filename[PV_SP_SIZE];
- } inst_t;
-
- /* Standard error pointer type */
-
- os_error * oserr_p;
-
- /* The "About this program" dialogue box */
-
- dbox info_dbox;
-
- /* Version string */
-
- char version[] = "Version 0.20";
-
- /* Prototypes... */
-
- static void remove_inst(inst_t * inst_p );
- static int makepcx_init(void);
- BOOL pcx_save ( char * filename, void * handle );
- static void bar_icon_event ( wimp_i icon );
- static void bar_menu_event ( void * handle, char * item );
- static void bar_load_event ( wimp_eventstr * event, void *handle );
- static void pcx_dbox_event ( dbox d, void * handle );
- static BOOL pcx_dbox_raw_event ( dbox d, wimp_eventstr * event,void * handle );
- void load_sprite_file(void);
- static void new_sprite_selected(inst_t * insp_p, sprite_ptr new_sp_p, int number);
- void set_palette_options(inst_t * inst_p);
- void get_palette_options(inst_t * inst_p);
-
- /*******************************************************************************
-
- Main WIMP polling loop
-
- *******************************************************************************/
-
-
- int main()
- {
- if ( makepcx_init() )
- while (1) event_process();
- return 0;
- }
-
- /*******************************************************************************
-
- Error actions for RISC-OS, CLIB and program errors respectively
-
- *******************************************************************************/
-
- void do_os_error ( os_error * oserr)
- {
- wimpt_noerr(oserr);
- }
-
- void do_c_error ( int c_err )
- {
- werr ( TRUE, "CLIB Error %x : %s\n", c_err, strerror(c_err) );
- }
-
- void do_error ( char * string, int param )
- {
- werr( TRUE, string, param );
- }
-
-
- /*******************************************************************************
-
- Initialise the application - setup the WIMP etc
-
- *******************************************************************************/
-
- int makepcx_init(void)
- {
-
- wimpt_init("MakePCX");
- flex_init();
- heap_init(TRUE);
- res_init("MakePCX");
- resspr_init();
- template_init();
- dbox_init();
-
- /* Install application on icon bar */
-
- baricon( "!MakePCX", (int)resspr_area(), bar_icon_event );
-
- /* Catch file load events */
-
- win_register_event_handler ( win_ICONBARLOAD, bar_load_event, (void *) 42 );
-
- /* About program dialogue box */
-
- if ( !(info_dbox = dbox_new("ProgInfo")) ) return FALSE;
-
- dbox_setfield ( info_dbox, ICN_VER, version );
-
- /* Menu on icon bar */
-
- if ( !(bar_menu = menu_new("MakePCX",">Info,Quit")) ) return FALSE;
-
- if ( !event_attachmenu(win_ICONBAR, bar_menu, bar_menu_event, 0) )
- return FALSE;
-
- return TRUE;
-
- }
-
-
- /*******************************************************************************
-
- The usual WIMP event handlers
-
- *******************************************************************************/
-
- static void bar_icon_event ( wimp_i icon )
- {
- icon=icon;
- }
-
-
- static void bar_menu_event ( void * handle, char * item )
- {
- handle=handle;
-
- switch ( item[0] )
- {
- case MEN_INFO :
- dbox_show(info_dbox);
- (void) dbox_fillin(info_dbox);
- dbox_hide(info_dbox);
- break;
-
- case MEN_QUIT :
- exit(0);
- default:
- break;
- }
- }
-
- static void bar_load_event ( wimp_eventstr * event, void *handle )
- {
- handle = handle;
-
- tracef0(">>> Iconbar Load Event <<<");
-
- if ( !(event->e == wimp_ESEND || event->e == wimp_ESENDWANTACK) ) return;
-
- switch ( event->data.msg.hdr.action )
- {
- case wimp_MDATASAVE :
- tracef0(">>> DATASAVE <<<");
- strcpy(event->data.msg.data.datasaveok.name,"<Wimp$Scrap>");
- event->data.msg.data.datasaveok.estsize = -1;
- event->data.msg.hdr.my_ref=event->data.msg.hdr.your_ref;
- event->data.msg.hdr.size=sizeof(wimp_msgstr);
- event->data.msg.hdr.action = wimp_MDATASAVEOK;
- wimp_sendmessage ( wimp_MDATASAVEOK, &event->data.msg,
- event->data.msg.hdr.task );
- break;
-
- case wimp_MDATALOAD:
- tracef0(">>> DATALOAD <<<");
- load_sprite_file();
- break;
- }
- }
-
-
-
- static void pcx_dbox_event ( dbox d, void * handle )
- {
- inst_t * inst_p;
- dbox_field field;
-
- inst_p = (inst_t * ) handle;
-
- field = dbox_get ( d );
-
- switch ( field )
- {
- case ICN_CONV:
- saveas ( PCX_TYPE, sp_h(inst_p->sp_p).name, 0, pcx_save,
- NULL, NULL, (void *) inst_p );
- break;
-
- case ICN_UP:
- if ( inst_p->sp_number < inst_p->sp_area_p->number )
- {
- inst_p->sp_number++;
- inst_p->sp_p = sprite_find ( inst_p->sp_area_p, inst_p->sp_number, NULL, NULL );
- new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
- }
- break;
-
- case ICN_DOWN:
- if ( inst_p->sp_number > 1 )
- {
- inst_p->sp_number--;
- inst_p->sp_p = sprite_find ( inst_p->sp_area_p, inst_p->sp_number, NULL, NULL );
- new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
- }
- break;
-
- case dbox_CLOSE:
- remove_inst(inst_p);
- break;
-
- default: break;
- }
- }
-
- /*******************************************************************************
-
- This is to detect changes to the sprite name/number editable fields which
- would not normally cause an action.
-
- *******************************************************************************/
-
- static BOOL pcx_dbox_raw_event ( dbox d, wimp_eventstr * event, void * handle )
- {
- inst_t * inst_p;
- sprite_ptr new_sp_p;
- int new_sp_n;
- char new_name[16];
- wimp_i icon = 0;
- int press = 0;
-
- inst_p = (inst_t *) handle;
- d = d;
-
- /* Check for mouse click and return pressed */
- /* & decide which icon it happened for */
-
- switch ( event -> e )
- {
- case wimp_EKEY :
- icon = event->data.key.c.i;
- press = ( event->data.key.chcode == 13 );
- break;
-
- case wimp_EBUT :
- icon = event->data.but.m.i;
- press = ( event->data.but.b & (wimp_BCLICKLEFT | wimp_BCLICKRIGHT) );
- break;
-
- default : press = 0;
- }
-
- if ( !press ) return FALSE; /* Nothing to do here */
-
- switch ( icon )
- {
- case ICN_SPNAME:
- dbox_getfield ( inst_p->pcx_dbox, ICN_SPNAME, new_name, 16 );
- new_sp_p = sprite_find ( inst_p->sp_area_p, 0, new_name, & new_sp_n );
- if ( !new_sp_p )
- /* Not found - Quick way of re-setting dbox */
- new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
- else
- /* Re-set dialogue box */
- new_sprite_selected(inst_p, new_sp_p, new_sp_n);
-
-
- break;
-
- case ICN_NUMBER:
- new_sp_n = dbox_getnumeric ( inst_p->pcx_dbox, ICN_NUMBER );
- new_sp_p = sprite_find ( inst_p->sp_area_p, new_sp_n, NULL, NULL );
- if ( !new_sp_p )
- /* Not found - Quick way of re-setting dbox */
- new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
- else
- /* Re-set dialogue box */
- new_sprite_selected(inst_p, new_sp_p, new_sp_n);
-
- break;
-
- default : return FALSE;
- }
- return FALSE;
- }
-
- /*******************************************************************************
-
- Extract the palette options from the dialogue box
-
- *******************************************************************************/
-
- void get_palette_options(inst_t * inst_p)
- {
- int i;
-
- inst_p->palette = 0;
-
- for ( i = 0; i < PAL_MAX; i++ )
- if ( dbox_getnumeric ( inst_p->pcx_dbox, ICN_SPAL+i ) )
- inst_p->palette = i;
- }
-
- /*******************************************************************************
-
- Set up the available & default palette options in the dialogue box
-
- *******************************************************************************/
-
- void set_palette_options(inst_t * inst_p)
- {
- int i;
-
- int pal, bpp;
-
- char enable[PAL_MAX];
-
- pal = inst_p->sp_attrib & 0x100;
- bpp = inst_p->sp_attrib & 0x0ff;
-
- if ( bpp > 4 )
- {
-
- for ( i=0; i<PAL_MAX; enable[i++]=0 );
-
- inst_p->palette = PAL_A256;
- }
- else
- {
- for ( i=0; i<PAL_MAX; enable[i++]=1 );
-
- /* Disable 256 colour option */
-
- enable[PAL_A256] = 0;
- if ( inst_p->palette == PAL_A256 ) inst_p->palette = PAL_SPRITE;
-
- if (!pal)
- {
- if (inst_p->palette == PAL_SPRITE) inst_p->palette = DEFAULT_PAL;
- enable[PAL_SPRITE] = 0;
- }
- }
-
- for ( i = 0; i < PAL_MAX; i++ )
- {
- if ( enable[i] )
- dbox_unfadefield ( inst_p->pcx_dbox, ICN_SPAL+i );
- else
- dbox_fadefield ( inst_p->pcx_dbox, ICN_SPAL+i );
-
- dbox_setnumeric ( inst_p->pcx_dbox, ICN_SPAL + i, i == inst_p->palette );
- }
- }
-
- /*******************************************************************************
-
- Load in a sprite file
-
- *******************************************************************************/
-
- void load_sprite_file()
- {
- char * filename;
- int filetype;
- int sp_area_len;
- char buffer[256];
- inst_t * inst_p;
- int sprites_loaded;
-
- sprites_loaded = FALSE;
-
- /* Create a data structure for this file */
-
- inst_p = (inst_t *) heap_alloc(sizeof(inst_t));
-
- if ( !inst_p )
- {
- do_error ( "No room for sprite file!", 0 );
- return;
- }
-
- memset ( inst_p, 0, sizeof(inst_t) );
-
- /* Create the preview sprite */
-
- sprite_area_initialise ( &(inst_p->preview_sp.sa), PV_SP_SIZE );
-
- wimpt_noerr( sprite_create( &(inst_p->preview_sp.sa), "preview", 0, PV_SP_W, PV_SP_H, 12) );
-
- /* Produce a new converter dialogue box */
-
- if ( !(inst_p->pcx_dbox = dbox_new("pcx_dbox")) )
- {
- remove_inst(inst_p);
- return;
- }
-
- /* Assign handler - handle is pointer to the data structure */
-
- dbox_eventhandler ( inst_p->pcx_dbox, pcx_dbox_event, (void *) inst_p );
- dbox_raw_eventhandler ( inst_p->pcx_dbox,
- (dbox_raw_handler_proc) pcx_dbox_raw_event, (void *) inst_p );
-
- inst_p->pcx_dbox_handle = dbox_syshandle ( inst_p->pcx_dbox );
-
- /* Now proceed with load operation */
-
- filetype = xferrecv_checkinsert(&filename);
-
- tracef2(">>> Loading %s type %x <<<\n",(int) filename, filetype);
-
- if ( filetype != 0xFF9 )
- werr ( 0, "Only RISC_OS Sprite Files, please!");
- else
- {
-
- filetype = finfo ( filename, &sp_area_len );
- sp_area_len+=4;
-
- /* Allocate memory for sprite file */
-
- inst_p->sp_area_p = (sprite_area *) heap_alloc ( sp_area_len );
-
- if ( !inst_p->sp_area_p )
- werr (0,"No room for sprites (need %d bytes)",sp_area_len);
- else
- {
- sprite_area_initialise ( inst_p->sp_area_p, sp_area_len );
-
- /* Load in sprite file */
-
- if ( oserr_p = sprite_area_load ( inst_p->sp_area_p, filename ) )
- wimpt_complain(oserr_p);
- else
- sprites_loaded = TRUE;
-
- }
- }
- xferrecv_insertfileok();
-
-
- if (!sprites_loaded)
- remove_inst ( inst_p );
- else
- {
- inst_p->sp_number = 1;
-
- inst_p->sp_p = sprite_find ( inst_p->sp_area_p, 1, NULL, NULL );
- if ( !inst_p->sp_p ) do_error ("Empty sprite file!\n",0);
-
- sprintf(buffer,"of %d",inst_p->sp_area_p->number);
- dbox_setfield ( inst_p->pcx_dbox, ICN_MAXNO, buffer );
-
- strncpy ( inst_p->sprite_filename, filename, 255 );
-
- new_sprite_selected(inst_p, inst_p->sp_p, inst_p->sp_number);
-
- sprintf(buffer, "MakePCX: %28s",filename);
- win_settitle ( inst_p->pcx_dbox_handle, buffer );
-
- dbox_showstatic ( inst_p->pcx_dbox );
-
- }
- }
-
- /*******************************************************************************
-
- A new sprite has been selected from the file: update the dbox, change
- the palette options, create the preview sprite etc.
-
- *******************************************************************************/
-
- static void new_sprite_selected(inst_t * inst_p,
- sprite_ptr new_sp_p, int new_sp_n)
- {
- wimp_icreate pv_icon_cr;
- wimp_i i_created;
- wimp_redrawstr redraw;
- sprite_ptr pv_sp_p;
- sprite_id pv_sp_id, sp_id;
- sprite_factors scaling = { 1000,1000,1000,1000 };
- sprite_pixtrans pixtrans[256];
- wimp_paletteword source_pal[256];
- wimp_palettestr dest_palstr;
- wimp_paletteword * pal_p;
- wimp_paletteword * spal_p;
- sprite_info sp_info;
- sprite_state state;
-
- /* Set pointers & numbers to new values */
-
- inst_p->sp_p = new_sp_p;
- inst_p->sp_number = new_sp_n;
-
- /* Get bpp and palette attributes */
-
- inst_p->sp_attrib = get_bpp_and_pal ( inst_p->sp_area_p, new_sp_p );
-
- /* Need to twiddle the picture-preview icon */
-
- pv_sp_p = (sprite_ptr) (inst_p->preview_sp.d + inst_p->preview_sp.sa.sproff);
- pv_sp_id.s.addr = pv_sp_p;
- pv_sp_id.tag = sprite_id_addr;
-
- sp_id.s.addr = new_sp_p;
- sp_id.tag = sprite_id_addr;
-
- /* Get size */
-
- wimpt_noerr ( sprite_readsize ( inst_p->sp_area_p, &sp_id, &sp_info ) );
-
- /* Get full, possibly 256 colour, pixtrans */
-
- /* First, munge palette into correct format */
-
- if ( sp_h(new_sp_p).image > sizeof(sprite_header) )
- {
- spal_p = source_pal;
- for ( pal_p = (wimp_paletteword *) (((char *)new_sp_p) + sizeof(sprite_header));
- pal_p < (wimp_paletteword *) (((char *)new_sp_p) + sp_h(new_sp_p).image);
- pal_p+=2
- )
- *spal_p++ = *pal_p;
- spal_p = source_pal;
- } else {
- /* No source pal */
- spal_p = NULL;
- }
-
- /* Build the translation table */
-
- wimp_readpalette ( &dest_palstr );
-
- wimpt_noerr ( colourtran_select_table (
- sp_h(new_sp_p).mode, spal_p,
- 12, dest_palstr.c, (void *)pixtrans
- ));
-
- /* Now, scale the sprite to fit preview area */
-
- if ( sp_info.height > PV_SP_H )
- scaling.ydiv = (sp_info.height*1000)/PV_SP_H;
-
- if ( sp_info.width > PV_SP_W )
- scaling.xdiv = (sp_info.width*1000)/PV_SP_W;
-
- /* Preserve aspect ratio */
-
- if ( scaling.xdiv > scaling.ydiv )
- scaling.ydiv = scaling.xdiv;
- else
- scaling.xdiv = scaling.ydiv;
-
- sp_info.height = (sp_info.height * scaling.ymag)/scaling.ydiv;
- sp_info.width = (sp_info.width * scaling.xmag)/scaling.xdiv;
-
-
- /* Now plot to the preview sprite */
-
-
- sprite_outputtosprite ( &(inst_p->preview_sp.sa), &pv_sp_id, NULL, &state);
-
- bbc_clg();
-
- sprite_put_scaled ( inst_p->sp_area_p, &sp_id, 0,
- (PV_SP_W - sp_info.width), (PV_SP_H-sp_info.height)*2,
- &scaling, pixtrans);
-
- sprite_restorestate ( state );
-
- /* Now create icon in window using this sprite */
-
- wimpt_noerr ( wimp_get_icon_info ( inst_p->pcx_dbox_handle, ICN_PVIEW, &pv_icon_cr.i) );
-
- wimpt_noerr ( wimp_delete_icon ( inst_p->pcx_dbox_handle, ICN_PVIEW) );
-
- pv_icon_cr.w = inst_p->pcx_dbox_handle;
-
- pv_icon_cr.i.flags = wimp_ISPRITE + wimp_IBORDER + wimp_IHCENTRE +
- wimp_IVCENTRE + wimp_INDIRECT;
- pv_icon_cr.i.data.indirectsprite.name = (char *) pv_sp_p;
- pv_icon_cr.i.data.indirectsprite.spritearea = inst_p->preview_sp.d;
- pv_icon_cr.i.data.indirectsprite.nameisname = FALSE;
-
- wimpt_noerr ( wimp_create_icon ( &pv_icon_cr, &i_created ) );
-
- /* Redraw icon area of window */
-
- redraw.w = inst_p->pcx_dbox_handle;
- redraw.box = pv_icon_cr.i.box;
-
- wimpt_noerr ( wimp_force_redraw ( &redraw ) );
-
- dbox_setfield ( inst_p->pcx_dbox, ICN_SPNAME, sp_h(inst_p->sp_p).name );
- dbox_setnumeric ( inst_p->pcx_dbox, ICN_NUMBER, new_sp_n );
-
- set_palette_options ( inst_p );
-
- }
-
- /*******************************************************************************
-
- Remove one sprite file & it's dialogue box
-
- *******************************************************************************/
-
- static void remove_inst(inst_t * inst_p)
- {
- if ( inst_p->pcx_dbox_handle ) dbox_dispose ( &(inst_p->pcx_dbox) );
- if ( inst_p->sp_area_p ) heap_free ( inst_p->sp_area_p );
- heap_free ( inst_p );
- }
-
- /*******************************************************************************
-
- Write a PCX file out to disc (this is where the conversion happens)
-
- *******************************************************************************/
-
- BOOL pcx_save ( char * filename, void * handle )
- {
- inst_t * inst_p = ( inst_t * ) handle;
- FILE * pcxfile;
-
- /* Set up palette defaults */
-
- get_palette_options(inst_p);
-
- default_pal_type = 1;
- if ( inst_p->palette == 2 ) default_pal_type = 0;
-
- if ( inst_p->palette ) force_pal = TRUE; else force_pal = FALSE;
-
- pcxfile = fopen ( filename, "wb" );
-
- if ( !pcxfile ) return FALSE;
-
- make_pcx ( inst_p->sp_area_p, inst_p->sp_p, pcxfile );
-
- fclose ( pcxfile );
- settype ( filename, PCX_TYPE );
-
- return TRUE;
- }
-