You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
5.7 KiB
C

#include <SDL.h>
#include <xmp.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL_image.h>
// Fanta <fanta@56k.es> 2026
// Presentator 0.2
// Variables
int modPlaying;
char * modName = NULL;
int modVolume = 100;
int iv;
char *imgVol[] = {"res/vol100.png","res/vol090.png","res/vol080.png","res/vol070.png","res/vol060.png","res/vol050.png","res/vol040.png","res/vol030.png","res/vol020.png","res/vol010.png","res/vol000.png"};
char windowTitle[16] = "Presentator 0.2";
int windowWidth = 1024;
int windowHeight = 768;
char * slidesIndex = "slides/index.txt";
char * actualSlide = NULL;
int actualNSlide = 1;
bool quit = false;
SDL_Window * window;
SDL_Renderer * render;
SDL_Texture *textureVolume = NULL;
SDL_Texture *textureSlide = NULL;
SDL_Texture *textureProgressRect = NULL;
SDL_Event evento;
xmp_context ctx;
int transition_active = 0;
// Functions
int createWindow(void){
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow(windowTitle,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,windowWidth,windowHeight,SDL_WINDOW_FULLSCREEN);
render = SDL_CreateRenderer(window, -1, 0);
return 0;
}
int refreshVolumeArea(int iv){
SDL_Rect textureVolumeRect1 = { 0, 0, 398, 68 };
SDL_Rect textureVolumeRect2 = { 910, 20, 100, 20 };
IMG_Init(IMG_INIT_PNG);
textureVolume = IMG_LoadTexture(render, imgVol[iv]);
SDL_RenderCopy(render, textureVolume, &textureVolumeRect1, &textureVolumeRect2);
return 0;
}
static void playBuffer(void *udata, Uint8 *stream, int len)
{
if (xmp_play_buffer((xmp_context)udata, stream, len, 0) < 0){ modPlaying = 0; }
}
static int initAudio(xmp_context ctx) {
SDL_AudioSpec a;
a.freq = 44100;
a.format = AUDIO_S16;
a.channels = 2;
a.samples = 2048;
a.callback = playBuffer;
a.userdata = ctx;
if (SDL_OpenAudio(&a, NULL) < 0) { printf("error inicializando audio: %s\n", SDL_GetError()); return 1; }
return 0;
}
void loadMod(char *modPath){
modName = modPath;
ctx = xmp_create_context();
xmp_load_module(ctx, modName);
xmp_start_player(ctx, 44100, 0);
xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
initAudio(ctx);
modPlaying = 1;
SDL_PauseAudio(0);
}
int stopMod(void){
xmp_end_player(ctx);
xmp_free_context(ctx);
SDL_CloseAudio();
return 0;
}
int loadSlide(int nslide){
FILE * fp;
char * line = NULL;
size_t len = 0;
int nline = 1;
ssize_t read;
int slideType;
char * slideName;
fp = fopen(slidesIndex, "r");
while ((read = getline(&line, &len, fp)) != -1) {
if (nslide == nline){
actualSlide = line;
char *token = strtok(actualSlide, ";");
int e;
for (e = 0; e < 2; e++) {
if (e == 0){ slideType = atoi(token); }
if (e == 1){ slideName = token; slideName[ strlen(slideName) - 1 ] = '\0';}
token = strtok(NULL, ";");
}
printf("%i %s\n", slideType, slideName);
actualSlide[ strlen(actualSlide) - 1 ] = '\0';
SDL_Rect textureSlideRect = { 0, 0, windowWidth, windowHeight };
IMG_Init(IMG_INIT_PNG);
if (slideType == 0){ textureSlide = IMG_LoadTexture(render, slideName); } // png
if (slideType == 1){ textureSlide = IMG_LoadTexture(render, slideName); } // gif incompleto ahora mismo pero ya detectado
SDL_RenderCopy(render, textureSlide, NULL, &textureSlideRect);
}
nline = nline +1;
}
fclose(fp);
nline = nline - 1;
if (line){ free(line); };
return 0;
}
int transition_BackToBlack(void){
SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
SDL_Rect barra = { 0, 0, windowWidth, windowHeight };
int z;
for (z = 250; z > 0; z = z -10) {
loadSlide(actualNSlide);
refreshVolumeArea(iv);
SDL_SetRenderDrawColor(render, 0, 0, 0, z);
SDL_RenderFillRect(render, &barra);
SDL_RenderPresent(render);
}
return 0;
}
int renderAll(void){
loadSlide(actualNSlide);
refreshVolumeArea(iv);
SDL_RenderPresent(render);
return 0;
}
// Main
int main(int argc, char ** argv) {
createWindow();
loadMod("mods/001.mod");
loadSlide(1);
refreshVolumeArea(0);
SDL_RenderPresent(render);
while (!quit) {
SDL_WaitEvent(&evento);
switch (evento.type) {
case SDL_KEYDOWN:
switch (evento.key.keysym.sym) {
case SDLK_q:
stopMod();
quit = true;
break;
case SDLK_DOWN:
if(modVolume > 0) {
modVolume = modVolume - 10;
xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
iv = iv + 1;
renderAll();
}
break;
case SDLK_UP:
if(modVolume < 100) {
modVolume = modVolume + 10;
xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
iv = iv - 1;
renderAll();
}
break;
case SDLK_1:
stopMod();
loadMod("mods/001.mod");
break;
case SDLK_2:
stopMod();
loadMod("mods/002.mod");
break;
case SDLK_3:
stopMod();
loadMod("mods/003.xm");
break;
case SDLK_4:
stopMod();
loadMod("mods/004.xm");
break;
case SDLK_5:
stopMod();
loadMod("mods/005.mod");
break;
case SDLK_6:
stopMod();
loadMod("mods/006.mod");
break;
case SDLK_7:
stopMod();
loadMod("mods/007.mod");
break;
case SDLK_8:
stopMod();
loadMod("mods/008.mod");
break;
case SDLK_9:
stopMod();
loadMod("mods/009.mod");
break;
case SDLK_RIGHT:
actualNSlide = actualNSlide + 1;
if (transition_active == 1 ){ transition_BackToBlack(); };
renderAll();
break;
case SDLK_LEFT:
actualNSlide = actualNSlide - 1;
if (transition_active == 1 ){ transition_BackToBlack(); };
renderAll();
break;
case SDLK_F1:
if (transition_active == 0){
transition_active = 1;
}else{
transition_active = 0;
}
break;
}
break;
}
}
}