From e30af52b91bd3c84212b426af9e257a22af2383b Mon Sep 17 00:00:00 2001 From: Kp Date: Mon, 4 Aug 2014 03:07:06 +0000 Subject: [PATCH] Improve collision detection switch --- similar/main/collide.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/similar/main/collide.cpp b/similar/main/collide.cpp index 0334ee2b3..aac708203 100644 --- a/similar/main/collide.cpp +++ b/similar/main/collide.cpp @@ -81,6 +81,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "dxxsconf.h" #include "compiler-integer_sequence.h" +#include "compiler-static_assert.h" #include "compiler-type_traits.h" using std::min; @@ -2474,7 +2475,7 @@ static void collide_weapon_and_debris( object * weapon, objptridx_t debris, vms_ /* DPH: Put these macros on one long line to avoid CR/LF problems on linux */ -#define COLLISION_OF(a,b) (((a)<<8) + (b)) +#define COLLISION_OF(a,b) (((a)<<4) + (b)) #define DO_COLLISION(type1,type2,collision_function) \ case COLLISION_OF( (type1), (type2) ): \ @@ -2499,6 +2500,12 @@ static void collide_weapon_and_debris( object * weapon, objptridx_t debris, vms_ case COLLISION_OF( (type1), (type1) ): \ break; +template +struct assert_no_truncation +{ + static_assert(static_cast(V) == V, "truncation error"); +}; + void collide_two_objects( objptridx_t A, objptridx_t B, vms_vector *collision_point ) { if (B->type < A->type) @@ -2506,13 +2513,15 @@ void collide_two_objects( objptridx_t A, objptridx_t B, vms_vector *collision_ using std::swap; swap(A, B); } - unsigned at = A->type; + uint_fast8_t at = A->type; if (at >= MAX_OBJECT_TYPES) throw std::runtime_error("illegal object type"); - unsigned bt = B->type; + uint_fast8_t bt = B->type; if (bt >= MAX_OBJECT_TYPES) throw std::runtime_error("illegal object type"); - unsigned collision_type = COLLISION_OF(at, bt); + uint_fast8_t collision_type = COLLISION_OF(at, bt); + struct assert_object_type_not_truncated : std::pair, assert_no_truncation> {}; + struct assert_collision_of_not_truncated : assert_no_truncation {}; switch( collision_type ) { COLLISION_TABLE(NO,DO) default: @@ -2543,6 +2552,8 @@ COLLISION_TABLE(DISABLE, ENABLE); template static inline constexpr collision_inner_array_t collide_init(index_sequence c) { + static_assert(COLLISION_OF(R, 0) < COLLISION_OF(R, sizeof...(C) - 1), "ambiguous collision"); + static_assert(COLLISION_OF(R, sizeof...(C) - 1) < COLLISION_OF(R + 1, 0), "ambiguous collision"); return collision_inner_array_t{{ collision_result_t(R), static_cast(C)>::value... }};