/* _create_fmandel_anim.rexx Create a FlashMandelWOS-iff-animation by GUI. © 2002 Edgar Schwan (eschwan@rz-online.de / http://www.schwan-clan.de/amiga/FlashMandel.shtml) $VER: _create_fmandel_anim.rexx 1.4 (9.8.2002) Notes: Added the iterations variable into account - Dino Papararo ver 1.4 date 9.8.2002 Some parts are taken and modified from 'ArtConvert.rexx 1.6 (4.5.2000) (C)' by Martin Steigerwald. Needs following executables in path "FLASHMANDEL:ARexx/c/": - "BuildAnim" from Christer Sundin (d8sunch@dtek.chalmers.se) - "GfxCon" from Dirk Farin (farindk@trick.informatik.uni-stuttgart.de / http://tick.informatik.uni-stuttgart.de/~farindk) */ PARSE ARG app.portname ' ' . IF app.portname = "" THEN app.portname = "FLASHMANDEL.1"; ADDRESS VALUE app.portname; OPTIONS RESULTS; OPTIONS FAILAT 21; SIGNAL ON SYNTAX; SIGNAL ON HALT; SIGNAL ON BREAK_C; IF ~SHOW('L','rexxsupport.library') THEN DO IF ~ADDLIB('rexxsupport.library', 0, -30) THEN SAY "Error: Could not open 'rexxsupport.library'"; END; NUMERIC DIGITS 14 app.DEBUG = 2; app.TRACE_FLAG = 0; app.USE_PRESETS = 0; /* internal script-settings */ app.TEMP_DIR = "t:"; app.TEMP_FILENAME = "pic"; app.GFXCON_PATH = "FLASHMANDEL:arexx/c/GfxCon"; app.BUILDANIM_PATH = "FLASHMANDEL:arexx/c/BuildAnim"; app.SCALE_SCRIPT_PATH = app.TEMP_DIR || "scale.script"; /*app.PUBSCREEN = "Workbench";*/ app.PUBSCREEN = app.portname; resolution.count = 8; resolution.0.width = 80; resolution.0.height = 60; resolution.1.width = 160; resolution.1.height = 120; resolution.2.width = 320; resolution.2.height = 240; resolution.3.width = 640; resolution.3.height = 480; resolution.4.width = 800; resolution.4.height = 600; resolution.5.width = 1024; resolution.5.height = 768; resolution.6.width = 1280; resolution.6.height = 1024; resolution.7.width = 1600; resolution.7.height = 1200; anim_fmt.0 = "ANIM5"; anim_fmt.1 = "ANIM7S"; anim_fmt.2 = "ANIM7L"; IF ~Init() THEN DO Cleanup(); EXIT 10; END; CALL LoadConfig(); res = CreateFMAnim_Dialog(); IF res = 1 THEN DO CALL CreateAnimation(); END; CALL Cleanup(); EXIT 0; BREAK_C: /* Handle HALT- and BREAK_C-event */ HALT: Cleanup(); EXIT 5; SYNTAX: /* Handle error */ SAY 'Error:' RC',' ERRORTEXT(RC) 'in line' SIGL'.'; Cleanup(); EXIT 10; /*** Subroutines ***/ /* CreateFMAnim_Dialog(): */ CreateFMAnim_Dialog: PROCEDURE EXPOSE app. config. resolution. res = 0; pipe = CreateFMAnim_OpenGUI(); IF pipe ~== "gui_err" THEN DO DO WHILE ~EOF(pipe) CALL topipe(pipe, "continue"); line = READLN(pipe); PARSE VAR line arg1 arg2 arg3 arg4 /* SAY "message: arg1:" arg1 "arg2:" arg2 "arg3:" arg3 "arg4:" arg4;*/ IF arg1 == "gadget" THEN DO IF arg2 = gads.path THEN config.PATH = STRIP(arg4); /* path-gadget */ IF arg2 = gads.animformat THEN config.ANIM_FORMAT = arg3; /* animformat-gadget */ IF arg2 = gads.numframes THEN config.NUM_FRAMES = arg3; /* numframes-gadget */ IF arg2 = gads.direction THEN config.DIRECTION = arg3; /* direction-gadget */ IF arg2 = gads.scale THEN DO /* scale-gadget */ config.SCALE = arg3; CALL topipe(pipe, 'id='gads.destwidth' disable='1-config.SCALE' refresh'); CALL topipe(pipe, 'id='gads.destheight' disable='1-config.SCALE' refresh'); CALL topipe(pipe, 'id='gads.resolution' disable='1-config.SCALE' refresh'); END; IF arg2 = gads.destwidth THEN DO /* destwidth-gadget */ config.DEST_WIDTH = arg3; res = checkresolution(config.DEST_WIDTH, config.DEST_HEIGHT); CALL topipe(pipe, 'id='gads.resolution' selected='res' refresh'); END; IF arg2 = gads.destheight THEN DO /* destheight-gadget */ config.DEST_HEIGHT = arg3; res = checkresolution(config.DEST_WIDTH, config.DEST_HEIGHT); CALL topipe(pipe, 'id='gads.resolution' selected='res' refresh'); END; IF arg2 = gads.resolution THEN DO /* resolution-gadget */ IF arg3 ~= 0 THEN DO arg3 = arg3 - 1; config.DEST_WIDTH = resolution.arg3.width; config.DEST_HEIGHT = resolution.arg3.height; END; ELSE DO res = checkresolution(config.DEST_WIDTH, config.DEST_HEIGHT); IF res ~= 0 THEN CALL topipe(pipe, 'id='gads.resolution' selected='res' refresh'); END; CALL topipe(pipe, 'id='gads.destwidth' defnumber 'config.DEST_WIDTH' refresh'); CALL topipe(pipe, 'id='gads.destheight' defnumber 'config.DEST_HEIGHT' refresh'); END; IF arg2 = gads.create THEN DO /* create-gadget */ res = 1; CALL SaveConfig(); LEAVE; END; IF arg2 = gads.cancel THEN LEAVE; /* cancel-gadget */ END; IF arg1 == "close" THEN LEAVE; END; CALL CLOSE(pipe); END; ELSE DO CALL DisplayRequest(app.name, getstr(300, "Error: Could not open user interface!"), getstr(100, "OK"), app.PUBSCREEN); END; RETURN res; /* CreateFMAnim_OpenGUI(): Open window for user-definitions. */ CreateFMAnim_OpenGUI: PROCEDURE EXPOSE app. config. gads. resolution. IF OPEN(pipe, "AWNPIPE:CreateFMAnimGUI/xc") THEN DO CALL topipe(pipe, 'title="'app.name'" centerscreen vertical closegadget sizegadget depthgadget dragbar spaceinner activate modify pubscreen='app.PUBSCREEN); CALL topipe(pipe, "layout bevel=0 vertical spaceinner spaceouter"); CALL topipe(pipe, 'layout bevel=3 weightedheight=30 vertical gadgettext="'getstr(201,"File")'" spaceinner spaceouter'); CALL topipe(pipe, 'label gadgettext="'getstr(202,"Animation-_path:")'" unattached'); gads.path = topipe(pipe, 'getfile childlabel minwidth=200 save filename='config.PATH); CALL topipe(pipe, 'label gadgettext="'getstr(203,"Animation-_format:")'" unattached'); gads.animformat = topipe(pipe, 'chooser childlabel weightedwidth=0 popup chooserlabels="IFF-ANIM 5|IFF-ANIM 7S|IFF-ANIM 7L" selected='config.ANIM_FORMAT); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, 'layout bevel=3 weightedheight=30 vertical centerjustify gadgettext="'getstr(204,"Animation")'" spaceinner spaceouter'); CALL topipe(pipe, 'label gadgettext="'getstr(205,"_Number of frames:")'" unattached'); gads.numframes = topipe(pipe, "integer TabCycle childlabel weightedwidth=0 minnumber=2 maxnumber=2000 arrows defnumber="config.NUM_FRAMES); CALL topipe(pipe, 'label gadgettext="'getstr(206,"_Direction:")'" unattached'); gads.direction = topipe(pipe, 'radiobutton childlabel radiolabels="'getstr(207,"In")'|'getstr(208,"Out")'" selected='config.DIRECTION); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, 'layout bevel=3 weightedheight=40 gadgettext="'getstr(209,"Scaling")'" spaceinner spaceouter'); CALL topipe(pipe, "layout bevel=0 centerjustify vertical spaceinner spaceouter"); CALL topipe(pipe, 'label gadgettext="'getstr(210,"_Scale?")'" unattached'); gads.scale = topipe(pipe, "checkbox childlabel selected="config.SCALE); CALL topipe(pipe, "layoutend") CALL topipe(pipe, "layout bevel=3 centerjustify vertical spaceinner spaceouter"); CALL topipe(pipe, 'label gadgettext="'getstr(211,"_Width:")'" unattached'); gads.destwidth = topipe(pipe, "integer TabCycle childlabel weightedwidth=0 minnumber=16 maxnumber=2048 arrows disable="1-config.SCALE" defnumber="config.DEST_WIDTH); CALL topipe(pipe, 'label gadgettext="'getstr(212,"_Height:")'" unattached'); gads.destheight = topipe(pipe, "integer TabCycle childlabel weightedwidth=0 minnumber=10 maxnumber=2048 arrows disable="1-config.SCALE" defnumber="config.DEST_HEIGHT); CALL topipe(pipe, 'space minheight=5'); CALL topipe(pipe, 'label gadgettext="'getstr(213,"_Resolution:")'" unattached'); res = checkresolution(config.DEST_WIDTH, config.DEST_HEIGHT); gads.resolution = topipe(pipe, 'chooser childlabel weightedwidth=0 popup chooserlabels="'getstr(214,"custom|80x60|160x120|320x240|640x480|800x600|1024x768|1280x1024|1600x1200")'" disable='1-config.SCALE' selected='res); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, "layout weightedheight=0 spaceouter spaceinner"); gads.create = topipe(pipe, 'button weightedheight=0 gadgettext="'getstr(102, "Cr_eate")'" close'); gads.cancel = topipe(pipe, 'button weightedheight=0 gadgettext="'getstr(101, "_Cancel")'" close'); CALL topipe(pipe, "layoutend"); CALL topipe(pipe, "open"); END; ELSE DO pipe="gui_err"; END; RETURN pipe; /* CreateAnimation(): Create the animation corresponding to the user-definitions. */ CreateAnimation: PROCEDURE EXPOSE app. config. anim_fmt. IF app.USE_PRESETS = 1 THEN DO /* for test only */ COORDS_A.RMIN = -2.000000; COORDS_A.RMAX = 1.000000; COORDS_A.IMIN = -1.125000; COORDS_A.IMAX = 1.125000; COORDS_A.JKRE = -0.720000; COORDS_A.JKIM = -0.260000; COORDS_B.RMIN = -1.313750; COORDS_B.RMAX = -0.346250; COORDS_B.IMIN = -0.142500; COORDS_B.IMAX = 0.585000; COORDS_B.JKRE = -0.720000; COORDS_B.JKIM = -0.260000; END; ELSE DO CALL DisplayRequest(app.name, getstr(1, "Click on 'Start point' when ready for the first frame animation."), getstr(100, "Start point"), app.PUBSCREEN); 'GET_COORDINATES' 'COORDS_A' /* Get first coordinates */ 'GET_ITERATIONS' 'ITERATIONS_A' CALL DisplayRequest(app.name, getstr(2, "Click on 'End point' when ready for the last frame animation."), getstr(100, "End point"), app.PUBSCREEN); 'GET_COORDINATES' 'COORDS_B' /* Get second coordinates */ 'GET_ITERATIONS' 'ITERATIONS_B' END; IF ((COORDS_A.RMIN = COORDS_B.RMIN) & (COORDS_A.RMAX = COORDS_B.RMAX) & (COORDS_A.IMIN = COORDS_B.IMIN) & (COORDS_A.IMAX = COORDS_B.IMAX)) THEN DO CALL DisplayRequest(app.name, getstr(301, "Error: The second frame must be different to the second frame!"), getstr(100, "OK"), app.PUBSCREEN); EXIT 10; END; IF app.DEBUG > 0 THEN DO SAY "First coordinates:"; SAY " COORDS_A.RMIN: " COORDS_A.RMIN; SAY " COORDS_A.RMAX: " COORDS_A.RMAX; SAY " COORDS_A.IMIN: " COORDS_A.IMIN; SAY " COORDS_A.IMAX: " COORDS_A.IMAX; SAY " COORDS_A.JKRE: " COORDS_A.JKRE; SAY " COORDS_A.JKIM: " COORDS_A.JKIM; SAY " ITERATIONS_A: " ITERATIONS_A; SAY "Second coordinates:"; SAY " COORDS_B.RMIN: " COORDS_B.RMIN; SAY " COORDS_B.RMAX: " COORDS_B.RMAX; SAY " COORDS_B.IMIN: " COORDS_B.IMIN; SAY " COORDS_B.IMAX: " COORDS_B.IMAX; SAY " COORDS_B.JKRE: " COORDS_B.JKRE; SAY " COORDS_B.JKIM: " COORDS_B.JKIM; SAY " ITERATIONS_B: " ITERATIONS_B; END; RMIN_DIFF = ABS(MAX(COORDS_A.RMIN,COORDS_B.RMIN) - MIN(COORDS_A.RMIN,COORDS_B.RMIN)); RMAX_DIFF = ABS(MAX(COORDS_A.RMAX,COORDS_B.RMAX) - MIN(COORDS_A.RMAX,COORDS_B.RMAX)); IMIN_DIFF = ABS(MAX(COORDS_A.IMIN,COORDS_B.IMIN) - MIN(COORDS_A.IMIN,COORDS_B.IMIN)); IMAX_DIFF = ABS(MAX(COORDS_A.IMAX,COORDS_B.IMAX) - MIN(COORDS_A.IMAX,COORDS_B.IMAX)); ITER_DIFF = MAX(ITERATIONS_A,ITERATIONS_B) - MIN(ITERATIONS_A,ITERATIONS_B); RMIN_STEP = RMIN_DIFF / (config.NUM_FRAMES-1); RMAX_STEP = RMAX_DIFF / (config.NUM_FRAMES-1); IMIN_STEP = IMIN_DIFF / (config.NUM_FRAMES-1); IMAX_STEP = IMAX_DIFF / (config.NUM_FRAMES-1); ITER_STEP = ITER_DIFF / (config.NUM_FRAMES-1); IF app.DEBUG > 0 THEN DO SAY "Mods:"; SAY " RMIN_MOD: " RMIN_STEP; SAY " RMAX_MOD: " RMAX_STEP; SAY " IMIN_MOD: " IMIN_STEP; SAY " IMAX_MOD: " IMAX_STEP; SAY " ITER_MOD: " ITER_STEP; END; IF config.DIRECTION = 0 THEN DO /* init direction */ FIRST = 1; LAST = config.NUM_FRAMES; STEP = 1; END; ELSE DO FIRST = config.NUM_FRAMES; LAST = 1; STEP = -1; END; COORDS.JKRE = COORDS_A.JKRE; COORDS.JKIM = COORDS_A.JKIM; DO S=FIRST TO LAST BY STEP PIC_PATH = app.TEMP_DIR || app.TEMP_FILENAME || '.' || RIGHT(S, 4, "0"); COORDS.RMIN = MIN(COORDS_A.RMIN,COORDS_B.RMIN) + (RMIN_STEP * (S - 1)); COORDS.RMAX = MAX(COORDS_A.RMAX,COORDS_B.RMAX) - (RMAX_STEP * (S - 1)); COORDS.IMIN = MIN(COORDS_A.IMIN,COORDS_B.IMIN) + (IMIN_STEP * (S - 1)); COORDS.IMAX = MAX(COORDS_A.IMAX,COORDS_B.IMAX) - (IMAX_STEP * (S - 1)); ITERATIONS = MIN(ITERATIONS_A,ITERATIONS_B) + (ITER_STEP * (S - 1)); IF app.DEBUG > 0 THEN DO SAY "Between coordinates:"; SAY " S: " S; SAY " COORDS.RMIN: " COORDS.RMIN; SAY " COORDS.RMAX: " COORDS.RMAX; SAY " COORDS.IMIN: " COORDS.IMIN; SAY " COORDS.IMAX: " COORDS.IMAX; SAY " ITERATIONS: " ITERATIONS; END; 'SET_COORDINATES' 'COORDS' 'SET_ITERATIONS' 'ITERATIONS'; 'RENDER' 'FORCE' 'SAVE_PICTURE' PIC_PATH 'FORCE'; IF config.SCALE = 1 THEN DO IF OPEN('sc', app.SCALE_SCRIPT_PATH, "W") THEN DO WRITELN('sc', "stack 50000"); WRITELN('sc', app.GFXCON_PATH PIC_PATH "FASTDITHER NOPROGRESS BOXFIT" config.DEST_WIDTH config.DEST_HEIGHT); CLOSE('sc'); ADDRESS COMMAND "Execute" app.SCALE_SCRIPT_PATH; END; END; IF app.TRACE_FLAG = 1 THEN CALL DisplayRequest("Test Movie", "Step" S, "weiter", app.PUBSCREEN); END S; /*RETURN 0;*/ ADDRESS COMMAND; /* create animation */ ANIM_PATH = config.PATH; SAY ""; SAY "create iff-animation... (" || ANIM_PATH || ")"; tmp = config.ANIM_FORMAT; app.BUILDANIM_PATH app.TEMP_DIR || app.TEMP_FILENAME || '.0001' ANIM_PATH anim_fmt.tmp; SAY "command: " app.BUILDANIM_PATH app.TEMP_DIR || app.TEMP_FILENAME || '.0001' ANIM_PATH anim_fmt.tmp; SAY ""; SAY "delete temporary frames..." /* delete temporary files */ DO S=1 TO config.NUM_FRAMES PIC_PATH = app.TEMP_DIR || app.TEMP_FILENAME || '.' || RIGHT(S, 4, "0"); 'delete' PIC_PATH; END S; SAY "delete scale-script..." 'delete' app.SCALE_SCRIPT_PATH; SAY "ready"; /* ready */ CALL DisplayRequest(app.name, getstr(3, "Ready!"), getstr(100, "OK"), app.PUBSCREEN); IF app.DEBUG > 1 THEN DO SAY "Second coordinates:"; SAY " COORDS_B.RMIN: " COORDS_B.RMIN; SAY " COORDS_B.RMAX: " COORDS_B.RMAX; SAY " COORDS_B.IMIN: " COORDS_B.IMIN; SAY " COORDS_B.IMAX: " COORDS_B.IMAX; SAY " COORDS_B.JKRE: " COORDS_B.JKRE; SAY " COORDS_B.JKIM: " COORDS_B.JKIM; END; RETURN 0; /* DisplayRequest(): Display a request and return result */ DisplayRequest: PARSE ARG Title,Body,Gadgets,Screen; ADDRESS COMMAND 'RequestChoice >t:rc.tmp TITLE="'Title'" BODY="'Body'" PUBSCREEN="'Screen'" GADGETS="'Gadgets'"'; IF OPEN(var, 't:rc.tmp', read) THEN DO res = READLN(var); CALL CLOSE(var); END; ELSE res = 0; ADDRESS COMMAND 'delete t:rc.tmp' RETURN res; /* LoadConfig(): Load the saved configuration. */ /* Routine taken from 'ArtConvert.rexx' and modified */ LoadConfig: PROCEDURE EXPOSE app. config. config.NUM_FRAMES = 5; config.DIRECTION = 0; /* IN OUT */ config.PATH = "ram:test.anim"; config.SCALE = 1; config.DEST_WIDTH = 320; config.DEST_HEIGHT = 240; config.ANIM_FORMAT = 0; /* ANIM5 ANIM7S ANIM7L */ IF OPEN('fh', app.configfile, 'R') THEN DO IF READLN('fh') == app.name'1' THEN DO DO UNTIL EOF("fh") line = STRIP(READLN('fh')); PARSE VAR line option "=" setting; option = UPPER(STRIP(option)); setting = STRIP(setting); config.option = setting; END; END; CLOSE('fh'); END; RETURN 0; /* SaveConfig(): Save the configuration. */ /* Routine taken from 'ArtConvert.rexx' and modified */ SaveConfig: PROCEDURE EXPOSE app. config. IF OPEN('fh', app.configfile, 'W') THEN DO WRITELN("fh", app.name"1"); WRITELN("fh", "NUM_FRAMES =" config.NUM_FRAMES); WRITELN("fh", "DIRECTION =" config.DIRECTION); WRITELN("fh", "PATH =" config.PATH); WRITELN("fh", "SCALE =" config.SCALE); WRITELN("fh", "DEST_WIDTH =" config.DEST_WIDTH); WRITELN("fh", "DEST_HEIGHT =" config.DEST_HEIGHT); WRITELN("fh", "ANIM_FORMAT = " config.ANIM_FORMAT); CLOSE('fh'); END; ELSE DO DisplayRequest(getstr(100, 'OK'), getstr(302, 'Error: Could not save config file »%s«!', app.configfile)); END; RETURN 0; /* Init(): Initialize environment */ /* Routine taken from 'ArtConvert.rexx' and modified */ Init: PROCEDURE EXPOSE app. success = 1; app.name = 'Create_FMandel_Anim'; app.configfile = "FLASHMANDEL:arexx/"app.name".cfg"; lf='0a'x; app.catalog = 0; app.locale = 0; IF SHOW('L', 'locale.library') THEN DO app.locale = 1; END; ELSE DO IF ADDLIB('locale.library', 0, -30, 0) THEN DO app.locale = 1; END; END; IF app.locale = 1 THEN DO /* SAY "Hallo " app.name".catalog"*/ app.catalog = OpenCatalog(app.name".catalog", 'english', 1); /* SAY app.catalog*/ END; RETURN success; /* Cleanup(): Cleanup environment. */ Cleanup: IF SHOW("P", app.portname) THEN DO ADDRESS VALUE app.portname; ; END; RETURN 0; IF app.catalog ~= 0 THEN CloseCatalog(app.catalog); EXIT; /* topipe(): send lines to awn-pipe including error-checking. */ /* Routine taken from 'ArtConvert.rexx' and modified */ topipe: PROCEDURE PARSE ARG pipe, out; /* get line to output */ CALL WRITELN(pipe, out); /* write to the pipe */ res = READLN(pipe); /* get responce and parse it. */ PARSE VAR res res1 res2 . IF res1 = 'ok' THEN RETURN(res2); /* if all is ok return the second part of the responce (usualy the GID) */ /* something went wrong, we notify the user then exit */ /* show problem line and responce (reponce may be just a blank line)*/ DisplayRequest(app.name, getstr(101, 'Cancel'), getstr(303, "GUI error »%s« / »%s«! Please report to author.", out, res)); CALL CLOSE(pipe.file); Cleanup(); EXIT 20; /* getstr(): Get string from catalog. */ /* Routine taken from 'ArtConvert.rexx' and modified */ getstr: PROCEDURE EXPOSE app.catalog PARSE ARG msgno, msgstring; IF app.catalog ~= 0 THEN msgstring = GetCatalogStr(app.catalog, msgno, msgstring); DO i = 3 TO ARG() PARSE VAR msgstring fore '%s' aft; msgstring = fore || ARG(i) || aft; END; RETURN msgstring; /* checkresolution(): Check for standard-resolution. */ /* Routine taken from 'ArtConvert.rexx' and modified */ checkresolution: PROCEDURE EXPOSE resolution. PARSE ARG checkwidth,checkheight; res = 0; DO i=0 TO resolution.count - 1 IF (checkwidth = resolution.i.width) & (checkheight = resolution.i.height) THEN DO res = i + 1; LEAVE; END; END; RETURN res;