2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* apps/graphics/traveler/tools/tcledit/tcl_paint.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Included files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
#ifndef NO_XSHM
|
|
|
|
# include <sys/shm.h>
|
|
|
|
# include <X11/extensions/XShm.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "trv_types.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "wld_mem.h"
|
|
|
|
#include "wld_bitmaps.h"
|
|
|
|
#include "wld_plane.h"
|
|
|
|
#include "wld_utils.h"
|
|
|
|
#include "tcl_x11graphics.h"
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Pre-processor Definitions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#define LINE_THICKNESS_DELTA 1
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Private Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_color_index
|
|
|
|
* Description:
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
static int tcl_color_index(tcl_window_t *w)
|
|
|
|
{
|
|
|
|
int ndx;
|
|
|
|
|
|
|
|
if (g_edit_mode != EDITMODE_NEW)
|
|
|
|
{
|
|
|
|
ndx = POS_COLORS * NUM_COLORS;
|
|
|
|
}
|
|
|
|
else if (g_edit_plane == w->plane)
|
|
|
|
{
|
|
|
|
ndx = SEL_COLORS * NUM_COLORS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ndx = NSEL_COLORS * NUM_COLORS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ndx;
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static void tcl_paint_rectangle(tcl_window_t *w, int hleft, int hright,
|
|
|
|
int vtop, int vbottom, dev_pixel_t pixel)
|
|
|
|
{
|
|
|
|
dev_pixel_t *rowstart;
|
|
|
|
dev_pixel_t *dest;
|
2016-11-11 15:19:10 +01:00
|
|
|
int row;
|
|
|
|
int col;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Paint from top to bottom */
|
|
|
|
|
|
|
|
rowstart = w->frameBuffer + vtop * w->width;
|
|
|
|
|
|
|
|
for (row = vtop; row <= vbottom; row++)
|
|
|
|
{
|
|
|
|
/* Paint from left to right */
|
|
|
|
|
|
|
|
dest = rowstart + hleft;
|
|
|
|
|
|
|
|
for (col = hleft; col <= hright; col++)
|
|
|
|
{
|
|
|
|
*dest++ = pixel;
|
|
|
|
}
|
|
|
|
|
|
|
|
rowstart += w->width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_coplanar_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static void tcl_paint_coplanar_rectangle(tcl_window_t *w,
|
2016-11-11 15:19:10 +01:00
|
|
|
rect_data_t *ptr, int hoffset,
|
|
|
|
int voffset, dev_pixel_t pixel)
|
2016-11-11 14:52:32 +01:00
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int hleft;
|
|
|
|
int hright;
|
|
|
|
int vtop;
|
|
|
|
int vbottom;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the left side offset and verify that some part of the rectangle lies
|
|
|
|
* to the left of the right side of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft = ptr->hstart - hoffset;
|
|
|
|
|
|
|
|
if (hleft >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (hleft < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hleft = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the right side offset and verify that some part of the rectangle lies
|
|
|
|
* to the right of the left side of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hright = ptr->hend - hoffset;
|
|
|
|
|
|
|
|
if (hright < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (hright >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hright = g_view_size - 1;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the top side offset and verify that some part of the rectangle lies
|
|
|
|
* above the bottom of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
vtop = ptr->vstart - voffset;
|
|
|
|
|
|
|
|
if (vtop >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (vtop < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vtop = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the bottom side offset and verify that some part of the rectangle lies
|
|
|
|
* below the top of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
vbottom = ptr->vend - voffset;
|
|
|
|
|
|
|
|
if (vbottom < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (vbottom >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vbottom = g_view_size - 1;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* If we are viewing the Z plane, then the vpos is "down" the screen from the
|
|
|
|
* top. Otherwise, it is "up" the screen from the bottom.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_Z)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int vtmp = vbottom;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
2016-11-11 15:19:10 +01:00
|
|
|
vbottom = g_view_size - vtop - 1;
|
|
|
|
vtop = g_view_size - vtmp - 1;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We now have some rectangle that we know is to fully on the the display.
|
|
|
|
* Get the display positions of the rectangle
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft = (hleft) * w->width / g_view_size;
|
|
|
|
hright = (hright) * w->width / g_view_size;
|
|
|
|
vtop = (vtop) * w->height / g_view_size;
|
|
|
|
vbottom = (vbottom) * w->height / g_view_size;
|
|
|
|
|
|
|
|
/* Paint it */
|
|
|
|
|
|
|
|
tcl_paint_rectangle(w, hleft, hright, vtop, vbottom, pixel);
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_horizontal_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static int tcl_check_horizontal_rectangle(tcl_window_t *w, rect_data_t *ptr, int pos)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int posstart;
|
|
|
|
int posend;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Search the plane list for every place whose "level" component includes the
|
|
|
|
* current map level. This will be the vertical component of the rectangle
|
|
|
|
* in every case except for EDITPLANE_X:
|
|
|
|
*
|
|
|
|
* w->plane vhead level component EDITPLANE_X g_zplane_list H (= X) EDITPLANE_Y
|
|
|
|
* g_zplane_list V (= Y) EDITPLANE_Z g_yplane_list V (= Z)
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_X)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
posstart = ptr->vstart;
|
|
|
|
posend = ptr->vend;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
posstart = ptr->hstart;
|
|
|
|
posend = ptr->hend;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify the the vertical rectangle intersects the viewing plane */
|
|
|
|
|
2016-11-11 15:19:10 +01:00
|
|
|
return ((posstart <= pos) && (posend >= pos));
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_horizontal_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static void tcl_paint_horizontal_rectangle(tcl_window_t *w, rect_data_t *ptr,
|
2016-11-11 15:19:10 +01:00
|
|
|
int hoffset, int voffset,
|
|
|
|
dev_pixel_t pixel)
|
2016-11-11 14:52:32 +01:00
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int hleft;
|
|
|
|
int hright;
|
|
|
|
int vtop;
|
|
|
|
int vbottom;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the "vertical" position of the horizontal line. This will always be
|
|
|
|
* the plane component of the rectangle, but will have to be "flipped" if the
|
|
|
|
* viewing plane is not EDITPLANE_Z:
|
|
|
|
*
|
|
|
|
* w->plane vhead vertical component EDITPLANE_X g_zplane_list plane (= Z)
|
|
|
|
* EDITPLANE_Y g_zplane_list plane (= Z) EDITPLANE_Z g_yplane_list plane (= Y)
|
|
|
|
*/
|
|
|
|
|
|
|
|
vtop = ptr->plane - voffset;
|
|
|
|
|
|
|
|
if ((vtop < 0) || (vtop >= g_view_size))
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_Z)
|
|
|
|
{
|
|
|
|
vtop = g_view_size - vtop - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the extent of the horizontal line. This will be the horizontal
|
|
|
|
* component of the rectangle in every case except when the viewing plane if
|
|
|
|
* EDITPLANE_X
|
|
|
|
*
|
|
|
|
* w->plane vhead horizontal component EDITPLANE_X g_zplane_list V (= Y) EDITPLANE_X
|
|
|
|
* g_zplane_list H (= X) EDITPLANE_X g_yplane_list H (= X)
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_X)
|
|
|
|
{
|
|
|
|
hleft = ptr->hstart;
|
|
|
|
hright = ptr->hend;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hleft = ptr->vstart;
|
|
|
|
hright = ptr->vend;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the left side offset and verify that some part of the rectangle lies
|
|
|
|
* to the left of the right side of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft -= hoffset;
|
|
|
|
|
|
|
|
if (hleft >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (hleft < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hleft = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the right side offset and verify that some part of the rectangle lies
|
|
|
|
* to the right of the left side of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hright -= hoffset;
|
|
|
|
|
|
|
|
if (hright < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (hright >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hright = g_view_size - 1;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* We now have some line segment that we know is to fully on the the display.
|
|
|
|
* Get the display positions of the line segment.
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft = hleft * w->width / g_view_size;
|
|
|
|
hright = hright * w->width / g_view_size;
|
|
|
|
vtop = vtop * w->height / g_view_size;
|
|
|
|
|
|
|
|
/* Apply Line thickness to get a narrow rectangle */
|
|
|
|
|
|
|
|
vbottom = vtop + LINE_THICKNESS_DELTA;
|
|
|
|
|
|
|
|
if (vbottom >= w->height)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vbottom = w->height - 1;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
vtop -= LINE_THICKNESS_DELTA;
|
|
|
|
|
|
|
|
if (vtop < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vtop = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Paint it */
|
|
|
|
|
|
|
|
tcl_paint_rectangle(w, hleft, hright, vtop, vbottom, pixel);
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_check_vertical_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static int tcl_check_vertical_rectangle(tcl_window_t *w, rect_data_t *ptr, int pos)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int posstart;
|
|
|
|
int posend;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Search the plane list for every place whose "level" component includes the
|
|
|
|
* current map level. This will be the horizontal component of the rectangle
|
|
|
|
* in every case except for EDITPLANE_Z
|
|
|
|
*
|
|
|
|
* x->plane hhead level component EDITPLANE_X g_yplane_list H (= X) EDITPLANE_Y
|
|
|
|
* g_xplane_list H (= Y) EDITPLANE_Z g_xplane_list V (= Z)
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_Z)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
posstart = ptr->hstart;
|
|
|
|
posend = ptr->hend;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
posstart = ptr->vstart;
|
|
|
|
posend = ptr->vend;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Verify the the vertical rectangle intersects the viewing plane */
|
|
|
|
|
2016-11-11 15:19:10 +01:00
|
|
|
return ((posstart <= pos) && (posend >= pos));
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_vertical_rectangle
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
static void tcl_paint_vertical_rectangle(tcl_window_t *w, rect_data_t *ptr,
|
|
|
|
int hoffset, int voffset, dev_pixel_t pixel)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int hleft;
|
|
|
|
int hright;
|
|
|
|
int vtop;
|
|
|
|
int vbottom;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the "horizontal" position of the vertical line. This will always be
|
|
|
|
* the plane component of the rectangle:
|
|
|
|
*
|
|
|
|
* w->plane hhead horizontal component EDITPLANE_X g_yplane_list plane (= Y)
|
|
|
|
* EDITPLANE_Y g_xplane_list plane (= X) EDITPLANE_Z g_xplane_list plane (= X)
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft = ptr->plane - hoffset;
|
|
|
|
|
|
|
|
if ((hleft < 0) || (hleft >= g_view_size))
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the extent of the vertical line. This will be the vertical component
|
|
|
|
* of the rectangle in every case except when the viewing plane is
|
|
|
|
* EDITPLANE_Z and will have to be "flipped" if the viewing plane is not
|
|
|
|
* EDITPLANE_Z:
|
|
|
|
*
|
|
|
|
* w->plane hhead horizontal component EDITPLANE_X g_yplane_list V (= Z) EDITPLANE_Y
|
|
|
|
* g_xplane_list V (= Z) EDITPLANE_Z g_xplane_list H (= Y)
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_Z)
|
|
|
|
{
|
|
|
|
vtop = ptr->vstart;
|
|
|
|
vbottom = ptr->vend;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vtop = ptr->hstart;
|
|
|
|
vbottom = ptr->hend;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the top side offset and verify that some part of the rectangle lies
|
|
|
|
* above the bottom of the display.
|
|
|
|
*/
|
|
|
|
|
|
|
|
vtop -= voffset;
|
|
|
|
|
|
|
|
if (vtop >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (vtop < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vtop = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Get the bottom side offset and verify that some part of the rectangle lies
|
|
|
|
* below the top of the display
|
|
|
|
*/
|
|
|
|
|
|
|
|
vbottom -= voffset;
|
|
|
|
|
|
|
|
if (vbottom < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (vbottom >= g_view_size)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
vbottom = g_view_size - 1;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Flip if necessary */
|
|
|
|
|
|
|
|
if (w->plane != EDITPLANE_Z)
|
|
|
|
{
|
2016-11-11 15:19:10 +01:00
|
|
|
int vtmp = vbottom;
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
vbottom = g_view_size - vtop - 1;
|
2016-11-11 15:19:10 +01:00
|
|
|
vtop = g_view_size - vtmp - 1;
|
2016-11-11 14:52:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We now have some line segment that we know is to fully on the the display.
|
|
|
|
* Get the display positions of the line segment
|
|
|
|
*/
|
|
|
|
|
|
|
|
hleft = hleft * w->width / g_view_size;
|
|
|
|
vtop = vtop * w->height / g_view_size;
|
|
|
|
vbottom = vbottom * w->height / g_view_size;
|
|
|
|
|
|
|
|
/* Apply Line thickness to get a narrow rectangle */
|
|
|
|
|
|
|
|
hright = hleft + LINE_THICKNESS_DELTA;
|
|
|
|
|
|
|
|
if (hright >= w->width)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hright = w->width;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
hleft -= LINE_THICKNESS_DELTA;
|
|
|
|
|
|
|
|
if (hleft < 0)
|
2016-11-11 15:19:10 +01:00
|
|
|
{
|
|
|
|
hleft = 0;
|
|
|
|
}
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
/* Paint it */
|
|
|
|
|
|
|
|
tcl_paint_rectangle(w, hleft, hright, vtop, vbottom, pixel);
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/*******************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_background
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
void tcl_paint_background(tcl_window_t *w)
|
|
|
|
{
|
|
|
|
dev_pixel_t *dest;
|
|
|
|
dev_pixel_t pixel;
|
|
|
|
int ndx = tcl_color_index(w);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ginfo("g_edit_mode=%d g_edit_plane=%d plane=%d ndx=%d\n",
|
|
|
|
g_edit_mode, g_edit_plane, w->plane, ndx);
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + BKGD_COLOR];
|
|
|
|
dest = w->frameBuffer;
|
|
|
|
|
|
|
|
ginfo("ndx=%d dest=%p pixel=0x%06lx\n", ndx, dest, pixel);
|
|
|
|
|
|
|
|
for (i = 0; i < w->width * w->height; i++)
|
|
|
|
{
|
|
|
|
*dest++ = pixel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_position
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
void tcl_paint_position(tcl_window_t *w)
|
|
|
|
{
|
|
|
|
/* Only show the position cursor in POS mode */
|
|
|
|
|
|
|
|
if (g_edit_mode == EDITMODE_POS)
|
|
|
|
{
|
|
|
|
dev_pixel_t *dest;
|
|
|
|
dev_pixel_t pixel;
|
|
|
|
int ndx = tcl_color_index(w);
|
|
|
|
int hpos;
|
|
|
|
int vpos;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ginfo("plane=%d ndx=%d\n", w->plane, ndx);
|
|
|
|
|
|
|
|
/* Horizontal and vertical positions will depend on which plane is
|
|
|
|
* selected.
|
2016-11-11 15:19:10 +01:00
|
|
|
*/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
switch (w->plane)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case EDITPLANE_X:
|
|
|
|
hpos = g_plane_position[EDITPLANE_Y] - g_coord_offset[EDITPLANE_Y];
|
|
|
|
vpos = g_plane_position[EDITPLANE_Z] - g_coord_offset[EDITPLANE_Z];
|
|
|
|
vpos = g_view_size - vpos - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Y:
|
|
|
|
hpos = g_plane_position[EDITPLANE_X] - g_coord_offset[EDITPLANE_X];
|
|
|
|
vpos = g_plane_position[EDITPLANE_Z] - g_coord_offset[EDITPLANE_Z];
|
|
|
|
vpos = g_view_size - vpos - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Z:
|
|
|
|
hpos = g_plane_position[EDITPLANE_X] - g_coord_offset[EDITPLANE_X];
|
|
|
|
vpos = g_plane_position[EDITPLANE_Y] - g_coord_offset[EDITPLANE_Y];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scale the position to fit in the display */
|
|
|
|
|
|
|
|
hpos = (hpos * w->width) / g_view_size;
|
|
|
|
vpos = (vpos * w->height) / g_view_size;
|
|
|
|
|
|
|
|
/* Paint the horizontal line */
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + HLINE_COLOR];
|
|
|
|
dest = w->frameBuffer + vpos * w->width;
|
|
|
|
|
|
|
|
ginfo("dest=%p pixel=0x%06lx\n", dest, pixel);
|
|
|
|
|
|
|
|
for (i = 0; i < w->width; i++)
|
|
|
|
{
|
|
|
|
*dest++ = pixel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Paint the vertical line */
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + HLINE_COLOR];
|
|
|
|
dest = w->frameBuffer + hpos;
|
|
|
|
|
|
|
|
ginfo("dest=%p pixel=0x%06lx\n", dest, pixel);
|
|
|
|
|
|
|
|
for (i = 0; i < w->height; i++)
|
|
|
|
{
|
|
|
|
*dest = pixel;
|
|
|
|
dest += w->width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_grid
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
void tcl_paint_grid(tcl_window_t *w)
|
|
|
|
{
|
|
|
|
dev_pixel_t *dest;
|
|
|
|
dev_pixel_t pixel;
|
|
|
|
int ndx = tcl_color_index(w);
|
|
|
|
int hoffset, hpos, haccum;
|
|
|
|
int voffset, vpos, vaccum;
|
|
|
|
int gridmask;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ginfo("plane=%d ndx=%d\n", w->plane, ndx);
|
|
|
|
|
|
|
|
/* Horizontal and vertical positions will depend on which plane is selected. */
|
|
|
|
|
|
|
|
switch (w->plane)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case EDITPLANE_X:
|
|
|
|
hoffset = g_coord_offset[EDITPLANE_Y];
|
|
|
|
voffset = g_view_size - g_coord_offset[EDITPLANE_Z] - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Y:
|
|
|
|
hoffset = g_coord_offset[EDITPLANE_X];
|
|
|
|
voffset = g_view_size - g_coord_offset[EDITPLANE_Z] - 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Z:
|
|
|
|
hoffset = g_coord_offset[EDITPLANE_X];
|
|
|
|
voffset = g_coord_offset[EDITPLANE_Y];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is the color of the grid */
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + GRID_COLOR];
|
|
|
|
|
|
|
|
/* Paint the horizontal grid lines */
|
|
|
|
|
|
|
|
gridmask = g_grid_step - 1;
|
|
|
|
vaccum = ((voffset + gridmask) & ~gridmask) - voffset;
|
|
|
|
vpos = (vaccum * w->height) / g_view_size;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Paint one horizontal grid line */
|
|
|
|
|
|
|
|
dest = w->frameBuffer + vpos * w->width;
|
|
|
|
|
2016-11-11 15:19:10 +01:00
|
|
|
for (i = 0; i < w->width; i++)
|
2016-11-11 14:52:32 +01:00
|
|
|
{
|
|
|
|
*dest++ = pixel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scale the next grid position onto the display */
|
|
|
|
|
|
|
|
vaccum += g_grid_step;
|
|
|
|
vpos = (vaccum * w->height) / g_view_size;
|
|
|
|
|
|
|
|
}
|
|
|
|
while (vpos < w->height);
|
|
|
|
|
|
|
|
/* Paint the vertical grid lines */
|
|
|
|
/* Force the starting offsets to lie on a grid line */
|
|
|
|
|
|
|
|
haccum = ((hoffset + gridmask) & ~gridmask) - hoffset;
|
|
|
|
hpos = (haccum * w->width) / g_view_size;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Paint one vertical grid line */
|
|
|
|
|
|
|
|
dest = w->frameBuffer + hpos;
|
|
|
|
|
2016-11-11 15:19:10 +01:00
|
|
|
for (i = 0; i < w->height; i++)
|
2016-11-11 14:52:32 +01:00
|
|
|
{
|
|
|
|
*dest = pixel;
|
|
|
|
dest += w->width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scale the next grid position onto the display */
|
|
|
|
|
|
|
|
haccum += g_grid_step;
|
|
|
|
hpos = (haccum * w->width) / g_view_size;
|
|
|
|
}
|
|
|
|
while (hpos < w->width);
|
|
|
|
}
|
|
|
|
|
2016-11-11 15:51:41 +01:00
|
|
|
/****************************************************************************
|
2016-11-11 14:52:32 +01:00
|
|
|
* Function: tcl_paint_rectangles
|
|
|
|
* Description:
|
2016-11-11 15:51:41 +01:00
|
|
|
***************************************************************************/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
void tcl_paint_rectangles(tcl_window_t *w)
|
|
|
|
{
|
|
|
|
rect_list_t *head, *vhead, *hhead;
|
|
|
|
rect_list_t *list;
|
|
|
|
rect_data_t *ptr;
|
|
|
|
dev_pixel_t pixel;
|
|
|
|
int ndx = tcl_color_index(w);
|
|
|
|
int hoffset, voffset;
|
|
|
|
int hplane, vplane;
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
/* Select the plane lists and plane position for the current window */
|
|
|
|
|
|
|
|
switch (w->plane)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case EDITPLANE_X:
|
|
|
|
pos = g_plane_position[EDITPLANE_X];
|
|
|
|
hplane = EDITPLANE_Y;
|
|
|
|
vplane = EDITPLANE_Z;
|
|
|
|
head = g_xplane_list.head;
|
|
|
|
hhead = g_yplane_list.head;
|
|
|
|
vhead = g_zplane_list.head;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Y:
|
|
|
|
pos = g_plane_position[EDITPLANE_Y];
|
|
|
|
hplane = EDITPLANE_X;
|
|
|
|
vplane = EDITPLANE_Z;
|
|
|
|
head = g_yplane_list.head;
|
|
|
|
hhead = g_xplane_list.head;
|
|
|
|
vhead = g_zplane_list.head;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EDITPLANE_Z:
|
|
|
|
pos = g_plane_position[EDITPLANE_Z];
|
|
|
|
hplane = EDITPLANE_X;
|
|
|
|
vplane = EDITPLANE_Y;
|
|
|
|
head = g_zplane_list.head;
|
|
|
|
hhead = g_xplane_list.head;
|
|
|
|
vhead = g_yplane_list.head;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
hoffset = g_coord_offset[hplane];
|
|
|
|
voffset = g_coord_offset[vplane];
|
|
|
|
|
|
|
|
/* Display the rectangles which are in the viewing plane */
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + NRECT_COLOR];
|
|
|
|
|
|
|
|
for (list = head; (list); list = list->flink)
|
|
|
|
{
|
|
|
|
ptr = &list->d;
|
|
|
|
|
|
|
|
/* We only want the rectangles which lie on the current display level */
|
|
|
|
|
|
|
|
if (ptr->plane == pos)
|
|
|
|
{
|
|
|
|
tcl_paint_coplanar_rectangle(w, ptr, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Are we currently editting a new plane that is not yet in the list? It it
|
|
|
|
* is the same as the display plane, then we will want to display that as
|
|
|
|
* well.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ((g_edit_mode == EDITMODE_NEW) &&
|
|
|
|
(g_edit_plane == w->plane) && (g_edit_rect.plane == pos))
|
|
|
|
{
|
|
|
|
pixel = w->colorLookup[ndx + SRECT_COLOR];
|
|
|
|
tcl_paint_coplanar_rectangle(w, &g_edit_rect, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Display the rectangles which are orthogonal and "horizontal" with respect
|
|
|
|
* to the viewing plane.
|
|
|
|
*
|
|
|
|
* Process every plane in the vertical axis (these will be horizontal) This
|
|
|
|
* will by the Z plane for every viewing plane except EDITPLANE_Z where it
|
|
|
|
* will be the Y plane */
|
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + BRECT_COLOR];
|
|
|
|
|
|
|
|
for (list = vhead; (list); list = list->flink)
|
|
|
|
{
|
|
|
|
ptr = &list->d;
|
|
|
|
|
|
|
|
/* Search the plane list for every place whose "level" component includes
|
|
|
|
* the current map level.
|
2016-11-11 15:19:10 +01:00
|
|
|
*/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (tcl_check_horizontal_rectangle(w, ptr, pos))
|
|
|
|
{
|
|
|
|
tcl_paint_horizontal_rectangle(w, ptr, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Are we currently editting a new plane that is not yet in the list? */
|
|
|
|
|
|
|
|
if ((g_edit_mode == EDITMODE_NEW) && (g_edit_plane == vplane))
|
|
|
|
{
|
|
|
|
ptr = &g_edit_rect;
|
|
|
|
|
|
|
|
if (tcl_check_horizontal_rectangle(w, ptr, pos))
|
|
|
|
{
|
|
|
|
pixel = w->colorLookup[ndx + SRECT_COLOR];
|
|
|
|
tcl_paint_horizontal_rectangle(w, ptr, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Display the rectangles which are orthogonal and "vertical" with respect to
|
|
|
|
* the viewing plane.
|
|
|
|
*
|
|
|
|
* Process every plane in the horizontal axis (these will be vertical) This
|
|
|
|
* will by the X plane for every viewing plane except EDITPLANE_X where it
|
2016-11-11 15:19:10 +01:00
|
|
|
* will be the Y plane.
|
|
|
|
*/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
pixel = w->colorLookup[ndx + BRECT_COLOR];
|
|
|
|
|
|
|
|
for (list = hhead; (list); list = list->flink)
|
|
|
|
{
|
|
|
|
ptr = &list->d;
|
|
|
|
|
|
|
|
/* Search the plane list for every place whose "level" component includes
|
|
|
|
* the current map level.
|
2016-11-11 15:19:10 +01:00
|
|
|
*/
|
2016-11-11 14:52:32 +01:00
|
|
|
|
|
|
|
if (tcl_check_vertical_rectangle(w, ptr, pos))
|
|
|
|
{
|
|
|
|
tcl_paint_vertical_rectangle(w, &list->d, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Are we currently editting a new plane that is not yet in the list? */
|
|
|
|
|
|
|
|
if ((g_edit_mode == EDITMODE_NEW) && (g_edit_plane == hplane))
|
|
|
|
{
|
|
|
|
ptr = &g_edit_rect;
|
|
|
|
|
|
|
|
if (tcl_check_vertical_rectangle(w, ptr, pos))
|
|
|
|
{
|
|
|
|
pixel = w->colorLookup[ndx + SRECT_COLOR];
|
|
|
|
tcl_paint_vertical_rectangle(w, ptr, hoffset, voffset, pixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|