599 lines
26 KiB
C++
599 lines
26 KiB
C++
|
//
|
||
|
// Copyright 2020 Electronic Arts Inc.
|
||
|
//
|
||
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code 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 3 of the License, or (at your option) any later version.
|
||
|
|
||
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
||
|
// in the hope that it will be useful, but with permitted additional restrictions
|
||
|
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||
|
// distributed with this program. You should have received a copy of the
|
||
|
// GNU General Public License along with permitted additional restrictions
|
||
|
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||
|
|
||
|
/* $Header: F:\projects\c&c\vcs\code\coord.cpv 2.18 16 Oct 1995 16:51:24 JOE_BOSTIC $ */
|
||
|
/***********************************************************************************************
|
||
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||
|
***********************************************************************************************
|
||
|
* *
|
||
|
* Project Name : Command & Conquer *
|
||
|
* *
|
||
|
* File Name : COORD.CPP *
|
||
|
* *
|
||
|
* Programmer : Joe L. Bostic *
|
||
|
* *
|
||
|
* Start Date : September 10, 1993 *
|
||
|
* *
|
||
|
* Last Update : January 7, 1995 [JLB] *
|
||
|
* *
|
||
|
* Support code to handle the coordinate system is located in this module. *
|
||
|
* Routines here will be called QUITE frequently during play and must be *
|
||
|
* as efficient as possible. *
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
|
||
|
* Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
|
||
|
* Coord_Scatter -- Determines a random coordinate from an anchor point. *
|
||
|
* Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
|
||
|
* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
#include "function.h"
|
||
|
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
* Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
|
||
|
* *
|
||
|
* This routine will take an arbitrary position and object size and return with a list of *
|
||
|
* cell offsets from the current cell for all cells that are overlapped by the object. The *
|
||
|
* first cell offset is always zero, so to just get the adjacent spill cell list, add one *
|
||
|
* to the return pointer. *
|
||
|
* *
|
||
|
* INPUT: coord -- The coordinate to examine. *
|
||
|
* *
|
||
|
* maxsize -- The maximum width/height of the object (pixels). *
|
||
|
* *
|
||
|
* OUTPUT: Returns with a pointer to a spillage list. *
|
||
|
* *
|
||
|
* WARNINGS: The algorithm is limited to working with a maxsize of 48 or less. Larger values *
|
||
|
* will generate an incomplete overlap list. *
|
||
|
* *
|
||
|
* HISTORY: *
|
||
|
* 11/06/1993 JLB : Created. *
|
||
|
* 03/25/1994 JLB : Added width optimization. *
|
||
|
* 04/29/1994 JLB : Converted to C. *
|
||
|
* 06/03/1994 JLB : Converted to general purpose spillage functionality. *
|
||
|
* 01/07/1995 JLB : Manually calculates spillage list for large objects. *
|
||
|
*=============================================================================================*/
|
||
|
short const * Coord_Spillage_List(COORDINATE coord, int maxsize)
|
||
|
{
|
||
|
static short const _MoveSpillage[(int)FACING_COUNT+1][5] = {
|
||
|
{0, -MAP_CELL_W, REFRESH_EOL, 0, 0}, // N
|
||
|
{0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL}, // NE
|
||
|
{0, 1, REFRESH_EOL, 0, 0}, // E
|
||
|
{0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL}, // SE
|
||
|
{0, MAP_CELL_W, REFRESH_EOL, 0, 0}, // S
|
||
|
{0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL}, // SW
|
||
|
{0, -1, REFRESH_EOL, 0, 0}, // W
|
||
|
{0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL}, // NW
|
||
|
{0, REFRESH_EOL, 0, 0, 0} // non-moving.
|
||
|
// {0, -MAP_CELL_W, -(MAP_CELL_W-1), 1, MAP_CELL_W+1, MAP_CELL_W, MAP_CELL_W-1, -1, -(MAP_CELL_W+1), REFRESH_EOL}
|
||
|
};
|
||
|
static short _manual[10];
|
||
|
//; 00 = on axis
|
||
|
//; 01 = below axis
|
||
|
//; 10 = above axis
|
||
|
//; 11 = undefined
|
||
|
static char const _SpillTable[16] = {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1};
|
||
|
int index=0;
|
||
|
int x,y;
|
||
|
|
||
|
/*
|
||
|
** For mondo-enourmo-gigundo objects, use a prebuilt mammoth table
|
||
|
** that covers a 5x5 square region.
|
||
|
*/
|
||
|
if (maxsize > ICON_PIXEL_W * 2) {
|
||
|
static short const _gigundo[] = {
|
||
|
-((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2),
|
||
|
-((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2),
|
||
|
-((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2),
|
||
|
((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2),
|
||
|
+((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2),
|
||
|
REFRESH_EOL
|
||
|
};
|
||
|
return(&_gigundo[0]);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** For very large objects, build the overlap list by hand. This is time consuming, but
|
||
|
** not nearly as time consuming as drawing even a single cell unnecessarily.
|
||
|
*/
|
||
|
if (maxsize > ICON_PIXEL_W) {
|
||
|
maxsize = MIN(maxsize, (ICON_PIXEL_W*2))/2;
|
||
|
|
||
|
x = Fixed_To_Cardinal(ICON_PIXEL_W, Coord_XLepton(coord));
|
||
|
y = Fixed_To_Cardinal(ICON_PIXEL_H, Coord_YLepton(coord));
|
||
|
int left = x-maxsize;
|
||
|
int right = x+maxsize;
|
||
|
int top = y-maxsize;
|
||
|
int bottom = y+maxsize;
|
||
|
|
||
|
_manual[index++] = 0;
|
||
|
if (left < 0) _manual[index++] = -1;
|
||
|
if (right >= ICON_PIXEL_W) _manual[index++] = 1;
|
||
|
if (top < 0) _manual[index++] = -MAP_CELL_W;
|
||
|
if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W;
|
||
|
if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1);
|
||
|
if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1;
|
||
|
if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1;
|
||
|
if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1);
|
||
|
_manual[index] = REFRESH_EOL;
|
||
|
return(&_manual[0]);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Determine the number of leptons "leeway" allowed this unit.
|
||
|
*/
|
||
|
int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2];
|
||
|
|
||
|
x = Coord_XLepton(coord) - 0x0080;
|
||
|
y = Coord_YLepton(coord) - 0x0080;
|
||
|
if (y > posval) index |= 0x08; // Spilling South.
|
||
|
if (y < -posval) index |= 0x04; // Spilling North.
|
||
|
if (x > posval) index |= 0x02; // Spilling East.
|
||
|
if (x < -posval) index |= 0x01; // Spilling West.
|
||
|
|
||
|
return(&_MoveSpillage[_SpillTable[index]][0]);
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
* Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
|
||
|
* *
|
||
|
* This function will move a coordinate in a using SIN and COS arithmetic. *
|
||
|
* *
|
||
|
* INPUT: start -- The starting coordinate. *
|
||
|
* *
|
||
|
* dir -- The direction to move the coordinate. *
|
||
|
* *
|
||
|
* distance -- The distance to move the coordinate position (in leptons). *
|
||
|
* *
|
||
|
* OUTPUT: Returns the new coordinate position. *
|
||
|
* *
|
||
|
* WARNINGS: This routine uses multiplies -- use with caution. *
|
||
|
* *
|
||
|
* HISTORY: *
|
||
|
* 05/27/1994 JLB : Created. *
|
||
|
*=============================================================================================*/
|
||
|
COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance)
|
||
|
{
|
||
|
short x = Coord_X(start);
|
||
|
short y = Coord_Y(start);
|
||
|
|
||
|
Move_Point(x, y, dir, distance);
|
||
|
return(XY_Coord(x,y));
|
||
|
#ifdef NEVER
|
||
|
static char const CosTable[256] = {
|
||
|
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
|
||
|
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
|
||
|
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
|
||
|
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
|
||
|
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
|
||
|
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
|
||
|
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
|
||
|
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
|
||
|
|
||
|
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
|
||
|
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
|
||
|
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
|
||
|
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
|
||
|
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
|
||
|
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
|
||
|
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
|
||
|
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
|
||
|
|
||
|
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
|
||
|
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
|
||
|
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
|
||
|
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
|
||
|
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
|
||
|
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
|
||
|
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
|
||
|
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
|
||
|
|
||
|
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
|
||
|
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
|
||
|
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
|
||
|
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
|
||
|
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
|
||
|
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
|
||
|
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
|
||
|
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
|
||
|
};
|
||
|
|
||
|
static char const SinTable[256] = {
|
||
|
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
|
||
|
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
|
||
|
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
|
||
|
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
|
||
|
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
|
||
|
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
|
||
|
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
|
||
|
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
|
||
|
|
||
|
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
|
||
|
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
|
||
|
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
|
||
|
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
|
||
|
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
|
||
|
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
|
||
|
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
|
||
|
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
|
||
|
|
||
|
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
|
||
|
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
|
||
|
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
|
||
|
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
|
||
|
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
|
||
|
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
|
||
|
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
|
||
|
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
|
||
|
|
||
|
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
|
||
|
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
|
||
|
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
|
||
|
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
|
||
|
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
|
||
|
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
|
||
|
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
|
||
|
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
|
||
|
};
|
||
|
distance = distance; // Keep LINT quiet.
|
||
|
|
||
|
/*
|
||
|
** Calculate and add in the X component of the move.
|
||
|
*/
|
||
|
_AX = CosTable[dir];
|
||
|
asm imul word ptr distance
|
||
|
asm shl ax,1
|
||
|
asm rcl dx,1
|
||
|
asm mov al,ah
|
||
|
asm mov ah,dl
|
||
|
_DX = _AX;
|
||
|
*((int*)&start) += _DX;
|
||
|
// asm add [word ptr start],ax
|
||
|
|
||
|
/*
|
||
|
** Calculate and add in the Y component of the move.
|
||
|
*/
|
||
|
_AX = SinTable[dir];
|
||
|
asm imul word ptr distance
|
||
|
asm shl ax,1
|
||
|
asm rcl dx,1
|
||
|
asm mov al,ah
|
||
|
asm mov ah,dl
|
||
|
asm neg ax // Subtraction needed because of inverted sine table.
|
||
|
_DX = _AX;
|
||
|
*(((int*)&start)+1) += _DX;
|
||
|
// asm add [word ptr start+2],ax
|
||
|
|
||
|
return(start);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef OBSOLETE
|
||
|
//BG: Note, this routine is replaced by assembly in COORDA.ASM
|
||
|
/***********************************************************************************************
|
||
|
* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
|
||
|
* *
|
||
|
* This utility function will convert cardinal numbers into a fixed point fraction. The *
|
||
|
* use of fixed point numbers occurs throughout the product -- since it is a convenient *
|
||
|
* tool. The fixed point number is based on the formula: *
|
||
|
* *
|
||
|
* result = cardinal / base *
|
||
|
* *
|
||
|
* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to *
|
||
|
* 256 as the largest. *
|
||
|
* *
|
||
|
* INPUT: base -- The key number to base the fraction about. *
|
||
|
* *
|
||
|
* cardinal -- The other number (hey -- what do you call it?) *
|
||
|
* *
|
||
|
* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates *
|
||
|
* to the "base" parameter. *
|
||
|
* *
|
||
|
* WARNINGS: none *
|
||
|
* *
|
||
|
* HISTORY: *
|
||
|
* 05/27/1994 JLB : Created. *
|
||
|
*=============================================================================================*/
|
||
|
unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal)
|
||
|
{
|
||
|
long temp = 0;
|
||
|
|
||
|
if (base) {
|
||
|
*(unsigned*)(((char*)&temp)+1) = cardinal; // Shift up by 8 bits.
|
||
|
_DX = FP_SEG(temp);
|
||
|
_AX = FP_OFF(temp);
|
||
|
asm div word ptr base
|
||
|
return(_AX);
|
||
|
}
|
||
|
return(0xFFFF);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef OBSOLETE
|
||
|
//BG: Note, this routine is replaced by assembly in COORDA.ASM
|
||
|
/***********************************************************************************************
|
||
|
* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
|
||
|
* *
|
||
|
* Use this routine to convert a fixed point number into a cardinal number. *
|
||
|
* *
|
||
|
* INPUT: base -- The base number that the original fixed point number was created from. *
|
||
|
* *
|
||
|
* fixed -- The fixed point number to convert. *
|
||
|
* *
|
||
|
* OUTPUT: Returns with the reconverted number. *
|
||
|
* *
|
||
|
* WARNINGS: none *
|
||
|
* *
|
||
|
* HISTORY: *
|
||
|
* 05/27/1994 JLB : Created. *
|
||
|
*=============================================================================================*/
|
||
|
unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed)
|
||
|
{
|
||
|
unsigned long temp;
|
||
|
|
||
|
_AX = base;
|
||
|
asm mul word ptr fixed
|
||
|
_CX = _AX;
|
||
|
temp = ((unsigned long)MK_FP(_DX, _CX)) + 0x80;
|
||
|
if ( *((char*)&temp+3) ) {
|
||
|
return(0xFFFF);
|
||
|
}
|
||
|
return(*(unsigned*)(((char*)&temp)+1));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
* Coord_Scatter -- Determines a random coordinate from an anchor point. *
|
||
|
* *
|
||
|
* This routine will perform a scatter algorithm on the specified *
|
||
|
* anchor point in order to return with another coordinate that is *
|
||
|
* randomly nearby the original. Typical use of this would be for *
|
||
|
* missile targeting. *
|
||
|
* *
|
||
|
* INPUT: coord -- This is the anchor coordinate. *
|
||
|
* *
|
||
|
* distance -- This is the distance in pixels that the scatter *
|
||
|
* should fall within. *
|
||
|
* *
|
||
|
* lock -- bool; Convert the new coordinate into a center *
|
||
|
* cell based coordinate? *
|
||
|
* *
|
||
|
* OUTPUT: Returns with a new coordinate that is nearby the original. *
|
||
|
* *
|
||
|
* WARNINGS: Maximum pixel scatter distance is 255. *
|
||
|
* *
|
||
|
* HISTORY: *
|
||
|
* 02/01/1992 JLB : Created. *
|
||
|
* 05/13/1992 JLB : Only uses Random(). *
|
||
|
*=============================================================================================*/
|
||
|
COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock)
|
||
|
{
|
||
|
COORDINATE newcoord;
|
||
|
|
||
|
newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance);
|
||
|
|
||
|
if (newcoord & 0xC000C000L) newcoord = coord;
|
||
|
|
||
|
if (lock) {
|
||
|
newcoord = Coord_Snap(newcoord);
|
||
|
}
|
||
|
|
||
|
return(newcoord);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int __cdecl calcx(signed short param1, short distance)
|
||
|
{
|
||
|
__asm {
|
||
|
|
||
|
//#pragma aux calcx parm [ax] [bx] \
|
||
|
|
||
|
movzx eax, [param1]
|
||
|
mov bx, [distance]
|
||
|
imul bx
|
||
|
shl ax,1
|
||
|
rcl dx,1
|
||
|
mov al,ah
|
||
|
mov ah,dl
|
||
|
cwd
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int __cdecl calcy(signed short param1, short distance)
|
||
|
{
|
||
|
__asm {
|
||
|
|
||
|
//#pragma aux calcy parm [ax] [bx] \
|
||
|
|
||
|
movzx eax, [param1]
|
||
|
mov bx, [distance]
|
||
|
imul bx
|
||
|
shl ax,1
|
||
|
rcl dx,1
|
||
|
mov al,ah
|
||
|
mov ah,dl
|
||
|
cwd
|
||
|
neg eax
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#if (0)
|
||
|
extern int calcx(signed short, short distance);
|
||
|
#pragma aux calcx parm [ax] [bx] \
|
||
|
modify [eax dx] \
|
||
|
value [eax] = \
|
||
|
"imul bx" \
|
||
|
"shl ax,1" \
|
||
|
"rcl dx,1" \
|
||
|
"mov al,ah" \
|
||
|
"mov ah,dl" \
|
||
|
"cwd" \
|
||
|
// "and eax,0FFFFh";
|
||
|
|
||
|
extern int calcy(signed short, short distance);
|
||
|
#pragma aux calcy parm [ax] [bx] \
|
||
|
modify [eax dx] \
|
||
|
value [eax] = \
|
||
|
"imul bx" \
|
||
|
"shl ax,1" \
|
||
|
"rcl dx,1" \
|
||
|
"mov al,ah" \
|
||
|
"mov ah,dl" \
|
||
|
"cwd" \
|
||
|
"neg eax";
|
||
|
// "and eax,0FFFFh"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
void Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
|
||
|
{
|
||
|
// static char const CosTable[256] = {
|
||
|
static unsigned char const CosTable[256] = {
|
||
|
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
|
||
|
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
|
||
|
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
|
||
|
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
|
||
|
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
|
||
|
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
|
||
|
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
|
||
|
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
|
||
|
|
||
|
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
|
||
|
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
|
||
|
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
|
||
|
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
|
||
|
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
|
||
|
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
|
||
|
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
|
||
|
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
|
||
|
|
||
|
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
|
||
|
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
|
||
|
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
|
||
|
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
|
||
|
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
|
||
|
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
|
||
|
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
|
||
|
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
|
||
|
|
||
|
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
|
||
|
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
|
||
|
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
|
||
|
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
|
||
|
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
|
||
|
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
|
||
|
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
|
||
|
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
|
||
|
};
|
||
|
|
||
|
// static char const SinTable[256] = {
|
||
|
static unsigned char const SinTable[256] = {
|
||
|
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
|
||
|
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
|
||
|
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
|
||
|
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
|
||
|
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
|
||
|
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
|
||
|
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
|
||
|
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
|
||
|
|
||
|
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
|
||
|
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
|
||
|
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
|
||
|
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
|
||
|
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
|
||
|
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
|
||
|
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
|
||
|
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
|
||
|
|
||
|
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
|
||
|
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
|
||
|
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
|
||
|
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
|
||
|
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
|
||
|
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
|
||
|
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
|
||
|
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
|
||
|
|
||
|
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
|
||
|
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
|
||
|
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
|
||
|
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
|
||
|
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
|
||
|
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
|
||
|
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
|
||
|
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
|
||
|
};
|
||
|
distance = distance; // Keep LINT quiet.
|
||
|
|
||
|
#ifdef OBSOLETE
|
||
|
/*
|
||
|
** Calculate and add in the X component of the move.
|
||
|
*/
|
||
|
_AX = CosTable[dir];
|
||
|
asm imul word ptr distance
|
||
|
asm shl ax,1
|
||
|
asm rcl dx,1
|
||
|
asm mov al,ah
|
||
|
asm mov ah,dl
|
||
|
_DX = _AX;
|
||
|
x += _DX;
|
||
|
#else
|
||
|
//
|
||
|
// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
|
||
|
//
|
||
|
// ST - 1/10/2019 11:20AM
|
||
|
//
|
||
|
char *cos_table = (char*)&CosTable[0];
|
||
|
x += calcx(cos_table[dir], distance);
|
||
|
#endif
|
||
|
// asm add [word ptr start],ax
|
||
|
|
||
|
#ifdef OBSOLETE
|
||
|
/*
|
||
|
** Calculate and add in the Y component of the move.
|
||
|
*/
|
||
|
_AX = SinTable[dir];
|
||
|
asm imul word ptr distance
|
||
|
asm shl ax,1
|
||
|
asm rcl dx,1
|
||
|
asm mov al,ah
|
||
|
asm mov ah,dl
|
||
|
asm neg ax // Subtraction needed because of inverted sine table.
|
||
|
_DX = _AX;
|
||
|
y += _DX;
|
||
|
#else
|
||
|
//
|
||
|
// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
|
||
|
//
|
||
|
// ST - 1/10/2019 11:20AM
|
||
|
//
|
||
|
char *sin_table = (char*)&SinTable[0];
|
||
|
y += calcy(sin_table[dir], distance);
|
||
|
#endif
|
||
|
// asm add [word ptr start+2],ax
|
||
|
|
||
|
}
|