Skip to content

AddSource

Note: most likely this technique is not needed for simple games. So, it's not mandatory for jr-devs.

The AddSource can be chosen in the Flag column of the Achievement Editor

When a condition has the AddSource flag, the value on that memory address is added to the accumulator. When a condition is reached that does not modify the accumulator, the accumulator is added to value of the address on that condition before the comparison is made, and the accumulator will be reset to 0. It may sound a bit confusing, but the example below will clarify how this works:

Simple example

IDFlagTypeSizeMemoryCmpTypeSizeMem/ValHits
1AddSourceMem8-bit0x8010
2Mem8-bit0x8020>Value0x040 (0)

In this example the value in 0x8010 will be added to the value in 0x8020 and the comparison will check is if this sum is greater than four.

If the value in 0x8010 is 1 and the value in 0x8020 is 2, the comparison will be 1 + 2 > 4, or 3 > 4.

Trying to summarize the explanation in an image:

 Explained

Chaining

You can use the AddSource flag to sum more addresses, like in the example below:

IDFlagTypeSizeMemoryCmpTypeSizeMem/ValHits
1AddSourceMem8-bit0x8010
2AddSourceMem8-bit0x8011
3Mem8-bit0x8020>Value0x040 (0)

This represents value(0x8010) + value(0x8011) + value(0x8020) > 4.

Independence

The accumulator is reset after its used, so you can have multiple AddSource chains in one trigger without having to worry about them interfering with each other.

IDFlagTypeSizeMemoryCmpTypeSizeMem/ValHits
1AddSourceMem8-bit0x8010
2Mem8-bit0x8020>Value0x040 (0)
3AddSourceMem8-bit0x8030
4Mem8-bit0x8040<Value0x800 (0)

This represents value(0x8010) + value(0x8020) > 4 AND value(0x8030) + value(0x8040) < 0x80.

Overflow

The accumulator and all logic being performed is limited to 32-bits. If the total value exceeds 0xFFFFFFFF, there will be an overflow and only the 32 least significant bits will be used in the comparison.

IDFlagTypeSizeMemoryCmpTypeSizeMem/ValHits
1AddSourceMem32-bit0x8010
2Mem32-bit0x8020>Value0x300000000 (0)

If 0x8010 is 0xC0000000 and 0x8020 is 0x54321ABC, then the total will be 0x114321ABC, which is more than 32-bits and will be truncated to 0x14321ABC, which is not more then 0x30000000, so the logic will evaluate false.

Using Modifiers

Additionally, you can use AddSource to modify a value. By clicking on the "Cmp" column, a dropdown will open with various math and logical operators. This allows you to modify the value before adding it to the accumulator.

*: Multiply the left side by the right side.

  • AddSource 8-bit Mem 0x8010 * Value 0x14 would read the 8-bit value from $8010, multiply it by 20 (0x14 hex) and then add that to the accumulator.

/: Divide the left side by the right side.

  • AddSource 8-bit Mem 0x8010 / Value 0x14 would read the 8-bit value from $8010, divide by 20 (rounding down) and then add that to the accumulator.
  • Note: If the divisor (right side) is zero, the result will be treated as a value of 0.

% Modulus operator: Divide the left side by the right side and return the remainder of the division.

  • AddSource 8-bit Mem 0x8010 % Value 0x14 would read the 8-bit value from $8010, divide by 20, and then add the remainder of that division to the accumulator. For example, if $8010 held a value of 43, the result of the modulus operation would be 3, which will be added to the accumulator.
  • Note: If the divisor (right side) is zero, the result will be treated as a value of 0.

+: Add the left side and the right side.

  • AddSource 8-bit Mem 0x8010 + Value 0x14 would read the 8-bit value from $8010, add 20 to it and then add that to the accumulator.

-: Subtract the right side from the left side.

  • AddSource 8-bit Mem 0x8010 - Value 0x14 would read the 8-bit value from $8010, subtract 20 from it and then add that to the accumulator.

&: Bitwise-mask the left side with the right side.

  • AddSource 8-bit Mem 0x8010 & Value 0x3f would read the 8-bit value from $8010, discard bits 6 and 7 (0x3f is 00111111 in binary) and then add that to the accumulator.

^: Bitwise-XOR the left side with the right side

  • AddSource 8-bit Mem 0x8010 ^ Mem 0x8011 would read the 8-bit values from $8010 and $8011, and result in a value where the resulting bits would be 1 if the same bit in the two operands differed, or 0 if the same bit in the two operands matched. This result would be added to the accumulator.

You can use memory references on the right side as well. AddSource 8-bit Mem 0x8010 * 8-bit Mem 0x8011 would read the two 8-bit values, multiply them together, and add that to the accumulator.

VERSION NOTICE

Addition, subtraction, and modulus operators are slated for the version 1.4 RA_Integration milestone. Processing support will be available in the version 11.4 rcheevos milestone.

Interaction with floats

The accumulator is typed based on the first thing added to it. If the first AddSource/SubSource of a chain is an integer, the accumulator will be an integer and any floats added to the accumulator will be floored before they're added to the accumulator. If the first AddSource/SubSource of a chain is a float, the accumulator will be a float and any integers added to the accumulator will be converted to floats before they're added to the accumulator.

Note that when the accumulator is added to the final condition, the type of the final condition is used. So if the final condition is float and the accumulator is an integer, the accumulator will be converted to a float before it's added to the final condition.

To force all floats in an AddSource chain to be floored, you need an extra first and last condition:

IDFlagTypeSizeMemoryCmpTypeSizeMem/ValHits
1AddSourceValue0
2AddSourceMemFloat0x1000
3AddSourceMemFloat0x1004
4AddSourceMemFloat0x1008
5Value0>Value120 (0)

Line 1 primes the accumulator as an integer, so lines 2-4 will be floored before they're added to the accumulator. Line 5 ensures the final value is an integer before doing the comparison. Without line 1, lines 2-4 would be accumulated as floats. Without line 5, the accumulator would be added to the last float without it being floored.

Released under the GPL-3 License. There are no copyright-protected ROMs available for download on RetroAchievements.