World map event scripting

  • Thread starter Thread starter luksy
  • Start date Start date
Status
Not open for further replies.
L

luksy

Guest
I've been poking around in the world map events, has anyone else had a look at the opcodes?

So far I have:

-----------------------------------
0x17
   !(bool) stack top (resulting value pushed as if 0x110 was used)
-----------------------------------
0x100
   Reset stack pointer to base (0xE3A7F0)
-----------------------------------
0x110
   Push value to stack as word
-----------------------------------
0x114
   Push value to stack as single bit from memory starting at offset *0xE3A7E0:
              addr           bit
   |0000000000000|000|
-----------------------------------
0x201
   if (!pop) jump to value as offset
-----------------------------------
0x203
   End script
-----------------------------------
0x307    
   0xDE6B5C = stack top // Enable / disable controls
   0xDFC4A8 = 3
-----------------------------------
0x32b // No idea
   e3a890 = stack top
-----------------------------------
0x321 // Again no idea

   *0xE2BB94 (ptr to 1 of 16 structs) = 0xE28CE0 + arg1 * 0x24
       
   val1 = *(*E2BB94 + 8) - *(*E39AD8 + C + 8)
   val2 = **E2BB94 - *(*E39AD8 + C)

   *(*0xE39AD8 + 4C) = *(*0xE39AD8 + 40) = *(*0xE39AD8 + 3C) =
   (((val1 << 8) / val2) *2) + 0xE37120

   *0xE39AD8 + 3E = 0
-----------------------------------
0x324
   Creates window using the top 4 values on stack, from bottom to top values are x, y, width, height
-----------------------------------
0x325
   Places text using index on top of stack, text is read from mes.
-----------------------------------
0x326
   Displays a question and saves user input (presumably to address on top of stack, haven't looked yet)
-----------------------------------

Stack base is always 0xE3A7F0, top of stack is stored at 0xE39ADC.
0x765E09 is a table of function pointers for 3xx opcodes.
0xE3A810 is a pointer to the current script op

The *.ev files have the following structure:

struct {

  struct {
    uint16_t id; // No idea yet
    uint16_t offset;
  } Header[0x100];

  uint16_t data[0x3600];
};
 
Last edited:
Cool, I actually had a look at the qGears source before, wonder why I didn't see that. Anyway I'm hoping to get the others done as well, maybe you'll find it useful too.
 
opcode 0x32d:

Code: [Select]
Code:
func 0x768E3D(int i){ int* j = *(i * 30 + 0x0CFF5E4) - 1;  if (*j > 12)  return 1;   switch(*j) {   case 0:   return 0;     case 1: case 3: case 5: case 7: case 10: case 12:   *j = 7;   return 1;     case 2: case 4: case 6: case 8: case 9: case 11:   return 1; }}func 0x75EF13(){ if (*0x0CFF5E4 && *0x0CFF5E4 != 7)  0x768E3D(0);  return !*0x0CFF5E4;}func 0x32d() // 0x765B86{ if (!*0xE3A7DC) {  uint16_t i = 0x75EF13();  *(*0xE39AD8 + 46) -= i  return i;   } return 0;}
 
This should be all the 0x1xx ops:

0x110 - Push value

0x114 - Push bit from memory @*0x0E3A7E0 + top 13 bits of value, which bit is bottom 3.

0x118 - Get byte from memory @*0x0E3A7E0 + value

0x11C - Get word from memory @*0x0E3A7E0 + value


0x113 / 0x117 / 0x11B Value between 0 and 20 results in an extended opcode that pushes information from memory, see code.

Code: [Select]
Code:
func 0x753B73() {  for (int i = 0; i < 0x20; ++i)  *((uint8_t*)0xE2B550 + i) ^= *((char*)0xE2B739 + i);  for (int i = 20; i < 0x209; ++i)  *((uint8_t*)0xE2B550 + i) ^= *((char*)0xE2B530 + i); }func popStack() // 0x76488C{ *pstack_top -= 8;  if ((push_op & 3) < 3) {  switch(push_op - 0x110) {     case 0:    return value;       case 4:    return (*(*0x0E3A7E0 + (value >> 3)) >> (value & 7)) & 1;      case 8:    return *(uint8_t*)(*0x0E3A7E0 + value);      case 0xC:    return *(uint16_t*)(*0x0E3A7E0 + value);      default:    return 0;  }   } else {    switch (value) {      case 0:    return *(*0xE39AD8 + 0xC) >> 0xD;      case 1:    return *(*0xE39AD8 + 0x14) >> 0xD;     case 2:    return *(*0xE39AD8 + 0xC) & 0x1FFF;      case 3:    return *(*0xE39AD8 + 0x14) & 0x1FFF;       case 4:    return (*(uint16_t*)(*0xE39AD8 + 0x40) >> 4) & 0xFF;      case 5:    return *0xE3A884;      case 6:    return *0xE3A894;           case 7:    return ((*(uint16_t*)0xE3A898 << 2) & 0xC) | (*0xDFC4B4 & 3);     case 8:        if (*0xE3A7D0)     return *(uint8_t*)(*0xE3A7D0 + 0x50);    return 0;        case 9:    return *(uint8_t*)0xDC0CD8;          case 0xA:    return !(*(uint16_t*)0xDB958A & 8);      case 0xB:    return *0xE2AB38;          case 0xC:    if (!*(uint16_t*)0xCFF5E4)     return -1;    return *(uint16_t*)0xE36104;      case 0xD:    return (*(uint16_t*)(*0xE39AD8 + 4A) >> 5) & 7;      case 0xE:        if (*(uint8_t*)0xDC09E5 == 2    ||  *(uint8_t*)0xDC09E6 == 2    ||  *(uint8_t*)0xDC09E7 == 2)     return 1;        if (*(uint8_t*)0xDC09E5 == 8    ||  *(uint8_t*)0xDC09E6 == 8    ||  *(uint8_t*)0xDC09E7 == 8)     return 2;        return 0;      case 0xF:    return *(uint8_t*)(*0xE39AD8 + 0x50);      case 0x10:       if ((*0xE2A138 += 1) >= 0x209) {     0x753B73();         *0xE2A138 = 0;    }        return *(uint8_t*)(*0xE2A138 + 0xE2B550);      case 0x11:    return *0xE39BA8;       case 0x12:    return *0xE39BAC;      case 0x13:    return *0xE39BA0;      case 0x14:    return *0xE39BA4;      default:    return 0;  }  }}
 
Last edited:
Status
Not open for further replies.
Back
Top