summaryrefslogtreecommitdiff
path: root/src/uqm/units.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/units.h')
-rw-r--r--src/uqm/units.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/uqm/units.h b/src/uqm/units.h
new file mode 100644
index 0000000..93d903c
--- /dev/null
+++ b/src/uqm/units.h
@@ -0,0 +1,227 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * 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.
+ */
+
+#ifndef UQM_UNITS_H_
+#define UQM_UNITS_H_
+
+#include "libs/gfxlib.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern int ScreenWidth;
+extern int ScreenHeight;
+
+#define SCREEN_WIDTH ScreenWidth
+#define SCREEN_HEIGHT ScreenHeight
+#define SAFE_X 0
+ /* Left and right screen margin to be left unused */
+#define SAFE_Y 0
+ /* Top and bottom screen margin to be left unused */
+#define SIS_ORG_X (7 + SAFE_X)
+#define SIS_ORG_Y (10 + SAFE_Y)
+#define STATUS_WIDTH 64
+ /* Width of the status "window" (the right part of the screen) */
+#define STATUS_HEIGHT (SCREEN_HEIGHT - (SAFE_Y * 2))
+ /* Height of the status "window" (the right part of the screen) */
+#define SPACE_WIDTH (SCREEN_WIDTH - STATUS_WIDTH - (SAFE_X * 2))
+ /* Width of the space "window" (the left part of the screen) */
+#define SPACE_HEIGHT (SCREEN_HEIGHT - (SAFE_Y * 2))
+ /* Height of the space "window" (the left part of the screen) */
+#define SIS_SCREEN_WIDTH (SPACE_WIDTH - 14)
+ /* Width of the usable part of the space "window" */
+#define SIS_SCREEN_HEIGHT (SPACE_HEIGHT - 13)
+ /* Height of the usable part of the space "window" */
+#define RADAR_X (4 + (SCREEN_WIDTH - STATUS_WIDTH - SAFE_X))
+#define RADAR_WIDTH (STATUS_WIDTH - 8)
+#define RADAR_HEIGHT 53
+#define RADAR_Y (SIS_ORG_Y + SIS_SCREEN_HEIGHT - RADAR_HEIGHT)
+
+#define SIS_TITLE_BOX_WIDTH 57
+#define SIS_TITLE_WIDTH (SIS_TITLE_BOX_WIDTH - 2)
+#define SIS_TITLE_HEIGHT 8
+#define SIS_SPACER_BOX_WIDTH 12
+#define SIS_MESSAGE_BOX_WIDTH (SIS_SCREEN_WIDTH - SIS_TITLE_BOX_WIDTH \
+ - SIS_SPACER_BOX_WIDTH)
+#define SIS_MESSAGE_WIDTH (SIS_MESSAGE_BOX_WIDTH - 2)
+#define SIS_MESSAGE_HEIGHT SIS_TITLE_HEIGHT
+
+#define STATUS_MESSAGE_WIDTH (STATUS_WIDTH - 4)
+#define STATUS_MESSAGE_HEIGHT 7
+
+#define SHIP_NAME_WIDTH (STATUS_WIDTH - 4)
+#define SHIP_NAME_HEIGHT 7
+
+#define MAX_REDUCTION 3
+#define MAX_VIS_REDUCTION 2
+#define REDUCTION_SHIFT 1
+#define NUM_VIEWS (MAX_VIS_REDUCTION + 1)
+
+#define ZOOM_SHIFT 8
+#define MAX_ZOOM_OUT (1 << (ZOOM_SHIFT + MAX_REDUCTION - 1))
+
+#define ONE_SHIFT 2
+#define BACKGROUND_SHIFT 3
+#define SCALED_ONE (1 << ONE_SHIFT)
+#define DISPLAY_TO_WORLD(x) ((x)<<ONE_SHIFT)
+#define WORLD_TO_DISPLAY(x) ((x)>>ONE_SHIFT)
+#define DISPLAY_ALIGN(x) ((COORD)(x)&~(SCALED_ONE-1))
+#define DISPLAY_ALIGN_X(x) ((COORD)((COUNT)(x)%LOG_SPACE_WIDTH)&~(SCALED_ONE-1))
+#define DISPLAY_ALIGN_Y(y) ((COORD)((COUNT)(y)%LOG_SPACE_HEIGHT)&~(SCALED_ONE-1))
+
+#define LOG_SPACE_WIDTH \
+ (DISPLAY_TO_WORLD (SPACE_WIDTH) << MAX_REDUCTION)
+#define LOG_SPACE_HEIGHT \
+ (DISPLAY_TO_WORLD (SPACE_HEIGHT) << MAX_REDUCTION)
+#define TRANSITION_WIDTH \
+ (DISPLAY_TO_WORLD (SPACE_WIDTH) << MAX_VIS_REDUCTION)
+#define TRANSITION_HEIGHT \
+ (DISPLAY_TO_WORLD (SPACE_HEIGHT) << MAX_VIS_REDUCTION)
+
+#define MAX_X_UNIVERSE 9999
+#define MAX_Y_UNIVERSE 9999
+// Due to the added rounding error correction, the maximum logical X and Y
+// in Hyperspace cannot go past 999.94999, otherwise the values will be
+// rounded up to 1000.0. We do not want that so we subtract half a unit.
+#define MAX_X_LOGICAL \
+ (UNIVERSE_TO_LOGX (MAX_X_UNIVERSE + 1) - (UNIVERSE_TO_LOGX (1) >> 1) \
+ - 1L)
+// The Y axis is inverted with respect to the screen Y axis.
+// (MAX_Y_UNIVERSE - 1) is really 1 for our purposes.
+#define MAX_Y_LOGICAL \
+ (UNIVERSE_TO_LOGY (-1) - (UNIVERSE_TO_LOGY (MAX_Y_UNIVERSE - 1) >> 1) \
+ - 1L)
+
+#define SPHERE_RADIUS_INCREMENT 11
+
+#define MAX_FLEET_STRENGTH (254 * SPHERE_RADIUS_INCREMENT)
+
+// XXX: These corrected for the weird screen aspect ratio on DOS
+// In part because of them, hyperflight is slower vertically
+#define UNIT_SCREEN_WIDTH 63
+#define UNIT_SCREEN_HEIGHT 50
+
+// Bug #945: Simplified, these set the speed of SIS in Hyperspace and
+// Quasispace. The ratio between UNIVERSE_UNITS_ and LOG_UNITS_ is
+// what sets the speed, and it should be 1:16 to match the original.
+// The unit factors are reduced to keep the translation math within
+// 32 bits. The original math is unnecessarily complex and depends
+// on the screen resolution when it should not.
+// Using the new math will break old savegames.
+#ifdef NORMALIZED_HYPERSPACE_SPEED
+#define LOG_UNITS_X ((SDWORD)(UNIVERSE_UNITS_X * 16))
+#define LOG_UNITS_Y ((SDWORD)(UNIVERSE_UNITS_Y * 16))
+#define UNIVERSE_UNITS_X (((MAX_X_UNIVERSE + 1) >> 4))
+#define UNIVERSE_UNITS_Y (((MAX_Y_UNIVERSE + 1) >> 4))
+#else
+// Original (and now broken) Hyperspace speed factors
+#define SECTOR_WIDTH 195
+#define SECTOR_HEIGHT 25
+
+#define LOG_UNITS_X ((SDWORD)(LOG_SPACE_WIDTH >> 4) * SECTOR_WIDTH)
+#define LOG_UNITS_Y ((SDWORD)(LOG_SPACE_HEIGHT >> 4) * SECTOR_HEIGHT)
+#define UNIVERSE_UNITS_X (((MAX_X_UNIVERSE + 1) >> 4) * 10)
+#define UNIVERSE_UNITS_Y (((MAX_Y_UNIVERSE + 1) >> 4))
+#endif
+
+#define ROUNDING_ERROR(div) ((div) >> 1)
+
+static inline COORD
+logxToUniverse (SDWORD lx)
+{
+ return (COORD) ((lx * UNIVERSE_UNITS_X + ROUNDING_ERROR(LOG_UNITS_X))
+ / LOG_UNITS_X);
+}
+#define LOGX_TO_UNIVERSE(lx) \
+ logxToUniverse (lx)
+static inline COORD
+logyToUniverse (SDWORD ly)
+{
+ return (COORD) (MAX_Y_UNIVERSE -
+ ((ly * UNIVERSE_UNITS_Y + ROUNDING_ERROR(LOG_UNITS_Y))
+ / LOG_UNITS_Y));
+}
+#define LOGY_TO_UNIVERSE(ly) \
+ logyToUniverse (ly)
+static inline SDWORD
+universeToLogx (COORD ux)
+{
+ return (ux * LOG_UNITS_X + ROUNDING_ERROR(UNIVERSE_UNITS_X))
+ / UNIVERSE_UNITS_X;
+}
+#define UNIVERSE_TO_LOGX(ux) \
+ universeToLogx (ux)
+static inline SDWORD
+universeToLogy (COORD uy)
+{
+ return ((MAX_Y_UNIVERSE - uy) * LOG_UNITS_Y
+ + ROUNDING_ERROR(UNIVERSE_UNITS_Y))
+ / UNIVERSE_UNITS_Y;
+}
+#define UNIVERSE_TO_LOGY(uy) \
+ universeToLogy (uy)
+
+#define CIRCLE_SHIFT 6
+#define FULL_CIRCLE (1 << CIRCLE_SHIFT)
+#define OCTANT_SHIFT (CIRCLE_SHIFT - 3) /* (1 << 3) == 8 */
+#define HALF_CIRCLE (FULL_CIRCLE >> 1)
+#define QUADRANT (FULL_CIRCLE >> 2)
+#define OCTANT (FULL_CIRCLE >> 3)
+
+#define FACING_SHIFT 4
+
+#define ANGLE_TO_FACING(a) (((a)+(1<<(CIRCLE_SHIFT-FACING_SHIFT-1))) \
+ >>(CIRCLE_SHIFT-FACING_SHIFT))
+#define FACING_TO_ANGLE(f) ((f)<<(CIRCLE_SHIFT-FACING_SHIFT))
+
+#define NORMALIZE_ANGLE(a) ((COUNT)((a)&(FULL_CIRCLE-1)))
+#define NORMALIZE_FACING(f) ((COUNT)((f)&((1 << FACING_SHIFT)-1)))
+
+#define DEGREES_TO_ANGLE(d) NORMALIZE_ANGLE((((d) % 360) * FULL_CIRCLE \
+ + HALF_CIRCLE) / 360)
+#define ANGLE_TO_DEGREES(d) (NORMALIZE_ANGLE(d) * 360 / FULL_CIRCLE)
+
+#define SIN_SHIFT 14
+#define SIN_SCALE (1 << SIN_SHIFT)
+#define INT_ADJUST(x) ((x)<<SIN_SHIFT)
+#define FLT_ADJUST(x) (SIZE)((x)*SIN_SCALE)
+#define UNADJUST(x) (SIZE)((x)>>SIN_SHIFT)
+#define ROUND(x,y) ((x)+((x)>=0?((y)>>1):-((y)>>1)))
+
+extern SIZE sinetab[];
+#define SINVAL(a) sinetab[NORMALIZE_ANGLE(a)]
+#define COSVAL(a) SINVAL((a)+QUADRANT)
+#define SINE(a,m) ((SIZE)((((long)SINVAL(a))*(long)(m))>>SIN_SHIFT))
+#define COSINE(a,m) SINE((a)+QUADRANT,m)
+extern COUNT ARCTAN (SIZE delta_x, SIZE delta_y);
+
+#define WRAP_VAL(v,w) ((COUNT)((v)<0?((v)+(w)):((v)>=(w)?((v)-(w)):(v))))
+#define WRAP_X(x) WRAP_VAL(x,LOG_SPACE_WIDTH)
+#define WRAP_Y(y) WRAP_VAL(y,LOG_SPACE_HEIGHT)
+#define WRAP_DELTA_X(dx) ((dx)<0 ? \
+ ((-(dx)<=LOG_SPACE_WIDTH>>1)?(dx):(LOG_SPACE_WIDTH+(dx))) : \
+ (((dx)<=LOG_SPACE_WIDTH>>1)?(dx):((dx)-LOG_SPACE_WIDTH)))
+#define WRAP_DELTA_Y(dy) ((dy)<0 ? \
+ ((-(dy)<=LOG_SPACE_HEIGHT>>1)?(dy):(LOG_SPACE_HEIGHT+(dy))) : \
+ (((dy)<=LOG_SPACE_HEIGHT>>1)?(dy):((dy)-LOG_SPACE_HEIGHT)))
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* UQM_UNITS_H_ */