Skip to content

Commit

Permalink
Initial add.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Feb 21, 2019
0 parents commit 70088f3
Show file tree
Hide file tree
Showing 4 changed files with 7,841 additions and 0 deletions.
23 changes: 23 additions & 0 deletions LICENSE.txt
@@ -0,0 +1,23 @@

Copyright (c) 2019 Ryan C. Gordon.

This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be
appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.

Ryan C. Gordon <icculus@icculus.org>

3 changes: 3 additions & 0 deletions build.sh
@@ -0,0 +1,3 @@
#!/bin/bash

gcc -Wall -Os -o marquee-displaydaemon marquee-displaydaemon.c `sdl2-config --cflags --libs`
286 changes: 286 additions & 0 deletions marquee-displaydaemon.c
@@ -0,0 +1,286 @@
/**
* arcade1up-lcd-marquee; control an LCD in a Arcade1Up marquee.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/

#include <stdio.h>
#include "SDL.h"


//#define STBI_SSE2 1

#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 8)) /* ARMv8 always has NEON. */
#error sdfsdf
#define STBI_NEON 1
#endif

//#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ASSERT(x) SDL_assert(x)
#define STBI_MALLOC(x) SDL_malloc(x)
#define STBI_REALLOC(x,y) SDL_realloc(x, y)
#define STBI_FREE(x) SDL_free(x)
#include "stb_image.h"

static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_Texture *texture = NULL;
static int texturew = 0;
static int textureh = 0;
static Uint32 fadems = 500;

static void redraw_window(void)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
if (texture) { // fading in
SDL_RenderSetLogicalSize(renderer, texturew, textureh);
SDL_SetTextureAlphaMod(texture, 255);
SDL_RenderCopy(renderer, texture, NULL, NULL);
}
SDL_RenderPresent(renderer);
}

static void set_new_image(const char *fname)
{
SDL_Texture *newtex = NULL;
int w = 0;
int h = 0;

if (fname) {
int n;
stbi_uc *img = stbi_load(fname, &w, &h, &n, 4);
if (!img) {
fprintf(stderr, "WARNING: couldn't load image \"%s\"\n", fname);
} else {
newtex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
SDL_TEXTUREACCESS_STATIC, w, h);
if (!newtex) {
fprintf(stderr, "WARNING: couldn't create texture for \"%s\"\n", fname);
} else {
SDL_UpdateTexture(newtex, NULL, img, w * 4);
SDL_SetTextureBlendMode(newtex, SDL_BLENDMODE_BLEND);
}
stbi_image_free(img);
}
}

const Uint32 startms = SDL_GetTicks();
const Uint32 timeout = startms + fadems;
for (Uint32 now = startms; !SDL_TICKS_PASSED(now, timeout); now = SDL_GetTicks()) {
const float unclamped_percent = ((float) (now - startms)) / ((float) fadems);
const float percent = SDL_max(0.0f, SDL_min(unclamped_percent, 1.0f));

SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

if (texture) { // fading out
SDL_RenderSetLogicalSize(renderer, texturew, textureh);
SDL_SetTextureAlphaMod(texture, (Uint8) (255.0f * (1.0f - percent)));
SDL_RenderCopy(renderer, texture, NULL, NULL);
}

if (newtex) { // fading in
SDL_RenderSetLogicalSize(renderer, w, h);
SDL_SetTextureAlphaMod(newtex, (Uint8) (255.0f * percent));
SDL_RenderCopy(renderer, newtex, NULL, NULL);
}

SDL_RenderPresent(renderer);
SDL_Delay(10);
}

SDL_Texture *destroyme = texture;
texture = newtex;
texturew = w;
textureh = h;

// one last time, with no fade at all.
redraw_window();

if (destroyme) {
SDL_DestroyTexture(destroyme);
}
}

static void deinitialize(void)
{
if (texture) {
SDL_DestroyTexture(texture);
texture = NULL;
}

if (renderer) {
SDL_DestroyRenderer(renderer);
renderer = NULL;
}

if (window) {
SDL_DestroyWindow(window);
window = NULL;
}

SDL_Quit();
}

static SDL_bool initialize(const int argc, char **argv)
{
int displayidx = 1; // presumably a good default for our use case.
const char *initial_image = NULL;
Uint32 window_flags = SDL_WINDOW_FULLSCREEN_DESKTOP;
int width = 800;
int height = 480;

for (int i = 1; i < argc; i++) {
const char *arg = argv[i];
if (SDL_strcmp(arg, "--display") == 0) {
displayidx = SDL_atoi(argv[++i]);
} else if (SDL_strcmp(arg, "--width") == 0) {
width = SDL_atoi(argv[++i]);
} else if (SDL_strcmp(arg, "--height") == 0) {
height = SDL_atoi(argv[++i]);
} else if (SDL_strcmp(arg, "--fadems") == 0) {
fadems = (Uint32) SDL_atoi(argv[++i]);
} else if (SDL_strcmp(arg, "--windowed") == 0) {
window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
} else if (SDL_strcmp(arg, "--fullscreen") == 0) {
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else if (SDL_strcmp(arg, "--startimage") == 0) {
initial_image = argv[++i];
} else {
fprintf(stderr, "WARNING: Ignoring unknown command line option \"%s\"\n", arg);
}
}

if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "ERROR! SDL_Init(SDL_INIT_VIDEO) failed: %s\n", SDL_GetError());
return SDL_FALSE;
}

const char *driver = SDL_GetCurrentVideoDriver();
if (SDL_strcmp(driver, "rpi") != 0) {
fprintf(stderr, "\n\n"
"WARNING: %s:\n"
"WARNING: you aren't using SDL's \"rpi\" video target.\n"
"WARNING: (you are using \"%s\" instead.)\n"
"WARNING: This is probably _not_ what you wanted to do!\n\n\n",
argv[0], driver);
}

const int numdpy = SDL_GetNumVideoDisplays();
if (numdpy <= displayidx) {
const int replacement = numdpy - 1;
fprintf(stderr, "\n\n"
"WARNING: %s:\n"
"WARNING: We want display index %d, but there are only %d displays.\n"
"WARNING: Choosing index %d instead.\n"
"WARNING: This is probably _not_ what you wanted to do!\n\n\n",
argv[0], displayidx, numdpy, replacement);
displayidx = replacement;
}

window = SDL_CreateWindow("Arcade1Up LCD Marquee",
SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayidx),
SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayidx),
width, height, window_flags);
if (!window) {
fprintf(stderr, "ERROR! SDL_CreateWindow failed: %s\n", SDL_GetError());
return SDL_FALSE;
}

renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!renderer) {
fprintf(stderr, "WARNING! SDL_CreateRenderer(accel|vsync) failed: %s\n", SDL_GetError());
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
fprintf(stderr, "WARNING! SDL_CreateRenderer(accel) failed: %s\n", SDL_GetError());
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
fprintf(stderr, "ERROR! SDL_CreateRenderer(0) failed: %s\n", SDL_GetError());
fprintf(stderr, "Giving up.\n");
return SDL_FALSE;
}
}
}

#if 1
SDL_RendererInfo info;
SDL_zero(info);
SDL_GetRendererInfo(renderer, &info);
printf("SDL renderer target: %s\n", info.name);
#endif

SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT)
return SDL_FALSE;
}

set_new_image(initial_image);

return SDL_TRUE;
}

static SDL_bool iterate(void)
{
SDL_bool redraw = SDL_FALSE;
SDL_bool saw_event = SDL_FALSE;
char *newimage = NULL;

SDL_Event e;
while (SDL_PollEvent(&e)) {
saw_event = SDL_TRUE;
if (e.type == SDL_QUIT) {
fprintf(stderr, "Got SDL_QUIT event, quitting now...\n");
return SDL_FALSE;
} else if (e.type == SDL_WINDOWEVENT) {
if ( (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) ||
(e.window.event == SDL_WINDOWEVENT_EXPOSED) ) {
redraw = SDL_TRUE;
}
} else if (e.type == SDL_DROPFILE) {
SDL_free(newimage);
newimage = e.drop.file;
}
}

if (!saw_event) {
SDL_Delay(100);
} else if (newimage) {
set_new_image(newimage);
SDL_free(newimage);
} else if (redraw) {
redraw_window();
}

return SDL_TRUE;
}


int main(int argc, char **argv)
{
if (!initialize(argc, argv)) {
deinitialize();
return 1;
}

while (iterate()) {
// spin.
}

deinitialize();
return 0;
}

// end of marquee-displaydaemon.c ...

0 comments on commit 70088f3

Please sign in to comment.