color
This commit is contained in:
		
							parent
							
								
									8aecd02ea7
								
							
						
					
					
						commit
						6788c6f07b
					
				
					 2 changed files with 212 additions and 121 deletions
				
			
		| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
cmake_minimum_required(VERSION 3.5)
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
project(cgbwebcam)
 | 
					project(cgbwebcam)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(SDL_STATIC ON)
 | 
					set(SDL_STATIC ON)
 | 
				
			||||||
set(SDL_SHARED OFF)
 | 
					set(SDL_SHARED OFF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										227
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										227
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					#include "SDL_blendmode.h"
 | 
				
			||||||
#include "SDL_error.h"
 | 
					#include "SDL_error.h"
 | 
				
			||||||
#include "SDL_stdinc.h"
 | 
					#include "SDL_stdinc.h"
 | 
				
			||||||
#include "SDL_surface.h"
 | 
					#include "SDL_surface.h"
 | 
				
			||||||
| 
						 | 
					@ -17,19 +18,21 @@
 | 
				
			||||||
#include "mgba/feature/commandline.h"
 | 
					#include "mgba/feature/commandline.h"
 | 
				
			||||||
#include "mgba-util/image.h"
 | 
					#include "mgba-util/image.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NUM_CHANNELS 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SDL_Window* window = NULL;
 | 
					static SDL_Window* window = NULL;
 | 
				
			||||||
static SDL_Renderer* renderer = NULL;
 | 
					static SDL_Renderer* renderer = NULL;
 | 
				
			||||||
static SDL_Camera* camera = NULL;
 | 
					static SDL_Camera* camera = NULL;
 | 
				
			||||||
static SDL_CameraSpec spec;
 | 
					static SDL_CameraSpec spec;
 | 
				
			||||||
static SDL_Texture* texture = NULL;
 | 
					static SDL_Texture* textures[NUM_CHANNELS] = { NULL, NULL, NULL };
 | 
				
			||||||
static SDL_bool texture_updated = SDL_FALSE;
 | 
					static SDL_bool texture_updated = SDL_FALSE;
 | 
				
			||||||
static SDL_Surface* frame_current = NULL;
 | 
					 | 
				
			||||||
static SDL_CameraDeviceID front_camera = 0;
 | 
					static SDL_CameraDeviceID front_camera = 0;
 | 
				
			||||||
static SDL_CameraDeviceID back_camera = 0;
 | 
					static SDL_CameraDeviceID back_camera = 0;
 | 
				
			||||||
static SDL_Surface* scaled = NULL;
 | 
					static SDL_Surface* scaled = NULL;
 | 
				
			||||||
static SDL_Surface* screen = NULL;
 | 
					static SDL_Surface* filtered[NUM_CHANNELS] = { NULL, NULL, NULL };
 | 
				
			||||||
 | 
					static SDL_Surface* screens[NUM_CHANNELS] = { NULL, NULL, NULL };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mCore* core = NULL;
 | 
					static struct mCore* cores[NUM_CHANNELS] = { NULL, NULL, NULL };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum mColorFormat pixfmt_sdl_to_mgba(uint32_t sdl_fmt) {
 | 
					enum mColorFormat pixfmt_sdl_to_mgba(uint32_t sdl_fmt) {
 | 
				
			||||||
    switch (sdl_fmt) {
 | 
					    switch (sdl_fmt) {
 | 
				
			||||||
| 
						 | 
					@ -54,47 +57,90 @@ enum mColorFormat pixfmt_sdl_to_mgba(uint32_t sdl_fmt) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void myStartRequestImage(struct mImageSource* self, unsigned w, unsigned h, int colorFormats) {
 | 
					void myStartRequestImageRed(struct mImageSource* self, unsigned w, unsigned h, int colorFormats) {
 | 
				
			||||||
    SDL_DestroySurface(scaled);
 | 
					    SDL_DestroySurface(scaled);
 | 
				
			||||||
 | 
					    SDL_DestroySurface(filtered[0]);
 | 
				
			||||||
    scaled = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
					    scaled = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
				
			||||||
 | 
					    filtered[0] = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_Log("scaled: %d x %d", w, h);
 | 
					    SDL_Log("red: %d x %d", w, h);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
//    SDL_DestroyTexture(texture);
 | 
					//    SDL_DestroyTexture(texture);
 | 
				
			||||||
//    texture = SDL_CreateTextureFromSurface(renderer, scaled);
 | 
					//    texture = SDL_CreateTextureFromSurface(renderer, scaled);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void myStopRequestImage(struct mImageSource* self) {
 | 
					void myStartRequestImageGreen(struct mImageSource* self, unsigned w, unsigned h, int colorFormats) {
 | 
				
			||||||
 | 
					    SDL_DestroySurface(filtered[1]);
 | 
				
			||||||
 | 
					    filtered[1] = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
				
			||||||
 | 
					    SDL_Log("green: %d x %d", w, h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myStartRequestImageBlue(struct mImageSource* self, unsigned w, unsigned h, int colorFormats) {
 | 
				
			||||||
 | 
					    SDL_DestroySurface(filtered[2]);
 | 
				
			||||||
 | 
					    filtered[2] = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
				
			||||||
 | 
					    SDL_Log("blue: %d x %d", w, h);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myStopRequestImageRed(struct mImageSource* self) {
 | 
				
			||||||
    SDL_DestroySurface(scaled);
 | 
					    SDL_DestroySurface(scaled);
 | 
				
			||||||
 | 
					    SDL_DestroySurface(filtered[0]);
 | 
				
			||||||
    scaled = NULL;
 | 
					    scaled = NULL;
 | 
				
			||||||
 | 
					    filtered[0] = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void myRequestImage(struct mImageSource* self, const void** buf, size_t* stride, enum mColorFormat* fmt) {
 | 
					void myStopRequestImageGreen(struct mImageSource* self) {
 | 
				
			||||||
    if (scaled != NULL && frame_current != NULL) {
 | 
					    SDL_DestroySurface(filtered[1]);
 | 
				
			||||||
        struct SDL_Rect srcrect = frame_current->clip_rect;
 | 
					    filtered[1] = NULL;
 | 
				
			||||||
        int w = srcrect.h * scaled->clip_rect.w / scaled->clip_rect.h;
 | 
					}
 | 
				
			||||||
        if (w >= srcrect.w) {
 | 
					
 | 
				
			||||||
            srcrect.x = (srcrect.w - w) / 2;
 | 
					void myStopRequestImageBlue(struct mImageSource* self) {
 | 
				
			||||||
            srcrect.w = w;
 | 
					    SDL_DestroySurface(filtered[2]);
 | 
				
			||||||
        } else {
 | 
					    filtered[2] = NULL;
 | 
				
			||||||
            int h = srcrect.w * scaled->clip_rect.h / scaled->clip_rect.w;
 | 
					}
 | 
				
			||||||
            srcrect.y = (srcrect.h - h) / 2;
 | 
					
 | 
				
			||||||
            srcrect.h = h;
 | 
					void myRequestImageRed(struct mImageSource* self, const void** buf, size_t* stride, enum mColorFormat* fmt) {
 | 
				
			||||||
        }
 | 
					    SDL_Surface* source = filtered[0];
 | 
				
			||||||
        int res = SDL_BlitSurfaceScaled(frame_current, &srcrect, scaled, &scaled->clip_rect, SDL_SCALEMODE_NEAREST);
 | 
					    if (source != NULL) {
 | 
				
			||||||
        if (res != 0) {
 | 
					        *fmt = pixfmt_sdl_to_mgba(source->format->format);
 | 
				
			||||||
            SDL_Log("failed to scale: %s", SDL_GetError());
 | 
					        *stride = source->pitch / (BYTES_PER_PIXEL / source->format->bytes_per_pixel);
 | 
				
			||||||
        }
 | 
					        *buf = source->pixels;
 | 
				
			||||||
        *fmt = pixfmt_sdl_to_mgba(scaled->format->format);
 | 
					 | 
				
			||||||
        *stride = scaled->pitch / (BYTES_PER_PIXEL / scaled->format->bytes_per_pixel);
 | 
					 | 
				
			||||||
        *buf = scaled->pixels;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct mImageSource gb_img_src = {
 | 
					void myRequestImageGreen(struct mImageSource* self, const void** buf, size_t* stride, enum mColorFormat* fmt) {
 | 
				
			||||||
    .requestImage = myRequestImage,
 | 
					    SDL_Surface* source = filtered[1];
 | 
				
			||||||
    .startRequestImage = myStartRequestImage,
 | 
					    if (source != NULL) {
 | 
				
			||||||
    .stopRequestImage = myStopRequestImage,
 | 
					        *fmt = pixfmt_sdl_to_mgba(source->format->format);
 | 
				
			||||||
 | 
					        *stride = source->pitch / (BYTES_PER_PIXEL / source->format->bytes_per_pixel);
 | 
				
			||||||
 | 
					        *buf = source->pixels;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void myRequestImageBlue(struct mImageSource* self, const void** buf, size_t* stride, enum mColorFormat* fmt) {
 | 
				
			||||||
 | 
					    SDL_Surface* source = filtered[2];
 | 
				
			||||||
 | 
					    if (source != NULL) {
 | 
				
			||||||
 | 
					        *fmt = pixfmt_sdl_to_mgba(source->format->format);
 | 
				
			||||||
 | 
					        *stride = source->pitch / (BYTES_PER_PIXEL / source->format->bytes_per_pixel);
 | 
				
			||||||
 | 
					        *buf = source->pixels;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct mImageSource gb_img_src[3] = {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .requestImage = myRequestImageRed,
 | 
				
			||||||
 | 
					        .startRequestImage = myStartRequestImageRed,
 | 
				
			||||||
 | 
					        .stopRequestImage = myStopRequestImageRed,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .requestImage = myRequestImageGreen,
 | 
				
			||||||
 | 
					        .startRequestImage = myStartRequestImageGreen,
 | 
				
			||||||
 | 
					        .stopRequestImage = myStopRequestImageGreen,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .requestImage = myRequestImageBlue,
 | 
				
			||||||
 | 
					        .startRequestImage = myStartRequestImageBlue,
 | 
				
			||||||
 | 
					        .stopRequestImage = myStopRequestImageBlue,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SDL_AppInit(int argc, char *argv[]) {
 | 
					int SDL_AppInit(int argc, char *argv[]) {
 | 
				
			||||||
| 
						 | 
					@ -112,7 +158,8 @@ int SDL_AppInit(int argc, char *argv[]) {
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    core = mCoreFind(args.fname);
 | 
					    for (i = 0; i < NUM_CHANNELS; i++) {
 | 
				
			||||||
 | 
					        struct mCore* core = mCoreFind(args.fname);
 | 
				
			||||||
        if (!core || !core->init(core)) {
 | 
					        if (!core || !core->init(core)) {
 | 
				
			||||||
            SDL_Log("Couldn't initialize mgba core!");
 | 
					            SDL_Log("Couldn't initialize mgba core!");
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
| 
						 | 
					@ -132,8 +179,12 @@ int SDL_AppInit(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mCoreLoadConfig(core);
 | 
					        mCoreLoadConfig(core);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cores[i] = core;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned w, h;
 | 
					    unsigned w, h;
 | 
				
			||||||
    core->currentVideoSize(core, &w, &h);
 | 
					    // without loss of generality
 | 
				
			||||||
 | 
					    cores[0]->currentVideoSize(cores[0], &w, &h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) != 0) {
 | 
					    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) != 0) {
 | 
				
			||||||
        SDL_Log("Couldn't initialize SDL3: %s", SDL_GetError());
 | 
					        SDL_Log("Couldn't initialize SDL3: %s", SDL_GetError());
 | 
				
			||||||
| 
						 | 
					@ -185,62 +236,77 @@ int SDL_AppInit(int argc, char *argv[]) {
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_CameraSpec spec = {
 | 
					    SDL_CameraSpec init_spec = {
 | 
				
			||||||
        .format = SDL_PIXELFORMAT_XBGR1555,
 | 
					        .format = SDL_PIXELFORMAT_XBGR1555,
 | 
				
			||||||
        .width = 320,
 | 
					        .width = 320,
 | 
				
			||||||
        .height = 240,
 | 
					        .height = 240,
 | 
				
			||||||
        .interval_numerator = 1,
 | 
					        .interval_numerator = 1,
 | 
				
			||||||
        .interval_denominator = 30,
 | 
					        .interval_denominator = 30,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    camera = SDL_OpenCameraDevice(devid, &spec);
 | 
					    camera = SDL_OpenCameraDevice(devid, &init_spec);
 | 
				
			||||||
    if (!camera) {
 | 
					    if (!camera) {
 | 
				
			||||||
        SDL_Log("Failed to open camera device: %s", SDL_GetError());
 | 
					        SDL_Log("Failed to open camera device: %s", SDL_GetError());
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if BYTES_PER_PIXEL == 4
 | 
					#if BYTES_PER_PIXEL == 4
 | 
				
			||||||
    screen = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR8888);
 | 
					    uint32_t fmt = SDL_PIXELFORMAT_XBGR8888;
 | 
				
			||||||
#elif BYTES_PER_PIXEL == 2
 | 
					#elif BYTES_PER_PIXEL == 2
 | 
				
			||||||
    screen = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_XBGR1555);
 | 
					    uint32_t fmt = SDL_PIXELFORMAT_XBGR1555;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    #error "unknown pixel format"
 | 
					    #error "unknown pixel format"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    for (i = 0; i < NUM_CHANNELS; i++) {
 | 
				
			||||||
 | 
					        int j;
 | 
				
			||||||
 | 
					        struct mCore* core = cores[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SDL_Surface* screen = SDL_CreateSurface(w, h, fmt);
 | 
				
			||||||
        core->setVideoBuffer(core, screen->pixels, screen->pitch / BYTES_PER_PIXEL);
 | 
					        core->setVideoBuffer(core, screen->pixels, screen->pitch / BYTES_PER_PIXEL);
 | 
				
			||||||
 | 
					        screens[i] = screen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Create texture with appropriate format */
 | 
					        /* Create texture with appropriate format */
 | 
				
			||||||
    texture = SDL_CreateTextureFromSurface(renderer, screen);
 | 
					        SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, screens[0]);
 | 
				
			||||||
        if (!texture) {
 | 
					        if (!texture) {
 | 
				
			||||||
            SDL_Log("Couldn't create texture: %s", SDL_GetError());
 | 
					            SDL_Log("Couldn't create texture: %s", SDL_GetError());
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD);
 | 
				
			||||||
 | 
					        textures[i] = texture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, (void*)&gb_img_src);
 | 
					        core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, (void*)&gb_img_src[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        core->reset(core);
 | 
					        core->reset(core);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        core->setKeys(core, 0);
 | 
					        core->setKeys(core, 0);
 | 
				
			||||||
    for (i = 0; i < 600; i++) {
 | 
					        for (j = 0; j < 600; j++) {
 | 
				
			||||||
            core->runFrame(core);
 | 
					            core->runFrame(core);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        core->setKeys(core, 1); // title screen
 | 
					        core->setKeys(core, 1); // title screen
 | 
				
			||||||
        core->runFrame(core);
 | 
					        core->runFrame(core);
 | 
				
			||||||
        core->setKeys(core, 0);
 | 
					        core->setKeys(core, 0);
 | 
				
			||||||
    for (i = 0; i < 25; i++) {
 | 
					        for (j = 0; j < 25; j++) {
 | 
				
			||||||
            core->runFrame(core);
 | 
					            core->runFrame(core);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        core->setKeys(core, 1); // select 'shoot'
 | 
					        core->setKeys(core, 1); // select 'shoot'
 | 
				
			||||||
        core->runFrame(core);
 | 
					        core->runFrame(core);
 | 
				
			||||||
        core->setKeys(core, 0);
 | 
					        core->setKeys(core, 0);
 | 
				
			||||||
    for (i = 0; i < 75; i++) {
 | 
					        for (j = 0; j < 75; j++) {
 | 
				
			||||||
            core->runFrame(core);
 | 
					            core->runFrame(core);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        core->setKeys(core, 1); // select 'shoot' again
 | 
					        core->setKeys(core, 1); // select 'shoot' again
 | 
				
			||||||
        core->runFrame(core);
 | 
					        core->runFrame(core);
 | 
				
			||||||
        core->setKeys(core, 0);
 | 
					        core->setKeys(core, 0);
 | 
				
			||||||
    for (i = 0; i < 100; i++) {
 | 
					        for (j = 0; j < 100; j++) {
 | 
				
			||||||
            core->runFrame(core);
 | 
					            core->runFrame(core);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SDL_Log("prepared core %d", i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_SetTextureColorMod(textures[0], 255, 0, 0);
 | 
				
			||||||
 | 
					    SDL_SetTextureColorMod(textures[1], 0, 255, 0);
 | 
				
			||||||
 | 
					    SDL_SetTextureColorMod(textures[2], 0, 0, 255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;  /* start the main app loop. */
 | 
					    return 0;  /* start the main app loop. */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,11 +328,6 @@ static int FlipCamera(void) {
 | 
				
			||||||
        if (nextcam) {
 | 
					        if (nextcam) {
 | 
				
			||||||
            SDL_Log("Flip camera!");
 | 
					            SDL_Log("Flip camera!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (frame_current) {
 | 
					 | 
				
			||||||
                SDL_ReleaseCameraFrame(camera, frame_current);
 | 
					 | 
				
			||||||
                frame_current = NULL;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SDL_CloseCamera(camera);
 | 
					            SDL_CloseCamera(camera);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            camera = SDL_OpenCameraDevice(nextcam, NULL);
 | 
					            camera = SDL_OpenCameraDevice(nextcam, NULL);
 | 
				
			||||||
| 
						 | 
					@ -321,49 +382,77 @@ int SDL_AppEvent(const SDL_Event *event) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SDL_AppIterate(void) {
 | 
					int SDL_AppIterate(void) {
 | 
				
			||||||
    SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, 255);
 | 
					    int i;
 | 
				
			||||||
    SDL_RenderClear(renderer);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (scaled != NULL) {
 | 
				
			||||||
        Uint64 timestampNS = 0;
 | 
					        Uint64 timestampNS = 0;
 | 
				
			||||||
    SDL_Surface *frame_next = camera ? SDL_AcquireCameraFrame(camera, ×tampNS) : NULL;
 | 
					        SDL_Surface *frame = camera ? SDL_AcquireCameraFrame(camera, ×tampNS) : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (frame_next) {
 | 
					        if (frame) {
 | 
				
			||||||
        if (frame_current) {
 | 
					            //SDL_Log("new frame %d x %d %s", frame->w, frame->h, SDL_GetPixelFormatName(frame->format->format));
 | 
				
			||||||
            if (SDL_ReleaseCameraFrame(camera, frame_current) < 0) {
 | 
					            texture_updated = SDL_FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            struct SDL_Rect srcrect = frame->clip_rect;
 | 
				
			||||||
 | 
					            int w = srcrect.h * scaled->clip_rect.w / scaled->clip_rect.h;
 | 
				
			||||||
 | 
					            if (w >= srcrect.w) {
 | 
				
			||||||
 | 
					                srcrect.x = (srcrect.w - w) / 2;
 | 
				
			||||||
 | 
					                srcrect.w = w;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                int h = srcrect.w * scaled->clip_rect.h / scaled->clip_rect.w;
 | 
				
			||||||
 | 
					                srcrect.y = (srcrect.h - h) / 2;
 | 
				
			||||||
 | 
					                srcrect.h = h;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            int res = SDL_BlitSurfaceScaled(frame, &srcrect, scaled, &scaled->clip_rect, SDL_SCALEMODE_NEAREST);
 | 
				
			||||||
 | 
					            if (res != 0) {
 | 
				
			||||||
 | 
					                SDL_Log("failed to scale: %s", SDL_GetError());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (SDL_ReleaseCameraFrame(camera, frame) < 0) {
 | 
				
			||||||
                SDL_Log("err SDL_ReleaseCameraFrame: %s", SDL_GetError());
 | 
					                SDL_Log("err SDL_ReleaseCameraFrame: %s", SDL_GetError());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SDL_SetSurfaceColorMod(scaled, 255, 0, 0);
 | 
				
			||||||
 | 
					            SDL_BlitSurface(scaled, NULL, filtered[0], NULL);
 | 
				
			||||||
 | 
					            SDL_SetSurfaceColorMod(scaled, 0, 255, 0);
 | 
				
			||||||
 | 
					            SDL_BlitSurface(scaled, NULL, filtered[1], NULL);
 | 
				
			||||||
 | 
					            SDL_SetSurfaceColorMod(scaled, 0, 0, 255);
 | 
				
			||||||
 | 
					            SDL_BlitSurface(scaled, NULL, filtered[2], NULL);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SDL_Log("new frame %d x %d %s", frame_next->w, frame_next->h, SDL_GetPixelFormatName(frame_next->format->format));
 | 
					    for (i = 0; i < NUM_CHANNELS; i++) {
 | 
				
			||||||
        
 | 
					        struct mCore* core = cores[i];
 | 
				
			||||||
        /* It's not needed to keep the frame once updated the texture is updated.
 | 
					 | 
				
			||||||
         * But in case of 0-copy, it's needed to have the frame while using the texture.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
         frame_current = frame_next;
 | 
					 | 
				
			||||||
         texture_updated = SDL_FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        core->runFrame(core);
 | 
					        core->runFrame(core);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!texture_updated) {
 | 
				
			||||||
 | 
					        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
 | 
				
			||||||
 | 
					        SDL_RenderClear(renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Update SDL_Texture with last video frame (only once per new frame) */
 | 
					        /* Update SDL_Texture with last video frame (only once per new frame) */
 | 
				
			||||||
    if (frame_current && !texture_updated) {
 | 
					        for (i = 0; i < NUM_CHANNELS; i++) {
 | 
				
			||||||
//        if (scaled) SDL_UpdateTexture(texture, NULL, scaled->pixels, scaled->pitch);
 | 
					            SDL_Surface* screen = screens[i];
 | 
				
			||||||
 | 
					            SDL_Texture* texture = textures[i];
 | 
				
			||||||
            SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch);
 | 
					            SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch);
 | 
				
			||||||
            texture_updated = SDL_TRUE;
 | 
					            texture_updated = SDL_TRUE;
 | 
				
			||||||
 | 
					            SDL_RenderTexture(renderer, texture, NULL, NULL);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_RenderTexture(renderer, texture, NULL, NULL);
 | 
					 | 
				
			||||||
        SDL_RenderPresent(renderer);
 | 
					        SDL_RenderPresent(renderer);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;  /* keep iterating. */
 | 
					    return 0;  /* keep iterating. */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SDL_AppQuit(void) {
 | 
					void SDL_AppQuit(void) {
 | 
				
			||||||
    mCoreConfigDeinit(&core->config);
 | 
					    int i;
 | 
				
			||||||
    core->deinit(core);
 | 
					    for (i = 0; i < NUM_CHANNELS; i++) {
 | 
				
			||||||
 | 
					        mCoreConfigDeinit(&cores[i]->config);
 | 
				
			||||||
 | 
					        cores[i]->deinit(cores[i]);
 | 
				
			||||||
 | 
					        SDL_DestroyTexture(textures[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_ReleaseCameraFrame(camera, frame_current);
 | 
					 | 
				
			||||||
    SDL_CloseCamera(camera);
 | 
					    SDL_CloseCamera(camera);
 | 
				
			||||||
    SDL_DestroyTexture(texture);
 | 
					 | 
				
			||||||
    SDL_DestroyRenderer(renderer);
 | 
					    SDL_DestroyRenderer(renderer);
 | 
				
			||||||
    SDL_DestroyWindow(window);
 | 
					    SDL_DestroyWindow(window);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue