/***************************************************************************
 *                                                                         *
 *   EXPLODE.C                                                             *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   These are the GCOMM.LIB routines for popping up "exploding" windows   *
 *   on the text screen, with shadowing to the lower right.  The global    *
 *   variable "explodem" may be set to zero if a simple appearance of the  *
 *   window on the screen is desired.  No provision is made for saving     *
 *   the screen memory behind the window -- when the window is no longer   *
 *   needed, a complete refresh of the background screen is suggested.     *
 *                                                                         *
 *   The explode() routine will explode the area from one screen to the    *
 *   same position on the CRT, while the explodeto() routine allows for    *
 *   additional "upper left x" and "upper left y" coordinates to be        *
 *   passed in order to position the block being exploded in a different   *
 *   place on the CRT than it was in the passed screen memory.             *
 *                                                                         *
 *                              - Stryker, Brinker, & Robert 2/3/92        *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"

#define FILREV "$Revision: 5 $"

INT explodem=1;               /* yes/no controlling exploding windows      */

#define XRATIO      2              /* how many chunks of x do we grow by?  */
#define YRATIO      1              /* how many chunks of y do we grow by?  */

static VOID explodell(CHAR *sptr,INT fux,INT fuy,INT flx,INT fly,INT tux,
                INT tuy,INT shd);

VOID
explode(                           /* explode a shadowed window to CRT     */
CHAR *sctptr,                      /*   screen image w/source graphic      */
INT wulx,                          /*   src/dest window upper left x-coord */
INT wuly,                          /*   src/dest window upper left y-coord */
INT wlrx,                          /*   src/dest window lower right x-coord*/
INT wlry)                          /*   src/dest window lower right y-coord*/
{
     explodell(sctptr,wulx,wuly,wlrx,wlry,wulx,wuly,1);
}

VOID
explodeto(                         /* explode a shadowed window to x,y     */
CHAR *sptr,                        /*   screen image w/source graphic      */
INT fux,                           /*   "from" window upper left x-coord   */
INT fuy,                           /*   "from" window upper left y-coord   */
INT flx,                           /*   "from" window lower right x-coord  */
INT fly,                           /*   "from" window lower right y-coord  */
INT tux,                           /*   "to" window upper left x-coord     */
INT tuy)                           /*   "to" window upper left y-coord     */
{
     explodell(sptr,fux,fuy,flx,fly,tux,tuy,1);
}

VOID
nsexploto(                         /* explode a window (no shadow)         */
CHAR *sptr,                        /*   screen image w/source graphic      */
INT fux,                           /*   "from" window upper left x-coord   */
INT fuy,                           /*   "from" window upper left y-coord   */
INT flx,                           /*   "from" window lower right x-coord  */
INT fly,                           /*   "from" window lower right y-coord  */
INT tux,                           /*   "to" window upper left x-coord     */
INT tuy)                           /*   "to" window upper left y-coord     */
{
     explodell(sptr,fux,fuy,flx,fly,tux,tuy,0);
}

static VOID
explodell(                         /* explode window low-level util        */
CHAR *sptr,                        /*   screen image w/source graphic      */
INT fux,                           /*   "from" window upper left x-coord   */
INT fuy,                           /*   "from" window upper left y-coord   */
INT flx,                           /*   "from" window lower right x-coord  */
INT fly,                           /*   "from" window lower right y-coord  */
INT tux,                           /*   "to" window upper left x-coord     */
INT tuy,                           /*   "to" window upper left y-coord     */
INT shd)                           /*   shadow this window? (1 or 0)       */
{
     CHAR chatr;
     UINT i,k,coffset;
     INT xsize,ysize;
     INT midx,midy;
     INT xhsize,yhsize;
     INT xcp1,ycp1;
     INT tlx,tly;
     INT mintl;

     proff(tux,tuy);
     tlx=tux+(flx-fux);
     tly=tuy+(fly-fuy);
     xhsize=(flx-fux+2)/2;
     midx=tux+(tlx-tux+1)/2;
     xcp1=((tlx-tux+1)&1);
     yhsize=(fly-fuy+2)/2;
     midy=tuy+(tly-tuy+1)/2;
     ycp1=((tly-tuy+1)&1);
     xsize=xhsize-1;
     ysize=yhsize-1;
     while (xsize != xhsize || ysize != yhsize) {
          if ((xsize+=XRATIO) > xhsize) {
               xsize=xhsize;
          }
          if ((ysize+=YRATIO) > yhsize) {
               ysize=yhsize;
          }
          for (i=0 ; i < (UINT)ysize ; i++) {
               if (sptr == 0) {
                    scn2scn(gvscnoff(fux,fuy+i),
                            gvscnoff(midx-xsize+xcp1,midy-ysize+i+ycp1),
                   xsize*2);
                    scn2scn(gvscnoff(flx-xsize+1,fuy+i),
                            gvscnoff(midx,midy-ysize+i+ycp1),xsize*2);
                    scn2scn(gvscnoff(fux,fly-ysize+i+1),
                            gvscnoff(midx-xsize+xcp1,midy+i),xsize*2);
                    scn2scn(gvscnoff(flx-xsize+1,fly-ysize+i+1),
                            gvscnoff(midx,midy+i),xsize*2);
               }
               else {
                    mem2scn(sptr+gvscnoff(fux,fuy+i),
                            gvscnoff(midx-xsize+xcp1,midy-ysize+i+ycp1),
                   xsize*2);
                    mem2scn(sptr+gvscnoff(flx-xsize+1,fuy+i),
                            gvscnoff(midx,midy-ysize+i+ycp1),xsize*2);
                    mem2scn(sptr+gvscnoff(fux,fly-ysize+i+1),
                            gvscnoff(midx-xsize+xcp1,midy+i),xsize*2);
                    mem2scn(sptr+gvscnoff(flx-xsize+1,fly-ysize+i+1),
                            gvscnoff(midx,midy+i),xsize*2);
               }
          }
          gcdelay(10);
     }
     if (shd) {
          mintl=min(tlx,79);
          if (tly <= 23) {
               k=0;
               for (i=tux+2 ; i <= (UINT)mintl ; i++,k+=2) {
                    chatr=scngetc(coffset=gvscnoff(tux+2,tly+1)+k+1);
                    chatr&=0x07;
                    scnputc(coffset,chatr);
               }
          }
          mintl=min(tly,23);
          if (tlx <= 78) {
               k=0;
               for (i=tuy ; i <= (UINT)mintl ; i++,k+=160) {
                    chatr=scngetc(coffset=gvscnoff(tlx+1,tuy+1)+k+1);
                    chatr&=0x07;
                    scnputc(coffset,chatr);
                    if (tlx <= 77) {
                         coffset+=2;
                         chatr=scngetc(coffset);
                         chatr&=0x07;
                         scnputc(coffset,chatr);
                    }
               }
          }
     }
}
