view vptest.c @ 510:43ea59887c69

Start work on making C64 formats encoding possible by changing DMDecodeOps to DMEncDecOps and adding fields and op enums for custom encode functions, renaming, etc. Split generic op sanity checking into a separate function in preparation for its use in generic encoding function.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 19 Nov 2012 15:06:01 +0200
parents a4a6082a9055
children
line wrap: on
line source

#include "dmlib.h"
#include "dmargs.h"
#include "dmres.h"
#include "dmimage.h"
#include "dmtext.h"
#include "dmq3d.h"
#include "dmvecmat.h"
#include <math.h>

#define DM_COLORS (256)

char *optFontFile = "font.ttf",
     *optBitmapFilename = "blurri.png";
BOOL optBenchmark = FALSE;
int optVFlags = SDL_SWSURFACE | SDL_HWPALETTE;
int optScrWidth = 640, optScrHeight = 480, optFontSize = 8, optScrDepth = 32;
int optBenchmarkLen = 20;

DMOptArg optList[] = {
    { 0, '?', "help",       "Show this help", OPT_NONE },
    { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
    { 3, 'f', "full",       "Fullscreen", OPT_NONE },
    { 4, 'h', "hw",         "Use SDL hardware surface", OPT_NONE },
    { 5, 's', "size",       "Initial window size/resolution -s 640x480", OPT_ARGREQ },
    { 6, 'd', "depth",      "Color depth of mode/window in bits (8/15/16/32)", OPT_ARGREQ },
    { 7, 'b', "bench",      "Run in benchmark mode", OPT_NONE },
};

const int optListN = sizeof(optList) / sizeof(optList[0]);


void argShowHelp()
{
    dmArgsPrintHelp(stdout, optList, optListN);
}


BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
{
    switch (optN) {
    case 0:
        argShowHelp();
        exit(0);
        break;

    case 2:
        dmVerbosity++;
        break;
    
    case 3:
        optVFlags |= SDL_FULLSCREEN;
        break;

    case 6:
        if (optArg)
            optScrDepth = atoi(optArg);
        break;

    case 5:
        {
            int w, h;
            if (sscanf(optArg, "%dx%d", &w, &h) == 2)
            {
                if (w < 320 || h < 200 || w > 3200 || h > 3200)
                {
                    dmError("Invalid width or height: %d x %d\n", w, h);
                    return FALSE;
                }
                optScrWidth = w;
                optScrHeight = h;
            }
            else 
            {
                dmError("Invalid size argument '%s'.\n", optArg);
                return FALSE;
            }
        }
        break;

    case 7:
        optBenchmark = TRUE;
        break;

    default:
        dmError("Unknown option '%s'.\n", currArg);
        return FALSE;
    }
    
    return TRUE;
}


void DM_PrintRect(FILE *f, SDL_Rect *r)
{
    fprintf(f, "SDL_Rect <%d, %d : %d, %d>\n",
        r->x, r->y, r->w, r->h);
}


BOOL DM_InitializeVideo(SDL_Surface **screen)
{
    *screen = SDL_SetVideoMode(optScrWidth, optScrHeight, optScrDepth, optVFlags | SDL_RESIZABLE);
    if (*screen == NULL)
    {
        dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError());
        return FALSE;
    }
    return TRUE;
}


int main(int argc, char *argv[])
{
    SDL_Surface *screen = NULL, *bmap = NULL, *fbmap = NULL, *screen2 = NULL;
    SDL_Color fontcol = { 255, 155, 155, 0 };
    SDL_Event event;
    TTF_Font *font = NULL;
    int mouseX, mouseY, bx, by, err;
    BOOL initSDL = FALSE, initTTF = FALSE, exitFlag;
    DM3DVectorSpriteModel *model, *model2;
    
    dmVerbosity = 5;
    if (!dmArgsProcess(argc, argv, optList, optListN,
        argHandleOpt, NULL, FALSE))
        exit(1);

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
    {
        dmError("Could not initialize SDL: %s\n", SDL_GetError());
        goto error_exit;
    }
    initSDL = TRUE;


    if (TTF_Init() < 0)
    {
        dmError("Could not initialize FreeType/TTF: %s\n", SDL_GetError());
        goto error_exit;
    }
    initTTF = TRUE;

    font = TTF_OpenFont(optFontFile, optFontSize);
    if (font == NULL)
    {
        dmError("Could not load TTF font '%s' (%d): %s\n",
            optFontFile, optFontSize, SDL_GetError());
        goto error_exit;
    }
    TTF_SetFontStyle(font, TTF_STYLE_NORMAL);

    DMResource *res = dmf_create_stdio(optBitmapFilename, "rb");
    if (res == NULL)
    {
        dmError("Could not open resource file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }
    bmap = dmLoadImage(res);
    dmf_close(res);
    if (bmap == NULL)
    {
        dmError("Could not load image file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }

    res = dmf_create_stdio("trans6x6.png", "rb");
    if (res == NULL)
    {
        dmError("Could not open resource file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }
    fbmap = dmLoadImage(res);
    dmf_close(res);
    if (fbmap == NULL)
    {
        dmError("Could not load image file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }
    
    
    res = dmf_create_stdio("mole.3d", "r");
    if (res == NULL)
    {
        dmError("Could not open resource file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }
    err = dmRead3DVectorSpriteModel(res, &model);
    dmf_close(res);
    dmMsg(0, "Loaded, %d: %s\n", err, dmErrorStr(err));

    res = dmf_create_stdio("roto.3d", "r");
    if (res == NULL)
    {
        dmError("Could not open resource file '%s'.\n", optBitmapFilename);
        goto error_exit;
    }
    err = dmRead3DVectorSpriteModel(res, &model2);
    dmf_close(res);
    dmMsg(0, "Loaded, %d: %s\n", err, dmErrorStr(err));
    
    if (optBenchmark)
    {
        screen = SDL_CreateRGBSurface(SDL_SWSURFACE, optScrWidth, optScrHeight, optScrDepth, 0, 0, 0, 0);
        if (screen == NULL)
        {
            dmError("Could not create screen surface.\n");
            goto error_exit;
        }
        
        dmMsg(0, "Benchmark mode, not opening window.\n");
    }
    else
    {
        if (!DM_InitializeVideo(&screen))
            goto error_exit;

        SDL_WM_SetCaption("Halleluja", "DMT");
    }

    screen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, optScrWidth, optScrHeight, optScrDepth, 0, 0, 0, 0);
    Uint32 lcol = dmMapRGB(screen, 255,255,255);

    int numFrames = 0, startTime = SDL_GetTicks(), endTime = 0;
    exitFlag = FALSE;

    if (optBenchmark)
        dmMsg(0, "Starting benchmark, running for %d seconds.\n", optBenchmarkLen);

    while (!exitFlag)
    {
        if (!optBenchmark)
        {
            while (SDL_PollEvent(&event))
            switch (event.type)
            {
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_ESCAPE: exitFlag = TRUE; break;
                            
                        default:
                            break;
                    }

                    break;
                
                case SDL_VIDEORESIZE:
                    optScrWidth = event.resize.w;
                    optScrHeight = event.resize.h;

                    if (!DM_InitializeVideo(&screen))
                        goto error_exit;

                    break;
                
                case SDL_VIDEOEXPOSE:
                    break;

                case SDL_QUIT:
                    exit(0);
            }

            SDL_GetMouseState(&mouseX, &mouseY);
            bx = 300 - ((DMFloat) mouseX * 500.0f ) / (DMFloat) optScrWidth;
            by = 300 - ((DMFloat) mouseY * 500.0f ) / (DMFloat) optScrHeight;
        }
        else
        {
            bx = 0;
            by = 0;
        }

        if (!optBenchmark && SDL_MUSTLOCK(screen) != 0 && SDL_LockSurface(screen) != 0)
        {
            dmError("Can't lock surface.\n");
            goto error_exit;
        }


        dmClearSurface(screen, 0);

        float f = SDL_GetTicks() / 150.0f,
              qw2 = (float) 132.0 * (1.0 + sin(f) * 0.1),
              qh2 = (float) 132.0 * (1.0 + sin(f) * 0.1);

#if 1
        dmScaledBlitSurfaceAny(bmap, bx-qw2, by-qh2, bmap->w+qw2, bmap->h+qh2, screen,
        DMD_TRANSPARENT
//        DMD_SATURATE
//        DMD_NONE
        );
#endif
#if 0
        float qw = (float) 32.0 * (1.0 + sin(f) * 0.1),
              qh = (float) 32.0 * (1.0 + sin(f) * 0.1),
        dmScaledBlitSurface32to32TransparentGA(bmap, bx*2-qw, by*2-qh, bmap->w+qw, bmap->h+qh, screen,
            128 + sin(f*0.1) * 120.0f);
#endif

#if 1
        DMVector pos;
        
        DMMatrix mat;
//        dm_matrix_rot_a(&mat, f*0.1, 0, (3.1415926535f * 2.0f * ((DMFloat) mouseX + (DMFloat) mouseY) ) / 500.0f);
//        dm_matrix_rot_a(&mat, f*0.1, f*0.1, f*0.1);
        dm_matrix_rot_a(&mat, 0, 0, f*0.1);

        pos.x = -118;
        pos.y = 0;
        pos.z = 100;
 
        dmDraw3DVectorSpriteModel(screen, model2, &pos, &mat, fbmap, lcol);

        pos.x = 118;
        pos.y = 0;
        pos.z = 100;

        dm_matrix_rot_a(&mat, 0, 0, -f*0.1+0.125);
        dmDraw3DVectorSpriteModel(screen, model2, &pos, &mat, fbmap, lcol);


#endif

#if 0
        int np;
        dmClearSurface(screen2, 0);
        for (np = 1; np <= 5; np++)
        {
            float n = ((float) np - 0.5f) * np;
            dmScaledBlitSurface32to32TransparentGA(screen, -n, -n, screen->w + n*2.0f, screen->h + n*2.0f, screen2,
            210 - np * 10
            );
            dmDirectBlitSurface(screen2, screen);
        }

        dmDraw3DVectorSpriteModel(screen, model, &pos, &mat, fbmap, lcol);

        for (np = 1; np <= 5; np++)
        {
            float n = ((float) np - 0.5f) / 2.0f;
            dmScaledBlitSurface32to32TransparentGA(screen, -n, -n, screen->w + n*2.0f, screen->h + n*2.0f, screen2,
            210 - np * 10
            );
            dmDirectBlitSurface(screen2, screen);
        }

#endif

        if (!optBenchmark)
        {
            dmDrawTTFText(screen, font, fontcol, 0, 0, "%3.1f FPS", 
                (float) (numFrames * 1000.0f) / (float) (endTime - startTime));

            if (SDL_MUSTLOCK(screen) != 0)
                SDL_UnlockSurface(screen);

            SDL_Flip(screen);
            SDL_Delay(25);
        }

        endTime = SDL_GetTicks();
        numFrames++;

        if (optBenchmark)
        {
            if (endTime - startTime > optBenchmarkLen * 1000)
                exitFlag = TRUE;
        }
    }

    // Print benchmark results
    dmMsg(0, "%d frames in %d ms, fps = %1.3f\n",
        numFrames, endTime - startTime,
        (float) (numFrames * 1000.0f) / (float) (endTime - startTime));


error_exit:
    dmMsg(0, "Shutting down dmlib.\n");
    if (screen)
        SDL_FreeSurface(screen);

    if (bmap)
        SDL_FreeSurface(bmap);

    if (font)
        TTF_CloseFont(font);

    if (initSDL)
        SDL_Quit();

    if (initTTF)
        TTF_Quit();

    return 0;
}