View Single Post
Old 24 October 2018, 04:35   #105
NovaCoder
Registered User
 
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,400
Thanks guys

Thought the coders might like to see the before and after shots

Original SDL based renderer:

PHP Code:

enum SCREEN_TYPES    

    
SCREEN_SURFACE,
    
SCREEN_SURFACE_DDRAW,
    
SCREEN_OVERLAY,
    
SCREEN_OPENGL
};

enum PRIORITY_LEVELS {
    
PRIORITY_LEVEL_LOWER,
    
PRIORITY_LEVEL_NORMAL,
    
PRIORITY_LEVEL_HIGHER,
    
PRIORITY_LEVEL_HIGHEST
};


struct SDL_Block {
    
bool active;                            //If this isn't set don't draw
    
bool updating;
    
struct {
        
Bit32u width;
        
Bit32u height;
        
Bitu flags;
        
GFX_Modes mode;
        
double scalex,scaley;
        
GFX_ResetCallBack reset;
    } 
draw;
    
bool wait_on_error;
    
struct {
        
Bit32u width,height,bpp;
        
bool fixed;
        
bool fullscreen;
        
bool doublebuf;
        
SCREEN_TYPES type;
        
SCREEN_TYPES want_type;
        
double hwscale;
    } 
desktop;
    
struct {
        
PRIORITY_LEVELS focus;
        
PRIORITY_LEVELS nofocus;
    } 
priority;
    
SDL_Rect clip;
    
SDL_Surface surface;
    
SDL_Overlay overlay;
    
SDL_cond *cond;
    
struct {
        
bool autolock;
        
bool autoenable;
        
bool requestlock;
        
bool locked;
        
Bitu sensitivity;
    } 
mouse;
};

static 
SDL_Block sdl;


<
SNIP>

bool GFX_StartUpdate(Bit8u * & pixels,Bitu pitch) {
    if (!
sdl.active || sdl.updating) return false;
    
sdl.updating=true;
    switch (
sdl.desktop.type) {
    case 
SCREEN_SURFACE:
        if (
SDL_MUSTLOCK(sdl.surface)) {
            if (
SDL_LockSurface(sdl.surface)) {
//                LOG_MSG("SDL Lock failed");
                
sdl.updating=false;
                return 
false;
            }
        }
        
pixels=(Bit8u *)sdl.surface->pixels;
        
pixels+=sdl.clip.y*sdl.surface->pitch;
        
pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel;
        
pitch=sdl.surface->pitch;
        return 
true;
#if defined(HAVE_DDRAW_H) && defined(WIN32)
    
case SCREEN_SURFACE_DDRAW:
        if (
SDL_LockSurface(sdl.blit.surface)) {
//            LOG_MSG("SDL Lock failed");
            
sdl.updating=false;
            return 
false;
        }
        
pixels=(Bit8u *)sdl.blit.surface->pixels;
        
pitch=sdl.blit.surface->pitch;
        return 
true;
#endif
    
case SCREEN_OVERLAY:
        
SDL_LockYUVOverlay(sdl.overlay);
        
pixels=(Bit8u *)*(sdl.overlay->pixels);
        
pitch=*(sdl.overlay->pitches);
        return 
true;
#if C_OPENGL
    
case SCREEN_OPENGL:
        
pixels=(Bit8u *)sdl.opengl.framebuf;
        
pitch=sdl.opengl.pitch;
        return 
true;
#endif
    
}
    return 
false;
}

void GFX_EndUpdate(void) {
    
int ret;
    if (!
sdl.updating) return;
    
sdl.updating=false;
    switch (
sdl.desktop.type) {
    case 
SCREEN_SURFACE:
        if (
SDL_MUSTLOCK(sdl.surface)) {
            
SDL_UnlockSurface(sdl.surface);
        }
        
SDL_Flip(sdl.surface);
        break;
#if defined(HAVE_DDRAW_H) && defined(WIN32)
    
case SCREEN_SURFACE_DDRAW:
        if (
SDL_MUSTLOCK(sdl.blit.surface)) {
            
SDL_UnlockSurface(sdl.blit.surface);
        }
        
ret=IDirectDrawSurface3_Blt(
            
sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect,
            
sdl.blit.surface->hwdata->dd_surface,0,
            
DDBLT_WAITNULL);
        switch (
ret) {
        case 
DD_OK:
            break;
        case 
DDERR_SURFACELOST:
            
IDirectDrawSurface3_Restore(sdl.blit.surface->hwdata->dd_surface);
            break;
        default:
            
LOG_MSG("DDRAW:Failed to blit, error %X",ret);
        }
        
SDL_Flip(sdl.surface);
        break;
#endif
    
case SCREEN_OVERLAY:
        
SDL_UnlockYUVOverlay(sdl.overlay);
        
SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip);
        break;
#if C_OPENGL
    
case SCREEN_OPENGL:
        
glBindTexture(GL_TEXTURE_2Dsdl.opengl.texture);
        
glTexSubImage2D(GL_TEXTURE_2D000
                
sdl.draw.widthsdl.draw.heightGL_BGRA_EXT,
                
GL_UNSIGNED_INT_8_8_8_8_REVsdl.opengl.framebuf);
        
glCallList(sdl.opengl.displaylist);
        
SDL_GL_SwapBuffers();
        break;
#endif

    
}
}


void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry entries) {
    
/* I should probably not change the GFX_PalEntry :) */
    
if (sdl.surface->flags SDL_HWPALETTE) {
        if (!
SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) {
            
E_Exit("SDL:Can't set palette");
        }
    } else {
        if (!
SDL_SetPalette(sdl.surface,SDL_LOGPAL,(SDL_Color *)entries,start,count)) {
            
E_Exit("SDL:Can't set palette");
        }
    }
}


static 
Bit8u laltstate SDL_KEYUP;
static 
Bit8u raltstate SDL_KEYUP;


void GFX_Events() {
    
SDL_Event event;
    while (
SDL_PollEvent(&event)) {
        switch (
event.type) {
        case 
SDL_ACTIVEEVENT:
            if (
event.active.state SDL_APPINPUTFOCUS) {
                if (
event.active.gain) {
                    if (
sdl.desktop.fullscreen && !sdl.mouse.locked)
                        
CaptureMouse();    
                    
SetPriority(sdl.priority.focus);
                } else {
                    if (
sdl.mouse.locked
                        
CaptureMouse();    
                    
SetPriority(sdl.priority.nofocus);
                }
            }
            break;
        case 
SDL_MOUSEMOTION:
            
HandleMouseMotion(&event.motion);
            break;
        case 
SDL_MOUSEBUTTONDOWN:
        case 
SDL_MOUSEBUTTONUP:
            
HandleMouseButton(&event.button);
            break;
        case 
SDL_VIDEORESIZE:
//            HandleVideoResize(&event.resize);
            
break;
        case 
SDL_QUIT:
            throw(
0);
            break;
#ifdef WIN32
        
case SDL_KEYDOWN:
        case 
SDL_KEYUP:
            
// ignore event alt+tab
            
if (event.key.keysym.sym==SDLK_LALTlaltstate event.key.type;
            if (
event.key.keysym.sym==SDLK_RALTraltstate event.key.type;
            if (((
event.key.keysym.sym==SDLK_TAB)) &&
                ((
laltstate==SDL_KEYDOWN) || (raltstate==SDL_KEYDOWN))) break;
#endif

        
default:
            
void MAPPER_CheckEvent(SDL_Event event);
            
MAPPER_CheckEvent(&event);
        }
    }


New native AGA version:

PHP Code:

/** Global Hardware window */
static struct Window *_hardwareWindow NULL;


/** Hardware screen */
static struct Screen *_hardwareScreen NULL;


// Hardware double buffering.
static struct ScreenBuffer *_hardwareScreenBuffer[2];
static 
BYTE _currentScreenBuffer 0;



// AGA C2P.
static void *c2p[2] = {NULLNULL};

static 
UWORD emptypointer[] = {
  
0x00000x0000,    /* reserved, must be NULL */
  
0x00000x0000,     /* 1 row of image data */
  
0x00000x0000    /* reserved, must be NULL */
};

 

// These settings are for PAL HIGH RES!
#define AGA_VIDEO_DEPTH         8
#define AGA_MAX_VIDEO_WIDTH     640
#define AGA_MAX_VIDEO_HEIGHT    512



struct AGA_Block {
    
bool active;                            //If this isn't set don't draw
    
struct {
        
Bit32u width;
        
Bit32u height;
    } 
draw;
    
    
Bit8u surface;
};

static 
AGA_Block aga;




void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused){
    
// TODO - will be used by RTG version.
}



static 
struct ScreenCreateHardwareScreen(ULONG modeIdint widthint height) {
    return 
OpenScreenTags(NULL,
                     
SA_DepthAGA_VIDEO_DEPTH,
                     
SA_DisplayIDmodeId,
                     
SA_Top0,
                     
SA_Left0,
                     
SA_Widthwidth,
                     
SA_Heightheight,
                     
SA_TypeCUSTOMSCREEN,
                     
SA_QuietTRUE,
                     
SA_ShowTitleFALSE,
                     
SA_DraggableFALSE,
                     
SA_ExclusiveTRUE,
                     
SA_AutoScrollFALSE,
                     
TAG_END);
}

static 
struct WindowCreateHardwareWindow(int widthint height) {
    return 
OpenWindowTags(NULL,
                          
WA_Left0,
                        
WA_Top0,
                        
WA_Widthwidth,
                        
WA_Heightheight,
                        
SA_AutoScrollFALSE,
                        
WA_CustomScreen, (ULONG)_hardwareScreen,
                        
WA_BackdropTRUE,
                        
WA_BorderlessTRUE,
                        
WA_DragBarFALSE,
                        
WA_ActivateTRUE,
                        
WA_SimpleRefreshTRUE,
                        
WA_NoCareRefreshTRUE,
                        
WA_ReportMouseTRUE,
                        
WA_RMBTrapTRUE,
                          
WA_IDCMPIDCMP_RAWKEY|IDCMP_MOUSEMOVE|IDCMP_MOUSEBUTTONS,
                          
TAG_END);  
}

static 
void GFX_ResetMode() {
    
aga.draw.width=0;
    
aga.draw.height=0;

    if (
aga.surface) {
        
free(aga.surface);
        
aga.surface NULL;
    }

    if (
_hardwareWindow) {
        
ClearPointer(_hardwareWindow);
        
CloseWindow(_hardwareWindow);
        
_hardwareWindow NULL;
    }

    if (
_hardwareScreenBuffer[0]) {
        
ChangeScreenBuffer (_hardwareScreen_hardwareScreenBuffer[0]);
        
WaitTOF();
        
WaitTOF();
        
FreeScreenBuffer (_hardwareScreen_hardwareScreenBuffer[0]);
        
_hardwareScreenBuffer[0] = NULL;
    }

    if (
_hardwareScreenBuffer[1]) {
        
FreeScreenBuffer (_hardwareScreen_hardwareScreenBuffer[1]);
        
_hardwareScreenBuffer[1] = NULL;
    }


    if (
_hardwareScreen) {
        
CloseScreen(_hardwareScreen);
        
_hardwareScreen NULL;
    }

    if (
c2p[0]) {
        
c2p8_deinit_stub(c2p[0]);
        
c2p[0] = NULL;
    }

    if (
c2p[1]) {
        
c2p8_deinit_stub(c2p[1]);
        
c2p[1] = NULL;
    }
    
    
aga.active false;
}
 

void GFX_SetSize(Bitu widthBitu height) {
    
ULONG modeId INVALID_ID;
    
DisplayInfoHandle handle;
    
struct DisplayInfo dispinfo;
    
struct DimensionInfo dimsinfo;
    
#ifdef C_DEBUG        
    
LOG_DEBUG("GFX_SetSize(width=%d, height=%d)\n"widthheight);
#endif

    // Check args.
    
if (width == 0) {
        
LOG_ERROR("Width cannot be zero");
        
E_Exit("Failed to create a rendering output");
    }
    
    if (
height == 0) {
        
LOG_ERROR("Height cannot be zero");
        
E_Exit("Failed to create a rendering output");
    }
    
       if (
width AGA_MAX_VIDEO_WIDTH) {
        
LOG_ERROR("Width cannot be greater than %d"AGA_MAX_VIDEO_WIDTH);
        
E_Exit("Failed to create a rendering output");
    }

    if (
height AGA_MAX_VIDEO_HEIGHT) {
        
LOG_ERROR("Height cannot be greater than %d"AGA_MAX_VIDEO_HEIGHT);
        
E_Exit("Failed to create a rendering output");
    }
    
    if ((
aga.draw.width == width) && (aga.draw.height == height)) {
        
// Nothing to do...
#ifdef C_DEBUG
        
LOG_DEBUG("GFX_SetSize: Skipping pointless resolution switch");
#endif
        
return;
    }

    
// Free any existing mode.
    
GFX_ResetMode();
    
    
    
// Reset.
    
aga.draw.width=width;
    
aga.draw.height=height;

    
// Automatically choose the best mode.
    
modeId BestModeID(BIDTAG_NominalWidthwidth,
                    
BIDTAG_NominalHeightheight,
                    
BIDTAG_DesiredWidthwidth,
                    
BIDTAG_DesiredHeightheight,
                    
BIDTAG_DepthAGA_VIDEO_DEPTH,
                    
BIDTAG_MonitorIDPAL_MONITOR_ID,
                    
TAG_END);


    
// Verify the mode choosen.
    
if (modeId != INVALID_ID) {
        if ((
handle FindDisplayInfo(modeId)) == NULL) {
            
LOG_ERROR("Couldn't find Display Info for requested mode");
             
E_Exit("Failed to create a rendering output");
        }

        if (
GetDisplayInfoData(handle, (UBYTE *)&dispinfosizeof(dispinfo), DTAG_DISP,0) == 0) {
            
LOG_ERROR("Couldn't get Display Info Data for requested mode");
             
E_Exit("Failed to create a rendering output");
        }

        if (
GetDisplayInfoData(handle, (UBYTE *)&dimsinfosizeof(dimsinfo), DTAG_DIMS0) == 0) {
            
LOG_ERROR("Couldn't get Display Info Data for requested mode");
             
E_Exit("Failed to create a rendering output");
        }

        if (
dimsinfo.MaxDepth != AGA_VIDEO_DEPTH) {
           
modeId INVALID_ID;
        }

        if ((
dimsinfo.Nominal.MaxX 1) != width) {
           
modeId INVALID_ID;
        }

        if ((
dimsinfo.Nominal.MaxY 1) < height) {
           
modeId INVALID_ID;
        }
    }

    if (
modeId == INVALID_ID) {
        
LOG_ERROR("Couldn't find a Screen Mode for the requested resolution (%d * %d)\n"widthheight);
        
E_Exit("Failed to create a rendering output");
    }
    
    
    
_hardwareScreen CreateHardwareScreen(modeIdwidthheight);
    if (!
_hardwareScreen ) {
        
LOG_ERROR("Couldn't create a Hardware Screen for the requested mode");
        
E_Exit("Failed to create a rendering output");
    }     
    
    
// Setup double buffering.
    
_hardwareScreenBuffer[0] = AllocScreenBuffer (_hardwareScreenNULLSB_SCREEN_BITMAP);
    if (!
_hardwareScreenBuffer[0]) {
        
LOG_ERROR("Couldn't set up double buffering for the requested mode");
        
E_Exit("Failed to create a rendering output");
    }
    
    
_hardwareScreenBuffer[1] = AllocScreenBuffer (_hardwareScreenNULL0);    
    if (!
_hardwareScreenBuffer[1]) {
        
LOG_ERROR("Couldn't set up double buffering for the requested mode");
        
E_Exit("Failed to create a rendering output");
    }


    
_currentScreenBuffer 1;

    
// Setup C2P.    
    
c2p[0] = c2p8_reloc_stub(_hardwareScreenBuffer[0]->sb_BitMap);
    
c2p[1] = c2p8_reloc_stub(_hardwareScreenBuffer[1]->sb_BitMap);
    
    
    
// Create the hardware window.
    
_hardwareWindow CreateHardwareWindow(widthheight);
    if (!
_hardwareWindow) {
        
LOG_ERROR("Couldn't create a Hardware Window for the requested mode");
        
E_Exit("Failed to create a rendering output");
    }
    
    
SetPointer(_hardwareWindowemptypointer1100);
    
    
// Create a new chunky back buffer.
    
aga.surface = (Bit8u *)malloc(width height);
    if (!
aga.surface) {
        
LOG_ERROR("Couldn't allocate buffer for requested mode");
        
E_Exit("Failed to create a rendering output");
    }

    
memset(aga.surface0width height);
    
    
    
// Good to go!
    
aga.active true;
}

void GFX_UpdatePalette(Bitu numberOfEntriesBitu paletteDirtyStart,  GFX_PalEntry currentPalette) {

    
int i;
    
ULONG  agaPalette[numberOfEntries*2];
    
    if (
aga.active) {
        for ( 
i=0numberOfEntriesi++ ) {
            
agaPalette[i*3+1] = currentPalette[paletteDirtyStart i].r<<24;
            
agaPalette[i*3+2] = currentPalette[paletteDirtyStart i].g<<24;
            
agaPalette[i*3+3] = currentPalette[paletteDirtyStart i].b<<24;
        }
    
        
agaPalette[0] = (numberOfEntries << 16) + paletteDirtyStart;
    
        
// Terminator: NEEDED
        
agaPalette[((numberOfEntries 3) + 1)] = 0x00000000;
    
        
LoadRGB32(&_hardwareScreen->ViewPortagaPalette);
    }
}

bool GFX_StartUpdate(Bit8u * & pixels) {
    if (!
aga.active) {
        
// Just in case GFX_SetSize() hasn't been called yet.
       
return false;
    }

     
pixels aga.surface;

     return 
true;
}

void GFX_EndUpdate(void) {
    
c2p8_stub(c2p[_currentScreenBuffer], _hardwareScreenBuffer[_currentScreenBuffer]->sb_BitMap, (UBYTE*)aga.surface, (aga.draw.width aga.draw.height));

    if (
ChangeScreenBuffer(_hardwareScreen_hardwareScreenBuffer[_currentScreenBuffer])) {
        
// Flip.
       
_currentScreenBuffer _currentScreenBuffer 1;
    }
}


void GFX_Events() {
    if (
aga.active) {       
        
struct IntuiMessage *imsg;
        
        while (
imsg = (struct IntuiMessage *)GetMsg(_hardwareWindow->UserPort)) {
    
            
ReplyMsg((struct Message *)imsg);
     
            switch (
imsg->Class) {  
                case 
IDCMP_MOUSEMOVE:
                    
// TODO
                    
break;
     
    
                case 
IDCMP_MOUSEBUTTONS:
                    
// TODO
                    
break;
 
 
                case 
IDCMP_RAWKEY:
                    
int code imsg->Code;
    
    
                    
bool pressed = (code IECODE_UP_PREFIX) ? false true;
    
                    
code &= ~IECODE_UP_PREFIX;
                    
                    
    
                    
KEYBOARD_AddKey(keycode_lookup[code], pressed);
            }
        }
    }    
}

static 
void GUI_ShutDown(Section sec) {
    
LOG_DEBUG("GUI shutdown called");

    
// Free any existing mode.
    
GFX_ResetMode();

NovaCoder is offline  
 
Page generated in 0.06356 seconds with 11 queries