00001
00002
00003
00004
00005
00006 #define C_RUNCTRL_SOURCE
00007
00008 #include "coordinate_ctrl.h"
00009 #include "commandCtrl.h"
00010 #include "move_ctrl.h"
00011 #include <stdio.h>
00012 #include <math.h>
00013
00014 enum { NO_OFFSET_DATA = -1 };
00015
00016
00017 #define CRD_EFFECT_CALL \
00018 if (crdEffectMode) { \
00019 int c_x, c_y, c_div16; \
00020 int crd_id, crd_x, crd_y, crd_div16; \
00021 run_getLastCommandPosition(&crd_id, &crd_x, &crd_y, &crd_div16); \
00022 run_getCoordinateOffset(&c_x,&c_y,&c_div16,GL,crd_id,crd_x,crd_y,crd_div16); \
00023 sendChangeCoordinateOffset(c_x, c_y, c_div16); \
00024 }
00025
00026
00027 static offsetInfo_t *CrdInfo = NULL;
00028 static int CrdInfoMax = 0;
00029 static int CrdInfoNext = 0;
00030 static int crdEffectMode = CRD_EFFECT_OFF;
00031
00032
00033 static void initOffsetInfo(offsetInfo_t *offset) {
00034 offset->parent_id = GL;
00035 offset->x = 0;
00036 offset->y = 0;
00037 offset->div16 = 0;
00038 }
00039
00040
00049 void _initCoordinateCtrl(offsetInfo_t *crdInfo, int num) {
00050 int i;
00051
00052 CrdInfo = crdInfo;
00053 CrdInfoMax = num;
00054
00055 for (i = 0; i < num; ++i) {
00056 CrdInfo[i].parent_id = NO_OFFSET_DATA;
00057 }
00058
00059
00060 initOffsetInfo(&CrdInfo[GL]);
00061 initOffsetInfo(&CrdInfo[FS]);
00062 CrdInfo[FS].parent_id = GL;
00063 CrdInfoNext = 2;
00064 }
00065
00066
00067
00068
00069
00070
00071
00082 int run_getBodyPos(int dest_id, int *x, int *y, int *div16) {
00083 int gl_x, gl_y;
00084 long gl_div16;
00085
00086 int ret_value = recvGetPosition(&gl_x, &gl_y, &gl_div16);
00087 if (ret_value < 0) {
00088 return ret_value;
00089 }
00090 if (dest_id == FS) {
00091 run_updateParentOffset(dest_id, gl_x, gl_y, gl_div16);
00092 *x = 0;
00093 *y = 0;
00094 *div16 = 0;
00095
00096 } else if (dest_id != GL) {
00097
00098 ret_value = run_getCoordinateOffset(x, y, div16, dest_id,
00099 GL, gl_x, gl_y, gl_div16);
00100 } else {
00101 *x = gl_x;
00102 *y = gl_y;
00103 *div16 = gl_div16;
00104 }
00105 return ret_value;
00106 }
00107
00108
00115 int run_createCoordinate(void) {
00116 int i;
00117 for (i = 0; i <= CrdInfoNext; ++i) {
00118 if (CrdInfo[i].parent_id == NO_OFFSET_DATA) {
00119 initOffsetInfo(&CrdInfo[i]);
00120 return i;
00121 }
00122 }
00123 return -1;
00124 }
00125
00126
00134 int run_deleteCoordinate(int crd_id) {
00135 CrdInfo[crd_id].parent_id = NO_OFFSET_DATA;
00136 return 0;
00137 }
00138
00139
00149 int run_getParentId(int crd_id) {
00150 return CrdInfo[crd_id].parent_id;
00151 }
00152
00153
00154 int run_getGLCoordinateOffset(int *offset_x, int *offset_y,
00155 int *offset_div16,
00156 int dest_id, int x, int y, int div16) {
00157 offsetInfo_t diff;
00158 int id;
00159
00160 diff.x = x;
00161 diff.y = y;
00162 diff.div16 = div16;
00163
00164 id = dest_id;
00165 while (id != GL) {
00166 int x_tmp = diff.x;
00167 int y_tmp = diff.y;
00168 double radian = 2.0 * M_PI * CrdInfo[id].div16 / 0x10000;
00169 diff.x = (int)(x_tmp * cos(radian) - y_tmp * sin(radian)) + CrdInfo[id].x;
00170 diff.y = (int)(x_tmp * sin(radian) + y_tmp * cos(radian)) + CrdInfo[id].y;
00171 diff.div16 += CrdInfo[dest_id].div16;
00172 id = CrdInfo[id].parent_id;
00173 }
00174
00175 *offset_x = diff.x;
00176 *offset_y = diff.y;
00177 *offset_div16 = diff.div16 & 0xffff;
00178
00179 return 0;
00180 }
00181
00182
00187 int run_getCoordinateOffset(int *offset_x, int *offset_y,
00188 int *offset_div16, int base_id,
00189 int target_id, int x, int y, int div16) {
00190 offsetInfo_t base_offset, this_offset;
00191 int x_diff, y_diff;
00192 double radian;
00193
00194
00195 if (base_id == GL) {
00196 return run_getGLCoordinateOffset(offset_x, offset_y, offset_div16,
00197 target_id, x, y, div16);
00198 }
00199 run_getCoordinateOffset(&base_offset.x, &base_offset.y, &base_offset.div16,
00200 GL, base_id, 0, 0, 0);
00201 run_getCoordinateOffset(&this_offset.x, &this_offset.y, &this_offset.div16,
00202 GL, target_id, x, y, div16);
00203
00204 x_diff = this_offset.x - base_offset.x;
00205 y_diff = this_offset.y - base_offset.y;
00206 *offset_div16 = (this_offset.div16 - base_offset.div16) & 0xffff;
00207
00208
00209 radian = 2.0 * M_PI * *offset_div16 / 0x10000;
00210 *offset_x = (int)(x_diff * cos(radian) - y_diff * sin(radian));
00211 *offset_y = (int)(x_diff * sin(radian) + y_diff * cos(radian));
00212
00213 return 0;
00214
00215 #if 0
00216 int diff_x = x;
00217 int diff_y = y;
00218 int diff_div16 = div16;
00219 int crd_id = target_id;
00220
00221 while (crd_id == GL) {
00222 int x_tmp = diff_x;
00223 int y_tmp = diff_y;
00224 double radian = 2.0 * M_PI * CrdInfo[crd_id].div16 / 65536;
00225
00226 diff_x = (int)(x_tmp * cos(radian) - y_tmp * sin(radian));
00227 diff_y = (int)(x_tmp * sin(radian) + y_tmp * cos(radian));
00228 diff_x += CrdInfo[crd_id].x;
00229 diff_y += CrdInfo[crd_id].y;
00230 diff_div16 += CrdInfo[crd_id].div16;
00231
00232 crd_id = CrdInfo[crd_id].parent_id;
00233 }
00234
00235 *offset_x = diff_x;
00236 *offset_y = diff_y;
00237 *offset_div16 = diff_div16 & 0xffff;
00238 return 0;
00239 #endif
00240 }
00241
00242
00252 int run_updateParentOffset(int dest_id, int x, int y, int div16) {
00253 int ret_value;
00254
00255 if (dest_id == GL) {
00256 ret_value = sendChangeCoordinateOffset(x, y, div16);
00257 if (ret_value < 0) {
00258 return ret_value;
00259 }
00260 } else {
00261 CrdInfo[dest_id].x = x;
00262 CrdInfo[dest_id].y = y;
00263 CrdInfo[dest_id].div16 = div16;
00264 }
00265
00266 CRD_EFFECT_CALL;
00267
00268 return 0;
00269 }
00270
00271
00272
00286 int run_setCoordinateParent(int dest_id, int parent_id,
00287 int x, int y, int div16) {
00288 int id;
00289
00290 if ((dest_id == GL) || (dest_id == FS)) {
00291 return -1;
00292 }
00293
00294
00295 if (dest_id == parent_id) {
00296 offsetInfo_t offset = CrdInfo[dest_id];
00297 double radian = 2.0 * M_PI * offset.div16 / 0x10000;
00298 offset.x += (int)(x * cos(radian) - y * sin(radian));
00299 offset.y += (int)(x * sin(radian) + y * cos(radian));
00300 offset.div16 += div16;
00301
00302
00303
00304
00305
00306 return run_updateParentOffset(dest_id, offset.x, offset.y, offset.div16);
00307 }
00308
00309
00310 for (id = dest_id; dest_id != GL; dest_id = CrdInfo[dest_id].parent_id) {
00311 if (dest_id == parent_id) {
00312 return -1;
00313 }
00314 }
00315
00316 CrdInfo[dest_id].parent_id = parent_id;
00317 CrdInfo[dest_id].x = x;
00318 CrdInfo[dest_id].y = y;
00319 CrdInfo[dest_id].div16 = div16;
00320
00321 CRD_EFFECT_CALL;
00322
00323 return 0;
00324 }
00325
00326
00337 int run_setCoordinateBody(int dest_id, int x, int y, int div16) {
00338 int pos_x, pos_y, pos_div16;
00339 int ret_value;
00340
00341 if ((dest_id == GL) || (dest_id == FS)) {
00342 return -1;
00343 }
00344
00345 ret_value = run_getBodyPos(dest_id, &pos_x, &pos_y, &pos_div16);
00346 if (ret_value < 0) {
00347 return ret_value;
00348 }
00349
00350 return run_setCoordinateParent(dest_id, CrdInfo[dest_id].parent_id,
00351 pos_x, pos_y, pos_div16);
00352 }
00353
00354
00368 int run_adjustBodyPos(int x, int y, int div16) {
00369
00370 CRD_EFFECT_CALL
00371
00372 return -1;
00373 }
00374
00375
00382 int run_setCoordinateMode(int mode) {
00383 crdEffectMode = (mode == CRD_EFFECT_ON) ? CRD_EFFECT_ON : CRD_EFFECT_OFF;
00384 return 0;
00385 }
00386