News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu

Wanting to understand Restunts source code structure

Started by Cas, August 28, 2022, 11:24:08 PM

Previous topic - Next topic

Daniel3D

Quote from: Cas on September 11, 2022, 10:33:20 PMRight. When I am the user and I download software, I rarely download the source unless I want to compile it for some reason or examine the code. Most of the free software code around today is written in horrible languages such as java, ha, ha or using lots of OOP, so studying the source normally isn't of any use to me. Then it's good to have an option like your #1.

Of course, if I split it, then people have to be aware that they can't redistribute package #1 without also putting the other packages available at the same location.
you provide the source for anyone interested in reading it.
If you want to compile it from your source then they need to get the third party stuff, either from you or directly from the source (if they want to work with your code, the latest version of the libraries is probably advisable)
therefore option 2 and 3.

If somebody wants to redistribute package 1, 2 or 3 they have to refer to the other options as well (as is stated in the documentation), but they can point to the source (you). So a redirect would suffice in my opinion.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

Uhm... maybe that's legal, I don't know, but I don't feel it to be correct. I mean, if I don't provide the source myself, then whatever site I point to might go down or remove it or change it and then I'd be providing an incomplete source.
Earth is my country. Science is my religion.

Daniel3D

As far as I understand you have to provide access to the third party source.
Therefore is option 3,that includes the content.
But you don't have to keep it updated, you provide what you used. In option two you provide information so one can get the original (maybe updated). And can get support for that part.

Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Daniel3D

#33
Quote from: llm on September 09, 2022, 11:18:02 AMdid it work to change the segment alignment to para?
i had little time so i did an all or nothing approach.
Changing all files creates a near copy, but there are many bit differences, and it does not run,.

A screenshot of a visual check included.
There is also an offset further in the file.

But i now have all obj files. So i can try again, one segment at a time.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on September 23, 2022, 12:04:33 PMi had little time so i did an all or nothing approach.
Changing all files creates a near copy, but there are many bit differences, and it does not run,.

expected result :)

Daniel3D

Quote from: llm on September 30, 2022, 08:13:04 AM
Quote from: Daniel3D on September 23, 2022, 12:04:33 PMi had little time so i did an all or nothing approach.
Changing all files creates a near copy, but there are many bit differences, and it does not run,.

expected result :)
Yes and no.
After fixing a typo I did it again and although it still doesn't work, i did get a clear error message.
I forgot to write it down but it was something along the line of that it failed to read the contents of sdmain. Vsh..
So maybe..

Te correct version is already in the post above, just didn't go into details because I had no time for it at that moment.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

llm

Quote from: Daniel3D on September 30, 2022, 09:11:34 AM
Quote from: llm on September 30, 2022, 08:13:04 AM
Quote from: Daniel3D on September 23, 2022, 12:04:33 PMi had little time so i did an all or nothing approach.
Changing all files creates a near copy, but there are many bit differences, and it does not run,.

expected result :)
Yes and no.
After fixing a typo I did it again and although it still doesn't work, i did get a clear error message.
I forgot to write it down but it was something along the line of that it failed to read the contents of sdmain. Vsh..
So maybe..

Te correct version is already in the post above, just didn't go into details because I had no time for it at that moment.

you will get random problems when not beeing binary equal - and you will not be able to test all effects (its impossible) - to not create a binary compatible version (which is easy and clear what to do) is like asking for random trouble somewhere over the complete code - anytime in the future - the 100% binary equal version is by design correct

there is no "it seems to work" partially :) - every move of code is just wrong (what does not mean in any form that the game will crash - but still its wrong, for example subtile errors in the physic engine, speed, while drawing etc., unlimited amount of silly invisble bugs)


Cas

That is true. That's why, about the needle mod, I recommended the fall back to the single colour mod, which is exactly identical to the original except for a word that we know exactly what it does. The bi-colour mod "seems to work" and probably does, but we will never be done testing. Yet, we had to do it that way because there was no other in this case, but a full rewrite of the game to C or a recreation with a new engine are the only options if we want a stable modded game (unless we could get to the original source, but it's many times been said it doesn't exist anymore).
Earth is my country. Science is my religion.

llm

Quote from: Cas on October 01, 2022, 04:45:58 PMYet, we had to do it that way because there was no other in this case, but a full rewrite of the game to C or a recreation with a new engine are the only options if we want a stable modded game

its still possible but you need to be very carefull - don't add code in between that moves code, always try
to be binary equal or not equal in very small well known parts

for example - adding only code by link-virus behavior, add a new segment, ignore relocation table changes, patch calls into the code (save the original code) - recover original code after running the new code - this way you can add large amounts of code without changing too much

or search the code for non-symbolic offsets and fix them to symbolic ones, then your able to change everything without problems - but that could be time consuming

but this is all in all very "tinker"



llm

my current solution for modifying games more or less safe is using dosbox as a backend
for example: im able to hook function calls and overwrite code parts, very good for porting because
you can port a function while the function is in use by the emulated code

for example the data compression routine of the Alpha Waves game
disassembled in IDA then converter to my tiny "emulator" that fakes the minimal
aspects of the x86 code to ease the porting to C

emu_t just got some registers, memory and methods that look like the original
asm and behave like the original asm code - but its just C/C++ code

this function gets called by dosbox when the emulated code actually wanted to call the original
16bit code, i can debug, step through it, log data, write unit-tests etc.

this is my third try to port that function properbly - before just in assembler and 16bit C
but subtile micro difference seemed to work but my port was until now only working with 95%
of the data

void UNCOMPRESS_sub_1BAE7(emu_t &e)
{
start:
e.push(e.es);
e.push(e.di);
e.cx = 0x80;
e.ax = e.ds;
e.es = e.ax;
e.di = 0x301;
e.xor(e.ax, e.ax);
e.rep_stosw();
e.pop(e.di);
e.pop(e.es);
e.sub(e.di, *e.word_ptr(e.cs, 0xBAA2));
e.ax = e.di;
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.cx = e.es;
e.add(e.cx, e.ax);
e.es = e.cx;
e.and (e.di, 0x0F);
e.add(e.di, *e.word_ptr(e.cs, 0xBAA2));
e.push(e.ds);
e.push(e.es);
e.push(e.si);
e.push(e.di);
e.cx = 4;
e.di = 0xBA9A; // offset byte_1BA9A; ???
e.ax = e.cs;   // seg seg000 // cs register; ???
e.es = e.ax;
e.lds(e.si, *e.dword_ptr(e.cs, 0xBAA4));
e.ax = e.si;
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.shr(e.ax, 1);
e.dx = e.ds;
e.add(e.ax, e.dx);
e.ds = e.ax;
e.and (e.si, 0x0F);
*e.word_ptr(e.cs, 0xBAA4) = e.si;
*e.word_ptr(e.cs, 0xBAA4 + 2) = e.ds;
e.add(*e.word_ptr(e.cs, 0xBAA4), e.cx);
e.rep_movsb();
e.pop(e.di);
e.pop(e.si);
e.pop(e.es);
e.pop(e.ds);
e.dx = *e.word_ptr(e.cs, 0xBA9C);
e.inc(e.dx);
e.cmp(*e.byte_ptr(e.cs, 0xBA9A), 0);
if (e.jnz())
goto loc_1BB63;
goto loc_1BC52;
// ---------------------------------------------------------------------------

loc_1BB63:
e.push(e.ds);
e.push(e.es);
e.push(e.di);
e.xor (e.ch, e.ch);
e.cl = *e.byte_ptr(e.cs, 0xBA9A);
e.di = 0x201;
e.ax = e.ds;
e.es = e.ax;
e.ds = *e.word_ptr(e.cs, 0xBAA4 + 2);
e.si = *e.word_ptr(e.cs, 0xBAA4);
e.add(*e.word_ptr(e.cs, 0xBAA4), e.cx);
e.rep_movsb();
e.cl = *e.byte_ptr(e.cs, 0xBA9A);
e.xor (e.ch, e.ch);
e.di = 1;
e.add(*e.word_ptr(e.cs, 0xBAA4), e.cx);
e.rep_movsb();
e.cl = *e.byte_ptr(e.cs, 0xBA9A);
e.di = 0x101;
e.add(*e.word_ptr(e.cs, 0xBAA4), e.cx);
e.rep_movsb();
e.pop(e.di);
e.pop(e.es);
e.pop(e.ds);
e.xor (e.ch, e.ch);
e.cl = *e.byte_ptr(e.cs, 0xBA9A);
e.xor (e.ah, e.ah);
e.bx = 1;
loc_1BBB4:
e.al = *e.byte_ptr(e.ds, e.bx + 0x200);
e.si = e.ax;
e.dl = *e.byte_ptr(e.ds, e.si + 0x301);
*e.byte_ptr(e.ds, e.bx + 0x402) = e.dl;
*e.byte_ptr(e.ds, e.si + 0x301) = e.bl;
e.inc(e.bx);
if (e.loop())
goto loc_1BBB4;
e.dx = *e.word_ptr(e.cs, 0xBA9C);
e.inc(e.dx);
e.cx = 1;
loc_1BBD2:
e.dec(e.dx);
if (e.jnz())
goto loc_1BBE1;
loc_1BBD5:
e.cmp(*e.byte_ptr(e.cs, 0xBA9B), 0);
if (e.jz())
goto locret_1BBE0;
goto start;
// ---------------------------------------------------------------------------

locret_1BBE0:
return;
// ---------------------------------------------------------------------------

loc_1BBE1:
e.push(e.ds);
e.si = *e.word_ptr(e.cs, 0xBAA4 + 2);
e.ds = e.si;
e.si = *e.word_ptr(e.cs, 0xBAA4);
e.lodsb();
*e.word_ptr(e.cs, 0xBAA4) = e.si;
e.pop(e.ds);
e.bx = e.ax;
e.cmp(*e.byte_ptr(e.ds, e.bx + 0x301), 0);
if (e.jnz())
goto loc_1BC01;
e.stosb();
goto loc_1BBD2;
// ---------------------------------------------------------------------------

loc_1BC01:
e.bl = *e.byte_ptr(e.ds, e.bx + 0x301);
e.xor (e.ax, e.ax);
e.push(e.ax);
goto loc_1BC35;
// ---------------------------------------------------------------------------

loop_x:
e.bp = e.ax;
e.cmp(*e.byte_ptr(e.ds, e.bp + 0x301), 0);
if (e.jz())
goto loc_1BC44;
e.cmp(e.bl, *e.byte_ptr(e.ds, e.bp + 0x301));
if (e.ja())
goto loc_1BC30;
e.al = e.bl;
e.bl = *e.byte_ptr(e.ds, e.bp + 0x301);
loc_1BC22:
e.bl = *e.byte_ptr(e.ds, e.bx + 0x402);
e.or (e.bl, e.bl);
if (e.jz())
goto loc_1BC42;
e.cmp(e.bl, e.al);
if (e.jb())
goto loc_1BC35;
goto loc_1BC22;
// ---------------------------------------------------------------------------

loc_1BC30:
e.bl = *e.byte_ptr(e.ds, e.bp + 0x301);

loc_1BC35:
e.al = *e.byte_ptr(e.ds, e.bx + 0x100);
e.ah = e.bl;
e.push(e.ax);
e.xor (e.ah, e.ah);
e.al = *e.byte_ptr(e.ds, e.bx);
goto loop_x;
// ---------------------------------------------------------------------------

loc_1BC42:
e.ax = e.bp;
loc_1BC44:
e.stosb();
e.pop(e.ax);
e.or (e.ax, e.ax);
if (e.jnz())
goto loc_1BC4C;
goto loc_1BBD2;
// ---------------------------------------------------------------------------

loc_1BC4C:
e.bl = e.ah;
e.xor (e.ah, e.ah);
goto loop_x;
// ---------------------------------------------------------------------------

loc_1BC52:
e.push(e.ds);
e.push(e.es);
e.cx = *e.word_ptr(e.cs, 0xBA9C);
e.push(e.cx);
e.ds = *e.word_ptr(e.cs, 0xBAA4 + 2);
e.si = *e.word_ptr(e.cs, 0xBAA4);
e.add(*e.word_ptr(e.cs, 0xBAA4), e.cx);
e.rep_movsb();
e.pop(e.cx);
e.pop(e.es);
e.pop(e.ds);
goto loc_1BBD5;
}

llm

from my VS2019 IDE - uncompress is started - the 16bit DOS game Alpha Waves is waiting for the uncompressed data - based on my 32bit C++ code :)
so i change dosbox in a way that calls inside of the emulated code are hooked and replaced by my own C++ code, this way i can partially replace code

https://imgur.com/a/vwhrMzY (use this link for a larger image)


Daniel3D

It is indeed difficult to tell if the extended color needle mod is 100% functioning like stunts 1.1.
For this reason i use it in the ccc.
Every replay that is checked is done in zakstunts and ccc version.
I play only the ccc version on my chromebook.
So far nothing found, all replays checked are the same in both versions.

Still, use at your own risk.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

That is really interesting to see!  Inline assembly emulation. That would help solve lots of things!

As I said, the dual-colour needle mod is unverifiable. I chose to do it that way because it was a way in which it could be implemented with the code we have, but while it has worked so far, building on top of it with the same approach would accumulate more and more likelyhood of failure and is not acceptable.

On the other hand, the interaction is good. What I mean is, if I later rewrite this some other way, but it does exactly the same thing with the same variables, the new mod would, in practical terms, be the same as this, so what we've done is just "one implementation" of the mod. I could redo it virus-like and we already have a live proof of concept.

I had already thought in the past about the possibility of just inserting a call instead of the direct code and putting the main code somewhere else, but what I don't know is if the new segment will end up at the end of the whole program code, because if it's somewhere in the middle, still some program code would be moved done. I don't know much about Turbo Assembler and how it does its thing. If I were sure about it, I could use that.

On the other hand, there's another idea I'm having right now which could simplify all this. Instead of inserting new code within the compiled program... this is DOS!  No memory protection, no difference between data and code. And while this is bad for many things, it has its advantages. How about I create a TSR that hooks up a custom interrupt and have Stunts call this interrupt as an API. The hooking would be small and I could do it virus-like, but then, every other bigger mod would just be part of the TSR, not the main program, so nothing would be moved down!  What's more, I could make the TSR be a mod hub where other mods can be plugged in. When I have a moment, I'll start working on that.
Earth is my country. Science is my religion.

llm

Quote from: Cas on October 04, 2022, 03:21:56 AMThat is really interesting to see!  Inline assembly emulation. That would help solve lots of things!

what things do you think about, different than my things?

Quote from: Cas on October 04, 2022, 03:21:56 AMI had already thought in the past about the possibility of just inserting a call instead of the direct code and putting the main code somewhere else, but what I don't know is if the new segment will end up at the end of the whole program code, because if it's somewhere in the middle, still some program code would be moved done. I don't know much about Turbo Assembler and how it does its thing. If I were sure about it, I could use that.

the order of the re-states segments in the inc file is the order of segments in the executable
new code (with segment-realtions) will change the relocation-table but that isn't a problem

Quote from: Cas on October 04, 2022, 03:21:56 AMOn the other hand, there's another idea I'm having right now which could simplify all this. Instead of inserting new code within the compiled program... this is DOS!  No memory protection, no difference between data and code. And while this is bad for many things, it has its advantages. How about I create a TSR that hooks up a custom interrupt and have Stunts call this interrupt as an API. The hooking would be small and I could do it virus-like, but then, every other bigger mod would just be part of the TSR, not the main program, so nothing would be moved down!  What's more, I could make the TSR be a mod hub where other mods can be plugged in. When I have a moment, I'll start working on that.

a TSR will not change the problem of moving code around
(which is solveable by link-virus style programming)

it makes not real sense staying away from the source by adding a patch-systems with mods that still can't be created without
decent knowledege about the code and positions


Daniel3D

Quote from: llm on October 04, 2022, 08:37:17 AMa TSR will not change the problem of moving code around
(which is solveable by link-virus style programming)

it makes not real sense staying away from the source by adding a patch-systems with mods that still can't be created without
decent knowledege about the code and positions
That is where my idea for a replacement main menu came from. We only need to know how it stores global variables (player car, opponent and car, track and graphics settings).
Then we can use the new menu as tsr.
We could add a simple redirect in the code and compile it. It would make further messing with the code unnecessary for menu related changes.

We could use a extended car showroom
A version of bliss as track editor
Make default car and track changeable.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)