Guest User

ShowFormattedDialog

a guest
Apr 6th, 2013
613
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //==============================================================================
  2. //              ShowFormattedDialog
  3. //                  by Daniel_Cortez
  4. //              www.pro-pawn.ru
  5. //==============================================================================
  6.  
  7. #if !defined    BYTES_PER_CELL
  8.     #define BYTES_PER_CELL  cellbits/8
  9. #else
  10.     #define BYTES_PER_CELL_WAS_DEFINED
  11. #endif
  12.  
  13. forward public ____ShowFmtDialog_fix__();
  14. public ____ShowFmtDialog_fix__()
  15. {
  16.     #emit retn
  17.     new s[1];
  18.     format(s, 0, "");
  19.     ShowPlayerDialog(0, 0, 0, "", "", "", "");
  20. }
  21.  
  22.  
  23. stock ShowFmgDialog(playerid, style, dialogid, caption[], button1[], button2[], fmtinfo[], {Float, _}:...)
  24. {
  25.     #define STATIC_ARGS 7
  26.     if(IsPlayerConnected(playerid) == 0)
  27.         return 1;
  28.     new count = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
  29.     if(count == 0)
  30.         return ShowPlayerDialog(playerid, style, dialogid, caption, fmtinfo, button1, button2);
  31.     new fmt_str[512], arg_start, arg_end;
  32.     // получить адрес начала динамических аргументов
  33.     #emit const.alt     fmtinfo
  34.     #emit lctrl         5
  35.     #emit add
  36.     #emit stor.s.pri    arg_start
  37.     // получить адрес конца динамических аргументов
  38.     #emit load.s.alt    count
  39.     #emit add
  40.     #emit stor.s.pri    arg_end
  41.     // выбран цикл do-while, т.к. он не генерирует
  42.     // лишних инструкций, приводящих к коллизии стека
  43.     do{// помещение динамических аргументов в стек
  44.         #emit load.i    // в pri - адрес текущего аргумента в стеке
  45.         #emit push.pri
  46.         arg_end -= BYTES_PER_CELL;
  47.         #emit load.s.pri    arg_end
  48.     }while (arg_end > arg_start);
  49.     // помещение в стек статических аргументов
  50.     #emit   push.s      fmtinfo
  51.     #emit   push.c      512
  52.     #emit   push.adr    fmt_str
  53.     // вызов format()
  54.     count += BYTES_PER_CELL*3;
  55.     #emit   push.s      count
  56.     #emit   sysreq.c    format
  57.     // восстановление стека
  58.     count += BYTES_PER_CELL;
  59.     #emit   lctrl       4
  60.     #emit   load.s.alt  count
  61.     #emit   add
  62.     #emit   sctrl       4
  63.     // ну тут и так всё понятно xD
  64.     return ShowPlayerDialog(playerid, style, dialogid, caption, fmt_str, button1, button2);
  65.     #undef  STATIC_ARGS
  66. }
  67.  
  68. stock ShowFmgDialogToAll(style, dialogid, caption[], button1[], button2[], fmtinfo[], {Float, _}:...)
  69. {
  70.     #define STATIC_ARGS 6
  71.     new count = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
  72.     new i = GetMaxPlayers();
  73.     if(count == 0)
  74.     {
  75.         /*do{
  76.             ShowPlayerDialog(--i, style, dialogid, caption, fmtinfo, button1, button2);
  77.         }while(i != 0);*/
  78.         #emit   push.s      button2
  79.         #emit   push.s      button1
  80.         #emit   push.s      fmtinfo
  81.         #emit   push.s      caption
  82.         #emit   push.s      dialogid
  83.         #emit   push.s      style
  84.         do{
  85.             if(IsPlayerConnected(--i)==0) continue;
  86.             #emit   push.s      i
  87.             #emit   push.c      28
  88.             #emit   sysreq.c    ShowPlayerDialog
  89.             #emit   stack       8
  90.         }while(i != 0);
  91.         #emit   stack       24
  92.         return 1;
  93.     }
  94.     new fmt_str[512], arg_start, arg_end;
  95.     #emit const.alt     fmtinfo
  96.     #emit lctrl         5
  97.     #emit add
  98.     #emit stor.s.pri    arg_start
  99.     #emit load.s.alt    count
  100.     #emit add
  101.     #emit stor.s.pri    arg_end
  102.     do{
  103.         #emit load.i
  104.         #emit push.pri
  105.         arg_end -= BYTES_PER_CELL;
  106.         #emit load.s.pri    arg_end
  107.     }while (arg_end > arg_start);
  108.     #emit   push.s      fmtinfo
  109.     #emit   push.c      512
  110.     #emit   push.adr    fmt_str
  111.     count += BYTES_PER_CELL*3;
  112.     #emit   push.s      count
  113.     #emit   sysreq.c    format
  114.     count += BYTES_PER_CELL;
  115.     #emit   lctrl       4
  116.     #emit   load.s.alt  count
  117.     #emit   add
  118.     #emit   sctrl       4
  119.     /*do{
  120.         ShowPlayerDialog(--i, style, dialogid, caption, fmt_str, button1, button2);
  121.     }while(i != 0);*/
  122.     #emit   push.s      button2
  123.     #emit   push.s      button1
  124.     #emit   push.adr    fmt_str
  125.     #emit   push.s      caption
  126.     #emit   push.s      dialogid
  127.     #emit   push.s      style
  128.     do{
  129.         if(IsPlayerConnected(--i)==0) continue;
  130.         #emit   push.s      i
  131.         #emit   push.c      28
  132.         #emit   sysreq.c    ShowPlayerDialog
  133.         #emit   stack       8
  134.     }while(i != 0);
  135.     #emit   stack       24
  136.     return 1;
  137.     #undef  STATIC_ARGS
  138. }
  139.  
  140. #if !defined    BYTES_PER_CELL_WAS_DEFINED
  141.     #undef  BYTES_PER_CELL
  142. #else
  143.     #undef  BYTES_PER_CELL_WAS_DEFINED
  144. #endif
  145. // зато константа BYTES_PER_CELL рассчитана наперёд =/
RAW Paste Data