src/timer/amigaos/SDL_systimer.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 27 Sep 2005 12:14:17 +0000
changeset 1147 b580f7201543
parent 769 b8d311d90021
child 1312 c9b51268668f
permissions -rw-r--r--
From: "Alex Volkov" <avcp-sdlmail@usa.net>
To: "'A list for developers using the SDL library. \(includesSDL-announce\)'" <sdl@libsdl.org>
Date: Mon, 19 Sep 2005 18:59:43 -0400
Subject: [SDL] [patch] Volume multiplier bug in

The volume multiplier in SDL_MixAudio_MMX_S8() is formed from the wrong
register.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdio.h>
    29 #include <time.h>
    30 #include <signal.h>
    31 #include <unistd.h>
    32 #include <string.h>
    33 #include <errno.h>
    34 #include <exec/types.h>
    35 #ifdef __SASC
    36 #include <proto/dos.h>
    37 #include <clib/graphics_protos.h>
    38 #include <pragmas/graphics.h>
    39 #include <clib/exec_protos.h>
    40 #include <pragmas/exec.h>
    41 #elif defined(STORMC4_WOS)
    42 #include <proto/dos.h>
    43 #include <proto/exec.h>
    44 #include <proto/graphics.h>
    45 #else
    46 #include <inline/dos.h>
    47 #include <inline/exec.h>
    48 #include <inline/graphics.h>
    49 #endif
    50 #include "mydebug.h"
    51 
    52 extern struct DosLibrary *DOSBase;
    53 extern struct ExecBase *SysBase;
    54 static struct GfxBase *GfxBase;
    55 
    56 #include "SDL_error.h"
    57 #include "SDL_timer.h"
    58 #include "SDL_timer_c.h"
    59 
    60 #if defined(DISABLE_THREADS) || defined(FORK_HACK)
    61 #define USE_ITIMER
    62 #endif
    63 
    64 /* The first ticks value of the application */
    65 
    66 #if !defined(__PPC__) || defined(STORMC4_WOS) || defined(MORPHOS)
    67 static clock_t start;
    68 
    69 void SDL_StartTicks(void)
    70 {
    71 	/* Set first ticks value */
    72 	start=clock();
    73 }
    74 
    75 Uint32 SDL_GetTicks (void)
    76 {
    77 	clock_t ticks;
    78 
    79 	ticks=clock()-start;
    80 
    81 #ifdef __SASC
    82 // CLOCKS_PER_SEC == 1000 !
    83 
    84 	return(ticks);
    85 #else
    86 // CLOCKS_PER_SEC != 1000 !
    87 
    88 	return ticks*(1000/CLOCKS_PER_SEC);
    89 #endif
    90 }
    91 
    92 void SDL_Delay (Uint32 ms)
    93 {
    94 // Do a busy wait if time is less than 50ms
    95 
    96 	if(ms<50)
    97 	{
    98 		clock_t to_wait=clock();
    99 
   100 #ifndef __SASC
   101 		ms*=(CLOCKS_PER_SEC/1000);
   102 #endif
   103 		to_wait+=ms;
   104 
   105 		while(clock()<to_wait);
   106 	}
   107 	else
   108 	{
   109 		Delay(ms/20);
   110 	}
   111 }
   112 
   113 #else
   114 
   115 ULONG MY_CLOCKS_PER_SEC;
   116 
   117 void PPC_TimerInit(void);
   118 APTR MyTimer;
   119 
   120 ULONG start[2];
   121 
   122 void SDL_StartTicks(void)
   123 {
   124 	/* Set first ticks value */
   125 	if(!MyTimer)
   126 		PPC_TimerInit();
   127 
   128 	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,start);
   129 	start[1]>>=10;
   130 	start[1]|=((result[0]&0x3ff)<<22);
   131 	start[0]>>=10;
   132 }
   133 
   134 Uint32 SDL_GetTicks (void)
   135 {
   136 	ULONG result[2];
   137 	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
   138 
   139 //	PPCAsr64p(result,10);
   140 // Non va, la emulo:
   141 
   142 	result[1]>>=10;
   143 	result[1]|=((result[0]&0x3ff)<<22);
   144 
   145 // Non mi interessa piu' result[0]
   146 
   147 	return result[1]*1000/MY_CLOCKS_PER_SEC;
   148 }
   149 
   150 void SDL_Delay (Uint32 ms)
   151 {
   152 // Do a busy wait if time is less than 50ms
   153 
   154 	if(ms<50)
   155 	{
   156 		ULONG to_wait[2],actual[2];
   157 		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
   158 		actual[1]=0;
   159 		to_wait[1]+=ms*1000/MY_CLOCKS_PER_SEC;
   160 
   161 		while(actual[1]<to_wait[1])
   162 		{
   163 			PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,actual);
   164 		}
   165 	}
   166 	else
   167 	{
   168 		Delay(ms/50);
   169 	}
   170 }
   171 
   172 void PPC_TimerInit(void)
   173 {
   174 	struct TagItem tags[]=
   175 		{
   176 			PPCTIMERTAG_CPU,TRUE,
   177 			TAG_DONE,0
   178 		};
   179 
   180 
   181 	if(MyTimer=PPCCreateTimerObject(tags))
   182 	{
   183 		ULONG result[2];
   184 
   185 		PPCGetTimerObject(MyTimer,PPCTIMERTAG_TICKSPERSEC,result);
   186 		D(bug("Timer inizializzato, TPS: %lu - %lu\n",result[0],result[1]));
   187 //		PPCAsr64p(result,10);
   188 		result[1]>>=10;
   189 		result[1]|=((result[0]&0x3ff)<<22);
   190 		result[0]>>=10;
   191 
   192 		D(bug("Shiftato TPS: %lu - %lu\n",result[0],result[1]));
   193 		MY_CLOCKS_PER_SEC=result[1];
   194 
   195 		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
   196 
   197 		D(bug("Current ticks: %lu - %lu\n",result[0],result[1]));
   198 		result[1]>>=10;
   199 		result[1]|=((result[0]&0x3ff)<<22);
   200 		result[0]>>=10;
   201 //		PPCAsr64p(result,10);
   202 		D(bug("Shiftato: %lu - %lu\n",result[0],result[1]));
   203 	}
   204 	else
   205 	{
   206 		D(bug("Errore nell'inizializzazione del timer!\n"));
   207 	}
   208 }
   209 
   210 #endif
   211 
   212 #include "SDL_thread.h"
   213 
   214 /* Data to handle a single periodic alarm */
   215 static int timer_alive = 0;
   216 static SDL_Thread *timer_thread = NULL;
   217 
   218 static int RunTimer(void *unused)
   219 {
   220 	D(bug("SYSTimer: Entering RunTimer loop..."));
   221 
   222 	if(GfxBase==NULL)
   223 		GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
   224 
   225 	while ( timer_alive ) {
   226 		if ( SDL_timer_running ) {
   227 			SDL_ThreadedTimerCheck();
   228 		}
   229 		if(GfxBase)
   230 			WaitTOF();  // Check the timer every fifth of seconds. Was SDL_Delay(1)->BusyWait!
   231 		else
   232 			Delay(1);
   233 	}
   234 	D(bug("SYSTimer: EXITING RunTimer loop..."));
   235 	return(0);
   236 }
   237 
   238 /* This is only called if the event thread is not running */
   239 int SDL_SYS_TimerInit(void)
   240 {
   241 	D(bug("Creating thread for the timer (NOITIMER)...\n"));
   242 
   243 	timer_alive = 1;
   244 	timer_thread = SDL_CreateThread(RunTimer, NULL);
   245 	if ( timer_thread == NULL )
   246 	{
   247 		D(bug("Creazione del thread fallita...\n"));
   248 
   249 		return(-1);
   250 	}
   251 	return(SDL_SetTimerThreaded(1));
   252 }
   253 
   254 void SDL_SYS_TimerQuit(void)
   255 {
   256 	timer_alive = 0;
   257 	if ( timer_thread ) {
   258 		SDL_WaitThread(timer_thread, NULL);
   259 		timer_thread = NULL;
   260 	}
   261 }
   262 
   263 int SDL_SYS_StartTimer(void)
   264 {
   265 	SDL_SetError("Internal logic error: AmigaOS uses threaded timer");
   266 	return(-1);
   267 }
   268 
   269 void SDL_SYS_StopTimer(void)
   270 {
   271 	return;
   272 }