Advertisement
MagNeteC

TimerFix

May 26th, 2013
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 8.10 KB | None | 0 0
  1. // TimerFix v2 beta by Slice
  2. //Türkçeleştirme ve Timer bugu düzeltme MagNeteC
  3. //http://www.gtaturk.com/forum/profile/?u=1014704
  4.  
  5. #if !defined _samp_included
  6.     #error Lutfen a_samp includesini Timer Fix includesinden once koyun.
  7. #endif
  8.  
  9. #if !defined TIMER_FIX_TICK_INTERVAL
  10.     #define TIMER_FIX_TICK_INTERVAL  5
  11. #endif
  12.  
  13. #if !defined TIMER_FIX_TIMER_SLOTS
  14.     #define TIMER_FIX_TIMER_SLOTS  128
  15. #endif
  16.  
  17. #if !defined TIMER_FIX_MAX_ARGUMENTS
  18.     #define TIMER_FIX_MAX_ARGUMENTS  32
  19. #endif
  20.  
  21. #if !defined TIMER_FIX_PERFORMANCE_CHECKS
  22.     #define TIMER_FIX_PERFORMANCE_CHECKS  true
  23. #endif
  24.  
  25. #if !defined TIMER_FIX_DEBUG
  26.     #define TIMER_FIX_DEBUG  false
  27. #endif
  28.  
  29. #define TF::  TF_
  30.  
  31. enum TF::e_TIMER {
  32.     bool:e_bIsUsed,
  33.          e_iNumArguments,
  34.          e_axArguments[TIMER_FIX_MAX_ARGUMENTS],
  35. #if TIMER_FIX_DEBUG
  36.          e_aiArgumentTypes[TIMER_FIX_MAX_ARGUMENTS],
  37. #endif
  38.          e_iFunctionAddress,
  39.          e_szFunctionName[32],
  40.          e_iInterval,
  41.          e_iNextCall,
  42.     bool:e_bIsRepeating
  43. };
  44.  
  45. static
  46. #if TIMER_FIX_DEBUG
  47.     TF::gs_szDebugBuffer[512],
  48. #endif
  49.     TF::gs_Timers[TIMER_FIX_TIMER_SLOTS][TF::e_TIMER],
  50.     TF::gs_iCurrentTimer = -1
  51. ;
  52. static
  53.     bool:s_bTimerTickTimerStarted = false
  54. ;
  55. // Fix for y_timers
  56. #define _Timer_C(O@  _Timer_C(SetTimerEx
  57.  
  58. stock SetTimerHook(const szFunctionName[], iInterval, {bool, _}:bRepeating, const szFormat[] = !"", {_, PlayerText3D, Text, Text3D, Menu, DB, DBResult, File, Float}:...) {
  59.    
  60.     if (!s_bTimerTickTimerStarted) {
  61.         SetTimer(!"TF_TimerTick", TIMER_FIX_TICK_INTERVAL, true);
  62.        
  63.         s_bTimerTickTimerStarted = true;
  64.     }
  65.    
  66.     new
  67.         iSlot = -1
  68.     ;
  69.    
  70.     for (new i = 0; i < sizeof(TF::gs_Timers); i++) {
  71.         if (!TF::gs_Timers[i][e_bIsUsed]) {
  72.             iSlot = i;
  73.            
  74.             break;
  75.         }
  76.     }
  77.    
  78.     if (iSlot == -1) {
  79.         print(!"(TimerFix) Hata: Hic timer slotu kalmadi. Slot sayisi icin TIMER_FIX_TIMER_SLOTS bakin. (Suanki slot: " #TIMER_FIX_TIMER_SLOTS ").");
  80.        
  81.         return -1;
  82.     }
  83.    
  84.     if (!(TF::gs_Timers[iSlot][e_iFunctionAddress] = TF::GetPublicFunctionAddress(szFunctionName))) {
  85.         new
  86.             szFunctionNameUnpacked[32]
  87.         ;
  88.        
  89.         strunpack(szFunctionNameUnpacked, szFunctionName);
  90.        
  91.         printf("(TimerFix) Hata: (\"%s\") Boyle bir fonksiyon yok.", szFunctionNameUnpacked);
  92.        
  93.         return -1;
  94.     }
  95.    
  96.     new
  97.         #if TIMER_FIX_DEBUG
  98.             bool:bFormatIsPacked = ispacked(szFormat),
  99.         #endif
  100.                  iNumArgs = max(0, numargs() - 4)
  101.     ;
  102.    
  103.     if (iNumArgs != strlen(szFormat)) {
  104.         new
  105.             szFormatUnpacked[128 char]
  106.         ;
  107.        
  108.         strunpack(szFormatUnpacked, szFormat);
  109.        
  110.         printf("(TimerFix) Hata: Parametre sayısı (%d) biçim belirten arguman (\"%s\") ile eslesmiyor.", iNumArgs, szFormatUnpacked);
  111.        
  112.         return -1;
  113.     }
  114.    
  115.     TF::gs_Timers[iSlot][e_bIsUsed]       = true;
  116.     TF::gs_Timers[iSlot][e_bIsRepeating]  = bRepeating;
  117.     TF::gs_Timers[iSlot][e_iInterval]     = iInterval;
  118.     TF::gs_Timers[iSlot][e_iNextCall]     = GetTickCount() + iInterval;
  119.     TF::gs_Timers[iSlot][e_iNumArguments] = iNumArgs;
  120.    
  121.     strunpack(TF::gs_Timers[iSlot][e_szFunctionName], szFunctionName, 32);
  122.    
  123.     for (new i = 0; i < iNumArgs; i++) {
  124.         TF::gs_Timers[iSlot][e_axArguments][i] = getarg(4 + i);
  125.        
  126.         #if TIMER_FIX_DEBUG
  127.             TF::gs_Timers[iSlot][e_aiArgumentTypes][i] = bFormatIsPacked ? szFormat{i} : szFormat[i];
  128.         #endif
  129.     }
  130.    
  131.     #if TIMER_FIX_DEBUG
  132.         printf("(TimerFix) DEBUG: Timer created; %d = \"%s\".", iSlot, TF::gs_Timers[iSlot][e_szFunctionName]);
  133.     #endif
  134.    
  135.     return iSlot;
  136. }
  137.  
  138. stock KillTimerHook(iTimer) {
  139.     if (0 <= iTimer < sizeof(TF::gs_Timers)) {
  140.         if (TF::gs_Timers[iTimer][e_bIsUsed]) {
  141.             TF::gs_Timers[iTimer][e_bIsUsed] = false;
  142.            
  143.             #if TIMER_FIX_DEBUG
  144.                 printf("(TimerFix) DEBUG: Timer durduruldu: %d (\"%s\").", iTimer, TF::gs_Timers[iTimer][e_szFunctionName]);
  145.             #endif
  146.            
  147.             return true;
  148.         }
  149.     }
  150.    
  151.     #if TIMER_FIX_DEBUG
  152.         printf("(TimerFix) DEBUG: %d id timer durdurulamadi; Gecersiz timer id.", iTimer);
  153.     #endif
  154.    
  155.     return false;
  156. }
  157.  
  158. #define SetTimer    SetTimerHook
  159. #define SetTimerEx  SetTimerHook
  160. #define KillTimer   KillTimerHook
  161.  
  162. stock KillThisTimer() {
  163.     if (TF::gs_iCurrentTimer != -1)
  164.         KillTimer(TF::gs_iCurrentTimer);
  165. }
  166.  
  167. forward TF::TimerTick();
  168. public TF::TimerTick() {
  169.     new
  170.         iTick,
  171.         iFunc,
  172.         iArg,
  173.         i, j
  174.     ;
  175.    
  176.     if (TF::gs_iCurrentTimer != -1) {
  177.         printf("(TimerFix) Hata: \"%s\" fonksiyonu duzgun calismadi, Bu timer cagirilir olmayabilir.", TF::gs_Timers[TF::gs_iCurrentTimer][e_szFunctionName]);
  178.        
  179.         TF::gs_iCurrentTimer = -1;
  180.     }
  181.    
  182.     for (i = 0; i < sizeof(TF::gs_Timers); i++) {
  183.         if (!TF::gs_Timers[i][e_bIsUsed])
  184.             continue;
  185.        
  186.         if ((iTick = GetTickCount()) >= TF::gs_Timers[i][e_iNextCall]) {
  187.             iFunc = TF::gs_Timers[i][e_iFunctionAddress];
  188.            
  189.             // This is done before and after execution, in case execution fails
  190.             if (TF::gs_Timers[i][e_bIsRepeating])
  191.                 TF::gs_Timers[i][e_iNextCall] = iTick + TF::gs_Timers[i][e_iInterval] - 1;
  192.            
  193.             #if TIMER_FIX_DEBUG
  194.                 TF::PrintFunctionCall(i);
  195.             #endif
  196.            
  197.             j = TF::gs_Timers[i][e_iNumArguments];
  198.            
  199.            
  200.             TF::gs_iCurrentTimer = i;
  201.            
  202.             // Push the arguments
  203.             while (--j >= 0) {
  204.                 #emit CONST.alt   TF_gs_Timers
  205.                 #emit LOAD.S.pri  i
  206.                 #emit IDXADDR
  207.                 #emit MOVE.alt
  208.                 #emit LOAD.I
  209.                 #emit ADD
  210.                 #emit ADD.C       8 // e_axArguments * 4
  211.                 #emit MOVE.alt
  212.                 #emit LOAD.S.pri  j
  213.                 #emit IDXADDR
  214.                 #emit LOAD.I
  215.                 #emit PUSH.pri
  216.             }
  217.            
  218.             // Push the number of arguments
  219.             iArg = TF::gs_Timers[i][e_iNumArguments] * 4;
  220.            
  221.             #emit PUSH.S      iArg
  222.  
  223.             // Push the return address
  224.             #emit LCTRL       6
  225.             #emit ADD.C       28
  226.             #emit PUSH.pri
  227.  
  228.             // Call the function
  229.             #emit LOAD.S.pri  iFunc
  230.             #emit SCTRL       6
  231.            
  232.             #if TIMER_FIX_PERFORMANCE_CHECKS
  233.                 if (GetTickCount() - iTick > 10) {
  234.                     printf("(TimerFix) Uyari: \"%s\" Bu fonksiyon %dms gec calisti! Bu diger timerlarida etkileyecek.", TF::gs_Timers[i][e_szFunctionName], GetTickCount() - iTick);
  235.                 }
  236.             #endif
  237.            
  238.             if (TF::gs_Timers[i][e_bIsRepeating])
  239.                 TF::gs_Timers[i][e_iNextCall] = GetTickCount() + TF::gs_Timers[i][e_iInterval] - 1;
  240.             else {
  241.                 TF::gs_Timers[i][e_bIsUsed] = false;
  242.                
  243.                 #if TIMER_FIX_DEBUG
  244.                     printf("(TimerFix) DEBUG: Timer %d (\"%s\") tamamlandi.", i, TF::gs_Timers[i][e_szFunctionName]);
  245.                 #endif
  246.             }
  247.            
  248.             TF::gs_iCurrentTimer = -1;
  249.         }
  250.     }
  251. }
  252.  
  253. stock TF::PrintFunctionCall(i) {
  254.     format(TF::gs_szDebugBuffer, sizeof(TF::gs_szDebugBuffer), "(TimerFix) DEBUG: Cagiriliyor: %s(", TF::gs_Timers[i][e_szFunctionName]);
  255.    
  256.     for (new j = 0; j < TF::gs_Timers[i][e_iNumArguments]; j++) {
  257.         if (j)
  258.             strcat(TF::gs_szDebugBuffer, ", ");
  259.        
  260.         switch (TF::gs_Timers[i][e_aiArgumentTypes][j]) {
  261.             case 'f', 'F':
  262.                 format(TF::gs_szDebugBuffer, sizeof(TF::gs_szDebugBuffer), "%s%.2f", TF::gs_szDebugBuffer, TF::gs_Timers[i][e_axArguments][j]);
  263.            
  264.             default:
  265.                 format(TF::gs_szDebugBuffer, sizeof(TF::gs_szDebugBuffer), "%s%d", TF::gs_szDebugBuffer, TF::gs_Timers[i][e_axArguments][j]);
  266.         }
  267.     }
  268.    
  269.     strcat(TF::gs_szDebugBuffer, ")");
  270.    
  271.     print(TF::gs_szDebugBuffer);
  272. }
  273.  
  274. stock TF::GetPublicFunctionAddress(const szName[]) {
  275.     new
  276.         iIndex,
  277.         iTemp
  278.     ;
  279.    
  280.     if (-1 != (iIndex = funcidx(szName))) {
  281.         // Load the offset to DAT from the prefix
  282.         #emit LCTRL        1
  283.        
  284.         // Invert it so we have the offset to the prefix from DAT
  285.         #emit NEG
  286.        
  287.         // Copy it to alt for use later
  288.         #emit MOVE.alt
  289.        
  290.         // Add 32 to jump to the offset containing the public function's table
  291.         #emit ADD.C        32
  292.        
  293.         // Read the value there; must be done using LREF because
  294.         // it's outside of the DAT section
  295.         #emit STOR.S.pri   iTemp
  296.         #emit LREF.S.pri   iTemp
  297.        
  298.         // Add the value we just loaded to the prefix (that we stored in alt)
  299.         #emit ADD
  300.        
  301.         // Add index * 8 (each entry contains 2 cells - a pointer to the function's name
  302.         // and a pointer to the function itself, relative to COD).
  303.         #emit LOAD.S.alt   iIndex
  304.         #emit SHL.C.alt    3
  305.        
  306.         // Add that to the offset
  307.         #emit ADD
  308.        
  309.         // Now get the address it's pointing to. This seems to only work
  310.         // using LREF (as opposed to LOAD.I, for example).
  311.         #emit STOR.S.pri   iTemp
  312.         #emit LREF.S.pri   iTemp
  313.        
  314.         // Restore the stack
  315.         #emit STACK        8
  316.        
  317.         // Return the address
  318.         #emit RETN
  319.     }
  320.    
  321.     return 0;
  322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement