view src/l_align.cc @ 107:20aa5a515896

Reformat one line /* */ comments to //
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 06 Oct 2014 12:42:55 +0300
parents 2f1ecc1c5f72
children f05330267c66
line wrap: on
line source

/*
 *        l_align.cc
 *        Linedef/sidedef texture alignment
 *        AYM 1998-02-03
 */


/*
This file is part of Yadex.

Yadex incorporates code from DEU 5.21 that was put in the public domain in
1994 by Raphaël Quinet and Brendon Wyber.

The rest of Yadex is Copyright © 1997-2003 André Majorel and others.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307, USA.
*/


#include "yadex.h"
#include "dialog.h"
#include "entry.h"
#include "gfx.h"
#include "levels.h"
#include "objid.h"
#include "oldmenus.h"
#include "selectn.h"
#include "textures.h"


/*
   get the absolute height from which the textures are drawn
*/

int GetTextureRefHeight(int sidedef)
{
    int l, sector;
    int otherside = OBJ_NO_NONE;

    // find the sidedef on the other side of the LineDef, if any
    for (l = 0; l < NumLineDefs; l++)
    {
        if (LineDefs[l].sidedef1 == sidedef)
        {
            otherside = LineDefs[l].sidedef2;
            break;
        }
        if (LineDefs[l].sidedef2 == sidedef)
        {
            otherside = LineDefs[l].sidedef1;
            break;
        }
    }

    // get the Sector number
    sector = SideDefs[sidedef].sector;

    /* if the upper texture is displayed, then the reference
     * is taken from the other Sector */
    if (otherside >= 0)
    {
        l = SideDefs[otherside].sector;
        if (l > 0)
        {
            if (Sectors[l].ceilh < Sectors[sector].ceilh
                && Sectors[l].ceilh > Sectors[sector].floorh)
                sector = l;
        }
    }

    // return the altitude of the ceiling
    if (sector >= 0)
        return Sectors[sector].ceilh;        // textures are drawn from the ceiling down
    else
        return 0;                // yuck!
}




/*
   Align all textures for the given SideDefs

   Note from RQ:
      This function should be improved!
      But what should be improved first is the way the SideDefs are selected.
      It is stupid to change both sides of a wall when only one side needs
      to be changed.  But with the current selection method, there is no
      way to select only one side of a two-sided wall.
*/

void AlignTexturesY(SelPtr * sdlist, int opt_sdef, bool opt_check)
{
    int h, refh;

    if (!*sdlist)
        return;

    // get the reference height from the first sidedef
    refh = GetTextureRefHeight((*sdlist)->objnum);
    SideDefs[(*sdlist)->objnum].yoff = 0;
    UnSelectObject(sdlist, (*sdlist)->objnum);

    // adjust Y offset in all other SideDefs
    while (*sdlist)
    {
        h = GetTextureRefHeight((*sdlist)->objnum);
        SideDefs[(*sdlist)->objnum].yoff = (refh - h) % 128;
        UnSelectObject(sdlist, (*sdlist)->objnum);
    }
    
    MadeChanges = 1;
}



/*
   Function is to align all highlighted textures in the X-axis

   Note from RJH:
   LineDefs highlighted are read off in reverse order of highlighting.
   The '*sdlist' is in the reverse order of the above mentioned LineDefs
   i.e. the first linedef sidedefs you highlighted will be processed first.

   Note from RQ:
   See also the note for the previous function.

   Note from RJH:
   For the menu for aligning textures 'X' NOW operates upon the fact that
   ALL the SIDEDEFS from the selected LINEDEFS are in the *SDLIST, 2nd
   sidedef is first, 1st sidedef is 2nd). Aligning textures X now does
   SIDEDEF 1's and SIDEDEF 2's.  If the selection process is changed,
   the following needs to be altered radically.
*/

void AlignTexturesX(SelPtr * sdlist, int opt_sdef, bool opt_check, bool opt_offset, int opt_mode)
{
    // FIRST texture name used in the highlited objects
    char texname[WAD_TEX_NAME + 1];
    char errormessage[128];          // area to hold the error messages produced
    int ldef;                        // linedef number
    int sdef;                         // current sidedef in *sdlist
    int vert1, vert2;                // vertex 1 and 2 for the linedef under scrutiny
    int xoffset;                     // xoffset accumulator
    int useroffset;                  // user input offset for first input
    i16 texlength;                   // the length of texture to format to
    int length;                      // length of linedef under scrutiny
    i16 dummy;                       // holds useless data

    vert1 = -1;
    vert2 = -1;                      // 1st time round the while loop the -1 value is needed
    texlength = 0;
    xoffset = 0;
    useroffset = 0;

    if (*sdlist == NULL)
    {
        Notify(-1, -1, "Error in AlignTexturesX: list is empty", 0);
        return;
    }

    if (opt_mode == -1)
    {
        /* No defined mode, we will try to "guess" which texture
         * the user wants to align ... and choose the operating mode
         * based on that.
         */
        SDPtr pdef = &SideDefs[(*sdlist)->objnum];
        if (ValidTextureName(pdef->tex3))
        {
            strncpy(texname, pdef->tex3, WAD_TEX_NAME);
            opt_mode = 3;
        }
        else if (ValidTextureName(pdef->tex2))
        {
            strncpy(texname, pdef->tex2, WAD_TEX_NAME);
            opt_mode = 2;
        }
        else if (ValidTextureName(pdef->tex1))
        {
            strncpy(texname, pdef->tex1, WAD_TEX_NAME);
            opt_mode = 1;
        }
        else
        {
            sprintf(errormessage, "No texture(s) for sidedef #%d.",
                    (*sdlist)->objnum);
            Notify(-1, -1, errormessage, 0);
            return;
        }
    }
    else
    {
        // Find first sidedef that has desired texture set

        // FIXME! Not implemented yet ... -ccr
    }

    /* Get texture width, do some sanity checking as the
     * WAD reading may fail.
     */
    GetWallTextureSize(&texlength, &dummy, texname);

    if (texlength < 4)
    {
        sprintf(errormessage, "Texture length for texture '%s' is %d. Not continuing.",
                texname, texlength);
        Notify(-1, -1, errormessage, 0);
        return;
    }

    // Get initial offset to use, if requested
    if (opt_offset)
    {
        int x0, y0, key;
        char prompt[80];

        sprintf(prompt, "Enter initial offset between 0 and %d:", texlength);

        x0 = (cfg.ScrMaxX - 25 - 8 * strlen(prompt)) / 2;
        y0 = (cfg.ScrMaxY - 55) / 2;

        DrawScreenBox3D(x0, y0, x0 + 25 + 8 * strlen(prompt), y0 + 55);
        set_colour(WHITE);
        DrawScreenText(x0 + 10, y0 + 8, prompt);

        while ((key = InputInteger(x0 + 10, y0 + 28, &useroffset, 0,
               (int) texlength)) != YK_RETURN && key != YK_ESC)
            Beep();

        if (key == YK_ESC)
            return;
    }

    // Main processing loop
    xoffset = opt_offset ? useroffset : 0;
    while (*sdlist != NULL)
    {
        sdef = (*sdlist)->objnum;

        // Check for contiguous textures, if required
        if (opt_check)
        {
            SDPtr pdef = &SideDefs[sdef];
            if ((opt_mode == 3 && strncmp(pdef->tex3, texname, WAD_TEX_NAME)) ||
                (opt_mode == 2 && strncmp(pdef->tex2, texname, WAD_TEX_NAME)) ||
                (opt_mode == 1 && strncmp(pdef->tex1, texname, WAD_TEX_NAME)))
            {
                sprintf(errormessage, "No texture or discontinuous texture on sidedef #%d.",
                        sdef);
                Notify(-1, -1, errormessage, 0);
                return;
            }
        }

        // Find out which linedef owns this sidedef
        int n;
        for (ldef = -1, n = 0; n < NumLineDefs; n++)
            if ((opt_sdef == 1 && LineDefs[n].sidedef1 == sdef) ||
                (opt_sdef == 2 && LineDefs[n].sidedef2 == sdef)) 
            {
                ldef = n;
                break;
            }

        if (ldef < 0)
        {
            sprintf(errormessage, "Linedef for sidedef #%d not found?!",
                    sdef);
            Notify(-1, -1, errormessage, 0);
            return;
        }

        // Test for linedef continuity
        vert1 = LineDefs[ldef].start;
        if (vert1 != vert2 && vert2 != -1)
        {
            sprintf(errormessage, "Linedef #%d is not contiguous"
                    " with the previous linedef, please reselect.",
                    (*sdlist)->objnum);
            Notify(-1, -1, errormessage, 0);
            return;
        }

        // Set offset
        SideDefs[sdef].xoff = xoffset;

        // Calculate length of linedef
        vert2 = LineDefs[ldef].end;
        length = ComputeDist(Vertices[vert2].x - Vertices[vert1].x,
                             Vertices[vert2].y - Vertices[vert1].y);

        xoffset += length;

        // Remove multiples of texlength from xoffset
        xoffset = xoffset % texlength;

        // move to next object in selected list
        UnSelectObject(sdlist, (*sdlist)->objnum);
    }

    MadeChanges = 1;
}