设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
查看: 487|回复: 7

[编程算法] 【寻找逆向大佬中】关于HMX ecl opcode的求助

[复制链接]
发表于 2025-2-13 18:52:36 | 显示全部楼层 |阅读模式
本人技术宅,上个暑假写了个STG游戏的框架,准备把HMX移植到64位通用c99上(SDL2+openAL).
本体已经做完 在github repo但是对于opcode的一些细节产生了困难 比如
  1. #include <openstg.h>

  2. #define VOID enemy_data* enm
  3. #define P1 enemy_data* enm, param_t *p1
  4. #define P2 enemy_data* enm, param_t *p1, param_t *p2
  5. #define P3 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3
  6. #define P4 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4
  7. #define P5 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5
  8. #define P6 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5, param_t *p6
  9. #define P7 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5, param_t *p6, param_t *p7
  10. #define P8 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5, param_t *p6, param_t *p7, param_t *p8
  11. #define P9 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5, param_t *p6, param_t *p7, param_t *p8, param_t *p9
  12. #define P14 enemy_data* enm, param_t *p1, param_t *p2, param_t *p3, param_t *p4, param_t *p5, param_t *p6, param_t *p7, param_t *p8, param_t *p9, param_t *p10, param_t *p11, param_t *p12, param_t *p13, param_t *p14

  13. #define ECL_INS void

  14. // only void, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14
  15. int ins_arg_count[] =
  16.     { 0, 1, 2, 3, 2, 2, 2, 3, 2, 3, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3,
  17.         5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 5, 5, 5, 5, 5, 5, 3, 3, 2, 1, 1, 1,
  18.         2, 2, 3, 3, 3,
  19.         3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 4, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1,
  20.         0, 0, 0, 3, 8,
  21.         0, 1, 14, 14, 1, 2, 2, 4, 1, 1, 3, 0, 7, 0, 1, 5, 2, 1, 1, 5, 3, 1, 1,
  22.         1, 1, 1, 2, 1,
  23.         1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 2, 1, 6, 1, 0, 0,
  24.         1, 0
  25. };

  26. int read_int_var(enemy_data * enm, int var_id)
  27. {                                // only used to get int
  28.         if (var_id >= 0 && var_id < FIELD_RANK_ID) {
  29.                 // local var
  30.                 ecl_stack_frame *frame = &(enm->stack[enm->sp]);
  31.                 if (var_id <= 3) {
  32.                         return frame->i_local_grp_1[var_id];
  33.                 } else if (var_id <= 7) {
  34.                         return -1;
  35.                 } else {
  36.                         var_id -= 8;
  37.                         return frame->i_local_grp_2[var_id];
  38.                 }
  39.         }
  40.         switch (var_id) {
  41.         case FIELD_RANK_ID:{
  42.                         return rank;
  43.                 }
  44.         case FIELD_DIFFICULTY_ID:{
  45.                         return difficulty;
  46.                 }
  47.         case FIELD_TIME_ID:{
  48.                         return enm->tick;
  49.                 }
  50.         case FIELD_LIFE_ID:{
  51.                         return enm->life;
  52.                 }
  53.         case FIELD_SHOT_TYPE_ID:{
  54.                         return shot_type;
  55.                 }
  56.         }
  57.         return -1;
  58. }

  59. float read_float_var(enemy_data * enm, int var_id)
  60. {                                // only used to get float
  61.         if (var_id >= 0 && var_id < FIELD_RANK_ID) {
  62.                 // local var
  63.                 ecl_stack_frame *frame = &(enm->stack[enm->sp]);
  64.                 if (var_id <= 3) {
  65.                         return -NAN;
  66.                 } else if (var_id <= 7) {
  67.                         var_id -= 4;
  68.                         return frame->f_local_grp_1[var_id];
  69.                 } else {
  70.                         return -NAN;
  71.                 }
  72.         }
  73.         switch (var_id) {
  74.         case FIELD_X_ID:{
  75.                         return enm->x;
  76.                 }
  77.         case FIELD_Y_ID:{
  78.                         return enm->y;
  79.                 }
  80.         case FIELD_Z_ID:{
  81.                         return enm->z;
  82.                 }
  83.         case FIELD_PLAYER_X_ID:{
  84.                         return player_x;
  85.                 }
  86.         case FIELD_PLAYER_Y_ID:{
  87.                         return player_y;
  88.                 }
  89.         case FIELD_PLAYER_Z_ID:{
  90.                         return player_z;
  91.                 }
  92.         case FIELD_AIM_ID:{
  93.                         return enm->aim;
  94.                 }
  95.         case FIELD_DIST_ID:{
  96.                         return enm->dist;
  97.                 }
  98.         }
  99.         return -NAN;
  100. }

  101. void write_int_var(enemy_data * enm, int var_id, int data)
  102. {                                // only used to put int
  103.         if (var_id >= 0 && var_id < FIELD_RANK_ID) {
  104.                 // local var
  105.                 ecl_stack_frame *frame = &(enm->stack[enm->sp]);
  106.                 if (var_id <= 3) {
  107.                         frame->i_local_grp_1[var_id] = data;
  108.                         return;
  109.                 } else if (var_id <= 7) {
  110.                         return;
  111.                 } else {
  112.                         var_id -= 8;
  113.                         frame->i_local_grp_2[var_id] = data;
  114.                         return;
  115.                 }
  116.         }
  117.         switch (var_id) {
  118.         case FIELD_TIME_ID:{
  119.                         enm->tick = data;
  120.                         return;
  121.                 }
  122.         case FIELD_LIFE_ID:{
  123.                         enm->life = data;
  124.                         return;
  125.                 }
  126.         }
  127. }

  128. void write_float_var(enemy_data * enm, int var_id, float data)
  129. {                                // only used to put float
  130.         if (var_id >= 0 && var_id < FIELD_RANK_ID) {
  131.                 // local var
  132.                 ecl_stack_frame *frame = &(enm->stack[enm->sp]);
  133.                 if (var_id <= 3) {
  134.                         return;
  135.                 } else if (var_id <= 7) {
  136.                         var_id -= 4;
  137.                         frame->f_local_grp_1[var_id] = data;
  138.                         return;
  139.                 } else {
  140.                         return;
  141.                 }
  142.         }
  143.         switch (var_id) {
  144.         case FIELD_X_ID:{
  145.                         enm->x = data;
  146.                         return;
  147.                 }
  148.         case FIELD_Y_ID:{
  149.                         enm->y = data;
  150.                         return;
  151.                 }
  152.         case FIELD_Z_ID:{
  153.                         enm->z = data;
  154.                         return;
  155.                 }
  156.         case FIELD_PLAYER_X_ID:{
  157.                         player_x = data;
  158.                         return;
  159.                 }
  160.         case FIELD_PLAYER_Y_ID:{
  161.                         player_y = data;
  162.                         return;
  163.                 }
  164.         case FIELD_PLAYER_Z_ID:{
  165.                         player_z = data;
  166.                         return;
  167.                 }
  168.         }
  169. }

  170. ECL_INS nop(VOID)
  171. {
  172. }

  173. ECL_INS delete(P1)
  174. {
  175.         // TODO: finish this after bossrush finished
  176.         info("multi enemy not supported yet");
  177. }

  178. ECL_INS jmp(P2)
  179. {
  180.         write_int_var(enm, FIELD_TIME_ID, p1->i);
  181.         int ip = search_symbol(enm, p2->hash);
  182.         if (ip == -1) {
  183.                 ABORT("bad symbol");
  184.         }
  185.         enm->ip = ip - 1;
  186. }

  187. ECL_INS loop(P3)
  188. {
  189.         int cx = read_int_var(enm, p3->var_id);
  190.         if (cx == 0) {
  191.                 return;
  192.         }
  193.         write_int_var(enm, p3->var_id, cx - 1);
  194.         jmp(enm, p1, p2);
  195. }

  196. ECL_INS iset(P2)
  197. {
  198.         write_int_var(enm, p1->var_id, p2->i);
  199. }

  200. ECL_INS fset(P2)
  201. {
  202.         write_float_var(enm, p1->var_id, p2->f);
  203. }

  204. ECL_INS iset_r(P2)
  205. {
  206.         write_int_var(enm, p1->var_id, zundom_i(p2->i));
  207. }

  208. ECL_INS iset_r2(P3)
  209. {
  210.         write_int_var(enm, p1->var_id, zundom_i2(p2->i, p3->i));
  211. }

  212. ECL_INS fset_r(P2)
  213. {
  214.         write_float_var(enm, p1->var_id, zundom_f(p2->f));
  215. }

  216. ECL_INS fset_r2(P3)
  217. {
  218.         write_float_var(enm, p1->var_id, zundom_f2(p2->f, p3->f));
  219. }

  220. ECL_INS get_x(P1)
  221. {
  222.         write_float_var(enm, p1->var_id, enm->x);
  223. }

  224. ECL_INS get_y(P1)
  225. {
  226.         write_float_var(enm, p1->var_id, enm->y);
  227. }

  228. ECL_INS get_z(P1)
  229. {
  230.         write_float_var(enm, p1->var_id, enm->z);
  231. }

  232. ECL_INS iadd(P3)
  233. {
  234.         write_int_var(enm, p1->var_id, (p2->i) + (p3->i));
  235. }

  236. ECL_INS isub(P3)
  237. {
  238.         write_int_var(enm, p1->var_id, (p2->i) - (p3->i));
  239. }

  240. ECL_INS imul(P3)
  241. {
  242.         write_int_var(enm, p1->var_id, (p2->i) * (p3->i));
  243. }

  244. ECL_INS idiv(P3)
  245. {
  246.         write_int_var(enm, p1->var_id, (p2->i) / (p3->i));
  247. }

  248. ECL_INS imod(P3)
  249. {
  250.         write_int_var(enm, p1->var_id, (p2->i) % (p3->i));
  251. }

  252. ECL_INS inc(P1)
  253. {
  254.         if (p1->type == PARAM_TYPE_INT) {
  255.                 write_int_var(enm, p1->var_id,
  256.                               read_int_var(enm, p1->var_id) + 1);
  257.         } else if (p1->type == PARAM_TYPE_FLOAT) {
  258.                 write_float_var(enm, p1->var_id,
  259.                                 read_float_var(enm, p1->var_id) + 1.0f);
  260.         }
  261. }

  262. ECL_INS dec(P1)
  263. {
  264.         if (p1->type == PARAM_TYPE_INT) {
  265.                 write_int_var(enm, p1->var_id,
  266.                               read_int_var(enm, p1->var_id) - 1);
  267.         } else if (p1->type == PARAM_TYPE_FLOAT) {
  268.                 write_float_var(enm, p1->var_id,
  269.                                 read_float_var(enm, p1->var_id) - 1.0f);
  270.         }
  271. }

  272. ECL_INS fadd(P3)
  273. {
  274.         write_float_var(enm, p1->var_id, (p2->f) + (p3->f));
  275. }

  276. ECL_INS fsub(P3)
  277. {
  278.         write_float_var(enm, p1->var_id, (p2->f) - (p3->f));
  279. }

  280. ECL_INS fmul(P3)
  281. {
  282.         write_float_var(enm, p1->var_id, (p2->f) * (p3->f));
  283. }

  284. ECL_INS fdiv(P3)
  285. {
  286.         write_float_var(enm, p1->var_id, (p2->f) / (p3->f));
  287. }

  288. ECL_INS ecl_fmod(P3)                // name conflict by libm
  289. {                                // IEEE 754 remainder
  290.         write_float_var(enm, p1->var_id, IEEE_754_remainder(p2->f, p3->f));
  291. }

  292. ECL_INS ecl_atan2(P5)                // name conflict by libm
  293. {
  294.         write_float_var(enm, p1->var_id,
  295.                         atan((p4->f - p2->f) / (p5->f - p3->f)));
  296. }

  297. ECL_INS norm_r(P1)
  298. {
  299.         float f = read_float_var(enm, p1->var_id);
  300.         int pi_count = (int)(f / M_PI);
  301.         if (f <= 0.0f) {
  302.                 f += pi_count * M_PI;
  303.         } else {
  304.                 f -= pi_count * M_PI;
  305.         }
  306.         write_float_var(enm, p1->var_id, f);
  307. }

  308. ECL_INS itest(P2)
  309. {
  310.         if (p1->i < p2->i) {
  311.                 enm->cmp_reg = -1;
  312.         } else if (p1->i == p2->i) {
  313.                 enm->cmp_reg = 0;
  314.         } else {
  315.                 enm->cmp_reg = 1;
  316.         }
  317. }

  318. ECL_INS ftest(P2)
  319. {
  320.         if (p1->f < p2->f) {
  321.                 enm->cmp_reg = -1;
  322.         } else if (p1->f == p2->f) {
  323.                 enm->cmp_reg = 0;
  324.         } else if (p1->f > p2->f) {
  325.                 enm->cmp_reg = 1;
  326.         }
  327. }

  328. ECL_INS jmp_l(P2)
  329. {
  330.         if (enm->cmp_reg == -1) {
  331.                 jmp(enm, p1, p2);
  332.         }
  333. }

  334. ECL_INS jmp_le(P2)
  335. {
  336.         if (enm->cmp_reg == -1 || enm->cmp_reg == 0) {
  337.                 jmp(enm, p1, p2);
  338.         }
  339. }

  340. ECL_INS jmp_e(P2)
  341. {
  342.         if (enm->cmp_reg == 0) {
  343.                 jmp(enm, p1, p2);
  344.         }
  345. }

  346. ECL_INS jmp_g(P2)
  347. {
  348.         if (enm->cmp_reg == 1) {
  349.                 jmp(enm, p1, p2);
  350.         }
  351. }

  352. ECL_INS jmp_ge(P2)
  353. {
  354.         if (enm->cmp_reg == 0 || enm->cmp_reg == 1) {
  355.                 jmp(enm, p1, p2);
  356.         }
  357. }

  358. ECL_INS jmp_n(P2)
  359. {
  360.         if (enm->cmp_reg == -1 || enm->cmp_reg == 1) {
  361.                 jmp(enm, p1, p2);
  362.         }
  363. }

  364. ECL_INS call(P3)
  365. {
  366.         enm->sp++;
  367.         if (enm->sp >= MAX_STACK_DEPTH) {
  368.                 ABORT("stack overflow");
  369.         }
  370.         ecl_stack_frame *curr_stack = &(enm->stack[enm->sp]);
  371.         // enm->ip always point to currently executing instruction
  372.         // as ip will automaticly increase by 1 after any instruction exection
  373.         // point return addr to currently "call" and after "return", ip will point to the next ins after "call"
  374.         curr_stack->return_address = enm->ip;
  375.         // set param
  376.         curr_stack->i_local_grp_1[0] = p2->i;
  377.         curr_stack->f_local_grp_1[0] = p3->f;
  378.         curr_stack->return_function = enm->fp;
  379.         int ip = search_sub(p1->hash, &enm->fp);
  380.         if (ip == -1) {
  381.                 ABORT("bad sub");
  382.         }
  383.         enm->ip = ip - 1;
  384. }

  385. ECL_INS ret(VOID)
  386. {
  387.         if (enm->sp == 0 || (enm->stack)[enm->sp].return_address == -1
  388.             || (enm->stack)[enm->sp].return_function == -1) {
  389.                 ABORT("stack underflow");
  390.         }
  391.         enm->ip = (enm->stack)[enm->sp].return_address;
  392.         enm->fp = (enm->stack)[enm->sp].return_function;
  393.         enm->sp--;
  394.         info("%i %i", enm->fp, enm->ip);
  395. }

  396. ECL_INS call_l(P3)
  397. {
  398.         if (enm->cmp_reg == -1) {
  399.                 call(enm, p1, p2, p3);
  400.         }
  401. }

  402. ECL_INS call_le(P3)
  403. {
  404.         if (enm->cmp_reg == -1 || enm->cmp_reg == 0) {
  405.                 call(enm, p1, p2, p3);
  406.         }
  407. }

  408. ECL_INS call_e(P3)
  409. {
  410.         if (enm->cmp_reg == 0) {
  411.                 call(enm, p1, p2, p3);
  412.         }
  413. }

  414. ECL_INS call_g(P3)
  415. {
  416.         if (enm->cmp_reg == 1) {
  417.                 call(enm, p1, p2, p3);
  418.         }
  419. }

  420. ECL_INS call_ge(P3)
  421. {
  422.         if (enm->cmp_reg == 0 || enm->cmp_reg == 1) {
  423.                 call(enm, p1, p2, p3);
  424.         }
  425. }

  426. ECL_INS call_n(P3)
  427. {
  428.         if (enm->cmp_reg == -1 || enm->cmp_reg == 1) {
  429.                 call(enm, p1, p2, p3);
  430.         }
  431. }

  432. ECL_INS pos(P3)
  433. {
  434.         enm->x = p1->f;
  435.         enm->y = p2->f;
  436.         enm->z = p3->f;
  437. }

  438. ECL_INS dir(P2)
  439. {
  440.         enm->dir = p1->f;
  441.         enm->v = p2->f;
  442. }

  443. ECL_INS rot(P1)
  444. {
  445.         enm->delta_dir = p1->f;
  446. }

  447. ECL_INS spd(P1)
  448. {
  449.         enm->v = p1->f;
  450. }

  451. ECL_INS acc(P1)
  452. {
  453.         enm->deltav = p1->f;
  454. }

  455. ECL_INS rot_r(P2)
  456. {
  457.         enm->dir = zundom_f2(p1->f, p2->f);
  458. }

  459. ECL_INS rot_r2(P2)
  460. {
  461.         enm->dir = zundom_f2(p1->f, p2->f);
  462. }

  463. ECL_INS rot_aim(P2)
  464. {                                // document conflict between pytouhou(P2) and touhouwiki(P3)
  465.         enm->dir = player_angle((v2d) {
  466.                                 enm->x, enm->y}
  467.         ) + p1->f;
  468.         enm->v = p2->f;
  469. }

  470. // all acc and dec need test to match original game behavior
  471. ECL_INS it_dec(P3)
  472. {
  473.         enm->dir = p2->f;
  474.         enm->v = p3->f;
  475.         enm->deltav = -abs_f(enm->deltav);
  476. }

  477. ECL_INS it_dec2(P3)
  478. {

  479. }

  480. ECL_INS it_acc(P3)
  481. {

  482. }

  483. ECL_INS it_acc2(P3)
  484. {

  485. }

  486. ECL_INS it_pt_lin(P4)
  487. {

  488. }

  489. ECL_INS it_pt_dec(P4)
  490. {

  491. }

  492. ECL_INS it_pt_dec2(P4)
  493. {

  494. }

  495. ECL_INS it_pt_acc(P4)
  496. {

  497. }

  498. ECL_INS it_pt_acc2(P4)
  499. {

  500. }

  501. ECL_INS it_t_dec(P4)
  502. {

  503. }

  504. ECL_INS it_t_dec2(P4)
  505. {

  506. }

  507. ECL_INS it_t_acc(P4)
  508. {

  509. }

  510. ECL_INS it_t_acc2(P4)
  511. {

  512. }

  513. ECL_INS clip(P4)
  514. {
  515.         enm->is_clip = 1;
  516.         enm->clip_lu.x = p1->f;
  517.         enm->clip_lu.y = p2->f;
  518.         enm->clip_rd.x = p3->f;
  519.         enm->clip_rd.y = p4->f;
  520. }

  521. ECL_INS unclip(VOID)
  522. {
  523.         enm->is_clip = 0;
  524. }

  525. ECL_INS et_on_fan_aim(P9)
  526. {
  527.         create_buman();
  528.         bstyle(TRACE);
  529.         bshape(p2->i, p1->i);
  530.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  531.         bamount(p3->i, p4->i);
  532.         bspeed(p5->f, p6->f);
  533.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  534. }

  535. ECL_INS et_on_fan(P9)
  536. {
  537.         create_buman();
  538.         bstyle(DEFAULT);
  539.         bshape(p2->i, p1->i);
  540.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  541.         bamount(p3->i, p4->i);
  542.         bspeed(p5->f, p6->f);
  543.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  544. }

  545. ECL_INS et_on_cir_aim(P9)
  546. {
  547.         create_buman();
  548.         bstyle(LAYER_DIF_TRACE);
  549.         bshape(p2->i, p1->i);
  550.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  551.         bamount(p3->i, p4->i);
  552.         bspeed(p5->f, p6->f);
  553.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  554. }

  555. ECL_INS et_on_cir(P9)
  556. {
  557.         create_buman();
  558.         bstyle(LAYER_DIF);
  559.         bshape(p2->i, p1->i);
  560.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  561.         bamount(p3->i, p4->i);
  562.         bspeed(p5->f, p6->f);
  563.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  564. }

  565. ECL_INS et_on_random_r(P9)
  566. {
  567.         create_buman();
  568.         bstyle(RANDOM_DIR);
  569.         bshape(p2->i, p1->i);
  570.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  571.         bamount(p3->i, p4->i);
  572.         bspeed(p5->f, p6->f);
  573.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  574. }

  575. ECL_INS et_on_random_sp(P9)
  576. {
  577.         create_buman();
  578.         bstyle(RANDOM_SPEED);
  579.         bshape(p2->i, p1->i);
  580.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  581.         bamount(p3->i, p4->i);
  582.         bspeed(p5->f, p6->f);
  583.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  584. }

  585. ECL_INS et_on_random(P9)
  586. {
  587.         create_buman();
  588.         bstyle(RANDOM);
  589.         bshape(p2->i, p1->i);
  590.         boffset(enm->x + enm->launch_off_x, enm->y + enm->launch_off_y);
  591.         bamount(p3->i, p4->i);
  592.         bspeed(p5->f, p6->f);
  593.         bangle(rad2ang(p7->f), rad2ang(p8->f));
  594. }

  595. ECL_INS interrupt(P2)
  596. {
  597.         // int behave as jmp to sub
  598.         int ip = search_sub(p1->hash, &enm->fp);
  599.         if (ip == -1) {
  600.                 ABORT("bad sub")
  601.         }
  602.         enm->ip = ip - 1;
  603. }

  604. ECL_INS breakpoint(VOID)
  605. {
  606.         printf("STOP AT MAGIC BREAKPOINT\n");
  607.         is_step = 1;
  608. }

  609. void *ins_prg[] =
  610.     { nop, delete, jmp, loop, iset, fset, iset_r, iset_r2, fset_r, fset_r2,
  611.         get_x, get_y,
  612.         get_z, iadd, isub, imul, idiv, imod, inc, dec, fadd, fsub, fmul, fdiv,
  613.         fmod,
  614.         ecl_atan2, norm_r, itest, ftest, jmp_l, jmp_le, jmp_e, jmp_g, jmp_ge,
  615.         jmp_n, call, ret,
  616.         call_l, call_le,        // spectre instruction
  617.         call_e, call_g, call_ge, call_n, pos, NULL, dir, rot, spd, acc, rot_r,
  618.         rot_r2, rot_aim,
  619.         it_dec, it_dec2,
  620.         it_acc, it_acc2, it_pt_lin, it_pt_dec, it_pt_dec2, it_pt_acc,
  621.         it_pt_acc2, it_t_dec, it_t_dec2, it_t_acc, it_t_acc2, clip,
  622.         unclip, et_on_fan_aim,
  623.         et_on_fan, et_on_cir_aim, et_on_cir, NULL, NULL, et_on_random_r,
  624.         et_on_random_sp, et_on_random, NULL, NULL, NULL, NULL, NULL, NULL,
  625.         NULL, NULL, NULL,
  626.         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  627.         NULL, NULL, NULL,
  628.         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, interrupt, NULL,
  629.         NULL,
  630.         NULL, NULL, NULL,
  631.         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  632.         NULL, NULL, NULL, NULL,
  633.         NULL, NULL, NULL, NULL, NULL, breakpoint
  634. };
复制代码
中530行后有很多敌人移动等opcode在thwiki与外文wiki中没有对具体加速/速度的像素数作出解释
求逆向大佬可不可以翻出原版游戏的具体数值 谢谢
PS:当然我知道这种帖子肯定没人会看的了 只是希望出现奇迹(笑)

发表于 2025-2-13 20:06:03 | 显示全部楼层
不懂帮顶,或许你可以尝试用THTK自己拆包看看?
回复

使用道具 举报

 楼主| 发表于 2025-2-13 21:20:00 | 显示全部楼层
定难军节度使 发表于 2025-2-13 20:06
不懂帮顶,或许你可以尝试用THTK自己拆包看看?

这个不是ECL或者THTK可以拆出来的 是属于游戏EXE内的硬编码

点评

那就爱莫能助了,或许有其他的exe解包软件?  发表于 2025-2-13 21:27
回复

使用道具 举报

发表于 2025-3-11 01:03:28 | 显示全部楼层
Jar387 发表于 2025-2-13 21:20
这个不是ECL或者THTK可以拆出来的 是属于游戏EXE内的硬编码

目前来说对原作ecl比较有研究的佬在魔改群里,您可以来这个群里讨论一下:489710775
这群里的伙计很多对thbwiki上ecl代码资料的完善做出不少贡献,应该能解答你的问题。

点评

即便是问逆向相关的东西也可以来,因为写ecl资料本身就要对原作引擎作逆向,很多东西应该是可以帮你看一下。  发表于 2025-3-11 01:06
回复

使用道具 举报

发表于 2025-7-10 14:34:24 | 显示全部楼层
本帖最后由 Kuriyama_Mirai 于 2025-7-10 17:32 编辑

你听过 Happy Havoc 的 红魔乡逆向工程仓库

帮你问了一些大佬,zero318 说“你可能需要迁就一些剩下的 opcode 而更改大量的代码,
尤其是 Patchy 用的 ‘call stack disable flag’”。

他还在 这里 写过一个更可读的 ECL 解析器,尽管那个解析器不是为了 100% 准确地模拟而写的;
不过,至少里面的 instructions 都是基于对原作代码基于比较良好的理解而命名的。

那里面的很多目前的文档,据他所说,不够完整,甚至在一些细节上有错误。
回复

使用道具 举报

 楼主| 发表于 2025-7-14 07:31:07 来自手机 | 显示全部楼层
Kuriyama_Mirai 发表于 2025-7-10 14:34
你听过 Happy Havoc 的 红魔乡逆向工程仓库 吗

帮你问了一些大佬,zero318 说“你可能需要迁就一些剩下的  ...

非常感谢 不过有点晚了 我的那个项目已经2次重构 现在和原作ecl没关系 更像86汇编和一些渲染 弹幕utility的结合体
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 00:02

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表