home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d polygonal solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Mar. 1990 *
- ******************************************************************************
- * General routines to handle the graphic calls. *
- * currently supported devices: *
- * Input: Keyboard, mouse. *
- * Output: Hercules, EGA/VGA. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <conio.h>
- #include <string.h>
- #include <dir.h>
- #include <dos.h>
- #include <math.h>
- #include <ctype.h>
- #include <graphics.h>
- #include <stdarg.h>
- #include <io.h>
- #include <fcntl.h>
- #include "program.h"
- #include "graphgng.h"
- #include "allocatg.h"
- #include "graphgnl.h"
- #include "mousedrv.h"
-
- #define SINGLEPAGE
-
- extern int MouseExists; /* Responsibility of program! */
- extern int GraphDriver; /* "" */
-
- int GraphMode; /* The Graphics mode value. */
- double AspectRatio; /* Aspect ratio of a pixel on the screen. */
- int ScreenMaxX, ScreenMaxY; /* The maximum resolution of the screen. */
- int ScreenMaxY2; /* ScreenMaxY / 2. */
- int ScreenMaxColors; /* The maximum # of colors available. */
- int ScreenMaxPages; /* The maximum # of pages available. */
- int ScreenErrorCode; /* Reports any graphics errors. */
- int CurrentCursorX, CurrentCursorY; /* Cursor current position. */
- int ScreenGraphicMode = FALSE; /* TRUE if the screen in graphic mode. */
-
- static double WndwAspectRatio, GlblAspectRatio;
- static struct palettetype palette; /* Used to read palette info. */
- static char *CursorImageBuffer; /* Cursor shape. */
- static int LocalMoveToX, LocalMoveToY; /* Save last position we move. */
- static char LastGetChar; /* Last char recieved in UpdateGetPoint. */
- static double MouseXRatio, MouseYRatio;
- static int DefaultFontSize; /* Depend on graphic driver. */
- static int ScreenCursorColor; /* Graphic and text (in graphic screen). */
- static int ViewPortX, ViewPortY; /* Viewport offset from top left (0, 0). */
- static int OldStdOut; /* To recover stdout when we done with graph mode. */
- static int CrntWindowName; /* Unique index for current window. */
-
- /* #define NOGRAPHICS /* If no graphics to perform (only routine calls). */
- /* #define DEBUG /* Print graphics driver info and dies... */
-
- /****************************************************************************
- * Routine to move to a normalized point between -1..1 on both axes : *
- ****************************************************************************/
- void GGMyMove(double x, double y)
- {
- #ifndef NOGRAPHICS
- /* Note I use ScreenMaxY2 as X>ScreenMaxY2 left for text (menus). */
- LocalMoveToX = (int) ((x * WndwAspectRatio * ScreenMaxY2 + ScreenMaxY2) *
- GlblAspectRatio);
- LocalMoveToY = (int) (-y * ScreenMaxY2 + ScreenMaxY2);
- moveto(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY);
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to draw to a normalized point between -1..1 on both axes : *
- ****************************************************************************/
- void GGMyDraw(double x, double y)
- {
- #ifndef NOGRAPHICS
- int NewX, NewY;
-
- /* Note I use ScreenMaxY2 as X>ScreenMaxY2 left for text (menus). */
- NewX = (int) ((x * WndwAspectRatio * ScreenMaxY2 + ScreenMaxY2) *
- GlblAspectRatio);
- NewY = (int) (-y * ScreenMaxY2 + ScreenMaxY2);
- line(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY,
- NewX - ViewPortX, NewY - ViewPortY);
- LocalMoveToX = NewX;
- LocalMoveToY = NewY;
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to draw to a normelized point between -1..1 on both axes : *
- ****************************************************************************/
- void GGMySetColor(int color)
- {
- #ifndef NOGRAPHICS
- if (color >= ScreenMaxColors) color = color % (ScreenMaxColors-1) + 1;
- setcolor(color);
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to reset all the system to starting condition : *
- ****************************************************************************/
- void GGInitGraph(void)
- {
- #ifndef NOGRAPHICS
- int xasp, yasp, /* Used to read the aspect ratio. */
- i, j;
-
- if (registerbgidriver(Herc_driver) < 0) MyExit(1);
- if (registerbgidriver(EGAVGA_driver) < 0) MyExit(1);
-
- /* For some wierd reason, some machines waits much more than expected on */
- /* the first delay. Lets do it now, so people will consider it part of */
- /* the initialization (make it a feature...)... */
- delay(1);
-
- if (GraphDriver == 0) {
- /* Use autodetect feature of graphic library to see what we have. */
- detectgraph(&GraphDriver, &GraphMode);
- if (GraphDriver < 0) {
- fprintf(stderr, "Auto detect: No graphics device detected\n");
- MyExit(1);
- }
- }
-
- /* Put in the following any graphic driver specific setup: */
- switch (GraphDriver) {
- case EGA:
- GraphMode = EGAHI;
- break;
- case EGA64:
- GraphMode = EGA64HI;
- break;
- case EGAMONO:
- GraphMode = EGAMONOHI;
- break;
- case HERCMONO:
- GraphMode = HERCMONOHI;
- break;
- case VGA:
- GraphMode = VGAHI;
- break;
- default:
- fprintf(stderr, "Requested graphic device (%d - see .cfg file) is not supported\n",
- GraphDriver);
- MyExit(1);
- break;
- }
-
- initgraph(&GraphDriver, &GraphMode, "");
- ScreenErrorCode = graphresult(); /* Read result of initialization. */
- if (ScreenErrorCode != grOk) { /* Error occured during init. */
- fprintf(stderr, " Graphics System Error: %s\n",
- grapherrormsg(ScreenErrorCode));
- MyExit(1);
- }
-
- getpalette(&palette); /* Read the palette from board. */
- ScreenMaxColors = getmaxcolor() + 1; /* Read maximum number of colors. */
- ScreenCursorColor = (ScreenMaxColors > 1 ? ScreenMaxColors - 1 :
- ScreenMaxColors);
-
- ScreenMaxX = getmaxx(); /* Read size of screen. */
- ScreenMaxY = getmaxy();
- ScreenMaxY2 = ScreenMaxY / 2;
- CurrentCursorX = ScreenMaxX / 2;
- CurrentCursorY = ScreenMaxY2;
- getaspectratio(&xasp, &yasp); /* Read the hardware aspect. */
- /* Get correction factor: */
- AspectRatio = (double) xasp / (double) yasp;
- GlblAspectRatio = 1.0 / AspectRatio;
- WndwAspectRatio = 1.0;
-
- /* Put in the following any graphic driver specific setup: */
- switch (GraphDriver) {
- case HERCMONO:
- DefaultFontSize = 1; /* Fixed width font. */
- ScreenMaxPages = 2;
- break;
-
- case EGA:
- DefaultFontSize = 1; /* Fixed width font. */
- ScreenMaxPages = 2;
-
- GlblAspectRatio = 1.2; /* I dont like it either, but its simple. */
- break;
-
- case EGA64:
- DefaultFontSize = 1; /* Fixed width font. */
- ScreenMaxPages = 1;
-
- GlblAspectRatio = 1.2; /* I dont like it either, but its simple. */
- break;
-
- case EGAMONO:
- DefaultFontSize = 1; /* Fixed width font. */
- ScreenMaxPages = 2;
- ScreenMaxColors = 2;
-
- GlblAspectRatio = 1.2; /* I dont like it either, but its simple. */
- break;
-
- case VGA:
- DefaultFontSize = 1; /* Fixed width font. */
- ScreenMaxPages = 2;
-
- GlblAspectRatio = 0.88;/* I dont like it either, but its simple. */
- break;
- }
-
- # ifdef SINGLEPAGE
- ScreenMaxPages = 1;
- # endif /* SINGLEPAGE */
-
- # ifdef DEBUG
- GGCloseGraph();
- fprintf(stderr, "ScreenMaxX = %d, ScreenMaxY = %d, MaxColors = %d\n",
- ScreenMaxX, ScreenMaxY, ScreenMaxColors);
- fprintf(stderr, "AspectRatio = %lf, ViewPortX = %d, ViewPortY = %d\n",
- AspectRatio, ViewPortX, ViewPortY);
- MyExit(1);
- # endif /* DEBUG */
-
- /* Prepare the cursor (Arrow) image : */
- cleardevice();
- GGMySetColor(ScreenCursorColor);
- setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
- line(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
- j = CURSOR_IMAGE_X / 3;
- for (i=1; i<=7; i++) line(0, 0, j, j + i); /* Draw the arrow head. */
- j = CURSOR_IMAGE_Y / 3;
- for (i=1; i<=7; i++) line(0, 0, j + i, j);
-
- CursorImageBuffer = MyMalloc(imagesize(0, 0, CURSOR_IMAGE_X,
- CURSOR_IMAGE_Y), OTHER_TYPE);
- getimage(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y, CursorImageBuffer);
-
- settextstyle(DEFAULT_FONT, HORIZ_DIR, DefaultFontSize);
-
- if (MouseExists) {
- switch (GraphDriver) {
- case EGA:
- case EGA64:
- case EGAMONO:
- case VGA:
- MSMouseXmax = 1000; /* Set Column Range. */
- MSMouseYmax = 1000; /* Set Row range. */
- break;
- case HERCMONO:
- /* Compensate on the text mode the mouse knows about as */
- /* hercules is not supported by the mouse driver! */
- MSMouseXmax = 8000; /* Set Column Range. */
- MSMouseYmax = 8000; /* Set Row range. */
- break;
- }
- MouseXRatio = ((double) ScreenMaxX) / MSMouseXmax;
- MouseYRatio = ((double) ScreenMaxY) / MSMouseYmax;
- }
-
- ScreenGraphicMode = TRUE;
- i = open("nul", O_WRONLY); /* Redirect the stdout to nul: (no ^C...). */
- fflush(stdout);
- OldStdOut = dup(1);
- dup2(i, 1);
- close(i);
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to close and shutdown graphic mode : *
- ****************************************************************************/
- void GGCloseGraph(void)
- {
- #ifndef NOGRAPHICS
- closegraph(); /* Return the system to text mode. */
- ScreenGraphicMode = FALSE;
- dup2(OldStdOut, 1); /* Recover stdout to its regular status. */
- close(OldStdOut);
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to update x, y coordinates according to current x, y and key *
- * pressed. Returns TRUE only if <Enter> or alpha char is pressed. *
- ****************************************************************************/
- static int GGUpdateGetPointKbd(int *x, int *y)
- {
- int BrkPressed = FALSE;
-
- switch (LastGetChar = getch()) {
- case 0:
- switch(getch()) { /* extended character: */
- case 16:
- MyExit(0); /* Alt - Q, async. exit... */
- case 71:
- *x -= 1; /* Arrowes - move 1 at a time. */
- *y -= 1;
- break;
- case 72:
- *y -= 1;
- break;
- case 73:
- *x += 1;
- *y -= 1;
- break;
- case 75:
- *x -= 1;
- break;
- case 77:
- *x += 1;
- break;
- case 79:
- *x -= 1;
- *y += 1;
- break;
- case 80:
- *y += 1;
- break;
- case 81:
- *x += 1;
- *y += 1;
- break;
- }
- break;
- case 10 :
- case 13 :
- BrkPressed = TRUE;
- break;
- case '1':
- *x -= 10; /* Shifted arrows - move 10 at a time. */
- *y += 10;
- break;
- case '2':
- *y += 10;
- break;
- case '3':
- *x += 10;
- *y += 10;
- break;
- case '4':
- *x -= 10;
- break;
- case '6':
- *x += 10;
- break;
- case '7':
- *x -= 10;
- *y -= 10;
- break;
- case '8':
- *y -= 10;
- break;
- case '9':
- *x += 10;
- *y -= 10;
- break;
- /* If the key pressed is an alpha - exit. */
- default:
- if isalpha(LastGetChar) BrkPressed = TRUE;
- break;
- }
-
- return BrkPressed;
- }
-
- /****************************************************************************
- * Routine to get one x, y selected point in normelized form (-1..1) : *
- ****************************************************************************/
- void GGGetPoint(double *x, double *y)
- {
- #ifndef NOGRAPHICS
- int Xtemp, Ytemp, Buttons, Xscreen, Yscreen, Quit, GetInput;
- struct viewporttype view;
-
- getviewsettings(&view);
- setviewport(0, 0, getmaxx(), getmaxy(), FALSE);
-
- LastGetChar = 0x001; /* Make in impossible if mouse input... */
-
- Xtemp = CurrentCursorX;
- Ytemp = CurrentCursorY;
- putimage(CurrentCursorX, /* Draw the cursor - starting position. */
- CurrentCursorY, CursorImageBuffer, XOR_PUT);
-
- if (MouseExists) /* Update mouse on current position. */
- MouseSetPosition((int) (CurrentCursorX / MouseXRatio),
- (int) (CurrentCursorY / MouseYRatio));
-
- Quit = FALSE;
- do {
- GetInput = FALSE;
- do {
- /* Wait for input from one of the devices: Mouse/Keyboard. */
- if (MouseExists && MouseQueryBuffer()) {
- MouseGetBuffer(&Xscreen, &Yscreen, &Buttons);
- GetInput = TRUE;
- CurrentCursorX = (int) (Xscreen * MouseXRatio);
- CurrentCursorY = (int) (Yscreen * MouseYRatio);
- Quit = Buttons & 0x01;
- }
- if (kbhit()) {
- Quit = GGUpdateGetPointKbd(&CurrentCursorX, &CurrentCursorY);
- if (MouseExists) /* Update mouse on the new position. */
- MouseSetPosition((int) (CurrentCursorX / MouseXRatio),
- (int) (CurrentCursorY / MouseYRatio));
- GetInput = TRUE;
- }
-
- }
- while (!GetInput);
- if (CurrentCursorX < 0) CurrentCursorX = 0;
- if (CurrentCursorY < 0) CurrentCursorY = 0;
- if (CurrentCursorX > ScreenMaxX - CURSOR_IMAGE_X)
- CurrentCursorX = ScreenMaxX - CURSOR_IMAGE_X;
- if (CurrentCursorY > ScreenMaxY - CURSOR_IMAGE_Y / 2)
- CurrentCursorY = ScreenMaxY - CURSOR_IMAGE_Y / 2;
-
- putimage(Xtemp, Ytemp, CursorImageBuffer, XOR_PUT);/* Erase old crsr!*/
- putimage(CurrentCursorX, CurrentCursorY, CursorImageBuffer,
- XOR_PUT); /* Draw new crsr! */
- Xtemp = CurrentCursorX; /* Save them so we could erase it later. */
- Ytemp = CurrentCursorY;
- }
- while (!Quit);
-
- putimage(Xtemp, /* Erase last old cursor before quiting. */
- Ytemp, CursorImageBuffer, XOR_PUT);
-
- /* See GGMyMove for ScreenMaxY2. */
- *x = ((double)(CurrentCursorX) / GlblAspectRatio - ScreenMaxY2) /
- ScreenMaxY2;
- *y = ((double)(CurrentCursorY) - ScreenMaxY2) / (-ScreenMaxY2);
-
- setviewport(view.left, view.top, view.right, view.bottom, view.clip);
-
- #endif /* NOGRAPHICS */
- }
-
- /****************************************************************************
- * Routine to draw a point on screen as marker + with a title : *
- ****************************************************************************/
- void GGDrawPoint(double p[], char title[], int PointColor)
- {
- #ifndef NOGRAPHICS
- GGMySetColor(PointColor);
- GGMyMove(p[1] + POINT_SIZE, p[2]);
- GGMyDraw(p[1] - POINT_SIZE, p[2]);
- GGMyMove(p[1], p[2] + POINT_SIZE);
- GGMyDraw(p[1], p[2] - POINT_SIZE);
-
- GGXYPutStr(p[1] + POINT_TITLE, p[2] + POINT_TITLE, title);
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to set up the view port. *
- *****************************************************************************/
- void GGWindowViewPort(double XMin, double YMin,
- double XMax, double YMax, int WindowName)
- {
- #ifndef NOGRAPHICS
- CrntWindowName = WindowName;
- switch (WindowName) {
- case NO_WINDOW_NAME:
- break;
- case INPUT_WINDOW_NAME:
- WndwAspectRatio = 1.0;
- break;
- case STATUS_WINDOW_NAME:
- WndwAspectRatio = 1.0;
- break;
- case VIEW_WINDOW_NAME:
- WndwAspectRatio = 1.2;
- break;
- }
-
- setviewport(
- (ViewPortX = (int) ((XMin * ScreenMaxY2 + ScreenMaxY2) *
- GlblAspectRatio)),
- (ViewPortY = (int) (-YMax * ScreenMaxY2 + ScreenMaxY2)),
- (int) ((XMax * ScreenMaxY2 + ScreenMaxY2) * GlblAspectRatio),
- (int) (-YMin * ScreenMaxY2 + ScreenMaxY2),
- TRUE);
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to clear given window area. *
- * Note the viewport on exit is the window only! *
- *****************************************************************************/
- void GGClearWindow(double XMin, double YMin,
- double XMax, double YMax, int WindowName)
- {
- #ifndef NOGRAPHICS
- GGWindowViewPort(XMin, YMin, XMax, YMax, WindowName);
- clearviewport();
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to clear all the screen. *
- *****************************************************************************/
- void GGClearAllScreen(void)
- {
- #ifndef NOGRAPHICS
- cleardevice();
- ViewPortX = ViewPortY = 0;
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to put one char in current position with given color: *
- * The position of the cursor is updated horizontally (only). *
- * If the char is BS (Back Space), the position is updated backward with no *
- * printing. Note it is assume no over/underflow of horizontal position. *
- *****************************************************************************/
- void GGXYPutChar(char c, int Color)
- {
- #ifndef NOGRAPHICS
- char c1[] = " "; /* One char in length string. */
-
- if (c == BSPACE) {
- LocalMoveToX -= textwidth(" "); /* Must be non justified font! */
- moveto(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY);
- }
- else {
- c1[0] = c;
- GGMySetColor(Color);
- outtext(c1);
- LocalMoveToX += textwidth(" "); /* Must be non justified font! */
- moveto(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY);
- }
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to print an message on the given location: *
- *****************************************************************************/
- void GGXYPutStr(double x, double y, char *s)
- {
- #ifndef NOGRAPHICS
- GGMyMove(x, y);
- outtext(s);
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Routine to read one line terminated by <Enter> and visualized on graphic *
- * screen. *
- * Full line editing is supported which includes: *
- * 1. Right and left arrow to move along the line. *
- * 2. Delete to delete current character. *
- * 3. Insert to toggle Insert/Overwrite mode. *
- * 4. Backspace to delete character before current one. *
- * 5. Home/End to move to beginning/End of string respectively. *
- * 6. Return to accept current line. *
- * 7. Esc to clear current line. *
- * If s is not empty it is used as starting string. *
- * Line is drawn starting from position x, y on screen (normalized -1..1). *
- *****************************************************************************/
- void GGGetGraphicLine(double x, double y, char s[], int Length, int Color)
- {
- #ifndef NOGRAPHICS
- static int Insert = TRUE;
- int NextKey, Xstep, CursorPos = 0, FirstVisible = 0, Len = strlen(s),
- EndOfString = FALSE, FirstTime = s[0];
- char *Cursor;
-
- /* Force the string to be empty. Note we saved s[0] in FirstTime, so if */
- /* the string is empty we change nothing, otherwise we can recover it. */
- s[0] = 0;
-
- Xstep = textwidth(" "); /* Get the width is pixels of current font. */
-
- while (!EndOfString) {
- if (Len >= Length) {
- s[Length-1] = 0;
- return;
- }
-
- /* Set the first character in string to be displayed: */
- FirstVisible = CursorPos > 70 ? CursorPos - 10 : 0;
- GGMySetColor(Color); /* Draw the string and the cursor: */
- GGXYPutStr(x, y, &s[FirstVisible]);
- Cursor = (Insert ? "_" : "-");
- GGMySetColor(ScreenCursorColor);
- GGMyMove(x, y);
- moverel((CursorPos - FirstVisible) * Xstep, 0);
- outtext(Cursor);
-
- NextKey = GGGetKey();
-
- GGMySetColor(BLACK); /* Erase the string and the cursor: */
- GGMyMove(x, y);
- moverel((CursorPos - FirstVisible) * Xstep, 0);
- outtext(Cursor);
- GGXYPutStr(x, y, &s[FirstVisible]);
-
- switch (NextKey) {
- case KEY_BSPACE:
- if (CursorPos == 0) {
- GGTone(1000, 100); /* Do some noise... */
- break;
- }
- movmem(&s[CursorPos], &s[CursorPos - 1], Len - CursorPos + 1);
- CursorPos--;
- Len--;
- break;
- case KEY_DELETE:
- if (CursorPos >= Len) {
- GGTone(1000, 100); /* Do some noise... */
- break;
- }
- movmem(&s[CursorPos + 1], &s[CursorPos], Len - CursorPos);
- Len--;
- break;
- case KEY_RIGHT:
- if (CursorPos >= Len) {
- GGTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos++;
- break;
- case KEY_LEFT:
- if (CursorPos <= 0) {
- GGTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos--;
- break;
- case KEY_UP:
- if (FirstTime) s[0] = FirstTime;
- break;
- case KEY_RETURN:
- EndOfString = TRUE;
- break;
- case KEY_ESC:
- Len = 0; /* Clear everything. */
- CursorPos = 0;
- s[0] = 0;
- break;
- case KEY_HOME:
- CursorPos = 0;
- break;
- case KEY_END:
- CursorPos = Len;
- break;
- case KEY_INSERT:
- Insert = !Insert;
- break;
- default: /* Regular ascii char. */
- if (Insert) {
- movmem(&s[CursorPos], &s[CursorPos + 1],
- Len - CursorPos + 1);
- Len++;
- }
- else if (CursorPos == Len) Len++;/* We are on last character.*/
- s[CursorPos++] = NextKey;
- if (CursorPos == Len) s[CursorPos] = 0;
- break;
- }
- FirstTime = FALSE;
- }
- #endif /* NOGRAPHICS */
- }
-
- /*****************************************************************************
- * Get a key from keyboard, and translating operational keys into special *
- * codes (>255). *
- *****************************************************************************/
- static int GGGetKey(void)
- {
- char c;
-
- while (TRUE) switch (c = getch()) {
- case 0: /* Extended code - get the next extended char. */
- switch (getch()) {
- case 75: return KEY_LEFT;
- case 77: return KEY_RIGHT;
- case 71: return KEY_HOME;
- case 72: return KEY_UP;
- case 79: return KEY_END;
- case 83: return KEY_DELETE;
- case 82: return KEY_INSERT;
- }
- break;
- case 8:
- return KEY_BSPACE;
- case 10:
- case 13:
- return KEY_RETURN;
- case 27:
- return KEY_ESC;
- default:
- if isprint(c) return c;
- }
-
- return KEY_RETURN; /* Make warnings silent. */
- }
-
- /*****************************************************************************
- * Routine to make some sound with given Frequency, Time milliseconds: *
- *****************************************************************************/
- void GGTone(int Frequency, int Time)
- {
- sound(Frequency);
- delay(Time);
- nosound();
- }
-