Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1654 → Rev 1655

/unsupported/branches/unsupported/thdemo/fft.c
0,0 → 1,533
// FFT Part
/*
 
FFTPlay 1.0
-----------
 
This application reads data from the audio microphone and then put it
to the screen in a graphical oscilloscope-like form (both standard Hartik
SB driver and Alsa driver can be used).
 
The application also calculate a FFT on the latest values, and displays
the power spectrum in tho ways, one like an equalizator, and the other in a
2D form.
 
A resolution of 1024x768, 64K colors is used.
 
The task set is composed by these tasks and functions:
 
Self buffering functions (SB only)
----------------------------------
this function takes the samples read by the mic and then makes a window
with the last WINDATA_NSAMPLES samples. The window is then put in
the CAB windata.
 
Task raw and task mixer (ALSA only)
-----------------------------------
These tasks are used with the Alsa driver; because it doesn't support the
self-buffering mode, we have to do a forever cycle in witch we have to read
all the data. Then the data are managed like the self-buffering functions of
the SB driver or sent to the mixer task (with a STREAM mailbox) which makes
the window.
(This approach is not good for realtime...)
 
Task wave
---------
This task read the last window and then put it on the screen in a wave form
on the top of the screen.
The task's period is set to 40 ms (25 fps).
 
Task fft
--------
This task read the last window and then it computes the FFT.
With the FFT data it computes the power spectrum, whitch is sent to the
CAB pwrdata.
The task's period is set to 10 ms (good for the 2D story task).
This task is the only Hard Task.
 
Task equ
--------
This task read the last power spectrum and displays it in a graphical
form, like a hi-fi equalizator.
The Histograms can be white or coloured like the equ2D task (see EQU_SHADE)
The task's period is set to 40 ms (25 fps).
 
Task equ2D
----------
This task read the lasf power spectrum and displays it in a graphical
one-line form. Each pixel is a power coefficient, and its colour shade
from black (no power) to red (high power) passing through green and blue.
The task display the last EQU2D_WIDTH power lines.
The task's period is set to 10 ms (good for the 2D story task).
 
****************************************************************************
TASK LOAD
****************************************************************************
 
period wcet
task tick (ms) us %
--------------------------------------------------------
sound driver 24->3 12->1.5 200 0.016->0.133
wave 80 40 11500 0.2875
fft 20 10 3000 0.3000
equ 80 40 7000 0.1750
equ2D 20 10 500 0.0500
-------------
0.812 (last 4)
*/
 
#include "demo.h"
//#include <ll/ll.h>
 
//#include <kernel/types.h>
#include <kernel/model.h>
#include <kernel/func.h>
 
#include <modules/cabs.h>
 
//#include <string.h>
//#include <stdlib.h>
#include <semaphore.h>
 
//#include <drivers/keyb.h>
//#include <drivers/crtwin.h>
#include <drivers/glib.h>
#include <drivers/sound.h>
#include <rfftw.h>
 
/* CAB ports... */
CAB cab_windata; /* a window on the last WINDATA_DIM samples */
CAB cab_pwrdata; /* the last power spectrum */
 
/* for the cab_windata */
typedef struct {
int start;
SAMPLE sample[WINDATA_NSAMPLES];
} window;
 
/* for the cab_pwrdata */
typedef struct {
fftw_real p[PWR_NSAMPLES];
} power;
 
 
// win is global... because is used by raw_infun...
window win;
 
/*
This is the self-buffering function: read the samples and put their mean
value in a CAB
*/
int raw_infun(void *b)
{
int i;
char *w;
SAMPLE *audiobuf = (SAMPLE *)b;
 
for (i=0; i<rawdata_nsamples/2; i++) {
win.sample[win.start] = audiobuf[i];
win.start = (win.start+1) % WINDATA_NSAMPLES;
}
 
w = cab_reserve(cab_windata);
memcpy(w, &win, sizeof(window));
cab_putmes(cab_windata,w);
 
#if defined(NO_GRX)
cprintf("X"); //"XXX%d\n",win.sample[win.start]);
#endif
return 0;
}
 
 
 
void init_rawdata()
{
int i;
char *w;
 
win.start = 0;
for (i=0; i<WINDATA_NSAMPLES; i++)
win.sample[i] = 0;
 
w = cab_reserve(cab_windata);
memcpy(w, &win, sizeof(window));
cab_putmes(cab_windata,w);
}
 
 
 
 
 
TASK wave_task()
{
window *p;
int x,y;
int s;
 
while(1)
{
p = (window *)cab_getmes(cab_windata);
 
/* let's print the wave */
mutex_lock(&mutex);
for(x = WAVE_X, s = p->start;
x < WAVE_X+WAVE_NSAMPLES;
x++, s = (s+1)%WINDATA_NSAMPLES )
{
y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
SHORT_CRITICAL_SECTIONS(x);
grx_plot(x,y,white);
}
mutex_unlock(&mutex);
 
task_endcycle();
 
/* let's erase the wave */
mutex_lock(&mutex);
for(x = WAVE_X, s = p->start;
x < WAVE_X+WAVE_NSAMPLES;
x++, s = (s+1)%WINDATA_NSAMPLES )
{
y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
SHORT_CRITICAL_SECTIONS(x);
grx_plot(x,y,black);
}
mutex_unlock(&mutex);
 
cab_unget(cab_windata,(char *)p);
 
}
}
 
 
rfftw_plan plan;
 
void fft_close(void *arg)
{
rfftw_destroy_plan(plan);
}
 
 
TASK fft_task()
{
fftw_real in[FFT_NSAMPLES], out[FFT_NSAMPLES];
power power_spectrum;
 
#if defined(NO_GRX)
fftw_real max = 0.0;
#endif
 
char *m;
 
int k, i;
 
window *p;
 
plan = rfftw_create_plan(FFT_NSAMPLES, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
 
sys_atrunlevel(fft_close, NULL, RUNLEVEL_BEFORE_EXIT);
 
while(1)
{
/* Let's prepare the intput FFT data */
p = (window *)cab_getmes(cab_windata);
 
for (k = 0, i = p->start;
k < FFT_NSAMPLES;
k++, i = (i+1)%WINDATA_NSAMPLES)
in[k] = p->sample[i]/FFT_SCALE;
 
cab_unget(cab_windata,(char *)p);
 
/* zero-padding if needed */
for (k=WINDATA_NSAMPLES; k < FFT_NSAMPLES; k++)
in[k] = 0.0;
 
rfftw_one(plan, in, out);
 
/* power spectrum computation */
power_spectrum.p[0] = out[0]*out[0]; /* DC component */
for (k = 1; k < PWR_NSAMPLES; ++k) /* (k < N/2 rounded up) */
power_spectrum.p[k] = out[k]*out[k] + out[FFT_NSAMPLES-k]*out[FFT_NSAMPLES-k];
if (FFT_NSAMPLES % 2 == 0) /* N is even */
power_spectrum.p[FFT_NSAMPLES/2] = out[FFT_NSAMPLES/2]*out[FFT_NSAMPLES/2]; /* Nyquist freq. */
 
m = cab_reserve(cab_pwrdata);
memcpy(m, &power_spectrum, sizeof(power));
cab_putmes(cab_pwrdata,m);
 
#if defined(NO_GRX)
max = 0.0;
for (k=0; k<PWR_NSAMPLES; k++)
if (power_spectrum.p[k] > max)
max = power_spectrum.p[k];
 
//cprintf("%f %f\n",max,(max / EQU_SCALE) );
#endif
 
task_endcycle();
 
}
}
 
/* structure is like the wave task... */
TASK equ_task()
{
power *p;
 
int x[PWR_NSAMPLES];
int y;
int s;
 
int r,g,b;
 
while(1)
{
p = (power *)cab_getmes(cab_pwrdata);
 
/* print the lines */
mutex_lock(&mutex);
for(y = EQU_Y, s = 0;
s < EQU_NSAMPLES;
y++, s++ )
{
x[s] = (int)(p->p[s] / EQU_SCALE);
 
if (x[s] > EQU_HEIGHT)
x[s] = EQU_HEIGHT;
 
x[s] = EQU_X - x[s];
 
 
#if defined(EQU_SHADE)
 
/* like the task equ2d... */
r = (int)(p->p[s] / EQU2D_SCALE);
if (r > EQU2D_CLIP)
r = EQU2D_CLIP;
 
if (r< 64) g = r * 4;
else if (r<128) g = (128-r) * 4;
else g = 0;
 
if (r<128) b = 0;
else if (r<192) b = (r-128) * 4;
else b = (256-r) * 4;
 
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,rgb16(r,g,b));
#else
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,white);
#endif
}
mutex_unlock(&mutex);
 
task_endcycle();
 
/* erase the lines... */
mutex_lock(&mutex);
for(y = EQU_Y, s = 0;
s < EQU_NSAMPLES;
y++, s++ )
{
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,black);
}
mutex_unlock(&mutex);
 
cab_unget(cab_pwrdata,(char *)p);
 
}
}
 
TASK equ2d_task()
{
power *p;
 
int pwrint;
 
int x = 0;
 
int y,s;
 
int r,g,b;
 
while(1)
{
 
p = (power *)cab_getmes(cab_pwrdata);
 
/* print the line */
mutex_lock(&mutex);
 
for(y = EQU2D_Y, s = 0;
s < EQU2D_NSAMPLES;
y++, s++ )
{
pwrint = (int)(p->p[s] / EQU2D_SCALE);
 
if (pwrint > EQU2D_CLIP)
pwrint = EQU2D_CLIP;
 
r = pwrint;
 
if (pwrint< 64) g = pwrint * 4;
else if (pwrint<128) g = (128-pwrint) * 4;
else g = 0;
 
if (pwrint<128) b = 0;
else if (pwrint<192) b = (pwrint-128) * 4;
else b = (256-pwrint) * 4;
 
SHORT_CRITICAL_SECTIONS(y);
grx_plot(EQU2D_X+x,y,rgb16(r,g,b));
}
 
x = (x+1) % EQU2D_WIDTH;
grx_line(EQU2D_X+x,EQU2D_Y,EQU2D_X+x,EQU2D_Y+EQU2D_NSAMPLES-1,white);
 
mutex_unlock(&mutex);
 
cab_unget(cab_pwrdata,(char *)p);
 
task_endcycle();
}
}
 
 
void init_fftplay(int freq)
{
SOFT_TASK_MODEL m3, m4, m5, m6;
 
PID p3,p4,p5,p6;
 
cab_windata = cab_create("windata", sizeof(window), 5);
cab_pwrdata = cab_create("pwr", sizeof(power), 5);
 
/* Init the sound lib */
sound_init((rawdata_nsamples * sizeof(SAMPLE)), NULL);
sound_info();
 
/* Init the data used by the raw_infun */
init_rawdata();
 
/* Start the self-buffering sampling operation */
sound_setfun(raw_infun, (int (*)(void *))-1);
sound_sample(NULL, freq, 0, DMA_OP | PCM16 | MYFUN, NULL);
 
soft_task_default_model(m3);
soft_task_def_level(m3,1);
soft_task_def_period(m3, PERIOD_WAVE);
soft_task_def_met(m3, WCET_WAVE);
soft_task_def_ctrl_jet(m3);
soft_task_def_group(m3, 1);
p3 = task_create("wave", wave_task, &m3, NULL);
if (p3 == -1) {
grx_close();
perror("FFTPlay: Could not create task <wave>\n");
ll_abort(54);
sys_end();
}
 
soft_task_default_model(m4);
soft_task_def_level(m4,1);
soft_task_def_period(m4, PERIOD_FFT);
soft_task_def_met(m4, WCET_FFT);
soft_task_def_group(m4, 1);
soft_task_def_stack(m4,32*1024);
soft_task_def_usemath(m4);
soft_task_def_ctrl_jet(m4);
p4 = task_create("fft", fft_task, &m4, NULL);
if (p4 == -1) {
grx_close();
perror("FFTPlay: Could not create task <fft>\n");
ll_abort(54);
sys_end();
}
 
soft_task_default_model(m5);
soft_task_def_level(m5,1);
soft_task_def_period(m5, PERIOD_EQU);
soft_task_def_met(m5, WCET_EQU);
soft_task_def_group(m5, 1);
soft_task_def_stack(m5,32*1024);
soft_task_def_usemath(m5);
soft_task_def_ctrl_jet(m5);
p5 = task_create("equ", equ_task, &m5, NULL);
if (p5 == -1) {
grx_close();
perror("FFTPlay: Could not create task <equ>\n");
ll_abort(54);
perror("FFTPlay: Could not create task <equ>\n");
sys_end();
}
 
soft_task_default_model(m6);
soft_task_def_level(m6,1);
soft_task_def_period(m6, PERIOD_EQU2D);
soft_task_def_met(m6, WCET_EQU2D);
soft_task_def_group(m6, 1);
soft_task_def_stack(m6,32*1024);
soft_task_def_usemath(m6);
soft_task_def_ctrl_jet(m6);
p6 = task_create("equ2D", equ2d_task, &m6, NULL);
if (p6 == -1) {
grx_close();
perror("FFTPlay: Could not create task <equ2d>\n");
ll_abort(54);
perror("FFTPlay: Could not create task <equ2D>\n");
sys_end();
}
}
 
void scenario_fftplay(int f)
{
int i,y;
char s[50];
 
grx_line(0,WAVE_Y-WAVE_HEIGHT-1,383,WAVE_Y-WAVE_HEIGHT-1,red);
grx_line(0,WAVE_Y+WAVE_HEIGHT+1,383,WAVE_Y+WAVE_HEIGHT+1,red);
grx_line(0,EQU_Y-11 ,383,EQU_Y-11 ,red);
 
 
 
/* lines near the frequencies */
grx_line(EQU_X +1,EQU_Y,EQU_X +1,EQU_Y+EQU_NSAMPLES-1,red);
grx_line(EQU2D_X-1,EQU_Y,EQU2D_X-1,EQU_Y+EQU_NSAMPLES-1,red);
 
for (i=0; i<SCENARIO_NLABEL; i++)
{
y = (i*EQU_NSAMPLES)/(SCENARIO_NLABEL-1);
if (i == SCENARIO_NLABEL-1) y--;
grx_line(EQU_X +1,EQU_Y+y,EQU_X +4,EQU_Y+y,red);
grx_line(EQU2D_X-1,EQU_Y+y,EQU2D_X-4,EQU_Y+y,red);
 
itoa((i*f)/(SCENARIO_NLABEL-1),s);
grx_text(s,EQU_X+20,EQU_Y+y-8,white,black);
}
 
grx_text("Power Spectrum" , 0, EQU_Y-21, rgb16(0,0,255), black);
grx_text("Power Spectrum Story", EQU2D_X+EQU2D_WIDTH-160, EQU_Y-21, rgb16(0,0,255), black);
grx_text("Waveform" , 0, WAVE_Y-WAVE_HEIGHT-10, rgb16(0,0,255), black);
}
 
void compute_params(int *freq,WORD *nsamp)
{
if (*freq< 2000)
{
cprintf("WARNING: frequency less than 2000Hz\n ---> frequency set to 2000Hz\n");
*freq = 2000;
}
if (*freq<= 8000) { *nsamp = 64; return; } //128
if (*freq<=16000) { *nsamp = 64; return; } //256
if (*freq<=24000) { *nsamp = 64; return; } //512
if (*freq>48000)
{
cprintf("WARNING: frequency greather than 48000Hz\n ---> frequency set to 48000Hz\n");
*freq = 48000;
}
if (*freq<=48000) { *nsamp = 64; return; } //1024
}
 
/unsupported/branches/unsupported/thdemo/initfile.c
0,0 → 1,146
/*
* Project: HARTIK (HA-rd R-eal TI-me K-ernel)
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
* Gerardo Lamastra <gerardo@sssup.it>
*
* Authors : Paolo Gai <pj@hartik.sssup.it>
* (see authors.txt for full list of hartik's authors)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
/**
------------
CVS : $Id: initfile.c,v 1.1.1.1 2004-05-24 18:03:47 giacomo Exp $
 
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2004-05-24 18:03:47 $
------------
 
System initialization file
 
h3pi.c
 
This file is equal to hartik3.c plus the resources module...
 
**/
 
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
//#define PI
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/cbs.h"
#include "modules/rr.h"
 
#ifndef PI
#include "modules/rrsoft.h"
#endif
 
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
 
#include "drivers/keyb.h"
 
 
/*+ sysyem tick in us +*/
#define TICK 1000
 
/*+ RR tick in us +*/
#define RRTICK 10000
//#define RRTICK 3000
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
#ifdef PI
EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL, 0);
#else
RRSOFT_register_level(RRTICK, RR_MAIN_NO, mb, RRSOFT_ONLY_HARD|RRSOFT_ONLY_SOFT);
RRSOFT_register_level(RRTICK, RR_MAIN_NO, mb, RRSOFT_ONLY_SOFT); //cbs
#endif
 
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
 
 
SEM_register_module();
 
CABS_register_module();
 
PI_register_module();
NOP_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
HARTPORT_init();
 
kern_printf("TIME=%ld\n",sys_gettime(NULL));
KEYB_init(NULL);
kern_printf("TIME=%ld\n",sys_gettime(NULL));
// KEYB_init(NULL);
 
__call_main__(mb);
 
return (void *)0;
}
 
 
#ifdef PI
void app_mutex_init(mutex_t *m)
{
PI_mutexattr_t attr;
 
PI_mutexattr_default(attr);
 
mutex_init(m, &attr);
}
#else
void app_mutex_init(mutex_t *m)
{
NOP_mutexattr_t attr;
 
NOP_mutexattr_default(attr);
 
mutex_init(m, &attr);
}
#endif
/unsupported/branches/unsupported/thdemo/demo.c
0,0 → 1,260
/* Project: HARTIK 3.0 */
/* Description: Hard Real TIme Kernel for 386 & higher machines */
/* Author: Paolo Gai <pgai@rsk.it> */
/* Advanced Linux Sound Architecture (ALSA) */
/* Copyright (c) by Jaroslav Kysela <perex@jcu.cz> */
/* Luca Abeni */
/* FFTW by M. Frigo and S. G. Johnson */
 
/* Date: 08/09/1999 */
 
/* File: fftplay.c */
/* Revision: 1.00 (Kernel 0.1.4; Library 0.0.9; Util 0.0.4) */
 
 
 
#include "demo.h"
 
//#include <kernel/types.h>
//#include <kernel/model.h>
#include <kernel/func.h>
 
//#include <modules/cabs.h>
 
#include <string.h>
#include <stdlib.h>
 
#include <drivers/keyb.h>
//#include <drivers/crtwin.h>
#include <drivers/glib.h>
//#include <drivers/sound.h>
//#include <ports/rfftw.h>
 
 
 
/* Informations about the sampling rate and buffers */
WORD rawdata_nsamples;
WORD rawdata_buffer_size;
WORD rawdata_freq;
 
/* graphic mutex... */
mutex_t mutex;
 
/* useful colors... */
int white;
int black;
int red;
int gray;
 
void app_mutex_init(mutex_t *m);
 
 
static void version( void )
{
cprintf( "Hartik FFT Play 1.0\n" );
cprintf( "-----------------------\n" );
cprintf( "by Paolo Gai 1999\n" );
cprintf( " <pj@hartik.sssup.it>\n" );
cprintf( "-----------------------\n" );
}
 
void reverse(char s[])
{
int c, i, j;
 
for (i = 0, j = strlen(s)-1; i<j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
 
char * itoa(int n, char *s)
{
int i, sign;
 
if ((sign = n) < 0)
n = -n;
 
i = 0;
 
do
{
s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
 
if (sign < 0)
s[i++] = '-';
 
s[i] = 0;
 
reverse(s);
 
return s;
}
 
void display_jet(PID i)
{
char st[200];
TIME sum, max;
int n;
 
if (jet_getstat(i, &sum, &max, &n, NULL) != -1) {
if (n==0) n=1;
sprintf(st, "PID=%2d st=%3d Mean=%5d Max=%5d na=%10s",
(int)i,
(int)proc_table[i].status, (int)sum/n, (int)max,
proc_table[i].name);
mutex_lock(&mutex);
grx_text(st, 0, 400+i*8, 255, 0);
mutex_unlock(&mutex);
}
}
 
 
 
void scenario(int f)
{
grx_text("HARTIK 4.0 - LEGO Version" , 0,0, rgb16(0,255,0), black );
grx_text("Thesis Demo", 0,8, rgb16(0,255,0), black );
 
#ifdef FFT_ON
scenario_fftplay(f);
#endif
 
#ifdef FRAMEGRABBER_ON
scenario_framegrabber();
#endif
 
#ifdef JET_ON
scenario_jetcontrol();
#endif
 
#ifdef BALL_ON
scenario_ball();
#endif
}
 
 
void my_close(void *arg)
{
grx_close();
}
 
 
void endfun(KEY_EVT *k)
{
grx_close();
cprintf("Ctrl-Brk pressed! Ending...\n");
sys_end();
}
 
void zerofun(KEY_EVT *k)
{
int i;
for (i=0; i<MAX_PROC; i++) jet_delstat(i);
}
 
void printeventqueue(void *arg)
{
struct event *p;
extern struct event *firstevent;
 
kern_cli();
grx_close();
kern_cli();
for (p = firstevent; p != NULL; p = p->next) {
kern_printf("par:%d time:%ld.%ld p:%d handler:%d\n",
(int)p->par, p->time.tv_sec, p->time.tv_nsec/1000, (int)p, (int)p->handler);
}
kern_sti();
}
 
int main(int argc, char **argv)
{
int modenum;
 
int f;
 
KEY_EVT k;
 
srand(4);
 
version();
 
#ifdef FRAMEGRABBER_ON
if (argc == 1)
{
cprintf("type x fftplay <freq>");
return 0;
}
 
f = atoi(argv[1]);
compute_params(&f,&rawdata_nsamples);
#endif
 
keyb_set_map(itaMap);
k.flag = CNTR_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,endfun);
k.flag = CNTL_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,endfun);
k.flag = ALTL_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,zerofun);
k.flag = 0;
k.scan = KEY_ENT;
k.ascii = 13;
keyb_hook(k,endfun);
 
sys_atrunlevel(my_close, NULL, RUNLEVEL_BEFORE_EXIT);
 
 
grx_init();
modenum = grx_getmode(640, 480, 16);
 
grx_setmode(modenum);
 
/* init the graphic mutex */
app_mutex_init(&mutex);
 
/* useful colors ... */
white = rgb16(255,255,255);
black = rgb16(0,0,0);
red = rgb16(255,0,0);
gray = rgb16(128,128,128);
 
scenario(f/2);
// grx_close();
// clear();
#ifdef FFT_ON
init_fftplay(f);
#endif
 
#ifdef FRAMEGRABBER_ON
init_framegrabber();
#endif
 
#ifdef JET_ON
init_jetcontrol();
#endif
 
#ifdef BALL_ON
init_ball();
#endif
 
group_activate(1);
 
#ifdef FRAMEGRABBER_ON
start_framegrabber();
#endif
 
return 0;
}
 
 
/unsupported/branches/unsupported/thdemo/fftplay.c
0,0 → 1,769
/* Project: HARTIK 3.0 */
/* Description: Hard Real TIme Kernel for 386 & higher machines */
/* Author: Paolo Gai <pgai@rsk.it> */
/* Advanced Linux Sound Architecture (ALSA) */
/* Copyright (c) by Jaroslav Kysela <perex@jcu.cz> */
/* Luca Abeni */
/* FFTW by M. Frigo and S. G. Johnson */
 
/* Date: 08/09/1999 */
 
/* File: fftplay.c */
/* Revision: 1.00 (Kernel 0.1.4; Library 0.0.9; Util 0.0.4) */
 
 
/*
 
FFTPlay 1.0
-----------
 
This application reads data from the audio microphone and then put it
to the screen in a graphical oscilloscope-like form (both standard Hartik
SB driver and Alsa driver can be used).
 
The application also calculate a FFT on the latest values, and displays
the power spectrum in tho ways, one like an equalizator, and the other in a
2D form.
 
A resolution of 1024x768, 64K colors is used.
 
The task set is composed by these tasks and functions:
 
Self buffering functions (SB only)
----------------------------------
this function takes the samples read by the mic and then makes a window
with the last WINDATA_NSAMPLES samples. The window is then put in
the CAB windata.
 
Task raw and task mixer (ALSA only)
-----------------------------------
These tasks are used with the Alsa driver; because it doesn't support the
self-buffering mode, we have to do a forever cycle in witch we have to read
all the data. Then the data are managed like the self-buffering functions of
the SB driver or sent to the mixer task (with a STREAM mailbox) which makes
the window.
(This approach is not good for realtime...)
 
Task wave
---------
This task read the last window and then put it on the screen in a wave form
on the top of the screen.
The task's period is set to 40 ms (25 fps).
 
Task fft
--------
This task read the last window and then it computes the FFT.
With the FFT data it computes the power spectrum, whitch is sent to the
CAB pwrdata.
The task's period is set to 10 ms (good for the 2D story task).
This task is the only Hard Task.
 
Task equ
--------
This task read the last power spectrum and displays it in a graphical
form, like a hi-fi equalizator.
The Histograms can be white or coloured like the equ2D task (see EQU_SHADE)
The task's period is set to 40 ms (25 fps).
 
Task equ2D
----------
This task read the lasf power spectrum and displays it in a graphical
one-line form. Each pixel is a power coefficient, and its colour shade
from black (no power) to red (high power) passing through green and blue.
The task display the last EQU2D_WIDTH power lines.
The task's period is set to 10 ms (good for the 2D story task).
 
****************************************************************************
TASK LOAD
****************************************************************************
 
period wcet
task tick (ms) us %
--------------------------------------------------------
sound driver 24->3 12->1.5 200 0.016->0.133
wave 80 40 11500 0.2875
fft 20 10 3000 0.3000
equ 80 40 7000 0.1750
equ2D 20 10 500 0.0500
-------------
0.812 (last 4)
*/
 
#include <ll/ll.h>
 
#include <kernel/types.h>
#include <kernel/model.h>
#include <kernel/func.h>
 
#include <modules/cabs.h>
 
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
 
#include <drivers/keyb.h>
#include <drivers/crtwin.h>
#include <drivers/glib.h>
#include <drivers/sound.h>
#include <ports/rfftw.h>
 
/* now the load constants... */
 
#define WCET_WAVE 11500
#define WCET_FFT 3000
#define WCET_EQU 500
#define WCET_EQU2D 500
 
#define PERIOD_WAVE 40000
#define PERIOD_FFT 10000
#define PERIOD_EQU 40000
#define PERIOD_EQU2D 10000
 
/* define if shorts critical sections wanted */
#define SHORT_CRITICAL_SECTIONS(x) \
if (!((x)%64)) \
{ \
sem_post(&mutex); \
sem_wait(&mutex); \
}
 
/* define if you want NRT or SOFT... */
#define TASK_TYPE SOFT
//#define TASK_TYPE NRT
 
 
 
/* Only 4 Debug... */
/*#define NO_GRX */
 
/* Samples are 16-bit signed integers */
typedef short SAMPLE;
#define MAX_SAMPLE 32768
 
/* Informations about the sampling rate and buffers */
WORD rawdata_nsamples;
WORD rawdata_buffer_size;
WORD rawdata_freq;
 
/* Numbers of samples of the sample window */
#define WINDATA_NSAMPLES 1024
 
/* task WAVE */
/* the point (wave_x,wave_y) is on the center left of the area... */
#define WAVE_NSAMPLES 1024
#define WAVE_X 0
#define WAVE_Y 130
#define WAVE_HEIGHT 80
 
/* task FFT */
#define FFT_NSAMPLES WINDATA_NSAMPLES
#define PWR_NSAMPLES (FFT_NSAMPLES/2+1)
 
/* task EQU */
/* the point (equ_x, equ_y) is the top right corner */
#define EQU_NSAMPLES PWR_NSAMPLES
#define EQU_X 170
#define EQU_Y 255
#define EQU_HEIGHT 170
#define EQU_SHADE
 
/* task EQU2D */
/* the point (equ2d_x, equ2d_y) is the top left corner */
#define EQU2D_NSAMPLES EQU_NSAMPLES
#define EQU2D_X 255
#define EQU2D_Y EQU_Y
#define EQU2D_WIDTH 768
#define EQU2D_CLIP 255
 
/* scenario */
#define SCENARIO_NLABEL 16
 
/* Scale factors */
#define FFT_SCALE (16384.0)
#define EQU_SCALE (32.0)
#define EQU2D_SCALE (8.0)
//#define EQU_SCALE (64.0)
//#define EQU2D_SCALE (16.0)
 
 
/* CAB ports... */
CAB cab_windata; /* a window on the last WINDATA_DIM samples */
CAB cab_pwrdata; /* the last power spectrum */
 
/* for the cab_windata */
typedef struct {
int start;
SAMPLE sample[WINDATA_NSAMPLES];
} window;
 
/* for the cab_pwrdata */
typedef struct {
fftw_real p[PWR_NSAMPLES];
} power;
 
/* graphic mutex... */
sem_t mutex;
 
// win is global... because is used by raw_infun...
window win;
 
 
 
/* useful colors... */
int white;
int black;
int red;
 
static void version( void )
{
cprintf( "Hartik FFT Play 1.0\n" );
cprintf( "-----------------------\n" );
cprintf( "by Paolo Gai 1999\n" );
cprintf( " <pj@hartik.sssup.it>\n" );
cprintf( "-----------------------\n" );
}
 
void reverse(char s[])
{
int c, i, j;
 
for (i = 0, j = strlen(s)-1; i<j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
 
char * itoa(int n, char *s)
{
int i, sign;
 
if ((sign = n) < 0)
n = -n;
 
i = 0;
 
do
{
s[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
 
if (sign < 0)
s[i++] = '-';
 
s[i] = 0;
 
reverse(s);
 
return s;
}
 
 
 
/*
This is the self-buffering function: read the samples and put their mean
value in a CAB
*/
int raw_infun(void *b)
{
int i;
char *w;
SAMPLE *audiobuf = (SAMPLE *)b;
 
for (i=0; i<rawdata_nsamples/2; i++) {
win.sample[win.start] = audiobuf[i];
win.start = (win.start+1) % WINDATA_NSAMPLES;
}
 
w = cab_reserve(cab_windata);
memcpy(w, &win, sizeof(window));
cab_putmes(cab_windata,w);
 
#if defined(NO_GRX)
cprintf("X"); //"XXX%d\n",win.sample[win.start]);
#endif
return 0;
}
 
 
 
void init_rawdata()
{
int i;
char *w;
 
win.start = 0;
for (i=0; i<WINDATA_NSAMPLES; i++)
win.sample[i] = 0;
 
w = cab_reserve(cab_windata);
memcpy(w, &win, sizeof(window));
cab_putmes(cab_windata,w);
}
 
 
 
 
 
TASK wave_task()
{
window *p;
int x,y;
int s;
 
while(1)
{
p = (window *)cab_getmes(cab_windata);
 
/* let's print the wave */
sem_wait(&mutex);
for(x = WAVE_X, s = p->start;
x < WAVE_X+WAVE_NSAMPLES;
x++, s = (s+1)%WINDATA_NSAMPLES )
{
y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
SHORT_CRITICAL_SECTIONS(x);
grx_plot(x,y,white);
}
sem_post(&mutex);
 
task_endcycle();
 
/* let's erase the wave */
sem_wait(&mutex);
for(x = WAVE_X, s = p->start;
x < WAVE_X+WAVE_NSAMPLES;
x++, s = (s+1)%WINDATA_NSAMPLES )
{
y = WAVE_Y + (WAVE_HEIGHT * p->sample[s]) / MAX_SAMPLE;
SHORT_CRITICAL_SECTIONS(x);
grx_plot(x,y,black);
}
sem_post(&mutex);
 
cab_unget(cab_windata,(char *)p);
 
}
}
 
 
rfftw_plan plan;
 
void fft_close(void *arg)
{
rfftw_destroy_plan(plan);
}
 
 
TASK fft_task()
{
fftw_real in[FFT_NSAMPLES], out[FFT_NSAMPLES];
power power_spectrum;
 
#if defined(NO_GRX)
fftw_real max = 0.0;
#endif
 
char *m;
 
int k, i;
 
window *p;
 
plan = rfftw_create_plan(FFT_NSAMPLES, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
 
sys_atrunlevel(fft_close, NULL, RUNLEVEL_BEFORE_EXIT);
 
while(1)
{
/* Let's prepare the intput FFT data */
p = (window *)cab_getmes(cab_windata);
 
for (k = 0, i = p->start;
k < FFT_NSAMPLES;
k++, i = (i+1)%WINDATA_NSAMPLES)
in[k] = p->sample[i]/FFT_SCALE;
 
cab_unget(cab_windata,(char *)p);
 
/* zero-padding if needed */
for (k=WINDATA_NSAMPLES; k < FFT_NSAMPLES; k++)
in[k] = 0.0;
 
rfftw_one(plan, in, out);
 
/* power spectrum computation */
power_spectrum.p[0] = out[0]*out[0]; /* DC component */
for (k = 1; k < PWR_NSAMPLES; ++k) /* (k < N/2 rounded up) */
power_spectrum.p[k] = out[k]*out[k] + out[FFT_NSAMPLES-k]*out[FFT_NSAMPLES-k];
if (FFT_NSAMPLES % 2 == 0) /* N is even */
power_spectrum.p[FFT_NSAMPLES/2] = out[FFT_NSAMPLES/2]*out[FFT_NSAMPLES/2]; /* Nyquist freq. */
 
m = cab_reserve(cab_pwrdata);
memcpy(m, &power_spectrum, sizeof(power));
cab_putmes(cab_pwrdata,m);
 
#if defined(NO_GRX)
max = 0.0;
for (k=0; k<PWR_NSAMPLES; k++)
if (power_spectrum.p[k] > max)
max = power_spectrum.p[k];
 
//cprintf("%f %f\n",max,(max / EQU_SCALE) );
#endif
 
task_endcycle();
 
}
}
 
/* structure is like the wave task... */
TASK equ_task()
{
power *p;
 
int x[PWR_NSAMPLES];
int y;
int s;
 
int r,g,b;
 
while(1)
{
p = (power *)cab_getmes(cab_pwrdata);
 
/* print the lines */
sem_wait(&mutex);
for(y = EQU_Y, s = 0;
s < EQU_NSAMPLES;
y++, s++ )
{
x[s] = (int)(p->p[s] / EQU_SCALE);
 
if (x[s] > EQU_HEIGHT)
x[s] = EQU_HEIGHT;
 
x[s] = EQU_X - x[s];
 
 
#if defined(EQU_SHADE)
 
/* like the task equ2d... */
r = (int)(p->p[s] / EQU2D_SCALE);
if (r > EQU2D_CLIP)
r = EQU2D_CLIP;
 
if (r< 64) g = r * 4;
else if (r<128) g = (128-r) * 4;
else g = 0;
 
if (r<128) b = 0;
else if (r<192) b = (r-128) * 4;
else b = (256-r) * 4;
 
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,rgb16(r,g,b));
#else
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,white);
#endif
}
sem_post(&mutex);
 
task_endcycle();
 
/* erase the lines... */
sem_wait(&mutex);
for(y = EQU_Y, s = 0;
s < EQU_NSAMPLES;
y++, s++ )
{
SHORT_CRITICAL_SECTIONS(y);
grx_line(EQU_X,y,x[s],y,black);
}
sem_post(&mutex);
 
cab_unget(cab_pwrdata,(char *)p);
 
}
}
 
TASK equ2d_task()
{
power *p;
 
int pwrint;
 
int x = 0;
 
int y,s;
 
int r,g,b;
 
while(1)
{
 
p = (power *)cab_getmes(cab_pwrdata);
 
/* print the line */
sem_wait(&mutex);
 
for(y = EQU2D_Y, s = 0;
s < EQU2D_NSAMPLES;
y++, s++ )
{
pwrint = (int)(p->p[s] / EQU2D_SCALE);
 
if (pwrint > EQU2D_CLIP)
pwrint = EQU2D_CLIP;
 
r = pwrint;
 
if (pwrint< 64) g = pwrint * 4;
else if (pwrint<128) g = (128-pwrint) * 4;
else g = 0;
 
if (pwrint<128) b = 0;
else if (pwrint<192) b = (pwrint-128) * 4;
else b = (256-pwrint) * 4;
 
SHORT_CRITICAL_SECTIONS(y);
grx_plot(EQU2D_X+x,y,rgb16(r,g,b));
}
 
x = (x+1) % EQU2D_WIDTH;
grx_line(EQU2D_X+x,EQU2D_Y,EQU2D_X+x,EQU2D_Y+EQU2D_NSAMPLES,white);
 
sem_post(&mutex);
 
cab_unget(cab_pwrdata,(char *)p);
 
task_endcycle();
}
}
 
TASK prova_task()
{
window *p;
 
while(1)
{
p = (window *)cab_getmes(cab_windata);
cprintf("%d %d %d\t", p->start /*sample[0]*/,p->sample[1],p->sample[2]);
cab_unget(cab_windata,(char *)p);
 
task_endcycle();
}
}
 
 
void scenario(int f)
{
int i,y;
char s[6];
 
grx_line(0,WAVE_Y-WAVE_HEIGHT-1,1023,WAVE_Y-WAVE_HEIGHT-1,red);
grx_line(0,WAVE_Y+WAVE_HEIGHT+1,1023,WAVE_Y+WAVE_HEIGHT+1,red);
grx_line(0,EQU_Y-11 ,1023,EQU_Y-11 ,red);
 
 
 
/* lines near the frequencies */
grx_line(EQU_X +1,EQU_Y,EQU_X +1,EQU_Y+EQU_NSAMPLES,red);
grx_line(EQU2D_X-1,EQU_Y,EQU2D_X-1,EQU_Y+EQU_NSAMPLES,red);
 
for (i=0; i<SCENARIO_NLABEL; i++)
{
y = (i*EQU_NSAMPLES)/(SCENARIO_NLABEL-1);
if (i == SCENARIO_NLABEL-1) y--;
grx_line(EQU_X +1,EQU_Y+y,EQU_X +10,EQU_Y+y,red);
grx_line(EQU2D_X-1,EQU_Y+y,EQU2D_X-10,EQU_Y+y,red);
 
itoa((i*f)/(SCENARIO_NLABEL-1),s);
grx_text(s,EQU_X+20,EQU_Y+y-8,white,black);
}
 
grx_text("FFTPlay 1.0 - by Paolo Gai 1999 <pj@hartik.sssup.it>", 0,8, rgb16(0,255,0), black );
grx_text("...press ENTER key to exit..." , 0,24, rgb16(0,255,0), black );
 
grx_text("FFT Power Spectrum", 0 , EQU_Y-21, rgb16(0,0,255), black);
grx_text("FFT Power Story", EQU2D_X+16, EQU_Y-21, rgb16(0,0,255), black);
grx_text("Waveform" , 0, WAVE_Y-WAVE_HEIGHT-10, rgb16(0,0,255), black);
 
}
 
 
 
 
void compute_params(int *freq,WORD *nsamp, WORD *per)
{
if (*freq< 2000)
{
cprintf("WARNING: frequency less than 2000Hz\n ---> frequency set to 2000Hz\n");
*freq = 2000;
}
if (*freq<= 8000) { *nsamp = 128; *per = 10; return; }
if (*freq<=16000) { *nsamp = 256; *per = 10; return; }
if (*freq<=24000) { *nsamp = 512; *per = 10; return; }
if (*freq>48000)
{
cprintf("WARNING: frequency greather than 48000Hz\n ---> frequency set to 48000Hz\n");
*freq = 48000;
}
if (*freq<=48000) { *nsamp = 1024;*per = 10; return; }
}
 
 
 
void my_close(void *arg)
{
grx_close();
}
 
 
void endfun(KEY_EVT *k)
{
cprintf("Ctrl-Brk pressed! Ending...\n");
sys_end();
}
 
int main(int argc, char **argv)
{
int modenum;
 
int f;
 
/* irq period... */
WORD period;
 
KEY_EVT k;
 
SOFT_TASK_MODEL m3, m4, m5, m6;
 
PID p3,p4,p5,p6;
 
version();
 
if (argc == 1)
{
cprintf("type x fftplay <freq>");
return 0;
}
 
f = atoi(argv[1]);
compute_params(&f,&rawdata_nsamples,&period);
 
keyb_set_map(itaMap);
k.flag = CNTR_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,endfun);
k.flag = CNTL_BIT;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k,endfun);
 
cab_windata = cab_create("windata", sizeof(window), 4);
cab_pwrdata = cab_create("pwr", sizeof(power), 4);
 
/* Init the sound lib */
sound_init((rawdata_nsamples * sizeof(SAMPLE)), NULL);
sound_info();
 
/* Init the data used by the raw_infun */
init_rawdata();
 
/* Start the self-buffering sampling operation */
sound_setfun(raw_infun, (int (*)(void *))-1);
sound_sample(NULL, f, 0, DMA_OP | PCM16 | MYFUN, NULL);
 
cprintf("Press Enter...");
while (keyb_getchar() != 13);
 
sys_atrunlevel(my_close, NULL, RUNLEVEL_BEFORE_EXIT);
 
#if !defined(NO_GRX)
grx_init();
modenum = grx_getmode(1024, 768, 16);
grx_setmode(modenum);
 
/* init the graphic mutex */
sem_init(&mutex, 0, 1);
 
/* useful colors ... */
white = rgb16(255,255,255);
black = rgb16(0,0,0);
red = rgb16(255,0,0);
 
scenario(f/2);
 
#endif
 
#if !defined(NO_GRX)
soft_task_default_model(m3);
soft_task_def_period(m3, PERIOD_WAVE);
soft_task_def_met(m3, WCET_WAVE);
soft_task_def_group(m3, 1);
p3 = task_create("wave", wave_task, &m3, NULL);
if (p3 == -1) {
perror("FFTPlay: Could not create task <wave>\n");
sys_end();
}
#endif
 
soft_task_default_model(m4);
soft_task_def_period(m4, PERIOD_FFT);
soft_task_def_met(m4, WCET_FFT);
soft_task_def_group(m4, 1);
soft_task_def_stack(m4,32*1024);
soft_task_def_usemath(m4);
p4 = task_create("fft", fft_task, &m4, NULL);
if (p4 == -1) {
perror("FFTPlay: Could not create task <fft>\n");
sys_end();
}
 
#if !defined(NO_GRX)
soft_task_default_model(m5);
soft_task_def_period(m5, PERIOD_EQU);
soft_task_def_met(m5, WCET_EQU);
soft_task_def_group(m5, 1);
soft_task_def_stack(m5,32*1024);
soft_task_def_usemath(m5);
p5 = task_create("equ", equ_task, &m5, NULL);
if (p5 == -1) {
perror("FFTPlay: Could not create task <equ>\n");
sys_end();
}
#endif
 
#if !defined(NO_GRX)
soft_task_default_model(m6);
soft_task_def_period(m6, PERIOD_EQU2D);
soft_task_def_met(m6, WCET_EQU2D);
soft_task_def_group(m6, 1);
soft_task_def_stack(m6,32*1024);
soft_task_def_usemath(m6);
p6 = task_create("equ2D", equ2d_task, &m5, NULL);
if (p6 == -1) {
perror("FFTPlay: Could not create task <equ2D>\n");
sys_end();
}
#else
/* Start the prova task */
//task_def_wcet(m6,1000);
//task_activate(task_create("prova",prova_task,TASK_TYPE,PERIODIC,200,&m6));
#endif
 
group_activate(1);
 
/* Wait until the user get bored */
while (keyb_getchar() != 13);
 
sys_end();
 
return 0;
}
 
 
/unsupported/branches/unsupported/thdemo/jetctrl.c
0,0 → 1,200
// JetControl
 
#include "demo.h"
#include "kernel/func.h"
 
TASK jetdummy_task(void *arg)
{
TIME now_dummy, last_dummy, diff_dummy, slice;
struct timespec now, last, diff;
int x = 0;
int height;
 
NULL_TIMESPEC(&last);
last_dummy = 0;
for (;;) {
task_nopreempt();
jet_getstat(DUMMY_PID, NULL, NULL, NULL, &now_dummy);
sys_gettime(&now);
task_preempt();
 
SUBTIMESPEC(&now, &last, &diff);
slice = diff.tv_sec * 1000000 + diff.tv_nsec/1000;
diff_dummy = now_dummy - last_dummy;
 
height = (int)(JET_DUMMY_HEIGHT*((float)diff_dummy)/((float)slice));
 
TIMESPEC_ASSIGN(&last, &now);
last_dummy = now_dummy;
 
mutex_lock(&mutex);
grx_line(JET_DUMMY_X+x,JET_DUMMY_Y,
JET_DUMMY_X+x,JET_DUMMY_Y+height ,black);
grx_line(JET_DUMMY_X+x,JET_DUMMY_Y+height,
JET_DUMMY_X+x,JET_DUMMY_Y+JET_DUMMY_HEIGHT,white);
grx_line(JET_DUMMY_X+(x+1)%JET_DUMMY_WIDTH,JET_DUMMY_Y,
JET_DUMMY_X+(x+1)%JET_DUMMY_WIDTH,JET_DUMMY_Y+JET_DUMMY_HEIGHT,255);
mutex_unlock(&mutex);
 
x = (x+1)%JET_DUMMY_WIDTH;
 
task_endcycle();
}
}
 
 
TASK jetctrl_task(void *arg)
{
char st[50];
TIME sum, max;
int n;
 
PID i;
int printed = 0;
 
for (;;) {
for (i=2, printed=0; i<MAX_PROC && printed<JET_NTASK; i++) {
if (jet_getstat(i, &sum, &max, &n, NULL) != -1) {
if (!n) n=1;
sprintf(st, "%6d %6d %10s", (int)sum/n, (int)max, proc_table[i].name);
mutex_lock(&mutex);
grx_text(st, 384, JET_Y_NAME+16+printed*8, gray, black);
mutex_unlock(&mutex);
printed++;
}
}
while (printed<JET_NTASK) {
mutex_lock(&mutex);
grx_text(" ",
384, JET_Y_NAME+16+printed*8, gray, black);
mutex_unlock(&mutex);
printed++;
}
task_endcycle();
}
}
 
TASK jetslide_task(void *arg)
{
TIME sum, curr, max;
 
TIME total[JET_NTASK];
int slides[JET_NTASK];
 
PID i;
int printed = 0;
 
for (;;) {
// Fill the total array in a nonpreemptive section
task_nopreempt();
for (i=2, printed=0; i<MAX_PROC && printed<JET_NTASK; i++) {
if (jet_getstat(i, &sum, NULL, NULL, &curr) != -1) {
total[printed] = sum+curr;
printed++;
}
}
task_preempt();
 
while (printed < JET_NTASK)
total[printed++] = 0;
 
// Compute the Max elapsed time
max = 0;
for (i=0; i<JET_NTASK; i++)
if (total[i] > max) max = total[i];
if (!max) max = 1;
 
// Compute the slides width
for (i=0; i<JET_NTASK; i++)
slides[i] = (int)( (((float)total[i])/max) * JET_SLIDE_WIDTH);
 
// print the data
mutex_lock(&mutex);
for (i=0; i<JET_NTASK; i++) {
grx_box(JET_SLIDE_X, JET_Y_NAME+16+i*8,
JET_SLIDE_X+slides[i], JET_Y_NAME+23+i*8, gray);
grx_box(JET_SLIDE_X+slides[i], JET_Y_NAME+16+i*8,
JET_SLIDE_X+JET_SLIDE_WIDTH, JET_Y_NAME+23+i*8, black);
}
 
while (i<JET_NTASK) {
grx_box(JET_SLIDE_X, JET_Y_NAME+16+i*8,
JET_SLIDE_X+JET_SLIDE_WIDTH, JET_Y_NAME+20+i*8, black);
i++;
}
mutex_unlock(&mutex);
task_endcycle();
}
}
 
 
void scenario_jetcontrol(void)
{
grx_text("System load" , 384, 248, rgb16(0,0,255), black);
grx_line(384,258,639,258,red);
 
grx_text(" Mean Max Name Slide", 384, JET_Y_NAME, gray, black);
grx_line(384,JET_Y_NAME+10,639,JET_Y_NAME+10,gray);
 
grx_rect(JET_DUMMY_X-1, JET_DUMMY_Y-1,
JET_DUMMY_X+JET_DUMMY_WIDTH, JET_DUMMY_Y+JET_DUMMY_HEIGHT+1, gray);
 
grx_text("100%", JET_DUMMY_X-40, JET_DUMMY_Y, gray, black);
grx_text(" 0%", JET_DUMMY_X-40, JET_DUMMY_Y+JET_DUMMY_HEIGHT-8, gray, black);
 
grx_line(JET_DUMMY_X-1, JET_DUMMY_Y, JET_DUMMY_X-5, JET_DUMMY_Y, gray);
grx_line(JET_DUMMY_X-1, JET_DUMMY_Y+JET_DUMMY_HEIGHT, JET_DUMMY_X-5, JET_DUMMY_Y+JET_DUMMY_HEIGHT, gray);
grx_line(384,258,639,258,red);
}
 
void init_jetcontrol(void)
{
SOFT_TASK_MODEL m3, m4, m5;
 
PID p3, p4, p5;
 
soft_task_default_model(m3);
soft_task_def_level(m3,1);
soft_task_def_period(m3, PERIOD_JETCTRL);
soft_task_def_met(m3, WCET_JETCTRL);
soft_task_def_ctrl_jet(m3);
soft_task_def_group(m3, 1);
p3 = task_create("jctrl", jetctrl_task, &m3, NULL);
if (p3 == -1) {
grx_close();
perror("FFTPlay: Could not create task <jetctrl>\n");
ll_abort(54);
sys_end();
}
 
soft_task_default_model(m4);
soft_task_def_level(m4,1);
soft_task_def_period(m4, PERIOD_JETDUMMY);
soft_task_def_met(m4, WCET_JETDUMMY);
soft_task_def_group(m4, 1);
soft_task_def_usemath(m4);
soft_task_def_ctrl_jet(m4);
p4 = task_create("jdmy", jetdummy_task, &m4, NULL);
if (p4 == -1) {
grx_close();
perror("FFTPlay: Could not create task <jetdummy>\n");
ll_abort(54);
sys_end();
}
 
soft_task_default_model(m5);
soft_task_def_level(m5,1);
soft_task_def_period(m5, PERIOD_JETSLIDE);
soft_task_def_met(m5, WCET_JETSLIDE);
soft_task_def_group(m5, 1);
soft_task_def_usemath(m5);
soft_task_def_ctrl_jet(m5);
p5 = task_create("jsli", jetslide_task, &m5, NULL);
if (p5 == -1) {
grx_close();
perror("FFTPlay: Could not create task <jetslide>\n");
ll_abort(54);
sys_end();
}
}
 
/unsupported/branches/unsupported/thdemo/camera.c
0,0 → 1,516
// framegrabber stuffs
 
/* File name ......... : ELABOR.C
* Project............ :
* Object ............ :
* Author ............ : Facchinetti Tullio
* Language .......... : C
* Compiler .......... : GNU C
* Operative system .. : MS-DOS/HARTIK
* Creation data ..... : 04/03/2000
* Last modify ....... : 19/11/99
*/
 
 
 
 
#include <kernel/func.h>
#include <modules/cabs.h>
#include <stdio.h>
#include <drivers/pxc.h>
#include "demo.h"
 
PID camera_PID;
PID tracking_PID;
 
static CAB frameCAB; // CAB di deposito delle immagini
static CAB trackingCAB; // CAB di deposito delle info di tracking
 
 
int img_border = 10;
int window_width = 40;
int window_height = 40;
TPixel pix_threshold = 128;
 
// a 256 grayscale palette
WORD gray_palette[256];
 
// the image to be putted on the screen
WORD converted_image[IMG_COL*IMG_ROW];
 
TDataObj sequence[N_FRAMES];
 
 
 
void border_up_function(KEY_EVT key)
{
img_border++;
}
 
void border_down_function(KEY_EVT key)
{
img_border--;
}
 
void threshold_up_function(KEY_EVT key)
{
char st[50];
pix_threshold++;
sprintf(st, "threshold %4d", pix_threshold);
mutex_lock(&mutex);
grx_text(st, 400, 100, 255, 0);
mutex_unlock(&mutex);
}
 
void threshold_down_function(KEY_EVT key)
{
char st[50];
pix_threshold--;
sprintf(st, "threshold %4d", pix_threshold);
mutex_lock(&mutex);
grx_text(st, 400, 100, 255, 0);
mutex_unlock(&mutex);
}
 
float distance(unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2)
{
return(sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1))));
}
 
char scan_window_frame(TDataObj *data, TPixel *in_frame,
unsigned int xc, unsigned int yc, int border)
{
unsigned long int offset;
unsigned int i, j;
TPixel pix;
double sum_x = 0.0, sum_y = 0.0;
unsigned int n_pix = 0;
int x1, y1, x2, y2; // Must be int!!!
char found;
 
data->x1 = N_COL;
data->y1 = N_ROW;
data->x2 = data->y2 = 0;
data->xb = data->yb = -1;
data->time_stamp = -1;
 
found = 0;
 
x1 = MAX_NUM((xc - window_width / 2), (border));
y1 = MAX_NUM((yc - window_height / 2), (border));
x2 = MIN_NUM((xc + window_width / 2), (N_COL - border));
y2 = MIN_NUM((yc + window_height / 2), (N_ROW - border));
 
for (i = y1; i < y2; i++) {
for (j = x1; j < x2; j++) {
offset = i * N_COL + j;
pix = *(in_frame + offset);
 
#ifdef __BLACK_ON_WHITE
// Pixel found (object is black, background is white)
if (pix < pix_threshold) {
#else
// Pixel found (object is white, background is black)
if (pix > pix_threshold) {
#endif
data->time_stamp = sys_gettime(NULL);
found = 1;
n_pix++;
sum_x += j;
sum_y += i;
// *(in_frame + offset) = 0;
if (i < data->y1)
data->y1 = i;
if (i > data->y2)
data->y2 = i;
if (j < data->x1)
data->x1 = j;
if (j > data->x2)
data->x2 = j;
 
} else {
// *(in_frame + offset) = 255;
}
}
}
data->xb = sum_x / n_pix;
data->yb = sum_y / n_pix;
return(found);
}
 
char scan_all_frame(TDataObj *data, TPixel *in_frame)
{
unsigned long int offset;
unsigned int i, j;
TPixel pix;
double sum_x = 0.0, sum_y = 0.0;
unsigned int n_pix = 0;
char found;
 
data->x1 = N_COL;
data->y1 = N_ROW;
data->x2 = data->y2 = 0;
data->xb = data->yb = -1;
data->time_stamp = -1;
 
found = 0;
 
// In a single image scanning it performs thresholding and computation
for (i = img_border; i < N_ROW - img_border; i++) {
for (j = img_border; j < N_COL - img_border; j++) {
offset = i * N_COL + j;
pix = *(in_frame + offset);
 
#ifdef __BLACK_ON_WHITE
// Pixel found (object is black, background is white)
if (pix < pix_threshold) {
#else
// Pixel found (object is white, background is black)
if (pix > pix_threshold) {
#endif
data->time_stamp = sys_gettime(NULL);
found = 1;
n_pix++;
sum_x += j;
sum_y += i;
// *(in_frame + offset) = 0;
if (i < data->y1)
data->y1 = i;
if (i > data->y2)
data->y2 = i;
if (j < data->x1)
data->x1 = j;
if (j > data->x2)
data->x2 = j;
 
} else {
// *(in_frame + offset) = 255;
}
}
}
data->xb = sum_x / n_pix;
data->yb = sum_y / n_pix;
return(found);
}
 
void tracking(int top_frame, int *track_x, int *track_y, int *int_vx, int *int_vy, int time_to)
{
float vx, vy;
 
vx = (float)(sequence[top_frame - 1].xb - sequence[top_frame - 2].xb) /
(float)(sequence[top_frame - 1].time_stamp - sequence[top_frame - 2].time_stamp);
vx *= 1000;
 
vy = (float)(sequence[top_frame - 1].yb - sequence[top_frame - 2].yb) /
(float)(sequence[top_frame - 1].time_stamp - sequence[top_frame - 2].time_stamp);
vy *= 1000;
 
*track_x = sequence[top_frame - 1].xb + vx * time_to;
*track_y = sequence[top_frame - 1].yb + vy * time_to;
 
*int_vx = vx * 1000;
*int_vy = vy * 1000;
}
 
TASK tracking_task(void *arg)
{
// static unsigned int n_frame = 0;
char found;
TPixel *grabber_frame;
int top_frame = 0;
TDataObj current;
TTracking *track;
 
frameCAB = PXC_GetCab();
 
grabber_frame = cab_getmes(frameCAB);
 
// Executes first time
found = scan_all_frame(&current, grabber_frame);
if (found) {
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
top_frame++;
}
 
cab_unget(frameCAB, grabber_frame);
 
task_endcycle();
 
while (1) {
// Acquisizione immagine corrente
grabber_frame = (TPixel *)cab_getmes(frameCAB);
track = (TTracking *)cab_reserve(trackingCAB);
 
// Estrazione della nuova trasformata sul frame corrente
if (found) {
found = scan_window_frame(&current, grabber_frame, current.xb, current.yb, img_border);
} else {
found = scan_all_frame(&current, grabber_frame);
}
 
track->found = found;
 
if (found) {
if (top_frame < N_FRAMES) {
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
top_frame++;
} else {
top_frame = 0;
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
}
 
track->top_frame = top_frame;
memcpy(&track->current, &current, sizeof(TDataObj));
 
if (top_frame > 1) {
tracking(top_frame, &track->predx, &track->predy,
&track->vx, &track->vy, 100);
}
} else {
track->top_frame = top_frame = 0;
}
 
// Release CABs
cab_putmes(trackingCAB, (char *)track);
cab_unget(frameCAB, grabber_frame);
 
task_endcycle();
}
}
 
 
 
 
 
 
 
/*
*
*
*
* Camera task
*
*
*
*
*/
 
 
TASK camera_task(void *arg)
{
register int i,j,col,row;
static unsigned int n_frame = 0;
TPixel *grabber_frame;
TTracking *track;
char st[50];
 
// Inizializzazione del task
frameCAB = PXC_GetCab();
 
while (1) {
n_frame++;
sprintf(st, "frame n. %5d", n_frame);
 
grx_text(st, 400, 224, white, 0);
 
// Acquisizione immagine corrente
grabber_frame = cab_getmes(frameCAB);
 
for (i=1; i<IMG_ROW-1; i++)
for (j=0; j<IMG_COL; j++) {
col = (j*(N_COL-1))/(IMG_COL-1);
row = (i*(N_ROW-1))/(IMG_ROW-1);
converted_image[i*IMG_COL+j] = gray_palette[*(grabber_frame+row*N_COL+col)];
}
 
// Release CAB
cab_unget(frameCAB, grabber_frame);
 
for (j=0; j<IMG_COL; j++) {
converted_image[j] = gray_palette[0];
converted_image[(IMG_ROW-1)*IMG_COL+j] = gray_palette[0];
}
 
mutex_lock(&mutex);
grx_putimage(IMG_X, IMG_Y, IMG_X+IMG_COL-1, IMG_Y+IMG_ROW-1,
(BYTE *)converted_image);
mutex_unlock(&mutex);
 
track = (TTracking *)cab_getmes(trackingCAB);
 
if (track->found) {
mutex_lock(&mutex);
// sprintf(st, "found: %d", track->found);
// grx_text(st, 400, 280, 255, 0);
 
if (track->top_frame > 1) {
int px, py;
 
// sprintf(st, "top_frame %5d", track->top_frame);
// grx_text(st, 400, 270, 255, 0);
 
if (track->predx < img_border)
px = img_border;
else if (track->predx > N_COL-img_border)
px = N_COL-img_border;
else
px = track->predx;
 
if (track->predy < img_border)
py = img_border;
else if (track->predy > N_ROW-img_border)
py = N_ROW-img_border;
else
py = track->predy;
 
grx_disc(IMG_X+(px*2)/3, IMG_Y+(py*2)/3, 3, 127);
 
// grx_disc(IMG_X+(current.xb*2)/3, IMG_Y+(current.yb*2)/3, 3, 127);
grx_rect(IMG_X+(track->current.x1*2)/3, IMG_Y+(track->current.y1*2)/3,
IMG_X+(track->current.x2*2)/3, IMG_Y+(track->current.y2*2)/3, 127);
 
sprintf(st, "speed = (%5d, %5d) pix/s", track->vx, track->vy);
grx_text(st, 400, 232, white, 0);
}
mutex_unlock(&mutex);
}
cab_unget(trackingCAB, (char *)track);
 
task_endcycle();
}
}
 
 
 
 
 
/*
*
*
*
* Framegrabber Initialization
*
*
*
*
*/
 
void start_listener(TIME p);
 
void framegrabber_close(void *arg)
{
PXC_Close();
}
 
void scenario_framegrabber()
{
grx_text("Camera" , 384, WAVE_Y-WAVE_HEIGHT-10, rgb16(0,0,255), black);
grx_line(384,WAVE_Y-WAVE_HEIGHT-1,639,WAVE_Y-WAVE_HEIGHT-1,red);
}
 
void init_framegrabber(void)
{
register int i;
KEY_EVT my_key;
TIME period;
 
my_key.ascii = 'a';
my_key.scan = KEY_A;
keyb_hook(my_key, (void (*)(KEY_EVT *))threshold_up_function);
 
my_key.ascii = 'z';
my_key.scan = KEY_Z;
keyb_hook(my_key, (void (*)(KEY_EVT *))threshold_down_function);
 
my_key.ascii = 's';
my_key.scan = KEY_S;
keyb_hook(my_key, (void (*)(KEY_EVT *))border_up_function);
 
my_key.ascii = 'x';
my_key.scan = KEY_X;
keyb_hook(my_key, (void (*)(KEY_EVT *))border_down_function);
 
// Aggiusta la palette
for (i = 0; i < 256; i++)
gray_palette[i] = rgb16(i,i,i);
//for (i = 0; i < 256; i++)
// grx_setcolor(i, i/4, i/4, i/4);
 
mutex_lock(&mutex);
// grx_text("Grabber enabled: no test!", 10, 10, 255, 0);
 
// Some messages on screen
// grx_text("A-Z change threshold", 400, 240, 255, 0);
// grx_text("S-X change window borders", 400, 250, 255, 0);
mutex_unlock(&mutex);
 
period = PXC_Initiate(4);
 
if (!period) {
grx_close();
cprintf("Problemi nell'inizializzazione del framegrabber\n");
halt();
sys_end();
} else {
TTracking *trdata;
// tracking CAB init
trackingCAB = cab_create("trackingCAB", sizeof(TTracking), 3);
trdata = (TTracking *)cab_reserve(trackingCAB);
trdata->found = 0;
cab_putmes(trackingCAB, (char *)trdata);
 
start_listener(period);
}
 
sys_atrunlevel(framegrabber_close, NULL, RUNLEVEL_BEFORE_EXIT);
}
 
 
void start_listener(TIME period)
{
SOFT_TASK_MODEL m1, m2;
 
soft_task_default_model(m1);
soft_task_def_level(m1,1);
soft_task_def_met(m1,WCET_TRACKING);
soft_task_def_usemath(m1);
// soft_task_def_aperiodic(m1);
soft_task_def_period(m1,(PERIOD_TRACKING));
soft_task_def_group(m1,1);
soft_task_def_ctrl_jet(m1);
soft_task_def_skip_arrivals(m1);
tracking_PID = task_create("track", tracking_task, &m1, NULL);
if (tracking_PID == -1) {
grx_close();
perror("FFTPlay: Could not create task <tra>\n");
ll_abort(54);
perror("FFTPlay: Could not create task <tracking>\n");
sys_end();
}
 
soft_task_default_model(m2);
soft_task_def_level(m2,1);
soft_task_def_met(m2,WCET_CAMERA);
soft_task_def_usemath(m2);
// soft_task_def_aperiodic(m2);
soft_task_def_period(m2,PERIOD_CAMERA);
soft_task_def_group(m2,1);
soft_task_def_ctrl_jet(m2);
// soft_task_def_skip_arrivals(m2);
camera_PID = task_create("cam", camera_task, &m2, NULL);
if (camera_PID == -1) {
grx_close();
perror("FFTPlay: Could not create task <came>\n");
ll_abort(54);
perror("FFTPlay: Could not create task <camera>\n");
sys_end();
}
 
}
 
void start_framegrabber()
{
// PXC_Push_Listener(tracking_PID,2);
PXC_Start();
}
/unsupported/branches/unsupported/thdemo/demo.h
0,0 → 1,280
 
 
#include <ll/ll.h>
#include <kernel/types.h>
#include <kernel/descr.h>
#include <math.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
 
 
#define FFT_ON
#define FRAMEGRABBER_ON
#define JET_ON
#define BALL_ON
 
/*
*
* WCET, Periods and Models
*
*/
 
 
/* define if you want NRT or SOFT... */
#define TASK_TYPE SOFT
//#define TASK_TYPE NRT
 
// on Celeron 366
#define WCET_WAVE 450
#define WCET_FFT 722
#define WCET_EQU 1000
#define WCET_EQU2D 318
 
#define PERIOD_WAVE 40000
#define PERIOD_FFT 3000
#define PERIOD_EQU 40000
#define PERIOD_EQU2D 3000
 
 
 
 
#define WCET_TRACKING 4000
#define WCET_CAMERA 7000
 
#define PERIOD_TRACKING 40000
#define PERIOD_CAMERA 40000
 
 
#define WCET_JETCTRL 2600
#define WCET_JETDUMMY 1000
#define WCET_JETSLIDE 1000
 
#define PERIOD_JETCTRL 100000
#define PERIOD_JETDUMMY 100000
#define PERIOD_JETSLIDE 100000
 
 
#define WCET_BALL 60
 
#define PERIOD_BALL 10000
 
 
/*
*
* Soundcard related defines
*
*/
 
 
/* Samples are 16-bit signed integers */
typedef short SAMPLE;
#define MAX_SAMPLE 32768
 
 
 
/*
*
* FFT defines
*
*/
 
/* Numbers of samples of the sample window */
#define WINDATA_NSAMPLES 512
 
/* task WAVE */
/* the point (wave_x,wave_y) is on the center left of the area... */
#define WAVE_NSAMPLES 384
#define WAVE_X 0
#define WAVE_Y 64
#define WAVE_HEIGHT 32
 
/* task FFT */
#define FFT_NSAMPLES 512
#define PWR_NSAMPLES (FFT_NSAMPLES/2+1)
 
/* task EQU */
/* the point (equ_x, equ_y) is the top right corner */
#define EQU_NSAMPLES PWR_NSAMPLES
#define EQU_X 64
#define EQU_Y 128
#define EQU_HEIGHT 64
#define EQU_SHADE
 
/* task EQU2D */
/* the point (equ2d_x, equ2d_y) is the top left corner */
#define EQU2D_NSAMPLES EQU_NSAMPLES
#define EQU2D_X 128
#define EQU2D_Y EQU_Y
#define EQU2D_WIDTH 255
#define EQU2D_CLIP 255
 
/* scenario */
#define SCENARIO_NLABEL 16
 
/* Scale factors */
#define FFT_SCALE (16384.0)
#define EQU_SCALE (32.0)
#define EQU2D_SCALE (8.0)
//#define EQU_SCALE (64.0)
//#define EQU2D_SCALE (16.0)
 
 
 
/* Informations about the sampling rate and buffers */
extern WORD rawdata_nsamples;
extern WORD rawdata_buffer_size;
extern WORD rawdata_freq;
 
 
 
/*
*
* Global Stuffs
*
*/
 
/* graphic mutex... */
extern mutex_t mutex;
 
/* useful colors... */
extern int white;
extern int black;
extern int red;
extern int gray;
 
/* define if shorts critical sections wanted */
#define SHORT_CRITICAL_SECTIONS(x) \
if (!((x)%64)) \
{ \
mutex_lock(&mutex); \
mutex_unlock(&mutex); \
}
 
void init_fftplay(int freq);
void init_framegrabber();
void init_jetcontrol();
void init_ball(void);
void start_framegrabber();
 
 
void scenario_jetcontrol(void);
void scenario_fftplay(int f);
void scenario_framegrabber();
void scenario_ball();
 
void compute_params(int *freq,WORD *nsamp);
 
char * itoa(int n, char *s);
 
/*
*
* Framegrabber stuffs
*
*/
 
// if defined... object black on a white background
#ifndef __BLACK_ON_WHITE
#define __BLACK_ON_WHITE
#endif
 
#define ABS_NUM(a) ((a >= 0) ? a : -a)
#define MIN_NUM(a, b) ((a < b) ? a : b)
#define MAX_NUM(a, b) ((a > b) ? a : b)
 
 
// Cols and rows of the framegrabber image
#define N_COL 384
#define N_ROW 288
#define N_BPS 8 // Bits per pixel
#define N_GRIGI 256
 
#define N_FRAMES 100
 
/* pixel of the video image */
#define IMG_COL 256
#define IMG_ROW 192
 
/* position of the video image */
#define IMG_X 384
#define IMG_Y 32
 
// I singoli pixel sono caratteri a 8 bit
typedef unsigned char TPixel;
 
typedef struct {
int x1, y1;
int x2, y2;
int xb, yb;
TIME time_stamp;
} TDataObj;
 
typedef struct {
int found;
int top_frame;
int vx,vy;
int predx;
int predy;
TDataObj current;
} TTracking;
 
 
float distance(unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2);
 
char scan_all_frame(TDataObj *data, TPixel *in_frame);
 
char scan_window_frame(TDataObj *data, TPixel *in_frame,
unsigned int xc, unsigned int yc, int border);
 
void threshold_up_function(KEY_EVT key);
void threshold_down_function(KEY_EVT key);
 
void border_up_function(KEY_EVT key);
void border_down_function(KEY_EVT key);
 
void tracking(int top_frame, int *track_x, int *track_y, int *int_vx, int *int_vy, int time_to);
 
TASK elab_image_TASK(void);
 
 
 
/*
*
* JETCONTROL stuffs
*
*/
 
#define JET_NTASK 18
#define JET_Y_NAME 320
 
#define DUMMY_PID 1
 
#define JET_DUMMY_WIDTH 210
#define JET_DUMMY_HEIGHT 40
 
/* the point (x, y) is the top left corner */
#define JET_DUMMY_X 428
#define JET_DUMMY_Y 264
 
#define JET_SLIDE_WIDTH 50
#define JET_SLIDE_X 576
 
 
 
 
/*
*
* BALL stuffs
*
*/
 
// x and y corners are specified whithout consider a border of 3 pixels
#define BALL_Y 475 /* position of the floor */
#define BALL_HEIGHT 70 /* initial height of the ball */
#define BALL_XMIN 3 /* min position X of the ball */
#define BALL_XMAX 380 /* max position X of the ball */
#define BALL_VELX 5. /* horizontal ball velocity */
#define BALL_VYMIN 11. /* velocit… minima per suono */
#define BALL_MAX_P 50 /* max number of balls */
 
#define BALL_GROUP 2 /* task group of the balls */
/unsupported/branches/unsupported/thdemo/readme.txt
0,0 → 1,17
PJ's Thesis demo
----------------
 
This is my Thesis Demo. The demo works correctly on my PC :-)
(a celeron 366 Mhz), Probably It will have some problems with other slower PCs.
 
The demo simply reads data from the soundblaster, then print the sound wave, compute a power spectrun and display it on the screen.
 
Then there is another few tasks that reads data from a framegrabber and track a black image on a white board.
 
Moreover, there are some noise balls to test the system in overload conditions, and there are finally a few tasks that displays the system load.
 
If you have any problems using this demo, please contact pj@sssup.it
 
bye
 
Paolo
/unsupported/branches/unsupported/thdemo/camera2.c
0,0 → 1,424
// framegrabber stuffs
 
/* File name ......... : ELABOR.C
* Project............ :
* Object ............ :
* Author ............ : Facchinetti Tullio
* Language .......... : C
* Compiler .......... : GNU C
* Operative system .. : MS-DOS/HARTIK
* Creation data ..... : 04/03/2000
* Last modify ....... : 19/11/99
*/
 
 
 
 
#include <kernel/func.h>
#include <modules/cabs.h>
#include <stdio.h>
#include <drivers/pxc.h>
#include "demo.h"
 
PID image_elab_PID;
TIME periodo;
CAB PXC_CAB;
 
static CAB frameCAB; // CAB di deposito delle immagini
static TDataObj current, older;
 
// extern in INIT.C
int img_border = 10;
int window_width = 40;
int window_height = 40;
 
// a 256 grayscale palette
WORD gray_palette[256];
 
// the image to be putted on the screen
WORD converted_image[IMG_COL*IMG_ROW];
 
 
#ifdef __BLACK_ON_WHITE
TPixel pix_threshold = 64;
#else
TPixel pix_threshold = 243;
#endif
 
 
// Global for testing!!!
static char st[50];
TIME before;
 
TDataObj sequence[N_FRAMES];
int top_frame = 0;
 
double dist, speed;
 
static TPixel *grabber_frame;
 
void border_up_function(KEY_EVT key)
{
img_border++;
}
 
void border_down_function(KEY_EVT key)
{
img_border--;
}
 
void threshold_up_function(KEY_EVT key)
{
pix_threshold++;
sprintf(st, "threshold %4d", pix_threshold);
mutex_lock(&mutex);
//grx_text(st, 400, 300, 255, 0);
mutex_unlock(&mutex);
}
 
void threshold_down_function(KEY_EVT key)
{
pix_threshold--;
sprintf(st, "threshold %4d", pix_threshold);
mutex_lock(&mutex);
//grx_text(st, 400, 300, 255, 0);
mutex_unlock(&mutex);
}
 
float distance(unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2)
{
return(sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1))));
}
 
char scan_window_frame(TDataObj *data, TPixel *in_frame,
unsigned int xc, unsigned int yc, int border)
{
unsigned long int offset;
unsigned int i, j;
TPixel pix;
double sum_x = 0.0, sum_y = 0.0;
unsigned int n_pix = 0;
int x1, y1, x2, y2; // Must be int!!!
char found;
 
data->x1 = N_COL;
data->y1 = N_ROW;
data->x2 = data->y2 = 0;
data->xb = data->yb = -1;
data->time_stamp = -1;
 
found = 0;
 
x1 = MAX_NUM((xc - window_width / 2), (border));
y1 = MAX_NUM((yc - window_height / 2), (border));
x2 = MIN_NUM((xc + window_width / 2), (N_COL - border));
y2 = MIN_NUM((yc + window_height / 2), (N_ROW - border));
 
for (i = y1; i < y2; i++) {
for (j = x1; j < x2; j++) {
offset = i * N_COL + j;
pix = *(in_frame + offset);
 
#ifdef __BLACK_ON_WHITE
// Pixel found (object is black, background is white)
if (pix < pix_threshold) {
#else
// Pixel found (object is white, background is black)
if (pix > pix_threshold) {
#endif
data->time_stamp = sys_gettime(NULL);
found = 1;
n_pix++;
sum_x += j;
sum_y += i;
*(in_frame + offset) = 0;
if (i < data->y1)
data->y1 = i;
if (i > data->y2)
data->y2 = i;
if (j < data->x1)
data->x1 = j;
if (j > data->x2)
data->x2 = j;
 
} else {
*(in_frame + offset) = 255;
}
}
}
data->xb = sum_x / n_pix;
data->yb = sum_y / n_pix;
return(found);
}
 
char scan_all_frame(TDataObj *data, TPixel *in_frame)
{
unsigned long int offset;
unsigned int i, j;
TPixel pix;
double sum_x = 0.0, sum_y = 0.0;
unsigned int n_pix = 0;
char found;
 
data->x1 = N_COL;
data->y1 = N_ROW;
data->x2 = data->y2 = 0;
data->xb = data->yb = -1;
data->time_stamp = -1;
 
found = 0;
 
// In a single image scanning it performs thresholding and computation
for (i = img_border; i < N_ROW - img_border; i++) {
for (j = img_border; j < N_COL - img_border; j++) {
offset = i * N_COL + j;
pix = *(in_frame + offset);
 
#ifdef __BLACK_ON_WHITE
// Pixel found (object is black, background is white)
if (pix < pix_threshold) {
#else
// Pixel found (object is white, background is black)
if (pix > pix_threshold) {
#endif
data->time_stamp = sys_gettime(NULL);
found = 1;
n_pix++;
sum_x += j;
sum_y += i;
*(in_frame + offset) = 0;
if (i < data->y1)
data->y1 = i;
if (i > data->y2)
data->y2 = i;
if (j < data->x1)
data->x1 = j;
if (j > data->x2)
data->x2 = j;
 
} else {
*(in_frame + offset) = 255;
}
}
}
data->xb = sum_x / n_pix;
data->yb = sum_y / n_pix;
return(found);
}
 
void tracking(int *track_x, int *track_y, int time_to)
{
float vx, vy;
 
vx = (float)(sequence[top_frame - 1].xb - sequence[top_frame - 2].xb) /
(float)(sequence[top_frame - 1].time_stamp - sequence[top_frame - 2].time_stamp);
vx *= 1000000;
 
vy = (float)(sequence[top_frame - 1].yb - sequence[top_frame - 2].yb) /
(float)(sequence[top_frame - 1].time_stamp - sequence[top_frame - 2].time_stamp);
vy *= 1000000;
 
(*track_x) = sequence[top_frame - 1].xb + vx * time_to;
(*track_y) = sequence[top_frame - 1].yb + vy * time_to;
 
sprintf(st, "speed = (%5d, %5d) pix/s", (int)vx, (int)vy);
mutex_lock(&mutex);
//grx_text(st, 400, 410, 255, 0);
mutex_unlock(&mutex);
}
 
void put_frame(TPixel *frame)
{
register int i,j,col,row;
 
for (i=0; i<IMG_ROW; i++)
for (j=0; j<IMG_COL; j++) {
col = (j*(N_COL-1))/(IMG_COL-1);
row = (i*(N_ROW-1))/(IMG_ROW-1);
converted_image[i*IMG_COL+j] = gray_palette[*(frame+row*N_COL+col)];
}
 
mutex_lock(&mutex);
//grx_putimage(IMG_X, IMG_Y, IMG_X+IMG_COL-1, IMG_Y+IMG_ROW-1,
// (BYTE *)converted_image);
mutex_unlock(&mutex);
}
 
 
TASK elab_image_TASK(void)
{
// register int i, j;
static unsigned int n_frame = 0;
char found;
int pred_x, pred_y;
 
// Inizializzazione del task
frameCAB = PXC_GetCab();
 
grabber_frame = cab_getmes(frameCAB);
 
// Executes first time
found = scan_all_frame(&current, grabber_frame);
// found =0;
if (found) {
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
top_frame++;
}
 
cab_unget(frameCAB, grabber_frame);
 
task_endcycle();
 
while (1) {
 
// before = sys_gettime(NULL);
 
n_frame++;
sprintf(st, "frame n. %5d", n_frame);
 
mutex_lock(&mutex);
//grx_text(st, 400, 290, 255, 0);
 
sprintf(st, "top_frame %5d", top_frame);
//grx_text(st, 400, 270, 255, 0);
 
sprintf(st, "found: %d!", found);
//grx_text(st, 400, 280, 255, 0);
mutex_unlock(&mutex);
 
// Acquisizione immagine corrente
grabber_frame = cab_getmes(frameCAB);
 
// copy current in older
memcpy(&older, &current, sizeof(TDataObj));
 
// Estrazione della nuova trasformata sul frame corrente
if (found) {
found = scan_window_frame(&current, grabber_frame, current.xb, current.yb, img_border);
} else {
found = scan_all_frame(&current, grabber_frame);
}
 
// //grx_putimage(0, 0, N_COL - 1, N_ROW - 1, grabber_frame);
put_frame(grabber_frame);
 
if (found) {
if (top_frame < N_FRAMES) {
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
top_frame++;
} else {
top_frame = 0;
memcpy(&sequence[top_frame], &current, sizeof(TDataObj));
}
 
if (top_frame > 1) {
tracking(&pred_x, &pred_y, 100);
 
mutex_lock(&mutex);
// //grx_disc(IMG_X+(pred_x*2)/3, IMG_Y+(pred_y*2)/3, 3, 127);
 
//grx_disc(IMG_X+(current.xb*2)/3, IMG_Y+(current.yb*2)/3, 3, 127);
//grx_rect(IMG_X+(current.x1*2)/3, IMG_Y+(current.y1*2)/3,
// IMG_X+(current.x2*2)/3, IMG_Y+(current.y2*2)/3, 127);
mutex_unlock(&mutex);
 
}
} else {
top_frame = 0;
}
 
// Release CAB
cab_unget(frameCAB, grabber_frame);
 
// sprintf(st, "durata = %3d ms", (int)(sys_gettime(NULL) - before)/1000);
// mutex_lock(&mutex);
// //grx_text(st, 400, 400, 255, 0);
// mutex_unlock(&mutex);
 
task_endcycle();
}
}
 
 
void start_listener(void);
 
void framegrabber_close(void *arg)
{
PXC_Close();
}
 
void init_framegrabber(void)
{
register int i;
KEY_EVT my_key;
 
my_key.ascii = 'a';
my_key.scan = KEY_A;
keyb_hook(my_key, (void (*)(KEY_EVT *))threshold_up_function);
 
my_key.ascii = 'z';
my_key.scan = KEY_Z;
keyb_hook(my_key, (void (*)(KEY_EVT *))threshold_down_function);
 
my_key.ascii = 's';
my_key.scan = KEY_S;
keyb_hook(my_key, (void (*)(KEY_EVT *))border_up_function);
 
my_key.ascii = 'x';
my_key.scan = KEY_X;
keyb_hook(my_key, (void (*)(KEY_EVT *))border_down_function);
 
// Aggiusta la palette
for (i = 0; i < 256; i++)
gray_palette[i] = rgb16(i,i,i);
//for (i = 0; i < 256; i++)
// grx_setcolor(i, i/4, i/4, i/4);
 
mutex_lock(&mutex);
// grx_text("Grabber enabled: no test!", 10, 10, 255, 0);
 
// Some messages on screen
//grx_text("A-Z change threshold", 400, 240, 255, 0);
//grx_text("S-X change window borders", 400, 250, 255, 0);
mutex_unlock(&mutex);
 
periodo = PXC_Initiate(3);
PXC_CAB = PXC_GetCab();
 
if (!periodo) {
//grx_close();
cprintf("Problemi nell'inizializzazione del driver\n");
sys_end();
} else {
start_listener();
}
 
sys_atrunlevel(framegrabber_close, NULL, RUNLEVEL_BEFORE_EXIT);
}
 
 
void start_listener(void)
{
SOFT_TASK_MODEL m_soft;
 
soft_task_default_model(m_soft);
soft_task_def_met(m_soft,IMAGING_WCET);
soft_task_def_usemath(m_soft);
soft_task_def_aperiodic(m_soft);
soft_task_def_period(m_soft,(periodo*3));
soft_task_def_group(m_soft,1);
soft_task_def_ctrl_jet(m_soft);
 
image_elab_PID = task_create("imaging", elab_image_TASK, &m_soft, NULL);
 
/* task_activate( image_elab_PID);
PXC_Push_Listener(image_elab_PID,2);
PXC_Start();*/
}
 
void start_framegrabber()
{
PXC_Push_Listener(image_elab_PID,2);
PXC_Start();
}
/unsupported/branches/unsupported/thdemo/ball.c
0,0 → 1,164
/*--------------------------------------------------------------*/
/* SIMULATION OF JUMPING BALLS */
/*--------------------------------------------------------------*/
 
/* CVS $Id: ball.c,v 1.1.1.1 2004-05-24 18:03:47 giacomo Exp $ */
 
 
#include "demo.h"
#include <kernel/func.h>
#include <stdlib.h>
 
#define R 2 /* dimension of a ball */
#define G 9.8 /* acceleration of gravity */
 
static int ballexit = 0;
static int npc = 0; /* number of tasks created */
 
/*--------------------------------------------------------------*/
/* Periodic task for ball simulation */
/*--------------------------------------------------------------*/
 
TASK palla(int i)
{
int x, y; /* coordinate grafiche pallina */
int ox, oy; /* vecchia posizione pallina */
int x0, y0; /* posizione iniziale X pallina */
float vx, vy; /* velocit… della pallina */
float vy0; /* velocita' pallina al primo rimbalzo */
float ty, tx; /* variabile temporale */
float dt; /* incremento temporale */
 
y = oy = y0 = BALL_HEIGHT;
x = ox = x0 = BALL_XMIN;
 
vy0= sqrt(2. * G * (float)BALL_HEIGHT);
vy = 0;
vx = BALL_VELX + rand()%9;
tx = 0;
ty = 0;
dt = ((float)PERIOD_BALL)/100000;
 
while (1) {
y = y0 + vy*ty - .5*G*ty*ty;
x = x0 + vx * tx;
 
if (y < 0) {
y = 0;
 
if (vy == 0.0)
vy = vy0;
else if (vy < BALL_VYMIN)
vy = vy0 * (1.0 - (rand()%50)/100.0);
else
vy = 0.9 * vy;
 
ty = 0.0;
y0 = 0;
}
 
if (x > BALL_XMAX) {
tx = 0.0;
x0 = BALL_XMAX;
vx = -vx;
x = x0 + vx * tx;
}
 
if (x < BALL_XMIN) {
tx = 0.0;
x0 = BALL_XMIN;
vx = -vx;
x = x0 + vx * tx;
}
 
mutex_lock(&mutex);
grx_disc(ox, oy, R, 0);
ox = x;
oy = BALL_Y - y;
mutex_unlock(&mutex);
 
if (ballexit) {
npc--;
return 0;
}
 
mutex_lock(&mutex);
grx_disc(ox, oy, R, i);
mutex_unlock(&mutex);
 
{
int xxx;
for (xxx=0; xxx<10000; xxx++);
}
ty += dt;
tx += dt;
task_endcycle();
}
}
 
void killball(KEY_EVT *k)
{
ballexit = 1;
}
 
void ballfun(KEY_EVT *k)
{
SOFT_TASK_MODEL mp;
int r,g,b;
PID pid;
 
if (npc == BALL_MAX_P) return;
 
ballexit = 0;
 
r = 64 + rand()%192;
g = 64 + rand()%192;
b = 64 + rand()%192;
 
soft_task_default_model(mp);
soft_task_def_level(mp,1);
soft_task_def_ctrl_jet(mp);
soft_task_def_arg(mp, (void *)rgb16(r,g,b));
soft_task_def_group(mp, BALL_GROUP);
soft_task_def_met(mp, WCET_BALL);
soft_task_def_period(mp,PERIOD_BALL);
soft_task_def_usemath(mp);
pid = task_create("palla", palla, &mp, NULL);
if (pid != NIL) {
task_activate(pid);
npc++;
}
}
 
 
/*--------------------------------------------------------------*/
/* MAIN process */
/*--------------------------------------------------------------*/
 
void scenario_ball()
{
grx_text("Noise", 0, BALL_Y-BALL_HEIGHT-15, rgb16(0,0,255), black);
grx_line(0,BALL_Y-BALL_HEIGHT-6,383,BALL_Y-BALL_HEIGHT-6,red);
}
 
void init_ball(void)
{
KEY_EVT k;
 
mutex_lock(&mutex);
grx_rect(BALL_XMIN-R-1, BALL_Y-BALL_HEIGHT-R-1,
BALL_XMAX+R+1, BALL_Y+R+1, rgb16(0,200,0));
mutex_unlock(&mutex);
 
k.flag = 0;
k.scan = KEY_SPC;
k.ascii = ' ';
keyb_hook(k,ballfun);
 
k.flag = 0;
k.scan = KEY_BKS;
k.ascii = ' ';
keyb_hook(k,killball);
}
 
/*--------------------------------------------------------------*/
/unsupported/branches/unsupported/thdemo/ball2.c
0,0 → 1,156
/*--------------------------------------------------------------*/
/* SIMULATION OF JUMPING BALLS */
/*--------------------------------------------------------------*/
 
/* CVS $Id: ball2.c,v 1.1.1.1 2004-05-24 18:03:47 giacomo Exp $ */
 
 
#include "demo.h"
#include <kernel/func.h>
#include <stdlib.h>
//#include <drivers/glib.h>
//#include <drivers/keyb.h>
//#include <math.h>
 
#define R 2 /* dimension of a ball */
#define G 9.8 /* acceleration of gravity */
#define BASE 30 /* position of the floor */
#define TOP 80 /* initial height of the ball */
#define XMIN 3 /* min position X of the ball */
#define XMAX 380 /* max position X of the ball */
#define VELX 5. /* horizontal ball velocity */
#define VMIN 11. /* velocit… minima per suono */
#define ESC 27 /* ASCII code of ESCAPE key */
#define MAX_P 50 /* max number of balls */
 
double v0[MAX_P]; /* impact velocity with floor */
 
/*--------------------------------------------------------------*/
/* Periodic task for ball simulation */
/*--------------------------------------------------------------*/
 
TASK palla(int i)
{
int x, y; /* coordinate grafiche pallina */
int ox, oy; /* vecchia posizione pallina */
int x0; /* posizione iniziale X pallina */
float vx, vy; /* velocit… della pallina */
float t, tx; /* variabile temporale */
float dt; /* incremento temporale */
double arg; /* variabile di appoggio */
 
y = oy = TOP;
x = ox = x0 = XMIN;
 
arg = 2. * G * (float)TOP;
vy = sqrt(arg);
vx = VELX;// + rand()%10;
tx = 0.0;
t = vy / G;
dt = 0.1;
 
while (1) {
y = TOP + vy*t - .5*G*t*t;
x = x0 + vx * tx;
 
if (y < BASE) {
t = 0.0;
v0[i] = .9 * v0[i];
// if (v0[i]<VMIN) {
 
// v0[i] = sqrt(2. * G * (float)TOP);
// v0[i] = sqrt(arg);// * (1-((float)(rand()%20))/100);
//vx = vx + rand()%5 - 2;
//tx = 0.0;
//x0 = x;
// }
 
vy = v0[i];
y = TOP + vy*t - .5*G*t*t;
}
 
 
if (x > XMAX) {
tx = 0.0;
x0 = XMAX;
vx = -vx;
x = x0 + vx * tx;
}
 
if (x < XMIN) {
tx = 0.0;
x0 = XMIN;
vx = -vx;
x = x0 + vx * tx;
}
y = 480-y;
 
mutex_lock(&mutex);
grx_disc(ox, oy, R, 0);
grx_disc(x, y, R, i);
mutex_unlock(&mutex);
 
oy = y; ox = x;
t += dt;
tx += dt;
task_endcycle();
}
}
 
 
void ballfun(KEY_EVT *k)
{
static int npc = 0; /* number of tasks created */
SOFT_TASK_MODEL mp;
int r,g,b;
PID pid;
 
if (npc == MAX_P) return;
 
r = 64 + rand()%192;
g = 64 + rand()%192;
b = 64 + rand()%192;
 
soft_task_default_model(mp);
soft_task_def_level(mp,1);
soft_task_def_ctrl_jet(mp);
soft_task_def_arg(mp, rgb16(r,g,b));
soft_task_def_group(mp, 1);
soft_task_def_met(mp, WCET_BALL);
soft_task_def_period(mp,PERIOD_BALL);
soft_task_def_usemath(mp);
pid = task_create("palla", palla, &mp, NULL);
if (pid != NIL) {
task_activate(pid);
npc++;
}
}
 
 
/*--------------------------------------------------------------*/
/* MAIN process */
/*--------------------------------------------------------------*/
 
 
void init_ball(void)
{
char c; /* character from keyboard */
int i; /* pressed number */
double arg; /* temporary variable */
KEY_EVT k;
 
arg = 2. * G * (float)TOP;
for (i=0; i<MAX_P; i++) v0[i] = sqrt(arg);
 
mutex_lock(&mutex);
grx_rect(XMIN-R-1, 480-TOP-BASE-R-1, XMAX+R+1, 480-BASE+R+1, 14);
mutex_unlock(&mutex);
 
k.flag = 0;
k.scan = KEY_SPC;
k.ascii = ' ';
keyb_hook(k,ballfun);
 
}
 
/*--------------------------------------------------------------*/
/unsupported/branches/unsupported/thdemo/camera4.c
0,0 → 1,168
// framegrabber stuffs
 
/* File name ......... : ELABOR.C
* Project............ :
* Object ............ :
* Author ............ : Facchinetti Tullio
* Language .......... : C
* Compiler .......... : GNU C
* Operative system .. : MS-DOS/HARTIK
* Creation data ..... : 04/03/2000
* Last modify ....... : 19/11/99
*/
 
 
 
 
#include <kernel/func.h>
#include <modules/cabs.h>
#include <stdio.h>
#include <drivers/pxc.h>
#include "demo.h"
 
PID image_elab_PID;
TIME periodo;
CAB PXC_CAB;
 
static CAB frameCAB; // CAB di deposito delle immagini
static TDataObj current, older;
 
// extern in INIT.C
int img_border = 10;
int window_width = 40;
int window_height = 40;
 
// a 256 grayscale palette
WORD gray_palette[256];
 
// the image to be putted on the screen
WORD converted_image[IMG_COL*IMG_ROW];
 
 
#ifdef __BLACK_ON_WHITE
TPixel pix_threshold = 64;
#else
TPixel pix_threshold = 243;
#endif
 
 
// Global for testing!!!
static char st[50];
TIME before;
 
TDataObj sequence[N_FRAMES];
int top_frame = 0;
 
double dist, speed;
 
static TPixel *grabber_frame;
 
void put_frame(TPixel *frame)
{
register int i,j,col,row;
 
for (i=1; i<IMG_ROW-1; i++)
for (j=0; j<IMG_COL; j++) {
col = (j*(N_COL-1))/(IMG_COL-1);
row = (i*(N_ROW-1))/(IMG_ROW-1);
converted_image[i*IMG_COL+j] = gray_palette[*(frame+row*N_COL+col)];
}
 
for (j=0; j<IMG_COL; j++) {
converted_image[j] = gray_palette[0];
converted_image[(IMG_ROW-1)*IMG_COL+j] = gray_palette[0];
}
 
mutex_lock(&mutex);
grx_putimage(IMG_X, IMG_Y, IMG_X+IMG_COL-1, IMG_Y+IMG_ROW-1,
(BYTE *)converted_image);
mutex_unlock(&mutex);
}
 
 
TASK elab_image_TASK(void)
{
// register int i, j;
static unsigned int n_frame = 0;
char found;
int pred_x, pred_y;
 
// Inizializzazione del task
frameCAB = PXC_GetCab();
 
while (1) {
n_frame++;
sprintf(st, "frame n. %5d", n_frame);
 
mutex_lock(&mutex);
grx_text(st, 400, 290, 255, 0);
mutex_unlock(&mutex);
 
// Acquisizione immagine corrente
grabber_frame = cab_getmes(frameCAB);
 
put_frame(grabber_frame);
 
// Release CAB
cab_unget(frameCAB, grabber_frame);
 
task_endcycle();
}
}
 
 
void start_listener(void);
 
void framegrabber_close(void *arg)
{
PXC_Close();
}
 
void init_framegrabber(void)
{
register int i;
KEY_EVT my_key;
 
// Aggiusta la palette
for (i = 0; i < 256; i++)
gray_palette[i] = rgb16(i,i,i);
 
periodo = PXC_Initiate(3);
PXC_CAB = PXC_GetCab();
 
if (!periodo) {
grx_close();
cprintf("Problemi nell'inizializzazione del driver\n");
sys_end();
} else {
start_listener();
}
 
sys_atrunlevel(framegrabber_close, NULL, RUNLEVEL_BEFORE_EXIT);
}
 
 
void start_listener(void)
{
SOFT_TASK_MODEL m_soft;
 
soft_task_default_model(m_soft);
soft_task_def_met(m_soft,IMAGING_WCET);
soft_task_def_usemath(m_soft);
soft_task_def_aperiodic(m_soft);
soft_task_def_period(m_soft,(periodo));
soft_task_def_group(m_soft,1);
soft_task_def_ctrl_jet(m_soft);
 
image_elab_PID = task_create("imaging", elab_image_TASK, &m_soft, NULL);
 
/* task_activate( image_elab_PID);
PXC_Push_Listener(image_elab_PID,2);
PXC_Start();*/
}
 
void start_framegrabber()
{
PXC_Push_Listener(image_elab_PID,1);
PXC_Start();
}
/unsupported/branches/unsupported/thdemo/makefile
0,0 → 1,17
#
#
#
 
ifndef BASE
BASE=../..
endif
include $(BASE)/config/config.mk
 
PROGS= demo
 
include $(BASE)/config/example.mk
 
demo:
make -f $(SUBMAKE) APP=demo INIT= OTHEROBJS="fft.o camera.o initfile.o jetctrl.o ball.o" SHARKOPT="__FFT__ __OLDCHAR__ __PXC__ __GRX__"
 
 
/unsupported/branches/unsupported/tracer/utils/udpdump.c
0,0 → 1,216
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
* Copyright (C) 2002 Tomas Lenvall
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: udpdump.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
/* this example simply prints a Shark trace file */
 
// INCLUDES
#include <netinet/in.h>
#include "types.h"
#include "trace.h"
#include "util.h"
 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>/* close() */
#include <string.h> /* memset() */
#include <stdlib.h>
 
 
// GLOBALS
char server_ipaddr[20]; // Store the IP adress of the server
 
// DEFINES
#define LOCAL_SERVER_PORT 20000
#define MAX_MSG 10000
 
// FUNCTIONS
/* */
int dumpsys(trc_system_event_t *sys)
{
printf("%02i\n",sys->task);
return 0;
}
 
/* */
int dumpusr(trc_user_event_t *usr)
{
printf("%8li ",usr->n);
printf("\n");
return 0;
}
 
/* */
int dumpsem(trc_sem_event_t *sem)
{
printf("on [%i]\n",sem->id);
return 0;
}
 
/* */
int dumpfunc(trc_event_t *ev)
{
static int counter=0;
printf("\t%4i ",counter);
counter++;
printf("%12s ",format_time(ev->time));
printf("%-10s ",event_name(ev->event));
 
//printf("%08x\n",(unsigned)ev->sys.event);
//return 0;
switch(event_class(ev->event)) {
case TRC_CLASS_SYSTEM: return dumpsys(&ev->x.sys);
case TRC_CLASS_USER: return dumpusr(&ev->x.usr);
case TRC_CLASS_SEM: return dumpsem(&ev->x.sem);
}
printf("\nEVENT %i... CLASS %i UNKNOWN!\n",ev->event,event_class(ev->event));
return -1;
}
 
 
/* Use UDP/IP to receive the events from the client computer */
int main(int argc, char *argv[])
{
int sd, rc, n, cliLen;
struct sockaddr_in cliAddr, servAddr;
char msg[MAX_MSG];
 
// socket creation
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd < 0) {
printf("%s: cannot open socket \n",argv[0]);
exit(1);
}
 
// bind local server port
servAddr.sin_family = AF_INET;
 
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
 
rc = bind (sd, (struct sockaddr *)&servAddr,sizeof(servAddr));
if(rc < 0) {
printf("%s: cannot bind port number %d \n",
argv[0], LOCAL_SERVER_PORT);
exit(1);
}
 
while(1){
// init buffer
memset(msg, 0x0, MAX_MSG);
 
// receive message
cliLen = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *)&cliAddr, &cliLen);
 
printf("Packet received, length %d, %d tracer events.\n", n,
*((short int *)msg));
if(n < 0) {
printf("%s: cannot receive data \n",argv[0]);
continue;
}
// Read the trace we got from the network
read_udp_trace(msg, dumpfunc);
}
 
return 0;
}
 
 
// test main: testing this program from a file (simulating a network package)
// ONLY USED FOR TESTING!!!
 
/*int main(int argc, char *argv[])
{
FILE* fin;
int nr_of_events = 0;
trc_event_t buffer;
char all_events[1000];
char tmpbuf[2];
 
if(argc != 2) {
printf("Missing filename!\n");
return -1;
}
 
// open the file and send event by event
fin = fopen(argv[1], "r");
if (fin == NULL) {
printf("Cannot open file\n");
return -1;
}
// check how many events
while (!feof(fin)) {
fread(&buffer, sizeof(trc_event_t), 1, fin);
nr_of_events++;
}
 
//printf("Nr of events: %d\n", nr_of_events);
 
rewind(fin); // start from the beginning again...
//strncpy(tmpbuf, itoa(nr_of_events), 2);
sprintf(tmpbuf, "%d", nr_of_events);
//printf("tmpbuf: %s\n", tmpbuf);
 
memset(all_events, 0, 1000);
memcpy(all_events, tmpbuf, 2);
printf("all_events(1): %s\n", all_events);
// read all tracer events and store them in an array
fread(all_events + 2, sizeof(trc_event_t), nr_of_events, fin);
fclose(fin);
 
printf("all_events(2): %s\n", all_events);
// send it to the event reader
read_trace(all_events, dumpfunc);
 
return 1;
}
*/
/unsupported/branches/unsupported/tracer/utils/jdump.c
0,0 → 1,470
/*
* Project: HARTIK (HA-rd R-eal TI-me K-ernel)
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
* Gerardo Lamastra <gerardo@sssup.it>
*
* Authors : Massimiliano Giorgi <massy@hartik.sssup.it>
* (see authors.txt for full list of hartik's authors)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
/*
* Copyright (C) 1999 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: jdump.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
 
#include "types.h"
#include <trace.h>
#include "util.h"
 
/*
*
* This filter converts trace file formats from SHARK to JTRACER
*
*/
 
/* All times are dived by this costant. */
#define TIMESCALE 1
 
/* If defined dump on stdout the packets (in ascii) that will be written
* on the output file (the file of the tracer).
*/
 
#define DUMPOUT
 
/*
*
*
*
*/
 
int pippo=0;
 
int writeInt(int h, int x)
{
int y,res;
y=htonl(x);
res=write(h,&y,sizeof(int));
return res!=sizeof(int);
}
 
 
int writeStr(int h, char *s)
{
int res,size;
size=strlen(s);
writeInt(h,size);
res=write(h,s,size);
return res!=size;
}
 
/*
*
*/
 
#define TASK_ARRIVAL 0
#define TASK_SCHEDULE 1
#define TASK_DESCHEDULE 2
#define TASK_END 3
#define TASK_DLINEPOST 4
#define TASK_DLINESET 5
#define TASK_WAIT 6
#define TASK_SIGNAL 7
#define TASK_IDLE 8
#define TASK_NAME 9
 
#define EVT_NUMBER 10
 
char *eventsname[]={
"task_arrival",
"task_schedule",
"task_deschedule",
"task_end",
"task_dlinepost",
"task_dlineset",
"task_wait",
"task_signal",
"task_idle",
"task_name"
};
 
struct j_evt_prolog {
int type;
int time;
};
 
struct j_evt_task {
struct j_evt_prolog p;
int task;
};
 
struct j_evt_dlinepost {
struct j_evt_task t;
int taskD;
int taskD2;
};
 
struct j_evt_dlineset {
struct j_evt_task t;
int taskD;
};
 
struct j_evt_semaph {
struct j_evt_task t;
int res;
char *name;
};
 
struct j_evt_name {
struct j_evt_task t;
char *name;
};
 
/*
*
*/
 
int j_write_prolog(int h, void *ptr)
{
#ifdef DUMPOUT
printf("%10i ",((struct j_evt_prolog *)ptr)->time);
printf("%-18s ",eventsname[((struct j_evt_prolog *)ptr)->type]);
#endif
if (writeInt(h,((struct j_evt_prolog *)ptr)->type)) return -2;
if (writeInt(h,((struct j_evt_prolog *)ptr)->time)) return -3;
return 0;
}
 
int j_write_task(int h, void *ptr)
{
int res;
res=j_write_prolog(h,ptr);
#ifdef DUMPOUT
printf("tsk=%i ",((struct j_evt_task *)ptr)->task);
#endif
if (res) return res;
if (writeInt(h,((struct j_evt_task *)ptr)->task)) return -4;
return 0;
}
 
int j_write_dlinepost(int h, void *ptr)
{
int res;
res=j_write_task(h,ptr);
if (res) return res;
if (writeInt(h,((struct j_evt_dlinepost *)ptr)->taskD)) return -5;
if (writeInt(h,((struct j_evt_dlinepost *)ptr)->taskD2)) return -6;
return 0;
}
 
int j_write_dlineset(int h, void *ptr)
{
int res;
res=j_write_task(h,ptr);
if (res) return res;
if (writeInt(h,((struct j_evt_dlineset *)ptr)->taskD)) return -7;
return 0;
}
 
int j_write_semaph(int h, void *ptr)
{
int res;
res=j_write_task(h,ptr);
if (res) return res;
if (writeInt(h,((struct j_evt_semaph *)ptr)->res)) return -8;
if (writeStr(h,((struct j_evt_semaph *)ptr)->name)) return -9;
return 0;
}
 
int j_write_name(int h, void *ptr)
{
int res;
res=j_write_task(h,ptr);
#ifdef DUMPOUT
printf("name='%s' ",((struct j_evt_name *)ptr)->name);
#endif
if (res) return res;
if (writeStr(h,((struct j_evt_name *)ptr)->name)) return -10;
return 0;
}
int writeEvent(int h, void *ptr)
{
int res;
//printf("<%i>",((struct j_evt_prolog*)ptr)->type);
((struct j_evt_prolog*)ptr)->time/=TIMESCALE;
 
switch(((struct j_evt_prolog*)ptr)->type) {
case TASK_ARRIVAL:
case TASK_SCHEDULE:
case TASK_DESCHEDULE:
case TASK_END:
case TASK_IDLE:
res=j_write_task(h,ptr);
break;
case TASK_DLINEPOST:
res=j_write_dlinepost(h,ptr);
break;
case TASK_DLINESET:
res=j_write_dlineset(h,ptr);
break;
case TASK_WAIT:
case TASK_SIGNAL:
res=j_write_semaph(h,ptr);
break;
case TASK_NAME:
res=j_write_name(h,ptr);
break;
default:
return -1;
}
 
#ifdef DUMPOUT
printf(" \n");
#endif
 
return res;
}
 
/*
*
*
*
*/
 
#define MAX_PROC 150
 
//int activated[MAX_PROC];
 
int cxx=0;
/* write MAXC-1 events */
#define MAXC 10000
 
long lasttime;
 
int sys_event(int h, void *param)
{
static int prevtask=-1;
trc_event_t *ptr=(trc_event_t *)param;
struct j_evt_task evt;
 
evt.p.time=ptr->time;
evt.task=ptr->x.sys.task;
 
lasttime=ptr->time;
switch(ptr->event) {
case TRC_CREATE:
return 0;
 
case TRC_ACTIVATE:
case TRC_INTACTIVATION:
 
 
//activated[ptr->x.sys.task]=1;
 
 
evt.p.type=TASK_ARRIVAL;
break;
case TRC_DESTROY:
 
 
//activated[ptr->x.sys.task]=0;
 
 
 
return 0;
 
case TRC_DISABLE:
 
return 0;
case TRC_DELAY:
prevtask=-1;
evt.p.type=TASK_DESCHEDULE;
break;
case TRC_SLEEP:
prevtask=-1;
evt.p.type=TASK_DESCHEDULE;
break;
case TRC_ENDCYCLE:
prevtask=-1;
evt.p.type=TASK_END;
break;
 
case TRC_SCHEDULE:
if (prevtask!=-1) {
struct j_evt_task evt2;
int res;
evt2.p.time=ptr->time;
evt2.p.type=TASK_DESCHEDULE;
evt2.task=prevtask;
res=writeEvent(h,&evt2);
if (res!=0) return -1;
}
 
/*
if (!activated[ptr->x.sys.task]) {
struct j_evt_task evt2;
 
evt2.p.time=ptr->time-1;
evt2.task=ptr->x.sys.task;
evt2.p.type=TASK_ARRIVAL;
 
writeEvent(h,&evt2);
activated[ptr->x.sys.task]=1;
}
*/
 
evt.p.type=TASK_SCHEDULE;
prevtask=ptr->x.sys.task;
break;
 
default:
return 0;
}
 
cxx++;
if (cxx==MAXC) return -1;
 
return writeEvent(h,&evt);
}
 
 
int sem_event(int h,void *param)
{
//trc_event_t *ptr=(trc_event_t *)param;
//struct j_evt_semaph evt;
 
return 0;
/*
evt.t.p.time=ptr->x.norm.when;
evt.t.task=ptr->x.norm.who;
switch(ptr->what) {
case TRC_SEM_WAIT: evt.t.p.type=TASK_WAIT; break;
case TRC_SEM_SIGNAL: evt.t.p.type=TASK_SIGNAL; break;
case TRC_SEM_WAITNB: return 0;
default: return 0;
}
evt.res=1;
evt.name="NoName";
return j_write_semaph(h,&evt);
*/
}
 
/* -- */
 
#define MAX_PROC 150
int names[MAX_PROC];
 
int outfile;
 
int dumpfunc(trc_event_t *ptr)
{
//printf("{%i}",ptr->event);
 
if (!names[ptr->x.sys.task]) {
struct j_evt_name evtname;
static char name[24];
 
cxx++;
if (cxx==MAXC) return -1;
evtname.t.p.time=lasttime;
evtname.t.task=ptr->x.sys.task;
evtname.t.p.type=TASK_NAME;
sprintf(name,"task%03i",ptr->x.sys.task);
evtname.name=name;
writeEvent(outfile,&evtname);
names[ptr->x.sys.task]=1;
 
}
 
switch(event_class(ptr->event)) {
case TRC_CLASS_SYSTEM:
return sys_event(outfile,ptr);
case TRC_CLASS_SEM:
return 0;
return sem_event(outfile,ptr);
case TRC_CLASS_USER:
return 0;
}
return 0;
}
 
/*
*
*/
 
#ifndef O_BINARY
#define O_BINARY 0
#endif
 
int main(int argc, char *argv[])
{
int res;
int i;
 
if (argc!=3) {
fprintf(stderr,"missing filenames\n");
fprintf(stderr,"usage: jdump SHARKtracefilename JTRACERtracefilename\n");
return -1;
}
 
for (i=0;i<MAX_PROC;i++) {
names[i]=0;
//activated[i]=0;
}
 
outfile=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0777);
if (outfile==-1) {
perror("can't open outfile");
return -1;
}
res=read_trace(argv[1],dumpfunc);
close(outfile);
//fprintf(stderr,"result=%i",res);
return 0;
}
/unsupported/branches/unsupported/tracer/utils/util.h
0,0 → 1,58
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: util.h,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#ifndef __UTIL_H
#define __UTIL_H
 
#include "types.h"
 
char *event_name(int evt);
char *event_hexdump(u_int8_t *ptr, int maxsize);
char *event_strdump(u_int8_t *ptr, int maxsize);
int event_class(int evt);
 
int read_trace(char *filename,int (*func)(trc_event_t *));
int read_udp_trace(void *msg, int (*func)(trc_event_t *));
 
char *format_time(long time);
 
#endif
/unsupported/branches/unsupported/tracer/utils/sa.c
0,0 → 1,120
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: sa.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#include <netinet/in.h>
 
#include <stdlib.h>
#include <stdio.h>
#include "types.h"
#include <trace.h>
#include "util.h"
 
/* this file prints the distribution of (schedule_time - arrival_time) */
 
#define MAXX 50
#define PREC 100
#define DELTA ((double)MAXX/(double)PREC)
 
#include "distr.c"
 
int task;
long a=-1;
long s;
 
int safunc(trc_event_t *ev)
{
if (event_class(ev->event)!=TRC_CLASS_SYSTEM) return 0;
if (ev->x.sys.task!=task) return 0;
 
if (a==-1) {
if (ev->event==TRC_ACTIVATE||ev->event==TRC_INTACTIVATION)
a=ev->time;
} else {
if (ev->event==TRC_SCHEDULE) {
s=ev->time;
d_insert(s-a);
a=-1;
}
}
return 0;
}
 
/* -- */
 
int main(int argc, char *argv[])
{
int res;
if (argc!=4) {
fprintf(stderr,"usage: sa [tracefile] [pid] [outputfile]\n");
return -1;
}
 
d_init();
 
task=atoi(argv[2]);
res=read_trace(argv[1],safunc);
 
if (res==0) {
FILE *fout;
fout=fopen(argv[3],"wt");
if (fout==NULL) {
fprintf(stderr,"error writing output file!\n");
return 0;
}
d_dump(fout);
fclose(fout);
}
 
if (res!=0) {
fprintf(stderr,"error=%i\n",res);
perror("ERROR");
}
 
return 0;
}
 
 
 
 
 
 
 
/unsupported/branches/unsupported/tracer/utils/wait.c
0,0 → 1,95
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: wait.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include <trace.h>
#include "util.h"
 
/* This demo computes the distribution of the wait times on disk requests */
 
#define MAXX 37000
#define PREC 37000
#define DELTA ((double)MAXX/(double)PREC)
 
#include "distr.c"
 
int task;
long a=-1;
 
int waitfunc(trc_event_t *ev)
{
if (event_class(ev->event)!=TRC_CLASS_USER) return 0;
if (ev->x.usr.n!=task) return 0;
if (ev->event==TRC_USER1) {
a=ev->time;
return 0;
}
if (ev->event==TRC_USER2) {
if (a!=-1) d_insert(ev->time-a);
a=-1;
}
return 0;
}
 
int main(int argc, char *argv[])
{
FILE *fout;
int res;
if (argc!=4) {
fprintf(stderr,"missing filename!\n");
return -1;
}
d_init();
task=atoi(argv[2]);
res=read_trace(argv[1],waitfunc);
if (res==0) {
fout=fopen(argv[3],"wt");
if (fout!=NULL) {
d_dump(fout);
fclose(fout);
} else
fprintf(stderr,"can't create output file!\n");
} else
fprintf(stderr,"read_trace error\n");
return 0;
}
/unsupported/branches/unsupported/tracer/utils/distr.c
0,0 → 1,83
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: distr.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
long t[PREC];
long counter;
long hoops;
long maxv=0;
 
void d_init(void)
{
int i;
hoops=counter=0;
for (i=0;i<PREC;i++) t[i]=0;
}
 
void d_insert(long d)
{
if (d>=MAXX) {
hoops++;
if (d>maxv) maxv=d;
return;
}
 
counter++;
t[(int)(d/DELTA)]++;
}
 
void d_dump(FILE *fout)
{
int i;
 
if (counter==0) {
fprintf(stderr,"nothing to write to the output file\n");
return;
}
if (hoops) {
fprintf(stderr,"%li values to big (max=%li)\n",hoops,maxv);
}
for (i=0;i<PREC;i++)
fprintf(fout,"%f %f\n",
DELTA/2.0+DELTA*i,
(double)t[i]/(double)counter
);
}
/unsupported/branches/unsupported/tracer/utils/road.c
0,0 → 1,96
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: road.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include <trace.h>
#include "util.h"
 
 
/* this test prints the distribution of the HD seeks */
 
#define MAXX 1000
#define PREC 1000
#define DELTA ((double)MAXX/(double)PREC)
 
#include "distr.c"
 
int dumpusr(int event, trc_user_event_t *usr)
{
static long last=-1;
long d;
if (event!=TRC_USER0) return 0;
if (last!=-1) {
d=abs(last-usr->n);
d_insert(d);
}
last=usr->n;
return 0;
}
 
int dumpfunc(trc_event_t *ev)
{
if (event_class(ev->event)==TRC_CLASS_USER) dumpusr(ev->event,&ev->x.usr);
return 0;
}
 
int main(int argc, char *argv[])
{
FILE *fout;
int res;
if (argc!=3) {
fprintf(stderr,"missing filename!\n");
return -1;
}
d_init();
res=read_trace(argv[1],dumpfunc);
if (res==0) {
fout=fopen(argv[2],"wt");
if (fout!=NULL) {
d_dump(fout);
fclose(fout);
} else
fprintf(stderr,"can't create output file!\n");
} else
fprintf(stderr,"read_trace error\n");
return 0;
}
/unsupported/branches/unsupported/tracer/utils/types.h
0,0 → 1,55
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: types.h,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#ifndef __TYPES_H__
#define __TYPES_H__
 
#include <sys/types.h>
 
/* when compiling under MSDOS, uncomment this three typedefs!!! */
 
//typedef unsigned char u_int8_t;
//typedef unsigned short u_int16_t;
//typedef unsigned long u_int32_t;
 
#include <types.h>
#endif
 
/unsupported/branches/unsupported/tracer/utils/tdump.c
0,0 → 1,115
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: tdump.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
/* this example simply prints a Shark trace file */
 
#include <netinet/in.h>
 
#include <stdio.h>
#include "types.h"
#include <trace.h>
#include "util.h"
 
int dumpsys(trc_system_event_t *sys)
{
/*
if (sys->event==TRC_SCHEDULE) {
//if (sys->prev!=65535)
// printf("%02i->%02i\n",sys->prev,sys->task);
//else
printf("??->%02i\n",sys->task);
return 0;
}
*/
printf("%02i\n",sys->task);
return 0;
}
 
int dumpusr(trc_user_event_t *usr)
{
printf("%8li ",usr->n);
printf("\n");
return 0;
}
 
int dumpsem(trc_sem_event_t *sem)
{
printf("on [%i]\n",sem->id);
return 0;
}
 
int dumpfunc(trc_event_t *ev)
{
static int counter=0;
printf("%4i ",counter);
counter++;
printf("%12s ",format_time(ev->time));
printf("%-10s ",event_name(ev->event));
 
//printf("%08x\n",(unsigned)ev->sys.event);
//return 0;
switch(event_class(ev->event)) {
case TRC_CLASS_SYSTEM: return dumpsys(&ev->x.sys);
case TRC_CLASS_USER: return dumpusr(&ev->x.usr);
case TRC_CLASS_SEM: return dumpsem(&ev->x.sem);
}
printf("\nEVENT %i... CLASS %i UNKNOWN!\n",ev->event,event_class(ev->event));
return -1;
}
 
int main(int argc, char *argv[])
{
int res;
if (argc!=2) {
fprintf(stderr,"missing filename!\n");
return -1;
}
 
res=read_trace(argv[1],dumpfunc);
 
//fprintf(stderr,"result=%i\n",res);
//fprintf(stderr,"size=%li\n",sizeof(trc_event_t));
return 0;
}
/unsupported/branches/unsupported/tracer/utils/makefile
0,0 → 1,70
#
# util -> compiles the tracer utilities under MSDOS/DJGPP
# util_linux -> compiles the tracer utilities under Linux
#
 
ifndef BASE
BASE=../../..
endif
 
.PHONY: util_dos util_linux clean
 
all:
@echo Targets: util_dos util_linux clean
@echo Note: udpdump is available only under linux
 
util_dos: tdump.exe jdump.exe sa.exe road.exe wait.exe
 
tdump.exe: tdump.c util.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace tdump.c util.c -o tdump.exe
 
jdump.exe: jdump.c util.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace jdump.c util.c -o jdump.exe
 
sa.exe: sa.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace sa.c util.c -o sa.exe
 
road.exe: road.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace road.c util.c -o road.exe
 
wait.exe: wait.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace wait.c util.c -o wait.exe
 
 
util_linux: jdump tdump sa road wait udpdump
 
jdump: jdump.c util.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace -I$(BASE)/oslib jdump.c util.c -o jdump
 
tdump: tdump.c util.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace -I$(BASE)/oslib tdump.c util.c -o tdump
 
sa: sa.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace -I$(BASE)/oslib sa.c util.c -o sa
 
road: road.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace -I$(BASE)/oslib road.c util.c -o road
 
wait: wait.c util.c distr.c
gcc -s -Wimplicit-function-declaration -Wall \
-I$(BASE)/include/trace -I$(BASE)/oslib wait.c util.c -o wait
 
udpdump: udpdump.c util.c
gcc -Wimplicit-function-declaration -Wall -ggdb\
-I$(BASE)/include/trace -I$(BASE)/oslib udpdump.c util.c -o udpdump
 
 
 
clean:
rm -rf *.o jdump tdump sa road wait tdump.exe jdump.exe sa.exe road.exe wait.exe
 
 
/unsupported/branches/unsupported/tracer/utils/readme
0,0 → 1,13
This directory contains a set of utilities that can be used to interpret
the tracer output:
 
- tdump this example simply prints a Shark trace file
- jdump converts trace file formats from SHARK to JTRACER
- sa prints the distribution of (schedule_time - arrival_time)
- road prints the distribution of the HD seeks
- wait computes the distribution of the wait times on disk requests
 
Under Linux: to compile, type "make util_linux"
Under MSDOS: uncomment the three lines into types.h, then type "make util_dos"
 
PJ
/unsupported/branches/unsupported/tracer/utils/util.c
0,0 → 1,203
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
* Copyright (C) 2002 Tomas Lenvall
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: util.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
 
#include "types.h"
#include <trace.h>
#include <types.h>
 
static char *names[]={
"reserved",
"hoops",
/*--*/
"create",
"activate",
"schedule",
"delay",
"sleep",
"endcycle",
"destroy",
"intactiv",
"disable",
/*--*/
"user0",
"user1",
"user2",
"user3",
"user4",
"user5",
"user6",
"user7",
/*--*/
"wait",
"waitnb",
"signal"
};
 
int classtable[TRC_NUMCLASSES+1]={
TRC_F_TRACER,
TRC_F_SYSTEM,
TRC_F_USER,
TRC_F_SEM,
TRC_F_LAST
};
 
int event_class(int ev)
{
int i;
 
if (ev < 0 || ev >= TRC_NUMEVENTS)
return -1;
 
for (i = 0; i < TRC_NUMCLASSES; i++)
if (ev >= classtable[i] && ev < classtable[i+1])
return i;
 
return -1;
}
 
char *event_name(int ev)
{
if (ev<0||ev>=TRC_NUMEVENTS) return "unknown";
return names[ev];
}
 
char *event_hexdump(u_int8_t *ptr,int maxsize)
{
static char buffer[256];
int i;
for (i=0;i<maxsize;i++) sprintf(buffer+i*2,"%02x",*(ptr+i));
buffer[maxsize*2]='\0';
return buffer;
}
 
char *event_strdump(u_int8_t *ptr, int maxsize)
{
static char buffer[256];
memcpy(buffer,ptr,maxsize);
buffer[maxsize]='\0';
return buffer;
}
 
 
char *format_time(long time)
{
static char buffer[256];
if (time<1000l) {
sprintf(buffer,"%li",time);
return buffer;
}
if (time<1000000l) {
sprintf(buffer,"%li,%03li",time/1000l,time%1000l);
return buffer;
}
sprintf(buffer,"%li,%03li,%03li",
(time/1000000l),
(time%1000000l)/1000l,
time%1000l);
return buffer;
}
 
#ifndef O_BINARY
#define O_BINARY 0
#endif
 
int read_trace(char *filename,int (*func)(trc_event_t *))
{
trc_event_t buffer;
int fin;
int res;
fin=open(filename,O_RDONLY|O_BINARY);
if (fin==-1) return -1;
for (;;) {
res=read(fin,&buffer,sizeof(trc_event_t));
if (res!=sizeof(trc_event_t)) {
close(fin);
return res==0?0:-2;
}
res=(*func)(&buffer);
if (res!=0) {
close(fin);
return res;
}
}
close(fin);
return 0;
}
 
 
/* reads trace events from a udp message */
int read_udp_trace(char *msg, int (*func)(trc_event_t *))
{
short int events; // temporary storage of nr of events
int res;
 
/* message:
|2 bytes=nr of events|12 bytes=event 0|12 bytes=event 1|...
 
Note: the size of an event depends on the extra informations that
are put on the trc_event_t data structures. That size is
currently 12 bytes, but it can change if additional fields are
added to the trc_event_t structure. Including the
include/trace/types.h header ensures that the size used in this
application is coherent with the size of the compiled Shark
applications...
*/
events = *((short int *)msg);
 
msg += 2; // skip the 2 first bytes
 
for (;
events > 0;
events--, msg += sizeof(trc_event_t))
res = (*func)((trc_event_t *)msg);
 
return 1;
}
 
/unsupported/branches/unsupported/tracer/dfixed/initfile.c
0,0 → 1,115
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: initfile.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/rr.h"
#include "modules/cbs.h"
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
#include "modules/nopm.h"
 
#include "drivers/keyb.h"
 
/*+ sysyem tick in us +*/
#define TICK 1000
 
/*+ RR tick in us +*/
#define RRTICK 10000
 
void mytracer_prologue(void);
void mytracer_epilogue(void);
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
mytracer_prologue();
 
EDF_register_level(EDF_ENABLE_ALL);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
CBS_register_level(CBS_ENABLE_ALL, 0);
dummy_register_level();
 
SEM_register_module();
 
CABS_register_module();
 
PI_register_module();
PC_register_module();
NPP_register_module();
SRP_register_module();
NOP_register_module();
NOPM_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
KEYB_PARMS keyb = BASE_KEYB;
extern void ctrlc_exit(KEY_EVT *k);
HARTPORT_init();
keyb_def_ctrlC(keyb, ctrlc_exit);
KEYB_init(&keyb);
 
mytracer_epilogue();
__call_main__(mb);
 
return (void *)0;
}
 
/unsupported/branches/unsupported/tracer/dfixed/dfixed.c
0,0 → 1,133
/*
* Project: HARTIK (HA-rd R-eal TI-me K-ernel)
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
* Gerardo Lamastra <gerardo@sssup.it>
*
* Authors : Massimiliano Giorgi <massy@hartik.sssup.it>
* (see authors.txt for full list of hartik's authors)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: dfixed.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
/*
* Example of tracer initialization.
*/
 
#include <ll/i386/cons.h>
 
#include <kernel/func.h>
#include <tracer.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
 
#include <trace.h>
#include <queues.h>
 
#include <sys/mount.h>
#include <stddef.h>
 
 
void mytracer_prologue(void)
{
int myqueue;
TRC_PARMS p;
TRC_FIXED_PARMS f;
 
trc_default_parms(p);
trc_def_path(p,"");
 
trc_fixed_default_parms(f);
trc_fixed_def_filename(f,"fixed");
 
/* Tracer Initialization */
/* the first functions to call... parameters can be passed */
TRC_init_phase1(&p);
 
/* all the tracer queue types must be registered */
trc_register_dosfs_fixed_queue();
 
/* then, we create all the queues we need */
myqueue = trc_create_queue(TRC_DOSFS_FIXED_QUEUE,&f);
 
/* Then, we say that events must be sent to a particular queue */
trc_trace_class(TRC_CLASS_SYSTEM);
trc_assign_class_to_queue(TRC_CLASS_SYSTEM, myqueue);
}
 
void mytracer_epilogue(void)
{
TRC_init_phase2();
}
 
void ctrlc_exit(KEY_EVT *k)
{
sys_end();
}
 
void *mytask(void *arg)
{
int i;
 
for(i=0; i<10; i++) {
cprintf("%d ", i);
task_endcycle();
}
 
return 0;
}
 
int main(int argc,char *argv[])
{
SOFT_TASK_MODEL mp;
 
PID pid;
 
soft_task_default_model(mp);
soft_task_def_met(mp, 10000);
soft_task_def_period(mp,50000);
soft_task_def_usemath(mp);
 
cprintf("\nHello, world!\n");
 
pid = task_create("mytask", mytask, &mp, NULL);
 
if (pid != NIL) task_activate(pid);
 
return 0;
}
/unsupported/branches/unsupported/tracer/dfixed/makefile
0,0 → 1,21
#
#
#
 
ifndef BASE
BASE=../../..
endif
 
include $(BASE)/config/config.mk
 
PROGS= dfixed
 
include $(BASE)/config/example.mk
 
dfixed:
make -f $(SUBMAKE) BASE=$(BASE) APP=dfixed INIT= OTHEROBJS=initfile.o SHARKOPT=__OLDCHAR__
 
 
 
 
 
/unsupported/branches/unsupported/tracer/dfixed/readme
0,0 → 1,8
This is a simple test that uses the tracer.
 
The example simply creates a soft task that does 10 instances and then dies.
It uses a DOSFS Fixed queue to write the output on a file.
 
Enjoy,
 
PJ
/unsupported/branches/unsupported/tracer/small/test0.c
0,0 → 1,71
/*
*
*
*
*/
 
#include <kernel/func.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
 
#include <sys/mount.h>
 
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
 
#include "common.h"
 
#define FILENAME "/TEMP/ALFA1.TXT"
 
#include <trace/trace.h>
#include <trace/queues.h>
 
int __register_sub_init_prologue(void)
{
TRC_init_phase1(NULL);
trc_register_fixed_queue();
trc_create_queue(TRC_FIXED_QUEUE,NULL);
return 0;
}
 
int main(int argc,char *argv[])
{
int h;
 
showmessage("A file is opened for reading while the tracer\n"
"with a fixed queue is runnig\n");
cprintf("OPENING %s\n",FILENAME);
h=open(FILENAME,O_RDONLY);
if (h>=0) {
char buffer[128];
int len;
cprintf("OPENED!\n");
 
cprintf("READING...\n");
len=read(h,buffer,sizeof(buffer));
cprintf("READ %i bytes\n",len);
memset(buffer,'\0',sizeof(buffer));
cprintf("buffer='%s'\n",buffer);
 
cprintf("READING...\n");
len=read(h,buffer,sizeof(buffer));
cprintf("READ %i bytes\n",len);
memset(buffer,'\0',sizeof(buffer));
cprintf("buffer='%s'\n",buffer);
 
close(h);
} else
cprintf("FAILED!\n");
waitend();
return 0;
}
/unsupported/branches/unsupported/tracer/small/hello.c
0,0 → 1,209
/*
* Project: HARTIK (HA-rd R-eal TI-me K-ernel)
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
* Gerardo Lamastra <gerardo@sssup.it>
*
* Authors : Massimiliano Giorgi <massy@hartik.sssup.it>
* (see authors.txt for full list of hartik's authors)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: hello.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
/*
* Example of tracer initialization.
*/
 
#include <ll/i386/cons.h>
 
#include <kernel/func.h>
#include <tracer.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
 
#include <trace.h>
#include <queues.h>
 
#include <sys/mount.h>
#include <stddef.h>
 
/*
this example use initfs.c to initialize the system; this file define
the following two function.
__kernel_register_levels__(), must initialize all kernel modules,
it has this structure:
 
{
__register_sub_init_prologue();
 
... modules initialization....
__register_sub_init();
}
 
__init__(void *arg) is called when the first task is created
and must call the main():
 
{
 
... drivers initialization ....
 
__bdev_sub_init();
__fs_sub_init();
 
call_main()
 
}
*/
 
/*
* This function is called before all other modules initialization because
* all modules that need the tracer must follow tracer initialization.
*/
int __register_sub_init_prologue(void)
{
/* the first functions to call... parameters can be passed */
TRC_init_phase1(NULL);
/* all the tracer queues must be registrated (in this case only */
/* a dummy queue is initialized) */
trc_register_dummy_queue();
/* the queues must be created (only one in this example) */
trc_create_queue(TRC_DUMMY_QUEUE,NULL);
/* events can be dispatch to a queue (nothing in this case) */
return 0;
}
 
/*
* This function is called after all other modules initialization
* functions... notjing to do.
*/
int __register_sub_init(void)
{
return 0;
}
 
__dev_t root_device;
__dev_t temp_device;
 
/*
* Now the system is running... we have to initialize the block device
* drivers
*/
int __bdev_sub_init(void)
{
BDEV_PARMS bdev=BASE_BDEV;
 
/* This to initialize the block device drivers... a NULL can be passed */
/* to the bdev_init() functions */
bdev_def_showinfo(bdev,FALSE);
bdev_init(&bdev);
 
/* The following phase ca be made in several way: we must decide the */
/* device that we want mount as root... we use the bdev_find_byname() */
/* functions to find a specific device */
root_device=bdev_find_byname("ide/hda1");
if (root_device<0) {
cprintf("can't find root device to mount on /!!!\n");
sys_end();
return -1;
}
 
/* Well, we want a device to mount into /TEMP */
temp_device=bdev_find_byname("ide/hdb3");
if (temp_device<0) {
cprintf("can't find a filesystem to mount on /TEMP!!!\n");
sys_end();
return -1;
}
return 0;
}
 
 
/*
* This is the real filesystem initialization!
*/
int __fs_sub_init(void)
{
FILESYSTEM_PARMS fs=BASE_FILESYSTEM;
extern int libc_initialize(void);
int res;
struct mount_opts opts;
 
/* We set the root device and call the filesystem_init() function */
filesystem_def_rootdevice(fs,root_device);
filesystem_def_fs(fs,FS_MSDOS);
filesystem_def_showinfo(fs,FALSE);
filesystem_init(&fs);
 
/* We must initialize the libC if we use it */
libc_initialize();
 
/* We have choose to mount the second partiotion into the /TEMP */
/* directory with read/write privilegies (this step is not required) */
if (temp_device>=0) {
memset(&opts,0,sizeof(struct mount_opts));
opts.flags=MOUNT_FLAG_RW;
res=mount(temp_device,FS_MSDOS,"/TEMP",&opts);
if (res!=0) {
cprintf("can't mount XXX on /TEMP (errno: %i)\n",errno);
}
}
 
/* NOW we call the tracer initialization phase 2!!! */
/* It must FOLLOW the filesystem initialization... (this function */
/* can be called after the call to filesystem_init() functions but */
/* we do it here because we want be able to write into the /TEMP */
/* directory! */
TRC_init_phase2();
return 0;
}
 
void ctrlc_exit(KEY_EVT *k)
{
sys_end();
}
 
int main(int argc,char *argv[])
{
cprintf("\nHello, world!\n");
return 0;
}
/unsupported/branches/unsupported/tracer/small/treec1.c
0,0 → 1,220
/*
*
*
*
*/
 
#include <kernel/func.h>
#include <kernel/model.h>
 
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
#include <stdio.h>
#include <time.h>
 
#include "common.h"
 
#include <trace/trace.h>
#include <trace/queues.h>
 
 
int noscroll=0;
SEM console;
 
#define MPROC ((50<(MAX_PROC-10))?50:MAX_PROC-10)
 
TASK viewdir(void *prof);
sem_t actmutex,actsync;
char *globpathname;
PID globpid;
int counter=0,actcounter=0;
 
void activate_task(int prof, char *pathname)
{
char tname[32];
NRT_TASK_MODEL m;
PID pid;
 
REPEAT:
sem_wait(&actmutex);
 
if (actcounter>=MPROC) {
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 10000000;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
goto REPEAT;
}
globpathname=pathname;
counter++;
sprintf(tname,"tsk%i",counter);
 
nrt_task_default_model(m);
nrt_task_def_arg(m,(void*)counter);
globpid=pid=task_create(tname,viewdir,&m,NULL);
if (pid==-1) {
sem_wait(&console);
cprintf("can't create '%s'\n",tname);
perror("can't create task");
sem_signal(&console);
sys_end();
return;
}
task_activate(pid);
sem_wait(&actsync);
actcounter++;
 
sem_signal(&actmutex);
}
 
/*
*
*/
 
int filecounter=0;
 
TASK viewdir(void *pointer)
{
struct dirent *den;
struct stat st;
char *str;
DIR *d;
int res;
int x;
char pathname[1024];
PID mypid;
int prof=(int)pointer;
 
strcpy(pathname,globpathname);
mypid=globpid;
sem_signal(&actsync);
 
str=pathname+(x=strlen(pathname));
d=opendir(pathname);
if (d==NULL) {
sem_wait(&console);
cprintf("%03i ERR: can't open dir %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
goto END;
}
 
while ((den=readdir(d))!=NULL) {
 
if (x==1&&*pathname=='/')
strcat(pathname,den->d_name);
else
strcat(strcat(pathname,"/"),den->d_name);
 
sem_wait(&console);
if (noscroll) {
place(0,10);
cprintf(" ");
place(0,10);
}
cprintf("t%03i %s\n",prof,pathname);
filecounter++;
sem_signal(&console);
 
if (!strcmp(den->d_name,".")) goto SKIP;
if (!strcmp(den->d_name,"..")) goto SKIP;
 
res=stat(pathname,&st);
if (res!=0) {
sem_wait(&console);
cprintf("t%03i can't stat %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
closedir(d);
goto END;
} else {
if (S_ISDIR(st.st_mode)) {
sem_wait(&console);
sem_signal(&console);
activate_task(prof,pathname);
}
}
 
SKIP:
*str='\0';
}
 
closedir(d);
 
END:
sem_wait(&actmutex);
actcounter--;
sem_signal(&actmutex);
 
return 0;
}
 
/*
*
*/
 
int __register_sub_init_prologue(void)
{
TRC_init_phase1(NULL);
trc_register_circular_queue();
trc_create_queue(TRC_CIRCULAR_QUEUE,NULL);
return 0;
}
 
/*
*
*/
 
int main(int argc,char *argv[])
{
// int res;
 
showmessage("This test show all filenames of a directory of an hardisk\n"
"recursively using a soft task for every directory.\n"
"The tracer with a circular queue is activated.\n");
 
sem_init(&console,0,1);
sem_init(&actmutex,0,1);
sem_init(&actsync,0,0);
 
activate_task(-1,FROMDIR);
 
{
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 500000000;
for(;;) {
sem_wait(&actmutex);
if (actcounter==0) break;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
}
}
 
cprintf("\nfiles: %i\n",filecounter);
waitend();
return 0;
}
/unsupported/branches/unsupported/tracer/small/hello1.c
0,0 → 1,27
/*
*
*
*
*/
 
#include <ll/i386/cons.h>
#include <stddef.h>
 
#include <trace/trace.h>
#include <trace/queues.h>
 
int __register_sub_init_prologue(void)
{
TRC_init_phase1(NULL);
trc_register_dummy_queue();
trc_create_queue(TRC_DUMMY_QUEUE,NULL);
return 0;
}
 
int main(int argc,char *argv[])
{
cprintf("\nHello, world!\n");
cprintf("The tracer has been activated!\n");
cprintf("(No result are produced)\n\n");
return 0;
}
/unsupported/branches/unsupported/tracer/small/treec2.c
0,0 → 1,233
/*
*
*
*
*/
 
#include <kernel/func.h>
#include <kernel/model.h>
 
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
#include <stdio.h>
#include <time.h>
 
#include "common.h"
 
#include <trace/trace.h>
#include <trace/queues.h>
 
#define sem_signal sem_post
 
int noscroll=0;
SEM console;
 
#define MPROC ((50<(MAX_PROC-10))?50:MAX_PROC-10)
 
TASK viewdir(void *prof);
sem_t actmutex,actsync;
char *globpathname;
PID globpid;
int counter=0,actcounter=0;
 
void activate_task(int prof, char *pathname)
{
char tname[32];
NRT_TASK_MODEL m;
PID pid;
 
REPEAT:
sem_wait(&actmutex);
 
if (actcounter>=MPROC) {
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 10000000;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
goto REPEAT;
}
globpathname=pathname;
counter++;
sprintf(tname,"tsk%i",counter);
 
nrt_task_default_model(m);
nrt_task_def_arg(m,(void*)counter);
globpid=pid=task_create(tname,viewdir,&m,NULL);
if (pid==-1) {
sem_wait(&console);
cprintf("can't create '%s'\n",tname);
perror("can't create task");
sem_signal(&console);
sys_end();
return;
}
task_activate(pid);
sem_wait(&actsync);
actcounter++;
 
sem_signal(&actmutex);
}
 
/*
*
*/
 
int filecounter=0;
 
TASK viewdir(void *pointer)
{
struct dirent *den;
struct stat st;
char *str;
DIR *d;
int res;
int x;
char pathname[1024];
PID mypid;
int prof=(int)pointer;
 
strcpy(pathname,globpathname);
mypid=globpid;
sem_signal(&actsync);
 
str=pathname+(x=strlen(pathname));
d=opendir(pathname);
if (d==NULL) {
sem_wait(&console);
cprintf("%03i ERR: can't open dir %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
goto END;
}
 
while ((den=readdir(d))!=NULL) {
 
if (x==1&&*pathname=='/')
strcat(pathname,den->d_name);
else
strcat(strcat(pathname,"/"),den->d_name);
 
sem_wait(&console);
if (noscroll) {
place(0,10);
cprintf(" ");
place(0,10);
}
cprintf("t%03i %s\n",prof,pathname);
filecounter++;
sem_signal(&console);
 
if (!strcmp(den->d_name,".")) goto SKIP;
if (!strcmp(den->d_name,"..")) goto SKIP;
 
res=stat(pathname,&st);
if (res!=0) {
sem_wait(&console);
cprintf("t%03i can't stat %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
closedir(d);
goto END;
} else {
if (S_ISDIR(st.st_mode)) {
sem_wait(&console);
sem_signal(&console);
activate_task(prof,pathname);
}
}
 
SKIP:
*str='\0';
}
 
closedir(d);
 
END:
sem_wait(&actmutex);
actcounter--;
sem_signal(&actmutex);
 
return 0;
}
 
/*
*
*/
 
int __register_sub_init_prologue(void)
{
TRC_CIRCULAR_PARMS args;
int q;
TRC_init_phase1(NULL);
trc_register_circular_queue();
trc_circular_default_parms(args);
trc_circular_def_onlinetask(args);
q=trc_create_queue(TRC_CIRCULAR_QUEUE,&args);
 
trc_assign_class_to_queue(TRC_CLASS_SYSTEM,q);
trc_trace_class(TRC_CLASS_SYSTEM);
return 0;
}
 
/*
*
*/
 
int main(int argc,char *argv[])
{
// int res;
 
showmessage("This test show all filenames of a directory of an hardisk\n"
"recursively using a soft task for every directory.\n"
"The tracer with a circular queue is activated that write\n"
"on hardisk online (while the system is running)\n");
 
sem_init(&console,0,1);
sem_init(&actmutex,0,1);
sem_init(&actsync,0,0);
 
activate_task(-1,FROMDIR);
//activate_task(-1,"/");
 
{
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 500000000;
for(;;) {
sem_wait(&actmutex);
if (actcounter==0) break;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
}
}
 
cprintf("\nfiles: %i\n",filecounter);
waitend();
return 0;
}
/unsupported/branches/unsupported/tracer/small/hello2.c
0,0 → 1,30
/*
*
*
*
*/
 
#include <ll/i386/cons.h>
#include <stddef.h>
 
#include <trace/trace.h>
#include <trace/queues.h>
 
int __register_sub_init_prologue(void)
{
int q;
TRC_init_phase1(NULL);
trc_register_fixed_queue();
q=trc_create_queue(TRC_FIXED_QUEUE,NULL);
trc_assign_class_to_queue(TRC_CLASS_SYSTEM,q);
trc_trace_class(TRC_CLASS_SYSTEM);
return 0;
}
 
int main(int argc,char *argv[])
{
cprintf("\nHello, world!\n");
cprintf("The tracer has been activated! Look at the results.\n");
cprintf("(A fixed queue has been created)\n\n");
return 0;
}
/unsupported/branches/unsupported/tracer/small/treef1.c
0,0 → 1,224
/*
*
*
*
*/
 
#include <kernel/func.h>
#include <kernel/model.h>
 
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <semaphore.h>
#include <stdio.h>
#include <time.h>
 
#include "common.h"
 
#include <trace/trace.h>
#include <trace/queues.h>
 
#define sem_signal sem_post
 
int noscroll=0;
SEM console;
 
#define MPROC ((50<(MAX_PROC-10))?50:MAX_PROC-10)
 
TASK viewdir(void *prof);
sem_t actmutex,actsync;
char *globpathname;
PID globpid;
int counter=0,actcounter=0;
 
void activate_task(int prof, char *pathname)
{
char tname[32];
NRT_TASK_MODEL m;
PID pid;
 
REPEAT:
sem_wait(&actmutex);
 
if (actcounter>=MPROC) {
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 10000000;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
goto REPEAT;
}
globpathname=pathname;
counter++;
sprintf(tname,"tsk%i",counter);
 
nrt_task_default_model(m);
nrt_task_def_arg(m,(void*)counter);
globpid=pid=task_create(tname,viewdir,&m,NULL);
if (pid==-1) {
sem_wait(&console);
cprintf("can't create '%s'\n",tname);
perror("can't create task");
sem_signal(&console);
sys_end();
return;
}
task_activate(pid);
sem_wait(&actsync);
actcounter++;
 
sem_signal(&actmutex);
}
 
/*
*
*/
 
int filecounter=0;
 
TASK viewdir(void *pointer)
{
struct dirent *den;
struct stat st;
char *str;
DIR *d;
int res;
int x;
char pathname[1024];
PID mypid;
int prof=(int)pointer;
 
strcpy(pathname,globpathname);
mypid=globpid;
sem_signal(&actsync);
 
str=pathname+(x=strlen(pathname));
d=opendir(pathname);
if (d==NULL) {
sem_wait(&console);
cprintf("%03i ERR: can't open dir %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
goto END;
}
 
while ((den=readdir(d))!=NULL) {
 
if (x==1&&*pathname=='/')
strcat(pathname,den->d_name);
else
strcat(strcat(pathname,"/"),den->d_name);
 
sem_wait(&console);
if (noscroll) {
place(0,10);
cprintf(" ");
place(0,10);
}
cprintf("t%03i %s\n",prof,pathname);
filecounter++;
sem_signal(&console);
 
if (!strcmp(den->d_name,".")) goto SKIP;
if (!strcmp(den->d_name,"..")) goto SKIP;
 
res=stat(pathname,&st);
if (res!=0) {
sem_wait(&console);
cprintf("t%03i can't stat %s\n",prof,pathname);
cprintf("errno: %i '%s'\n",errno,strerror(errno));
sem_signal(&console);
 
sys_end();
l1_exit(0);
closedir(d);
goto END;
} else {
if (S_ISDIR(st.st_mode)) {
sem_wait(&console);
sem_signal(&console);
activate_task(prof,pathname);
}
}
 
SKIP:
*str='\0';
}
 
closedir(d);
 
END:
sem_wait(&actmutex);
actcounter--;
sem_signal(&actmutex);
 
return 0;
}
 
/*
*
*/
 
int __register_sub_init_prologue(void)
{
int q;
TRC_init_phase1(NULL);
trc_register_fixed_queue();
q=trc_create_queue(TRC_FIXED_QUEUE,NULL);
trc_assign_class_to_queue(TRC_CLASS_SYSTEM,q);
trc_trace_class(TRC_CLASS_SYSTEM);
return 0;
}
 
/*
*
*/
 
int main(int argc,char *argv[])
{
// int res;
 
showmessage("This test show all filenames of a directory of an hardisk\n"
"recursively using a soft task for every directory.\n"
"The tracer with a circular queue is activated.\n");
 
sem_init(&console,0,1);
sem_init(&actmutex,0,1);
sem_init(&actsync,0,0);
 
activate_task(-1,FROMDIR);
 
{
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = 500000000;
for(;;) {
sem_wait(&actmutex);
if (actcounter==0) break;
sem_signal(&actmutex);
nanosleep(&delay, NULL);
}
}
 
cprintf("\nfiles: %i\n",filecounter);
waitend();
return 0;
}
/unsupported/branches/unsupported/tracer/small/common.c
0,0 → 1,133
 
#include <kernel/func.h>
#include <tracer.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
 
#include <trace.h>
#include <queues.h>
 
#include <sys/mount.h>
 
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
 
int __register_sub_init(void)
{
return 0;
}
 
/* -- */
 
__dev_t root_device;
__dev_t temp_device;
 
int choose_root_callback(__dev_t dev,__uint8_t fs)
{
if (fs==FS_MSDOS) return dev;
return -1;
}
 
int choose_temp_callback(__dev_t dev,__uint8_t fs)
{
static int flag=0;
if (fs==FS_MSDOS) {
if (flag) return dev;
flag=1;
}
return -1;
}
 
/* -- */
 
extern int bdev_scan_devices(int(*callback)(__dev_t,__uint8_t));
 
int __bdev_sub_init(void)
{
BDEV_PARMS bdev=BASE_BDEV;
bdev_def_showinfo(bdev,FALSE);
bdev_init(&bdev);
 
root_device=bdev_scan_devices(choose_root_callback);
if (root_device<0) {
cprintf("can't find root device to mount on /!!!\n");
sys_end();
return -1;
}
 
temp_device=bdev_scan_devices(choose_temp_callback);
if (temp_device<0) {
cprintf("can't find a filesystem to mount on /TEMP!!!\n");
}
return 0;
}
 
/* -- */
 
extern int libc_initialize(void);
 
int __fs_sub_init(void)
{
FILESYSTEM_PARMS fs=BASE_FILESYSTEM;
struct mount_opts opts;
int res;
filesystem_def_rootdevice(fs,root_device);
filesystem_def_fs(fs,FS_MSDOS);
filesystem_def_showinfo(fs,FALSE);
 
 
//filesystem_init_prologue();
filesystem_init(&fs);
libc_initialize();
 
if (temp_device>=0) {
memset(&opts,0,sizeof(struct mount_opts));
opts.flags=MOUNT_FLAG_RW;
res=mount(temp_device,FS_MSDOS,"/TEMP",&opts);
if (res!=0) {
cprintf("can't mount XXX on /TEMP (errno: %i)\n",errno);
}
}
TRC_init_phase2();
return 0;
}
 
/* -- */
 
void ctrlc_exit(KEY_EVT *k)
{
extern void dump_sem_table(void);
extern void dump_nop_table(void);
//dump_sem_table();
//dump_nop_table();
sys_end();
}
 
/* -- */
 
void showmessage(char *s)
{
cputs(s);
cprintf("Press [x] to begin...");
while (keyb_getchar()!='x');
cprintf("\n");
}
 
void waitend(void)
{
int c;
cprintf("Press [x] to exit...");
while ((c=keyb_getchar())!='x');
cprintf("\n");
}
/unsupported/branches/unsupported/tracer/small/simple.c
0,0 → 1,132
/*
* Project: HARTIK (HA-rd R-eal TI-me K-ernel)
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
* Gerardo Lamastra <gerardo@sssup.it>
*
* Authors : Massimiliano Giorgi <massy@hartik.sssup.it>
* (see authors.txt for full list of hartik's authors)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: simple.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
/*
* Example of simple tracer initialization.
*/
 
#include <ll/i386/cons.h>
 
#include <kernel/func.h>
#include <trace.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
 
#include <trace.h>
 
#include <sys/mount.h>
#include <stddef.h>
 
#define ROOTDEVICE "ide/hda2"
 
int __register_sub_init_prologue(void)
{
int res;
/* tracer initialization phase 1 */
res=TRC_init_phase1_standard();
if (res!=0) {
cprintf("tracer initialization error (%i)!!!\n",res);
sys_end();
return -1;
}
return 0;
}
 
int __register_sub_init(void)
{
return 0;
}
 
__dev_t root_device;
 
int __bdev_sub_init(void)
{
/* block device initialization */
bdev_init(NULL);
 
/* choose root device */
root_device=bdev_find_byname(ROOTDEVICE);
if (root_device<0) {
cprintf("can't find root device to mount on /!!!\n");
sys_end();
return -1;
}
 
return 0;
}
 
int __fs_sub_init(void)
{
FILESYSTEM_PARMS fs=BASE_FILESYSTEM;
extern int libc_initialize(void);
 
/* filesystems initialization */
filesystem_def_rootdevice(fs,root_device);
filesystem_def_fs(fs,FS_MSDOS);
filesystem_def_showinfo(fs,FALSE);
filesystem_init(&fs);
 
/* libC initialization */
libc_initialize();
 
/* tracer initialization phase 2 */
TRC_init_phase2_standard();
return 0;
}
 
void ctrlc_exit(KEY_EVT *k)
{
sys_end();
}
 
int main(int argc,char *argv[])
{
cprintf("\nSimple hello world (with tracer)!\n\n");
return 0;
}
/unsupported/branches/unsupported/tracer/small/makefile
0,0 → 1,29
#
#
#
 
ifndef BASE
BASE=../../..
endif
include $(BASE)/config/config.mk
 
PROGS= simple hello hello1 hello2 test0 treef1 treec1 treec2
 
include $(BASE)/config/example.mk
 
simple:
make -f $(SUBMAKE) BASE=$(BASE) APP=simple OTHEROBJS=initfs.o SHARKOPT=__OLDCHAR__
hello:
make -f $(SUBMAKE) BASE=$(BASE) APP=hello OTHEROBJS=initfs.o SHARKOPT=__OLDCHAR__
hello1:
make -f $(SUBMAKE) BASE=$(BASE) APP=hello1 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
hello2:
make -f $(SUBMAKE) BASE=$(BASE) APP=hello2 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
test0:
make -f $(SUBMAKE) BASE=$(BASE) APP=test0 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
treef1:
make -f $(SUBMAKE) BASE=$(BASE) APP=treef1 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
treec1:
make -f $(SUBMAKE) BASE=$(BASE) APP=treec1 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
treec2:
make -f $(SUBMAKE) BASE=$(BASE) APP=treec2 OTHEROBJS="initfs.o common.o" SHARKOPT=__OLDCHAR__
/unsupported/branches/unsupported/tracer/small/initfs.c
0,0 → 1,119
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: initfs.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/rr.h"
#include "modules/cbs.h"
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
#include "modules/nopm.h"
 
#include "drivers/keyb.h"
 
/*+ sysyem tick in us +*/
#define TICK 1000
 
/*+ RR tick in us +*/
#define RRTICK 10000
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
extern int __register_sub_init_prologue(void);
extern int __register_sub_init(void);
 
__register_sub_init_prologue();
 
EDF_register_level(EDF_ENABLE_ALL);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
CBS_register_level(CBS_ENABLE_ALL, 0);
dummy_register_level();
 
SEM_register_module();
 
CABS_register_module();
 
PI_register_module();
PC_register_module();
NPP_register_module();
SRP_register_module();
NOP_register_module();
NOPM_register_module();
 
__register_sub_init();
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
KEYB_PARMS keyb = BASE_KEYB;
extern int __bdev_sub_init(void);
extern int __fs_sub_init(void);
extern void ctrlc_exit(KEY_EVT *k);
HARTPORT_init();
keyb_def_ctrlC(keyb, ctrlc_exit);
KEYB_init(&keyb);
 
__bdev_sub_init();
__fs_sub_init();
__call_main__(mb);
 
return (void *)0;
}
 
/unsupported/branches/unsupported/tracer/small/readme
0,0 → 1,27
This directory contains a set of tests that uses the Shark Filesystem and the tracer
 
treef1 - the test shows all filenames of a directory of an hardisk
recursively using a soft task for every directory.
The tracer with a circular queue is activated.
 
treec2 - the test shows all filenames of a directory of an hardisk
recursively using a soft task for every directory.
The tracer with a circular queue is activated that write
on hardisk online (while the system is running).
 
treec1 - This test show all filenames of a directory of an hardisk
recursively using a soft task for every directory.
The tracer with a circular queue is activated.
 
test0 - A file is opened for reading while the tracerwith a fixed
queue is runnig.
 
simple - Simple hello world (with tracer)!
 
hello - another hello world...
 
hello1 - another hello world with a dummy queue...
 
hello2 - another hello world with a fixed queue...
 
PJ
/unsupported/branches/unsupported/tracer/small/common.h
0,0 → 1,28
 
#ifndef _COMMON_H
#define _COMMON_H
 
#include <sys/types.h>
 
/*
#include <kernel/int_sem.h>
#define SEM internal_sem_t
#define sem_init internal_sem_init
#define sem_signal internal_sem_post
#define sem_wait internal_sem_wait
*/
 
#define SEM sem_t
#define sem_signal sem_post
 
extern __dev_t root_device;
extern __dev_t temp_device;
 
int choose_temp_callback(__dev_t dev,__uint8_t fs);
 
void showmessage(char *s);
void waitend(void);
 
#define FROMDIR "/TEMP"
 
#endif
/unsupported/branches/unsupported/tracer/udp/initfile.c
0,0 → 1,115
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: initfile.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1.1.1 $
* Last update: $Date: 2004-05-24 18:03:44 $
*/
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/rr.h"
#include "modules/cbs.h"
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
#include "modules/nopm.h"
 
#include "drivers/keyb.h"
 
/*+ sysyem tick in us +*/
#define TICK 0
 
/*+ RR tick in us +*/
#define RRTICK 10000
 
void mytracer_prologue(void);
void mytracer_epilogue(void);
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
mytracer_prologue();
 
EDF_register_level(EDF_ENABLE_ALL);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
CBS_register_level(CBS_ENABLE_ALL, 0);
dummy_register_level();
 
SEM_register_module();
 
CABS_register_module();
 
PI_register_module();
PC_register_module();
NPP_register_module();
SRP_register_module();
NOP_register_module();
NOPM_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
KEYB_PARMS keyb = BASE_KEYB;
extern void ctrlc_exit(KEY_EVT *k);
HARTPORT_init();
keyb_def_ctrlC(keyb, ctrlc_exit);
KEYB_init(&keyb);
 
mytracer_epilogue();
__call_main__(mb);
 
return (void *)0;
}
 
/unsupported/branches/unsupported/tracer/udp/udptrace.c
0,0 → 1,159
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
* Copyright (C) 2002 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: udptrace.c,v 1.1.1.1 2004-05-24 18:03:44 giacomo Exp $
*/
 
/*
* Example of tracer initialization.
*/
 
#include <ll/i386/cons.h>
 
#include <kernel/func.h>
 
#include <fs/bdevinit.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
 
#include <drivers/keyb.h>
#include <drivers/udpip.h>
 
#include <tracer.h>
#include <queues.h>
 
#include <sys/mount.h>
#include <stddef.h>
#include <string.h>
 
char myipaddr[15], toipaddr[15];
 
void mytracer_prologue(void)
{
int myqueue;
TRC_PARMS p;
TRC_UDP_PARMS u;
UDP_ADDR local, remote;
 
/* these are the IP numbers of my home PCs ;-) */
strcpy(myipaddr, "192.168.82.120");
strcpy(toipaddr, "192.168.82.20");
 
clear();
 
ip_str2addr(toipaddr,&(remote.s_addr));
remote.s_port = 20000; // htons is done automatically;
ip_str2addr(myipaddr,&(local.s_addr));
local.s_port = 20000; // htons is done automatically;
 
trc_default_parms(p);
trc_def_path(p,"");
 
trc_udp_default_parms(u,local,remote);
/* Tracer Initialization */
/* the first functions to call... parameters can be passed */
TRC_init_phase1(&p);
 
/* all the tracer queue types must be registered */
trc_register_udp_queue();
 
/* then, we create all the queues we need */
myqueue = trc_create_queue(TRC_UDP_QUEUE,&u);
 
/* Then, we say that events must be sent to a particular queue */
trc_trace_class(TRC_CLASS_SYSTEM);
trc_assign_class_to_queue(TRC_CLASS_SYSTEM, myqueue);
}
 
void mytracer_epilogue(void)
{
struct net_model m = net_base;
/* We want a task for TX mutual exclusion */
net_setmode(m, TXTASK);
/* We use UDP/IP stack */
net_setudpip(m, myipaddr, "255.255.255.255");
/* OK: let's start the NetLib! */
if (net_init(&m) == 1) {
cprintf("udptrace: Net Init OK...\n");
} else {
cprintf("udptrace: Net Init Failed...\n");
sys_abort(300);
}
TRC_init_phase2();
}
 
void ctrlc_exit(KEY_EVT *k)
{
sys_end();
}
 
void *mytask(void *arg)
{
int i;
 
for(i=0; i<10; i++) {
cprintf("%d\n", i);
task_endcycle();
}
 
return 0;
}
 
int main(int argc,char *argv[])
{
SOFT_TASK_MODEL mp;
 
PID pid;
 
soft_task_default_model(mp);
soft_task_def_met(mp, 10000);
soft_task_def_period(mp,50000);
soft_task_def_usemath(mp);
 
cprintf("\nHello, world!\n");
 
pid = task_create("mytask", mytask, &mp, NULL);
 
if (pid != NIL) task_activate(pid);
 
return 0;
}
/unsupported/branches/unsupported/tracer/udp/makefile
0,0 → 1,21
#
#
#
 
ifndef BASE
BASE=../../..
endif
 
include $(BASE)/config/config.mk
 
PROGS= udptrace
 
include $(BASE)/config/example.mk
 
udptrace:
make -f $(SUBMAKE) BASE=$(BASE) APP=udptrace INIT= OTHEROBJS=initfile.o OTHERINCL="-I$(BASE)/tracer/include" SHARKOPT=__OLDCHAR__
 
 
 
 
 
/unsupported/branches/unsupported/tracer/udp/readme
0,0 → 1,10
This is a simple test that uses the tracer.
 
The example assigns the IP address 192.168.1.2 to the machine, and
sends the tracer data to 192.168.1.1 using UDp, port 20000.
 
You can use demos/tracer/utils/udpdump to get the informations.
 
Enjoy,
 
PJ
/unsupported/branches/unsupported/tracer/makefile
0,0 → 1,11
.PHONY: all clean
 
all:
make -C dfixed
make -C small
make -C udp
 
clean:
make -C dfixed clean
make -C small clean
make -C udp clean
/unsupported/branches/unsupported/tracer/readme
0,0 → 1,14
This directory contains a set of sub directories containing all the tracer
examples and utilities.
 
Here a short description of the contents
 
utils - some small utilities that can read tracer files
dfixed - a small applications that defines a tracer queue.
At the end a file is written (using DOSFS).
small - a set of small examples of tracer usage (using the Shark Filesystem)
udp - a small application that sends its trace data through the network
 
Enjoy
 
PJ
/unsupported/branches/unsupported/rtdac4/test.c
0,0 → 1,53
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#include "kernel/kern.h"
 
#include "drivers/shark_keyb26.h"
#include "rtdac4.h"
 
int main(int argc, char **argv)
{
 
char ch,buf_char[4];
short buf_short[2];
long prescaler;
 
RTDAC4_open();
 
RTDAC4_read_states(buf_char);
buf_short[0] = 0;
buf_short[1] = 0;
 
RTDAC4_set_motor(buf_short);
 
/* Reset encoders */
RTDAC4_ioctl(1, 0);
 
prescaler = 0;
 
/* Set prescaler */
RTDAC4_ioctl(2, prescaler);
 
ch = keyb_getch(BLOCK);
 
sys_end();
 
return 0;
 
}
/unsupported/branches/unsupported/rtdac4/rtdac4.c
0,0 → 1,142
#include "kernel/kern.h"
 
#define BASE_ADDRESS 0xDC00 // Base address of PCI card
#define MAX_SIGNAL 650 // Max output signal
 
int i;
int b;
short tempNbr1, tempNbr2, tempNbr3, tempNbr4, tempNbr5;
 
int RTDAC4_open() {
 
printk("Init RT-DAC4/PCI - Base Address (%x)\n",(int)(BASE_ADDRESS));
 
return 0;
}
 
int RTDAC4_close() {
 
return 0;
}
 
/* Reads state information into vector buf.
Angle address: BASE_ADDRESS + 8 (16 bits)
Cart address: BASE_ADDRESS + 12 (16 bits)
*/
int RTDAC4_read_states(char *buf) {
for (i=0; i<2; i++) {
*(buf + i) = inp(BASE_ADDRESS + 4 +8 + i);
*(buf + 2 + i) = inp(BASE_ADDRESS + 4 + 12 + i);
}
return 0;
}
 
/* Control the electric motor.
Max output when testing: 650.
Max to motor: 1023.
*/
int RTDAC4_set_motor(const short *buff) {
unsigned short dir;
unsigned short brake;
unsigned short readBack;
if (BASE_ADDRESS == 0)
return 0;
dir = inp(BASE_ADDRESS + 4*0x24); // ?
brake = inp(BASE_ADDRESS + 4*0x25); // ?
tempNbr1 = (short) buff[0];
tempNbr2 = (short) buff[1];
if(abs(tempNbr1) <= MAX_SIGNAL) {
outpw(BASE_ADDRESS + 4*0x21, ((short) abs((int) tempNbr1)));
readBack = inpw(BASE_ADDRESS + 4*0x21);
if (readBack == 0)
brake = brake | 0x01;
else
brake = brake & 0xFE;
if ((short) tempNbr1 < 0)
dir = dir | 0x01;
else
dir = dir & 0xFE;
}
if(abs(tempNbr2) <= MAX_SIGNAL) {
outpw(BASE_ADDRESS + 4*0x22, ((short) abs((int) tempNbr2)));
readBack = inpw(BASE_ADDRESS + 4*0x22);
if (readBack == 0)
brake = brake | 0x02;
else
brake = brake & 0xFD;
if ((short) tempNbr1 < 0)
dir = dir | 0x02;
else
dir = dir & 0xFD;
}
outpw(BASE_ADDRESS + 4*0x24, dir);
outpw(BASE_ADDRESS + 4*0x25, brake);
return 0;
}
 
int RTDAC4_ioctl(unsigned int request, unsigned long l) {
/**
* Reset Encoders
*/
if(request == 1) {
unsigned short aux;
tempNbr1 = 0;
tempNbr2 = 0;
tempNbr3 = 0;
tempNbr4 = 0;
tempNbr5 = 0;
if ( BASE_ADDRESS == 0 )
{
printk("RTDAC4 ERROR: Reset encoders: BASE_ADDRESS = 0\n");
return -1;
}
aux = inp(BASE_ADDRESS + 4*0x05);
if( tempNbr1 == 0 ) aux = aux & 0x00FE;
if( tempNbr1 == 1 ) aux = aux | 0x0001;
if( tempNbr2 == 0 ) aux = aux & 0x00FD;
if( tempNbr2 == 1 ) aux = aux | 0x0002;
if( tempNbr3 == 0 ) aux = aux & 0x00FB;
if( tempNbr3 == 1 ) aux = aux | 0x0004;
if( tempNbr4 == 0 ) aux = aux & 0x00F7;
if( tempNbr4 == 1 ) aux = aux | 0x0008;
if( tempNbr5 == 0 ) aux = aux & 0x00EF;
if( tempNbr5 == 1 ) aux = aux | 0x0010;
outp(BASE_ADDRESS + 4*0x05, aux);
aux = inp(BASE_ADDRESS + 4*0x05);
return 0;
}
/**
* Prescaler.
*/
else if(request == 2) {
tempNbr1 = (short) l;
if ( BASE_ADDRESS == 0 ) {
return -1;
}
if( ( tempNbr1 >= 0 ) && ( tempNbr1 <= 63 ) )
{
outp(BASE_ADDRESS + 4*0x18, tempNbr1);
}
return 0;
}
return 0;
}
 
/unsupported/branches/unsupported/rtdac4/initfile.c
0,0 → 1,164
/*
* Project: S.Ha.R.K
*
* Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://hartik.sssup.it
*/
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/cbs.h"
#include "modules/rr.h"
#include "modules/dummy.h"
#include "modules/intdrive.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
 
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
 
#include <drivers/shark_linuxc26.h>
#include <drivers/shark_input26.h>
#include <drivers/shark_keyb26.h>
 
#define FRAME_BUFFER_DEVICE 0
 
/*+ sysyem tick in us +*/
#define TICK 0
 
/*+ RR tick in us +*/
#define RRTICK 10000
 
/*+ Interrupt Server +*/
#define INTDRIVE_Q 1000
#define INTDRIVE_T 10000
#define INTDRIVE_FLAG 0
 
void call_shutdown_task(void *arg);
int device_drivers_init();
int device_drivers_close();
void set_shutdown_task();
TASK shutdown_task_body(void *arg);
 
PID shutdown_task_PID = 1;
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
INTDRIVE_register_level(INTDRIVE_Q,INTDRIVE_T,INTDRIVE_FLAG);
EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL, 1);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
 
SEM_register_module();
 
PI_register_module();
PC_register_module();
NPP_register_module();
SRP_register_module();
NOP_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
HARTPORT_init();
 
/* Create the shutdown task. It will be activated at RUNLEVEL
SHUTDOWN */
set_shutdown_task();
 
/* Init the drivers */
device_drivers_init();
 
/* Set the shutdown task activation */
sys_atrunlevel(call_shutdown_task, NULL, RUNLEVEL_SHUTDOWN);
 
__call_main__(mb);
 
return (void *)0;
}
 
void set_shutdown_task() {
 
/* WARNING: the shutdown task is a background thread. It cannot execute
if the system is overloaded */
NRT_TASK_MODEL nrt;
 
nrt_task_default_model(nrt);
nrt_task_def_system(nrt);
 
shutdown_task_PID = task_create("Shutdown Task",shutdown_task_body,&nrt,NULL);
if (shutdown_task_PID == NIL) {
sys_shutdown_message("Error: Cannot create shutdown task\n");
sys_end();
}
 
}
 
int device_drivers_init() {
 
KEYB_PARMS kparms = BASE_KEYB;
LINUXC26_register_module();
 
INPUT26_init();
 
keyb_def_ctrlC(kparms, NULL);
 
KEYB26_init(&kparms);
 
return 0;
 
}
 
int device_drivers_close() {
KEYB26_close();
INPUT26_close();
return 0;
}
 
#define SHUTDOWN_TIMEOUT_SEC 3
 
void call_shutdown_task(void *arg)
{
struct timespec t;
 
sys_gettime(&t);
t.tv_sec += SHUTDOWN_TIMEOUT_SEC;
 
/* Emergency timeout to exit from RUNLEVEL_SHUTDOWN */
kern_event_post(&t,(void *)((void *)sys_abort_shutdown),(void *)0);
 
task_activate(shutdown_task_PID);
}
 
TASK shutdown_task_body(void *arg) {
 
device_drivers_close();
 
sys_shutdown_message("-- S.Ha.R.K. Closed --\n");
 
sys_abort_shutdown(0);
 
return NULL;
 
}
/unsupported/branches/unsupported/rtdac4/rtdac4.h
0,0 → 1,25
#ifndef __RTDAC4__
#define __RTDAC4__
 
/* Open the RT-DAC4/PCI card */
int RTDAC4_open(void);
 
/* Close the RT-DAC4/PCI card */
int RTDAC4_close(void);
 
/* Reads state information into vector buf.
Angle address: BASE_ADDRESS + 8 (16 bits)
Cart address: BASE_ADDRESS + 12 (16 bits)
*/
int RTDAC4_read_states(char *buf);
 
/* Control the electric motor.
Max output when testing: 650.
Max to motor: 1023.
*/
int RTDAC4_set_motor(const short *buff);
 
/* IOCTL emulation */
int RTDAC4_ioctl(unsigned int request, unsigned long l);
 
#endif
/unsupported/branches/unsupported/rtdac4/makefile
0,0 → 1,16
#
#
#
 
ifndef BASE
BASE=../..
endif
include $(BASE)/config/config.mk
 
PROGS= test
 
include $(BASE)/config/example.mk
 
test:
make -f $(SUBMAKE) APP=test INIT= OTHEROBJS="initfile.o rtdac4.o" SHARKOPT="__LINUXC26__ __PCI__ __INPUT__"
 
/unsupported/branches/unsupported/oscilloscopio/osc.c
0,0 → 1,871
/*****************************************************************************
* Filename: osc.c *
* Author: Ghiro Andrea,Franchino Gianluca *
* Date: 09/2003 *
* Description: Oscilloscope and function generator for PCI6025E *
*----------------------------------------------------------------------------*
* Notes: Connect DAC output pin (21) to ADC input pins (3-18) and *
* watch the waveforms. *
*****************************************************************************/
 
/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
*
* Copyright (C) 2003 Ghiro Andrea,Franchino Gianluca
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
 
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <math.h>
#include <drivers/pci6025e/dac.h>
#include <modules/hartport.h>
#include <modules/srp.h>
#include "adc.h"
 
#define MAX_VAL 500
#define NUM_POINT 20
#define GRAPH_PERIOD 50000
#define GRAPH_WCET 2000
#define WAVE_WCET 200
#define OSC_WCET 200
#define TASK_GROUP 1
#define CHFREQ_PERIOD 5000
#define CHFREQ_WCET 200
 
void drawInterface(void);
void endfun(KEY_EVT *);
void close_event(void *);
void createWaves(void);
void change_disp(KEY_EVT *);
void change_mode(KEY_EVT *);
void change_wave(KEY_EVT *);
void change_passo(KEY_EVT *);
void change_channel(KEY_EVT *);
void inc(KEY_EVT *);
void dec(KEY_EVT *);
 
TASK video_body(int);
TASK wave_body(int);
TASK osc_body(int);
TASK chfreq_body(int);
 
HARD_TASK_MODEL wave0;
HARD_TASK_MODEL chfreq;
HARD_TASK_MODEL osc;
SRP_RES_MODEL r;
SRP_mutexattr_t a;
 
PID wave0_pid;
PID chfreq_pid;
PID osc_pid;
 
mutex_t m1 ;
 
int black = rgb16(0,0,0),
white = rgb16(255, 255, 255);
 
int wave = 3,
varfun = 0,
varosc = 0,
flagch = 0,
channel = 0;
 
float vfun = 0,
vosc = 2.5,
ffun = 1,
tbase = 75,
yr[MAX_VAL],
yrdac[NUM_POINT],
ys[MAX_VAL],
ysdac[NUM_POINT],
yq[MAX_VAL],
yqdac[NUM_POINT];
 
BYTE disp = 0,
modefun= 0,
modeosc= 0,
lib = 0,
sys = 0;
 
short yoscold[MAX_VAL];
 
unsigned int period= 1e6/NUM_POINT;
unsigned int oscperiod = 1500;
 
int main(int argc, char **argv)
{
KEY_EVT k;
 
HARD_TASK_MODEL video;
PID video_pid;
 
int modenum;
 
k.flag = CNTR_BIT;
k.scan = KEY_X;
k.ascii = 'x';
keyb_hook(k, endfun);
k.flag = CNTL_BIT;
keyb_hook(k, endfun);
k.flag = 0;
k.scan = KEY_A;
k.ascii = 'a';
keyb_hook(k, change_disp);
 
k.flag = 0;
k.scan = KEY_S;
k.ascii = 's';
keyb_hook(k, change_mode);
 
k.flag = 0;
k.scan = KEY_F;
k.ascii = 'f';
keyb_hook(k, change_wave);
k.flag = 0;
k.scan = KEY_G;
k.ascii = 'g';
keyb_hook(k, change_wave);
k.flag = 0;
k.scan = KEY_H;
k.ascii = 'H';
keyb_hook(k, change_wave);
k.flag = 0;
k.scan = KEY_D;
k.ascii = 'd';
keyb_hook(k, change_passo);
 
k.flag = 0;
k.scan = KEY_J;
k.ascii = 'j';
keyb_hook(k, change_channel);
 
k.flag = 0;
k.scan = 78;
k.ascii = 43;
keyb_hook(k, inc);
 
k.flag = 0;
k.scan = 74;
k.ascii = 45;
keyb_hook(k, dec);
 
sys_atrunlevel(close_event, NULL, RUNLEVEL_BEFORE_EXIT);
 
/*initialize the srp mutex*/
SRP_mutexattr_default(a);
mutex_init(&m1,&a);
 
hard_task_default_model(wave0);
hard_task_def_wcet(wave0, WAVE_WCET);
hard_task_def_mit(wave0, period);
hard_task_def_group(wave0, TASK_GROUP);
if( (wave0_pid = task_create("Wave 0", wave_body, &wave0, NULL)) == NIL )
{
sys = 10;
sys_end();
}
 
hard_task_default_model(video);
hard_task_def_wcet(video, GRAPH_WCET);
hard_task_def_mit(video, GRAPH_PERIOD);
hard_task_def_group(video, TASK_GROUP);
SRP_res_default_model(r,2);
if( (video_pid = task_createn("Video task", video_body, &video, &r,
SRP_usemutex(&m1), NULL))== NIL )
{
sys = 12;
sys_end();
}
 
hard_task_default_model(osc);
hard_task_def_wcet(osc, OSC_WCET);
hard_task_def_mit(osc, oscperiod);
hard_task_def_group(osc, TASK_GROUP);
SRP_res_default_model(r,1);
if((osc_pid = task_createn("osc task", osc_body, &osc, &r,
SRP_usemutex(&m1), NULL))== NIL )
{
sys = 11;
sys_end();
}
 
hard_task_default_model(chfreq);
hard_task_def_wcet(chfreq, CHFREQ_WCET);
hard_task_def_mit(chfreq, CHFREQ_PERIOD);
hard_task_def_group(chfreq, TASK_GROUP);
if( (chfreq_pid = task_create("chfreq", chfreq_body, &chfreq, NULL)) == NIL )
{
sys = 13;
sys_end();
}
 
if(grx_init() == -1)
{
sys = 30;
sys_end();
}
 
if((modenum = grx_getmode(800, 600, 16)) == -1)
{
sys = 31;
sys_end();
}
 
if(pci_init() == -1)
{
sys = 20;
sys_end();
}
 
if(!reMap())
{
sys = 21;
sys_end();
}
 
grx_setmode(modenum);
 
createWaves();
drawInterface();
 
DAC_Init(); //Program the DAQ-STC AOTM
Configure_Board(channel); //Configure the board with the channel settings.
ADC_Init(); //Program the DAQ-STC AITM
group_activate(TASK_GROUP);
 
return 0;
}
 
void endfun(KEY_EVT *k)
{
sys_end();
}
 
void close_event(void *arg)
{
grx_close();
switch(sys)
{
case 0: cprintf("Regular End!\n"); break;
case 10: cprintf("Cannot create <wave 0> task!\n"); break;
case 11: cprintf("Cannot create <osc> task!\n"); break;
case 12: cprintf("Cannot create <video> task!\n"); break;
case 13: cprintf("Cannot create <chfreq> task!\n"); break;
case 14: cprintf("Cannot kill <wave 0> task!\n"); break;
case 15: cprintf("Cannot kill <osc> task\n");break;
case 20: cprintf("No PCI bus found!\n"); break;
case 21: cprintf("No NATIONAL PCI E-Series board found on PCI bus!\n");break;
case 30: cprintf("Cannot start graphic envirorment!\n"); break;
case 31: cprintf("800x600x16 video mode not supported!\n");break;
default: cprintf("Unknown exit event!\n"); break;
}
}
 
/*
* kill wave0 or osc when frequency change
*/
 
TASK chfreq_body(int w)
{
PORT p;
char msg[1];
p = port_create("activation",1,1,STREAM,WRITE);
 
while(1)
{
if(flagch == 1)
{
if(task_kill(wave0_pid)!=0)
{
sys=14;
sys_end();
}
hard_task_def_mit(wave0, period);
if( (wave0_pid = task_create("wave 0", wave_body, &wave0, NULL))== NIL )
{
sys = 10;
sys_end();
}
flagch = 0;
task_activate(wave0_pid);
}
 
if(flagch == 2)
{
if(task_kill(osc_pid)!=0)
{
sys=15;
sys_end();
}
hard_task_def_mit(osc, oscperiod);
if( (osc_pid = task_createn("osc", osc_body, &osc, &r,
SRP_usemutex(&m1), NULL))== NIL )
{
sys = 11;
sys_end();
}
flagch = 0;
msg[0]=1;
port_send(p,msg,NON_BLOCK);
}
task_endcycle();
}
}
 
/*
* acquisition of input samples
*/
 
TASK osc_body(int wv)
{
int i = 0 ;
short y = 0;
WORD Status = 0;
 
while(1)
{
mutex_lock(&m1);
if(lib)
{
mutex_unlock(&m1);
AI_Start_The_Acquisition();
do {
Status = DAQ_STC_Windowed_Mode_Read(AI_STATUS_1);
if (!( (Status & 0x1000) == 0x1000 ) )
y = Immediate_Readw(ADC_DATA_READ);
} while(((Status & 0x1000) == 0x1000));
y = (2.5/vosc)*(y-40)/20;
if(abs(y)<=100)
{
grx_plot(19+i,483-y,rgb16(255,255,0));
}
yoscold[i]=y;
i=(i+1)%500;
if(i==0)
{
mutex_lock(&m1);
lib=0;
mutex_unlock(&m1);
task_testcancel();
}
}
else mutex_unlock(&m1);
task_endcycle();
}
}
 
/*
* Sends out waves' samples
*/
 
TASK wave_body(int wv)
{
int i = 0;
int y = 0;
while(1)
{
if(wave==0)
{
y=vfun*(yrdac[i]*20);
y=(y & 0x0FFF);
}
if(wave==1)
{
y=vfun*(ysdac[i]*20);
y=(y & 0x0FFF);
}
if(wave==2)
{
y=vfun*(yqdac[i]*20);
y=(y & 0x0FFF);
}
DAC_output(DAC1,y);
i = (i + 1) % NUM_POINT;
task_testcancel();
task_endcycle();
}
}
 
/*
* Shows setting,wave,grid and clear display
*/
 
TASK video_body(int dummy)
{
BYTE dispold = 1,
modefunold = 1,
modeoscold = 1,
new = 0;
 
int waveold = 3,
varfunold = 2,
i = 0,
y = 0,
channelold = 16,
yold[MAX_VAL];
 
 
float vfunold = 1,
voscold = 1,
ffunold = 0,
tbaseold = 1;
char st[20];
 
PORT p;
char msg[1];
p=port_connect("activation",1,STREAM,READ);
 
while(1)
{
mutex_lock(&m1);
if(!lib)
{
mutex_unlock(&m1);
for(i=0;i<MAX_VAL;i++)
{
if(abs(yoscold[i])<=100)
{
grx_plot(19+i,483-yoscold[i],rgb16(0,0,0));
}
}
//OSCILLOSCOPE GRID
grx_line(19, 385, 519, 385, rgb16(150,150,150));
grx_line(19, 410, 519, 410, rgb16(150,150,150));
grx_line(19, 435, 519, 435, rgb16(150,150,150));
grx_line(19, 460, 519, 460, rgb16(150,150,150));
grx_line(19, 485, 519, 485, rgb16(150,150,150));
grx_line(19, 510, 519, 510, rgb16(150,150,150));
grx_line(19, 535, 519, 535, rgb16(150,150,150));
grx_line(19, 560, 519, 560, rgb16(150,150,150));
grx_line(19, 585, 519, 585, rgb16(150,150,150));
grx_line(19, 385, 19, 585, rgb16(150,150,150));
grx_line(69, 385, 69, 585, rgb16(150,150,150));
grx_line(119, 385, 119, 585, rgb16(150,150,150));
grx_line(169, 385, 169, 585, rgb16(150,150,150));
grx_line(219, 385, 219, 585, rgb16(150,150,150));
grx_line(269, 385, 269, 585, rgb16(150,150,150));
grx_line(319, 385, 319, 585, rgb16(150,150,150));
grx_line(369, 385, 369, 585, rgb16(150,150,150));
grx_line(419, 385, 419, 585, rgb16(150,150,150));
grx_line(469, 385, 469, 585, rgb16(150,150,150));
grx_line(519, 385, 519, 585, rgb16(150,150,150));
mutex_lock(&m1);
lib=1;
mutex_unlock(&m1);
port_receive(p,msg,NON_BLOCK);
if(msg[0]==1)
{
task_activate(osc_pid);
}
}
else mutex_unlock(&m1);
if(disp != dispold)
{
dispold = disp;
grx_disc(780,120,10,rgb16(255*(1-disp),0,0));
grx_disc(780,390,10,rgb16(0,255*disp,0));
}
if(modefun != modefunold)
{
modefunold = modefun;
grx_disc(780,237,5,rgb16(255*(1-modefun),0,0));
grx_disc(780,267,5,rgb16(255*(modefun),0,0));
}
if(modeosc != modeoscold)
{
modeoscold = modeosc;
grx_disc(780,502,5,rgb16(0,255*(1-modeosc),0));
grx_disc(780,532,5,rgb16(0,255*(modeosc),0));
}
if(wave != waveold)
{
waveold = wave;
grx_disc(730,127,3,rgb16(127*(1-wave)*(2-wave),0,0));
grx_disc(730,142,3,rgb16(254*wave*(2-wave),0,0));
grx_disc(730,157,3,rgb16(254*wave*(wave-1),0,0));
new=1;
}
if(varfun != varfunold)
{
varfunold = varfun;
grx_disc(675,292,3,rgb16(42*(1-varfun)*(2-varfun)*(3-varfun),0,0));
grx_disc(775,292,3,rgb16(126*varfun*(2-varfun)*(3-varfun),0,0));
grx_disc(675,307,3,rgb16(252*varfun*(varfun-1)*(3-varfun),0,0));
grx_disc(775,307,3,rgb16(42*varfun*(varfun-1)*(varfun-2),0,0));
}
 
if(channel != channelold)
{
sprintf(st,"%2d",channel);
grx_text(" ",660,470,black,white);
grx_text(st,660,470,black,white);
}
 
if(ffun != ffunold)
{
ffunold = ffun;
sprintf(st,"%10f",ffun);
grx_text(" ",660,265,black,white);
grx_text(st,660,265,black,white);
}
if(tbase != tbaseold)
{
tbaseold = tbase;
sprintf(st,"%10f",tbase);
grx_text(" ",660,530,black,white);
grx_text(st,660,530,black,white);
}
if(vfun != vfunold)
{
vfunold = vfun;
sprintf(st,"%3.1f",vfun);
grx_text(" ",660,235,black,white);
grx_text(st,660,235,black,white);
new=1;
}
if(vosc != voscold)
{
voscold = vosc;
sprintf(st,"%3.1f",vosc);
grx_text(" ",660,500,black,white);
grx_text(st,660,500,black,white);
}
if(new)
{
for(i=0; i<MAX_VAL; i++)
{
grx_plot(19+i, 215-yold[i],rgb16(0, 0, 0));
}
//FUNCTION GENERATOR GRID
grx_line(22, 115, 525, 115, rgb16(150,150,150));
grx_line(22, 165, 525, 165, rgb16(150,150,150));
grx_line(22, 265, 525, 265, rgb16(150,150,150));
grx_line(22, 315, 525, 315, rgb16(150,150,150));
grx_line(19, 110, 19, 320, rgb16(150,150,150));
grx_line(14, 215, 525, 215, rgb16(150,150,150));
if(wave==0)
{
for(i=0;i<MAX_VAL;i++)
{
y=(vfun)*yr[i];
grx_plot(19+i,215-y,rgb16(255,255,0));
yold[i]=y;
}
}
if(wave==1)
{
for(i=0;i<MAX_VAL;i++)
{
y=(vfun)*ys[i];
grx_plot(19+i,215-y,rgb16(255,255,0));
yold[i]=y;
}
}
if(wave==2)
{
for(i=0;i<MAX_VAL;i++)
{
y=(vfun)*yq[i];
grx_plot(19+i,215-y,rgb16(255,255,0));
yold[i]=y;
}
}
 
new=0;
}
task_endcycle();
}
}
 
/*
* create wave triangular,sinusoidal and square
*/
 
void createWaves(void)
{
float u=0,
qdac= 2*PI/NUM_POINT,
q = 2*PI/(MAX_VAL/2);
 
register int i;
 
BYTE direction=0;
/*create the vectors for the video task*/
for(i=0;i<MAX_VAL/2;i++)
{
yr[i]=yr[i+MAX_VAL/2]=u/10;
if(!direction) u += 1.613;
else u -= 1.613;
if(u >= 100) direction = 1;
if(u <= -101) direction = 0;
ys[i]=ys[i+MAX_VAL/2] = (sin(i*q)*10);
 
if((i>=(MAX_VAL/4) && i< (MAX_VAL/2))) yq[i]=yq[i+MAX_VAL/2]=0;
else yq[i]=yq[i+MAX_VAL/2]=10;
}
/*create the vectors for the wave_body task*/
direction=0;
u = 0;
for(i=0;i<NUM_POINT;i++)
{
yrdac[i]=u/10;
if(!direction) u += (400/NUM_POINT);
else u -= (400/NUM_POINT);
if(u >= 100) direction = 1;
if(u <= -100) direction = 0;
ysdac[i]=(sin(i*qdac)*10);
 
if((i>=(NUM_POINT/2) && i<NUM_POINT)) yqdac[i]=0;
else yqdac[i]=10;
}
}
 
/*
* select device (0 function generator,1 oscilloscope)
*/
 
void change_disp(KEY_EVT *k)
{
if(disp) disp = 0;
else disp = 1;
}
 
/*
* select volt or frequency
*/
 
void change_mode(KEY_EVT *k)
{
if(disp && modeosc) modeosc = 0;
else
if(disp && !modeosc) modeosc = 1;
else
if(!disp && modefun) modefun = 0;
else
if(!disp && !modefun) modefun =1;
}
 
/*
* select wave (0 triangular,1 sinusoindal,2 square
*/
 
void change_wave(KEY_EVT *k)
{
if(!disp && k->ascii =='f')
{
wave=0;
}
else
if(!disp && k->ascii =='g')
{
wave=1;
}
else
if(!disp && k->ascii =='h')
{
wave=2;
}
}
 
/*
* select increase or decrease step
*/
 
void change_passo(KEY_EVT *k)
{
if(!disp && modefun)
{
varfun=(varfun+1)%2;
}
}
 
/*
* select input channel
*/
 
void change_channel(KEY_EVT *k)
{
if(disp)
{
channel=(channel+1)%16;
Configure_Board(channel);
}
}
 
/*
* increase selected variable
*/
 
void inc(KEY_EVT *k)
{
if(disp && modeosc && tbase<300)
{
flagch=2;
switch(varosc)
{
case(0): tbase = tbase*2;
oscperiod=(tbase/50)*1000;
break;
}
}
else
if(disp && !modeosc && vosc<10) vosc += 0.1;
else
if(!disp && modefun && ffun<(1e6/(1020*NUM_POINT))-1)
{
flagch=1;
switch(varfun)
{
case(0): ffun += 1;
period = 1e6/(NUM_POINT*ffun);
break;
case(1): ffun += 10;
period = 1e6/(NUM_POINT*ffun);
break;
}
}
else
if(!disp && !modefun && vfun<10) vfun += 0.1;
}
 
/*
* decrease selected variable
*/
 
void dec(KEY_EVT *k)
{
if(disp && modeosc && tbase> 75)
{
flagch=2;
switch(varosc)
{
case(0): tbase = tbase/2;
oscperiod=(tbase/50)*1000;
break;
}
}
else
if(disp && !modeosc && vosc> 0.2) vosc -= 0.1;
else
if(!disp && modefun && ffun> 0)
{
flagch = 1;
switch(varfun)
{
case(0): ffun -= 1;
if(ffun == 0) period =1e6;
else
period = 1e6/(NUM_POINT*ffun);
break;
case(1): ffun -= 10;
if(ffun == 0) period =1e6;
else
period = 1e6/(NUM_POINT*ffun);
break;
}
}
else
if(!disp && !modefun && vfun> -10) vfun -= 0.1;
}
 
/*
* draw interface
*/
 
void drawInterface(void)
{
//TITLE
grx_rect(1, 1, 799, 69, rgb16(105, 0, 105));
grx_rect(2, 2, 798, 68, rgb16(155, 0, 155));
grx_rect(3, 3, 797, 67, rgb16(205, 0, 205));
grx_rect(4, 4, 796, 66, rgb16(255, 0, 255));
grx_text("Oscilloscope and function generator for PCI6025E",7, 10, rgb16(50, 255, 50), black);
grx_text("Pin ADC 3-18, DAC 21",7, 25, rgb16(0, 255, 255), black);
grx_text("A for select Oscilloscope or Function generator",7, 40, rgb16(0, 255, 255), black);
grx_text("CTRL-X for Exit", 7, 55, rgb16(200, 200, 0), black);
 
//FUNCTION GENERATOR
grx_text("FUNCTION GENERATOR", 100, 92, rgb16(200, 200, 0), black);
grx_rect(1, 100, 549, 325, rgb16(0, 105, 0));
grx_rect(2, 101, 548, 324, rgb16(0, 155, 0));
grx_rect(3, 102, 547, 323, rgb16(0, 205, 0));
grx_rect(4, 103, 546, 322, rgb16(0, 255, 0));
grx_rect(579, 100, 799, 325, rgb16(0, 105, 0));
grx_rect(580, 101, 798, 324, rgb16(0, 155, 0));
grx_rect(581, 102, 797, 323, rgb16(0, 205, 0));
grx_rect(582, 103, 796, 322, rgb16(0, 255, 0));
grx_text("Wave selection",589,110,rgb16(0, 255, 0), black);
grx_text("f -->triangular",589,125,rgb16(200, 200, 0), black);
grx_text("g -->sin",589,140,rgb16(200, 200, 0), black);
grx_text("h -->square",589,155,rgb16(200, 200, 0), black);
grx_text("s -->select volt/freq",589,180,rgb16(200, 200, 0), black);
grx_text("+/- -->set volt/freq",589,195,rgb16(200, 200, 0), black);
grx_text("d -->frequency increase",589,210,rgb16(200, 200, 0),black);
grx_text("Vpicco V",589,235,rgb16(0, 255, 0),black);
grx_text("Freq Hz",589,265,rgb16(0, 255, 0),black);
grx_text("+/- 1 Hz",589,290,rgb16(0, 255, 0),black);
grx_text("+/- 10 HZ",689,290,rgb16(0, 255, 0),black);
//OSCILLOSCOPE
grx_text("OSCILLOSCOPE", 100, 362, rgb16(200, 200, 0), black);
grx_rect(1, 370, 549, 595, rgb16(105, 0, 0));
grx_rect(2, 371, 548, 594, rgb16(155, 0, 0));
grx_rect(3, 372, 547, 593, rgb16(205, 0, 0));
grx_rect(4, 373, 546, 592, rgb16(255, 0, 0));
grx_rect(579, 370, 799, 595, rgb16(105, 0, 0));
grx_rect(580, 371, 798, 594, rgb16(155, 0, 0));
grx_rect(581, 372, 797, 593, rgb16(205, 0, 0));
grx_rect(582, 373, 796, 592, rgb16(255, 0, 0));
grx_text("Scale selection",589,380,rgb16(255, 0, 0), black);
grx_text("s -->select volt/freq",589,400,rgb16(200, 200, 0), black);
grx_text("+/- -->set volt/freq",589,415,rgb16(200, 200, 0), black);
grx_text("j -->change channel",589,430,rgb16(200, 200, 0),black);
grx_text("Channel",589,470,rgb16(255, 0, 0),black);
grx_text("Volt/div V",589,500,rgb16(255, 0, 0),black);
grx_text("Time/div ms",589,530,rgb16(255, 0, 0),black);
 
//LABEL
grx_text("0 V", 555, 211, rgb16(0, 255, 0), black);
grx_text("+10", 555, 111, rgb16(0, 255, 0), black);
grx_text("+5", 555, 161, rgb16(0, 255, 0), black);
grx_text("-5", 555, 261, rgb16(0, 255, 0), black);
grx_text("-10", 555, 311, rgb16(0, 255 , 0), black);
grx_text("0 V", 555, 481, rgb16(255, 0, 0), black);
}
/unsupported/branches/unsupported/oscilloscopio/adc.c
0,0 → 1,400
/*****************************************************************************
* Filename: ADC.C *
* Author: Ghiro Andrea,Franchino Gianluca *
* Date: 06/06/2001 *
* Description: Analog 2 digital conversion functions *
*----------------------------------------------------------------------------*
* Notes: Funcion for one sample from Ch0 *
*****************************************************************************/
 
/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
*
* Copyright (C) 2003 Ghiro Andrea,Franchino Gianluca
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#include "adc.h"
 
/*
* Call this function to configure board options.
*/
 
void Configure_Board(BYTE numch)
{
WORD memhi;
/*
* Writing to register Write_Strobe_0_Register with address 82.
* Write_Strobe_0 <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(WRITE_STROBE_0,0x0001);
/*
* Writing to register Write_Strobe_1_Register with address 83.
* Write_Strobe_1 <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(WRITE_STROBE_1,0x0001);
 
/*
* Writing to register Config_Memory_High_Register with address 18.
* CM_Channel_Number <= channel_number (0)
* CM_Channel_Bank <= channel_bank (0)
* CM_Channel_Type <= channel_type_for_rev_b (3)
* New pattern = 0x3000
*/
memhi = 0x3000 | numch;
Immediate_Writew(ADC_CONFIG_HI,memhi);
 
/*
* Writing to register Config_Memory_Low_Register with address 16.
* CM_Last_Channel <= last_channel (1)
* CM_Trigger <= trigger (0)
* CM_AI_Gain <= ai_gain (1)
* CM_AI_Polarity <= ai_polarity (0)
* CM_AI_Dither_Enable <= ai_dither_enable (0)
* New pattern = 0x8001
*/
Immediate_Writew(ADC_CONFIG_LO,0x8100);
return;
}
 
/*
* program the ADC_STC
*/
void ADC_Init()
{
/*
* configure the timebase options.
*/
/*
* Writing to register Clock_and_FOUT_Register with address 56.
* Slow_Internal_Timebase <= p->msc_slow_int_tb_enable (1)
* Slow_Internal_Time_Divide_By_2 <= p->msc_slow_int_tb_divide_by_2 (1)
* Clock_To_Board <= p->msc_clock_to_board_enable (1)
* Clock_To_Board_Divide_By_2 <= p->msc_clock_to_board_divide_by_2 (1)
* New pattern = 0x1B00
*/
DAQ_STC_Windowed_Mode_Write(CLOCK_AND_FOUT,0x1B00);
 
/*
* clear the AI FIFO.
*/
/*
* Writing to register Write_Strobe_1_Register with address 83.
* Write_Strobe_1 <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(WRITE_STROBE_1,0x0001);
 
/*
* stop any activities in progress.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Reset <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0001);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register Interrupt_A_Ack_Register with address 2.
* AI_SC_TC_Error_Confirm <= 1
* AI_SC_TC_Interrupt_Ack <= 1
* AI_START1_Interrupt_Ack <= 1
* AI_START2_Interrupt_Ack <= 1
* AI_START_Interrupt_Ack <= 1
* AI_STOP_Interrupt_Ack <= 1
* AI_Error_Interrupt_Ack <= 1
* New pattern = 0x3F80
*/
DAQ_STC_Windowed_Mode_Write(INTERRUPT_A_ACK,0x3F80);
 
/*
* Writing to register AI_Command_1_Register with address 8.
* AI_Command_1_Register <= 0
* New pattern = 0x0000
*/
DAQ_STC_Windowed_Mode_Write(AI_COMMAND_1,0x0000);
 
/*
* Writing to register AI_Mode_1_Register with address 12.
* Reserved_One <= 1
* AI_Start_Stop <= 1
* New pattern = 0x000C
*/
DAQ_STC_Windowed_Mode_Write(AI_MODE_1,0x000C);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
 
/*
* setup the board.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register Clock_and_FOUT_Register with address 56.
* AI_Source_Divide_By_2 <= p->ai_source_divide_by_2 (0)
* AI_Output_Divide_By_2 <= p->ai_output_divide_by_2 (1)
* New pattern = 0x1B80
*/
DAQ_STC_Windowed_Mode_Write(CLOCK_AND_FOUT,0x1B80);
 
/*
* Writing to register AI_Personal_Register with address 77.
* AI_CONVERT_Pulse_Timebase <= p->ai_convert_pulse_timebase (0)
* AI_CONVERT_Pulse_Width <= p->ai_convert_pulse_width (1)
* AI_FIFO_Flags_Polarity <= p->ai_fifo_flags_polarity (0)
* AI_LOCALMUX_CLK_Pulse_Width <= p->ai_localmux_clk_pulse_width (1)
* AI_AIFREQ_Polarity <= p->ai_aifreq_polarity (0)
* AI_SHIFTIN_Polarity <= p->ai_shiftin_polarity (0)
* AI_SHIFTIN_Pulse_Width <= p->ai_shiftin_pulse_width (1)
* AI_EOC_Polarity <= p->ai_eoc_polarity (0)
* AI_SOC_Polarity <= p->ai_soc_polarity (1)
* AI_Overrun_Mode <= p->ai_overrun_mode (1)
* New pattern = 0xA4A0
*/
DAQ_STC_Windowed_Mode_Write(AI_PERSONAL,0xA4A0);
 
/*
* Writing to register AI_Output_Control_Register with address 60.
* AI_CONVERT_Output_Select <= p->ai_convert_output_select (2)
* AI_SC_TC_Output_Select <= p->ai_sc_tc_output_select (3)
* AI_SCAN_IN_PROG_Output_Select <= p->ai_scan_in_prog_output_select (3)
* AI_LOCALMUX_CLK_Output_Select <= p->ai_localmux_clk_output_select (2)
* New pattern = 0x032E
*/
DAQ_STC_Windowed_Mode_Write(AI_OUTPUT_CONTROL,0x032E);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
 
/*
* access the first value in the configuration
* FIFO.
*/
/*
* Writing to register AI_Command_1_Register with address 8.
* AI_CONVERT_Pulse <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(AI_COMMAND_1,0x0001);
/*
* setup for external hardware.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register AI_Mode_2_Register with address 13.
* AI_External_MUX_Present <= 0
* New pattern = 0x0000
*/
DAQ_STC_Windowed_Mode_Write(AI_MODE_2,0x0000);
 
/*
* Writing to register AI_Output_Control_Register with address 60.
* AI_EXTMUX_CLK_Output_Select <= p->ai_extmux_clk_output_select (0)
* New pattern = 0x032E
*/
DAQ_STC_Windowed_Mode_Write(AI_OUTPUT_CONTROL,0x032E);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
 
/*
* enable or disable retriggering.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register AI_Mode_1_Register with address 12.
* AI_Trigger_Once <= 1
* New pattern = 0x000D
*/
DAQ_STC_Windowed_Mode_Write(AI_MODE_1,0x000D);
 
/*
* Writing to register AI_Trigger_Select_Register with address 63.
* AI_START1_Select <= 0
* AI_START1_Polarity <= 0
* AI_START1_Edge <= 1
* AI_START1_Sync <= 1
* New pattern = 0x0060
*/
DAQ_STC_Windowed_Mode_Write(AI_TRIGGER_SELECT,0x0060);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
/*
* select the number of scans.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
DAQ_STC_Windowed_Mode_Write(AI_MODE_1,0x000F);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
/*
* select the scan start event.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register AI_START_STOP_Select_Register with address 62.
* AI_START_Select <= 0
* AI_START_Edge <= 1
* AI_START_Sync <= 1
* AI_START_Polarity <= 0
* New pattern = 0x0060
*/
DAQ_STC_Windowed_Mode_Write(AI_START_STOP_SELECT,0x0060);
 
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
/*
* select the end of scan event.
*/
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 1
* New pattern = 0x0010
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0010);
 
/*
* Writing to register AI_START_STOP_Select_Register with address 62.
* AI_STOP_Select <= p->ai_stop_select (19)
* AI_STOP_Edge <= 0
* AI_STOP_Polarity <= p->ai_stop_polarity (0)
* AI_STOP_Sync <= 1
* New pattern = 0x29E0
*/
DAQ_STC_Windowed_Mode_Write(AI_START_STOP_SELECT,0x29E0);
 
/*
* Writing to register Joint_Reset_Register with address 72.
* AI_Configuration_Start <= 0
* AI_Configuration_End <= 1
* New pattern = 0x0100
*/
DAQ_STC_Windowed_Mode_Write(JOINT_RESET,0x0100);
/*
* clear the AI FIFO.
*/
/*
* Writing to register Write_Strobe_1_Register with address 83.
* Write_Strobe_1 <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(WRITE_STROBE_1,0x0001);
return;
}
 
/*
* Call this function to start the acquistion.
*/
 
void AI_Start_The_Acquisition()
{
/*
* Writing to register AI_Command_1_Register with address 8.
* AI_CONVERT_Pulse <= 1
* New pattern = 0x0001
*/
DAQ_STC_Windowed_Mode_Write(AI_COMMAND_1,0x0001);
return;
}
/*End of file: adc.c*/
 
 
 
 
/unsupported/branches/unsupported/oscilloscopio/initosc.c
0,0 → 1,69
/*
* Filename: Initosc.c
* Author: Ghiro Andrea, Franchino Gianluca
* Date: 09/03
* Description: this file is for osc
*/
 
/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
*
* Copyright (C) 2003 Ghiro Andrea Franchino Gianluca
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#include <kernel/kern.h>
#include <modules/edf.h>
#include <modules/cbs.h>
#include <modules/rr.h>
#include <modules/hartport.h>
#include <modules/dummy.h>
#include <modules/sem.h>
#include <modules/srp.h>
 
#include <drivers/keyb.h>
 
#define TICK 1000
#define RRTICK 5000
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL, 0);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
 
SEM_register_module();
 
SRP_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
HARTPORT_init();
KEYB_init(NULL);
 
__call_main__(mb);
 
return (void *)0;
}
/unsupported/branches/unsupported/oscilloscopio/readme.txt
0,0 → 1,0
Verione con tutti i task periodici Hard
/unsupported/branches/unsupported/oscilloscopio/makefile
0,0 → 1,18
#
#
# PCI6025E Examples and Test programs
#
#
 
ifndef BASE
BASE=../..
endif
include $(BASE)/config/config.mk
 
PROGS= osc
 
include $(BASE)/config/example.mk
 
osc:
make -f $(SUBMAKE) APP=osc OTHEROBJS="initosc.o adc.o" SHARKOPT="__6025E__ __OLDCHAR__ __GRX__"
 
/unsupported/branches/unsupported/oscilloscopio/adc.h
0,0 → 1,48
/*****************************************************************************
* Filename: ADC.H *
* Author: Ghiro Andrea,Franchino Gianluca *
* Date: 09/2003 *
* Description: Analog 2 digital conversion package header file *
*----------------------------------------------------------------------------*
* Notes: *
*****************************************************************************/
 
/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
*
* Copyright (C) 2003 Ghiro Andrea,Franchino Gianluca
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
 
#ifndef _MY_ADC_H_
#define _MY_ADC_H_
 
#include <drivers/pci6025e/pci6025e.h>
#include <drivers/pci6025e/regconst.h>
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
//Analog input releted functions
void Configure_Board(BYTE);
void ADC_Init(void);
void AI_Start_The_Acquisition(void);
 
__END_DECLS
#endif
/*End of file: adc.h*/
 
/unsupported/branches/unsupported/simcity/keyboard.c
0,0 → 1,49
/* ------------------ */
/* Keyboard handler */
/* ------------------ */
 
#include <drivers/keyb.h>
#include "include/keyfunct.h"
 
void keyb_h() {
KEY_EVT k;
keyb_set_map(itaMap);
/* Exit keys: ALT-X, ENTER */
k.flag = ALTL_BIT;
k.scan = KEY_X;
k.ascii = 'x';
keyb_hook(k, endfun);
k.flag = ALTR_BIT;
k.scan = KEY_X;
k.ascii = 'x';
keyb_hook(k, endfun);
k.flag = 0;
k.scan = KEY_ENT;
k.ascii = 13;
keyb_hook(k, endfun);
/* Create HARD cars */
k.flag = 0;
k.scan = KEY_C;
k.ascii = 'c';
keyb_hook(k, h_car_create);
/* kill hard cars*/
k.flag = 0;
k.scan = KEY_K;
k.ascii = 'k';
keyb_hook(k, h_car_kill);
//refresh map
k.flag=0;
k.scan = KEY_R;
k.ascii = 'r';
keyb_hook(k, refresh);
//create soft cars
k.flag=0;
k.scan = KEY_S;
k.ascii = 's';
keyb_hook(k, s_car_create);
//toggle sensors
k.flag=0;
k.scan = KEY_D;
k.ascii = 'd';
keyb_hook(k, sensor_switch);
}
/unsupported/branches/unsupported/simcity/include/constant.h
0,0 → 1,99
/*************************const.h*******************************/
// constants and new types declaration
#include <kernel/func.h>
#define CST
 
#define NO_SPRITE 8
 
 
#define GRAPH
#define SENSOR
#define MAX_CAR 10
#define MAX_TL 3
#define S_POINT 4
#define PERIOD_CAR 135000 //period for K62 350MHZ
//#define PERIOD_CAR 87000 //period for PIII 733MHZ
#define SPERIOD_CAR 13000
#define SCAR_WCET 4300
#define SECOND 1000000
#define TL_WCET 200
#define CAM_WCET 200
#define GAUGE_WCET 200
#define ARROW_WCET 100
//#define CAR_WCET 7700 //wcet for PIII 733MHZ
#define CAR_WCET 12400 //wcet for K62 350MHZ
#define ROW 30
#define COL 30
#define NCAR 24
#define W 640
#define H 480
#define SH 12
#define SW 12
#define MAX_DIST 50.0
#define NORM_DIST 15.0
#define COLL_DIST 25.0
#define MIN_SPEED 0.0
#define NORM_SPEED 4.0
#define MAX_SPEED 6.0
#define MAX_LOOK 50
#define LOOK_ANGLE 70
#define DIST_ANGLE 90
#define CORR_FACT 0.7
#define FRANTIC 0.0
#define POS_RAND
#define OBL_START 1
#define DEG_TO_RAD(x) ((float)x)/180.0*3.14
#define RAD_TO_DEG(x) ((float)x)/3.14*180.0
#define RANDDIR (rand()%3-1)
#define L 0
#define R 1
#define U 2
#define D 3
 
#define DRAW 1
#define CANCEL 0
#define VERTICAL 1
#define HORIZONTAL 0
 
#define STEER_LEFT 1
#define STEER_RIGHT -1
#define STRAIGHT 0
 
#define CAMX 670
#define CAMY 120
#define MAPX 8
#define MAPY 113
 
#define FREE 0
#define STOP 1
#define CAR 2
 
/*data types*/
 
typedef struct car_d {
int number;
float xpos,ypos;
int xp,yp;
float dist_obs,dist_sem;
float speed,middle,front,rear,somma;
int angle,sat;
char collision,boom,correggi,incrocio;
char dir,running;
struct car_d *next;
} car_data;
 
typedef struct {
int x,y;
} point;
 
typedef struct {
char vpos,hpos,tl_name[8];
point l,r,u,d;
PID pid;
DWORD period;
} tl_data;
 
 
typedef struct {
int xpos,ypos,angles;
} starting_set;
/unsupported/branches/unsupported/simcity/include/misc.h
0,0 → 1,18
//*****************************misc.h************************************
// miscellaneous useful functions
#ifndef CST
#include "constant.h"
#endif
 
int my_rint(float);
void fill_table();
void tl_init();
void set_start_point();
int returnCarIndex(int);
int find_col(int,int);
int find_tl(int,int,int);
int allinea(int);
int module(int,int,int,int);
int normalize(int);
 
 
/unsupported/branches/unsupported/simcity/include/draw.h
0,0 → 1,14
//****************************draw.h*******************************
// drawing functions
#ifndef CST
#include "constant.h"
#endif
 
void drawSprites(int,int,char,char);
void drawStreet(int,int);
void get_images();
void drawCar(int,int,int,char);
void bold_rect(WORD,WORD,WORD,WORD,BYTE,BYTE,BYTE);
void draw_scenario();
void draw_tl(int x,int y,DWORD img[SH][SW]);
void drawFaces(int,int,short);
/unsupported/branches/unsupported/simcity/include/simcity.h
0,0 → 1,77
/********************************simcity.h***************************/
// global variables and tasks bodies declaration
 
#include <kernel/func.h>
#include <semaphore.h>
#ifndef CST
#include "constant.h"
#endif
 
/*Global stuff*/
 
extern car_data car_data_array[MAX_CAR];
extern tl_data tl_data_array[MAX_TL];
 
//car starting points
extern starting_set starting_set_array[S_POINT];
 
// PID vectors
extern PID p_table[MAX_CAR];
extern PID c_table[MAX_CAR];
extern PID g_table[MAX_CAR];
extern PID a_table[MAX_CAR];
 
extern char kill_flag[MAX_CAR];
//graphic mutex
extern sem_t mutex;
 
//kill_flag mutexes
extern sem_t kill_mutex[MAX_CAR];
 
//various sprites
extern DWORD macchine[ROW][COL][NCAR];
extern DWORD strada[H][W];
extern BYTE street[H*W*2];
extern BYTE vbuf[MAX_CAR][ROW*COL*2];
extern BYTE clrcam[(ROW+2)*(COL+2)*2];
extern BYTE gauge_img[ROW*COL*2];
extern BYTE brk_gauge[ROW*COL*2];
extern BYTE arrow[3][ROW*COL*2];
extern DWORD sprites[ROW][COL][NO_SPRITE];
extern BYTE clrscr[800*600*2];
extern DWORD faces[2][74][47];
 
extern char sens;
//sine & cosine look-up tables
extern float cosine[360],sine[360];
 
//traffic light sprites
extern DWORD y_sem[4][SH][SW];
extern DWORD r_sem[4][SH][SW];
extern DWORD g_sem[4][SH][SW];
 
//useful colors
extern DWORD white;
extern DWORD black;
extern DWORD red;
extern DWORD gray;
extern DWORD blue;
extern DWORD green;
extern DWORD border;
extern DWORD tl_bg;
 
//task chain pointers
extern car_data *free_n,*busy_n,*free_o,*busy_o;
// car counter
extern short maxc;
 
/*function declaration */
 
/* task bodies*/
TASK car(car_data *);
TASK traffic_light(tl_data *);
TASK camera(int);
TASK gauge_c(int);
TASK blink_arrow(int);
TASK refresher(void *);
TASK killer(void *);
/unsupported/branches/unsupported/simcity/include/states.h
0,0 → 1,21
enum stati {
NORM,
INC1,
DX1,
STR1,
STR2,
SX1,
SX2,
SX3
} ;
 
enum sprite_type {
EXPL,
GAUGE,
ARR_OFF,
ARR_SX,
ARR_DX,
VECCHINA,
V_SPLAT,
GAUGE_ROTTO
};
/unsupported/branches/unsupported/simcity/include/proc.h
0,0 → 1,23
//***************************proc.h******************************
// task management functions
#ifndef CST
#include "constant.h"
#endif
 
 
int add();
void del(int);
void init_struct();
int del_o();
void gauge_create(char *,int);
void arrow_create(char *,int);
void killer_create();
void ref_create();
void cam_create(char *,int);
void stl_create(char *,int);
void h_create(char *,int);
void s_create(char *,int);
void killing(int);
 
 
 
/unsupported/branches/unsupported/simcity/include/car.h
0,0 → 1,10
//*****************************car.h********************************
// car management functions
#ifndef CST
#include "constant.h"
#endif
 
char collision_sensor(car_data *);
int sensore(car_data *);
void ch_spd(car_data *,char);
 
/unsupported/branches/unsupported/simcity/include/keyfunct.h
0,0 → 1,10
/*******************************keyfunct.h****************************/
// keyboard handler functions
#include <drivers/keyb.h>
 
void h_car_create(KEY_EVT *);
void s_car_create(KEY_EVT *);
void h_car_kill(KEY_EVT *);
void endfun(KEY_EVT *);
void refresh(KEY_EVT *);
void sensor_switch(KEY_EVT *);
/unsupported/branches/unsupported/simcity/sem/green_l.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/red_r.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/yellow_r.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/red_d.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€ÿÿ€€€€€€€€€ÿÿÿÿ€€€€€€€ÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/yellow_d.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€ÿÿÿÿ€€€€€€€€€ÿÿÿÿÿÿÿÿ€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/red_u.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿ€€€€€€€ÿÿÿÿ€€€€€€€€€ÿÿ€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/yellow_u.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€ÿÿÿÿÿÿÿÿ€€€€€€€€€ÿÿÿÿ€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/green_r.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/green_d.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€ÿÿ€€€€€€€€€ÿÿÿÿ€€€€€€€ÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/green_u.raw
0,0 → 1,0
€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿ€€€€€€€ÿÿÿÿ€€€€€€€€€ÿÿ€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/red_l.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/sem/yellow_l.raw
0,0 → 1,0
€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€
/unsupported/branches/unsupported/simcity/initfile.c
0,0 → 1,106
//****************************initfile.c*******************************
#define PI
 
#include "kernel/kern.h"
#include "modules/edf.h"
#include "modules/cbs.h"
#include "modules/rr.h"
 
#ifndef PI
#include "modules/rrsoft.h"
#endif
 
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
#include "modules/pi.h"
#include "modules/pc.h"
#include "modules/srp.h"
#include "modules/npp.h"
#include "modules/nop.h"
#include <drivers/keyb.h>
 
//#include "ll/i386/x-dos.h"
 
 
/*+ sysyem tick in us +*/
#define TICK 0
 
/*+ RR tick in us +*/
//#define RRTICK 10000
#define RRTICK 2000
 
 
void getCars(void);
void getRoad(void);
void getSem(void);
void getSprites(void);
void getFaces(void);
void tl_pos();
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
 
EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL, 0);
 
// RRSOFT_register_level(RRTICK, RR_MAIN_NO, mb, RRSOFT_ONLY_HARD|RRSOFT_ONLY_SOFT);
// RRSOFT_register_level(RRTICK, RR_MAIN_NO, mb, RRSOFT_ONLY_SOFT); //cbs
 
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
 
 
SEM_register_module();
 
CABS_register_module();
 
PI_register_module();
NOP_register_module();
 
getFaces();
getCars();
getRoad();
getSem();
getSprites();
tl_pos();
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
HARTPORT_init();
 
KEYB_init(NULL);
 
__call_main__(mb);
 
return (void *)0;
}
 
 
#ifdef PI
void app_mutex_init(mutex_t *m)
{
PI_mutexattr_t attr;
 
PI_mutexattr_default(attr);
 
mutex_init(m, &attr);
}
#else
void app_mutex_init(mutex_t *m)
{
NOP_mutexattr_t attr;
 
NOP_mutexattr_default(attr);
 
mutex_init(m, &attr);
}
#endif
/unsupported/branches/unsupported/simcity/proc.c
0,0 → 1,393
#include <drivers/glib.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "include/simcity.h"
#include "include/misc.h"
#include "include/proc.h"
 
int add() {
if(maxc>0 && maxc<MAX_CAR-1) {
busy_n->next=free_o;
busy_n=free_o;
free_o=free_o->next;
busy_n->next=NULL;
}
if(maxc==0) {
busy_n=busy_o=free_o;
free_o=free_o->next;
busy_n->next=NULL;
}
if(maxc==MAX_CAR-1) {
busy_n->next=free_o;
busy_n=free_o;
free_o=free_n=NULL;
busy_n->next=NULL;
}
if(maxc<MAX_CAR) {
maxc++;
return(busy_n->number);
} else
return(-1);
}
 
void del(int num) {
car_data *d,*db;
 
db=d=busy_o;
if(maxc>1) {
while((d->number)!=num) {
db=d;
d=d->next;
}
if(d==busy_n) {
db->next=NULL;
busy_n=db;
} else if(d==busy_o) {
busy_o=busy_o->next;
} else {
db->next=d->next;
}
if(maxc!=MAX_CAR) {
free_n->next=d;
free_n=d;
free_n->next=NULL;
}
else {
free_n=free_o=d;
}
}
else {
free_n->next=d;
free_n=d;
free_n->next=NULL;
busy_n=busy_o=NULL;
}
maxc--;
}
 
void init_struct() {
int i;
 
free_o=&(car_data_array[0]);
free_n=&(car_data_array[MAX_CAR-1]);
busy_n=busy_o=NULL;
for(i=0;i<MAX_CAR;i++)
car_data_array[i].number=i;
for(i=0;i<MAX_CAR;i++) {
if(i<MAX_CAR-1)
car_data_array[i].next=&(car_data_array[i+1]);
else
car_data_array[i].next=NULL;
}
maxc=0;
}
 
int del_o() {
 
if(maxc<MAX_CAR && maxc>1) {
free_n->next=busy_o;
free_n=busy_o;
busy_o=busy_o->next;
free_n->next=NULL;
} else
if(maxc==MAX_CAR) {
free_n=free_o=busy_o;
busy_o=busy_o->next;
free_n->next=NULL;
} else
if(maxc==1) {
free_n->next=busy_o;
free_n=busy_o;
free_n->next=NULL;
busy_o=busy_n=NULL;
}
if(maxc>0) {
maxc--;
return(free_n->number);
} else
return -1;
}
 
void gauge_create(char *name,int num) {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) num;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,GAUGE_WCET);
soft_task_def_period(stm,PERIOD_CAR);
soft_task_def_usemath(stm);
pid = task_create(name, gauge_c, &stm, NULL);
if (pid == NIL) {
grx_close();
perror("stl_create():Could not create task <Gauge_c>");
sys_abort(1);
}
g_table[num]=pid;
task_activate(pid);
}
 
 
void arrow_create(char *name,int num) {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) num;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,ARROW_WCET);
soft_task_def_period(stm,PERIOD_CAR*4);
pid = task_create(name,blink_arrow, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("stl_create():Could not create task <arrow>");
sys_abort(1);
}
a_table[num]=pid;
task_activate(pid);
}
 
void killer_create() {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) 0;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,1000);
soft_task_def_period(stm,5*SECOND);
pid = task_create("killer", killer, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("ref_create():Could not create task <killer>");
sys_abort(1);
}
task_activate(pid);
}
 
 
void ref_create() {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) 0;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,3000);
soft_task_def_period(stm,4*SECOND);
pid = task_create("Refresher", refresher, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("ref_create():Could not create task <refresher>");
sys_abort(1);
}
task_activate(pid);
}
 
void cam_create(char *name,int num) {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) num;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,CAM_WCET);
soft_task_def_period(stm,PERIOD_CAR);
pid = task_create(name, camera, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("stl_create():Could not create task <Camera>");
sys_abort(1);
}
c_table[num]=pid;
task_activate(pid);
}
 
void stl_create(char *name,int num) {
void *par;
PID pid;
SOFT_TASK_MODEL stm;
 
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
strcpy(tl_data_array[num].tl_name,name);
par=(void *) &(tl_data_array[num]);
soft_task_def_arg(stm,par);
soft_task_def_met(stm,TL_WCET);
soft_task_def_period(stm,tl_data_array[num].period);
pid = task_create(name, traffic_light, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("stl_create():Could not create task <Traffic Light>");
sys_abort(1);
}
tl_data_array[num].pid=pid;
task_activate(pid);
}
 
void h_create(char *name,int num) {
void *par;
PID pid;
int start_point=0;
short flag=0;
HARD_TASK_MODEL htm;
car_data cd,*d;
 
#ifdef POS_RAND
start_point=rand()%S_POINT;
if(busy_o!=NULL)
do {
flag=0;
d=busy_o;
do {
if(d->number!=num)
if(module(starting_set_array[start_point].xpos,d->xp,starting_set_array[start_point].ypos,d->yp)<256) {
start_point=(start_point+1)%S_POINT;
flag=1;
break;
}
d=d->next;
} while(d!=NULL);
} while(flag);
#endif
#ifndef POS_RAND
start_point=OBL_START;
#endif
 
cd.number=num;
cd.xpos=cd.xp=starting_set_array[start_point].xpos;
cd.ypos=cd.yp=starting_set_array[start_point].ypos;
cd.angle=starting_set_array[start_point].angles;
cd.speed=MIN_SPEED;
cd.dist_obs=MAX_DIST;
cd.collision=cd.boom=cd.correggi=cd.somma=0;
cd.dir=STRAIGHT;
car_data_array[num]=cd;
hard_task_default_model(htm);
hard_task_def_ctrl_jet(htm);
par=(void *) &(car_data_array[num]);
hard_task_def_arg(htm,par);
hard_task_def_wcet(htm, CAR_WCET);
hard_task_def_mit(htm,PERIOD_CAR);
hard_task_def_usemath(htm);
pid = task_create(name, car, &htm, NULL);
if (pid == NULL) {
grx_close();
perror("h_create():Could not create task <hard car>");
sys_abort(1);
}
else {
p_table[num]=pid;
sem_wait(&(kill_mutex[num]));
kill_flag[num]=0;
car_data_array[num].running=1;
sem_post(&(kill_mutex[num]));
task_activate(pid);
}
}
 
void s_create(char *name,int num) {
void *par;
PID pid;
int start_point=0;
SOFT_TASK_MODEL stm;
car_data cd,*d;
short flag=0;
 
#ifdef POS_RAND
start_point=rand()%S_POINT;
if(busy_o!=NULL)
do {
flag=0;
d=busy_o;
do {
if(d->number!=num)
if(module(starting_set_array[start_point].xpos,d->xp,starting_set_array[start_point].ypos,d->yp)<256) {
start_point=(start_point+1)%S_POINT;
flag=1;
break;
}
d=d->next;
} while(d!=NULL);
} while(flag);
#endif
#ifndef POS_RAND
start_point=OBL_START;
#endif
 
cd.number=num;
cd.xpos=cd.xp=starting_set_array[start_point].xpos;
cd.ypos=cd.yp=starting_set_array[start_point].ypos;
cd.angle=starting_set_array[start_point].angles;
cd.speed=MIN_SPEED;
cd.dist_obs=MAX_DIST;
cd.collision=cd.boom=cd.correggi=cd.somma=0;
cd.dir=STRAIGHT;
car_data_array[num]=cd;
soft_task_default_model(stm);
soft_task_def_level(stm,1);
soft_task_def_ctrl_jet(stm);
par=(void *) &(car_data_array[num]);;
soft_task_def_arg(stm,par);
soft_task_def_met(stm,SCAR_WCET);
soft_task_def_period(stm,SPERIOD_CAR);
soft_task_def_usemath(stm);
pid = task_create(name, car, &stm, NULL);
if (pid == NULL) {
grx_close();
perror("h_create():Could not create task <soft car>");
sys_abort(1);
}
else {
p_table[num]=pid;
sem_wait(&(kill_mutex[num]));
kill_flag[num]=0;
car_data_array[num].running=1;
sem_post(&(kill_mutex[num]));
task_activate(pid);
}
}
 
void killing(int num) {
PID car_to_kill,cam_to_kill,gauge_to_kill,a_to_kill;
int c;
 
c=car_data_array[num].number*46;
car_to_kill=p_table[num];
cam_to_kill=c_table[num];
gauge_to_kill=g_table[num];
a_to_kill=a_table[num];
sem_wait(&(kill_mutex[num]));
kill_flag[num]=1;
car_data_array[num].running=0;
sem_post(&(kill_mutex[num]));
task_kill(car_to_kill);
task_kill(cam_to_kill);
task_kill(gauge_to_kill);
task_kill(a_to_kill);
sem_wait(&mutex);
grx_putimage(car_data_array[num].xp-15,car_data_array[num].yp-15,car_data_array[num].xp+14,car_data_array[num].yp+14,vbuf[car_data_array[num].number]);
grx_putimage(CAMX-1,CAMY-1+c,CAMX+30,CAMY+30+c,clrcam);
grx_putimage(CAMX+40-1,CAMY-1+c,CAMX+40+30,CAMY+c+30,clrcam);
grx_putimage(CAMX+80-1,CAMY-1+c,CAMX+80+30,CAMY+c+30,clrcam);
grx_text(" ",CAMX,CAMY+c+30,black,black);
sem_post(&mutex);
}
/unsupported/branches/unsupported/simcity/car.c
0,0 → 1,175
#include <drivers/glib.h>
#include <stdlib.h>
#include <math.h>
#include "include/simcity.h"
#include "include/misc.h"
#include "include/car.h"
#include "include/draw.h"
 
char collision_sensor(car_data *cd) {
float i,dx,dx1,dy,dy1,deltax,deltay;
int colore,colore1;
int speed_done=0;
char col=FREE;
 
dx=cd->xpos+2.0*cosine[normalize(cd->angle+90)];
dy=cd->ypos-2.0*sine[normalize(cd->angle+90)];
dx1=cd->xpos-8.0*cosine[normalize(cd->angle+90)];
dy1=cd->ypos+8.0*sine[normalize(cd->angle+90)];
 
for (i=0.0;i<MAX_LOOK;i+=0.1) {
deltax=i*cosine[normalize(cd->angle)];
deltay=i*sine[normalize(cd->angle)];
sem_wait(&mutex);
colore=grx_getpixel(my_rint(dx+deltax),my_rint(dy-deltay));
colore1=grx_getpixel(my_rint(dx1+deltax),my_rint(dy1-deltay));
sem_post(&mutex);
if (((colore==white)||(colore1==white) || ((colore==red)||(colore1==red)))) {
if((colore==white)||(colore1==white))
col=STOP;
else
col=CAR;
cd->dist_obs=i;
cd->collision=1;
speed_done=1;
}
if (!speed_done) {
if (sens) {
sem_wait(&mutex);
grx_plot(my_rint(dx+deltax),my_rint(dy-deltay),gray);
grx_plot(my_rint(dx1+deltax),my_rint(dy1-deltay),gray);
sem_post(&mutex);
}
}
}
if (!speed_done) {
cd->collision=0;
cd->dist_obs=MAX_LOOK;
}
return col;
}
 
int sensore(car_data *cd) {
int col_front,col_rear,col_middle;
int done_front=0,done_rear=0,done_middle=0;
float front,rear,middle,store_middle;
int angolo;
float i;
float x1,y1,x05,y05;
float xs,ys,xs1,ys1;
float coordx,coordy,distx,disty;
 
cd->front=cd->rear=cd->middle=front=rear=middle=store_middle=NORM_DIST;
x1=cd->xpos-10.0*cosine[normalize(cd->angle)]; // coordinata sensore dietro
y1=cd->ypos+10.0*sine[normalize(cd->angle)];
 
x05=cd->xpos-5.0*cosine[normalize(cd->angle)]; // coordinata sensore mezzo
y05=cd->ypos+5.0*sine[normalize(cd->angle)];
 
for (i=0.0;i<MAX_DIST;i+=0.1) {
coordx=i*cosine[normalize(cd->angle-LOOK_ANGLE)];
coordy=i*sine[normalize(cd->angle-LOOK_ANGLE)];
distx=i*cosine[normalize(cd->angle-DIST_ANGLE)];
disty=i*sine[normalize(cd->angle-DIST_ANGLE)];
col_front=grx_getpixel(my_rint(cd->xpos+coordx),my_rint(cd->ypos-coordy));
col_rear=grx_getpixel(my_rint(x1+coordx),my_rint(y1-coordy));
col_middle=grx_getpixel(my_rint(x05+distx),my_rint(y05-disty));
if ((col_front==border) && !done_front) {
done_front=1;
cd->front=front=i;
}
if ((col_middle==border) && !done_middle) {
done_middle=1;
middle=cd->middle=i;
}
if ((col_rear==border) && !done_rear) {
done_rear=1;
cd->rear=rear=i;
}
if (sens) {
sem_wait(&mutex);
if (!done_front) {
grx_plot(my_rint(cd->xpos+coordx),my_rint(cd->ypos-coordy),gray);
}
if (!done_rear) {
grx_plot(my_rint(x1+coordx),my_rint(y1-coordy),blue);
}
if (!done_middle) {
grx_plot(my_rint(x05+distx),my_rint(y05-disty),green);
}
sem_post(&mutex);
}
}
 
if (!done_front) {
front=cd->front=MAX_DIST;
}
if (!done_rear) {
rear=cd->rear=MAX_DIST;
}
if (!done_middle) {
cd->middle=middle=MAX_DIST;
}
xs=cd->xpos+front*cosine[normalize(cd->angle-LOOK_ANGLE)];
xs1=x1+rear*cosine[normalize(cd->angle-LOOK_ANGLE)];
ys=cd->ypos-front*sine[normalize(cd->angle-LOOK_ANGLE)];
ys1=y1-rear*sine[normalize(cd->angle-LOOK_ANGLE)];
if (xs==xs1) {
angolo=90;
} else {
angolo=my_rint(RAD_TO_DEG(atan((-ys1+ys)/(xs1-xs))));
}
 
if (angolo<0) angolo+=360;
if (angolo>=360) angolo-=360;
 
if ((ys-ys1<0) && (xs1-xs>0)) {
angolo-=180;
}
if ((ys-ys1>=0) && (xs1-xs>0)) {
angolo+=180;
}
 
if ((xs1-xs==0) && (ys-ys1>0)) {
angolo=270;
}
 
if (abs(middle-NORM_DIST)>FRANTIC) {
cd->correggi=1;
} else {
cd->somma=0;
cd->correggi=0;
}
 
if (cd->correggi) {
if (middle>NORM_DIST) {
cd->somma-=CORR_FACT;
}
if (middle<NORM_DIST) {
cd->somma+=CORR_FACT;
}
}
angolo+=cd->somma;
return angolo;
}
 
void ch_spd(car_data *cd,char ob_type) {
float set_spd=0.0;
float bf;
 
if(cd->collision) {
if(ob_type==STOP)
bf=0.001;
else
bf=0.7;
set_spd=cd->speed-(MAX_LOOK-cd->dist_obs)*bf;
if(set_spd<0)
set_spd=0;
}
else {
set_spd=cd->speed+0.4;
if(set_spd>MAX_SPEED)
set_spd=MAX_SPEED;
}
cd->speed=set_spd;
}
/unsupported/branches/unsupported/simcity/reading.c
0,0 → 1,237
/********************************************reading.c******************************/
#include <kernel/func.h>
#include <drivers/glib.h>
#include <ll/i386/x-dos.h>
#include <stdlib.h>
#include <string.h>
#include "include/constant.h"
#define rgb rgb16
 
DWORD macchine[ROW][COL][NCAR];
DWORD strada[H][W];
DWORD sprites[ROW][COL][NO_SPRITE];
DWORD y_sem[4][SH][SW];
DWORD r_sem[4][SH][SW];
DWORD g_sem[4][SH][SW];
DWORD faces[2][74][47];
extern tl_data tl_data_array[MAX_TL];
 
char nomefile[17];
char nomestrada[17];
char nomesem[17];
char nomesprite[16];
 
void getSem() {
int i,j,k,count;
BYTE colore[3];
DOS_FILE *fp;
char letter[5];
 
strcpy(letter,"lrud");
strcpy(nomesem,"sem/green_ .raw");
 
//green traffic light....
for(k=0;k<4;k++) {
nomesem[10]=letter[k];
fp=DOS_fopen(nomesem,"r");
if(!fp) {
perror(nomesem);
sys_abort(1);
}
for(i=0;i<SH;i++) {
for(j=0;j<SW;j++) {
count=DOS_fread(&colore,sizeof(BYTE),3,fp);
if(count!=3) break;
g_sem[k][i][j]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
}
 
//red traffic light...
strcpy(nomesem,"sem/red_ .raw");
for(k=0;k<4;k++) {
nomesem[8]=letter[k];
fp=DOS_fopen(nomesem,"r");
if(!fp) {
perror(nomesem);
sys_abort(1);
}
for(i=0;i<SH;i++) {
for(j=0;j<SW;j++) {
count=DOS_fread(&colore,sizeof(BYTE),3,fp);
if(count!=3) break;
r_sem[k][i][j]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
}
 
//yellow traffic light...
strcpy(nomesem,"sem/yellow_ .raw");
for(k=0;k<4;k++) {
nomesem[11]=letter[k];
fp=DOS_fopen(nomesem,"r");
if(!fp) {
perror(nomesem);
sys_abort(1);
}
for(i=0;i<SH;i++) {
for(j=0;j<SW;j++) {
count=DOS_fread(&colore,sizeof(BYTE),3,fp);
if(count!=3) break;
y_sem[k][i][j]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
}
}
 
void getCars() {
int i,j,k,l,index;
int tmp;
char id_car[3];
BYTE colore[3];
DOS_FILE *fp;
 
strcpy(nomefile,"img/car_XXXn.raw");
k=0;
for (index=0;index<360;index+=15) {
tmp=index;
for (l=2;l>=0;l--) {
id_car[l]=tmp%10+'0';
tmp/=10;
}
nomefile[8]=id_car[0];
nomefile[9]=id_car[1];
nomefile[10]=id_car[2];
fp=DOS_fopen(nomefile,"r");
if (!fp) {
perror(nomefile);
sys_abort(1);
}
 
for (i=0;i<ROW;i++) {
for (j=0;j<COL;j++) {
DOS_fread(&colore,sizeof(BYTE),3,fp);
macchine[i][j][k]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
k++;
}
}
 
void getRoad() {
DOS_FILE *fp;
int i,j,test;
BYTE colore[3];
 
strcpy(nomestrada,"img/street.raw");
fp=DOS_fopen(nomestrada,"r");
if (!fp) {
perror(nomestrada);
sys_abort(1);
}
 
for (i=0;i<H;i++) {
for (j=0;j<W;j++) {
test=DOS_fread(&colore,sizeof(BYTE),3,fp);
if(test!=3) {
perror("Few bytes read!!!!!!\n");
 
}
strada[i][j]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
}
 
void getSprites(void) {
int i,j,k;
DOS_FILE *fp;
BYTE colore[3];
 
strcpy(nomesprite,"sprite/sp_X.raw");
for (k=0;k<NO_SPRITE;k++) {
nomesprite[10]=k+'0';
fp=DOS_fopen(nomesprite,"r");
if (!fp) {
perror(nomesprite);
sys_abort(1);
}
for (i=0;i<ROW;i++) {
for (j=0;j<COL;j++) {
DOS_fread(&colore,sizeof(BYTE),3,fp);
sprites[i][j][k]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
}
}
 
void tl_pos(void) {
DOS_FILE *fp;
int i;
char buf[7];
int dimx,dimy;
 
fp=DOS_fopen("sem.raw","r");
if (!fp) {
perror("sem.raw");
sys_abort(1);
}
buf[6]='\0';
for (i=0;i<MAX_TL;i++) {
DOS_fread(&buf,sizeof(char),6,fp);
dimx=(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
dimy=(buf[3]-'0')*100+(buf[4]-'0')*10+(buf[5]-'0');
tl_data_array[i].u.x=dimx;
tl_data_array[i].u.y=dimy;
DOS_fread(&buf,sizeof(char),6,fp);
dimx=(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
dimy=(buf[3]-'0')*100+(buf[4]-'0')*10+(buf[5]-'0');
tl_data_array[i].d.x=dimx;
tl_data_array[i].d.y=dimy;
DOS_fread(&buf,sizeof(char),6,fp);
dimx=(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
dimy=(buf[3]-'0')*100+(buf[4]-'0')*10+(buf[5]-'0');
tl_data_array[i].l.x=dimx;
tl_data_array[i].l.y=dimy;
DOS_fread(&buf,sizeof(char),6,fp);
dimx=(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
dimy=(buf[3]-'0')*100+(buf[4]-'0')*10+(buf[5]-'0');
tl_data_array[i].r.x=dimx;
tl_data_array[i].r.y=dimy;
}
DOS_fclose(fp);
}
 
void getFaces(void) {
int i,j,k;
DOS_FILE *fp;
BYTE colore[3];
 
strcpy(nomesprite,"img/bbX.raw");
for (k=0;k<2;k++) {
nomesprite[6]=k+'0';
fp=DOS_fopen(nomesprite,"r");
if (!fp) {
perror(nomesprite);
sys_abort(1);
}
for (i=0;i<74;i++) {
for (j=0;j<47;j++) {
DOS_fread(&colore,sizeof(BYTE),3,fp);
faces[k][i][j]=rgb(colore[0],colore[1],colore[2]);
}
}
DOS_fclose(fp);
fp=0;
}
}
/unsupported/branches/unsupported/simcity/simcity.c
0,0 → 1,154
/************************** Simcity ************************/
// Main,initialization functions and global variables allocation
#include <kernel/func.h>
#include <string.h>
#include <stdlib.h>
#include <drivers/keyb.h>
#include <drivers/glib.h>
#include <kernel/kern.h>
#include <semaphore.h>
#include <math.h>
#include "include/constant.h"
#include "include/misc.h"
#include "include/draw.h"
#include "include/proc.h"
#define rgb rgb16
 
/* graphic mutex... */
sem_t mutex;
//kill flag mutexes
sem_t kill_mutex[MAX_CAR];
 
// various sprites to use with grx_putimage()....
BYTE vbuf[MAX_CAR][ROW*COL*2];
BYTE clrscr[800*600*2];
BYTE clrcam[(ROW+2)*(COL+2)*2];
BYTE gauge_img[ROW*COL*2];
BYTE brk_gauge[ROW*COL*2];
BYTE arrow[3][ROW*COL*2];
BYTE street[H*W*2];
 
//task chain pointers
car_data *free_n,*free_o,*busy_n,*busy_o;
 
// various sprites to plot
extern DWORD macchine[ROW][COL][NCAR];
extern DWORD sprites[ROW][COL][NO_SPRITE];
extern DWORD strada[H][W];
 
//resolution to use
WORD r=600;
WORD c=800;
BYTE bpp=16;
 
// useful colors...
DWORD white;
DWORD black;
DWORD red;
DWORD gray;
DWORD blue;
DWORD green;
DWORD border;
DWORD tl_bg;
 
//PID vectors
 
PID p_table[MAX_CAR];
PID c_table[MAX_CAR];
PID g_table[MAX_CAR];
PID a_table[MAX_CAR];
 
char kill_flag[MAX_CAR];
float cosine[360],sine[360];
 
// data structures
car_data car_data_array[MAX_CAR];
tl_data tl_data_array[MAX_TL];
starting_set starting_set_array[S_POINT];
 
void keyb_h(void);
 
static void version( void )
{
cprintf("\n\nDemo presented by\n");
cprintf("Aguzzi Marco\n");
cprintf(" &\n");
cprintf("Ferrari Fabio\n");
}
 
void my_close(void *arg)
{
grx_close();
kern_printf("Shutting down SIMCITY\n");
}
 
int main(int argc, char **argv)
{
int i;
char tl_name[4];
 
version();
 
sys_atrunlevel(my_close, NULL, RUNLEVEL_BEFORE_EXIT);
 
//resetting kill flags
for(i=0;i<MAX_CAR;i++) {
p_table[i]=0;
kill_flag[i]=0;
}
 
// graphic mode initialization
#ifdef GRAPH
if (grx_init() < 1) {
kern_printf("Error initializing graphics\n");
sys_abort(1);
}
if (grx_open(c,r,bpp) < 0) {
kern_printf("GRX Open Err\n");
sys_abort(1);
}
get_images();
#endif
srand(sys_gettime(NULL));
 
//init the graphic mutex
sem_init(&mutex,1,1);
//init kill flag mutexes
for(i=0;i<MAX_CAR;i++) sem_init(&(kill_mutex[i]),1,1);
//fill sine & cosine lookup tables
fill_table();
/*init keys*/
keyb_h();
set_start_point();
tl_init();
init_struct();
 
/* useful colors ... */
white = rgb(255,255,255);
black = rgb(0,0,0);
red = rgb(255,0,0);
gray = rgb(210,210,210);
blue = rgb(0,0,220);
green = rgb(0,255,0);
border= rgb(128,128,128);
tl_bg= rgb(0,128,0);
#ifdef GRAPH
/* paint scenario*/
draw_scenario();
#endif
#ifndef GRAPH
cprintf("Main: max_tl:%d\n",MAX_TL);
#endif
 
//creating refresher,killer and traffic light processes...
ref_create();
killer_create();
for(i=0;i<MAX_TL;i++) {
sprintf(tl_name,"tl%d",i+1);
#ifndef GRAPH
cprintf("main:tname=%s",tl_name);
#endif
stl_create(tl_name,i);
}
return 0;
}
/unsupported/branches/unsupported/simcity/sprite/sp_6.raw
0,0 → 1,23
ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*~*~*ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*~*~*
ÿÿÿÿÿÿÿÿÿ~*
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿ~*
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿ
ÿÿÿ~*
ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~*
/unsupported/branches/unsupported/simcity/sprite/sp_7.raw
0,0 → 1,0
vtvÀÀÀÀÀÀÀÀÀÂÀÂÂÀÂÂÀÂÀÀÀ'&'œ›œ•—•{{€€{{~~||{{€€µ´µKLKÂÀ‰Š‰~~RNRMNMRNRNONPOPRORaba~~¦¥¦vtv'''ÀÀÀ~~tutRQRÞÝÞÞÝÞXYXÞÛÞÞÛÞ¢¤¢XYX{{™™™˜˜˜ŠŽŠ€}€jljikiÞÛÞXWXÙÛÙÞÛÞÜÛÜÚÝÚXYXÁ¿ÁRMR€€KLKÂÀŠbbb…‰…ÞÛÞÞÝÞÚÛÚÚÛڅƒ…±°±ÞÜÞÞÛÞÞÛÞÞßÞMNMtut¦¥¦vtvqtq¦£¦WXW¥¤¥…ƒ…°°°ÚÜÚÙÛÙÞÛÞXYXÜÛÜÚÛÚÙÛÙÙÛÙXWXÞÝÞiiijljÀ¾À'%''''ÀÀÀlklÀÁÀÞÛÞÞÜÞÙÛÙXWXÞÜÞXWX………±¯±ÙÛÙÞÛÞÜÝÜÚÛÚÞÛÞÞÞޅ‡…š™š–˜–—›—š—šÞÝÞXWXÙÛÙÚÝÚ¯®¯………ÚÛÚÜÛÜXYXÜÛÜÚÝÚÚÛÚÞÜÞ¬¯¬………¶µ¶µ´µKLKŒ]b]ÚÛÚÜÝÜÞÛÞÙÛÙ±®±ÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞ¢¤¢€€ONOKNK‚¥£¥ÞÝÞÙÛÙÞÛÞÞÛÞXYXÞÝÞÜÛÜÙÛÙÙÜÙÞÛÞXXXXYXÞÛÞÜÛÜsss¦¦¦§¦§xsx¥¤¥ÚÛÚÜÛÜÚÛÚÚÝÚÚÛÚÚÛÚÜÛÜÚÛÚÚÛÚÞÛÞ,+,ÚÛÚÜÛÜÙÜÙÞÛÞsvs~~vtv¦¥¦swsXYX…ƒ…,,,ÙÜÙÙÛÙÞÛÞÙÛÙÞÛÞÞÛÞÙÜÙÞÛÞÞÝÞÞÛÞÙÝÙÞÛހƒ€”’”lllqqqvtvjij¾ÂÞÛÞÞÝÞXWXÞÛÞÙÛÙÙÛÙÙÝÙÞÛÞÚÛÚÚÜÚÞÛÞÙÛÙÙÛÙXYX,,,ÞÜÞÞÜޅ‡…š™š%&%qqqlllÀÁÀÙÛمƒ…±±±ÙÛÙÞÛÞÙÝÙÚÝÚÜÛÜÙÛÙÞÛÞÙÛÙÙÛÙÞÛÞÞÜÞXWXXXXXYXÞÝÞÙÛمˆ…š—š%%%'''™™™ŠˆŠÞÝÞÞÛހƒ€,,,ÞÛÞÚÜÚÜÛÜÞÛÞÜÛÜÚÛÚÚÛÚÜÛÜÙÛÙÙÛÙXWX,+,ÚÛÚÜÛÜÞÛÞada‹‹‹&&&ššš…‡…ÜÛÜÚÛÚÞÝÞÞÛÞÙÜÙÞÛÞÚÛÚÚÛÚÜÛÜÞÛÞÙÛÙÜÝÜÚÛÚÞÛÞÚÝÚÜÛÜÞÜÞ]`]Žb`b………±¯±ÞÛÞÙÛÙÙÛÙÞÛÞÜÛÜÞÝÞÙÛÙÜÝÜÚÛÚÞÝÞÞÛÞÙÛÙÜÝÜÞÛÞÙÛÙXWX¥¦¥‚ONO‹Œ‹abaÞÜÞÜÛÜÚÛÚÞÛÞÜÝÜÙÜÙÜÛÜÚÛÚÞÛÞÙÛÙÞÛÞÙÛÙÙÛÙÞÝÞÙÛÙÞÛÞÞÛÞÙÝÙÞÛÞÙÛÙÜÛÜÚÛÚ¢¢¢ƒƒƒKLKONO‚¥£¥ÚÝÚÜÛÜÞÛÞÙÝÙÙÛÙÚÛÚÜÛÜÞÛÞÙÜÙÞÛÞÙÛÙÞÛÞÚÛÚÜÛÜÙÛÙÚÝÚÜÛÜXWX…ƒ…,,,ÞÝÞÞÜÞsss¦¦¦KLKƒƒƒ¢¤¢ÞÛÞ¬®¬XWXÜÛÜÙÝÙÜÛÜÚÝÚÞÛÞÙÛÙÞÛÞÜÛÜÙÜÙÞÛÞÙÛÙXWXÞÝÞXXXÙÜÙÞÛÞquq§£§ONO‚¥£¥ÙÛÙ±®±………XYXÞÛÞÙÝÙÙÛÙÞÛÞÙÛÙÞÛÞÞÛÞÜÛÜÚÛÚÚÛÚÜÛÜÙÛÙXWX…ƒ…±±±ÞÛÞÙÛÙsss¦¨¦KLKƒƒƒ¢¢¢XWX±®±ÜÛÜÙÛÙÞÛÞÞÝÞÚÛÚÜÛÜÞÛÞÙÛÙÜÛÜÚÝÚÞÛÞÙÝÙÙÛÙXYXsts¦¥¦ONO‚MNMÞÜÞÚÛÚÜÛÜÙÜÙÞÛÞÜÛÜÚÝÚÜÝÜÙÛÙÞÛÞÜÛÜÚÜÚÞÜÞÙÛÙÞÛÞÙÛÙÞÛÞÞÛÞÙÝÙÞÛÞ¢¤¢XVX§£§KLKŒbbb½¾½ÂÀ½¾½ÀÀÀ¾À¾Â¾Â½¾½¾¿¾ÀÀÀÀÀÀ¾¾¾Â¾Â½¾½¾À¾À¾À½À½Â¿Â½À½ÂÀ½¾½½À½Â¾Â½À½½À½’’xwx¢¨¢
/unsupported/branches/unsupported/simcity/sprite/sp_0.raw
0,0 → 1,0
ÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÀÀÀÿÿÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÀÀÀÿÿÿÀÀÀÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿ€€ÿ€ÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÀÀÀÿÿÿÀÀÀÀÀÀÀÀÀÿÿÿÿ€€€ÿ€ÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿ€€ÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÿÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÿÿÀÀÀÿÿÿÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿ€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿ€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿÿÿ€€€€€€€
/unsupported/branches/unsupported/simcity/sprite/sp_1.raw
0,0 → 1,0
vtvÀÀÀÀÀÀÀÀÀÂÀÂÂÀÂÂÀÂÀÀÀ'&'œ›œ•—•{{€€{{~~||{{€€µ´µKLKÂÀ‰Š‰~~RNRMNMRNRNONPOPRORaba~~¦¥¦vtv'''ÀÀÀ~~tutRQRÞÝÞÞÛÞÞÝÞXYXÞÛÞÞÛÞ¢¤¢XYX{{™™™˜˜˜ŠŽŠ€}€jljikiÞÛÞXWXÞÝÞÙÛÙÞÛÞÜÛÜÚÝÚXYXÁ¿ÁRMR€€KLKÂÀŠbbb…‰…ÞÛÞÞÝÞÚÛÚÚÛÚÚÛڅƒ…±°±ÞÜÞÞÛÞÞÛÞÞßÞMNMtut¦¥¦vtvqtq¦£¦WXW¥¤¥…ƒ…°°°ÚÜÚÙÛÙÞÛÞÞÛÞXYXÜÛÜÚÛÚÙÛÙÙÛÙXWXÞÝÞiiijljÀ¾À'%''''ÀÀÀlklÀÁÀÞÛÞÞÜÞÙÛÙXWXÞÜÞÙÛÙXWX………±¯±ÙÛÙÞÛÞÜÝÜÚÛÚÞÛÞÞÞޅ‡…š™š–˜–—›—š—šÞÝÞXWXÙÛÙÚÝÚ¯®¯………ÚÛÚÜÛÜXWXXYXÜÛÜÚÝÚÚÛÚ*+*ÞÜÞ¬¯¬………¶µ¶µ´µKLKŒ]b]ÚÛÚÜÝÜÞÛÞÙÛÙ±®±ÞÛÞÙÛÙÞÜÞÞÛÞÙÛÙÞÛÞÙÛÙ,+,ÚÝÚÜÛÜÞÛÞ¢¤¢€€ONOKNK‚¥£¥ÞÝÞÙÛÙÙÛÙÞÛÞÞÛÞXYXÞÝÞÜÛÜÚÛÚÙÛÙÞÛÞÙÜÙÞÛÞXXXXYXÞÛÞÜÛÜÚÝÚÞÜÞsss¦¦¦§¦§xsx¥¤¥ÚÛÚÜÛÜÞÝÞÚÛÚÚÝÚÚÛÚÚÛÚÜÛÜÞÛÞÚÝÚÚÛÚÚÛÚÞÛÞ,+,ÚÛÚÜÛÜÙÜÙÞÛÞsvs~~vtv¦¥¦swsXYX…ƒ…,,,ÙÜÙÞÛÞÙÛÙÞÛÞÙÛÙÜÛÜÚÜÚÙÛÙÞÛÞÞÛÞÙÜÙÞÛÞÞÝÞÞÛÞÙÝÙÞÛހƒ€”’”lllqqqvtvjij¾ÂÞÛÞÞÝÞXWXÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞÙÝÙÞÛÞÚÛÚÚÛÚÚÜÚÞÛÞÙÛÙÙÛÙXYX,,,ÞÜÞÞÜޅ‡…š™š%&%qqqlllÀÁÀÙÛمƒ…±±±ÙÛÙÞÛÞÙÝÙÞÛÞÚÝÚÜÛÜÙÛÙÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞÞÜÞXWXXXXXYXÞÝÞÙÛمˆ…š—š%%%'''™™™ŠˆŠÞÝÞÞÛހƒ€,,,ÞÛÞÚÜÚÜÛÜÙÛÙÞÛÞÜÛÜÚÛÚÚÛÚÜÛÜÙÛÙÞÝÞÙÛÙÙÛÙXWX,+,ÚÛÚÜÛÜÞÛÞada‹‹‹&&&ššš…‡…ÜÛÜÚÛÚÞÝÞÞÛÞÙÜÙÞÛÞÜÛÜÚÛÚÚÛÚÜÛÜÞÛÞÙÛÙÜÝÜÚÛÚÚÛÚÜÛÜÞÛÞÚÝÚÜÛÜÞÜÞÙÛÙÞÛÞÞÛÞ]`]Žb`b………±¯±ÞÛÞÙÛÙÙÛÙÞÛÞÚÛÚÜÛÜÞÝÞÙÛÙÜÝÜÚÛÚÞÝÞÙÛÙÞÛÞÙÛÙÜÝÜÚÛÚÙÛÙÜÛÜÚÛÚÞÛÞÙÛÙXWX¥¦¥‚ONO‹Œ‹abaÞÜÞÜÛÜÚÛÚÞÛÞÜÝÜÚÛÚÙÜÙÜÛÜÚÛÚÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞÙÛÙÞÝÞÙÛÙÞÛÞÞÛÞÙÝÙÞÛÞÙÛÙÜÛÜÚÛÚ¢¢¢ƒƒƒKLKONO‚¥£¥ÚÝÚÜÛÜÞÛÞÙÝÙÙÛÙÞÛÞÚÛÚÜÛÜÞÛÞÙÜÙÞÛÞÙÛÙÞÛÞÙÛÙÞÝÞÚÛÚÜÛÜÙÛÙÚÝÚÜÛÜXWX…ƒ…,,,ÞÝÞÞÜÞsss¦¦¦KLKƒƒƒ¢¤¢ÞÛÞ¬®¬XWXÜÛÜÚÛÚÙÝÙÜÛÜÚÝÚÞÛÞÙÛÙÞÛÞÚÝÚÜÛÜÙÜÙÞÛÞÜÛÜÚÛÚÞÛÞÙÛÙXWXÞÝÞXXXÙÜÙÞÛÞquq§£§ONO‚¥£¥ÙÛÙ±®±………XYXÞÛÞÙÝÙÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞÙÛÙÞÛÞÜÛÜÚÛÚÚÛÚÜÛÜÙÛÙÚÛÚÜÛÜXWX…ƒ…±±±ÞÛÞÙÛÙsss¦¨¦KLKƒƒƒ¢¢¢XWX±®±XWXÙÛÙÞÛÞÚÛÚÜÛÜÙÛÙÞÛÞÙÛÙÞÝÞÚÛÚÜÛÜÞÛÞÙÛÙÜÛÜÚÝÚÞÛÞÙÝÙXWX…ƒ…,,,ÙÛÙXYXsts¦¥¦ONO‚MNMÞÝÞÙÛÙÞÜÞÚÛÚÜÛÜÙÜÙÞÛÞÜÛÜÚÝÚÚÛÚÜÝÜÙÛÙÞÛÞÜÛÜÚÜÚÞÜÞÙÛÙÞÛÞÙÛÙÞÛÞÞÛÞÙÝÙÞÛÞÞÛÞ¢¤¢XVX§£§KLKŒbbb½¾½ÂÀ½¾½ÀÀÀ¾À¾Â¾Â½¾½¾¿¾ÀÀÀÀÀÀ¾¾¾Â¾Â½¾½¾À¾À¾À½À½Â¿Â½À½ÂÀ½¾½½À½Â¾Â½À½½À½’’xwx¢¨¢
/unsupported/branches/unsupported/simcity/sprite/sp_2.raw
0,0 → 1,0
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
/unsupported/branches/unsupported/simcity/sprite/sp_3.raw
0,0 → 1,0
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿ@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿ@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
/unsupported/branches/unsupported/simcity/sprite/sp_4.raw
0,0 → 1,0
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@ÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÿÿÿÿÿ@@@ÀÀÀÀÀÀ@@@@@@@@@@@@ÀÀÀÀÀÀ@@@@@@@@@ÿÿ@@@ÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ@@@@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀ@@@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
/unsupported/branches/unsupported/simcity/sprite/sp_5.raw
0,0 → 1,26
ÿÿÿÿ
ÿÿÿÿÿÿ
ÿÀÿÿÀÿÿÀÿÿÀÿ
ÿÀÿÿÀÿÿÀÿ@@@@@@@@@@@@
ÿÀÿÿÀÿÿÀÿÿÀÿÿÀÿ@@@@@@@@@@@@@@@@@@ÿÀÿÿÀÿÿÀÿÿÀÿ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÿÀÿ@@@@@@@@@@@@@@@@@@@@@@@@ÿÀÿÿÀÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€~*~*~*~*€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~*~*~*~*€€€€€€€€€ÜÜ܀€€€€€€€€ÜÜ܀€€€€€€€€~*~*~*~*
€€€€€€€€€€€€ÜÜ܀€€€€€€€€ÜÜ܀€€€€€€€€~*
€€€€€€€€€€€€ÜÜ܀€€€€€€€€ÜÜ܀€€€€€€€€~*
€€€€€€€€€€€€ÜÜ܀€€€€€€€€ÜÜ܀€€€€€€€€~*
€€€€€€€€€€€€ÜÜ܀€€€€€€€€€€€ÜÜ܀€€€€€€€€€€€~*€€€€€€€€€ÜÜÜÜÜ܀€€€€€€€€€€€€€€ÜÜ܀€€€€€€€€€€€~*€€€€€€€€€ÜÜ܀€€€€€€€€€€€€€€€€€ÜÜ܀€€€€€€€€€€€~*€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~*€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~*€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~*
@@@@@@
@@@@@@~*
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@~*
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@~*
/unsupported/branches/unsupported/simcity/tasks.c
0,0 → 1,409
//*******************************tasks.c************************************
// task bodies
#include <drivers/glib.h>
#include <stdlib.h>
#include <string.h>
#include <kernel/func.h>
#include <drivers/glib.h>
#include <semaphore.h>
#include <math.h>
#include "include/simcity.h"
#include "include/states.h"
#include "include/draw.h"
#include "include/misc.h"
#include "include/car.h"
#include "include/proc.h"
#define rgb rgb16
 
/*extern starting_set starting_set_array[S_POINT];
extern short maxc; */
 
TASK killer(void *arg) {
short i,j=0;
DWORD col[3];
char flag=0;
 
col[0]=red;
col[1]=green;
col[2]=white;
 
while(1) {
if(maxc>0) {
for(i=0;i<MAX_CAR;i++) {
sem_wait(&(kill_mutex[i]));
if(car_data_array[i].boom && car_data_array[i].running) flag=1;
else flag=0;
sem_post(&(kill_mutex[i]));
if(flag) {
del(i);
killing(i);
}
}
}
j=(j+1)%3;
sem_wait(&mutex);
grx_text("Killer active!",CAMX,CAMY+MAX_CAR*46,col[j],black);
sem_post(&mutex);
task_endcycle();
}
}
 
 
TASK refresher(void *arg) {
int i;
tl_data *d;
 
while(1) {
sem_wait(&mutex);
grx_putimage(MAPX,MAPY,MAPX+W-1,MAPY+H-1,street);
for(i=0;i<MAX_TL;i++) {
d=&(tl_data_array[i]);
if((d->vpos=='g')) {
draw_tl(d->u.x,d->u.y,g_sem[U]);
draw_tl(d->d.x,d->d.y,g_sem[D]);
draw_tl(d->l.x,d->l.y,r_sem[L]);
draw_tl(d->r.x,d->r.y,r_sem[R]);
} else if(d->vpos=='y') {
draw_tl(d->u.x,d->u.y,y_sem[U]);
draw_tl(d->d.x,d->d.y,y_sem[D]);
draw_tl(d->l.x,d->l.y,r_sem[L]);
draw_tl(d->r.x,d->r.y,r_sem[R]);
} else if(d->hpos=='g') {
draw_tl(d->u.x,d->u.y,r_sem[U]);
draw_tl(d->d.x,d->d.y,r_sem[D]);
draw_tl(d->l.x,d->l.y,g_sem[L]);
draw_tl(d->r.x,d->r.y,g_sem[R]);
} else if(d->hpos=='y') {
draw_tl(d->u.x,d->u.y,r_sem[U]);
draw_tl(d->d.x,d->d.y,r_sem[D]);
draw_tl(d->l.x,d->l.y,y_sem[L]);
draw_tl(d->r.x,d->r.y,y_sem[R]);
}
}
sem_post(&mutex);
task_endcycle();
}
}
 
TASK blink_arrow(int number) {
char ld=0,prev=0,dir=0;
short c;
BYTE *arrow_img;
 
c=number*46;
while(1) {
if(kill_flag[number]) {
return 0;
}
if(!car_data_array[number].boom) {
dir=car_data_array[number].dir+1;
if(dir==prev) {
ld=(ld+1)%2;
if(ld==1)
arrow_img=arrow[(int)dir];
else
arrow_img=arrow[1];
 
sem_wait(&mutex);
grx_putimage(CAMX+80,CAMY-1+c,CAMX+80+29,CAMY-1+c+29,arrow_img);
sem_post(&mutex);
} else {
prev=dir;
ld=0;
sem_wait(&mutex);
grx_putimage(CAMX+80,CAMY-1+c,CAMX+80+29,CAMY-1+c+29,arrow[(int)dir]);
sem_post(&mutex);
}
}
task_endcycle();
}
}
 
 
TASK gauge_c(int number) {
int c;
float angle,ro;
int x,y;
char vel[5];
 
c=number*46;
while(1) {
if(kill_flag[number]) {
return 0;
}
if(!car_data_array[number].boom) {
angle=180.0*car_data_array[number].speed/MAX_SPEED;
sprintf(vel,"%.1f",car_data_array[number].speed);
ro=9.0;
y=my_rint(ro*sine[my_rint(angle)]);
x=my_rint(ro*cosine[my_rint(angle)]);
sem_wait(&mutex);
grx_putimage(CAMX,CAMY+c,CAMX+29,CAMY+29+c,gauge_img);
grx_line(CAMX+14,CAMY-1+c+25,CAMX+14-x,CAMY-1+c+25-y,blue);
grx_text(vel,CAMX,CAMY+c+30,white,black);
sem_post(&mutex);
} else {
sem_wait(&mutex);
grx_putimage(CAMX,CAMY+c,CAMX+29,CAMY+29+c,brk_gauge);
sem_post(&mutex);
}
task_endcycle();
}
}
 
TASK camera(int number) {
int c;
 
c=number*46;
grx_rect(CAMX+40-1,CAMY-1+c,CAMX+40+30,CAMY+30+c,green);
while(1) {
if(kill_flag[number]) {
return 0;
}
sem_wait(&mutex);
grx_putimage(CAMX+40,CAMY+c,CAMX+40+29,CAMY+c+29,vbuf[number]);
sem_post(&mutex);
task_endcycle();
}
}
 
TASK traffic_light(tl_data *d) {
char hpos,vpos,flag;
 
flag=0;
vpos=d->vpos;
if(vpos=='g') {
hpos='r';
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->l.x,d->l.y,r_sem[L]);
draw_tl(d->r.x,d->r.y,r_sem[R]);
draw_tl(d->u.x,d->u.y,g_sem[U]);
draw_tl(d->d.x,d->d.y,g_sem[D]);
sem_post(&mutex);
#endif
} else {
vpos='r';
hpos='g';
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->l.x,d->l.y,g_sem[L]);
draw_tl(d->r.x,d->r.y,g_sem[R]);
draw_tl(d->u.x,d->u.y,r_sem[U]);
draw_tl(d->d.x,d->d.y,r_sem[D]);
sem_post(&mutex);
#endif
}
task_endcycle();
while(1) {
if(vpos=='g') {
vpos='y';
flag=1;
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->u.x,d->u.y,y_sem[U]);
draw_tl(d->d.x,d->d.y,y_sem[D]);
sem_post(&mutex);
#endif
}
if((vpos=='y')&&(!flag)) {
vpos='r';
hpos='g';
flag=1;
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->u.x,d->u.y,r_sem[U]);
draw_tl(d->d.x,d->d.y,r_sem[D]);
draw_tl(d->l.x,d->l.y,g_sem[L]);
draw_tl(d->r.x,d->r.y,g_sem[R]);
sem_post(&mutex);
#endif
}
if((vpos=='r')&&(!flag)) {
if(hpos=='g') {
hpos='y';
flag=1;
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->l.x,d->l.y,y_sem[L]);
draw_tl(d->r.x,d->r.y,y_sem[R]);
sem_post(&mutex);
#endif
}
if((hpos=='y')&&(!flag)) {
hpos='r';
vpos='g';
#ifdef GRAPH
sem_wait(&mutex);
draw_tl(d->l.x,d->l.y,r_sem[L]);
draw_tl(d->r.x,d->r.y,r_sem[R]);
draw_tl(d->u.x,d->u.y,g_sem[U]);
draw_tl(d->d.x,d->d.y,g_sem[D]);
sem_post(&mutex);
#endif
}
}
flag=0;
d->vpos=vpos;
d->hpos=hpos;
#ifndef GRAPH
sem_wait(&mutex);
cprintf("semaforo %s: verticale:%c orizz.:%c\n",d->tl_name,vpos,hpos);
sem_post(&mutex);
#endif
task_endcycle();
}
}
 
TASK car(car_data *cd) {
char ob_type=FREE;
int start_point,sat_angle=0;
int tl=0;
short stato=NORM,dir_flag=0;
 
sem_wait(&(kill_mutex[cd->number]));
while(kill_flag[cd->number]){
cd->running=0;
sem_post(&(kill_mutex[cd->number]));
return 0;
}
sem_post(&(kill_mutex[cd->number]));
while(1) {
sem_wait(&(kill_mutex[cd->number]));
while(kill_flag[cd->number]){
cd->running=0;
sem_post(&(kill_mutex[cd->number]));
return 0;
}
sem_post(&(kill_mutex[cd->number]));
if(cd->xp>630||cd->yp>590||cd->xp<18||cd->yp<MAPY+3) {
start_point=rand()%S_POINT;
if(start_point==2)
start_point++;
cd->xpos=cd->xp=starting_set_array[start_point].xpos;
cd->ypos=cd->yp=starting_set_array[start_point].ypos;
cd->angle=starting_set_array[start_point].angles;
}
if (!cd->boom) {
// Control State Machine
if(stato==NORM) {
cd->dir=STRAIGHT;
ob_type=collision_sensor(cd);
ch_spd(cd,ob_type);
if(cd->dist_obs<30 && ob_type==STOP) {
stato=INC1;
}
if(ob_type==FREE || cd->dist_obs>=27 || cd->speed>=2.0) {
cd->angle=sensore(cd);
cd->angle=normalize(cd->angle);
}
}
if(stato==INC1) {
tl=find_tl(cd->angle,cd->xp,cd->yp);
if(!dir_flag)
cd->dir=rand()%3-1;
if(find_col(cd->angle,tl)=='g') {
switch(cd->dir) {
case STEER_RIGHT:
stato=DX1;
break;
case STRAIGHT:
case STEER_LEFT:
stato=STR1;
break;
default:
stato=DX1;
}
} else {
cd->speed=0.0;
dir_flag=1;
}
}
if(stato==DX1) {
dir_flag=0;
cd->speed=4.0;
cd->angle=sensore(cd);
if(ob_type!=STOP)
stato=NORM;
else {
ob_type=collision_sensor(cd);
if(ob_type==CAR)
ch_spd(cd,ob_type);
}
}
if(stato==STR1) {
dir_flag=0;
cd->angle=allinea(cd->angle);
sensore(cd);
cd->speed=4.0;
ob_type=collision_sensor(cd);
if(ob_type==CAR)
ch_spd(cd,ob_type);
if(cd->middle==MAX_DIST) {
if(cd->dir==STRAIGHT)
stato=STR2;
else {
sat_angle=cd->angle+90;
stato=SX1;
}
}
}
if(stato==STR2) {
cd->speed=4.0;
sensore(cd);
ob_type=collision_sensor(cd);
if(ob_type==CAR)
ch_spd(cd,ob_type);
if(abs(cd->front-cd->rear)<0.1 && ((cd->middle-NORM_DIST)<7.0))
stato=NORM;
}
if(stato==SX1) {
cd->speed=4.0;
sensore(cd);
ob_type=collision_sensor(cd);
if(ob_type==CAR)
ch_spd(cd,ob_type);
else {
cd->angle+=7;
if(cd->angle>=sat_angle) {
cd->angle=sat_angle;
}
}
if(abs(cd->front-cd->rear)<0.1 && ((cd->middle-NORM_DIST)<7.0))
stato=NORM;
}
}
if (cd->dist_obs<COLL_DIST && ob_type==CAR) {
cd->boom=1;
cd->speed=0.0;
}
sem_wait(&mutex);
grx_getimage(cd->xp-15,cd->yp-15,cd->xp+14,cd->yp+14,vbuf[cd->number]);
if (cd->boom==0) {
drawCar(cd->xp,cd->yp,cd->angle,DRAW);
}
if (cd->boom==1) {
drawSprites(cd->xp,cd->yp,0,DRAW);
}
sem_post(&mutex);
task_endcycle();
sem_wait(&mutex);
if (cd->boom==0) {
grx_putimage(cd->xp-15,cd->yp-15,cd->xp+14,cd->yp+14,vbuf[cd->number]);
} else {
drawSprites(cd->xp,cd->yp,0,CANCEL);
}
sem_post(&mutex);
sem_wait(&(kill_mutex[cd->number]));
while(kill_flag[cd->number]){
cd->running=0;
sem_post(&(kill_mutex[cd->number]));
return 0;
}
sem_post(&(kill_mutex[cd->number]));
cd->xpos+=cd->speed*cos(DEG_TO_RAD(cd->angle));
cd->ypos-=cd->speed*sin(DEG_TO_RAD(cd->angle));
cd->xp=my_rint(cd->xpos);
cd->yp=my_rint(cd->ypos);
}
}
/unsupported/branches/unsupported/simcity/keyfunct.c
0,0 → 1,85
/**************** Functions called by keyboard handler*********/
#include <drivers/keyb.h>
#include <drivers/glib.h>
#include <drivers/glib.h>
#include <stdlib.h>
#include <string.h>
#include "include/simcity.h"
#include "include/proc.h"
 
short maxc=0;
char sens=0;
 
extern starting_set starting_set_array[S_POINT];
 
void h_car_create(KEY_EVT *k)
{
char name[10];
int num;
 
if((maxc<MAX_CAR)) {
num=add();
if(num>=0) {
sprintf(name,"car%d",num);
h_create(name,num);
sprintf(name,"camera%d",num);
cam_create(name,num);
sprintf(name,"speed%d",num);
gauge_create(name,num);
sprintf(name,"arrow%d",num);
arrow_create(name,num);
}
}
}
 
void s_car_create(KEY_EVT *k)
{
char name[10];
int num;
 
if((maxc<MAX_CAR)) {
num=add();
if(num>=0) {
sprintf(name,"car%d",num);
h_create(name,num);
sprintf(name,"camera%d",num);
cam_create(name,num);
sprintf(name,"speed%d",num);
gauge_create(name,num);
sprintf(name,"arrow%d",num);
arrow_create(name,num);
}
}
}
 
void h_car_kill(KEY_EVT *k) {
int num;
 
if(maxc>0) {
num=del_o();
if(num>=0) {
killing(num);
}
}
}
 
void endfun(KEY_EVT *k)
{
grx_close();
cprintf("Brk command pressed! Ending...\n");
sys_end();
}
 
void refresh(KEY_EVT *k){
 
sem_wait(&mutex);
//heavy and obsolete.....
//draw_scenario();
grx_putimage(MAPX,MAPY,MAPX+W-1,MAPY+H-1,street);
sem_post(&mutex);
}
 
void sensor_switch(KEY_EVT *k) {
if(sens==0) sens=1;
else sens=0;
}
/unsupported/branches/unsupported/simcity/misc.c
0,0 → 1,215
#include <math.h>
#include "include/misc.h"
#include "include/simcity.h"
 
int my_rint(float num) {
return (int)floor(num+0.5);
}
 
void fill_table(void) {
int i;
for (i=0;i<360;i++) {
sine[i]=sin(DEG_TO_RAD(i));
cosine[i]=cos(DEG_TO_RAD(i));
}
}
 
void tl_init() {
//MAPX,MAPY
char col[2];
short i;
 
col[0]='r';
col[1]='g';
for(i=0;i<MAX_TL;i++) {
tl_data_array[i].vpos=col[i%2];
tl_data_array[i].period=(i+3)*SECOND;
tl_data_array[i].l.x+=MAPX;
tl_data_array[i].l.y+=MAPY;
tl_data_array[i].r.x+=MAPX;
tl_data_array[i].r.y+=MAPY;
tl_data_array[i].u.x+=MAPX;
tl_data_array[i].u.y+=MAPY;
tl_data_array[i].d.x+=MAPX;
tl_data_array[i].d.y+=MAPY;
}
}
 
void set_start_point() {
//MAPX,MAPY
starting_set_array[0].xpos=607+MAPX;
starting_set_array[0].ypos=20+MAPY;
starting_set_array[0].angles=180;
starting_set_array[1].xpos=12+MAPX;
starting_set_array[1].ypos=62+MAPY;
starting_set_array[1].angles=0;
starting_set_array[2].xpos=260+MAPX;
starting_set_array[2].ypos=460+MAPY;
starting_set_array[2].angles=90;
starting_set_array[3].xpos=605+MAPX;
starting_set_array[3].ypos=205+MAPY;
starting_set_array[3].angles=180;
}
 
int returnCarIndex(int a) {
int indice=-1;
int angle;
 
angle=normalize(a);
if (((angle>=0) && (angle<=8)) || ((angle>353) && (angle<360))) { // 0 (+8 ; -7)
indice=0;
}
if ((angle<=23) && (angle>8)) { // 15
indice=1;
}
if ((angle<=38) && (angle>23)) { // 30
indice=2;
}
if ((angle<=53) && (angle>38)) { // 45
indice=3;
}
if ((angle<=68) && (angle>53)) { // 60
indice=4;
}
if ((angle<=83) && (angle>68)) { // 75
indice=5;
}
if ((angle<=98) && (angle>83)) { // 90
indice=6;
}
if ((angle<=113) && (angle>98)) { // 105
indice=7;
}
if ((angle<=128) && (angle>113)) { // 120
indice=8;
}
if ((angle<=143) && (angle>128)) { // 135
indice=9;
}
if ((angle<=158) && (angle>143)) { // 150
indice=10;
}
if ((angle<=173) && (angle>158)) { // 165
indice=11;
}
if ((angle<=188) && (angle>173)) { // 180
indice=12;
}
if ((angle<=203) && (angle>188)) { // 195
indice=13;
}
if ((angle<=218) && (angle>203)) { // 210
indice=14;
}
if ((angle<=233) && (angle>218)) { // 225
indice=15;
}
if ((angle<=248) && (angle>233)) { // 240
indice=16;
}
if ((angle<=263) && (angle>248)) { // 255
indice=17;
}
if ((angle<=278) && (angle>263)) { // 270
indice=18;
}
if ((angle<=293) && (angle>278)) { // 285
indice=19;
}
if ((angle<=308) && (angle>293)) { // 300
indice=20;
}
if ((angle<=323) && (angle>308)) { // 315
indice=21;
}
if ((angle<=338) && (angle>323)) { // 330
indice=22;
}
if ((angle<=353) && (angle>338)) { // 345
indice=23;
}
if (angle==360) {
indice=0;
}
return indice;
}
 
int normalize(int angle) {
if(angle<0)
return ((angle+360));
if(angle>=360)
return ((angle-360));
return angle;
}
 
int module(int x1,int x2,int y1,int y2) {
int x,y;
 
x=x1-x2;
y=y1-y2;
x*=x;
y*=y;
return x+y;
}
 
int allinea(int angle) {
int old_angle;
 
old_angle=normalize(angle);
if(old_angle<45)
old_angle=0;
else if(old_angle<135)
old_angle=90;
else if(old_angle<225)
old_angle=180;
else
old_angle=270;
return old_angle;
}
 
int find_tl(int angle,int xp,int yp) {
int a,min_tl,old_min,mins,i;
 
a=allinea(angle);
min_tl=old_min=10000;
for(mins=i=0;i<MAX_TL;i++) {
switch(a) {
case 0:
min_tl=module( xp,tl_data_array[i].l.x, yp,tl_data_array[i].l.y);
break;
case 90:
min_tl=module( xp,tl_data_array[i].d.x, yp,tl_data_array[i].d.y);
break;
case 180:
min_tl=module( xp,tl_data_array[i].r.x, yp,tl_data_array[i].r.y);
break;
case 270:
min_tl=module( xp,tl_data_array[i].u.x, yp,tl_data_array[i].u.y);
break;
default:
break;
}
if(min_tl<old_min) {
old_min=min_tl;
mins=i;
}
}
return mins;
}
 
int find_col(int angle,int tl) {
int min_tl=0,a;
 
a=allinea(angle);
switch(a) {
case 0:
case 180:
min_tl=tl_data_array[tl].hpos;
break;
case 90:
case 270:
min_tl=tl_data_array[tl].vpos;
break;
}
return min_tl;
}
/unsupported/branches/unsupported/simcity/sem.raw
0,0 → 1,0
199146290278187261299163441142537285427269538166193318290431178423298324
/unsupported/branches/unsupported/simcity/img/car_000n.raw
0,0 → 1,0
€€€ÿ€€€ÿÿÿÿÿ€€€ÿÿÿÿÿÿÿ€€€ÿÿ€ÿ€€€ÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿ€€€ÿ€€€€€€€€€ÿÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€€€€ÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿ€€€€€€ÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€€€€€€€ÿÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿ€€€ÿ€€€ÿÿÿÿÿ€€€ÿÿÿÿÿÿÿ€€€ÿÿ€
/unsupported/branches/unsupported/simcity/img/Bb0.raw
0,0 → 1,0
ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBZ9Rc„ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJJ9)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBsZÿÞçÎçÎçÎçÎ99cJ)))ZޜçÎï΄Œ!!!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1kBïÎçÎçÎçÎçÎçÎçÎïÎïÎçÎïÖçÎçÎÿÞçÎïÎïÎsc)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZJscçÎïÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎïÖïÎïÎçÎçÎçÎçÎçÎÿÞïÎ{„ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1ZRçÎçÎçÎçÎçÆçÆçÎçÆçÆçÎ÷ÖïÎçÎïÎïÖïÎçÎçÎçÎçÎïÎçÎçÎçÎïČÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)9B)!sZïÎçÎ÷ÖïÖçÎçÎçÆçÎçÆçÎçÎçÆçÆçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÆçÎïÖ9c1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ!!1­”çÎçÎçÎïÎçÎçÎçÎçÎçÎçÆçÎçÎçÎçÆçÎçÆçÆçÎçÎçÎçÆïÎçÆçÎïÎçÎçÎçÎçÎçÎJBkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ{kïÎçÎçÎïÎçÆçÆçÎçÆçÆçÎçÆçÎïÎçÎçÆçÎçÎçÎçÎïÎçÎçÆçÎçÎçÆçÎçÎçÎïÎçÎçÎïÎksÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎRZkÿÞçÎçÎçÆçÎçÎçÎçÆçÎçÎçÎçÎçÎçÆçÆçÎçÎçÎïÎçÎçÆçÎçÎïÎçÎçÎçÆïÎçÎçÎçÎçÎçÎçέµRRZkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆέ”çÎçÎçÆçÆçÆçÆçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÆïÎçÎçÎçÎïÎçÎçÎçÎçÎçÎïÎçÆçÎçÎïք{!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ19ZïÎïÎçÎçÆçÆçÆçÎçÎçÆçÆçÆçÆçÎçÎçÆçÎçÎçÆçÎçÎçÎïÎçÎçÎçÎçÎçÎçÆçÎçÎçÆïÎçÎçÎçÎçÆçÆçÎçÎ1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆέ”çÎçÎçÆçÆçÆçÆçÆçÎçÎçÎçÎçÆçÆçÎçÎçÎïÎçÎçÎïÎçÎçÎçÎçÎïÎçÆïÎçÎçÎçÎçÎçÎçÎçÎçÎçÆçÎçÎçÎ99ÆÆÎÆÆÎÆÆÎÆÆÎ99BçÎçÎçÎçÆçÆÞ½çÎçÎçÎçÎçÆçÎçÎçÆçÎçÎçÎçÎïÎçÆçÎçÎçÎçÎçÎçÎçÎçÎçÆïÎçÆçÎçÎçÎïÎçÎçÎïÎçÎ1ÆÆÎÆÆÎÆÆÎÆÆÎ9çÎçÎçÎçÆçÆçÎçÎçÎçÎçÆçÎçÎçÎçÎçÎçÎçÎçÎçÆçÎçÆïÎçÎïÎçÎçÎïÎçÎçÎçÆçÎïÎçÎçÎçÎçÆçÆçÎçÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZ)ïÎçÎçÎçÎçÎçÎçÎçÆçÆçÆçÎçÎçÎçÎçÎçÎçÎçÎçÎçÎçÆçÎçÎçÎçÆçÎçÆçÎïÎçÎçÎçÆçÎçÎçÎïÎçÆçÎçÎ19ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ{JçÎçÎçÎçÎçÆçÎçÎçÎçÎçÎçÎçÆçÎçÎçÎïÎçÆçÎïÎçÆçÎïÎçÆçÎçÆïÎçÎçÎçÆçÆçÎçÎçÎçÎçÎçÎçÎçÎïÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎsZçÎçÎçÎçÎçÆçÆçÎçÆçÎçÎçÆçÎçÎçÆçÎçÎçÎçÎçÆïÎçÎçÎçÆçÎçÎçÎçÎçÎçÆçÎçÎçÎçÎçÎçÎçÎçÎçÎçέ”ÆÆÎÆÆÎÆÆÎÆÆε„ïÎçÎïÎçÆçÆçÎçÎçÎçÆçÎçÎçÎçÎçÆçÎçÆçÎçÎçÆçÆçÆçÎçÎçÎçÎçÎçÎçÆçÎçÆçÎçÎçÎçÎçÆçÎïÎçÎçÎçÎZRÆÆÎÆÆÎÆÆÎÆÆΜsçÎçÎçÎçÆçÆçÎçÎçÎçÎïÎçÆçÎçÎçÎïÎçÆçÎçÎçÆçÎïÎçÆçÆçÆçÎçÎçÎçÎçÆçÆçÎçÎçÎçÎçÎïÎçÎçÎçÎçÎRÆÆÎÆÆÎÆÆÎJZB¥{çÎçÎçÆçÆçÆçÆçÆçÆçÎçÎçÎçÎçÎçÎçÆçÆçÆçÎçÆçÎçÎçÎçÎçÆçÎçÆçÎçÎçÎçÆçÆçÎïÎïÖçÎçÎçÎïÎçÎ¥ÞÆÆÎÆÆÎÆÆÎ¥„çÎçÎçÆçÆçÆçÎçÎçÎçÆçÆçÆçÎçÎçÆçÎçÆçÆçÎçÎçÆïÎçÆïÎçÎïÎçÎçÆçÆçÎçÆçÆïÎïÖÞÎçÎçÎïÎçÎçÎBJBkÆÆÎÆÆÎÆÆÎZskçÎçÎçÎçÆçÆçÎçÎçÎçÎçÎçÎçÎçÎçÆçÎçÎçÎïÎ÷ÖçÎçÎçÎçÎçÎçÎçÎçÎçÎçÆçÆçÆçÎçέ”ZJÞÎ÷ÖÿÞçÎBÆÆÎÆÆÎÆÆÎÆÆÎ!!JïÎçÎçÎçÆçÆçÎçÎçÎçÎçÎçÆçÎçÎçÎçÆçÎçÎïÎÿÞçƽ¥çÎÆÆçÎçÎçÎïÎçÎçÎÆÆ1ïÎçÎçÎ1c1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎsZçÎçÎçÆçÆÞ½çÎçÆçÎçÎçÎçÎçÆçÆçÎçÎçÎïÎçČïÿ„ŒŒsïÎçÎ{JçÎçÎÆÆÿÞçÆç΄ŒÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ{kçÎçÎçÆçÆçÆÞÎçÎçÆÞÎÞ½çÎçÎçÎçÆçÎçÆçÎçÎkBïÿRsçÎ{„1sçÎçÎÆÆÞ½çÎçÎçÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎkBçÎçÎçÆÞ½çÆçÆçÎÞÎÞ½çÎçÎçÆçÎçÎçÆçÎç΄Œ1çÎïÖks„ŒçÎ{„)çÎçÎçΌsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΜsçÎçÎçÆçÆçÎÞÎçÆçÆçÎçÎçÆçÎçÆçÎçÎçÎRs!!{9J„kZk1JŒZJ!!1sc!sc!199BŒsZBk1J¥ŒÿZRZ9ZskÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΔkçÎçÎçÎçÆçÆçÆçÎçÆçÎçÆçÎçÎçÆçÎçÎ1ƄZç¥Rç¥Zç¥Zç¥Zï¥Zç¥Rç¥Zç¥Rç¥Rç¥Rç¥Rç¥Zç¥R­ŒsZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ¥{çÎçÆçÎçÆÞ½çÆÞ½çÎÞÎçÎçÆïÎçÎçÎ)֔Zç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥Zç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆν¥ïÎÞ½çÎçÆçÆÞÎçÎçÎçÆçÆçÆçÎçÎ11ƄZç¥Zç¥Zç¥Jï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥Rç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1”kçÎÞ½çÎçÆçÆçÆçÎçÎÞ½çÆïÎÆÆsç¥Zç¥Zç¥Rç¥Rç¥Rç¥Rï¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥R֔ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎޜçÎçÆçÎçÆÞ½ÞÎÞÎçÎçÎçÆçÎÞ½œcBç¥Zç¥Rç¥Rï¥Zç¥Zï¥Rç¥Jç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆέ”çÎÞ½çÎçÆçÎçÆçÎÞ½çÆçÆçÎçÎç¥Zç¥Rç¥Rç¥Rç¥Rï¥Rç¥Rç¥Jç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥Rç¥Zç¥R”{BÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïÎÞ½çÎçÆÞ½çÎÞÎçÎçÎçÆçÎïÎç¥Zç¥Rç¥Rï¥Rç¥Rç¥Rç­Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥ZƔBBkZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÎçÆçÎçÎÞÎçÆÞ½çÎçÎçΌJ1ï¥Zç¥Rç¥Rç¥Rç¥Rç¥Zï¥Rç¥Zç¥Rç¥Jç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΌsçÎçÆçÎçÆçÆÞ½çÎçÎçÆçÆçÎç΄cBç¥Rï¥Jç¥Rç¥Zç¥Rï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥Zç¥Rç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZRçÎÞ½çÆçÆÞ½çÎÞ½ÞÎçÆçÎçÎçÎç¥Rï¥Rç¥Jï¥Rï¥Zç¥Rç¥Rç¥Rç¥Zï¥Rï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥RZJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎÞ½çÆÞ½çÎçÎçÎçÆçÎçÎçÎ֔Zï¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥Rç¥Rï¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥Rï¥ZJ1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïÎçÎÞ½çÆçÆÞÎÞ½ÞÎÞ½ïÎçÎçνsBï¥Rç¥Rï¥Rç¥Zk9¥{1ç¥Zï¥Rç¥Rç¥Rç¥Rï¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÆçÆçÆçÎçÎçÆÞÎçÆçÎçεk9ç¥Zç¥Rï¥Rï¥Rç¥R­ŒJsZ)֔Jï¥Rï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Z¥{BÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÆÞ½çÆÞÎÞ½çÎçÆçÆçÎçνsBç¥Rç¥Rç¥Rç¥Rï¥Rï¥Z­ŒJ!!½„1ÿ­Rï¥Zç¥Zç¥Rç¥Zç¥Rç¥Rç¥Rç¥RkRB9ckÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΌsçÎÞ½çÆçÆçÆçÎçÆçÆïÎçÎçΜcBç¥Zç¥Rç¥Rç¥Rç¥Rï¥Rÿ­R”{B1)Œc)ç¥Rç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥ZkJ!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÆçÆÞ½Þ½çÎçÆçÎçÎçÎcç¥Zï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rï¥Rï¥ZBkZ)ƄZç¥Jç¥Rç¥Zç¥Rç¥Rç¥Rç¥RRBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÎçÆçÆçÎçÎçÎçÎçÎçÎkç¥Zï¥Rç¥Rç¥Jç¥Rç¥Rç¥Jï¥Rç¥Rç¥Z”{B1!RB!ç¥Rç¥Zç¥Rç¥Zç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎŒsçÎçÎçÆçÎçÎçÎ1¥µŒ!ïÎ{1)ï¥Jç¥Rç¥Rç¥Rï¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥R„cBŒc!֔Jç¥Rç¥Rï¥RccJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)kBçÎçÎçÆçÎçÎïÎZJ„JJÿ1)BƄZï¥Rç¥Rç¥Rç¥Rç¥Rç¥Jç¥Rç¥Rç¥Rç¥Jç¥Rç¥R”{B1)œs)ï¥RŒ„s19RJJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9ïÎçÎçÆçÎçÎ)BJ9RJBkRJJ1„cBï¥Jï¥Jç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥R­ŒJ¥kÿœ9ç¥Rç¥Rç¥Z”„R¥{BBB!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZZkçÎçÎçÎçÎçÎ9)kRBç¥Rç¥Rç¥Rï¥Rç¥Rç¥Rç¥Rç¥Zç¥Zç¥Rï¥Zï¥R­ŒJcœÿÿœ9ç¥Rç¥Rï¥Zç¥ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÎçÎçÎB)kRBç¥Rç¥Rç¥Rç¥Rç¥Rç¥Jç¥Rç¥Zç¥Zç¥Rç¥Rç¥Rï¥Zï¥Z”k9œœ„ÿÿÿµÖÿΌBç¥Rç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ÷½çÎïÎçÎcï¥Zç¥Rç¥Zï¥Rç¥Jç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zï¥Rï¥R½„1ZskBkŒkcZççÖÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÎ1))ç¥Rï¥Rç¥Rç¥Rç¥Jç¥Rç¥Rç¥Zç¥Zç¥Rç¥Rç¥Rç¥Rï¥R֔J)!ZskœµÖÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎçÎï¥Z1J)ç¥Rï¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zï¥Zç¥Zï¥Zç¥Rç¥Rï¥Rï¥Z­ŒJ„cBµ”cŒ„s)111ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçÎçÎ1ç¥Zç¥Rç¥Zç¥Rç¥Zç¥Jç¥Rç¥Rç¥Rç¥Jï¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rï¥Zç¥Rç¥ZRJJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBkŒkBçÎç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rï¥Rï¥Rç¥Rç¥Rç¥Rï¥Zç¥Zç¥Zç¥Zç¥Zç¥Zç¥Rï¥Rç¥Rç¥Rç¥ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBZRç¥Zç¥Rç¥Jç¥Rç¥Rï¥Rç¥Rç¥R֔Jç¥Rç¥Jç¥Rç¥Rç¥Zç¥Zç¥Zç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zç¥R!!1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Rç¥Rç¥Rç¥Rç¥Jï¥Zks9!!RZ1¥{Bç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥J„c!J!9sZ)ç¥Zç¥ZŒsZ)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZskç¥Rç¥Zç¥Rç¥Rç¥Jï¥Zç¥ZsZ)”„RcJ)ç¥Zç¥Rç¥Rç¥Rç¥Zç¥Rç¥ZŒc!ccJBB!ç¥Rç¥Z„cBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Zç¥Rç¥Jç¥Rç¥Rï¥Zç¥R­ŒJç¥Rks9ÿœ9ç¥Rç¥Rç¥Rç¥Zç¥R֔JB!ï¥Z1111!֔Jç¥Rç¥Z1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Z)„R)ï¥Zï¥Jÿœ9ÿ­Rÿ­Rï¥R{c1cJ){c1µ”cŒsZ{c1΄9ç¥ZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Zç¥Jç¥Rç¥Rç¥Rç¥Zç¥Rç¥RkRBJZZÞï÷sZ)”{B”s1΄!ÿ­Rÿœ9ï¥Rµ„BƜcµ”c19!!1µŒ!µ„BÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Rç¥Rç¥Jç¥Rç¥Rç¥Rç¥Rï¥Z֔JJZBZsksµÿ19ÿÿÿœœ„œs½„1ÿµRÿµRÿµR)ÆÆÎÆÆÎ1!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Zç¥Jç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rï¥Z­ŒZ)BB1ÿÿÿ„ÿÿ1ÿÿÿ­ŒZç¥Zç¥Z99ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1ç¥Rç¥Rç¥Rç¥R֔Jç¥Zç¥Rç¥Zç¥Zç¥Rç¥Rç¥Z”„R)))!!!Œ½ÆJZB”„R„sJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1ç¥Zç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥Rç¥Rç¥Rç¥Rç¥Z֔Z1BB!1)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ!!ç¥Rç¥Zç¥Rç¥Jç¥Jç¥Zç¥Zç¥Zç¥Rç¥Rç¥Zç¥Rç¥Rç¥Rç¥Rç¥Z­ŒJkRB1)11!!!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9ç¥Zç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Zç¥Zç¥Zç¥Zç¥Zç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥R„{RBJRÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Zç¥Rç¥Rç¥Zç¥Zç¥Zç¥Zç¥Zç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Zç¥Rç¥R­ŒZ111JZZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1)Z9ç¥Zç¥Rç¥Rç¥Z֔Zç¥Rç¥Rç¥Zç¥Rç¥Zç¥Rç¥Zç¥Zç¥Rç¥Rï¥Jï¥Rç¥Rç¥Rç¥Zç¥Rç¥Rç¥Z„kZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Zç¥Rç¥Zç¥Jç¥Rç¥Zç¥Rç¥Rç¥R„c!BB!ÆÆÎ){Jç¥Rç¥Zç¥Rç­Zï¥Zç¥Rç¥Rç¥R¥s!ccZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Rç¥Rç¥Jç¥Rç¥Rç¥Rç¥ZsZ)))ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBRZcJ)µ„Bç¥Rç¥Rç¥Zï¥Zç¥RskBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Rç¥Rç¥Zï¥Rç¥Rç¥Rç¥Rœs)ZskÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΔk9ï¥Rç¥Zµ”c1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBç¥Rç¥Rç¥Rç¥Rç¥Zç¥RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ΄9÷Œ)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎç¥Zç¥Rç¥RkBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎBJRÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ
/unsupported/branches/unsupported/simcity/img/bb1.raw
0,0 → 1,0
ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZcc!)!911))111ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ111J))91)Z))J)9))ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJJJ)19!9!)Z)c19)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)JJ)c1)))!91)!!)91ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9)J)1c1B1Z!J191)91))J))!!ZZZkcZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)9!)c1J)J)c1B1)!!91)!)9)))9)J11)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9JB))J)Z)9)9))!J!9))))91)9)kcZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJJ)1)1)J1Z)))J1)B1))91)!)91!!9)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)1))1))9))!!J911))))1)J)!!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJ)))1)J)1)!!J))B191)1)!!9!)!cZBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1JJ)k1B1)!9!9)JJ!))9))9!9)!!)!)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJ9)9)Z)))J!9)1B1))1)9!)J!)!!!RB9ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1)J!J)1)Z)Z)))9!J11J)9!J!)9!Z)Z))Z)Z)B1)1)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9!Z)))!9!)))))!J)919)J!!)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)B11)J19!J)B1Z)c1)91)91)J9J))!!9))1)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)!)19)J1J)J)!)J19)J9911)91)911)9)J)9!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ))9!9)9))!J)c1))9)91911))J!)9)Jk1Z)9!!!!)!ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)!)))!J!9)9))ZB1))J1))91!!))))ç­Bï­B)))sB9)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)!)))9!)B1J!k1)J9J))))B19!)9!ç­Bç­Bç­Bç­Bç­Bç­Bç­BÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)))sBc1sB1)­k!­c)1J1)B1))ç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­B1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)!)1)9!c1))ïœç­Bç­B)))J9)ç­Bç­Bç­Bç­J÷­Jç­Bç­Bç­Jç­B„RkcZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ))çœ!ïœçœ!ç­Bç­Bç­Bÿ¥9))))))ç­Bç­Bç­Jç­Bï­Bç­JçµZç­Bç­Bç­Jç­B1B91ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎB1k1ïœçœ!çœ!ç­Bç­Bï­Bç­Bç­Bç­B)))J9)ç­Bç­Bç­Bç¥9ç­Bç­Bç­Rïµkç­Bç­Bç­Bç­J))ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎk1„Bçœ!ïœçœ!ç­Bç¥9ç¥9ç­Jç­Bç­Bç¥9ޔ!”c!„Rç­Jç­Bç­Bç­Bç¥9ç­Bç­Bç­Rç­Rïµsïµsç­Bç­B)!)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ))΄çœ!çœ!ç­Bç¥9ç­Bç­Bç­Bç­Bç­Bç­Bï­Bç¥9Þ­Jï­Bï­Bç­Bç­Bç­Bç­Bç­Bç­Jç­Jç­Rïµkïµkïµsç­BZBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!ï¥)ç¥9ç­Bç¥9ç­Bç­Jç­Bç­Bç¥9ç­Jç­Bï­Bç¥9ç­Bç­Jç­Bç­Bç­Jç­Bç­Bç­RçµZçµZçµsïµkïµkç­BÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!ïœï¥)ç¥9ç­Bç­Bç­Bç­Bç­Jç­Bç­Bç­Bç­Bç­Bç­Bç­Jç­Jç­Bç­Bç­Jç­Jç­Bç­JçµZÞ­cïµkïµkïµsïµkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!çœ1çœ1ç¥9ç­Jç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Jç­Jç­Bç­Bç­Bç­Jç­JçµZÞ­cïµsïµkïµkïµsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœçœ!çœ1ç¥9ç­Bç­Bç­Bç­Bç­Jç­Bç­Bç­Bç­Jç¥9ç¥9ç­Jç­Bç­Jç­Jç­Bç­Bç­Jç­Rç­RïµkçµZçµsïµkïµkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!ï¥)ç¥)çœ1ç­Bç­Bç­Bç­Jç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Bç­Jç­Jç­Jç­Jç­Rç­Jç­RçµZïµkïµsïµkïµsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!÷œ!çœ1ç¥9ç­Bç­Bç­Bç­Bç¥9ç­Jç­Jç­Jç­Bï­Bç­Bç­Bç­Bç­Jç­Bç­Jç­Rç­JçµZçµZçµZÞ­cïµkïµkïµk!)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!ïœçœ1çœ1ç¥9ç¥9ç­Bç­Bç­J½œJ­Œ1ç­Bç­Jï­Bç­Bç­Bç­Bç­Bç­Jç­JÞ­J­”Rœ„B­ŒRÞ­cïµkïµkçµsïµk1)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!ïœç¥)çœ1ç­Bç­Bç­Bï­Bç­Js1Ö¥Bç­Bç­Bç­Jç­Rç­Jç­B½œJΜRï½kçµZïµkïµs)1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!ç¥)ç¥9ç­Bç­Jç­Bç­JÿÖRÿÿcç¥9ç­Bç­Jïµkç­RÞ­J„„B1kBJkB”kBÿÆcçµZÞ­kçµZïµsïµkB91ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!çœ!çœ1ç¥9ç­Bç­Bç¥9ÿ½JJ{B!ZB)c1ç¥9ç­Bç­RçµZç­RçµZ¥”B19!)çµZçµZïµkçµZÞ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœçœ!ç¥)ç¥9ç­Bç­Bç­Bÿ½J„BB1÷­Jç­Bç­RεkB1çµZµ”Bµ{JçµZçµZçµZÞ­kçµZçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!ç¥)ç¥9ç­Bç­Bç­Bç­Bÿ½J½œJsB)ï­Bç­Jç­J­­kçµZçµZçµZçµZÞ­kçµZïµkï½kçµZçµZïµsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1ksçœ!ïœç¥)ç¥9ç­Bç­Bç­Jç­Jï­Bÿ½Jÿ½Jÿ½Jç­Bç­Bï­Bµ­{9çµZçµZç­RçµZçµZçµZÞ­cÞ­kÞ­cçµZïµkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!çœ!çœ1ç¥9ç¥9ç­Bç­Jç­Jç­Bï­Bï­Bç­Bç­Bç­J½­sJJçµZçµZç­Rç­RçµZçµZï½kçµsçµZçµZçµsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZ)çœ!çœ!ïœç¥)ç¥9ç­Jç­Jç­Bç­Bç­J÷­Jç­Jç­Jç­Bç­BÞ­ccZc!9çµZç­RçµZçµZÞ­cïµkçµsÞ­cçµZïµsÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!ïœç¥)ç¥9ç­Bç­Jç­Bÿ½JÖ¥B))çµZç­Jç­Bç­Bç­R½­s„„B1)­ŒRçµZçµZÞ­kçµZçµZçµZïµkÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!ޔޔ!Þ¥1ç¥9ç­B÷­JΜRœs1çµZçµZçµZçµZçµZçµZçµZçµZ{ŒJçµZÞ­cï½kçµZçµZçµZJkBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJRsçœ!ÿ”çœ!ïœçœ1ç¥9ç¥9ÿ½J„Bç­RçµZçµZÞ­cçµZçµZs„cçµZçµZÞ­kÞ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJJïœçœ!ïœç¥)Þ¥1ç¥9ÿ½J„BçµZçµZçµZœœk!ZBçµZçµZçµsçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎR{{çœ!ïœޔ!çœ1ç¥9ç­J½œJµ”BŒc1÷­c)1Þ­kçµZçµZJJ”B)çµZçµZçµZçµZçµZïµkçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœçœ!ç¥)Þ¥1ç­Bï­Bÿ½Jÿ½JÿÖR{9R!çµZµÞ­÷­JçµZçµZïµkÞ­cçµsçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!ïœç¥)ç¥9ç¥9ç­Bç­BÞ¥B÷­J¥”BÿÞ¥„ZïµkçµZçµZçµZçµZï½kÞ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1„Bçœ!ïœޔ!ç¥9Þ¥Bç­BÞ¥Bç­Bï­BÞ­Jc)9B)1÷­JçµZçµZÞ­cïµkïµkçµsçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœï¥)çœ1ç¥9ç­Bç­Jç­Bç­BçµZçµZçµZçµZçµZçµZçµZçµZÞ­cÞ­cçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!çœ!çœ!ç¥9ç¥9ç¥9ç¥9ç¥9çµZçµZçµZçµZçµZçµZçµZçµZï½kçµZçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!c„kç¥9ç¥9ç¥9ç¥9ç¥9¥{B1B!ksZcJ1çµZçµZçµZÞ­cçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ)ccïœçœ!½{!ç¥9ç¥9ç¥9¥”Bç¥9k{„s)Œc1çµZçµZï½kÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ1çœ!„Rÿ”ç¥9Ö¥B­”RkZBB1cBc9Jÿÿÿ9BR„cB9RZ{JJ„sBçµZÞ­cÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ9sBBJÿ”Ɣ11Zœ99)1{!)11J„9çµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ!!9{R½sÿ”ÿ¥9µ”B­”RŒs9cJ1­”RçµZçµZΜRÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎk1çœ!ÿ”ÿ”ÿ¥9ÿ¥9ÿ¥9„„B)J1ZZ)BR)1))J1ZZ)ïµkçµZçµZï½k„sBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ÿ”ÿ”çœ1ï­Bÿ¥9ÿ½J¥”BŒs9sc)kk9„sB½œJçµZçµZÞ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ!)ZœJÿ”ÿ”ï¥)ÿ¥9ï­B÷­J÷­J÷­Jÿ¥9÷­JçµZÿ½kÿ½kçµZçµZÞ­cÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ÿ”çœ!ç¥9ï­B÷­JçµZ÷­J÷­c÷­Jÿ½k÷Æ{÷Æ{ïµsÞ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœïœç¥9c)Œs9ïµsÞ­cÞ­cïµkïք­­k”„ZïµsçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ!)Zsÿ”çœ!ï¥)ZŒ9µ{Jç½{Þ­cçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!ç­Bç¥9ç¥9ç¥9çµZçµZçµZïµkçµZçµZçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!çœ!ïœç¥9ç­Jç­Jç­RçµZçµZÞ­kÞµsçµZçµZÞ­c1cBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJRskïœçœ!Þ¥1ç¥9Þ¥BÞ¥Bç­RÞ­cÞ­cïµkÞµsÞµsÞ­c­”RÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!Þ¥1Þ¥1Þ¥BÞ­Jç­RçµZÞ­cÞ­kçµsÞµsçµZ­ŒR)J1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆΜJÿ”Þ”!ޔ!ç¥9ç­Rç­RçµZÞ­kÞ­kçµsÞµsçµZ”„Z111ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎJJJJÿ”Þ”Þ¥1Þ¥BÞ­Jç­RΜRïµkÞ­kÞµsç½{çµZŒc1ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!ޔ!ç¥9Ö¥BÞ­cÞ­cçµZïµkçµsç½{çµZ”kBÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!ïœޔ!çœ!Þ­Jç­RÞ­cÞ­cïµkïµsïµsçµZŒkJÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎçœ!çœ!ïœçœ!ïœÞ­cçµZÞ­cçµZÞ­cçµZçµZœ„B9ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎïœçœ!çœ!çœ!çœ!çµZçµZçµZçµZçµZçµZçµZçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZ„cJ1çµZçµZÞ­kçµZÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎZcc9B)9)ÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎÆÆÎ
/unsupported/branches/unsupported/simcity/img/car_210n.raw
0,0 → 1,0
€ÿ€ÿ€€€ÿÿ€€€ÿÿ€€€€€€€€€ÿ€€€€€€€ÿÿ€ÿ€€€ÿÿ€€€€€€ÿ€€€ÿÿÿÿ€€€ÿÿ€€€€€€ÿÿ€€€ÿ€€€€€€€€€ÿÿÿÿÿÿ€€€€€€€€€ÿÿ€€€ÿÿÿÿ€€€ÿ€€€ÿ€€€ÿÿ€€€ÿÿ€€€€€€ÿÿÿ€€€ÿÿ€€€ÿÿ€€€ÿ€€€€€€€ÿÿÿÿÿÿ€€€€€€€€€ÿÿÿÿ€€€ÿÿ€€€€€€ÿÿ€€€ÿ€€€€€€ÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿ€€€ÿÿ€€€ÿÿ€€€ÿ€€€€€€€€€ÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€€€€€ÿÿÿÿ€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿ€€€€ÿÿÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€ÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿ€€€€€€€€€ÿÿÿÿÿÿ€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿ€€€€€€ÿÿ€€€ÿÿ€€€ÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿ€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿ€€€€ÿÿÿÿ€€€ÿÿ€€€€€€€€€ÿÿÿÿÿ€€€ÿÿÿ€
/unsupported/branches/unsupported/simcity/img/car_120n.raw
0,0 → 1,0
€ÿÿÿÿÿ€ÀÀÀÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€ÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€ÿÿÿÿÿ€€€€€€€€€ÿÿÿÿ€€€€€€ÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿ€€€€€€€€€ÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿ€€€ÿÿÿÿÿÿ€€€€€€€€€€€€€€€ÿÿÿÿ€€€ÿÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿÿÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿÿ€€€ÿÿÿÿ€€€€€€€€€€€€€€€ÿÿÿÿÿÿ€€€€€€ÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿÿÿÿ€€€ÿ€ÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿ€€€ÿÿÿ€ÿÿÿÿÿ€€€€ÿÿ€€€€€€ÿÿ€€€€€€€€€ÿ€€€ÿÿ€€€€€€€€€€€€ÿÿÿÿ€€€€€€ÿÿ€€€€€€€€€€€€ÿ€€€ÿÿ€€€€€€ÿÿÿÿ€€€€€€ÿÿ€€€€ÿ€€€€€€€€€ÿÿÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿ€€€€ÿ€€€€€€€€€ÿÿ€€€€€€€ÿÿ€€€€ÿ€€€€
/unsupported/branches/unsupported/simcity/img/car_030n.raw
0,0 → 1,0
€ÿÿÿ€€€ÿÿÿÿÿ€€€€€€€€€ÿÿ€€€ÿÿÿÿ€€€€ÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€€€€ÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ€€€ÿÿ€€€ÿÿ€€€€€€ÿ€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀ€€€€ÿÿÿÿÿÿ€€€€€€€€€ÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€ÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿ€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿÿ€€€ÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿ€€€€€€€€€€€€€€ÿÿÿÿ€€€€€€€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿ€€€€€€€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿ€€€€€€ÿ€€€ÿÿ€€€€€€ÿÿ€€€ÿÿÿÿ€€€€€€€€€ÿÿÿÿÿÿ€€€€€€€ÿ€€€ÿÿ€€€ÿÿ€€€ÿÿÿ€€€€€€ÿÿ€€€ÿÿ€€€ÿ€€€ÿ€€€ÿÿÿÿ€€€ÿÿ€€€€€€€€€ÿÿÿÿÿÿ€€€€€€€€€ÿ€€€ÿÿ€€€€€€ÿÿ€€€ÿÿÿÿ€€€ÿ€€€€€€ÿÿ€€€ÿ€ÿÿ€€€€€€€ÿ€€€€€€€€€ÿÿ€€€ÿÿ€€€ÿ€ÿ€
/unsupported/branches/unsupported/simcity/img/car_300n.raw
0,0 → 1,0
€€€€ÿ€€€€ÿÿ€€€€€€€ÿÿ€€€€€€€€€ÿ€€€€ÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿÿÿ€€€€€€€€€ÿ€€€€ÿÿ€€€€€€ÿÿÿÿ€€€€€€ÿÿ€€€ÿ€€€€€€€€€€€€ÿÿ€€€€€€ÿÿÿÿ€€€€€€€€€€€€ÿÿ€€€ÿ€€€€€€€€€ÿÿ€€€€€€ÿÿ€€€€ÿÿÿÿÿ€ÿÿÿ€€€ÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿ€ÿ€€€ÿÿÿÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿ€€€€€€ÿÿÿÿÿÿ€€€€€€€€€€€€€€€ÿÿÿÿ€€€ÿÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿ€€€€€€ÿÿÿÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿÿ€€€ÿÿÿÿ€€€€€€€€€€€€€€€ÿÿÿÿÿÿ€€€ÿÿÿÿÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿ€€€€€€€€€ÿÿ€€€€€€ÿÿÿÿ€€€ÿÿÿ€€€€€€ÿÿÿÿ€€€€€€€€€ÿÿÿÿÿ€€€€€€€€€€€€ÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿ€€€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿ€€€ÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÀÀÀ€ÿÿÿÿÿ€
/unsupported/branches/unsupported/simcity/img/street.raw
0,0 → 1,0
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„÷ó÷÷ó÷„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„„‚„