예제 #1
0
파일: anim.c 프로젝트: adsr/agar
/* Resize an animation; pixels are left uninitialized. */
int
AG_AnimResize(AG_Anim *a, Uint w, Uint h)
{
	Uint8 *pixelsNew;
	int i;
	int pitchNew;

	AG_MutexLock(&a->lock);

	pitchNew = w*a->format->BytesPerPixel;
	for (i = 0; i < a->n; i++) {
		AG_AnimFrame *af = &a->f[i];
		if ((pixelsNew = TryRealloc(af->pixels, h*pitchNew)) == NULL) {
			for (i--; i >= 0; i--) {
				Free(af->pixels);
			}
			goto fail;
		}
		af->pixels = pixelsNew;
	}
	a->pitch = pitchNew;
	a->w = w;
	a->h = h;
	a->clipRect = AG_RECT(0,0,w,h);

	AG_MutexUnlock(&a->lock);
	return (0);
fail:
	AG_MutexUnlock(&a->lock);
	return (-1);
}
예제 #2
0
파일: anim.c 프로젝트: adsr/agar
/* Return a newly-allocated duplicate of an animation. */
AG_Anim *
AG_AnimDup(AG_Anim *sa)
{
	AG_Anim *a;
	int i;

	AG_MutexLock(&sa->lock);

	a = AG_AnimNew(sa->type, sa->w, sa->h, sa->format,
	    (sa->flags & AG_SAVED_ANIM_FLAGS));
	if (a == NULL) {
		AG_MutexUnlock(&sa->lock);
		return (NULL);
	}
	if ((a->f = TryMalloc(sa->n*sizeof(AG_AnimFrame))) == NULL) {
		goto fail;
	}
	for (i = 0; i < sa->n; i++) {
		AG_AnimFrame *af = &a->f[i];

		if ((af->pixels = TryMalloc(sa->h*sa->pitch)) == NULL) {
			goto fail;
		}
		memcpy(af->pixels, sa->f[i].pixels, sa->h*sa->pitch);
		a->n++;
	}
	AG_MutexUnlock(&sa->lock);
	return (a);
fail:
	AG_MutexUnlock(&sa->lock);
	AG_AnimFree(a);
	return (NULL);
}
예제 #3
0
static int
GetIfConfig(AG_NetAddrList *nal)
{
	PIP_ADAPTER_INFO pAdapterInfo;
	PIP_ADAPTER_INFO pAdapter;
	PIP_ADDR_STRING pAddress;
	DWORD dwRetVal = 0;
	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
	
	AG_NetAddrListClear(nal);

	if ((pAdapterInfo = TryMalloc(sizeof(IP_ADAPTER_INFO))) == NULL)
		return (-1);

	AG_MutexLock(&agNetWin32Lock);

	dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
	if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
		PIP_ADAPTER_INFO pAdapterInfoNew;
		if ((pAdapterInfoNew = TryRealloc(pAdapterInfo, ulOutBufLen))
		    == NULL) {
			free(pAdapterInfo);
			goto fail;
		}
		pAdapterInfo = pAdapterInfoNew;
		dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
	}
	if (dwRetVal != NO_ERROR) {
		AG_SetError("GetAdaptersInfo() failed");
		goto fail;
	}
	for (pAdapter = pAdapterInfo;
	     pAdapter != NULL;
	     pAdapter = pAdapter->Next) {
		for (pAddress = &pAdapterInfo->IpAddressList;
		     pAddress != NULL;
		     pAddress = pAddress->Next) {
			AG_NetAddr *na;

			if ((na = AG_NetAddrNew()) == NULL) {
				AG_NetAddrListClear(nal);
				goto fail;
			}
			na->family = AG_NET_INET4;
			na->port = 0;
			na->na_inet4.addr = inet_addr(pAddress->IpAddress.String);
			TAILQ_INSERT_TAIL(nal, na, addrs);
		}
	}

	AG_MutexUnlock(&agNetWin32Lock);
	free(pAdapterInfo);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #4
0
static int
GetOption(AG_NetSocket *ns, enum ag_net_socket_option so, void *p)
{
	socklen_t optLen;
	int rv = 0;
	
	AG_MutexLock(&agNetWin32Lock);

	switch (so) {
	case AG_NET_BACKLOG:
		*(int *)p = ns->listenBacklog;
		break;
	case AG_NET_DEBUG:
	case AG_NET_REUSEADDR:
	case AG_NET_KEEPALIVE:
	case AG_NET_DONTROUTE:
	case AG_NET_BROADCAST:
	case AG_NET_SNDBUF:
	case AG_NET_RCVBUF:
		optLen = sizeof(int);
		rv = getsockopt(ns->fd, SOL_SOCKET, agSockOptionMap[so],
		    p, &optLen);
		break;
	case AG_NET_OOBINLINE:
		optLen = sizeof(int);
		rv = getsockopt(ns->fd, SOL_SOCKET, SO_OOBINLINE, p, &optLen);
		break;
	case AG_NET_LINGER:
		{
			struct linger ling;

			optLen = sizeof(struct linger);
			rv = getsockopt(ns->fd, SOL_SOCKET, SO_LINGER,
			    (char *)&ling, &optLen);
			if (rv == 0) {
				*(int *)p = ling.l_onoff ? ling.l_linger : 0;
			}
		}
		break;
	default:
		AG_SetError("Bad socket option");
		goto fail;
	}
	if (rv == SOCKET_ERROR) {
		AG_SetError("getsockopt(%u): %s", (Uint)so, strerror(errno));
		goto fail;
	}
	
	AG_MutexUnlock(&agNetWin32Lock);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #5
0
static int
SetOption(AG_NetSocket *ns, enum ag_net_socket_option so, const void *p)
{
	int rv = 0;
	
	AG_MutexLock(&agNetWin32Lock);

	switch (so) {
	case AG_NET_BACKLOG:
		ns->listenBacklog = *(const int *)p;
		break;
	case AG_NET_DEBUG:
	case AG_NET_REUSEADDR:
	case AG_NET_KEEPALIVE:
	case AG_NET_DONTROUTE:
	case AG_NET_BROADCAST:
	case AG_NET_SNDBUF:
	case AG_NET_RCVBUF:
		rv = setsockopt(ns->fd, SOL_SOCKET, agSockOptionMap[so],
		    p, sizeof(int));
		break;
	case AG_NET_OOBINLINE:
		rv = setsockopt(ns->fd, SOL_SOCKET, SO_OOBINLINE, p, sizeof(int));
		break;
	case AG_NET_LINGER:
		{
			int val = *(const int *)p;
			struct linger ling;

			ling.l_onoff = (val > 0);
			ling.l_linger = val;
			rv = setsockopt(ns->fd, SOL_SOCKET, SO_LINGER,
			    (const char *)&ling, sizeof(struct linger));
		}
		break;
	default:
		AG_SetError("Bad socket option");
		goto fail;
	}
	if (rv != SOCKET_ERROR) {
		AG_SetError("setsockopt(%u): %s", (Uint)so, strerror(errno));
		goto fail;
	}

	AG_MutexUnlock(&agNetWin32Lock);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #6
0
static void
RENDERER_Delay(Uint32 Tdelay)
{
	struct timespec ts, tsNow;
	int rv;

	AG_MutexLock(&agCondRenderLock);
	clock_gettime(CLOCK_MONOTONIC, &ts);
	ts.tv_sec += (Tdelay/1000);
	ts.tv_nsec += (Tdelay % 1000)*1000000;

	for (;;) {
		rv = AG_CondTimedWait(&agCondBeginRender, &agCondRenderLock, &ts);
		if (rv != 0) {
			clock_gettime(CLOCK_MONOTONIC, &tsNow);
			if (tsNow.tv_sec < ts.tv_sec) {
				continue;
			}
			if (tsNow.tv_sec > ts.tv_sec ||
			    tsNow.tv_nsec >= ts.tv_nsec)
				break;
		}
	}
	AG_MutexUnlock(&agCondRenderLock);
}
예제 #7
0
파일: anim.c 프로젝트: adsr/agar
/* Set effective playback speed. */
void
AG_AnimSetFPS(AG_AnimState *ast, double fps)
{
	AG_MutexLock(&ast->lock);
	ast->fps = fps;
	AG_MutexUnlock(&ast->lock);
}
예제 #8
0
파일: anim.c 프로젝트: adsr/agar
/* Set original playback speed. */
void
AG_AnimSetOrigFPS(AG_Anim *an, double fps)
{
	AG_MutexLock(&an->lock);
	an->fpsOrig = fps;
	AG_MutexUnlock(&an->lock);
}
예제 #9
0
파일: anim.c 프로젝트: adsr/agar
void
AG_AnimStop(AG_AnimState *ast)
{
	AG_MutexLock(&ast->lock);
	ast->play = 0;
	AG_MutexUnlock(&ast->lock);
}
예제 #10
0
void DumpObject::DrawCursor(BOOL Flag)
{
    AG_Rect rec;
    AG_Color col;
    AG_Color fg,bg;
    AG_Surface *s;


    rec.h = CHRH;
    rec.w = CHRW;
    rec.x = CHRW * CURX;
    rec.y = CHRH * CURY;
    col = fgColor;
    col.a = 64;
    if(Flag) {
        AG_MutexLock(&mutex);
        fg = fgColor;
        bg = bgColor;
        fgColor = bg;
        bgColor = fg;
        PutCharScreen(ConsoleBuf[CURY * W + CURX]);
        AG_FillRect(Screen, &rec, col);
        fgColor = fg;
        bgColor = bg;
        AG_MutexUnlock(&mutex);
    }
}
예제 #11
0
void GLCLDraw::CopyPalette(void)
{
   struct palettebuf_t *pold, *pnew;
   int newline;
   int endline;
   int alines;
   int dlines;
   cl_int r;
   cl_event ev_unmap, ev_map;
   int i;
   
   AG_MutexLock(&mutex_palette);

   pold = palettebuf;
   newline = palette_bank + 1;
   if(newline >= 2) newline = 0;
   
   pnew = clEnqueueMapBuffer(command_queue, palette_buf[newline], CL_TRUE, CL_MAP_READ | CL_MAP_WRITE,
			     0, (size_t)sizeof(struct palettebuf_t),
			     0, NULL, &ev_map, &r);
   if(r < CL_SUCCESS) {
      AG_MutexUnlock(&mutex_palette);
      return;
   }
   alines = pold->alines_h * 256 + pold->alines_l;
   dlines = pold->dlines_h * 256 + pold->dlines_l;
   if(alines < 0)   alines = 0;
   if(alines > 199) alines = 199;
   if(dlines < 0)   dlines = 0;
   if(dlines > 399) dlines = 399;

   if((pold != NULL) && (pnew != NULL)) {
     memcpy(pnew, pold, sizeof(Uint8) * 4 + sizeof(struct apalettetbl_t) * alines); // Copy Lines + Analog Palette
     memcpy(&(pnew->dtbls[0]), &(pold->dtbls[0]), sizeof(struct dpalettetbl_t) * dlines); // Copy Digital Palette
     palettebuf = pnew;
     
     clEnqueueUnmapMemObject(command_queue, palette_buf[palette_bank], 
			     pold, 1, &ev_map,
			     &ev_unmap);
     palette_bank_old = palette_bank;
     palette_bank = newline;
   }
   
   AG_MutexUnlock(&mutex_palette);
   //clFinish(command_queue);
   clFlush(command_queue);
}
예제 #12
0
//
// InitLogFile
//
int Xbox::InitLogFile()
{
	AG_MutexInit(&XBLogMutex);

	AG_MutexLock(&XBLogMutex);

	XBLogFile.open("T:\\ag-odalaunch.log");
	if(XBLogFile.fail())
	{
		AG_MutexUnlock(&XBLogMutex);
		return -1;
	}

	AG_MutexUnlock(&XBLogMutex);

	return 0;
}
예제 #13
0
//
// CloseLogFile
//
void Xbox::CloseLogFile()
{
	AG_MutexLock(&XBLogMutex);

	XBLogFile.close();

	AG_MutexUnlock(&XBLogMutex);
}
예제 #14
0
파일: anim.c 프로젝트: adsr/agar
/* Animation processing loop */
static void *
AnimProc(void *arg)
{
	AG_AnimState *ast = arg;
	Uint32 delay;

	while (ast->play) {
		AG_MutexLock(&ast->lock);
		AG_MutexLock(&ast->an->lock);

		if (ast->an->n < 1) {
			AG_MutexUnlock(&ast->an->lock);
			AG_MutexUnlock(&ast->lock);
			goto out;
		}
		if (ast->f & AG_ANIM_REVERSE) {
			if (--ast->f < 0) {
				if (ast->flags & AG_ANIM_LOOP) {
					ast->f = (ast->an->n - 1);
				} else if (ast->flags & AG_ANIM_PINGPONG) {
					ast->f = 0;
					ast->flags &= ~(AG_ANIM_REVERSE);
				} else {
					ast->play = 0;
					AG_MutexUnlock(&ast->an->lock);
					AG_MutexUnlock(&ast->lock);
					goto out;
				}
			}
		} else {
			if (++ast->f >= ast->an->n) {
				if (ast->flags & AG_ANIM_LOOP) {
					ast->f = 0;
				} else if (ast->flags & AG_ANIM_PINGPONG) {
					ast->f--;
					ast->flags |= AG_ANIM_REVERSE;
				} else {
					ast->play = 0;
					AG_MutexUnlock(&ast->an->lock);
					AG_MutexUnlock(&ast->lock);
					goto out;
				}
			}
		}

		delay = (Uint32)(1000.0/ast->fps);

		AG_MutexUnlock(&ast->an->lock);
		AG_MutexUnlock(&ast->lock);

		AG_Delay(delay);
	}
out:
	return (NULL);
}
예제 #15
0
DumpObject::~DumpObject()
{
    AG_MutexLock(&mutex);
//    if(TextFont != NULL) AG_DestroyFont(TextFont);
//    if(SymFont != NULL) AG_DestroyFont(SymFont);
    if(ConsoleBuf != NULL) delete [] ConsoleBuf;
    if(BackupConsoleBuf != NULL) delete [] BackupConsoleBuf;
    AG_MutexUnlock(&mutex);
    AG_MutexDestroy(&mutex);
}
예제 #16
0
void DumpObject::MoveDrawPos(int x, int y)
{
    AG_MutexLock(&mutex);
    X = x;
    Y = y;
    if(X >= W) X = W - 1;
    if(Y >= H) Y = H - 1;
    if(X <= 0) X = 0;
    if(Y <= 0) Y = 0;
    AG_MutexUnlock(&mutex);
}
예제 #17
0
void DumpObject::MoveCursor(int x, int y)
{
    AG_MutexLock(&mutex);
    X = x;
    Y = y;
    if(CURX >= W) CURX = W - 1;
    if(CURY >= H) CURY = H - 1;
    if(CURX <= 0) CURX = 0;
    if(CURY <= 0) CURY = 0;
    AG_MutexUnlock(&mutex);
}
예제 #18
0
static int
Write(AG_NetSocket *ns, const void *p, size_t size, size_t *nWrote)
{
	int rv;

	AG_MutexLock(&agNetWin32Lock);

	rv = send(ns->fd, (const char *)p, size, 0);
	if (rv == SOCKET_ERROR) {
		AG_SetError("send: failed (%d)", rv);
		goto fail;
	}
	if (nWrote != NULL) { *nWrote = (size_t)rv; }

	AG_MutexUnlock(&agNetWin32Lock);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #19
0
static int
Read(AG_NetSocket *ns, void *p, size_t size, size_t *nRead)
{
	int rv;

	AG_MutexLock(&agNetWin32Lock);

	rv = recv(ns->fd, (char *)p, size, 0);
	if (rv == SOCKET_ERROR) {
		AG_SetError("recv: failed (%d)", rv);
		goto fail;
	}
	if (nRead != NULL) { *nRead = (size_t)rv; }

	AG_MutexUnlock(&agNetWin32Lock);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #20
0
파일: anim.c 프로젝트: adsr/agar
void
AG_AnimSetPingPong(AG_AnimState *ast, int enable)
{
	AG_MutexLock(&ast->lock);
	if (enable) {
		ast->flags |= AG_ANIM_PINGPONG;
		ast->flags &= ~(AG_ANIM_LOOP);
	} else {
		ast->flags &= ~(AG_ANIM_PINGPONG);
	}
	AG_MutexUnlock(&ast->lock);
}
예제 #21
0
파일: anim.c 프로젝트: adsr/agar
/* Set the source alpha flag and per-animation alpha. */
void
AG_AnimSetAlpha(AG_Anim *an, Uint flags, Uint8 alpha)
{
	AG_MutexLock(&an->lock);
	if (flags & AG_SRCALPHA) {
		an->flags |= AG_SRCALPHA;
	} else {
		an->flags &= ~(AG_SRCALPHA);
	}
	an->format->alpha = alpha;
	AG_MutexUnlock(&an->lock);
}
예제 #22
0
파일: anim.c 프로젝트: adsr/agar
/* Set the source colorkey flag and per-animation colorkey. */
void
AG_AnimSetColorKey(AG_Anim *an, Uint flags, Uint32 colorkey)
{
	AG_MutexLock(&an->lock);
	if (flags & AG_SRCCOLORKEY) {
		an->flags |= AG_SRCCOLORKEY;
	} else {
		an->flags &= ~(AG_SRCCOLORKEY);
	}
	an->format->colorkey = colorkey;
	AG_MutexUnlock(&an->lock);
}
예제 #23
0
파일: anim.c 프로젝트: adsr/agar
/* Insert a new animation frame. */
int
AG_AnimFrameNew(AG_Anim *a, const AG_Surface *su)
{
	AG_AnimFrame *afNew, *af;
	AG_Surface *suTmp = NULL;
	int nf;

	AG_MutexLock(&a->lock);

	if (su->w != a->w || su->h != a->h) {
		if (AG_ScaleSurface(su, a->w, a->h, &suTmp) == -1)
			goto fail;
	} else {
		if ((suTmp = AG_SurfaceConvert(su, a->format)) == NULL)
			goto fail;
	}

	if ((afNew = TryRealloc(a->f, (a->n+1)*sizeof(AG_AnimFrame))) == NULL) {
		goto fail;
	}
	a->f = afNew;
	af = &a->f[a->n];
	af->flags = 0;
	if ((af->pixels = TryMalloc(su->h*a->pitch)) == NULL) {
		a->n--;
		goto fail;
	}
	memcpy(af->pixels, suTmp->pixels, su->h*a->pitch);
	nf = a->n++;
	AG_MutexUnlock(&a->lock);

	AG_SurfaceFree(suTmp);
	return (nf);
fail:
	AG_MutexUnlock(&a->lock);
	if (suTmp != NULL) {
		AG_SurfaceFree(suTmp);
	}
	return (-1);
}
예제 #24
0
파일: anim.c 프로젝트: adsr/agar
void
AG_AnimStateInit(AG_Anim *an, AG_AnimState *ast)
{
	AG_MutexInitRecursive(&ast->lock);
	ast->an = an;
	ast->flags = 0;
	ast->play = 0;
	ast->f = 0;
	
	AG_MutexLock(&an->lock);
	ast->fps = an->fpsOrig;
	AG_MutexUnlock(&an->lock);
}
예제 #25
0
static void
Close(AG_NetSocket *ns)
{
	AG_MutexLock(&agNetWin32Lock);

	if (ns->fd != -1) {
		closesocket(ns->fd);
		ns->fd = -1;
	}
	if (InitSocket(ns) == -1)
		AG_FatalError(NULL);
	
	AG_MutexUnlock(&agNetWin32Lock);
}
예제 #26
0
static int
Connect(AG_NetSocket *ns, const AG_NetAddr *na)
{
	struct sockaddr_storage sa;
	socklen_t saLen = 0;
	
	AG_MutexLock(&agNetWin32Lock);
	if (ns->family == 0) {			/* Inherit from address */
		ns->family = na->family;
		if (InitSocket(ns) == -1)
			goto fail;
	}
	NetAddrToSockAddr(na, &sa, &saLen);
	if (connect(ns->fd, (struct sockaddr *)&sa, saLen) < 0) {
		AG_SetError("connect: %s", strerror(errno));
		goto fail;
	}
	AG_MutexUnlock(&agNetWin32Lock);
	return (0);
fail:
	AG_MutexUnlock(&agNetWin32Lock);
	return (-1);
}
예제 #27
0
BOOL DumpObject::Draw(BOOL redraw)
{
    int xx;
    int yy;
    int Xb;
    int Yb;
    int pos;
    BOOL flag = FALSE;

    if(Screen == NULL) return FALSE;
    // Backup X,Y
    AG_MutexLock(&mutex);

    Xb = X;
    Yb = Y;
    AG_SurfaceLock(Screen);
    //redraw = TRUE;
    if(redraw) {
        flag = TRUE;
        for(yy = 0; yy < H; yy++) {
            pos = yy * W;
            for(xx = 0; xx < W; xx++) {
                X = xx;
                Y = yy;
                PutCharScreen(ConsoleBuf[pos + xx]);
                BackupConsoleBuf[pos + xx] = ConsoleBuf[pos + xx];
            }
        }
    } else { // Diff
        for(yy = 0; yy < H; yy++) {
            pos = yy * W;
            for(xx = 0; xx < W; xx++) {
                if(ConsoleBuf[pos + xx] != BackupConsoleBuf[pos + xx]) {
                    X = xx;
                    Y = yy;
                    PutCharScreen(ConsoleBuf[pos + xx]);
                    flag = TRUE;
                }
                BackupConsoleBuf[pos + xx] = ConsoleBuf[pos + xx];
            }
        }
    }
    // Restore Original X,Y
    X = Xb;
    Y = Yb;
    AG_MutexUnlock(&mutex);
    AG_SurfaceUnlock(Screen);
    return TRUE;
}
예제 #28
0
파일: hsvpal.c 프로젝트: LiberatorUSA/GUCEF
static void
CopyColor(AG_Event *event)
{
	AG_HSVPal *pal = AG_PTR(1);
	
	AG_ObjectLock(pal);
	AG_MutexLock(&CopyLock);
	cH = AG_GetFloat(pal, "hue");
	cS = AG_GetFloat(pal, "saturation");
	cV = AG_GetFloat(pal, "value");
	cA = AG_GetFloat(pal, "alpha");
	AG_MutexUnlock(&CopyLock);
	AG_ObjectUnlock(pal);
	AG_Redraw(pal);
}
예제 #29
0
파일: anim.c 프로젝트: adsr/agar
/* Set one or more entries in an indexed animation's palette. */
int
AG_AnimSetPalette(AG_Anim *a, AG_Color *c, Uint offs, Uint count)
{
	Uint i;

	AG_MutexLock(&a->lock);
	if (a->type != AG_ANIM_INDEXED) {
		AG_SetError("Not an indexed animation");
		goto fail;
	}
	if (offs >= a->format->palette->nColors ||
	    offs+count >= a->format->palette->nColors) {
		AG_SetError("Bad palette offset/count");
		goto fail;
	}
	for (i = 0; i < count; i++) {
		a->format->palette->colors[offs+i] = c[i];
	}
	AG_MutexUnlock(&a->lock);
	return (0);
fail:
	AG_MutexUnlock(&a->lock);
	return (-1);
}
예제 #30
0
BOOL DumpObject::InitConsole(int w, int h)
{
    int size;
    AG_PixelFormat fmt;
    int xx;
    int yy;

    if((w <= 0) || (h <= 0)) return FALSE;
    AG_MutexLock(&mutex);
    W = w;
    H = h;
    X = 0;
    Y = 0;
    size = w * h;
    if(ConsoleBuf != NULL) delete [] ConsoleBuf;
    if(BackupConsoleBuf != NULL) delete [] ConsoleBuf;
    if(Screen != NULL) {
        Screen = NULL;
        AG_SurfaceFree(Screen);
    }

    ConsoleBuf = new BYTE[size];
    BackupConsoleBuf = new BYTE[size];
    for(yy = 0; yy < H; yy++) {
        for(xx = 0; xx < W; xx++) {
            ConsoleBuf[xx + yy * W] = 0x00000000;
            BackupConsoleBuf[xx + yy * W] = 0x00000000;
        }
    }
    SetPixelFormat(&fmt);
    Screen = AG_SurfaceNew(AG_SURFACE_PACKED, W * CHRW, H * CHRH, &fmt, 0);
    {
        AG_Color col;
        AG_Rect rec;
        col.r = 0;
        col.g = 0;
        col.b = 0;
        col.a = 255;
        rec.x = 0;
        rec.y = 0;
        rec.w = Screen->w;
        rec.h = Screen->h;
        AG_FillRect(Screen, &rec, col);
    }
    AG_MutexUnlock(&mutex);
}