Hi ACagliano,
I think there are formulas to write arctan with others trigonometric functions.
Maybe it can help you.
I think there are formulas to write arctan with others trigonometric functions.
Maybe it can help you.
const char cosLUT[72] = {127, 126, 125, 122, 119, 115, 109, 104, 97, 89, 81, 72, 63, 53, 43, 32, 22, 11, 0, -11, -22, -32, -43, -53, -63, -72, -81, -89, -97, -104, -109, -115, -119, -122, -125, -126, -127, -126, -125, -122, -119, -115, -109, -104, -97, -89, -81, -72, -63, -53, -43, -32, -22, -11, 0, 11, 22, 32, 43, 53, 63, 72, 81, 89, 97, 104, 109, 115, 119, 122, 125, 126};
const char sinLUT[72] = {0, 11, 22, 32, 43, 53, 63, 72, 81, 89, 97, 104, 109, 115, 119, 122, 125, 126, 127, 126, 125, 122, 119, 115, 109, 104, 97, 89, 81, 72, 63, 53, 43, 32, 22, 11, 0, -11, -22, -32, -43, -53, -63, -72, -81, -89, -97, -104, -109, -115, -119, -122, -125, -126, -127, -126, -125, -122, -119, -115, -109, -104, -97, -89, -81, -72, -63, -53, -43, -32, -22, -11};
const int arctanLUT[18] = {0, 11, 22, 34, 46, 59, 73, 88, 106, 126, 151, 181, 219, 272, 348, 473, 720, 1451};
signed char byteCos(unsigned char x){
return cosLUT[x];
}
signed char byteSin(unsigned char x){
return sinLUT[x];
}
char byteATan(long non_x, long x){
char index = 17, quadrant;
int value;
if(x == 0){ // handle infinity
if(non_x > 0) return 18; // 90 degrees
if(non_x < 0) return 54; // 270 degrees
}
if(non_x == 0){
if(x > 0) return 0;
if(x < 0) return 36;
}
if(non_x > 0 && x > 0) quadrant = 0;
else if(non_x > 0 && x < 0) quadrant = 1;
else if(non_x < 0 && x < 0) quadrant = 2;
else quadrant = 3;
if(!(quadrant & 1)) value = abs(127 * non_x / x);
else value = abs(127 * x / non_x);
while(index >= 0){
if(value >= arctanLUT[index]) break;
index--;
}
return 18 * quadrant + index;
}
void GUI_PrepareFrame(MapData_t *map, renderitem_t *renderbuffer, Position_t *playerpos, framedata_t* frame){
char i, count = 0, scale;
double val = 180/M_PI;
unsigned long player_x = playerpos->coords.x;
unsigned long player_y = playerpos->coords.y;
unsigned long player_z = playerpos->coords.y;
unsigned long item_x, item_y, item_z;
long distance_x, distance_y, distance_z;
unsigned long distance;
memset(renderbuffer, 0, sizeof(renderitem_t) * 20);
for(i=0; i<20; i++){
MapData_t *item = &map[i];
item_x = item->position.coords.x;
item_y = item->position.coords.y;
item_z = item->position.coords.z;
distance_x = item_x - player_x;
distance_y = item_y - player_y;
distance_z = item_z - player_z;
distance = (long)sqrt(r_GetDistance(distance_x, distance_y, distance_z));
if(distance < RENDER_DISTANCE){
char objectvect_xz = byteATan(distance_z, distance_x);
char objectvect_y = byteATan(distance_y, distance_x);
char diff_xz = objectvect_xz - playerpos->angles.xz;
char diff_y = objectvect_y - playerpos->angles.y;
//objectvect_xz = AngleOpsBounded(objectvect_xz, -1 * playerpos->angles.xz);
//objectvect_y = AngleOpsBounded(objectvect_y, -1 * playerpos->angles.y);
//vectordiff_xz = AngleOpsBounded(objectvect_xz, playerpos->angles.xz);
// vectordiff_y = AngleOpsBounded(objectvect_y, playerpos->angles.y);
if((abs(diff_xz) <= 9) && (abs(diff_y) <= 9)){
int vcenter = vHeight>>1 + yStart;
renderitem_t *render = &renderbuffer[count++];
render->spriteid = item->entitytype-1;
render->distance = (RENDER_DISTANCE - distance) * 100 / RENDER_DISTANCE;
diff_xz += 10;
render->x = vWidth * diff_xz / 19;
diff_y += 10;
render->y = (vHeight * diff_y / 19);
}
}
}
frame->count = count;
if(count){
heapsort(renderbuffer, count);
for(i = 0; i < count; i++){
renderitem_t *render = &renderbuffer[i];
if(render->spriteid){
gfx_sprite_t* sprite = (gfx_sprite_t*)trekvfx[render->spriteid];
gfx_sprite_t* uncompressed;
gfx_sprite_t* scaled;
char scale = render->distance;
int width, height;
switch(render->spriteid){
case et_ship-1:
uncompressed = gfx_MallocSprite(64, 32);
break;
default:
uncompressed = gfx_MallocSprite(32, 32);
}
zx7_Decompress(uncompressed, sprite);
//if(scale != -1){
width = uncompressed->width * scale / 100;
height = uncompressed->height * scale / 100;
scaled = gfx_MallocSprite(width, height);
scaled->width = width;
scaled->height = height;
gfx_ScaleSprite(uncompressed, scaled);
gfx_TransparentSprite(scaled, render->x - (scaled->width>>1), render->y - (scaled->height>>1));
free(scaled);
// }
free(uncompressed);
//render->type; // use this to locate sprite
}
}
}
}
void map_MoveObjects(MapData_t* map, char tick){
char i;
for(i = 0; i < 20; i++){
MapData_t *entity = &map[i];
if(entity->entitytype){
if(entity->mobile){
if(!tick) proc_MoveEntity(&entity->position, entity->speed>>1);
else proc_MoveEntity(&entity->position, entity->speed % 2);
if(!entity->entitystats.weapon.range--) memset(entity, 0, sizeof(MapData_t));
}
}
}
}
void proc_MoveEntity(Position_t *pos, char speed){
int coord_x = pos->coords.x, coord_y = pos->coords.y, coord_z = pos->coords.z;
int vector_x = pos->vectors.x, vector_y = pos->vectors.y, vector_z = pos->vectors.z;
coord_x += (speed * vector_x);
coord_y += (speed * vector_y);
coord_z += (speed * vector_z);
pos->coords.x = coord_x;
pos->coords.y = coord_y;
pos->coords.z = coord_z;
}
void AnglesToVectors(Position_t *pos){
// this is how i convert angles to vectors
// x and z are divided by 127 to ensure the value remains N/127
// a byte overflow doesn't guarantee this
// y is not /127 because it's return will always be in range
unsigned char xzangle = pos->angles.xz, yangle = pos->angles.y;
pos->vectors.x = byteCos(xzangle) * byteCos(yangle) / 127;
pos->vectors.z = byteSin(xzangle) * byteCos(yangle) / 127;
pos->vectors.y = byteSin(yangle);
//pos->vectors[2] = z vector
}
const int arctanLUT[64] = {0, 3, 6, 9, 12, 15, 18, 22, 25, 28, 31, 35, 38, 41, 45, 48, 52, 56, 60, 63, 67, 71, 76, 80, 84, 89, 94, 99, 104, 109, 115, 120, 126, 133, 140, 147, 154, 162, 171, 180, 190, 200, 211, 224, 237, 252, 268, 286, 306, 329, 354, 384, 418, 458, 507, 565, 638, 731, 856, 1029, 1289, 1721, 2585, 5173};
unsigned char byteATan(long non_x, long x){
char index = 63, quadrant;
int value;
if(x == 0){ // handle infinity
if(non_x > 0) return 63; // 90 degrees
if(non_x < 0) return 191; // 270 degrees
}
if(non_x == 0){
if(x >= 0) return 0;
if(x < 0) return 127;
}
if(non_x > 0 && x > 0) quadrant = 0;
else if(non_x > 0 && x < 0) quadrant = 1;
else if(non_x < 0 && x < 0) quadrant = 2;
else quadrant = 3;
if(!(quadrant & 1)) value = abs(127 * non_x / x);
else value = abs(127 * x / non_x);
while(index > 0){
if(value >= arctanLUT[index]) break;
index--;
}
return 64 * quadrant + index;
}
const int arctanLUT[64] = {0, 3, 6, 9, 12, 15, 18, 22, 25, 28, 31, 35, 38, 41, 45, 48, 52, 56, 60, 63, 67, 71, 76, 80, 84, 89, 94, 99, 104, 109, 115, 120, 126, 133, 140, 147, 154, 162, 171, 180, 190, 200, 211, 224, 237, 252, 268, 286, 306, 329, 354, 384, 418, 458, 507, 565, 638, 731, 856, 1029, 1289, 1721, 2585, 5173};
unsigned char byteATan(long non_x, long x){
char index = 63, quadrant;
int value;
if(!x && !non_x) return 0;
if(!x){ // handle infinity
if(non_x > 0) return 63; // 90 degrees
if(non_x < 0) return 191; // 270 degrees
}
if(non_x >= 0 && x > 0) quadrant = 0;
else if(non_x > 0 && x < 0) quadrant = 1;
else if(non_x < 0 && x < 0) quadrant = 2;
else quadrant = 3;
if(!(quadrant & 1)) value = abs(127 * non_x / x);
else value = abs(127 * x / non_x);
while(index > 0){
if(value >= arctanLUT[index]) break;
index--;
}
return 64 * quadrant + index;
}
#ifndef ships_h
#define ships_h
#include "tech.h"
// POWER CONTROL STRUCTURE
#define DRAW_CORE 0
#define DRAW_AUX 1
#define DRAW_RESERVE 2
typedef struct {
char priority; // determines which module draws power first
signed int capacity; // how much power a module can store
signed int current; // the amount of power the module currently has
signed int baseusage; // baseline power usage
signed int usage; // how much power the module expends when active
bool alwaysUse; // boolean to specify if the module is always using power when active
char drawFrom;
} power_t;
// Related Functions
signed int power_GetBatteryPercent(power_t* power);
signed int power_GetExpendPercent(power_t* power);
//bool power_ExpendThisCycle(power_t* power);
//bool power_ReserveThisCycle(power_t* power);
void power_SetDraw(power_t* power, char source);
#define power_SetDrawCore(power_t* power) \
power_SetDraw(power_t* power, DRAW_CORE)
#define power_SetDrawAux(power_t* power) \
power_SetDraw(power_t* power, DRAW_AUX)
#define power_SetDrawReserve(power_t* power) \
power_SetDraw(power_t* power, DRAW_RESERVE)
// HEALTH MONITORING STRUCTURE
typedef struct {
signed int max;
signed int current;
} health_t;
// Related Functions
signed int health_GetHealthPercent(health_t* health);
void health_DamageModule(health_t* health, int amount);
#define health_RepairModule(health_t* health, int amount) \
health_DamageModule(health_t* health, (-amount));
// Module Online States
#define STATE_OFFLINE 0
#define STATE_ONLINE 1
#define STATE_REPAIRING 2
// Module Set State Error Codes
#define SETSTATE_SUCCESS 0
#define SETSTATE_NOPOWER 1
#define SETSTATE_NOHEALTH 2
// Module Effectiveness Step Values
#define STEP_DEFAULT 20
#define STEP_MID 10
#define STEP_LOW 5
typedef struct {
unsigned char techclass; // locked, determines compatible module classes
unsigned char type; // locked, determines compatible modules
unsigned char techid; // corresponds to equipped tech id (tech.h)
char online; // is module online
power_t power; // power control
health_t health; // health monitor
stats_t stats;
} module_t;
char module_GetOnlineState(module_t* module); // return online, offline, or repairing
char module_SetOnlineState(module_t* module, char state); // set module state or return no power or no health
int module_GetEffectiveness(module_t* module, char steps); // get % effectiveness of module
#define module_CopyData(module_t* module, module_t* source) \
memcpy((module), (source), (sizeof(module_t));
typedef struct {
module_t integrity;
module_t warpcore;
module_t warpdrive;
module_t impulsedrive;
module_t lifesupport;
module_t sensors;
module_t transporters;
module_t tactical[6]; // tactical or shield modules
module_t misc[3]; // miscellaneous modules
} ship_t;
// Core system defines
#define integrity (module_t*)&ship->integrity;
#define warpcore (module_t*)&ship->warpcore;
#define warpdrive (module_t*)&ship->warpdrive;
#define impulsedrive (module_t*)&ship->impulsedrive;
#define lifesupport (module_t*)&ship->lifesupport;
#define sensors (module_t*)&ship->sensors;
#define transporters (module_t*)&ship->transporters;
#endif
void* module_GetDataPtr(module_t* module);
void* module_GetSysDataPtr(module_t* module, unsigned char type);
void* module_GetTactDataPtr(module_t* module, unsigned char type);
Advertisement