Created
September 26, 2025 22:29
-
-
Save PhoenixBound/6da220aa0eda7a26442ad519d0800b5c to your computer and use it in GitHub Desktop.
Fallible money giving commands for CCExpand
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // "Fallible money giving" commands by PhoenixBound | |
| // Last updated: 2025-09-26 | |
| // --- | |
| // SETUP INSTRUCTIONS | |
| // 1. In CCExpand.ccs, add cc_try_give_money.CC_TryGiveMoney and | |
| // cc_try_give_money.CC_CanGiveMoney to the "CodeTable" in their | |
| // appropriate spots. | |
| // 2. Adjust the command definitions below, to replace "1A xx" | |
| // and "1A yy" with their appropriate byte values, based on | |
| // where you put them in the CodeTable in step 1. | |
| // 3. (OPTIONAL) Re-export the command definitions here into your | |
| // own file full of useful command definitions: | |
| // | |
| // // See cc_try_give_money.ccs for documentation | |
| // command try_give_money(n) { | |
| // cc_try_give_money.try_give_money(n) | |
| // } | |
| // // See cc_try_give_money.ccs for documentation | |
| // command money_gift_is_too_big(amt) { | |
| // cc_try_give_money.money_gift_is_too_big(amt) | |
| // } | |
| // | |
| // I assume that works anyway. I haven't tried doing that in | |
| // CCScript before. Doing this means you don't have to import | |
| // this ugly file everywhere. | |
| // 4. It's for *your* hack's money. Use it when *you* need it! | |
| // https://www.youtube.com/watch?v=pdPM6j1Q4sg | |
| import asm65816 | |
| import ccexpand | |
| // Inputs: | |
| // amt: The amount of money to give to the player | |
| // (0 means use the argument register) | |
| // Outputs: | |
| // result register: 0 if the player fully received `amt` | |
| // dollars; otherwise, the player's current | |
| // cash on hand + `amt` - 99999 (i.e., the | |
| // remainder that would be lost if | |
| // `givemoney(amt)` were used instead). | |
| // Effects: | |
| // If the player's cash on hand + `amt` > 99'999, does | |
| // nothing; otherwise, gives the player `amt` more dollars | |
| // of cash on hand, as if `givemoney(amt)` were used. | |
| command try_give_money(amt) { | |
| "[1A xx {long amt}]" | |
| } | |
| // Inputs: | |
| // amt: The amount of money to give to the player | |
| // (0 means use the argument register) | |
| // Outputs: | |
| // result register: 0 if the player has room for all | |
| // `amt` dollars in their wallet; | |
| // otherwise, the player's current cash on | |
| // hand + `amt` - 99999 (i.e., the | |
| // remainder that would be lost after | |
| // using `givemoney(amt)`). | |
| // Effects: | |
| // Nothing | |
| command money_gift_is_too_big(amt) { | |
| "[1A yy {long amt}]" | |
| } | |
| CC_TryGiveMoney: M_EB_Function_Wrapper({ | |
| LDY_i (0x0004) | |
| JSL (R_Read_Parameter_Bytes) | |
| LDA_a (D_cc_argv) | |
| STA_d (0x06) | |
| LDA_a (D_cc_argv_2) | |
| STA_d (0x08) | |
| JSL (R_Set_06_To_Argument_If_Zero) | |
| LDA_d (0x06) | |
| STA_d (0x0A) | |
| STA_d (0x0E) | |
| LDA_d (0x08) | |
| STA_d (0x0C) | |
| STA_d (0x10) | |
| JSL (Can_Give_Money) | |
| LDA_d (0x06) | |
| STA_d (0x0E) | |
| LDA_d (0x08) | |
| STA_d (0x10) | |
| JSL (R_Set_Working_Memory) | |
| LDA_d (0x06) | |
| ORA_d (0x08) | |
| BNE_a (_return) | |
| // If there's nothing that'll vanish out of existence, then | |
| // give the money for real | |
| LDA_d (0x0A) | |
| STA_d (0x0E) | |
| LDA_d (0x0C) | |
| STA_d (0x10) | |
| JSL (0xC22214) | |
| _return: | |
| }) | |
| CC_CanGiveMoney: M_EB_Function_Wrapper({ | |
| LDY_i (0x0004) | |
| JSL (R_Read_Parameter_Bytes) | |
| LDA_a (D_cc_argv) | |
| STA_d (0x06) | |
| LDA_a (D_cc_argv_2) | |
| STA_d (0x08) | |
| JSL (R_Set_06_To_Argument_If_Zero) | |
| LDA_d (0x06) | |
| STA_d (0x0E) | |
| LDA_d (0x08) | |
| STA_d (0x10) | |
| JSL (Can_Give_Money) | |
| LDA_d (0x06) | |
| STA_d (0x0E) | |
| LDA_d (0x08) | |
| STA_d (0x10) | |
| JSL (R_Set_Working_Memory) | |
| }) | |
| Can_Give_Money: M_EB_Function_Wrapper_UserStack_Clobber(-4, { | |
| // $00-$03 = amt + player's cash on hand (GAME_STATE+game_state::money_carried) | |
| LDA_d (0x12) | |
| CLC | |
| ADC_a (0x9831) | |
| STA_d (0x00) | |
| LDA_d (0x14) | |
| ADC_a (0x9833) | |
| STA_d (0x02) | |
| // Subtract 99999 | |
| LDA_d (0x00) | |
| SEC | |
| SBC_i (short [0] 99999) | |
| STA_d (0x00) | |
| LDA_d (0x02) | |
| SBC_i (short [1] 99999) | |
| // STA_d (0x02) | |
| // If the result was negative, return 0 | |
| // If the result was 0 or something positive, return that | |
| BMI_a (_return_zero) | |
| STA_d (0x0C) | |
| LDA_d (0x00) | |
| STA_d (0x0A) | |
| BRA_a (_return) | |
| _return_zero: | |
| STZ_d (0x0A) | |
| STZ_d (0x0C) | |
| _return: | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Test script for the fallible money giving commands | |
| // You don't need this file in your hack! It's only useful for | |
| // debugging and testing the commands. | |
| import cc_try_give_money | |
| command zero_money { | |
| givemoney(50000) | |
| givemoney(49999) | |
| takemoney(50000) | |
| takemoney(49999) | |
| } | |
| // Attach this to an NPC to ensure that the control code is working as specified | |
| // in its doc comment | |
| try_give_money_test: { | |
| zero_money | |
| open_wallet | |
| "@TRY GIVE MONEY TEST" next | |
| // TEST 1: test that giving succeeds under ideal conditions | |
| try_give_money(99999) | |
| rtoarg | |
| "@Ensure that 0 = {number(0)} and the player has $99999" | |
| open_wallet | |
| next | |
| // TEST 2: test that giving can fail when you're at $99999 | |
| givemoney(50000) | |
| givemoney(49999) | |
| try_give_money(1) | |
| rtoarg | |
| "@Ensure that 1 = {number(0)} and the player has $99999" | |
| open_wallet | |
| next | |
| try_give_money(420) | |
| rtoarg | |
| "@And that {number(0)} is lit fam, and the player still has $99999" | |
| open_wallet | |
| next | |
| // TEST 3: test that when giving money fails, no money is actually given | |
| zero_money | |
| givemoney(50000) | |
| try_give_money(50000) | |
| rtoarg | |
| "@Ensure again that 1 = {number(0)} and the player has $50000" | |
| open_wallet | |
| next | |
| try_give_money(50419) | |
| rtoarg | |
| "@And that {number(0)} is still an overused joke, and the player has $50000" | |
| open_wallet | |
| next | |
| // TEST 4: same thing but for a difference of >65536 | |
| zero_money | |
| givemoney(25000) | |
| try_give_money(75000) | |
| rtoarg | |
| "@Ensure again that 1 = {number(0)} and the player has $25000" | |
| open_wallet | |
| next | |
| try_give_money(75419) | |
| rtoarg | |
| "@And that {number(0)} is discussed on r[5F]trees and the player has $25000" | |
| open_wallet | |
| next | |
| // TEST 5: giving money succeeds when you already have money | |
| zero_money | |
| givemoney(25000) | |
| try_give_money(252) | |
| rtoarg | |
| "@0 = {number(0)} and the player has $25252 dollars" | |
| open_wallet | |
| next | |
| // TEST 6: the amount to give is read from the argument register when 0 is passed in | |
| zero_money | |
| givemoney(33334) | |
| // Set all registers to something other than 33334 | |
| counter(69) | |
| ctoarg | |
| swap | |
| rtoarg | |
| store_registers | |
| // Set only the argument register to 33334 | |
| "[19 27 06]" | |
| swap | |
| // Give that much money | |
| try_give_money(0) | |
| swap | |
| "@0 = {number(0)} and the player has $66668" | |
| open_wallet | |
| next | |
| // And again | |
| swap | |
| try_give_money(0) | |
| swap | |
| "@3 = {number(0)} and the player has $66668" | |
| open_wallet | |
| next | |
| swap | |
| "@And just to make sure... 33334 = {number(0)}" next | |
| // TEST 7: same thing, but make the high word of the argument register nonzero | |
| zero_money | |
| givemoney(60000) | |
| givemoney(6000) | |
| counter(69) | |
| ctoarg | |
| swap | |
| rtoarg | |
| store_registers | |
| "[19 27 06]" | |
| swap | |
| try_give_money(0) | |
| swap | |
| "@32001 = {number(0)} and the player has $66000" | |
| open_wallet | |
| next | |
| "@If all of those statements are correct, then the control code must be working." next | |
| "@MONEY GIFT IS TOO BIG TEST" next | |
| zero_money | |
| // TEST 1: give various immediate amounts big and small | |
| money_gift_is_too_big(0x7FFF) | |
| rtoarg | |
| "@0 = {number(0)} and player has $0" | |
| open_wallet | |
| next | |
| money_gift_is_too_big(99999) | |
| rtoarg | |
| "@0 = {number(0)} and player has $0" | |
| open_wallet | |
| next | |
| money_gift_is_too_big(9999999) | |
| rtoarg | |
| "@9900000 =" linebreak | |
| " {number(0)} and player has $0" | |
| open_wallet | |
| next | |
| // TEST 2: now with money | |
| zero_money | |
| givemoney(50000) | |
| money_gift_is_too_big(49999) | |
| rtoarg | |
| "@0 = {number(0)} and player has $50000" | |
| open_wallet | |
| next | |
| money_gift_is_too_big(50000) | |
| rtoarg | |
| "@1 = {number(0)} and player has $50000" | |
| open_wallet | |
| next | |
| money_gift_is_too_big(150000) | |
| rtoarg | |
| "@100001 =" linebreak | |
| " {number(0)} and player has $50000" | |
| open_wallet | |
| next | |
| // TEST 3: now with the argument register | |
| zero_money | |
| givemoney(33334) | |
| counter(69) | |
| ctoarg | |
| swap | |
| rtoarg | |
| store_registers | |
| "[19 27 06]" | |
| swap | |
| money_gift_is_too_big(0) | |
| swap | |
| "@0 = {number(0)} and the player has $33334" | |
| open_wallet | |
| next | |
| zero_money | |
| givemoney(33334) | |
| givemoney(33334) | |
| counter(69) | |
| ctoarg | |
| swap | |
| rtoarg | |
| store_registers | |
| "[19 27 06]" | |
| swap | |
| money_gift_is_too_big(0) | |
| swap | |
| "@33337 = {number(0)} and the player has $66668" | |
| open_wallet | |
| next | |
| swap | |
| "@And 66668 = {number(0)}" next | |
| "@...That's probably enough for now. Good night." end | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment