/***************************************************************************** * MAND7.C - Save Dragon (Write Picture) * Mandelbrot Self-Squared Dragon Generator * For the Commodore Amiga * Version 2.01 * * Copyright (C) 1986, =Robert J. Mical= * Placed in the Public Domain * * This program may be distributed free of charge as long as the above * notice is retained. You may extract any or all information contained * in this file for use in your own programs * ****************************************************************************/ #include "mand.h" extern struct Menu MainMenu[MENU_COUNT]; extern struct MenuItem OptionsItems[OPTIONS_COUNT]; extern int MathBase, MathTransBase; extern SHORT Color0, Color1, Color2; extern SHORT UserPalette[29]; /*----------------------*/ /* Graphics definitions */ extern struct GfxBase *GfxBase; extern struct IntuitionBase *IntuitionBase; extern struct RastPort *rp,*rp2; extern struct ViewPort *vp; extern struct Window *w,*w2, *ColorWindow; extern struct Screen *screen; extern struct IntuiMessage *message; extern long last_color; extern BOOL SettingCenter, SettingBoxSize; /*----------------------------------*/ /* Miscellaneous Global Definitions */ extern union kludge { float f; int i; } start_r,end_r,start_i,end_i; /* Block bounds for set */ extern int max_x,max_y,max_mem_y; /* Graphics window size */ extern int max_count,color_inc,color_offset,color_set,color_mode,color_div; extern int color_inset,func_num; extern int v_starty,max_mem; extern long v_offset; extern UWORD *color_table,*v_mand_store; extern int modified, want_read; extern FILE *console,*v_fp,*redir_fp; extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY; extern SHORT ZoomBoxStartX, ZoomBoxStartY; extern struct NewScreen ns; /* === variables defined here ============================================= */ UBYTE *FriendlyTools[] = { "FILETYPE=Graphicraft", }; UWORD ProjectObjectData[] = { 0x1FF0, 0x0000, 0x783C, 0x6000, 0xE00F, 0xF800, 0xE00F, 0xF800, 0x783C, 0x6000, 0x1FF0, 0x0000, /* */ 0x0000, 0x0000, 0x07C0, 0x0000, 0x1FF0, 0x0000, 0x1FF0, 0x0000, 0x07C0, 0x0000, 0x0000, 0x0000, }; struct Image ProjectObjectImage = { 0, 0, 21, 6, 2, &ProjectObjectData[0], 3, 0, NULL, }; struct DiskObject ProjectObject = { WB_DISKMAGIC, WB_DISKVERSION, { /* the Gadget structure */ NULL, 0, 0, 25, 12, GADGHBOX | GADGIMAGE, RELVERIFY | GADGIMMEDIATE, BOOLGADGET, (APTR)&ProjectObjectImage, NULL, NULL, 0, 0, 0, 0, }, WBPROJECT, ":Graphicraft", &FriendlyTools[0], NO_ICON_POSITION, NO_ICON_POSITION, NULL, NULL, PROCESS_STACKSIZE, }; LONG PictModes[3] = { CAMG, 4, NULL, }; LONG PictBody[2] = { BODY, 40000, }; struct PaintingHeader PaintingHeader = { FORM, /* IFFID */ (40156), /* file length (not a nice way (too bad, eh?)) */ ILBM, BMHD, sizeof(struct BitMapHeader), { /* start of the BitMapHeader structure */ 320, 200, 0, 0, 5, 0, 0, 0, 0, 10, 11, 320, 200, /* end of BitMapHead */ }, CMAP, 96, /* this value is followed by 32 color registers */ }; BOOL SavePicture(filename) UBYTE *filename; { SHORT i, j, offset; ULONG length, actual_length, file; UBYTE *p, component, rgbbyte; USHORT rgb; BOOL written; written = FALSE; /* Open the data file */ file = Open(filename, MODE_NEWFILE); if (file == NULL) /* Couldn't open as a new file */ goto EXIT_ERROR; /*********************************************************************** * to write the buffer to the disk, we need to write: * "FORM" * file length * "ILBM" * "BMHD" * BMHD length * BitMapHeader structure * "CMAP" * CMAP length * colors * pad byte if needed * "BODY" * BODY length * body data **********************************************************************/ /* First, write out the header */ length = sizeof(struct PaintingHeader); actual_length = Write(file, &PaintingHeader, length); if (actual_length != length) goto WRITE_ERROR; /* also, enough bytes for each color register */ for (i = 0; i < (1 << ns.Depth); i++) { for (component = 0; component < 3; component++) { rgb = (GetRGB4(vp->ColorMap, i)); rgbbyte = (rgb >> (4 * (2 - component))); rgbbyte <<= 4; actual_length = Write(file, &rgbbyte, 1); if (actual_length != 1) goto WRITE_ERROR; } } actual_length = Write(file, &PictBody[0], 8); if (actual_length != 8) goto WRITE_ERROR; /* Finally, the data (uncompressed for now). */ /* First, get the bytelength per line */ length = (((ns.Width + 15) >> 4) << 1); /* For every line ... */ for (j = 0; j < ns.Height; j++) { offset = length * j; /* For every bit plane ... */ for (i = 0; i < ns.Depth; i++) { /* p is set to the start of the line in this bit plane */ p = (screen->BitMap.Planes[i]) + offset; actual_length = Write(file, p, length); if (actual_length != length) goto WRITE_ERROR; } } PictModes[2] = vp->Modes; actual_length = Write(file, &PictModes[0], 12); if (actual_length != 12) goto WRITE_ERROR; if (PutDiskObject(filename, &ProjectObject) == FALSE) goto WRITE_ERROR; written = TRUE; WRITE_ERROR: Close(file); EXIT_ERROR: if (NOT written) { fprintf(console, "*** COULDN'T WRITE YOUR FILE! ***\n"); DisplayBeep(NULL); DeleteFile(filename); } return(written); }