This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/deps/odoors/ODWin.c

320 lines
10 KiB
C
Raw Normal View History

2016-12-03 05:08:50 +00:00
/* OpenDoors Online Software Programming Toolkit
* (C) Copyright 1991 - 1999 by Brian Pirie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* File: ODWin.c
*
* Description: Implements the od_window_...() functions for creating
* and removing text-mode windows.
*
* Revisions: Date Ver Who Change
* ---------------------------------------------------------------
* Oct 13, 1994 6.00 BP New file header format.
* Nov 01, 1994 6.00 BP Include stdlib.h for malloc prototype.
* Dec 09, 1994 6.00 BP Standardized coding style.
* Dec 12, 1994 6.00 BP Set od_error on window remove failure.
* Aug 19, 1995 6.00 BP 32-bit portability.
* Nov 16, 1995 6.00 BP Removed oddoor.h, added odcore.h.
* Dec 12, 1995 6.00 BP Added entry, exit and kernel macros.
* Dec 30, 1995 6.00 BP Added ODCALL for calling convention.
* Feb 19, 1996 6.00 BP Changed version number to 6.00.
* Mar 03, 1996 6.10 BP Begin version 6.10.
* Aug 10, 2003 6.23 SH *nix support
*/
#define BUILDING_OPENDOORS
#include <string.h>
#include <stdlib.h>
#include "OpenDoor.h"
#include "ODGen.h"
#include "ODCore.h"
#include "ODKrnl.h"
/* ----------------------------------------------------------------------------
* od_window_create()
*
* Creates a window on the screen, storing information on the original screen
* contents "under" the window in order to restore the screen after the window
* is removed. A window that is created with this function must be destroyed
* by od_window_remove() in order to free up memory that is allocated by this
* function.
*
* Parameters: nLeft - 1-based column number of left edge of window.
*
* nTop - 1-based row number of top edge of window.
*
* nRight - 1-based column number of right edge of window.
*
* nBottom - 1-based row number of bottom edge of window.
*
* pszTitle - Pointer to a string containing title for window.
* If this string is empty, no title is displayed.
*
* btBoarderCol - Colour of window boarder.
*
* btTitleCol - Colour of window title.
*
* btInsideCol - Colour of rest of window.
*
* nReserved - Should always be 0 for this version.
*
* Return: Pointer to window description buffer (which must later be
* passed to od_window_remove(), or NULL on failure.
*/
ODAPIDEF void * ODCALL od_window_create(INT nLeft, INT nTop, INT nRight,
INT nBottom, char *pszTitle, BYTE btBorderCol, BYTE btTitleCol,
BYTE btInsideCol, INT nReserved)
{
BYTE btLine;
BYTE btBetweenSize;
void *pBuffer;
BYTE btTitleSize;
BYTE btRemaining;
/* Log function entry if running in trace mode. */
TRACE(TRACE_API, "od_window_create()");
/* Ensure that OpenDoors has been initialized */
if(!bODInitialized) od_init();
OD_API_ENTRY();
nReserved &= 0x00;
btBetweenSize = (nRight - nLeft) - 1;
/* Setup od_box_chars appropriately. */
if(od_control.od_box_chars[BOX_BOTTOM]==0)
{
od_control.od_box_chars[BOX_BOTTOM] = od_control.od_box_chars[BOX_TOP];
}
if(od_control.od_box_chars[BOX_RIGHT]==0)
{
od_control.od_box_chars[BOX_RIGHT] = od_control.od_box_chars[BOX_LEFT];
}
/* Ensure that the current display mode can support the capabilities */
/* required to display and remove windows. */
if(!(od_control.user_ansi || od_control.user_avatar))
{
od_control.od_error = ERR_NOGRAPHICS;
OD_API_EXIT();
return(NULL);
}
/* Validate parameters. */
if(nLeft < 1 || nTop < 1 || nRight > 80 || nBottom > 25 || nRight-nLeft < 2
|| nBottom-nTop < 2)
{
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(NULL);
}
/* Allocate a buffer large enough to hold all window information. */
if((pBuffer = malloc((nRight - nLeft + 1) * 2 + (nBottom - nTop + 1) * 160
+ 4)) == NULL)
{
od_control.od_error = ERR_MEMORY;
OD_API_EXIT();
return(NULL);
}
/* Store current contents of screen where window will be drawn. */
if(!od_gettext(nLeft, nTop, nRight, nBottom, (char *)pBuffer+4))
{
free(pBuffer);
/* Note: od_control.od_error code has been set by od_gettext(). */
OD_API_EXIT();
return(NULL);
}
/* Store window information in buffer. */
((char *)pBuffer)[0]=nLeft;
((char *)pBuffer)[1]=nTop;
((char *)pBuffer)[2]=nRight;
((char *)pBuffer)[3]=nBottom;
/* Determine number of characters of title to display. */
if(pszTitle==NULL)
{
btTitleSize = 0;
}
else
{
if((btTitleSize = strlen(pszTitle)) > (btBetweenSize - 4))
{
btTitleSize = btBetweenSize - 4;
}
}
/* Move to position of window's top corner, prepare to begin drawing the */
/* window. */
od_set_cursor(nTop,nLeft);
od_set_attrib(btBorderCol);
/* Display corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERLEFT]);
/* If there is no title, display top line all in one piece. */
if(btTitleSize == 0)
{
/* Display top line. */
od_repeat(od_control.od_box_chars[BOX_TOP],btBetweenSize);
}
else
{
/* If there is a title, display the top line with a title centered in */
/* it. */
od_repeat(od_control.od_box_chars[BOX_TOP],btRemaining =
((btBetweenSize - btTitleSize - 2) / 2));
od_set_attrib(btTitleCol);
od_putch(' ');
od_disp(pszTitle,btTitleSize,TRUE);
od_putch(' ');
od_set_attrib(btBorderCol);
od_repeat(od_control.od_box_chars[BOX_TOP],
(BYTE)(btBetweenSize - btRemaining - btTitleSize - 2));
}
/* Display top right corner character. */
od_putch(od_control.od_box_chars[BOX_UPPERRIGHT]);
/* If AVATAR mode is available. */
if(od_control.user_avatar)
{
/* Display first left verticle line. */
od_set_cursor(nTop + 1, nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Fill in center of window with AVATAR clear area control sequence. */
od_emulate(22);
od_emulate(12);
od_emulate(btInsideCol);
od_emulate((BYTE)((nBottom - nTop) - 1));
od_emulate(btBetweenSize);
od_set_attrib(btBorderCol);
od_set_cursor(nTop + 1 , nRight);
/* Display first right verticle line. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
/* Display remaining verticle lines. */
for(btLine=nTop+2;btLine<nBottom;++btLine)
{
/* Move to line start and display left line character. */
od_set_cursor(btLine,nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Move to line start and display right line character. */
od_set_cursor(btLine,nRight);
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* If AVATAR mode is not available. */
else
{
/* Loop through middle lines of window. */
for(btLine=nTop+1;btLine<nBottom;++btLine)
{
/* Move to line start and display left line character. */
od_set_cursor(btLine,nLeft);
od_putch(od_control.od_box_chars[BOX_LEFT]);
/* Set window colour. */
od_set_attrib(btInsideCol);
/* display blank area between left and right vertical lines. */
od_repeat(' ',btBetweenSize);
/* Set border colour. */
od_set_attrib(btBorderCol);
/* Display right line. */
od_putch(od_control.od_box_chars[BOX_RIGHT]);
}
}
/* Display bottom border of window */
od_set_cursor(nBottom,nLeft);
od_putch(od_control.od_box_chars[BOX_LOWERLEFT]);
od_repeat(od_control.od_box_chars[BOX_BOTTOM],btBetweenSize);
od_putch(od_control.od_box_chars[BOX_LOWERRIGHT]);
/* Return a pointer to the window information buffer. */
OD_API_EXIT();
return(pBuffer);
}
/* ----------------------------------------------------------------------------
* od_window_remove()
*
* Removes window from the screen, restoring the screen contents that where
* in the window area when the window was first created.
*
* Parameters: pWinInfo - Pointer to buffer returned by od_window_create().
* This buffer is deallocated before od_window_remove()
* returns.
*
* Return: TRUE on success, or FALSE on failure.
*/
ODAPIDEF BOOL ODCALL od_window_remove(void *pWinInfo)
{
/* Log function entry if running in trace mode */
TRACE(TRACE_API, "od_window_remove()");
/* Ensure that OpenDoors has been initialized */
if(!bODInitialized) od_init();
OD_API_ENTRY();
if(pWinInfo == NULL)
{
/* Set error code and return with failure. */
od_control.od_error = ERR_PARAMETER;
OD_API_EXIT();
return(FALSE);
}
if(!od_puttext(((char *)pWinInfo)[0], ((char *)pWinInfo)[1], ((char *)pWinInfo)[2], ((char *)pWinInfo)[3], (char *)pWinInfo + 4))
{
/* Deallocate memory assigned to window information structure. */
free(pWinInfo);
/* Note: od_control.od_error code has been set by od_puttext(). */
/* Return with failure. */
OD_API_EXIT();
return(FALSE);
}
/* Deallocate memory assigned to window information structure. */
free(pWinInfo);
/* Return with success. */
OD_API_EXIT();
return(TRUE);
}