-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Original game mechanics and Wiki discussion #178
Comments
This is great. I can make you a collaborator so you can add this and anything else you like to the wiki. |
Thanks. I've never edited a wiki before but I'll give it a shot later if you make me a collaborator. There's a few other things I've also found out that I can also add. |
@afritz1, I've added a new page with the above. I thought about where to put the spell points formula. I considered the existing pages but ended up making a new one called "Player and NPC stats". I was thinking it may be good to move the NPCStats information from "Save File Formats" into "Player and NPC stats", and then just refer to NPCStats by name (maybe a URL link if that is possible) in the "Save File Formats" page, but for now I won't touch any of the existing text. @Carmina16, I welcome your input if you would like to say anything. Also, things I add to the wiki will probably be a little bit inconsistent with the way Carmina16 wrote, in that I want to write pseudocode in C. Carmina16 put the offset locations of data as offsets from the start of the decompressed A.EXE (1.06) to the start of the data, whereas I was thinking of putting (as I did above) the offsets as they need to be entered in the As for this issue, for now I think I will keep it open as a place for discussion about original game mechanics and the wiki, if that is all right with you afritz1. |
Hmm, well it would be a pain to go back through all of the existing Wiki pages and make the offsets refer to the |
Changed the page to "Player stats" since NPC-specific stuff is already going in the "NPC" page. |
Added information on spell and regeneration assignment to the NPC page. |
Added information on the length of time that top-of-screen messages are shown to a new page called "Timing". |
@afritz1, do you receive notification when I add to the Wiki? If so, I won't bother mentioning here when I've added something. |
I get notices in my activity feed which is great. Thanks for adding all that stuff. I'm working on location refactoring right now but I will try getting to the things you added once I get that far. The reason why the aExeStrings.txt offsets are different from Carmina16's is because the PKLITE decompression code I implemented is missing a chunk of data -- I think it's the original game's executable code. It wasn't needed since we only need to decompress the original executables for the global constant data. |
I added lockpicking information, but unfortunately I don't know where the lockpicking difficulty of a door comes from yet. It's easiest to reverse the "end tips" of things that are closest to output, like code just before string messages that indicate success or failure. If you or Carmina16 know where door lockpicking difficulty comes from then you could probably get lockpicking running pretty quickly.
OK, I won't post here just to say when I added something anymore, then. |
I already have some code for lock difficulty. It comes from the level data in .MIF files.
OpenTESArena/OpenTESArena/src/World/LevelData.cpp Line 1056 in 9b885e1
|
You can add syntax highlighting to code blocks if you put the language right after the three back ticks. Like:
|
Thanks, I updated the pages and changed the data types like "byte" and "uint" to be primitive types like "unsigned char" and "unsigned int" so they will be highlighted as data types. |
Some unsolved problems I have on my mind that I just want to write down and maybe looking in the original executable would help. I didn't see them in the wiki anywhere but maybe I missed them: Interior raised platform texture coordinates (#129)
Wilderness raised platform sizes and heights (similar to #129) Moon 1 and 2 positions (uses strange integer coordinates but I couldn't get it to look right yet. Ideally we could figure out what those numbers mean in regular Vector3 values)
|
Those various arrays are |
Sorry, I meant that I have the arrays but I don't know how to interpret them for all cases -- for interior raised platforms and wilderness raised platforms. They seem to be interpreted differently. Here is where they are used currently:
|
I know that issue is for an interior, not the wilderness, and so this may not be useful, but does this snip from the original look to give the same results as what your code is doing? Decompiled original in pseudocode: if (worldType == WorldType::Wilderness)
{
for (int i = 0; i < 56; i++) // 56 entries covering Box 1A, 1B, 1C, 2A, 2B.
{
int value = BoxArrays[i] * 192;
BoxArrays[i] = value / 256 | (value / 512) * 256;
}
} Your code:
|
Looks useful but I don't immediately know how to work with |
By The calculations done are 16-bit, so I guess that shouldn't be an int. I'll change it to an unsigned short. Edit: The final value in Box1BWallHeightTable, 190h(400), will overflow beyond the 16-bit registers being used when multiplied by 192, so I wonder if it looks correct in the original game? |
Thanks, will look at it after this current attempt with city entrance jingles. |
Wait, sorry, it should be 32-bit after all. Changed it back to int. |
Another similar bit of code exists dealing with the BoxArrays. I think while the above matches your int a = funcCall() // This gets some value, it may be like your "inf.getCeiling().boxScale"
if (a < 33)
a = 100; // Don't know what this is
int b = -a; // Or this
int c = funcCall() // Same function as above. Gets the next value from the file?
if (c > 31) // I guess this value is like the "32" you use?
{
for (int i = 0; i < 56; i++) // 56 entries covering Box 1A, 1B, 1C, 2A, 2B.
{
int value = BoxArrays[i] * c;
BoxArrays[i] = value / 256 | (value / 512) * 256;
}
} With your familiarity with the code, I'm hoping maybe some of these values will be recognizable to you. Or maybe Carmina16 knows more. |
There is one other bit of code I can see regarding the BoxTables, which might be relevant to #129. Like the above snippets, I don't know what this data represents, but maybe with your knowledge you can recognize things and piece it together. if (*(unsigned char *)data != *(unsigned char *)(data + 1)) // If the next byte of some data (.INF or .MIF file?) being read differs from the current
{
int i = (*(unsigned int *)(data + 1) & 7); // Height index?
if (Player is outside) // Outside in city or in wilderness
{
if (Player is outside in city)
i += 8; // Use BoxB
else if (Player is outside in wilderness)
i += 16; // Use BoxC
}
short global1 = Box3AWallHeightTable[i] & 0x3f;
short global2 = Box1AWallHeightTable[i];
short global3 = -global2;
int index2 = *(unsigned int *)(data + 1) >> 3 & 0xf;
short global4 = Box4WallHeightTable[index2];
short global5 = 64 - (global4 + global1);
if (PlayerInWilderness)
index2 += 16; // Use BoxB
short global6 = Box2AWallHeightTable[index2] + global2;
short global7 = -global6;
short global8 = Unknown[(byte *)(data >> 4 & 0xf)]; // Unknown[] is an empty-at-start array.
unsigned char global9 = 1;
unsigned char global10 = 2;
short global11 = global7;
short global12 = global3;
} The above pseudocode allows spilling over from one array to another. So |
The layout seems to be: WORD dungeon_start[8];
WORD city_start[8];
WORD wilderness_start[8];
WORD interior_thickness[16];
WORD wilderness_thickness[16];
WORD source_copy[56]; // unscaled values of those above
WORD unknown1[8];
WORD unknown2[8];
BYTE unknown3[16]; There are only 2 The values from A <- unknownX[platform_start_id] mod 64
B <- 64-unknown3[platform_thik_id]-A Those seems to be used in texture mapping of some sort. |
Hello! I have stumbled into here quite late. But I am quite hopeful that I could help or learn a thing or too. I saw people previously mentioned a decompressed A.EXE and I have found a website which seemed to reference strings they observed in the executable. I would also like to see this decompressed version. |
I haven't invested time in disassemblers/tools like Ghidra, but if you want to play around with the decompressed A.EXE/ACD.EXE used by OpenTESArena, start with
The project's
I did a bomb lab too, lost a point cause I was a noob with breakpoints ;) |
Thanks! (once with time again i wil delve into this, i may postpone work on this til winterbreak) Also here is dissassembled assembly code of the unpacked ACD.EXE via sourcerer. |
You'll need an interactive disassembler like IDA or ghidra, and the debug version of Dosbox. Luckily, Arena is a real-mode application, so it would be easy to debug. I would start with investigating strings and functions that use them, then identifying the game logic and data structures. You will also need the documentation on DOS, VGA and LIM/EMS interrupts and structures. |
Added the pixelation effect to the wiki. |
Thanks. I always turned this effect off in Dosbox but will get to it sometime after 0.15.0. |
It's also used in the intro screens (the ones with the scroll background) and it's always enabled there since you have to get in-game for the toggle to work, and starting a new game resets it to the default value. Also, I didn't realize until I looked at the code, but the pixelation effect is done across the whole 320x200 screen, not just the message box areas. It isn't noticeable because the only difference in the screen pre-effect and post-effect is the message box being there or not being there, since everything else is paused. |
I've reversed the game's formula for spell points. Of course, the results (the spell point multipliers per class, etc.) are already known information, so I guess this is mainly just for curiosity or for emulating the original game and using the .exe data.
I don't know whether this is also used for NPCs or if it's just the player.
The "SpellPointModifiers" array location for aExeStrings.txt is 0x40110. For acdExeStrings.txt it is 0x40750. It looks like:
The text was updated successfully, but these errors were encountered: