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.

201 lines
4.5 KiB
C

#include <SDL.h>
#include <xmp.h>
#include <stdbool.h>
#include <stdio.h>
#include <SDL_image.h>
// Fanta <fanta@56k.es> 2026
// Presentator 0.1
// 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.1";
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;
// 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;
fp = fopen(slidesIndex, "r");
while ((read = getline(&line, &len, fp)) != -1) {
if (nslide == nline){
actualSlide = line;
actualSlide[ strlen(actualSlide) - 1 ] = '\0';
SDL_Rect textureSlideRect = { 0, 0, windowWidth, windowHeight };
IMG_Init(IMG_INIT_PNG);
textureSlide = IMG_LoadTexture(render, actualSlide);
SDL_RenderCopy(render, textureSlide, NULL, &textureSlideRect);
}
nline = nline +1;
}
fclose(fp);
nline = nline - 1;
if (line){ free(line); };
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;
renderAll();
break;
case SDLK_LEFT:
actualNSlide = actualNSlide - 1;
renderAll();
break;
}
break;
}
}
}