diff options
| author | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
|---|---|---|
| committer | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
| commit | 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch) | |
| tree | c28d0748652ad4b4222309e46e6cfc82c0906220 /examples/psxmod | |
| parent | a2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff) | |
| download | psxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz | |
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'examples/psxmod')
| -rw-r--r-- | examples/psxmod/Makefile | 16 | ||||
| -rw-r--r-- | examples/psxmod/psxmod.c | 472 |
2 files changed, 488 insertions, 0 deletions
diff --git a/examples/psxmod/Makefile b/examples/psxmod/Makefile new file mode 100644 index 0000000..7a410ec --- /dev/null +++ b/examples/psxmod/Makefile @@ -0,0 +1,16 @@ +PROJNAME = psxmod +PROJ_LIBS = -lmodplay -lm -ladpcm + +include ../project.mk + +SAMPLES = $(patsubst mods/%.mod, mods/%.smp, $(wildcard mods/*.mod)) + +$(PROJNAME)_extra: $(SAMPLES) + mkdir -p cd_root + cp -r mods cd_root + +$(PROJNAME)_clean_extra: + rm -f mods/*.smp + +mods/%.smp: mods/%.mod + mod4psx $< $@ diff --git a/examples/psxmod/psxmod.c b/examples/psxmod/psxmod.c new file mode 100644 index 0000000..f11f164 --- /dev/null +++ b/examples/psxmod/psxmod.c @@ -0,0 +1,472 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <psx.h> +#include <modplay.h> + +#if defined(EXAMPLES_VMODE) == VMODE_PAL + #define TICKS_PER_SECOND 50 +#else + #define TICKS_PER_SECOND 60 +#endif + +unsigned char fileBuffer[0x80000]; // 512 kilobytes + +unsigned int primList[0x8000]; +int dbuf = 0; +volatile int display_is_old = 1; +char current_dir[256] = "cdrom:"; +char name_buf[24]; +char name_buf2[32]; +ModMusic *music = NULL; +int music_loop; +char *music_player_fname; +int music_player_time; +short music_player_vol; +int music_player_vol_pc; + +GsRectangle prog_rect; + +void program_vblank_handler() +{ + display_is_old = 1; +} + +struct +{ + char name[20]; + int size; + int type; /* 0 = file, 1 = directory */ +}file_list[256]; + +int file_list_size = 0; +int file_list_pos = 0; + +int wasUp = 0; +int wasDown = 0; +int wasEnter = 0; +int wasLeft = 0; +int wasRight = 0; + +void update_file_list() +{ + struct DIRENTRY de; + struct DIRENTRY *r; + char *cp; + int i, k=0; + + if(strcmp(current_dir, "cdrom:") != 0) + { + strcpy(file_list[0].name, ".."); + file_list[0].type = 1; + k=1; + } + + r = firstfile("cdrom:*", &de); + + for(i = k; i < 256 && r; i++) + { + if(de.name[0] == 0x1) + { +// Throw away useless entry. + r = nextfile(&de); + i--; + continue; + } + + memcpy(file_list[i].name, de.name, 20); + + if((cp = strrchr(file_list[i].name, ';'))) + { + *cp = '\0'; + file_list[i].type = 0; + } + else + file_list[i].type = 1; + + file_list[i].size = de.size; + + r = nextfile(&de); + } + + file_list[i].size = -1; + file_list_size = i; +} + +void file_browser(int redraw) +{ + int i, k, ok, allowed_ext; + unsigned short padbuf; + char *cp; + FILE *f; + + PSX_ReadPad(&padbuf, NULL); + + if(wasUp) + wasUp++; + + if(wasDown) + wasDown++; + + if((padbuf & PAD_UP) && !wasUp) + { + if(file_list_pos > 0) + { + file_list_pos--; + redraw=1; + } + + wasUp=1; + } + + if((padbuf & PAD_DOWN) && !wasDown) + { + file_list_pos++; + + if(file_list[file_list_pos].size == -1) + file_list_pos--; + else + redraw = 1; + + wasDown = 1; + } + + if((padbuf & PAD_CROSS) && !wasEnter) + { + if(file_list[file_list_pos].type == 1) + allowed_ext = 1; + else + allowed_ext = 0; + + if((cp = strchr(file_list[file_list_pos].name, '.'))) + { + if(strcmp(cp+1, "MOD") == 0) + allowed_ext = 1; + } + + if(allowed_ext) + { + if(file_list[file_list_pos].type == 0) + { + if(music != NULL) + { + MODUnload(music); + music = NULL; + } + +// It is a file, we will play it + +// First check if there is a file which contains the +// samples + strcpy(name_buf, file_list[file_list_pos].name); + + if((cp = strchr(name_buf, '.'))) + *(cp+1) = '\0'; + + strcat(name_buf, "SMP"); + + ok = 0; + + if(!(padbuf & PAD_SELECT)) + { + for(i = 0; file_list[i].size != -1; i++) + { + if(strcmp(name_buf, file_list[i].name) == 0) + { + ok = 1; + break; + } + } + } + + if(ok) + { +// We found a sample file + printf("Loading sample file for %s...\n", + file_list[file_list_pos].name); + + sprintf(name_buf2, "cdrom:%s;1", name_buf); + printf("namebuf2=%s\n",name_buf2); + + f = fopen(name_buf2, "rb"); + + // printf("SZ = %d\n", file_list[i].size); + + fread(fileBuffer, sizeof(char), file_list[i].size, f); + fclose(f); + + memcpy(name_buf, fileBuffer, 8); + name_buf[8] = 0; + + MOD4PSX_Upload(fileBuffer, SPU_DATA_BASE_ADDR); + } + else + printf("No sample file found for %s!\n", + file_list[file_list_pos].name); + + sprintf(name_buf2, "cdrom:%s;1", file_list[file_list_pos].name); + + f = fopen(name_buf2, "rb"); + + fread(fileBuffer, sizeof(char), file_list[file_list_pos].size, f); + + fclose(f); + + music = MODLoadEx(fileBuffer, ok?MODLOAD_NOSAMPLES:0); + + if(!ok) + MODUploadSamples(music, SPU_DATA_BASE_ADDR); + + music_player_fname = file_list[file_list_pos].name; + music_player_time = 0; + music_player_vol = SPU_MAXVOL+1; + music_player_vol_pc = 100; + MODSetMaxVolume(music_player_vol-1); + music_loop = -1; + } + else + { +// It is a directory, we will go inside it + if(strcmp(file_list[file_list_pos].name, "..") == 0) + { + *(strrchr(current_dir, '\\')) = '\0'; + + if(strcmp(current_dir, "cdrom:") == 0) + chdir("cdrom:\\"); + else + chdir(current_dir); + } + else + { + strcat(current_dir, "\\"); + strcat(current_dir, file_list[file_list_pos].name); + chdir(current_dir); + } + + file_list_pos = 0; + update_file_list(); + redraw = 1; + } + } + + wasEnter = 1; + } + + if(!(padbuf & PAD_UP) || wasUp >= 15) + wasUp = 0; + if(!(padbuf & PAD_DOWN) || wasDown >= 15) + wasDown = 0; + if(!(padbuf & PAD_CROSS)) + wasEnter = 0; + + /* Drawing */ + if(!redraw) + return; + + + + GsSortCls(0, 0, 0); + GsPrintFont(0, 0, "-= PsxMod =-"); + GsPrintFont(0, 8, "Folder: <root>%s", current_dir + 6); + GsPrintFont(0, 16, "X to play, hold SELECT to convert SFX"); + + k=0; + + if(file_list_size > 24) + { + if(file_list_pos > 12) + { + k = file_list_pos - 12; + + if(k > (file_list_size - 26)) + k = file_list_size - 26; + } + } + + prog_rect.x = 0; + prog_rect.y = 32 + ((file_list_pos-k) * 8); + prog_rect.w = GsScreenW / 2; + prog_rect.h = 8; + prog_rect.r = 0; + prog_rect.g = 0; + prog_rect.b = 255; + prog_rect.attribute = 0; + GsSortRectangle(&prog_rect); + + for(i = 0; file_list[i+k].size != -1; i++) + { + if(file_list[i+k].type == 1) + GsPrintFont(0, 32 + (i * 8), " +- %s", file_list[i+k].name); + else + GsPrintFont(0, 32 + (i * 8), " %s", file_list[i+k].name); + } + + GsDrawList(); + + dbuf = !dbuf; + GsSetDispEnvSimple(0, dbuf?256:0); + GsSetDrawEnvSimple(0, dbuf?0:256, 320, 240); +} + +void music_player_draw() +{ + unsigned short padbuf; + static int old_song_pos = 10000; + int change_vol = 0; + + GsSortCls(0, 0, 0); + GsPrintFont(0, 0, "-= PsxMod =-"); + GsPrintFont(0, 8, "File: %s", music_player_fname); + GsPrintFont(0, 16, "Title: %s", music->title); + GsPrintFont(0, 24, "pat:%03d/%03d pos:%02X spd:%d/%d", + music->song_pos, music->song_pos_num - 1, music->pat_pos, + music->ticks_division, music->beats_minute); + + GsPrintFont(0, 32, "vol: %03d%%/100%% time: %d:%02d chn: %d", + music_player_vol_pc, music_player_time / (TICKS_PER_SECOND * 60), + (music_player_time % (TICKS_PER_SECOND * 60) ) / TICKS_PER_SECOND, + music->channel_num); + + GsPrintFont(0, 56, "Press X to change music."); + + dbuf = !dbuf; + GsSetDispEnvSimple(0, dbuf?256:0); + GsSetDrawEnvSimple(0, dbuf?0:256, 320, 240); + GsDrawList(); + + if(old_song_pos > music->song_pos) + music_player_time = 0; + + PSX_ReadPad(&padbuf, NULL); + + if(padbuf & PAD_UP) + { + music_player_vol+=32; + change_vol = 1; + } + + if(padbuf & PAD_DOWN) + { + music_player_vol-=32; + change_vol = 1; + } + + if(padbuf & PAD_LEFT) + { + if(!wasLeft) + { + music->pat_pos = 0; + + if(music->song_pos > 0) + music->song_pos--; + } + + wasLeft++; + } + + if(padbuf & PAD_RIGHT) + { + if(!wasRight) + { + music->pat_pos = 0; + + if(music->song_pos < (music->song_pos_num - 1)) + music->song_pos++; + else + music->song_pos = 0; + } + + wasRight++; + } + + if(!(padbuf & PAD_LEFT) || wasLeft >= 15) + wasLeft = 0; + + if(!(padbuf & PAD_RIGHT) || wasRight >= 15) + wasRight = 0; + + if((padbuf & PAD_CROSS) && !wasEnter) + { + MODStop(music); + MODUnload(music); + music = NULL; + wasEnter = 1; + } + + if(!(padbuf & PAD_CROSS)) + wasEnter = 0; + + if(music_player_vol < 0) + music_player_vol = 0; + + if(music_player_vol > (SPU_MAXVOL+1)) + music_player_vol = SPU_MAXVOL+1; + + if(change_vol) + { + music_player_vol_pc = (int)((float)100 * ((float)music_player_vol / (float)(SPU_MAXVOL+1))); + MODSetMaxVolume((music_player_vol == 0)?0:(music_player_vol-1)); + } + + music_player_time++; + + old_song_pos = music->song_pos; +} + +int main() +{ + int redraw=1; + FILE *f; + + PSX_Init(); + GsInit(); + SsInit(); + + GsClearMem(); + GsSetAutoWait(); + GsSetList(primList); + GsSetVideoMode(320, 240, EXAMPLES_VMODE); + GsLoadFont(768, 0, 768, 256); + + SetVBlankHandler(program_vblank_handler); + +// Open any existing file before calling firstfile() for the first time. +// If before calling firstfile() for the first time, you have never called open() on an existing file before, +// every subsequent read will fail but it will report that files are opened ok! +// This bug happens at least with the SCPH1001 BIOS version. +// We try to open PSX.EXE and SYSTEM.CNF, as one of them must exist in order to boot from CDROM. + + f = fopen("cdrom:PSX.EXE;1", "rb"); + if(f)fclose(f); + + f = fopen("cdrom:SYSTEM.CNF;1", "rb"); + if(f)fclose(f); + + update_file_list(); + + dbuf = !dbuf; + GsSetDispEnvSimple(0, dbuf?256:0); + GsSetDrawEnvSimple(0, dbuf?0:256, 320, 240); + + while(1) + { + if(display_is_old) + { + /* Update music */ + if(music) + { + redraw = 1; + MODPlay(music, &music_loop); + music_player_draw(); + } + else + { + file_browser(redraw); + redraw=0; + } + + display_is_old = 0; + } + } +} |
