| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155 |
- /*----------------------------------------------------------------------------*\
- ===========================
- Y Sever Includes - INI Core
- ===========================
- Description:
- Does some internal processing for the text system.
- Legal:
- Version: MPL 1.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is the YSI ini include.
-
- The Initial Developer of the Original Code is Alex "Y_Less" Cole.
- Portions created by the Initial Developer are Copyright (C) 2011
- the Initial Developer. All Rights Reserved.
-
- Contributors:
- ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
-
- Thanks:
- JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
- ZeeX - Very productive conversations.
- koolk - IsPlayerinAreaEx code.
- TheAlpha - Danish translation.
- breadfish - German translation.
- Fireburn - Dutch translation.
- yom - French translation.
- 50p - Polish translation.
- Zamaroht - Spanish translation.
- Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
- for me to strive to better.
- Pixels^ - Running XScripters where the idea was born.
- Matite - Pestering me to release it and using it.
-
- Very special thanks to:
- Thiadmer - PAWN, whose limits continue to amaze me!
- Kye/Kalcor - SA:MP.
- SA:MP Team past, present and future - SA:MP.
-
- Version:
- 1.0
- Changelog:
- 01/05/11:
- First version.
- Functions:
- Public:
- -
- Core:
- -
- Stock:
- -
- Static:
- -
- Inline:
- -
- API:
- -
- Callbacks:
- -
- Definitions:
- -
- Enums:
- -
- Macros:
- -
- Tags:
- -
- Variables:
- Global:
- -
- Static:
- -
- Commands:
- -
- Compile options:
- -
- Operators:
- -
- \*----------------------------------------------------------------------------*/
- #include "..\y_amx"
- #include "..\y_utils"
- #include "..\y_ini"
- #include "..\y_debug"
- #include "..\y_iterate"
- #include "..\y_scriptinit"
- #include "..\y_languages"
- #include "..\y_dialog"
- #include "..\y_inline"
- #include "y_natives"
- enum e_TEXT_DISPLAY_TYPE
- {
- text_type_print = cellmin,
- text_type_3d = -4,
- text_type_player = -3,
- text_type_alert = -2,
- text_type_td = -1,
- text_type_client = 0,
- text_type_game1,
- text_type_game2,
- text_type_game3,
- text_type_game4,
- text_type_game5,
- text_type_game6
- }
- //#include "..\y_master"
- // End conditions for the recursive calls (strings and publics).
- #define _YT@LE@E%0>
- #define _YT@LT@E%0> ;
- // Recursive wanted text definition. Needs two levels of indirection to strip
- // the excess commas (,%0,%1).
- #if defined Y_TEXT_UNIQUE
- #define _YT@LO(,%0,%1) UNIQUE_FUNCTION<%0@%1@...@yX_>();public UNIQUE_FUNCTION<%0@%1@...@yX_>(){}
- #else
- #define _YT@LO(,%0,%1) %0@%1@yX_();public %0@%1@yX_(){}
- #endif
- #define _YT@LE%0[%1]%2> _YT@LO(%0,%1) _YT@LE%2>
- // Recursive local default string definition.
- #define _YT@LJ(,%0,%1) #%0":"#%1"|"
- #define _YT@LT%0[%1]%2> _YT@LJ(%0,%1)_YT@LT%2>
- // Recursive macro with clever ending to load many items from 1 "loadtext"
- // keyword. NOW RENAMED FROM JUST "text" - WORST NAMING EVER!
- #define loadtext%0[%1]%2; _YT@LE,%0[%1]%2@E>static stock DEFAULT_TEXT_SET[]=_YT@LT,%0[%1]%2@E>
- #define Text_RegisterTag(%1) \
- loadtext core[%1]
- // Clever macros to load default values when not specified.
- //#define Text_Send(%0,%1) _Text_Send(%0,DEFAULT_TEXT_SET,#%1)
- #define DO_TEXT_SET: _:HAS_TEXT_SET:NO_TEXT_SET:
- #define HAS_TEXT_SET:NO_TEXT_SET:%0$%1||| DEFAULT_TEXT_SET,#%1|||
- #define NO_TEXT_SET: "\3",
- #define DEFAULT_TEXT_SET,#%1->%2||| #core#:#%1#|,#%2|||
- // WTF does this do? I can't even remember what slots are!
- //#define core":"#%1:%2"|",%3) %1":"#%2"|",%3)
- #define core#:#%1[%2]%9#|,%3) %1#:#%2#|,%3)
- /*#if defined _inc_y_languages
- #define Text_GetLanguageCodes() Langs_GetLanguageCodes()
-
- #define Text_GetPlayerLanguage(%0) Langs_GetPlayerLanguage(%0)
- #else
- // y_languages doesn't really do much TBH... This used to have three
- // langugages, but then I realised that without the "y_languages"
- // library there was no way for a player to select their language.
- // "XX" is used as a dummy to ensure that the array in the enum is always
- // valid and that the compiler doesn't optimise it out.
- #define Text_GetLanguageCodes() "EN|XX|" //|NL|ES|"
- // Number of "|" separated strings above (always 1).
- #define YSI_MAX_LANGUAGES (Language:2)
-
- #define Text_GetPlayerLanguage(%0) (Language:0)
- #endif*/
- // Return types
- enum E_TEXT_FIND
- {
- E_TEXT_FIND_NONE,
- E_TEXT_FIND_JUST,
- E_TEXT_FIND_MANY
- }
- // This holds the data for all entry points.
- enum e_TEXT_SETS
- {
- e_TEXT_SETS_NAME[28],
- e_TEXT_SETS_HASH,
- e_TEXT_SETS_INDEX,
- e_TEXT_SETS_LOADED
- }
- enum e_TEXT_ENTRY
- {
- e_TEXT_ENTRY_NAME[MAX_INI_ENTRY_NAME],// char],
- e_TEXT_ENTRY_HASH,
- e_TEXT_ENTRY_LEFT,
- e_TEXT_ENTRY_RIGHT,
- e_TEXT_ENTRY_POINTERS[YSI_MAX_LANGUAGES]
- }
- #define TEXT_MASTER YSI_g_sDistributionID
- #if !defined MAX_SINGLE_TEXT_ITEM
- #define MAX_SINGLE_TEXT_ITEM (1024)
- #endif
- #include "..\y_styles"
- #include "..\y_hooks"
- static stock
- YSI_g_sTextSets[Y_TEXT_MAX_SETS][e_TEXT_SETS],
- YSI_g_sTextEntries[MAX_TEXT_ENTRIES][e_TEXT_ENTRY],
- YSI_g_sTextStrings[MAX_TEXT_ENTRIES * _:YSI_MAX_LANGUAGES][MAX_INI_ENTRY_TEXT / 4],// char],
- YSI_g_sReturnText[MAX_SINGLE_TEXT_ITEM],
- YSI_g_sExtraText[MAX_SINGLE_TEXT_ITEM],
- YSI_g_sUnusedEntry = 0,
- YSI_g_sDistributionID = -1,
- YSI_g_sUnusedSlot = 0,
- YSI_g_sCurLoadTextFile[64],
- YSI_g_sCallbacks,
- YSI_g_sRemaining = sizeof (YSI_g_sTextStrings) * sizeof (YSI_g_sTextStrings[]),
- Language:YSI_g_sLangIndex;
- // OnFilterScriptInit
- // =============================================================================
- // | ========================================================================= |
- // | | | |
- // | | HERE STARTS THE LOADING CODE | |
- // | | | |
- // | ========================================================================= |
- // =============================================================================
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- This callback is hard coded in to YSI to be called absolutely last! Note
- that this WAS hard coded, but now uses a more generic chaining method not
- based on y_scriptinit and instead just uses the regular ALS method.
- \*----------------------------------------------------------------------------*/
- public OnGameModeInit()
- {
- P:1("TextInt_OnGameModeInit called");
- if (YSI_FILTERSCRIPT)
- {
- if (YSI_g_sCallbacks & 16)
- {
- CallLocalFunction("TextInt_OnGameModeInit", "");
- }
- }
- else
- {
- CallLocalFunction("TextInt_OnGameModeInit", "");
- //Text_SpecialInit();
- Text_RefreshLoaded();
- _Styles_SpecialInit();
- }
- P:1("TextInt_OnGameModeInit ended");
- return 1;
- }
- #if defined _ALS_OnGameModeInit
- #undef OnGameModeInit
- #else
- #define _ALS_OnGameModeInit
- #endif
- #define OnGameModeInit TextInt_OnGameModeInit
- forward TextInt_OnGameModeInit();
- public OnFilterScriptInit()
- {
- P:1("TextInt_OnFilterScriptInit called");
- if (funcidx("TextInt_OnGameModeInit") != -1)
- {
- YSI_g_sCallbacks |= 16;
- }
- // DO ALL (MOST) OTHER INITS FIRST. ENSURE WE COME LATER.
- CallLocalFunction("TextInt_OnFilterScriptInit", "");
- //Text_SpecialInit();
- Text_RefreshLoaded();
- _Styles_SpecialInit();
- P:1("TextInt_OnFilterScriptInit ended");
- return 1;
- }
- #if defined _ALS_OnFilterScriptInit
- #undef OnFilterScriptInit
- #else
- #define _ALS_OnFilterScriptInit
- #endif
- #define OnFilterScriptInit TextInt_OnFilterScriptInit
- forward TextInt_OnFilterScriptInit();
- //forward Text_SpecialInit();
- //
- //public Text_SpecialInit()
- //static stock Text_SpecialInit()
- //{
- // P:1("Text_SpecialInit called");
- // // Scan the AMX for all public functions of the type "XX@YY@NN@yX_". These
- // // are the declarations for included texts.
- // Text_RefreshLoaded();
- // _Styles_SpecialInit();
- // P:2("Text_SpecialInit ended");
- //}
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- //static stock Text_GetDistributionID()
- hook OnScriptInit()
- {
- P:1("Text_OnScriptInit called");
- // Initialise.
- new
- i;
- for (i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- YSI_g_sTextSets[i][e_TEXT_SETS_NAME][0] = '\1';
- YSI_g_sTextSets[i][e_TEXT_SETS_INDEX] = -1;
- }
- for (i = 0; i != MAX_TEXT_ENTRIES; ++i)
- {
- YSI_g_sTextEntries[i][e_TEXT_ENTRY_HASH] = i + 1;
- }
- // Redirect all the pointers to the last cell.
- new
- offset = (sizeof (YSI_g_sTextStrings) - 1) * 4;
- i = (sizeof (YSI_g_sTextStrings[]) - 1) * 4;
- // Get the absolute address of the pointer to the last array.
- #emit CONST.pri YSI_g_sTextStrings
- #emit LOAD.S.alt offset
- #emit ADD
- // Get the data at that address (i.e. the RELATIVE pointer).
- #emit LOAD.I
- // Get the RELATIVE address of the last element.
- #emit LOAD.S.alt i
- #emit ADD
- #emit STOR.S.pri offset
- for (i = sizeof (YSI_g_sTextStrings) - 1; i != 0; --i)
- {
- //YSI_g_sTextStrings[i][0] = i + 1;
- #emit CONST.pri YSI_g_sTextStrings
- #emit LOAD.S.alt i
- #emit SHL.C.alt 2
- #emit ADD
- #emit MOVE.alt
- #emit LOAD.S.pri offset
- #emit STOR.I
- #emit ADD.C 4
- #emit STOR.S.pri offset
- }
- offset = getproperty(8, YSIM_TEXT_D);
- i = 0;
- while (i != 32)
- {
- if (!(offset & (1 << i)))
- {
- YSI_g_sDistributionID = i;
- offset |= 1 << i;
- break;
- }
- ++i;
- }
- if (i != 32)
- {
- setproperty(8, YSIM_TEXT_D, offset);
- }
- P:C(else P:E("y_text distribution ID not set"););
- CallRemoteFunction("Text_ResetLoaded", "");
- state y_text_ending : n;
- state y_text_get_text : n;
- state y_render_show : y_render_show_print;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- hook OnScriptExit()
- {
- P:1("Textint_OnScriptExit called");
- new
- idx = 0,
- buffer[32],
- pos;
- while ((idx = AMX_GetPublicNameSuffix(idx, buffer, _A<@yX_>)))
- {
- pos = chrfind('@', buffer);
- if (pos != -1)
- {
- buffer[pos] = ':';
- pos = chrfind('@', buffer, pos);
- if (pos != -1)
- {
- buffer[pos] = '\0';
- if (existproperty(7, buffer) && getproperty(7, buffer) == TEXT_MASTER)
- {
- deleteproperty(7, buffer);
- }
- }
- }
- }
- state y_text_ending:y;
- CallRemoteFunction("Text_RefreshLoaded", "");
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_ResetLoaded
- Params:
- -
- Return:
- -
- Notes:
- When a mode ends this is called so that other scripts can know to re-load
- any text which was previously owned by this script that they still need.
- \*----------------------------------------------------------------------------*/
- forward Text_ResetLoaded();
- public Text_ResetLoaded() <>
- {
- }
- public Text_ResetLoaded() <y_text_ending:n>
- {
- // Called to reset the owners of texts after a gamemode restart.
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- if (YSI_g_sTextSets[i][e_TEXT_SETS_NAME][0] != '\1')
- {
- setproperty(7, YSI_g_sTextSets[i][e_TEXT_SETS_NAME], TEXT_MASTER);
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_RefreshLoaded
- Params:
- -
- Return:
- -
- Notes:
- Loops through all text definition functions in the mode (defined as:
- "file@section@unique@yX_" (note that "@unique" is optional but irrelevant).
- If any are found and the property "file:section" isn't defined claims
- ownership of that section so that the text can be loaded in to this mode.
- \*----------------------------------------------------------------------------*/
- forward Text_RefreshLoaded();
- public Text_RefreshLoaded() <y_text_ending:y>
- {
- //printf("Text_RefreshLoaded: y");
- // Do nothing, only called for other scripts to check that all their text
- // items are still loaded.
- }
- public Text_RefreshLoaded() <y_text_ending:n>
- {
- //printf("Text_RefreshLoaded: n");
- if (Langs_GetLanguageCount() == Language:0)
- {
- P:E("No languages found - Did you add \"Langs_AddLanguage\" to the script init (NOT \"main\")?");
- }
- new
- idx = 0,
- buffer[32],
- pos;
- while ((idx = AMX_GetPublicNameSuffix(idx, buffer, _A<@yX_>)))
- {
- strunpack(buffer, buffer);
- pos = chrfind('@', buffer);
- //printf("%d, %x", pos, buffer[0]);
- if (pos != -1)
- {
- // Get rid of the end parts, doesn't matter if "Y_TEXT_UNIQUE" is
- // defined or not as EVERYTHING later is dropped.
- buffer[pos] = ':';
- pos = chrfind('@', buffer, pos);
- if (pos != -1)
- {
- buffer[pos] = '\0';
- //printf("buffer: %s %d", buffer, existproperty(7, buffer));
- //buffer[pos + 1] = '\0';
- if (!existproperty(7, buffer))
- {
- setproperty(7, buffer, TEXT_MASTER);
- Text_AddLocal(buffer, bernstein(buffer));
- }
- }
- }
- }
- Text_LoadLocals();
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- static stock Text_AddLocal(buffer[], hash)
- {
- P:4("Text_AddLocal called: \"%s\", %i", buffer, hash);
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- if (YSI_g_sTextSets[i][e_TEXT_SETS_NAME][0] == '\1')
- {
- YSI_g_sTextSets[i][e_TEXT_SETS_HASH] = hash;
- strcpy(YSI_g_sTextSets[i][e_TEXT_SETS_NAME], buffer, 28);
- return;
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- forward Text_INILoad(offset, tag[], name[], value[]);
- public Text_INILoad(offset, tag[], name[], value[])
- {
- // Get the path.
- // Get the file.
- // Get the extension.
- P:1("Text_INILoad called: %d, %s, %s, %s", offset, tag, name, value);
- P:5("Text_INILoad: IsPacked? %08x%08x", value[0], value[1]);
- new
- fname[sizeof (YSI_g_sCurLoadTextFile) - (3 + 9)],
- len = strlen(YSI_g_sCurLoadTextFile);
- //format(fname, sizeof (fname
- strcpy(fname, YSI_g_sCurLoadTextFile[9], len - (3 + 9 - 1));
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- //printf("fname: %s, %d, %d, %s", fname, len, offset, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]);
- if (!strcmp(YSI_g_sTextSets[i][e_TEXT_SETS_NAME], fname, true, offset - 1) && !strcmp(YSI_g_sTextSets[i][e_TEXT_SETS_NAME][offset], tag, true))
- {
- //printf("%d \"%s\" \"%s\" \"%s\"", len, fname, YSI_g_sCurLoadTextFile[len - 2], tag);
- len = strlen(name);
- new
- slot = name[--len],
- number,
- hash = 1;
- P:6("Text_INILoad: Get Number");
- while ('0' <= slot <= '9')
- {
- name[len] = '\0';
- number += (slot - '0') * hash;
- hash *= 10;
- slot = name[--len];
- }
- // So "MY_TEXT_1" becomes "MY_TEXT", not "MY_TEXT_".
- if (slot == '_')
- {
- name[len] = '\0';
- }
- hash = bernstein(name);
- slot = Text_FindEntry(YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], hash);
- P:6("Text_INILoad: Check slot %d", slot);
- if (slot == -1)
- {
- Text_AddEntry(i, name, value, hash);
- //P:5("%d,%d,%d,%d,%d", YSI_g_sTextStrings[ss][0], YSI_g_sTextStrings[ss][1], YSI_g_sTextStrings[ss][2], YSI_g_sTextStrings[ss][3], YSI_g_sTextStrings[ss][4]);
- }
- else
- {
- P:6("Text_INILoad: Check Collision");
- if (strcmp(name, YSI_g_sTextEntries[slot][e_TEXT_ENTRY_NAME], true))
- {
- P:E("Text collision on \"%s\" and \"%s\"!", name, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]);
- return;
- }
- else if (YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex] == -1)
- {
- new
- ss = Text_GetFreeSlot();
- if (ss == -1)
- {
- P:E("Text buffer full!");
- return;
- }
- //strpack(YSI_g_sTextStrings[ss], value, MAX_INI_ENTRY_TEXT * 4);
- Text_UpdateFreeSlot(Format_Standardise(value, YSI_g_sTextStrings[ss], MAX_INI_ENTRY_TEXT));
- //P:5("%d,%d,%d,%d,%d", YSI_g_sTextStrings[ss][0], YSI_g_sTextStrings[ss][1], YSI_g_sTextStrings[ss][2], YSI_g_sTextStrings[ss][3], YSI_g_sTextStrings[ss][4]);
- //strcpy(YSI_g_sTextStrings[ss], value, MAX_INI_ENTRY_TEXT * 4);
- YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex] = ss;
- }
- else if (number)
- {
- // Found a string with multiple entries in the INI file to
- // be linked together dynamically.
- new
- ss = Text_GetFreeSlot();
- if (ss == -1)
- {
- P:E("Text buffer full!");
- return;
- }
- Text_UpdateFreeSlot(Format_Standardise(value, YSI_g_sTextStrings[ss], MAX_INI_ENTRY_TEXT));
- hash = YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex];
- if (hash == -1)
- {
- // Will happen when the text entry exists in other
- // languages but not yet in this one.
- YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex] = ss;
- }
- else if (number == 1)
- {
- YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex] = ss;
- len = strlen(YSI_g_sTextStrings[ss]);
- //if (len < sizeof (YSI_g_sTextStrings[]) - 2)
- //{
- // Add the linked list.
- Text_DoLinkedText(YSI_g_sTextStrings[ss], hash, len);
- //}
- //else
- //{
- // P:W("Text size error on \"%s\"!", name);
- //}
- }
- else
- {
- // Add the string to the chain.
- slot = 2;
- len = strlen(YSI_g_sTextStrings[hash]);
- // Loop through existing strings in this list till we
- // find the right position (either the specified ID or
- // the last item) at which to add the new string.
- while (slot < number)
- {
- if (len < 2)
- {
- break;
- }
- //if (YSI_g_sTextStrings[hash][len - 2] != '\05')
- //{
- // break;
- //}
- //hash = YSI_g_sTextStrings[hash][len - 1];
- if (!Text_GetLinkedText(YSI_g_sTextStrings[hash], hash, len))
- {
- break;
- }
- len = strlen(YSI_g_sTextStrings[hash]);
- ++slot;
- }
- if (len < 2)
- {
- Text_DoLinkedText(YSI_g_sTextStrings[hash], ss, len);
- }
- //else if (YSI_g_sTextStrings[hash][len - 2] == '\05')
- else if (Text_HasLinkedText(YSI_g_sTextStrings[hash], len))
- {
- slot = Text_UpdateLinkedText(YSI_g_sTextStrings[hash], ss, len);
- //slot = YSI_g_sTextStrings[hash][len - 1];
- //YSI_g_sTextStrings[hash][len - 1] = ss;
- len = strlen(YSI_g_sTextStrings[ss]);
- //if (len < sizeof (YSI_g_sTextStrings[]) - 2)
- //{
- // // Add the linked list.
- // YSI_g_sTextStrings[ss][len] = '\05';
- // YSI_g_sTextStrings[ss][len + 1] = slot;
- // YSI_g_sTextStrings[ss][len + 2] = '\0';
- Text_DoLinkedText(YSI_g_sTextStrings[ss], slot, len);
- //}
- //else
- //{
- // P:W("Text size error on \"%s\"!", name);
- //}
- }
- else
- {
- //if (len < sizeof (YSI_g_sTextStrings[]) - 2)
- //{
- // // Add the linked list.
- // YSI_g_sTextStrings[hash][len] = '\05';
- // YSI_g_sTextStrings[hash][len + 1] = ss;
- // YSI_g_sTextStrings[hash][len + 2] = '\0';
- Text_DoLinkedText(YSI_g_sTextStrings[hash], ss, len);
- //}
- //else
- //{
- // P:W("Text size error on \"%s\"!", name);
- //}
- }
- }
- }
- else
- {
- P:W("Text repeat on \"%s\"!", name);
- }
- }
- // Add the current value to the current tag.
- break;
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- static stock Text_LoadLocals()
- {
- //printf("Text_LoadLocals called");
- P:4("Text_LoadLocals called");
- // This is the interesting part. Load all the sets which have a name not
- // '\1' and an index of -1.
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- P:6("Text_LoadLocals: i = %d, text = %s, %d, %d", i, YSI_g_sTextSets[i][e_TEXT_SETS_NAME], YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], YSI_g_sTextSets[i][e_TEXT_SETS_HASH]);
- if (YSI_g_sTextSets[i][e_TEXT_SETS_INDEX] == -1 && YSI_g_sTextSets[i][e_TEXT_SETS_HASH])
- {
- new
- offset = chrfind(':', YSI_g_sTextSets[i][e_TEXT_SETS_NAME]) + 1,
- j = i + 1;
- while (j != Y_TEXT_MAX_SETS)
- {
- if (YSI_g_sTextSets[j][e_TEXT_SETS_INDEX] == -1 && YSI_g_sTextSets[j][e_TEXT_SETS_HASH] && !strcmp(YSI_g_sTextSets[i][e_TEXT_SETS_NAME], YSI_g_sTextSets[j][e_TEXT_SETS_NAME], false, offset))
- {
- break;
- }
- ++j;
- }
- // Only load a file one.
- if (j != Y_TEXT_MAX_SETS)
- {
- continue;
- }
- --offset;
- //YSI_g_sTextSets[i][e_TEXT_SETS_NAME][offset] = '\0';
- YSI_g_sLangIndex = Language:0;
- new
- langs[YSI_MAX_STRING],
- pos;
- langs = Langs_GetLanguageCodes();
- while ((pos = chrfind('|', langs, pos)) != -1)
- {
- format(YSI_g_sCurLoadTextFile, sizeof (YSI_g_sCurLoadTextFile), "YSI/text/%.*s.%.2s", offset, YSI_g_sTextSets[i][e_TEXT_SETS_NAME], langs[pos - 2]);
- INI_ParseFile(YSI_g_sCurLoadTextFile, "Text_INILoad", _, true, offset + 1, _, true);
- ++pos;
- ++YSI_g_sLangIndex;
- // We can add code here to load the data from y_styles.
- }
- //format(YSI_g_sCurLoadTextFile, sizeof (YSI_g_sCurLoadTextFile), "%.*s", offset, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]);
- P:6("Text_LoadLocals: Loading style %s (%d)", YSI_g_sCurLoadTextFile, offset);
- //_Styles_ParseOne(YSI_g_sCurLoadTextFile);
- //YSI_g_sTextSets[i][e_TEXT_SETS_NAME][offset] = ':';
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- forward Text_CheckLoad(buffer[], hash);
- public Text_CheckLoad(buffer[], hash) <y_text_ending:y>
- {
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- YSI_g_sTextSets[i][e_TEXT_SETS_HASH] = 0;
- YSI_g_sTextSets[i][e_TEXT_SETS_NAME][0] = '\1';
- YSI_g_sTextSets[i][e_TEXT_SETS_NAME][1] = '\0';
- }
- }
- public Text_CheckLoad(buffer[], hash) <y_text_ending:n>
- {
- // Check if another script is already in charge of this set.
- if (getproperty(8, "T_CL"))
- {
- return;
- }
- // Nope, are we?
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- if (hash == YSI_g_sTextSets[i][e_TEXT_SETS_HASH] && !strcmp(buffer, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]))
- {
- setproperty(8, "T_CL", 1);
- return;
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_ReturnTheText
- Params:
- master - The script which owns this string.
- index - The slot in which this string is stored.
- str[] - The string to display.
- len0 - The length of the string array.
- style[E_STYLE_DATA] - The style of the string.
- len1 - The length of the style array.
- label[E_3D_DATA] - The 3D label style of the string.
- len2 - The length of the 3D array.
- Return:
- -
- Notes:
- This function is used to pass data from the owner script to the script
- which is doing the display. It passes the string to format (as an array,
- not as a string, to keep the non-standard characters). A copy of the style
- data, any 3D text label style data, the index and the master ID. Note that
- TD data isn't handled here - if there is need to use a text draw the script
- will have to call to the remote script for display functions. TD data is
- loaded in all scripts where it is relevant. This does mean that if people
- modify a style we need to modify it in ALL scripts.
-
- TODO: Modify the y_text system to store copies of required strings in all
- modes, just because it's slightly better.
- \*----------------------------------------------------------------------------*/
- forward Text_ReturnTheText(master, index, str[], len0, style[E_STYLE_DATA], len1, label[E_3D_DATA], len2);
- public Text_ReturnTheText(master, index, str[], len0, style[E_STYLE_DATA], len1, label[E_3D_DATA], len2) <y_text_get_text:n>
- {
- }
- public Text_ReturnTheText(master, index, str[], len0, style[E_STYLE_DATA], len1, label[E_3D_DATA], len2) <y_text_get_text:y>
- {
- P:4("Text_ReturnTheText called: %d,%d,%d,%d,%d len = %d (%s)", str[0], str[1], str[2], str[3], str[4], len0, str);
- strcpy(YSI_g_sReturnText, str, len0);
- setproperty(8, YSIM_TXTLEN, _Format_SetStyleData(master, index, style, label));
- }
- /*----------------------------------------------------------------------------*\
- Function:
- _Text_CheckOwnership
- Params:
- file[] - File to check.
- str[] - Section name to check.
- Return:
- Does this script own the named section in the current file?
- Notes:
- Sets "YSI_g_sReturnText" for use in "_Text_LookupName" too.
- \*----------------------------------------------------------------------------*/
- stock _Text_CheckOwnership(file[], str[])
- {
- P:4("_Text_CheckOwnership called: %s, %s", file, str);
- format(YSI_g_sReturnText, sizeof (YSI_g_sReturnText), "%s:%s", file, str);
- return existproperty(7, YSI_g_sReturnText) && (getproperty(7, YSI_g_sReturnText) == TEXT_MASTER);
- }
- /*----------------------------------------------------------------------------*\
- Function:
- _Text_LookupName
- Params:
- name[] - Name of the string to look up.
- Return:
- Slot storing the pointers for the named section.
- Notes:
- Assumes this script owns the section based on previously having called
- "_Text_CheckOwnership". This is assumed as both functions are called from
- only y_styles (hence the private naming convention). Note that the string
- "YSI_g_sReturnText" is set in "_Text_CheckOwnership" because we make
- guarantees about the order in which these functions are called.
- \*----------------------------------------------------------------------------*/
- stock _Text_LookupName(name[])
- {
- P:4("_Text_LookupName called: %s, %s", name, YSI_g_sReturnText);
- //format(YSI_g_sReturnText, sizeof (YSI_g_sReturnText), "%s:%s", YSI_g_sCurLoadTextFile, str);
- new
- sh = bernstein(YSI_g_sReturnText);
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- if (sh == YSI_g_sTextSets[i][e_TEXT_SETS_HASH] && !strcmp(YSI_g_sReturnText, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]))
- {
- // Got the start slot.
- return Text_FindEntry(YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], bernstein(name));
- }
- }
- return -1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- _Text_ReturnSingle
- Params:
- str[] - String to be returned.
- len0 - The length of the string.
- Return:
- -
- Notes:
- This function, along with _Text_RemoteSingle, is used to get a single string
- from a remote script when the exact ID is known in advance and no other data
- like stlyes are required.
- \*----------------------------------------------------------------------------*/
- forward _Text_ReturnSingle(str[], len0);
- public _Text_ReturnSingle(str[], len0) <y_text_get_text : n>
- {
- }
- public _Text_ReturnSingle(str[], len0) <y_text_get_text : y>
- {
- #pragma unused len0
- strcpy(YSI_g_sExtraText, str);
- }
- forward _Text_RemoteSingle(master, id);
- public _Text_RemoteSingle(master, id)
- {
- if (master == TEXT_MASTER)
- {
- CallRemoteFunction("_Text_ReturnSingle", "ai", YSI_g_sTextStrings[id], MAX_SINGLE_TEXT_ITEM); //sizeof (YSI_g_sTextStrings[]));
- }
- }
- stock _Text_GetPointer(master, id)
- {
- if (master == TEXT_MASTER)
- {
- //new
- // ret = id * sizeof (YSI_g_sTextStrings[]);
- //printf("%d", ret);
- #emit CONST.alt YSI_g_sTextStrings
- #emit LOAD.S.pri id
- #emit IDXADDR
- #emit MOVE.alt
- #emit LOAD.i
- #emit ADD
- #emit RETN
- }
- state y_text_get_text : y;
- CallRemoteFunction("_Text_RemoteSingle", "ii", master, id);
- state y_text_get_text : n;
- #emit CONST.pri YSI_g_sExtraText
- #emit RETN
- //#emit STOR.S.pri ret
- //printf("%d", ret);
- // Never actually called, but shuts up the compiler
- return id;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_GetStandard
- Params:
- search[] - Search blocks to look in.
- nh - Hash of the string name to find.
- Language:l - Language in which to get the text.
- Return:
- -
- Notes:
- Gets a string in a language from a hash and a text set.
- \*----------------------------------------------------------------------------*/
- forward Text_GetStandard(search[], nh, Language:l);
- public Text_GetStandard(search[], nh, Language:l)
- {
- if (getproperty(8, YSIM_TXTFND) != -1)
- {
- return;
- }
- if (getproperty(7, search) != TEXT_MASTER)
- {
- return;
- }
- P:4("Text_GetStandard called");
- new
- sh = bernstein(search);//,
- //fail[MAX_INI_ENTRY_TEXT] = "String not found";
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- P:7("Text_GetStandard: %d, %d, %d", i, sh, YSI_g_sTextSets[i][e_TEXT_SETS_HASH]);
- if (sh == YSI_g_sTextSets[i][e_TEXT_SETS_HASH] && !strcmp(search, YSI_g_sTextSets[i][e_TEXT_SETS_NAME]))
- {
- // Got the start slot.
- new
- slot = Text_FindEntry(YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], nh);
- P:7("Text_GetStandard: found %d, %d, %d", YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], nh, slot);
- if (slot != -1)
- {
- new
- pointer = YSI_g_sTextEntries[slot][e_TEXT_ENTRY_POINTERS][l];
- P:5("Text_GetStandard: %d, %d, %d, %d", slot, pointer, getproperty(8, YSIM_TXTIND), _@);
- if (pointer != -1)
- {
- //P:5("Text_GetStandard: %08x%08x%08x%08x%08x", YSI_g_sTextStrings[pointer][0], YSI_g_sTextStrings[pointer][1], YSI_g_sTextStrings[pointer][2], YSI_g_sTextStrings[pointer][3], YSI_g_sTextStrings[pointer][4]);
- //setproperty(9, "", YSIM_STRING, YSI_g_sTextStrings[pointer]);
- setproperty(8, YSIM_TXTFND, _@);
- // I reckon this is the only time these functions have ever
- // been used together directly...
- P:5("Text_GetStandard: %s", YSI_g_sTextStrings[pointer]);
- //SetPVarString(getproperty(8, YSIM_TXTIND), "YSI_g_sString", YSI_g_sTextStrings[pointer]);
- //printf("%d %d %d %d %d = %d", YSI_g_sTextStrings[pointer][0], YSI_g_sTextStrings[pointer][1], YSI_g_sTextStrings[pointer][2], YSI_g_sTextStrings[pointer][3], YSI_g_sTextStrings[pointer][4], strlen(YSI_g_sTextStrings[pointer]));
- // TODO: Fix this for the new parameter list.
- new
- style[E_STYLE_DATA],
- label[E_3D_DATA];
- Styles_GetData(slot, style, label);
- CallRemoteFunction("Text_ReturnTheText", "iiaiaiai", TEXT_MASTER, pointer, YSI_g_sTextStrings[pointer], MAX_SINGLE_TEXT_ITEM /*sizeof (YSI_g_sTextStrings[])*/, style, _:E_STYLE_DATA, label, _:E_3D_DATA);
- //format(fail, sizeof (fail), "%s", YSI_g_sTextStrings[pointer]);
- //printf("fail: %s", fail);
- //break;
- return;
- }
- }
- break;
- }
- }
- //static const
- // fail[MAX_INI_ENTRY_TEXT] = "\1";
- //setproperty(9, "", YSIM_STRING, "\1");
- //return fail;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_GetText
- Params:
- search[] - A "|" separated list of files and sections to search in.
- name[] - The text entry to look for.
- Language:l - The language to get.
- Return:
- The specified string in the specified language.
- Notes:
- Uses "YSI_g_sReturnText" instead of a normal return because this may call
- remote scripts which will need to return a standardised string as an array
- to preserve all the non-standard characters (passing data as a string using
- __CallRemoteFunction packs the string, which we don't want).
- \*----------------------------------------------------------------------------*/
- // Get the loaded standardised version of this string.
- //forward Text_GetStandard(start[] name[], Language:l);
- static stock Text_GetText(search[], name[], Language:l)
- {
- /*new
- start = Text_GetProvider(search),
- slot = Text_FindEntry(*/
- // TODO: Parse multiple search strings.
- //search[strlen(search) - 1] = '\0';
- //new loops = 0;
- //static
- // ret[MAX_INI_ENTRY_TEXT];
- new
- pos,
- lst;
- state y_text_get_text:y;
- setproperty(8, YSIM_TXTFND, -1);
- //setproperty(8, YSIM_TXTIND, index);
- while (search[lst])
- {
- pos = strfind(search[lst], "|");
- P:7("Text_GetText: loop1 %s %d %d %s %d", search, lst, pos, search[lst], search[lst + pos + 1]);
- search[lst + pos] = '\0';
- if (existproperty(7, search[lst]))
- {
- // Only call other scripts if ANYONE owns this search.
- CallRemoteFunction("Text_GetStandard", "sii", search[lst], bernstein(name), _:l);
- //P:7("Text_GetText: loop2 %s %d %d %s %d %d", search, lst, pos, search[lst], search[pos + 1], ret[0]);
- search[lst + pos] = '|';
- //if (ret[0] != '\1')
- if (getproperty(8, YSIM_TXTFND) != -1)
- {
- //getproperty(9, "", YSIM_STRING, ret);
- //strunpack(ret, ret)
- //GetPVarString(index, "YSI_g_sString", ret, MAX_INI_ENTRY_TEXT);
- state y_text_get_text:n;
- return;// ret;
- }
- }
- lst += pos + 1;
- //if (++loops == 10) break;
- //break;
- }
- //if (ret[0] == '\1')
- {
- // Need better error reporting here.
- YSI_g_sReturnText = "Text Not Found";
- }
- state y_text_get_text:n;
- return;// ret;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- // To be public.
- //stock Text_GetProvider(search[])
- //{
- //}
- static stock Text_FindEntry(start, hash)
- {
- P:4("Text_FindEntry called: %i, %i", start, hash);
- while (start != -1)
- {
- new
- cmp = YSI_g_sTextEntries[start][e_TEXT_ENTRY_HASH] - hash;
- if (cmp < 0)
- {
- start = YSI_g_sTextEntries[start][e_TEXT_ENTRY_RIGHT];
- }
- else if (cmp > 0)
- {
- start = YSI_g_sTextEntries[start][e_TEXT_ENTRY_LEFT];
- }
- else
- {
- return start;
- }
- }
- return -1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- static stock Text_AddEntry(set, name[], value[], hash)
- {
- P:4("Text_AddEntry called: %i, \"%s\", \"%s\", %i", set, name, value, hash);
- new
- entry = Text_GetFreeEntry(),
- slot = Text_GetFreeSlot();
- if (entry == -1 || slot == -1)
- {
- P:E("Text buffer full!");
- return;
- }
- // Save the string.
- //strpack(YSI_g_sTextStrings[slot], value, MAX_INI_ENTRY_TEXT * 4);
- Text_UpdateFreeSlot(Format_Standardise(value, YSI_g_sTextStrings[slot], YSI_g_sRemaining));
- //strpack(YSI_g_sTextStrings[slot], value, MAX_INI_ENTRY_TEXT * 4);
- //strcpy(YSI_g_sTextStrings[slot], value, MAX_INI_ENTRY_TEXT * 4);
- // Save the identifier.
- P:5("Text_AddEntry: slot = %d %d,%d,%d,%d,%d", slot, YSI_g_sTextStrings[slot][0], YSI_g_sTextStrings[slot][1], YSI_g_sTextStrings[slot][2], YSI_g_sTextStrings[slot][3], YSI_g_sTextStrings[slot][4]);
- strpack(YSI_g_sTextEntries[entry][e_TEXT_ENTRY_NAME], name, MAX_INI_ENTRY_NAME * 4);
- //strcpy(YSI_g_sTextEntries[entry][e_TEXT_ENTRY_NAME], name, MAX_INI_ENTRY_NAME * 4);
- YSI_g_sTextEntries[entry][e_TEXT_ENTRY_HASH] = hash;
- YSI_g_sTextEntries[entry][e_TEXT_ENTRY_POINTERS][YSI_g_sLangIndex] = slot;
- // Insert the identifier.
- new
- idx = YSI_g_sTextSets[set][e_TEXT_SETS_INDEX],
- next;
- if (idx == -1)
- {
- YSI_g_sTextSets[set][e_TEXT_SETS_INDEX] = entry;
- }
- else
- {
- for ( ; ; )
- {
- new
- cmp = YSI_g_sTextEntries[idx][e_TEXT_ENTRY_HASH] - hash;
- if (cmp < 0)
- {
- next = YSI_g_sTextEntries[idx][e_TEXT_ENTRY_RIGHT];
- if (next == -1)
- {
- YSI_g_sTextEntries[idx][e_TEXT_ENTRY_RIGHT] = entry;
- return;
- }
- }
- else if (cmp > 0)
- {
- next = YSI_g_sTextEntries[idx][e_TEXT_ENTRY_LEFT];
- if (next == -1)
- {
- YSI_g_sTextEntries[idx][e_TEXT_ENTRY_LEFT] = entry;
- return;
- }
- }
- idx = next;
- }
- }
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- static stock Text_GetFreeSlot()
- {
- if (YSI_g_sUnusedSlot == MAX_TEXT_ENTRIES * _:YSI_MAX_LANGUAGES)
- {
- return -1;
- }
- return YSI_g_sUnusedSlot++;
- /*P:4("Text_GetFreeSlot called");
- if (YSI_g_sUnusedSlot == MAX_TEXT_ENTRIES * _:YSI_MAX_LANGUAGES)
- {
- return -1;
- }
- new
- ret = YSI_g_sUnusedSlot;
- YSI_g_sUnusedSlot = YSI_g_sTextStrings[ret][0];
- YSI_g_sTextStrings[ret][0] = '\0';
- return ret;*/
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_UpdateFreeSlot
- Params:
- length
- Return:
- -
- Notes:
- Adjusts the first index table in "YSI_g_sTextStrings" such that the next
- call to "Text_GetFreeSlot" will point to a non-zero length target string.
- \*----------------------------------------------------------------------------*/
- static stock Text_UpdateFreeSlot(len)
- {
- YSI_g_sRemaining -= len + 3;
- // Get the address of the previous slot's pointer.
- #emit LOAD.pri YSI_g_sUnusedSlot
- #emit ADD.C 0xFFFFFFFF
- #emit SHL.C.pri 2
- #emit CONST.alt YSI_g_sTextStrings
- #emit ADD
- // Get the pointer to the start of the data.
- #emit LOAD.I
- // Get the pointer to the end of the data.
- #emit LOAD.S.alt len
- #emit SHL.C.alt 2
- #emit ADD
- // Add an offset for "\05" (NULL is implicit in the code because we get an
- // extra four bytes of offset from shifting the index up a slot).
- #emit ADD.C 12
- // Temporarily store the data on the stack.
- #emit PUSH.pri
- // Now get the address of the slot of the CURRENT data.
- #emit LOAD.pri YSI_g_sUnusedSlot
- #emit SHL.C.pri 2
- #emit CONST.alt YSI_g_sTextStrings
- #emit ADD
- #emit MOVE.alt
- // Retrieve the data and store it in the new index.
- #emit POP.pri
- #emit STOR.I
- #emit RETN
- //printf("%d %d", len, YSI_g_sUnusedSlot - 1);
- // Bypass compiler warnings.
- return len;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_DebugAll
- Params:
- -
- Return:
- -
- Notes:
- Prints all the strings loaded by the system, including their data offsets
- and storage array lengths (cunning tightly packed array).
- \*----------------------------------------------------------------------------*/
- stock Text_DebugAllText()
- {
- for (new i = 0; i != YSI_g_sUnusedSlot; ++i)
- {
- new
- next,
- cur;
- printf("%d %d %d %d", i, cur, next, YSI_g_sUnusedSlot);
- Text_GetCurNextOffset(i, cur, next);
- printf("Offset: %d, Length: %d", cur, (next - cur) / 4);
- printf("Text: %s", YSI_g_sTextStrings[i]);
- }
- }
- static stock Text_GetCurNextOffset(i, &cur, &next)
- {
- // Get the address of the previous slot's pointer.
- #emit LOAD.S.pri i
- #emit SHL.C.pri 2
- #emit CONST.alt YSI_g_sTextStrings
- #emit ADD
- // Get the pointer to the start of the data.
- #emit LOAD.I
- #emit SREF.S.pri cur
- // Get the address of the previous slot's pointer.
- #emit LOAD.S.pri i
- #emit ADD.C 0x1
- #emit SHL.C.pri 2
- #emit CONST.alt YSI_g_sTextStrings
- #emit ADD
- // Get the pointer to the start of the data.
- #emit LOAD.I
- #emit SREF.S.pri next
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- Bypass run-time OOB errors when -d0 is disabled. Set the initial "next"
- pointer on the end of the string.
- \*----------------------------------------------------------------------------*/
- static stock Text_DoLinkedText(entry[], add, len)
- {
- entry[len] = '\05';
- entry[len + 1] = add;
- entry[len + 2] = '\0';
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- Bypass run-time OOB errors when -d0 is disabled. Get and set the "next"
- pointer on the end of the string.
- \*----------------------------------------------------------------------------*/
- static stock Text_UpdateLinkedText(entry[], add, len)
- {
- new
- ret = entry[len - 1];
- entry[len - 1] = add;
- return ret;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- Bypass run-time OOB errors when -d0 is disabled. Get the "next" pointer on
- the end of the string.
- \*----------------------------------------------------------------------------*/
- static stock Text_GetLinkedText(entry[], &ret, len)
- {
- if (entry[len - 2] != '\05')
- {
- return 0;
- }
- ret = entry[len - 1];
- return 1;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- Bypass run-time OOB errors when -d0 is disabled. Check if there is a "next"
- pointer.
- \*----------------------------------------------------------------------------*/
- static stock Text_HasLinkedText(entry[], len)
- {
- return (entry[len - 2] == '\05');
- }
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- static stock Text_GetFreeEntry()
- {
- P:4("Text_GetFreeEntry called");
- if (YSI_g_sUnusedEntry == MAX_TEXT_ENTRIES)
- {
- return -1;
- }
- new
- ret = YSI_g_sUnusedEntry;
- YSI_g_sUnusedEntry = YSI_g_sTextEntries[ret][e_TEXT_ENTRY_HASH];
- YSI_g_sTextEntries[ret][e_TEXT_ENTRY_HASH] = 0;
- YSI_g_sTextEntries[ret][e_TEXT_ENTRY_LEFT] = -1;
- YSI_g_sTextEntries[ret][e_TEXT_ENTRY_RIGHT] = -1;
- // Reset text storage pointers.
- for (new Language:i = Language:0; i != YSI_MAX_LANGUAGES; ++i)
- {
- YSI_g_sTextEntries[ret][e_TEXT_ENTRY_POINTERS][i] = -1;
- }
- return ret;
- }
- /*----------------------------------------------------------------------------*\
- Function:
- Text_IsLocalOwner
- Params:
- -
- Return:
- -
- Notes:
- Checks if the string we are trying to display is owned by the local script,
- and if so just use that pointer and text directly.
- \*----------------------------------------------------------------------------*/
- static stock Text_IsLocalOwner(search[], ident[], &len)
- {
- // First, find out if this script owns it's own text for speed reasons, and
- // if it does, save the handle to the text set.
- switch (search[0])
- {
- case '\1', '\2':
- {
- return -1;
- }
- case '\3':
- {
- // TODO...
- }
- default:
- {
- //Text_GetText(search, ident, lang);
- new
- pos,
- lst,
- hash;
- while (search[lst])
- {
- pos = strfind(search[lst], "|");
- search[lst + pos] = '\0';
- if (existproperty(7, search[lst]) && (getproperty(7, search[lst]) == TEXT_MASTER))
- {
- hash = bernstein(search[lst]);
- for (new i = 0; i != Y_TEXT_MAX_SETS; ++i)
- {
- if (hash == YSI_g_sTextSets[i][e_TEXT_SETS_HASH] && !strcmp(search[lst], YSI_g_sTextSets[i][e_TEXT_SETS_NAME]))
- {
- new
- ret = Text_FindEntry(YSI_g_sTextSets[i][e_TEXT_SETS_INDEX], bernstein(ident));
- if (ret != -1)
- {
- search[lst + pos] = '|';
- new
- style[E_STYLE_DATA],
- label[E_3D_DATA];
- Styles_GetData(ret, style, label);
- len = _Format_SetStyleData(TEXT_MASTER, -1, style, label) - 1;
- return ret;
- }
- }
- }
- }
- search[lst + pos] = '|';
- lst += pos + 1;
- }
- }
- }
- return -1;
- }
- static stock
- YSI_g_sLangBuffer[YSI_MAX_LANGUAGES][MAX_SINGLE_TEXT_ITEM];
- /*----------------------------------------------------------------------------*\
- Function:
- _Text_Send
- Params:
- @PlayerSet:players - A representation of players to show to.
- search[] - Text sets to look in for this string.
- ident[] - The name of the string to look for (or the string itself).
- GLOBAL_TAG_TYPES:... - All the parameters to pass to the string.
- Return:
- -
- Notes:
- Main entry point for showing any sort of code to anyone.
-
- TODO: Change the code to push the parameters to Format_Render only once and
- reuse the resulting stack.
- \*----------------------------------------------------------------------------*/
- stock _Text_Send(@PlayerSet:players, search[], ident[], GLOBAL_TAG_TYPES:...)
- {
- setproperty(8, YSIM_TXTLEN, 1023);
- new
- bool:wasOnce[YSI_MAX_LANGUAGES] = {false, ...},
- n = (numargs() - 3) * 4,
- maxlen,
- owned = Text_IsLocalOwner(search, ident, maxlen);
- // Loop through all the players passed to the function (however they were
- // passed to the function). This uses "@PlayerArray" instead of
- // "@PlayerVar" so that we can optimised for multiple languages. Now it
- // uses "@PlayerSet" instead because that's the new one designed for
- // situations like this in which we want direct access to the variable.
- if (n)
- {
- new
- arg_start,
- arg_end;
- // Load the real address of the last static parameter. Do this by
- // loading the address of the parameter and then adding the value of
- // [FRM] (frame pointer).
- #emit CONST.alt ident
- #emit LCTRL 5
- #emit ADD
- #emit STOR.S.pri arg_start
- // Load the address of the last variable parameter. Do this by adding
- // the number of variables on the value just loaded.
- #emit LOAD.S.alt n
- #emit ADD
- #emit STOR.S.pri arg_end
- // Push the variable arguments. This is done by loading the value of
- // each one in reverse order and pushing them. I'd love to be able to
- // rewrite this to use the values of pri and alt for comparison, instead
- // of having or constantly reload two variables.
- foreach (new playerid : PS(players))
- //new playerid = 0;
- {
- new
- Language:lang = Langs_GetPlayerLanguage(playerid);
- if (lang == NO_LANGUAGE)
- {
- lang = Language:0;
- }
- if (wasOnce[lang])
- {
- // Optimisation for sending messages to multiple players.
- Format_JustShow(playerid, YSI_g_sLangBuffer[lang]);
- continue;
- }
- new
- arg_cur = arg_end,
- ret;
- do
- {
- #emit LOAD.S.pri arg_cur
- #emit LOAD.I
- #emit PUSH.pri
- arg_cur -= 4;
- }
- while (arg_cur > arg_start);
- switch (search[0])
- {
- case '\1':
- {
- // Null - error.
- P:E("Text_Send called with NULL");
- }
- case '\2':
- {
- // None - just print the string directly.
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, ident, n / 4);
- }
- case '\3':
- {
- if (owned == -1)
- {
- new
- pos = strfind(ident, ">"),
- br = strfind(ident, "[");
- if (pos > 1 && br != -1)
- {
- ident[pos - 2] = '\0';
- if (br)
- {
- ident[br] = ':';
- Text_GetText(ident, ident[pos + 1], lang);
- }
- else
- {
- Text_GetText(ident[1], ident[pos + 1], lang);
- }
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, YSI_g_sReturnText, n / 4);
- }
- else
- {
- // Var - May contain location search information in
- // "name". Maybe add an "all" search parameter...
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, "Could not find text source", n / 4);
- // The code generated messes up the pushing.
- }
- }
- else
- {
- ret = YSI_g_sTextEntries[owned][e_TEXT_ENTRY_POINTERS][lang];
- if (ret == -1)
- {
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, "Language text not found", n / 4);
- }
- else
- {
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, YSI_g_sTextStrings[ret], n / 4);
- }
- }
- }
- default:
- {
- if (owned == -1)
- {
- Text_GetText(search, ident, lang);
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, YSI_g_sReturnText, n / 4);
- }
- else
- {
- ret = YSI_g_sTextEntries[owned][e_TEXT_ENTRY_POINTERS][lang];
- if (ret == -1)
- {
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, "Language text not found", n / 4);
- }
- else
- {
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, YSI_g_sTextStrings[ret], n / 4);
- }
- }
- }
- }
- #emit LCTRL 4
- #emit LOAD.S.alt n
- #emit ADD
- #emit SCTRL 4
- wasOnce[lang] = !ret;
- }
- }
- else
- {
- foreach (new playerid : PS(players))
- {
- new
- Language:lang = Langs_GetPlayerLanguage(playerid);
- if (wasOnce[lang])
- {
- // Optimisation for sending messages to multiple players.
- Format_JustShow(playerid, YSI_g_sLangBuffer[lang]);
- continue;
- }
- switch (search[0])
- {
- case '\1':
- {
- // Null - error.
- P:E("Text_Send called with NULL");
- }
- case '\2':
- {
- // None - just print the string directly.
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, ident, 0);
- }
- case '\3':
- {
- new
- pos = strfind(ident, ">"),
- br = strfind(ident, "[");
- if (pos > 1 && br != -1)
- {
- ident[pos - 2] = '\0';
- if (br)
- {
- ident[br] = ':';
- Text_GetText(ident, ident[pos + 1], lang);
- }
- else
- {
- Text_GetText(ident[1], ident[pos + 1], lang);
- }
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, YSI_g_sReturnText, 0);
- }
- else
- {
- // Var - May contain location search information in
- // "name". Maybe add an "all" search parameter...
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, "Could not find text source", 0);
- }
- }
- default:
- {
- if (owned == -1)
- {
- Text_GetText(search, ident, lang);
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], getproperty(8, YSIM_TXTLEN) - 1, 0, 0, YSI_g_sReturnText, 0);
- }
- else
- {
- new
- ret = YSI_g_sTextEntries[owned][e_TEXT_ENTRY_POINTERS][lang];
- if (ret == -1)
- {
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, "Language text not found", 0);
- }
- else
- {
- wasOnce[lang] = !Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], maxlen, 0, 0, YSI_g_sTextStrings[ret], 0);
- }
- }
- }
- }
- }
- }
- return Text_GetLastID();
- }
- static stock
- YSI_g_sCaptionText[YSI_MAX_LANGUAGES][64],
- YSI_g_sButton1Text[YSI_MAX_LANGUAGES][16],
- YSI_g_sButton2Text[YSI_MAX_LANGUAGES][16];
- /*----------------------------------------------------------------------------*\
- Function:
- -
- Params:
- -
- Return:
- -
- Notes:
- -
- \*----------------------------------------------------------------------------*/
- //stock @PlayerArray:players<MAX_PLAYERS>, callback[], csearch[], cident[], isearch[], iident[], b1search[], b1ident[], b2search[], b2ident[], GLOBAL_TAG_TYPES:...)
- //stock _Text_MessageBox(@PlayerArray:players<MAX_PLAYERS>, callback[], csearch[], cident[], isearch[], iident[], b1search[], b1ident[], b2search[], b2ident[], GLOBAL_TAG_TYPES:...)
- //stock _Text_MessageBox(@PlayerArray:players<MAX_PLAYERS>, callback[], csearch[], cident[], isearch[], iident[], b1search[], b1ident[], b2search[], b2ident[], GLOBAL_TAG_TYPES:...)
- stock _Text_DialogBox(@PlayerSet:players, style, callback:callback, csearch[], cident[], isearch[], iident[], b1search[], b1ident[], b2search[], b2ident[], GLOBAL_TAG_TYPES:...)
- //stock _Text_MessageBox(__ps_addr_t:__ps_addr, callback[], csearch[], cident[], isearch[], iident[], b1search[], b1ident[], b2search[], b2ident[], GLOBAL_TAG_TYPES:...)
- {
- // This is what the "@PlayerArray" macro expands to, but I needed more
- // control to allow me to return a value. The fact that I can't ATM is a
- // serious problem, but not serious enough to warrant fixing.
- new
- bool:wasOnce[YSI_MAX_LANGUAGES] = {false, ...},
- bool:gotExtras[YSI_MAX_LANGUAGES] = {false, ...},
- n = (numargs() - 10) * 4,
- dialog = Dialog_ObtainID(),
- maxlen,
- owned = Text_IsLocalOwner(isearch, iident, maxlen);
- // Loop through all the players passed to the function (however they were
- // passed to the function). This uses "@PlayerArray" instead of
- // "@PlayerVar" so that we can optimised for multiple languages.
- if (n)
- {
- new
- arg_start,
- arg_end;
- // Load the real address of the last static parameter. Do this by
- // loading the address of the parameter and then adding the value of
- // [FRM] (frame pointer).
- #emit CONST.alt b2ident
- #emit LCTRL 5
- #emit ADD
- #emit STOR.S.pri arg_start
- // Load the address of the last variable parameter. Do this by adding
- // the number of variables on the value just loaded.
- #emit LOAD.S.alt n
- #emit ADD
- #emit STOR.S.pri arg_end
- // Push the variable arguments. This is done by loading the value of
- // each one in reverse order and pushing them. I'd love to be able to
- // rewrite this to use the values of pri and alt for comparison, instead
- // of having or constantly reload two variables.
- //for (new PlayerArray:players<MAX_PLAYERS>; __PS_A(_:__ps_addr, players); )
- foreach (new playerid : PS(players))
- {
- new
- Language:lang = Langs_GetPlayerLanguage(playerid);
- if (lang == NO_LANGUAGE)
- {
- lang = Language:0;
- }
- // Only ever do this part once per language.
- if (!gotExtras[lang])
- {
- // Get the text for the caption in this language.
- switch (csearch[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sCaptionText[lang], cident, sizeof (YSI_g_sCaptionText[]));
- case '\3':
- {
- new pos = strfind(cident, ">"), br = strfind(cident, "[");
- if (pos > 1 && br != -1)
- {
- cident[pos - 2] = '\0';
- if (br) cident[br] = ':', Text_GetText(cident, cident[pos + 1], lang);
- else Text_GetText(cident[1], cident[pos + 1], lang);
- strcpy(YSI_g_sCaptionText[lang], YSI_g_sReturnText, sizeof (YSI_g_sCaptionText[]));
- }
- else YSI_g_sCaptionText[lang] = "Could not find title source";
- }
- default: Text_GetText(csearch, cident, lang), strcpy(YSI_g_sCaptionText[lang], YSI_g_sReturnText, sizeof (YSI_g_sCaptionText[]));
- }
- // Get the text for button 1 in this language.
- switch (b1search[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sButton1Text[lang], b1ident, sizeof (YSI_g_sButton1Text[]));
- case '\3':
- {
- new pos = strfind(b1ident, ">"), br = strfind(b1ident, "[");
- if (pos > 1 && br != -1)
- {
- b1ident[pos - 2] = '\0';
- if (br) b1ident[br] = ':', Text_GetText(b1ident, b1ident[pos + 1], lang);
- else Text_GetText(b1ident[1], b1ident[pos + 1], lang);
- strcpy(YSI_g_sButton1Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton1Text[]));
- }
- else YSI_g_sButton1Text[lang] = "Not Found";
- }
- default: Text_GetText(b1search, b1ident, lang), strcpy(YSI_g_sButton1Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton1Text[]));
- }
- // Get the text for button 1 in this language.
- if (b2ident[0])
- {
- switch (b2search[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sButton2Text[lang], b2ident, sizeof (YSI_g_sButton2Text[]));
- case '\3':
- {
- new pos = strfind(b2ident, ">"), br = strfind(b2ident, "[");
- if (pos > 1 && br != -1)
- {
- b2ident[pos - 2] = '\0';
- if (br) b2ident[br] = ':', Text_GetText(b2ident, b2ident[pos + 1], lang);
- else Text_GetText(b2ident[1], b2ident[pos + 1], lang);
- strcpy(YSI_g_sButton2Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton2Text[]));
- }
- else YSI_g_sButton2Text[lang] = "";
- }
- default: Text_GetText(b2search, b2ident, lang), strcpy(YSI_g_sButton2Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton2Text[]));
- }
- }
- else YSI_g_sButton2Text[lang] = "";
- gotExtras[lang] = true;
- }
- if (!wasOnce[lang])
- {
- // Optimisation for sending messages to multiple players.
- //Format_DoDisplay(playerid, 0xFF0000AA, YSI_g_sLangBuffer[lang]);
- //continue;
- new
- arg_cur = arg_end,
- ret;
- do
- {
- #emit LOAD.S.pri arg_cur
- #emit LOAD.I
- #emit PUSH.pri
- arg_cur -= 4;
- }
- while (arg_cur > arg_start);
- switch (isearch[0])
- {
- case '\1':
- {
- // Null - error.
- P:E("Text_Send called with NULL");
- }
- case '\2':
- {
- // None - just print the string directly.
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, iident, n / 4);
- }
- case '\3':
- {
- new
- pos = strfind(iident, ">"),
- br = strfind(iident, "[");
- if (pos > 1 && br != -1)
- {
- iident[pos - 2] = '\0';
- if (br)
- {
- iident[br] = ':';
- Text_GetText(iident, iident[pos + 1], lang);
- }
- else
- {
- Text_GetText(iident[1], iident[pos + 1], lang);
- }
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, YSI_g_sReturnText, n / 4);
- }
- else
- {
- // Var - May contain location isearch information in
- // "name". Maybe add an "all" isearch parameter...
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, "Could not find text source", n / 4);
- // The code generated messes up the pushing.
- }
- }
- default:
- {
- Text_GetText(isearch, iident, lang);
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, YSI_g_sReturnText, n / 4);
- }
- }
- #emit LCTRL 4
- #emit LOAD.S.alt n
- #emit ADD
- #emit SCTRL 4
- wasOnce[lang] = !ret;
- }
- // Display the message.
- Dialog_Show(playerid, style, YSI_g_sCaptionText[lang], YSI_g_sLangBuffer[lang], YSI_g_sButton1Text[lang], YSI_g_sButton2Text[lang], dialog);
- }
- }
- else
- {
- // Push the variable arguments. This is done by loading the value of
- // each one in reverse order and pushing them. I'd love to be able to
- // rewrite this to use the values of pri and alt for comparison, instead
- // of having or constantly reload two variables.
- foreach (new playerid : PS(players))
- //for (new PlayerArray:players<MAX_PLAYERS>; __PS_A(_:__ps_addr, players); )
- {
- new
- Language:lang = Langs_GetPlayerLanguage(playerid);
- if (lang == NO_LANGUAGE)
- {
- lang = Language:0;
- }
- // Only ever do this part once per language.
- if (!gotExtras[lang])
- {
- // Get the text for the caption in this language.
- switch (csearch[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sCaptionText[lang], cident, sizeof (YSI_g_sCaptionText[]));
- case '\3':
- {
- new pos = strfind(cident, ">"), br = strfind(cident, "[");
- if (pos > 1 && br != -1)
- {
- cident[pos - 2] = '\0';
- if (br) cident[br] = ':', Text_GetText(cident, cident[pos + 1], lang);
- else Text_GetText(cident[1], cident[pos + 1], lang);
- strcpy(YSI_g_sCaptionText[lang], YSI_g_sReturnText, sizeof (YSI_g_sCaptionText[]));
- }
- else YSI_g_sCaptionText[lang] = "Could not find title source";
- }
- default: Text_GetText(csearch, cident, lang), strcpy(YSI_g_sCaptionText[lang], YSI_g_sReturnText, sizeof (YSI_g_sCaptionText[]));
- }
- // Get the text for button 1 in this language.
- switch (b1search[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sButton1Text[lang], b1ident, sizeof (YSI_g_sButton1Text[]));
- case '\3':
- {
- new pos = strfind(b1ident, ">"), br = strfind(b1ident, "[");
- if (pos > 1 && br != -1)
- {
- b1ident[pos - 2] = '\0';
- if (br) b1ident[br] = ':', Text_GetText(b1ident, b1ident[pos + 1], lang);
- else Text_GetText(b1ident[1], b1ident[pos + 1], lang);
- strcpy(YSI_g_sButton1Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton1Text[]));
- }
- else YSI_g_sButton1Text[lang] = "Not Found";
- }
- default: Text_GetText(b1search, b1ident, lang), strcpy(YSI_g_sButton1Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton1Text[]));
- }
- // Get the text for button 1 in this language.
- if (b2ident[0])
- {
- switch (b2search[0])
- {
- case '\1': P:E("Text_Send called with NULL");
- case '\2': strcpy(YSI_g_sButton2Text[lang], b2ident, sizeof (YSI_g_sButton2Text[]));
- case '\3':
- {
- new pos = strfind(b2ident, ">"), br = strfind(b2ident, "[");
- if (pos > 1 && br != -1)
- {
- b2ident[pos - 2] = '\0';
- if (br) b2ident[br] = ':', Text_GetText(b2ident, b2ident[pos + 1], lang);
- else Text_GetText(b2ident[1], b2ident[pos + 1], lang);
- strcpy(YSI_g_sButton2Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton2Text[]));
- }
- else YSI_g_sButton2Text[lang] = "";
- }
- default: Text_GetText(b2search, b2ident, lang), strcpy(YSI_g_sButton2Text[lang], YSI_g_sReturnText, sizeof (YSI_g_sButton2Text[]));
- }
- }
- else YSI_g_sButton2Text[lang] = "";
- gotExtras[lang] = true;
- }
- if (!wasOnce[lang])
- {
- new
- ret;
- switch (isearch[0])
- {
- case '\1':
- {
- // Null - error.
- P:E("Text_Send called with NULL");
- }
- case '\2':
- {
- // None - just print the string directly.
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, iident, n / 4);
- }
- case '\3':
- {
- new
- pos = strfind(iident, ">"),
- br = strfind(iident, "[");
- if (pos > 1 && br != -1)
- {
- iident[pos - 2] = '\0';
- if (br)
- {
- iident[br] = ':';
- Text_GetText(iident, iident[pos + 1], lang);
- }
- else
- {
- Text_GetText(iident[1], iident[pos + 1], lang);
- }
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, YSI_g_sReturnText, n / 4);
- }
- else
- {
- // Var - May contain location isearch information in
- // "name". Maybe add an "all" isearch parameter...
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, "Could not find text source", n / 4);
- // The code generated messes up the pushing.
- }
- }
- default:
- {
- Text_GetText(isearch, iident, lang);
- _Text_SetDialogMode();
- ret = Format_Render(playerid, lang, YSI_g_sLangBuffer[lang], sizeof (YSI_g_sLangBuffer[]) - 1, 0, e_FORMAT_FLAGS_NONE, YSI_g_sReturnText, n / 4);
- }
- }
- wasOnce[lang] = !ret;
- }
- // Display the message.
- Dialog_Show(playerid, style, YSI_g_sCaptionText[lang], YSI_g_sLangBuffer[lang], YSI_g_sButton1Text[lang], YSI_g_sButton2Text[lang], dialog);
- }
- }
- // Sort out the callbacks etc for the dialog return.
- new
- cd[E_CALLBACK_DATA];
- Callback_Get(callback, cd, _F<iiiis>);
- Dialog_SetCallbackData(dialog, cd); //AMX_GetPublicPointer(callback));
- return dialog;
- }
|