Advertisement
Y_Less

y_va.inc

May 2nd, 2011
1,259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 5.67 KB | None | 0 0
  1. /*----------------------------------------------------------------------------*\
  2.                     ==============================
  3.                      y_va - Enhanced vararg code!
  4.                     ==============================
  5. Description:
  6.     This library currently provides two functions - va_printf and va_format
  7.     which perform printf and format using variable arguments passed to another
  8.     function.
  9.    
  10.     This is bsed on the variable parameter passing method based on code by Zeex.
  11.     See page 15 of the code optimisations topic.
  12. Legal:
  13.     Version: MPL 1.1
  14.    
  15.     The contents of this file are subject to the Mozilla Public License Version
  16.     1.1 (the "License"); you may not use this file except in compliance with
  17.     the License. You may obtain a copy of the License at
  18.     http://www.mozilla.org/MPL/
  19.    
  20.     Software distributed under the License is distributed on an "AS IS" basis,
  21.     WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  22.     for the specific language governing rights and limitations under the
  23.     License.
  24.    
  25.     The Original Code is the YSI vararg include.
  26.    
  27.     The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  28.     Portions created by the Initial Developer are Copyright (C) 2011
  29.     the Initial Developer. All Rights Reserved.
  30.    
  31.     Contributors:
  32.         ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
  33.    
  34.     Thanks:
  35.         JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  36.         ZeeX - Very productive conversations.
  37.         koolk - IsPlayerinAreaEx code.
  38.         TheAlpha - Danish translation.
  39.         breadfish - German translation.
  40.         Fireburn - Dutch translation.
  41.         yom - French translation.
  42.         50p - Polish translation.
  43.         Zamaroht - Spanish translation.
  44.         Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  45.             for me to strive to better.
  46.         Pixels^ - Running XScripters where the idea was born.
  47.         Matite - Pestering me to release it and using it.
  48.    
  49.     Very special thanks to:
  50.         Thiadmer - PAWN, whose limits continue to amaze me!
  51.         Kye/Kalcor - SA:MP.
  52.         SA:MP Team past, present and future - SA:MP.
  53.    
  54. Version:
  55.     1.0
  56. Changelog:
  57.     02/05/11:
  58.         First version.
  59. Functions:
  60.     Public:
  61.         -
  62.     Core:
  63.         -
  64.     Stock:
  65.         -
  66.     Static:
  67.         -
  68.     Inline:
  69.         -
  70.     API:
  71.         -
  72. Callbacks:
  73.     -
  74. Definitions:
  75.     -
  76. Enums:
  77.     -
  78. Macros:
  79.     -
  80. Tags:
  81.     -
  82. Variables:
  83.     Global:
  84.         -
  85.     Static:
  86.         -
  87. Commands:
  88.     -
  89. Compile options:
  90.     -
  91. Operators:
  92.     -
  93. \*----------------------------------------------------------------------------*/
  94.  
  95. #include <YSI\internal\y_version>
  96. #include <YSI\internal\y_funcinc>
  97.  
  98. //#define va_args<%0> %0
  99. #define va_args<%0> {Float,File,Bit,PlayerText3D,Text,Text3D,Menu,DB,DBResult,Style,XML,Bintree,Group,_}:...
  100. #define va_start<%0> (va_:(%0))
  101.  
  102. stock va_printf(fmat[], va_:STATIC_ARGS)
  103. {
  104.     new
  105.         num_args,
  106.         arg_start,
  107.         arg_end;
  108.     // Get the pointer to the number of arguments to the last function.
  109.     #emit LOAD.S.pri   0
  110.     #emit ADD.C        8
  111.     #emit MOVE.alt
  112.     // Get the number of arguments.
  113.     #emit LOAD.I
  114.     #emit STOR.S.pri   num_args
  115.     // Get the variable arguments (end).
  116.     #emit ADD
  117.     #emit STOR.S.pri   arg_end
  118.     // Get the variable arguments (start).
  119.     #emit LOAD.S.pri   STATIC_ARGS
  120.     #emit SMUL.C       4
  121.     #emit ADD
  122.     #emit STOR.S.pri   arg_start
  123.     // Using an assembly loop here screwed the code up as the labels added some
  124.     // odd stack/frame manipulation code...
  125.     while (arg_end != arg_start)
  126.     {
  127.         #emit MOVE.pri
  128.         #emit LOAD.I
  129.         #emit PUSH.pri
  130.         #emit CONST.pri    4
  131.         #emit SUB.alt
  132.         #emit STOR.S.pri   arg_end
  133.     }
  134.     // Push the additional parameters.
  135.     #emit PUSH.S       fmat
  136.     // Push the argument count.
  137.     #emit LOAD.S.pri   num_args
  138.     #emit ADD.C        4
  139.     #emit LOAD.S.alt   STATIC_ARGS
  140.     #emit XCHG
  141.     #emit SMUL.C       4
  142.     #emit SUB.alt
  143.     #emit PUSH.pri
  144.     #emit MOVE.alt
  145.     // This gets confused if you have a local variable of the same name as it
  146.     // seems to factor in them first, so you get the offset of the local
  147.     // variable instead of the index of the native.
  148.     #emit SYSREQ.C     printf
  149.     // Clear the stack.
  150.     #emit CONST.pri    4
  151.     #emit ADD
  152.     #emit MOVE.alt
  153.     // The three lines above get the total stack data size, now remove it.
  154.     #emit LCTRL        4
  155.     #emit ADD
  156.     #emit SCTRL        4
  157.     // Now do the real return.
  158. }
  159.  
  160. stock va_format(out[], size, fmat[], va_:STATIC_ARGS)
  161. {
  162.     new
  163.         num_args,
  164.         arg_start,
  165.         arg_end;
  166.     // Get the pointer to the number of arguments to the last function.
  167.     #emit LOAD.S.pri   0
  168.     #emit ADD.C        8
  169.     #emit MOVE.alt
  170.     // Get the number of arguments.
  171.     #emit LOAD.I
  172.     #emit STOR.S.pri   num_args
  173.     // Get the variable arguments (end).
  174.     #emit ADD
  175.     #emit STOR.S.pri   arg_end
  176.     // Get the variable arguments (start).
  177.     #emit LOAD.S.pri   STATIC_ARGS
  178.     #emit SMUL.C       4
  179.     #emit ADD
  180.     #emit STOR.S.pri   arg_start
  181.     // Using an assembly loop here screwed the code up as the labels added some
  182.     // odd stack/frame manipulation code...
  183.     while (arg_end != arg_start)
  184.     {
  185.         #emit MOVE.pri
  186.         #emit LOAD.I
  187.         #emit PUSH.pri
  188.         #emit CONST.pri    4
  189.         #emit SUB.alt
  190.         #emit STOR.S.pri   arg_end
  191.     }
  192.     // Push the additional parameters.
  193.     #emit PUSH.S       fmat
  194.     #emit PUSH.S       size
  195.     #emit PUSH.S       out
  196.     // Push the argument count.
  197.     #emit LOAD.S.pri   num_args
  198.     #emit ADD.C        12
  199.     #emit LOAD.S.alt   STATIC_ARGS
  200.     #emit XCHG
  201.     #emit SMUL.C       4
  202.     #emit SUB.alt
  203.     #emit PUSH.pri
  204.     #emit MOVE.alt
  205.     // This gets confused if you have a local variable of the same name as it
  206.     // seems to factor in them first, so you get the offset of the local
  207.     // variable instead of the index of the native.
  208.     #emit SYSREQ.C     format
  209.     // Clear the stack.
  210.     #emit CONST.pri    4
  211.     #emit ADD
  212.     #emit MOVE.alt
  213.     // The three lines above get the total stack data size, now remove it.
  214.     #emit LCTRL        4
  215.     #emit ADD
  216.     #emit SCTRL        4
  217.     // Now do the real return.
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement