Ejemplo n.º 1
0
int main(void)
{
	logOpen();
	initXWindows();
	init_opengl();
	Game game;
	init(&game);
	srand(time(NULL));
	clock_gettime(CLOCK_REALTIME, &timePause);
	clock_gettime(CLOCK_REALTIME, &timeStart);
	int done=0;
	while (!done) {
		while (XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_resize(&e);
			check_mouse(&e);
			done = check_keys(&e);
		}
		clock_gettime(CLOCK_REALTIME, &timeCurrent);
		timeSpan = timeDiff(&timeStart, &timeCurrent);
		timeCopy(&timeStart, &timeCurrent);
		physicsCountdown += timeSpan;
		while (physicsCountdown >= physicsRate) {
			physics(&game);
			physicsCountdown -= physicsRate;
		}
		render(&game);
		glXSwapBuffers(dpy, win);
	}
	cleanupXWindows();
	cleanup_fonts();
	logClose();
	return 0;
}
Ejemplo n.º 2
0
int main(void)
{

    int done=0;
    srand(time(NULL));
    initXWindows();
    init_opengl();
    //declare game object
    Game game;
    //start animation
    while(!done) {
        while(XPending(dpy)) {
            XEvent e;
            XNextEvent(dpy, &e);
            check_mouse(&e, &game);
            done = check_keys(&e, &game);
        }
        movement(&game);
        render(&game);
        glXSwapBuffers(dpy, win);
    }
    cleanupXWindows();
    cleanup_fonts();
    return 0;
}
Ejemplo n.º 3
0
/*
 * Clean up the GDI data structures without attempting any more printing.
 */
static void
gdi_abort(void)
{
    if (pstate.out_row) {
	(void) EndPage(pstate.dlg.hDC);
	pstate.out_row = 0;
    }
    (void) EndDoc(pstate.dlg.hDC);

    cleanup_fonts();
}
Ejemplo n.º 4
0
int main(void)
{
	logOpen();
	initXWindows();
	init_opengl();
	init();
	init_sounds();
	clock_gettime(CLOCK_REALTIME, &timePause);
	clock_gettime(CLOCK_REALTIME, &timeStart);
	while(!done) {
		while(XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_resize(&e);
			check_mouse(&e);
			check_keys(&e);
		}
		//
		//Below is a process to apply physics at a consistent rate.
		//1. Get the time right now.
		clock_gettime(CLOCK_REALTIME, &timeCurrent);
		//2. How long since we were here last?
		timeSpan = timeDiff(&timeStart, &timeCurrent);
		//3. Save the current time as our new starting time.
		timeCopy(&timeStart, &timeCurrent);
		//4. Add time-span to our countdown amount.
		physicsCountdown += timeSpan;
		//5. Has countdown gone beyond our physics rate? 
		//       if yes,
		//           In a loop...
		//              Apply physics
		//              Reducing countdown by physics-rate.
		//              Break when countdown < physics-rate.
		//       if no,
		//           Apply no physics this frame.
		while(physicsCountdown >= physicsRate) {
			//6. Apply physics
			physics();
			//7. Reduce the countdown by our physics-rate
			physicsCountdown -= physicsRate;
		}
		//Always render every frame.
		render();
		glXSwapBuffers(dpy, win);
	}
	cleanupXWindows();
	cleanup_fonts();
	#ifdef USE_SOUND
	fmod_cleanup();
	#endif //USE_SOUND
	logClose();
	return 0;
}
Ejemplo n.º 5
0
int main(void)
{
	int done=0;
	srand(time(NULL));
	initXWindows();
	init_opengl();
	//declare game object
	Game game;
	game.n=0;

	//declare a box shape
	game.box[0].width = 100;
	game.box[0].height = 10;
	game.box[0].center.x = 270 + 5*65;
	game.box[0].center.y = 500 - 5*60;
    game.box[1].width = 100;
    game.box[1].height = 10;
    game.box[1].center.x = 270 + 5*65 - 75;
    game.box[1].center.y = 500 - 5*60 + 45;
    game.box[2].width = 100;
    game.box[2].height = 10;
    game.box[2].center.x = 270 + 5*65 - 150;
    game.box[2].center.y = 500 - 5*60 + 90;
    game.box[3].width = 100;
    game.box[3].height = 10;
    game.box[3].center.x = 270 + 5*65 - 225;
    game.box[3].center.y = 500 - 5*60 + 135;
    game.box[4].width = 100;
    game.box[4].height = 10;
    game.box[4].center.x = 270 + 5*65 - 300;
    game.box[4].center.y = 500 - 5*60 + 180;
	game.circle.center.x = 760;
	game.circle.center.y = -25;
	game.circle.radius = 100;

	//start animation
	while(!done) {
		while(XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_mouse(&e, &game);
			done = check_keys(&e, &game);
		}
		movement(&game);
		render(&game);
		glXSwapBuffers(dpy, win);
	}
	cleanupXWindows();
	cleanup_fonts();
	return 0;
}
Ejemplo n.º 6
0
void cleanup_mem(void)
{
	int i;

	destroy_url_list();
	history_destroy();
	command_cleanup();
	queue_destroy(buddy_request_queue);
	cleanup_manufacture();
	cleanup_text_buffers();
	cleanup_fonts();
	destroy_all_actors();
	end_actors_lists();
	cleanup_lights();
	/* 2d objects */
	destroy_all_2d_objects();
	destroy_all_2d_object_defs();
	/* 3d objects */
	destroy_all_3d_objects();
	/* caches */
	cache_e3d->free_item = &destroy_e3d;
	cache_delete(cache_e3d);
	cache_e3d = NULL;
#ifdef NEW_TEXTURES
	free_texture_cache();
#endif
	// This should be fixed now  Sir_Odie
	cache_delete(cache_system);
	cache_system = NULL;
	/* map location information */
	for (i = 0; continent_maps[i].name; i++)
	{
	    free(continent_maps[i].name);
	}
	free (continent_maps);

	destroy_hash_table(server_marks);
	
	for (i = 0; i < video_modes_count; i++)
	{
		if (video_modes[i].name)
			free(video_modes[i].name);
	}
	free_shaders();
}
Ejemplo n.º 7
0
int main(void)
{
    int done=0;
    srand(time(NULL));
    initXWindows();
    init_opengl();
    init_sounds();

    clock_gettime(CLOCK_REALTIME, &timePause);
    clock_gettime(CLOCK_REALTIME, &timeStart);
    //declare game object
    Game game;

    fmod_playsound(1);
    //start animation
    while(!done) {
	while(XPending(dpy)) {
	    XEvent e;
	    XNextEvent(dpy, &e);
	    check_resize(&e);
	    check_mouse(&e, &game);
	    done = check_keys(&e, &game);
	}
	clock_gettime(CLOCK_REALTIME, &timeCurrent);
	timeSpan = timeDiff(&timeStart, &timeCurrent);
	timeCopy(&timeStart, &timeCurrent);
	movementCountdown += timeSpan;
	while(movementCountdown >= movementRate)
	{
	    movement(&game);
	    movementCountdown -= movementRate;
	}
	render(&game);
	glXSwapBuffers(dpy, win);
    }
    cleanupXWindows();
    cleanup_fonts();
#ifdef USE_SOUND
    fmod_cleanup();
#endif //USE_SOUND
    return 0;
}
Ejemplo n.º 8
0
/*
 * Finish the GDI print-out and clean up the data structures.
 */
static int
gdi_done(const char **fail)
{
    int rc = 0;

    if (pstate.out_row) {
	if (EndPage(pstate.dlg.hDC) <= 0) {
	    *fail = "EndPage failed";
	    rc = -1;
	}
	pstate.out_row = 0;
    }
    if (EndDoc(pstate.dlg.hDC) <= 0) {
	*fail = "EndDoc failed";
	rc = -1;
    }

    cleanup_fonts();

    return rc;
}
Ejemplo n.º 9
0
int main(void)
{
    logOpen();
    initXWindows();
    init_opengl();
    init();
    //buttonsInit();------------------------------------------------------------------
    init_sounds();
    clock_gettime(CLOCK_REALTIME, &timePause);
    clock_gettime(CLOCK_REALTIME, &timeStart);
    while(!done) {
        while(XPending(dpy)) {
            XEvent e;
            XNextEvent(dpy, &e);
            check_resize(&e);
            check_mouse(&e);
            GOcheck_mouse(&e);
            check_keys(&e);

        }
        clock_gettime(CLOCK_REALTIME, &timeCurrent);
        timeSpan = timeDiff(&timeStart, &timeCurrent);
        timeCopy(&timeStart, &timeCurrent);
        physicsCountdown += timeSpan;
        while(physicsCountdown >= physicsRate) {
            physics();
            physicsCountdown -= physicsRate;
        }
        render();
        glXSwapBuffers(dpy, win);
    }
    cleanupXWindows();
    cleanup_fonts();
#ifdef USE_SOUND
    fmod_cleanup();
#endif //USE_SOUND
    logClose();
    return 0;
}
Ejemplo n.º 10
0
int main(void)
{
    int done=0;
    srand(time(NULL));
    initXWindows();
    Game game;
    DefineRagdoll(&game);
    init_opengl(&game);
    create_sounds();
    play();
    //declare game object
    init_keys();
    clock_gettime(CLOCK_REALTIME, &timePause);
    clock_gettime(CLOCK_REALTIME, &timeStart);

    //start animation
    while(!done) {
	while(XPending(dpy)) {
	    XEvent e;
	    XNextEvent(dpy, &e);
	    check_mouse(&e, &game);
	    check_resize(&game, &e);
	    done = check_keys(&e);
	}
	clock_gettime(CLOCK_REALTIME, &timeCurrent);
	timeSpan = timeDiff(&timeStart, &timeCurrent);
	timeCopy(&timeStart, &timeCurrent);
	physicsCountdown += timeSpan;
	while(physicsCountdown >= physicsRate) {
	    movement(&game);
	    physicsCountdown -= physicsRate;
	}
	render(&game);
	glXSwapBuffers(dpy, win);
    }
    cleanupXWindows();
    cleanup_fonts();
    return 0;
}
Ejemplo n.º 11
0
int main(void)
{
	initXWindows();
    srand(time(NULL));
    clock_gettime(CLOCK_REALTIME, &timePause);
    clock_gettime(CLOCK_REALTIME, &timeStart);
    init_opengl();
    init_ship();
	//Do this to allow fonts
	glEnable(GL_TEXTURE_2D);
	initialize_fonts();
	init_textures();
	while(!done) {
		while(XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_resize(&e);
			check_mouse(&e);
			check_keys(&e);
		}
        clock_gettime(CLOCK_REALTIME, &timeCurrent);
        timeSpan = timeDiff(&timeStart, &timeCurrent);
        timeCopy(&timeStart, &timeCurrent);
        physicsCountdown += timeSpan;
        while (physicsCountdown >= physicsRate) {
            physics();
            physicsCountdown -= physicsRate;
            render();
        }
		//physics();
		//render();
		glXSwapBuffers(dpy, win);
	}
	cleanupXWindows();
	cleanup_fonts();
	return 0;
}
Ejemplo n.º 12
0
int main(int argc, char *argv[])
{
	if(argc > 1) {
		if(argv[1] != NULL) {
			beginTesting();
		}
		return 0;
	}

	logOpen();
	initXWindows();
	init_opengl();
	Game game;
	init(&game);
	srand(time(NULL));
	clock_gettime(CLOCK_REALTIME, &timePause);
	clock_gettime(CLOCK_REALTIME, &timeStart);	

	hud = new Hud(xres ,yres);
	if (TEST_Hud){
		hud->testHUDAll();
		return 0;
	}
	//DEFUALT IS LEVEL 1 SELECTED:
	selected_screen = LEFT;    
	level =1;
	//--------------
	is_gameover = false;
	high_score = 0;
	gameStarted = false;
	lastPaddleHit = 'N';//'N' means no paddle hit

	bombBegin = time(NULL);
	bombRandom = random(7);

	beginSmallLeftPaddle = time(NULL);
	smallLeftPaddleTime = 7;
	beginSmallRightPaddle = time(NULL);
	smallRightPaddleTime = 7;
	hud->setAI(false);//DEFAULT: player2 is human	
	ball_saved_X_velocity = 8.0f * cos(30);
	ball_saved_Y_velocity = 8.0f * sin(90);    
	obstacle_saved_Y_velocity = -5.0;

	int min;
	if (xres<yres){
		min=xres;
	}
	else{
		min=yres;
	}
	bomb_radius = ((int)(3*min)/10);

	//MAIN MENU LOOP 
	while(intro != 0) {
		while (XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_resize(&e);
			intro = check_keys(&e, &game);
		}
		render(&game);
		glXSwapBuffers(dpy, win);
	}


	//BEGIN MAIN GAME LOOP
	int done=0;
	while (!done) {        
		while (XPending(dpy)) {
			XEvent e;
			XNextEvent(dpy, &e);
			check_resize(&e);
			done = check_keys(&e, &game);
		}
		clock_gettime(CLOCK_REALTIME, &timeCurrent);
		timeSpan = timeDiff(&timeStart, &timeCurrent);
		timeCopy(&timeStart, &timeCurrent);
		physicsCountdown += timeSpan;
		while (physicsCountdown >= physicsRate) {
			physics(&game);
			physicsCountdown -= physicsRate;
		}        
		render(&game);
		glXSwapBuffers(dpy, win);
	}
	cleanupXWindows();
	cleanup_fonts();
	logClose();

	return 0;
}
Ejemplo n.º 13
0
int main(void)
{
    int done=0;
    srand(time(NULL));
    initXWindows();
    init_opengl();
    //declare game object
    Game game;
    game.n=0;

    //declare a box shape

    //First
    game.box[0].width = 100;
    game.box[0].height = 11;
    game.box[0].center.x = 65;
    game.box[0].center.y = 456;
    //Second
    game.box[1].width = 100;
    game.box[1].height = 11;
    game.box[1].center.x = 175;
    game.box[1].center.y = 385;
    //Third
    game.box[2].width = 100;
    game.box[2].height = 11;
    game.box[2].center.x = 285;
    game.box[2].center.y = 305;
    //Fourth
    game.box[3].width = 100;
    game.box[3].height = 11;
    game.box[3].center.x = 385;
    game.box[3].center.y = 215;
    //Fifth
    game.box[4].width = 100;
    game.box[4].height = 11;
    game.box[4].center.x = 485;
    game.box[4].center.y = 155;
    //Source  (Sixth)
    game.box[5].width = 75;
    game.box[5].height = 15;
    game.box[5].center.x = 0;
    game.box[5].center.y = 600;
    //Source 2 (Seventh)
    game.box[6].width = 70;
    game.box[6].height = 60;
    game.box[6].center.x = 5;
    game.box[6].center.y = 515;
    //LS-Glasses (Eighth)
    game.box[7].width = 40;
    game.box[7].height = 20;
    game.box[7].center.x = 650;
    game.box[7].center.y = 554;
    //Mid-Glasses (Ninth)
    game.box[8].width = 50;
    game.box[8].height = 8;
    game.box[8].center.x = 740;
    game.box[8].center.y = 554;
    //RS-Glasses (Tenth)
    game.box[9].width = 40;
    game.box[9].height = 20;
    game.box[9].center.x = 755;
    game.box[9].center.y = 554;
    //LS-Glasses Edge (Eleventh)
    game.box[10].width = 18;
    game.box[10].height = 8;
    game.box[10].center.x = 593;
    game.box[10].center.y = 565;
    //RS-Glasses Edge (Twelfth)
    game.box[11].width = 18;
    game.box[11].height = 8;
    game.box[11].center.x = 760;
    game.box[11].center.y = 565;






    game.circle.center.x = 720;
    game.circle.center.y = 546;
    game.circle.radius = 142;

    //SET WATER AT (1,580)

    //game.circle[1].center.x = ;
    //game.circle[1].center.y = ;
    //game.corcle[1].radius = 90;


    //start animation
    while(!done) {
        while(XPending(dpy)) {
            XEvent e;
            XNextEvent(dpy, &e);
            check_mouse(&e, &game);
            done = check_keys(&e, &game);

        }
        movement(&game);
        render(&game);
        glXSwapBuffers(dpy, win);
    }
    cleanupXWindows();
    cleanup_fonts();
    return 0;
}
Ejemplo n.º 14
0
/*
 * Initalize the named GDI printer. If the name is NULL, use the default
 * printer.
 */
static gdi_status_t
gdi_init(const char *printer_name, unsigned opts, const char **fail)
{
    char *default_printer_name;
    LPDEVMODE devmode;
    HDC dc;
    DOCINFO docinfo;
    DEVNAMES *devnames;
    int rmargin, bmargin; /* right margin, bottom margin */
    int maxphmargin, maxpvmargin;
    int i;
    static char get_fail[1024];
    int fheight, fwidth;

    memset(&pstate.dlg, '\0', sizeof(pstate.dlg));
    pstate.dlg.lStructSize = sizeof(pstate.dlg);
    pstate.dlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE |
	PD_NOSELECTION;

    if (printer_name == NULL || !*printer_name) {
	default_printer_name = get_default_printer_name(get_fail,
		sizeof(get_fail));
	if (default_printer_name == NULL) {
	    *fail = get_fail;
	    goto failed;
	}
	printer_name = default_printer_name;
    }
    if (!get_printer_device(printer_name, &pstate.dlg.hDevNames,
		&pstate.dlg.hDevMode)) {
	snprintf(get_fail, sizeof(get_fail),
		"GetPrinter(%s) failed: %s",
		printer_name, win32_strerror(GetLastError()));
	*fail = get_fail;
	goto failed;
    }
    if (uparm.orientation) {
	devmode = (LPDEVMODE)GlobalLock(pstate.dlg.hDevMode);
	devmode->dmFields |= DM_ORIENTATION;
	devmode->dmOrientation = uparm.orientation;
	GlobalUnlock(devmode);
    }

    if (opts & FPS_NO_DIALOG) {
	/* They don't want the print dialog. Allocate a DC for it. */
	devmode = (LPDEVMODE)GlobalLock(pstate.dlg.hDevMode);
	pstate.dlg.hDC = CreateDC("WINSPOOL", printer_name, NULL, devmode);
	GlobalUnlock(devmode);
	if (pstate.dlg.hDC == NULL) {
	    snprintf(get_fail, sizeof(get_fail), "Cannot create DC for "
		    "printer '%s'", printer_name);
	    *fail = get_fail;
	    goto failed;
	}
    } else {
	if (default_printer_name != NULL) {
	    Free(default_printer_name);
	    default_printer_name = NULL;
	}

	/* Pop up the dialog to get the printer characteristics. */
	if (!PrintDlg(&pstate.dlg)) {
	    return GDI_STATUS_CANCEL;
	}
    }
    dc = pstate.dlg.hDC;

    if (default_printer_name != NULL) {
	Free(default_printer_name);
	default_printer_name = NULL;
    }

    /* Find out the printer characteristics. */

    /* LOGPIXELSX and LOGPIXELSY are the pixels-per-inch for the printer. */
    pchar.ppiX = GetDeviceCaps(dc, LOGPIXELSX);
    if (pchar.ppiX <= 0) {
	*fail = "Can't get LOGPIXELSX";
	goto failed;
    }
    pchar.ppiY = GetDeviceCaps(dc, LOGPIXELSY);
    if (pchar.ppiY <= 0) {
	*fail = "Can't get LOGPIXELSY";
	goto failed;
    }

    /*
     * PHYSICALOFFSETX and PHYSICALOFFSETY are the fixed top and left-hand
     * margins, in pixels. Whatever you print is offset by these amounts, so
     * you have to subtract them from your coordinates. You cannot print in
     * these areas.
     */
    pchar.poffX = GetDeviceCaps(dc, PHYSICALOFFSETX);
    if (pchar.poffX < 0) {
	*fail = "Can't get PHYSICALOFFSETX";
	goto failed;
    }
    pchar.poffY = GetDeviceCaps(dc, PHYSICALOFFSETY);
    if (pchar.poffY < 0) {
	*fail = "Can't get PHYSICALOFFSETY";
	goto failed;
    }

    /*
     * HORZRES and VERTRES are the size of the usable area of the page, in
     * pixels. They implicitly give you the size of the right-hand and
     * bottom physical offsets.
     */
    pchar.horzres = GetDeviceCaps(dc, HORZRES);
    if (pchar.horzres <= 0) {
	*fail = "Can't get HORZRES";
	goto failed;
    }
    pchar.vertres = GetDeviceCaps(dc, VERTRES);
    if (pchar.vertres <= 0) {
	*fail = "Can't get VERTRES";
	goto failed;
    }

    /*
     * PHYSICALWIDTH and PHYSICALHEIGHT are the size of the entire area of
     * the page, in pixels.
     */
    pchar.pwidth = GetDeviceCaps(dc, PHYSICALWIDTH);
    if (pchar.pwidth <= 0) {
	*fail = "Can't get PHYSICALWIDTH";
	goto failed;
    }
    pchar.pheight = GetDeviceCaps(dc, PHYSICALHEIGHT);
    if (pchar.pheight <= 0) {
	*fail = "Can't get PHYSICALHEIGHT";
	goto failed;
    }

    /* Trace the device characteristics. */
    devnames = (DEVNAMES *)GlobalLock(pstate.dlg.hDevNames);
    vtrace("[gdi] Printer '%s' capabilities:\n",
	    (char *)devnames + devnames->wDeviceOffset);
    GlobalUnlock(devnames);
    vtrace("[gdi]  LOGPIXELSX %d LOGPIXELSY %d\n",
	    pchar.ppiX, pchar.ppiY);
    vtrace("[gdi]  PHYSICALOFFSETX %d PHYSICALOFFSETY %d\n",
	    pchar.poffX, pchar.poffY);
    vtrace("[gdi]  HORZRES %d VERTRES %d\n",
	    pchar.horzres, pchar.vertres);
    vtrace("[gdi]  PHYSICALWIDTH %d PHYSICALHEIGHT %d\n",
	    pchar.pwidth, pchar.pheight);

    /* Compute the scale factors (points to pixels). */
    pstate.xptscale = (FLOAT)pchar.ppiX / (FLOAT)PPI;
    pstate.yptscale = (FLOAT)pchar.ppiY / (FLOAT)PPI;

    /* Compute the implied right and bottom margins. */
    rmargin = pchar.pwidth - pchar.horzres - pchar.poffX;
    bmargin = pchar.pheight - pchar.vertres - pchar.poffY;
    if (rmargin > pchar.poffX) {
	maxphmargin = rmargin;
    } else {
	maxphmargin = pchar.poffX;
    }
    if (bmargin > pchar.poffY) {
	maxpvmargin = bmargin;
    } else {
	maxpvmargin = pchar.poffY;
    }
    vtrace("[gdi] maxphmargin is %d, maxpvmargin is %d pixels\n",
	    maxphmargin, maxpvmargin);

    /* Compute the margins in pixels. */
    pstate.hmargin_pixels = (int)(uparm.hmargin * pchar.ppiX);
    pstate.vmargin_pixels = (int)(uparm.vmargin * pchar.ppiY);

    /* See if the margins are too small. */
    if (pstate.hmargin_pixels < maxphmargin) {
	pstate.hmargin_pixels = maxphmargin;
	vtrace("[gdi] hmargin is too small, setting to %g\"\n",
		(float)pstate.hmargin_pixels / pchar.ppiX);
    }
    if (pstate.vmargin_pixels < maxpvmargin) {
	pstate.vmargin_pixels = maxpvmargin;
	vtrace("[gdi] vmargin is too small, setting to %g\"\n",
		(float)pstate.vmargin_pixels / pchar.ppiX);
    }

    /* See if the margins are too big. */
    if (pstate.hmargin_pixels * 2 >= pchar.horzres) {
	pstate.hmargin_pixels = pchar.ppiX;
	vtrace("[gdi] hmargin is too big, setting to 1\"\n");
    }
    if (pstate.vmargin_pixels * 2 >= pchar.vertres) {
	pstate.vmargin_pixels = pchar.ppiY;
	vtrace("[gdi] vmargin is too big, setting to 1\"\n");
    }

    /*
     * Compute the usable area in pixels. That's the physical page size
     * less the margins, now that we know that the margins are reasonable.
     */
    pstate.usable_xpixels = pchar.pwidth - (2 * pstate.hmargin_pixels);
    pstate.usable_ypixels = pchar.pheight - (2 * pstate.vmargin_pixels);
    vtrace("[gdi] usable area is %dx%d pixels\n",
	    pstate.usable_xpixels, pstate.usable_ypixels);

    /*
     * Create the Roman font.
     *
     * If they specified a particular font size, use that as the height,
     * and let the system pick the width.
     *
     * If they did not specify a font size, or chose "auto", then let the
     * "screens per page" drive what to do. If "screens per page" is set,
     * then divide the page Y pixels by the screens-per-page times the
     * display height to get the font height, and let the system pick the
     * width.
     *
     * Otherwise, divide the page X pixels by COLS to get the font width,
     * and let the system pick the height.
     */
    if (uparm.font_size) {
	/* User-specified fixed font size. */
	fheight = (int)(uparm.font_size * pstate.yptscale);
	fwidth = 0;
    } else {
	if (uparm.spp > 1) {
	    /*
	     * Scale the height so the specified number of screens will
	     * fit.
	     */
	    fheight = pstate.usable_ypixels /
		(uparm.spp * maxROWS /* spp screens */
		 + (uparm.spp - 1) /* spaces between screens */
		 + 2 /* space and caption*/ );
	    fwidth = 0;
	} else {
	    /*
	     * Scale the width so a screen will fit the page horizonally.
	     */
	    fheight = 0;
	    fwidth = pstate.usable_xpixels / maxCOLS;
	}
    }
    if (create_roman_font(dc, fheight, fwidth, fail) < 0) {
	goto failed;
    }

    /*
     * If we computed the font size, see if the other dimension is too
     * big. If it is, scale using the other dimension, which is guaranteed to
     * make the original computed dimension no bigger.
     *
     * XXX: This needs more testing.
     */
    if (!uparm.font_size) {
	if (fwidth == 0) {
	    /*
	     * We computed the height because spp > 1. See if the width
	     * overflows.
	     */
	    if (pstate.space_size.cx * maxCOLS > pstate.usable_xpixels) {
		vtrace("[gdi] font too wide, retrying\n");
		DeleteObject(pstate.font);
		pstate.font = NULL;

		fheight = 0;
		fwidth = pstate.usable_xpixels / maxCOLS;
		if (create_roman_font(dc, fheight, fwidth, fail) < 0) {
		    goto failed;
		}
	    }
	} else if (fheight == 0) {
	    /*
	     * We computed the width (spp <= 1). See if the height
	     * overflows.
	     */
	    if (pstate.space_size.cy * (maxROWS + 2) >
		    pstate.usable_xpixels) {
		vtrace("[gdi] font too high, retrying\n");
		DeleteObject(pstate.font);
		pstate.font = NULL;

		fheight = pstate.usable_xpixels / (maxROWS + 2);
		fwidth = 0;
		if (create_roman_font(dc, fheight, fwidth, fail) < 0) {
		    goto failed;
		}
	    }
	}
    }

    /* Create a bold font that is the same size, if possible. */
    pstate.bold_font = CreateFont(
	    pstate.space_size.cy,	/* height */
	    pstate.space_size.cx,	/* width */
	    0,			/* escapement */
	    0,			/* orientation */
	    FW_BOLD,		/* weight */
	    FALSE,			/* italic */
	    FALSE,			/* underline */
	    FALSE,			/* strikeout */
	    ANSI_CHARSET,		/* character set */
	    OUT_OUTLINE_PRECIS,	/* output precision */
	    CLIP_DEFAULT_PRECIS,	/* clip precision */
	    DEFAULT_QUALITY,	/* quality */
	    FIXED_PITCH|FF_DONTCARE,/* pitch and family */
	    uparm.font_name);	/* face */
    if (pstate.bold_font == NULL) {
	*fail = "CreateFont (bold) failed";
	goto failed;
    }

    /* Create an underscore font that is the same size, if possible. */
    pstate.underscore_font = CreateFont(
	    pstate.space_size.cy,	/* height */
	    pstate.space_size.cx,	/* width */
	    0,			/* escapement */
	    0,			/* orientation */
	    FW_NORMAL,		/* weight */
	    FALSE,			/* italic */
	    TRUE,			/* underline */
	    FALSE,			/* strikeout */
	    ANSI_CHARSET,		/* character set */
	    OUT_OUTLINE_PRECIS,	/* output precision */
	    CLIP_DEFAULT_PRECIS,	/* clip precision */
	    DEFAULT_QUALITY,	/* quality */
	    FIXED_PITCH|FF_DONTCARE,/* pitch and family */
	    uparm.font_name);	/* face */
    if (pstate.underscore_font == NULL) {
	*fail = "CreateFont (underscore) failed";
	goto failed;
    }

    /* Create a bold, underscore font that is the same size, if possible. */
    pstate.bold_underscore_font = CreateFont(
	    pstate.space_size.cy,	/* height */
	    pstate.space_size.cx,	/* width */
	    0,			/* escapement */
	    0,			/* orientation */
	    FW_BOLD,		/* weight */
	    FALSE,			/* italic */
	    TRUE,			/* underline */
	    FALSE,			/* strikeout */
	    ANSI_CHARSET,		/* character set */
	    OUT_OUTLINE_PRECIS,	/* output precision */
	    CLIP_DEFAULT_PRECIS,	/* clip precision */
	    DEFAULT_QUALITY,	/* quality */
	    FIXED_PITCH|FF_DONTCARE,/* pitch and family */
	    uparm.font_name);	/* face */
    if (pstate.bold_underscore_font == NULL) {
	*fail = "CreateFont (bold underscore) failed";
	goto failed;
    }

    /* Create a caption font. */
    pstate.caption_font = CreateFont(
	    pstate.space_size.cy,	/* height */
	    0,			/* width */
	    0,			/* escapement */
	    0,			/* orientation */
	    FW_NORMAL,		/* weight */
	    TRUE,			/* italic */
	    FALSE,			/* underline */
	    FALSE,			/* strikeout */
	    ANSI_CHARSET,		/* character set */
	    OUT_OUTLINE_PRECIS,	/* output precision */
	    CLIP_DEFAULT_PRECIS,	/* clip precision */
	    DEFAULT_QUALITY,	/* quality */
	    VARIABLE_PITCH|FF_DONTCARE,/* pitch and family */
	    "Times New Roman");	/* face */
    if (pstate.bold_underscore_font == NULL) {
	*fail = "CreateFont (bold underscore) failed";
	goto failed;
    }

    /* Set up the manual spacing array. */
    pstate.dx = Malloc(sizeof(INT) * maxCOLS);
    for (i = 0; i < maxCOLS; i++) {
	pstate.dx[i] = pstate.space_size.cx;
    }

    /* Fill in the document info. */
    memset(&docinfo, '\0', sizeof(docinfo));
    docinfo.cbSize = sizeof(docinfo);
    docinfo.lpszDocName = "wc3270 screen";

    /* Start the document. */
    if (StartDoc(dc, &docinfo) <= 0) {
	*fail = "StartDoc failed";
	goto failed;
    }

    return GDI_STATUS_SUCCESS;

failed:
    /* Clean up what we can and return failure. */
    if (default_printer_name != NULL) {
	Free(default_printer_name);
    }
    cleanup_fonts();
    return GDI_STATUS_ERROR;
}