Cheat engine : Stephh's WIP (feedback needed)

If you are having problems finding or using cheats for an Emulator (particularly MAME/MESS) or have found a trick that you wish to share this is the place to do it. But please read the Cheat FAQ first.
Post Reply
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Cheat engine : Stephh's WIP (feedback needed)

Post by stephh »

First, donc expect me to rewrite the full thing : I have PLENTY other things to do (and in MAME, mainly in the drivers) ... However, if there are a few bugs I can easily fix, I'll try to have to look (unless Shimapong or Ian beat me to do it) ...

Message to Pugsy : when the file is "ready", I'll mail it to you so you can upload it somewhere on this site with the hope people test it before submission to MAME Team (to avoid multiple mails that may cause some changes to be lost) ...

Image Steph from The Ultimate Patchers Image
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

2006.09.16

I've included Shimapong's numerous fixes "as is" ... The only important thing I've change is that I didn't like the "code_pressed_memory(KEYCODE_R)" : you should use "input_ui_pressed(IPT_UI_RELOAD_CHEAT)" instead ...

This means that I had to modify src/inptport.h and src/inptport.c to add the new key to the UI ... BTW, note that I had to change the key to 'L' because 'R' was already used to rotate the screen ...

While I was at it, I've created a "static void ReloadCheatDatabase(void);" function for easier changes in the future (if any) ...


Now, before I submit the source files to you, I'd like to modify the way numeric data is edited and I REALLY need feedback ...

At the moment, I have found 4 main functions :

. static int ReadHexInput(void);
. static UINT32 DoEditHexField(UINT32 data);
. static UINT32 DoEditHexFieldSigned(UINT32 data, UINT32 mask);
. static INT32 DoEditDecField(INT32 data, INT32 min, INT32 max);

What we should have (sort of) :

1) static int ReadDigit(int pBase, int BCDonly);

This would allow to correctly read a digit (ie with the keyboard AND the keypad) depending on the "pBase" parameter (2 for binary, 8 for octal, 10 for decimal and 16 for hexa) and the BCDonly "flag" (!= 0 when set) ... Binary and octal support might not be useful, but it's not that difficult to add them if we ever need such stuff one day or another ...

Code: Select all

static int ReadDigit(int pBase, int BCDonly)
{
	int	i, digit;
 
	if ((pBase == 16) && (BCDonly))  /* adjust max value */
		pBase = 10;
 
	digit = -1;  /* no good key pressed */
 
	for(i = 0; i < 10; i++)
	{
		if(code_pressed_memory(KEYCODE_0 + i))
		{
			digit = i;
		}
	}
 
	for(i = 0; i < 10; i++)
	{
		if(code_pressed_memory(KEYCODE_0_PAD + i))
		{
			digit = i;
		}
	}
 
	for(i = 0; i < 6; i++)
	{
		if(code_pressed_memory(KEYCODE_A + i))
		{
			digit = i + 10;
		}
	}
 
	if (digit > pBase)
		digit = -1;
 
	return digit;
}

2) static INT32 DoEditDecField(INT32 data, INT32 min, INT32 max);

This function is good to me, but it needs to call ReadDigit and handle the specific keys (backspace and "-") ...

Code: Select all

static INT32 DoEditDecField(INT32 data, INT32 min, INT32 max)
{
	int	digit = ReadDigit(kBaseDecimal, 0)
	char	code = osd_readkey_unicode(0) & 0xFF;
 
	if (digit != -1)
	{
		data *= kBaseDecimal;
		data += digit;
	}
	else if (code == '-')
	{
		data = -data;
	}
	else if (code == 0x08)
	{
		data /= kBaseDecimal;
	}
 
	if (data < min)
		data = min;
	if (data > max)
		data = max;
 
	return data;
}
Note that there's a bug in Shimapong's fix : when you press BACKSPACE, you shall compute "data /= 10" instead of "data >> 4" (we're in DECIMAL !) ... Fast copy/paste without checking I guess ...

3) static static UINT32 DoEditHexField(UINT32 data, int BCDonly)

This function should now be very similar to the previous one if you except the fact that you can't have a negative value ...

Code: Select all

static static UINT32 DoEditHexField(UINT32 data, int BCDonly)
{
	int	digit = ReadDigit(kBaseHexadecimal, BCDonly)
	char	code = osd_readkey_unicode(0) & 0xFF;
 
	if (digit != -1)
	{
		data *= kBaseHexadecimal;
		data += digit;
	}
	else if (code == 0x08)
	{
		data /= kBaseHexadecimal;
	}
 
	return data;
}
Now I wonder if we REALLY need to have a way to edit negative hexadecimal values : from what I see in the source file, the old routine was only called to change the data in case of menu on kType_WatchAddValue and it was only for a byte change (thing that can easily be done with the arrows keys) ...

4) static float DoEditFloatField(float data, float min, float max, int maxDecimals)

Heavily based on function 2, it will be used for the watches positions (unless we decide to have UINT32 values that will be computed during the display) ... The maxDecimals parameter is used to prevent long entries ... No proposition at the moment on how it will be coded, I must think a bit more about it first ...


That's all for now (I think it's enough for a first proposition) ... Comments are welcome ...

Image Steph from The Ultimate Patchers Image
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

Nothing new as I didn't have any feedback for my previous propositions (does nobody look at the sticky posts ? :( )

Anyway, I have a question about the possibility to type digits when you select a value (eg: starting level) ... Is it that really useful while you have the arrow keys ? Furthermore, it looks completely bogus (I've tested with 'bangball') ... If we could also use the Shift, Ctrl, and Alt keys, this would be IMO far enough for what we want to do ...

Image Steph from The Ultimate Patchers Image
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

stephh wrote:The only important thing I've change is that I didn't like the "code_pressed_memory(KEYCODE_R)" : you should use "input_ui_pressed(IPT_UI_RELOAD_CHEAT)" instead ...
I think it will be the best.
The reason I have not added Database Reload Key as "general" input is that I don't know other source files.
I have analized current cheat.c only.
stephh wrote:Note that there's a bug in Shimapong's fix : when you press BACKSPACE, you shall compute "data /= 10" instead of "data >> 4" (we're in DECIMAL !) ... Fast copy/paste without checking I guess ...
Confirmed. I didn't noticed.
But I don't know why BACKSPACE isn't added in all "Edit" function.
stephh wrote:static float DoEditFloatField(float data, float min, float max, int maxDecimals)
IMO, it may be unneeded. Because it's enough that the increment/decrement by arrow key.
And this field doesn't need large value. Even it's the cause of the MAME crash.
stephh wrote:I have a question about the possibility to type digits when you select a value (eg: starting level) ... Is it that really useful while you have the arrow keys ?
I think the direct key input in value-selection menu is useful.
In fact I'm using this input much in the value-selection menu.
stephh wrote:it looks completely bogus
In case of value-selection with "minimum display value = 1", display value is "input value +1".
And the cheat engine tries to display for the input value with this rule.
For example, when you input "12", the real value is set as "12" but "13" is displayed in the selection menu.
But it surely brings about the mess...
So I think it's the best that input value = display value and real value is input value -1.
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

Thanks ShimaPong for your comments even if the files have been submitted yesterday to MAME Team ... It doesn't include any new "edit" functions ...
ShimaPong wrote:
stephh wrote:Note that there's a bug in Shimapong's fix : when you press BACKSPACE, you shall compute "data /= 10" instead of "data >> 4" (we're in DECIMAL !) ... Fast copy/paste without checking I guess ...
Confirmed. I didn't noticed.
But I don't know why BACKSPACE isn't added in all "Edit" function.
There's a "if (code == 0x08)" statement though ... The problem is that there are not many decimal values to test (the only "big" ones were the watches positions) ...
stephh wrote:static float DoEditFloatField(float data, float min, float max, int maxDecimals)
IMO, it may be unneeded. Because it's enough that the increment/decrement by arrow key.
And this field doesn't need large value. Even it's the cause of the MAME crash.
We can add a test when we increment/decrement ... The only thing to find is to know the maximum values depending on the game visible area ...
stephh wrote:I have a question about the possibility to type digits when you select a value (eg: starting level) ... Is it that really useful while you have the arrow keys ?
I think the direct key input in value-selection menu is useful.
In fact I'm using this input much in the value-selection menu.
stephh wrote:it looks completely bogus
In case of value-selection with "minimum display value = 1", display value is "input value +1".
And the cheat engine tries to display for the input value with this rule.
For example, when you input "12", the real value is set as "12" but "13" is displayed in the selection menu.
But it surely brings about the mess...
So I think it's the best that input value = display value and real value is input value -1.
The other problem is IMO mainly when you get BCD values ... But I agree that the digit entry shall affect the displayed value ...


I'll now wait for an official release to see what has been include and I'll then start coding what we discussed about ... Now, if there are some other things you think about, don't hesitate to post in this subject ...

Image Steph from The Ultimate Patchers Image
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

MAME 0.108u5 is out and includes the changes (mainly all the ones made by ShimaPong) :)

The "major" change is that you now need to press 'L' to reload the database instead of 'R' ...

I repeat that there is nothing new about the "edit" functions yet (things must be clear first) ...

Image Steph from The Ultimate Patchers Image
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

Thanks, I confirmed on 0.108u5.
But I wonder that whatsnew commentates very simply about it.
Especially, I think it's main update that 16-bit force range is now available.
stephh wrote:The other problem is IMO mainly when you get BCD values
I don't know other problem you said but I have found a bug in case of BCD with UserSelectMinimum = 1.

Code: Select all

:game:00000D00:1234:00000089:FFFFFFFF:Input Test (BCD & MinimumValue = 1)
If you press left key when current value is 0x00, display value is 0x8A instead of 89.
Because current cheat engine doesn't check and convert BCD for maximum value.

Code: Select all

	if(delta || forceUpdate)
	{
		INT32	min = EXTRACT_FIELD(action->type, UserSelectMinimum); // min = 1
		INT32	max = action->originalDataField + min; // max = 89 + 1 = 8A

		if(TEST_FIELD(action->type, UserSelectBCD))
		{
			value = BCDToDecimal(value);
		}

		value += delta; // If press left key when current value is 0, 0 - 1 = -1 (< min)

		if(TEST_FIELD(action->type, UserSelectBCD))
		{
			value = DecimalToBCD(value);
		}

		if(value < min)
			value = max; // set 0x8A as new value...!
		if(value > max)
			value = min; // NOTE : min is always 0 or 1 so that it will be without problem
	}
Anyway, I have tried to update for this function (UserSelectValueMenu) significantly.
http://zetubou.mine.nu/timer/file/bomber26089_d7.zip
PASS : Kriptokapi, NOT NEVER COMES HERE !

- Added Direct Key Input Mode -
If you input hex or dec value, "Select a value" (select mode) message is changed to "Input a value" (input mode).
This mode allows direct key input and frees of the influence of minimum display option.
  • left or right key : decrease or increase current value and change to select mode.
  • select key : set current value and return to previous menu (the same as select mode)
  • cancel key : close selection menu and return to previous menu (the same as select mode)
  • shift + cancel key : change to select mode
- Convert "invalid" maximum value in BCD -
It blocks invalid maximum value if direct key or left key (the above problem) input.
If a value is invalid, converts the lowest digit to "9". (2A -> 29, 91A -> 919 etc)
But original maximum value itself is invalid (eg, "F"9, 1"C"7, 3"D""E"4 etc), it's meaningless.
So the code creator has to notice that don't set invalid value into data field if BCD...

I expect that the direct key input is more convenient than previous version.
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

ShimaPong wrote:Thanks, I confirmed on 0.108u5.
But I wonder that whatsnew commentates very simply about it.
Especially, I think it's main update that 16-bit force range is now available.
It's my fault here : I submitted the source files and told to look at the board to know what was new (there were really too MANY fixes/updates) ...

Anyway, it shouldn't be a problem : people who don't care won't notice it, and people who need the cheat engine will read the posts here ...

stephh wrote:The other problem is IMO mainly when you get BCD values
I don't know other problem you said but I have found a bug in case of BCD with UserSelectMinimum = 1.

Code: Select all

:game:00000D00:1234:00000089:FFFFFFFF:Input Test (BCD & MinimumValue = 1)
If you press left key when current value is 0x00, display value is 0x8A instead of 89.
Because current cheat engine doesn't check and convert BCD for maximum value.

Code: Select all

	if(delta || forceUpdate)
	{
		INT32	min = EXTRACT_FIELD(action->type, UserSelectMinimum); // min = 1
		INT32	max = action->originalDataField + min; // max = 89 + 1 = 8A

		if(TEST_FIELD(action->type, UserSelectBCD))
		{
			value = BCDToDecimal(value);
		}

		value += delta; // If press left key when current value is 0, 0 - 1 = -1 (< min)

		if(TEST_FIELD(action->type, UserSelectBCD))
		{
			value = DecimalToBCD(value);
		}

		if(value < min)
			value = max; // set 0x8A as new value...!
		if(value > max)
			value = min; // NOTE : min is always 0 or 1 so that it will be without problem
	}
Anyway, I have tried to update for this function (UserSelectValueMenu) significantly.
http://zetubou.mine.nu/timer/file/bomber26089_d7.zip
PASS : Kriptokapi, NOT NEVER COMES HERE !
Yipee ! Another bug in the "UserSelectValueMenu" function ! :x I'll have a look at your source file, but I REALLY want to rewrite this function and add sort of "ComputeDAA(value, delta, isBCD)" function :

Code: Select all

ComputeDAA(UINT32 pVal, int delta, int isBCD)
{
	if (isBCD)
	{
		pVal = BCDToDecimal(pVal);
	}
 
	pVal += delta;
 
	if (isBCD)
	{
		pVal = BCDToDecimal(pVal);
	}
 
	return pVal;
}
Comments about it are welcome ...

- Added Direct Key Input Mode -
If you input hex or dec value, "Select a value" (select mode) message is changed to "Input a value" (input mode).
This mode allows direct key input and frees of the influence of minimum display option.
  • left or right key : decrease or increase current value and change to select mode.
  • select key : set current value and return to previous menu (the same as select mode)
  • cancel key : close selection menu and return to previous menu (the same as select mode)
  • shift + cancel key : change to select mode
I'm not sure that this is really useful and IMO this is not the correct way to do ... You mentioned earlier to work on the DisplayValue then compute Value according to the "settings", and that was fine to me ...

- Convert "invalid" maximum value in BCD -
It blocks invalid maximum value if direct key or left key (the above problem) input.
If a value is invalid, converts the lowest digit to "9". (2A -> 29, 91A -> 919 etc)
But original maximum value itself is invalid (eg, "F"9, 1"C"7, 3"D""E"4 etc), it's meaningless.
So the code creator has to notice that don't set invalid value into data field if BCD...

I expect that the direct key input is more convenient than previous version.
IMO, the tests for min and max value shall be done when you press the left/right keys ... Now, when user enters a value (using my new ReadDigit and other new functions), we'll have to check the bounds again each time a digit is entered ...

But as I said, I don't understand why user can't use the arrow keys ONLY to select a value : if you add support for Shift, Ctrl and Alt keys, there shall be NO need to bother with an edit "window" which causes troubles ...

Last thing : when you hit min or max, what do you do ? Force to min or max ? Or min - 1 = max and max + 1 = min ?

Note that the cheat engine doesn't have to check that there is a correct max BCD value (even if it'll try to fix it) in the cheat.dat file : this "job" is supposed to be done by CheckCDB ...

Image Steph from The Ultimate Patchers Image
User avatar
Pugsy
Posts: 3638
Joined: Fri Aug 17, 2001 12:59 am
Location: North Wales, UK.
Has thanked: 1 time
Been thanked: 12 times
Contact:

Post by Pugsy »

I haven't made a post in this thread before because to I can't see what you are meaning to do I don't know if it will affect me at all. Although I can write C to an extent...I have enough problems understanding my own code as months often go by without looking at any code at all. As for the select cheats I've always just used the arrow keys..I suppose if any select cheat had thousands of possible values a direct entry would be desirable but I can't see that ever being needed - so the arrow keys alone should be all that's ever needed for select cheats.
Last thing : when you hit min or max, what do you do ? Force to min or max ? Or min - 1 = max and max + 1 = min ?
I peresume you mean on a select cheat? In which case if a value is on the maximum and the user presses to increase it then it should change to the minimum this way holding down one key will continuously rotate throught the poss values and also allows the use to select the high values quicker by decreasing from the minimum.

My own personnal wants..

Any chance of adding the facility to continue a cheat search in the advanced search by hitting ENTER or another key without having to use the arrow keys to select "Do Search" and then hit ENTER. Ian said he'd do this a few years back but I'm still waiting :cry:

Advanced Search - Start a New Cheat Search options are mostly obsolete - SAVE memory is all that's really needed from that menu. It maybe better to rename Continue Search to Cheat Search, delete the 'Start a New Cheat Search' option and add a new Start a New Cheat Search option to the combined Cheat Search Menu (the Save Memory option should be retained though - as it's needed for multiple searches (I think))

The capability of placing a watch on a ROM cheat (at the moment I have to change a cheat to a RAM cheat and then use W and then change it back)
Pugsy

Servicing your cheating needs since 1985 8)

Grab the latest cheat collection:
MAME 0.259 XML cheat collection (6 OCTOBER 2023) from http://www.mamecheat.co.uk or direct from:-
https://mega.nz/file/q4dHGZ6K#i-EUiqIjH ... KMz7hnbTfw (ZIP Archive 3.76MB)
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

Stephh wrote:It's my fault here : I submitted the source files and told to look at the board to know what was new (there were really too MANY fixes/updates) ...

Anyway, it shouldn't be a problem : people who don't care won't notice it, and people who need the cheat engine will read the posts here ...
OK, I wrote whatsnew about my customization.
viewtopic.php?t=2461&start=13
Stephh wrote:IMO this is not the correct way to do
Also I think so. But I don't know what is the best way.
Anyway, it needs to clearn up fully, I think.
Stephh wrote:But as I said, I don't understand why user can't use the arrow keys ONLY to select a value : if you add support for Shift, Ctrl and Alt keys, there shall be NO need to bother with an edit "window" which causes troubles ...
I guess the direct key input is the most simple and easy.
Extreme case though, if you try to set 55555555 (max = 99999999) with default value = 0, press "5" key 8 times only.
In this case, it will be hard to reach this value by arrow key only even if you use Shift, Alt and Ctrl.

But I don't stick around the direct input though I feel it's very useful.
It's too hard coding and many problems happen.
Stephh wrote:Last thing : when you hit min or max, what do you do ? Force to min or max ? Or min - 1 = max and max + 1 = min ?
I don't know which is the "best".
I feel strange if a value is converted to min when over max with direct input or converted to max when over max with arrow key input.
Current cheat engine supports both adjustement. I think it's "better".
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

Pugsy wrote:As for the select cheats I've always just used the arrow keys..I suppose if any select cheat had thousands of possible values a direct entry would be desirable but I can't see that ever being needed - so the arrow keys alone should be all that's ever needed for select cheats.
OK ... I'll only add support for the Shift, Ctrl and Alt keys when I rewrite the function ...

Last thing : when you hit min or max, what do you do ? Force to min or max ? Or min - 1 = max and max + 1 = min ?
I peresume you mean on a select cheat? In which case if a value is on the maximum and the user presses to increase it then it should change to the minimum this way holding down one key will continuously rotate throught the poss values and also allows the use to select the high values quicker by decreasing from the minimum.
You seem to have a different "vision" of the problem than ShimaPong, so I guess I'll add an option which could be "stored" in the '_command' cheat line ... BTW, I think that we should really think about having a bit-related '_command' cheat line to define the options ... The only thing to know is what options we want to "save" ...

Any chance of adding the facility to continue a cheat search in the advanced search by hitting ENTER or another key without having to use the arrow keys to select "Do Search" and then hit ENTER. Ian said he'd do this a few years back but I'm still waiting :cry:
The first thing to do is to write a function which includes what we need :

Code: Select all

{
	if(	(!kSearchOperandNeedsInit[search->lhs] && !kSearchOperandNeedsInit[search->rhs]) ||
		!startNew)
	{
		BackupSearch(search);
		DoSearch(search);
	}
 
	UpdateSearch(search);
 
	popmessage("%d results found", search->numResults);
 
	if(search->numResults == 1)
	{
		AddCheatFromFirstResult(search);
		popmessage("1 result found, added to list");
	}
}
Then, I think we could easily call it from almost anywhere (provided the cheat menu is active - I'm not sure if would be accepted if it was with the main stuff such as the UI_PAUSE key) like we do for the "Reload Database" ... FYI, it could be mapped by default to the 'K' key which is not used ...

Advanced Search - Start a New Cheat Search options are mostly obsolete - SAVE memory is all that's really needed from that menu. It maybe better to rename Continue Search to Cheat Search, delete the 'Start a New Cheat Search' option and add a new Start a New Cheat Search option to the combined Cheat Search Menu (the Save Memory option should be retained though - as it's needed for multiple searches (I think))
I don't use the advanced search stuff, so let me see if I've understood everything :

. remove the "Start a New Cheat Search" menu item from main menu
. rename "Continue Search" menu to "Cheat Search"
. in new "Cheat Search" menu, add "Start a New Cheat Search" menu item before "Do Search" menu item

Is that it ? This might affect "classic" search but this doesn't seem impossible ...

BTW, when you use "classic" search, we could also do so something similar :

. remove the "Start a New Cheat Search" menu item from main menu
. rename "Continue Search" menu to "Cheat Search"
. in new "Cheat Search" menu, add "Start a New Cheat Search" menu item before "CPU" menu item

What do you think about this ?

The capability of placing a watch on a ROM cheat (at the moment I have to change a cheat to a RAM cheat and then use W and then change it back)
This doesn't look as easy as I thought :( More investigation is needed ...

Image Steph from The Ultimate Patchers Image
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

ShimaPong wrote:Anyway, it needs to clearn up fully, I think.
Added to the TO DO list ...

I guess the direct key input is the most simple and easy.
Extreme case though, if you try to set 55555555 (max = 99999999) with default value = 0, press "5" key 8 times only.
In this case, it will be hard to reach this value by arrow key only even if you use Shift, Alt and Ctrl.
You're right, but as you said, this is an extreme case ... Remember that most of the time, max range will be 0x0000-0xffff which can be handled with the Shift, Ctrl and Alt keys ... And when you now that level or score rarely exceeds 0x99, we shouldn't have problems ...
But I don't stick around the direct input though I feel it's very useful.
It's too hard coding and many problems happen.
Don't bother with it : when the function is rewritten, you'll be happy with the arrow keys :)

Then, if there are still troubles, we'll see how the "direct input" stuff can be coded ...

Stephh wrote:Last thing : when you hit min or max, what do you do ? Force to min or max ? Or min - 1 = max and max + 1 = min ?
I don't know which is the "best".
I feel strange if a value is converted to min when over max with direct input or converted to max when over max with arrow key input.
Current cheat engine supports both adjustement. I think it's "better".
Read my reply to Pugsy in my previous message ...

Image Steph from The Ultimate Patchers Image
User avatar
Pugsy
Posts: 3638
Joined: Fri Aug 17, 2001 12:59 am
Location: North Wales, UK.
Has thanked: 1 time
Been thanked: 12 times
Contact:

Post by Pugsy »

stephh wrote:You seem to have a different "vision" of the problem than ShimaPong, so I guess I'll add an option which could be "stored" in the '_command' cheat line ... BTW, I think that we should really think about having a bit-related '_command' cheat line to define the options ... The only thing to know is what options we want to "save" ...
That way also has the advantage if you assign a single activation key to the cheat then it should be easier to rotate through all the possible values.. To be honest I thought that was the way it worked at the moment anyway..

I don't think making the command option bit-related is a good idea as it means people have to understand bits to be able to change it. Unless you mean having seperate command options with 0 and 1 to toggle ON and OFF

stephh wrote:The first thing to do is to write a function which includes what we need :

Code: Select all

{
	if(	(!kSearchOperandNeedsInit[search->lhs] && !kSearchOperandNeedsInit[search->rhs]) ||
		!startNew)
	{
		BackupSearch(search);
		DoSearch(search);
	}
 
	UpdateSearch(search);
 
	popmessage("%d results found", search->numResults);
 
	if(search->numResults == 1)
	{
		AddCheatFromFirstResult(search);
		popmessage("1 result found, added to list");
	}
}
Then, I think we could easily call it from almost anywhere (provided the cheat menu is active - I'm not sure if would be accepted if it was with the main stuff such as the UI_PAUSE key) like we do for the "Reload Database" ... FYI, it could be mapped by default to the 'K' key which is not used ...
The K key would be fine, I suppose I could always remap it anyway as long as it exists. But K for Kontinue(sic) seems fairly logical

stephh wrote: I don't use the advanced search stuff, so let me see if I've understood everything :

. remove the "Start a New Cheat Search" menu item from main menu
. rename "Continue Search" menu to "Cheat Search"
. in new "Cheat Search" menu, add "Start a New Cheat Search" menu item before "Do Search" menu item

Is that it ? This might affect "classic" search but this doesn't seem impossible ...

BTW, when you use "classic" search, we could also do so something similar :

. remove the "Start a New Cheat Search" menu item from main menu
. rename "Continue Search" menu to "Cheat Search"
. in new "Cheat Search" menu, add "Start a New Cheat Search" menu item before "CPU" menu item

What do you think about this ?
Yes that's the gist of it ....it simplifies the menu structure to make it easier for old and new users alike. To change the classic search would also be an excellent idea - the current way of start and continue is a throwback to the old cheat engine which worked in that manner, the new cheat engine never did as you can mix and match search methods as much as you like.
stephh wrote:
The capability of placing a watch on a ROM cheat (at the moment I have to change a cheat to a RAM cheat and then use W and then change it back)
This doesn't look as easy as I thought :( More investigation is needed ...
I appreciate that, I know Ian had looked at it and it wasn't as simple as it would appear because of the memory structure. I think the best way to implement maybe so that when you press W on a ROM cheat it sees it as a standard RAM location rather than anything else - maybe pressing W on the a ROM cheat could read in the present addressing mode and make a note of it and then change it to a RAM location and implement the W and finally convert it back to it's original state...
Pugsy

Servicing your cheating needs since 1985 8)

Grab the latest cheat collection:
MAME 0.259 XML cheat collection (6 OCTOBER 2023) from http://www.mamecheat.co.uk or direct from:-
https://mega.nz/file/q4dHGZ6K#i-EUiqIjH ... KMz7hnbTfw (ZIP Archive 3.76MB)
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

Stephh wrote:
The capability of placing a watch on a ROM cheat (at the moment I have to change a cheat to a RAM cheat and then use W and then change it back)

This doesn't look as easy as I thought More investigation is needed ...
I guess it's "a watchpoint for ROM code" but not so ?

Code: Select all

static void AddActionWatch(CheatAction * action, CheatEntry * entry)
{
// Custom - Allowed a Value for ROM code to Display Watchpoint [AddActionWatch]
	if((EXTRACT_FIELD(action->type, LocationType) == kLocation_Standard) ||
		(EXTRACT_FIELD(action->type, LocationType) == kLocation_MemoryRegion))
	{
This "simple" fix allows a ROM code to display watchpoint.
I have confirmed that watchpoint for ROM code is displayed with W key.
But if a driver has special handling for ROM region, it may not work correctly.
Stephh wrote:Remember that most of the time, max range will be 0x0000-0xffff which can be handled with the Shift, Ctrl and Alt keys
Current cheat engine supports the input with Arrow key + Shift, Ctrl or Alt in EditCheatMenu and EditW atch.

Code: Select all

	if(AltKeyPressed())
		increment <<= 4;
	if(ControlKeyPressed())
		increment <<= 8;
	if(ShiftKeyPressed())
		increment <<= 16;
Is new handling the same as the above ?
But in this case, pressing Shift + Arrow key changes 5th digit (ten thousand), eg 10000 -> 20000, instead of thousand.
Because it is "16"-bit shift instead of "12".

In many cases, this function is unused because direct key input is very useful.
But several games, like colt/nycaptor, cyclshtg/bronx, don't allow to input with several keys.
Does it need to change to "12-bit" shift ?

And also I want to display in case of Relative Address.
Fortunatery, current cheat engine supports address display.

So...

Code: Select all

:game:81000000:FFE000:00000009:00000123:Relative Address
If pointer address ($FFE000) has 0xEF0000, I want to display it as...

Code: Select all

EF0123 : 09
And if change a value in pointer address, 0xEF0000 -> 0xEFD000...

Code: Select all

EFD123 : 09
But in current cheat engine, we have to set watchpoint with $FFE000 firstly.
Next, set 2nd watchpoint as $EF0123. And 3rd watchpoint as $EFD123...
What annonying it is !

But it's hard coding...

Watchinfo structer doesn't have the info for relative address.

Code: Select all

struct WatchInfo
{
	UINT32			address;
	UINT8			cpu;
	UINT8			numElements;
	UINT8			elementBytes;
	UINT8			labelType;
	UINT8			displayType;
	UINT8			skip;
	UINT8			elementsPerLine;
	INT8			addValue;
	INT8			addressShift;
	INT8			dataShift;
	UINT32			xor;

	float			x, y;

	CheatEntry *	linkedCheat;

	char			label[256];
};
But it inclueds CheatEntry structer.

Code: Select all

struct CheatEntry
{
	char			* name;
	char			* comment;

	INT32			actionListLength;
	CheatAction		* actionList;

	int				activationKey;

	UINT32			flags;
	int				selection;
};
The flag of Relative Address is included not in this structer but CheatAction.

Code: Select all

struct CheatAction
{
	UINT32	type;
	UINT32	address;
	UINT32	data;
	UINT32	extendData;
	UINT32	originalDataField;

	INT32	frameTimer;
	UINT32	lastValue;

	UINT32	flags;

	UINT8	** cachedPointer;
	UINT32	cachedOffset;

	char	* optionalName;
};
Type field has the required flag.
So how to check this flag in cheat_display_watches function ?
"EXTRACT_FIELD(info->linkedCheat->actionList, type)" ?
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

Pugsy wrote:That way also has the advantage if you assign a single activation key to the cheat then it should be easier to rotate through all the possible values.. To be honest I thought that was the way it worked at the moment anyway..
IIRC ShimaPong fixed the problem for the list cheats and you can change the activation key in the menu with the arrow keys ...

But I don't understand why you should rotate when you press the activation key on a select value cheat ...


"_command" cheat lines
I don't think making the command option bit-related is a good idea as it means people have to understand bits to be able to change it. Unless you mean having seperate command options with 0 and 1 to toggle ON and OFF
IMO, there shall be only ONE way to change the options, but you can add multiple lines if you don't master the bits stuff ... And we could have sort of "default" settings with explanation in the 'description' and 'comments' fields ...

Imagine that bit 0 determines kind of search (0 = classic - 1 = advanced) and that bit 1 determines "autosave" status (0 OFF - 1 ON) ... You could then have these cheat lines :

Code: Select all

:_command:00000001:Search Dialog Style:00000000 = classic - 00000001 = advanced
:_command:00000002:Auto Save Cheats:00000000 = OFF - 00000002 = ON
This way, you tell that you intend to use the advanced search menu and that you autosave modified cheats when you exit MAME ...

Of course, if you exactly know what the bits do, you can have a single "_command" cheat line :

Code: Select all

_command:00000003
This will do the same thing as the 2 previous "_command" cheat lines" ...

I hope that you understood what I meant ...


Continue Search key
The K key would be fine, I suppose I could always remap it anyway as long as it exists. But K for Kontinue(sic) seems fairly logical
The 'K' key will be in the UI (same as 'R' to reload the database), so you'll easily be able to map it to whatever you want to do :) And yes, 'K' was meant for "Kontinue" ;)


New Search menu
Yes that's the gist of it ....it simplifies the menu structure to make it easier for old and new users alike. To change the classic search would also be an excellent idea - the current way of start and continue is a throwback to the old cheat engine which worked in that manner, the new cheat engine never did as you can mix and match search methods as much as you like.
I'll see what I can do ... But I think that this will be the last step of my "rewrite" ...


ROM watch cheats
I appreciate that, I know Ian had looked at it and it wasn't as simple as it would appear because of the memory structure. I think the best way to implement maybe so that when you press W on a ROM cheat it sees it as a standard RAM location rather than anything else - maybe pressing W on the a ROM cheat could read in the present addressing mode and make a note of it and then change it to a RAM location and implement the W and finally convert it back to it's original state...
Look at what ShimaPong did in previous message and tell me if it's OK for you ...

Image Steph from The Ultimate Patchers Image
stephh
Posts: 601
Joined: Fri Aug 17, 2001 1:00 am
Location: Paris, France

Post by stephh »

ROM watch cheats
ShimaPong wrote:

Code: Select all

static void AddActionWatch(CheatAction * action, CheatEntry * entry)
{
// Custom - Allowed a Value for ROM code to Display Watchpoint [AddActionWatch]
	if((EXTRACT_FIELD(action->type, LocationType) == kLocation_Standard) ||
		(EXTRACT_FIELD(action->type, LocationType) == kLocation_MemoryRegion))
	{
This "simple" fix allows a ROM code to display watchpoint.
I have confirmed that watchpoint for ROM code is displayed with W key.
Thanks for the fix ! Does it also work for banked ROM ?
But if a driver has special handling for ROM region, it may not work correctly.
That makes sense ...


Shift, Ctrl and Alt keys
Current cheat engine supports the input with Arrow key + Shift, Ctrl or Alt in EditCheatMenu and t##t.

Code: Select all

	if(AltKeyPressed())
		increment <<= 4;
	if(ControlKeyPressed())
		increment <<= 8;
	if(ShiftKeyPressed())
		increment <<= 16;
Is new handling the same as the above ?
But in this case, pressing Shift + Arrow key changes 5th digit (ten thousand), eg 10000 -> 20000, instead of thousand.
Because it is "16"-bit shift instead of "12".
Does it need to change to "12-bit" shift ?
I don't know why it was defined as 16 ... It should really be 12 ...
In many cases, this function is unused because direct key input is very useful.
But several games, like colt/nycaptor, cyclshtg/bronx, don't allow to input with several keys.
All the games you mention are in the same driver and there are troubles only with a debug build ... Look at the src/vidhrdw/nycaptor.c file ...


Relative address cheats
And also I want to display in case of Relative Address.
This is a really difficult thing to code at the moment, so I won't look at it for the moment ...
Type field has the required flag.
So how to check this flag in cheat_display_watches function ?
"EXTRACT_FIELD(info->linkedCheat->actionList, type)" ?
I'm sorry, but I can't help that much with such stuff as I don't know exactly how it is coded :(

But I would say that you shall need such thing like this :

Code: Select all

if (EXTRACT_FIELD(info->linkedCheat->actionList->type, LocationType) == kLocation_IndirectIndexed)
{
	...
}
Please let me know if it's OK ...

Image Steph from The Ultimate Patchers Image
ShimaPong
Posts: 1063
Joined: Wed May 21, 2003 4:19 pm
Location: Japan

Post by ShimaPong »

Stephh wrote:Does it also work for banked ROM ?
Oops... We can't get correct view for banked ROM. I have confirmed in pc_ddrgn (N2A03) and chinagat(HD6309).

Code: Select all

:pc_ddrgn:21B00000:22F97:D000C918:FFFFFFFF:Invincibility:This pokes $AF97 - $AF98 (lda $18 / cmp #$00 / bne $AF9E)

:chinagat:21800000:14105:0000007E:FFFFFFFF:Invincibility
:chinagat:21910000:14261:00001CFE:FFFFFFFF:Invincibility (2/8):1st = Enemy [JSR $447E], 2nd = Boss [ANDCC #$00FE]
:chinagat:21A10000:14B50:007E7FA0:FFFFFFFF:Invincibility (3/8):3rd - 8th = Fire [JMP $7FA0]
:chinagat:21A10000:17FA0:008C01A1:FFFFFFFF:Invincibility (4/8):CMPX #$01A1
:chinagat:21910000:17FA3:00002306:FFFFFFFF:Invincibility (5/8):BLS $7FAB
:chinagat:21A10000:17FA5:0010AE2D:FFFFFFFF:Invincibility (6/8):LDY 000D,Y
:chinagat:21A10000:17FA8:007E4B53:FFFFFFFF:Invincibility (7/8):JMP $4B53
:chinagat:21910000:17FAB:000035B0:FFFFFFFF:Invincibility (8/8):PULS X,Y,PC
And if ROM is loaded into User region, watchpoint display causes MAME crash with "invalid CPU num".

Code: Select all

:dangseed:39800000:3FAAC4:00000020:FFFFFFFF:Invincibility
:dangseed:39810000:3FB82D:00000020:FFFFFFFF:Invincibility (2/4):1st = Middle Enemy, 2nd = Boss
:dangseed:39810000:3FDB1F:00000020:FFFFFFFF:Invincibility (3/4):Enemy
:dangseed:39810000:3FEA63:00000020:FFFFFFFF:Invincibility (4/4):Fire
"Hint" is in ReadData.

Code: Select all

static UINT32 ReadData(CheatAction * action)
{
	UINT8	parameter = EXTRACT_FIELD(action->type, LocationParameter);
	UINT8	bytes = EXTRACT_FIELD(action->type, BytesUsed) + 1;
	UINT8	swapBytes = EXTRACT_FIELD(action->type, Endianness);

	switch(EXTRACT_FIELD(action->type, LocationType))
	{
		case kLocation_Standard:
		{
			return DoCPURead(parameter, action->address, bytes, CPUNeedsSwap(parameter) ^ swapBytes);
		}
		break;

		case kLocation_MemoryRegion:
		{
			int		region = REGION_CPU1 + parameter;
			UINT8	* buf = memory_region(region);

			if(buf)
			{
				if(IsAddressInRange(action, memory_region_length(region)))
				{
					return DoMemoryRead(buf, action->address, bytes, RegionNeedsSwap(region) ^ swapBytes, GetRegionCPUInfo(region));
				}
			}
		}
		break;
If RAM region, it uses "DoCPURead" but "DoMemoryRead" for ROM.
But cheat_display_watches uses "DoCPURead" only.
So watchpoint tries to read a data for banked ROM and user region by "DoCPURead".
Anyway, I wonder why "DoCPURead" gets a value on ROM region.

I have tried to copy it from ReadData to cheat_display_watches.

Code: Select all

struct WatchInfo
{
	UINT32			address;
	UINT8			cpu;
	UINT8			numElements;
	UINT8			elementBytes;
	UINT8			labelType;
	UINT8			displayType;
	UINT8			skip;
	UINT8			elementsPerLine;
	INT8			addValue;
	INT8			addressShift;
	INT8			dataShift;
	UINT32			xor;

// Custom - Added Watchpoint for ROM Region & Relative Address [WatchInfo structer]
	UINT8			locationType;

	float			x, y;

	CheatEntry *	linkedCheat;

	char			label[256];
};
1st, I added "locationType" in WatchInfo structer.

Code: Select all

static void AddActionWatch(CheatAction * action, CheatEntry * entry)
{
// Custom - Added Watchpoint for ROM region & Relative Address [AddActionWatch]
	if((EXTRACT_FIELD(action->type, LocationType) == kLocation_Standard) ||
		(EXTRACT_FIELD(action->type, LocationType) == kLocation_MemoryRegion) ||
		(EXTRACT_FIELD(action->type, LocationType) == kLocation_IndirectIndexed))

	{
		WatchInfo	* info = GetUnusedWatch();
...
		info->skip =			0;

// Custom - Added Watchpoint for ROM Region & Relative Address [AddActionWatch]
		info->locationType =	EXTRACT_FIELD(action->type, LocationType);

		if(EXTRACT_FIELD(action->type, Type) == kType_Watch)

Code: Select all

void cheat_display_watches(void)
{
	int		i;
...
			for(j = 0; j < info->numElements; j++)
			{
				UINT32	data = 0;

// Custom - Added Watchpoint for ROM Region & Relative Address [cheat_display_watches] : get a data
				switch(info->locationType)
				{
					case kLocation_Standard:
						data = (DoCPURead(info->cpu, address, kSearchByteIncrementTable[info->elementBytes], CPUNeedsSwap(info->cpu)) + info->addValue)
								& kSearchByteMaskTable[info->elementBytes];
						break;

					case kLocation_MemoryRegion:
					{
						int		region = REGION_CPU1 + info->cpu;
						UINT8	* buf = memory_region(region);

						if(buf)
							data =  DoMemoryRead(buf, address, kSearchByteIncrementTable[info->elementBytes], RegionNeedsSwap(region) + info->addValue, GetRegionCPUInfo(region))
									& kSearchByteMaskTable[info->elementBytes];
						break;
					}

					case kLocation_IndirectIndexed:
						return; // under construction...

					default:
						logerror("invalid location type [watchpoint]: %x\n", info->locationType);
						return;

				}

				data = DoShift(data, info->dataShift);
OK, Watchpoint for ROM region seems to work correctly by this fix even if banked ROM and user region. But it has several problems...
  • Unreal address is displayed. In pc_ddrgn, $22F97 instead of $AF97.
    But I don't know how to adjust an address. I think it's out of cheat.c...
  • In case of user region, unreal cpu number. In dangseed (M6809), it is "CPU 25" !
  • If you try to fix an address in watchpoint edit menu, the cheat engine will adjust it.
    In chinagat, if you press left key on $14105 in 1st code, new address is $4104 instead of $14104.
  • Endian problem ?
You can see a value on special ROM region but you can't get and set "in-game" address and CPU.

Stephh wrote:

Code: Select all

if (EXTRACT_FIELD(info->linkedCheat->actionList->type, LocationType) == kLocation_IndirectIndexed) 
{ 
   ... 
}
It succeeds to compile but MAME crashes when you try to display watchpoint... Therefore I have stopped checking a flag directly via CheatEntry and Cheat Action. It's complicated !
But sorry, I have added "locationType" for WatchInfo strucer instead.
Post Reply