added lib files

master
lerabot 4 years ago
parent b677d1a31b
commit b9d9a336fb
  1. BIN
      1ST_READ.BIN
  2. 6
      Makefile.pc
  3. 6340
      cdi4dc.log
  4. 97
      libdcmc/pvr_driver.h
  5. 239
      libdcmc/pvrdrv.c
  6. 175
      libdcmc/snddrv.c
  7. 115
      libdcmc/snddrv.h
  8. 44
      makeCD.sh
  9. BIN
      sample.roq

Binary file not shown.

@ -0,0 +1,6 @@
all: test-dreamroq
test-dreamroq: test-dreamroq.o dreamroqlib.o
clean:
rm -f *.o test-dreamroq

File diff suppressed because it is too large Load Diff

@ -0,0 +1,97 @@
/*
**
** PVR Video Driver
** (C) Josh "PH3NOM" Pearson 2011-2012
**
*/
#ifndef PVR_DRIVER_H
#define PVR_DRIVER_H
#include <dc/pvr.h>
#include <dc/video.h>
//#include <cache.h>
#define PVR_TEX_WIDTH 1024.0f
#define PVR_TEX_HEIGHT 1024.0f
#define DISPLAY_WIDTH 640
#define DISPLAY_HEIGHT 480
#define DISPLAY_AR 4/3
#include <kos/mutex.h>
mutex_t * pvr_mutex;
#define PVR_create_mutex() { pvr_mutex = mutex_create(); }
#define PVR_lock_mutex() { mutex_lock( pvr_mutex ); }
#define PVR_unlock_mutex() { mutex_unlock( pvr_mutex ); }
#define PVR_destroy_mutex() { mutex_destroy( pvr_mutex ); }
struct pvr_frame
{
int tex_width;
int tex_height;
int vram_width;
int vram_height;
int texFmt;
int texColor;
pvr_ptr_t * vram_tex;
pvr_vertex_t vert[4];
pvr_poly_hdr_t poly;
pvr_poly_cxt_t cxt;
};
struct pvr_frame_vertex
{
int top;
int bottom;
int left;
int right;
int width;
int height;
float height_ratio;
float width_ratio;
};
/* PVR Driver - Public Function Protocols */
/* Driver functions require using above structures pvr_frame/pvr_frame_vertex */
/* Allocate VRAM for the texture. Must be done before any PVR driver function */
int pvr_malloc( struct pvr_frame *pvr, int width, int height );
/* Free allocated VRAM for the texture. Should be done when finished. */
int pvr_free( struct pvr_frame *pvr );
/* Automatically set polygon co-ordinates for fullscreen, before compiling */
void pvr_resize_resolution( struct pvr_frame pvr, struct pvr_frame_vertex *display );
/* Manually set polygon co-ordinates, before compiling the polygon */
int pvr_set_resolution( struct pvr_frame pvr, int x, int y,
int dispWidth, int dispHeight, struct pvr_frame_vertex *display );
/* Compile the polygon. Only needs to be done once, before display */
int pvr_compile_poly( struct pvr_frame_vertex display, struct pvr_frame *pvr, int mode, int fmt, float z );
/* Load Texture Data from RAM to VRAM, Pixel by Pixel */
/* To use this function, first PVR_create_mutex() must be called. */
/* When finished, PVR_destroy_mutex() should be called */
/* This function is intended for use with pvr_draw_frame() */
void pvr_pixel_load( unsigned char *src, struct pvr_frame *pvr );
/* Load Texture Data from RAM to VRAM, 32bytes at a time */
/* This function is intended for use with pvr_draw_frame() */
void pvr_txr_load_sq( unsigned char *src, struct pvr_frame *pvr );
/* Load Texture Data from RAM to VRAM, using fast DMA */
/* This function is intended for use with pvr_draw_frame_dma() */
void pvr_dma_load( unsigned char *src, struct pvr_frame *pvr );
/* Draw a single Opaqe Polygon */
void pvr_draw_frame( struct pvr_frame *pvr_frame );
/* Draw a single Opaqe Polygon with DMA enabled */
void pvr_draw_frame_dma( struct pvr_frame *pvr_frame );
#endif

@ -0,0 +1,239 @@
/*
**
** PVR Video Driver
** (C) Josh "PH3NOM" Pearson 2011-2012
**
*/
#include <stdio.h>
#include <kos.h>
#include "pvr_driver.h"
/* Free PVR Ram */
int pvr_free( struct pvr_frame *pvr )
{
if(pvr->vram_tex)
{
pvr_mem_free(pvr->vram_tex);
return 1;
}
return 0;
}
/* Find and allocate the smallest possible PVR VRAM texture area */
int pvr_malloc( struct pvr_frame *pvr, int width, int height )
{
/* Set the texture context width and height */
pvr->tex_width = width;
pvr->tex_height = height;
/* Check if Texture resolution exceeds PVR maximum */
if ( pvr->tex_width > PVR_TEX_WIDTH || pvr->tex_height > PVR_TEX_HEIGHT ) {
printf("ERROR: IMAGE Exceeds PVR maximum resolution!\n");
return 0;
}
/* Find the smallest PVR Polygon size to fit the Texture, from 8x8 to 1024x1024 */
pvr->vram_width = pvr->vram_height = 0x08;
while( pvr->vram_width<pvr->tex_width )
pvr->vram_width<<=1;
while( pvr->vram_height<pvr->tex_height )
pvr->vram_height<<=1;
/* Allocate PVR VRAM for the current Texture */
if(pvr->vram_tex) pvr_mem_free(pvr->vram_tex);
pvr->vram_tex = pvr_mem_malloc(pvr->vram_width*pvr->vram_height*2);
return 1;
}
/* Transfer texture data from SH4 RAM to PVR VRAM using DMA */
void pvr_dma_load( unsigned char *src, struct pvr_frame *pvr )
{
dcache_flush_range((unsigned int)src, 16384); /* Flush the SH4 Cache */
pvr_wait_ready(); /* Wait for PVR to be in a ready state */
while (!pvr_dma_ready()); /* Wait for PVR DMA to finish transfer */
pvr_dma_transfer( src,(unsigned int)pvr->vram_tex, pvr->vram_width*pvr->tex_height*2,
PVR_DMA_VRAM64, 1, NULL, 0 );
}
/* Copy a frame from RAM to VRAM, pixel by pixel. Mutex protected. */
void pvr_pixel_load( unsigned char *src, struct pvr_frame *pvr )
{
int x, y;
uint16 *texture;
uint16 *image;
/* Copy the image data from RAM to VRAM, byte by byte */
image = (uint16 *)src;
texture = (uint16 *)pvr->vram_tex;
PVR_lock_mutex();
for (y=0; y<pvr->tex_height; y++)
{
for (x=0; x<pvr->tex_width; x++)
texture[x] = image[x];
texture += pvr->vram_width; image += pvr->tex_width;
}
PVR_unlock_mutex();
/* free the resources */
sq_clr(image, sizeof(image));
sq_clr(texture, sizeof(texture));
}
/* Copy a frame from RAM to VRAM, 32 bytes at a time using Store-Queues */
void pvr_txr_load_sq( unsigned char *src, struct pvr_frame *pvr )
{
int i, n;
unsigned int *d, *s;
/* Make sure our video width is compatible with SQ transfers */
uint32 count = pvr->tex_width * 2;
if (count % 4)
count = (count & 0xfffffffc) + 4;
d = (unsigned int *)(void *)
(0xe0000000 | (((unsigned long)pvr->vram_tex) & 0x03ffffe0));
s = (unsigned int *)src;
/* Set store queue memory area as desired */
QACR0 = ((((unsigned int)pvr->vram_tex)>>26)<<2)&0x1c;
QACR1 = ((((unsigned int)pvr->vram_tex)>>26)<<2)&0x1c;
for(i=0;i<pvr->tex_height;i++){
d = (unsigned int *)(void *)
(0xe0000000 | (((unsigned long)pvr->vram_tex+(i*(pvr->vram_width*2))) & 0x03ffffe0));
n = count>>5;
while(n--) {
asm("pref @%0" : : "r" (s + 8)); // prefetch 32 bytes for next loop
d[0] = *(s++);
d[1] = *(s++);
d[2] = *(s++);
d[3] = *(s++);
d[4] = *(s++);
d[5] = *(s++);
d[6] = *(s++);
d[7] = *(s++);
asm("pref @%0" : : "r" (d));
d += 8;
}
}
/* Wait for both store queues to complete */
d = (unsigned int *)0xe0000000;
d[0] = d[8] = 0;
}
/* Calculate output resolution */
void pvr_resize_resolution( struct pvr_frame pvr, struct pvr_frame_vertex *display )
{
/* Initialize texture width and height */
display->width = pvr.tex_width;
display->height = pvr.tex_height;
/* Calculate display resolution */
if ( pvr.tex_height < pvr.tex_width * DISPLAY_AR ) {
display->top = ( DISPLAY_HEIGHT - (( pvr.tex_height * DISPLAY_WIDTH ) / pvr.tex_width) ) / 2;
display->bottom = DISPLAY_HEIGHT - display->top;
display->left = 0; display->right = DISPLAY_WIDTH;
}
else {
display->top = 0; display->bottom = DISPLAY_HEIGHT;
display->left = ( DISPLAY_WIDTH - (( pvr.tex_width * DISPLAY_HEIGHT ) / pvr.tex_height) ) / 2;
display->right = DISPLAY_WIDTH - display->left;
}
/* Calculate Top and Bottom u/v co-oridnates */
display->width_ratio = pvr.tex_width / (float)pvr.vram_width;
display->height_ratio = pvr.tex_height / (float)pvr.vram_height;
}
/* Calculate output resolution */
int pvr_set_resolution( struct pvr_frame pvr, int x, int y,
int dispWidth, int dispHeight, struct pvr_frame_vertex *display )
{
/* Fill the pvr_frame_vertex structure*/
display->top = y;
display->bottom = y+dispHeight;
display->left = x;
display->right = x+dispWidth;
display->width = pvr.tex_width;
display->height = pvr.tex_height;
display->width_ratio = pvr.tex_width / (float)pvr.vram_width;
display->height_ratio = pvr.tex_height / (float)pvr.vram_height;
return 1;
}
/* Cache our PVR verticies */
int pvr_compile_poly( struct pvr_frame_vertex display, struct pvr_frame *pvr, int mode, int fmt, float z )
{
/* Submit the vertecies */
pvr->vert[0].argb = pvr->vert[1].argb = pvr->vert[2].argb = pvr->vert[3].argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
pvr->vert[0].oargb = pvr->vert[1].oargb = pvr->vert[2].oargb = pvr->vert[3].oargb = 0;
pvr->vert[0].z = pvr->vert[1].z = pvr->vert[2].z = pvr->vert[3].z = z;
pvr->vert[0].flags = pvr->vert[1].flags = pvr->vert[2].flags = PVR_CMD_VERTEX;
pvr->vert[3].flags = PVR_CMD_VERTEX_EOL;
pvr->vert[0].x = display.left;
pvr->vert[0].y = display.bottom;
pvr->vert[0].u = 0.0f;
pvr->vert[0].v = display.height_ratio;
pvr->vert[1].x = display.left;
pvr->vert[1].y = display.top;
pvr->vert[1].u = 0.0f;
pvr->vert[1].v = 0.0f;
pvr->vert[2].x = display.right;
pvr->vert[2].y = display.bottom;
pvr->vert[2].u = display.width_ratio;
pvr->vert[2].v = display.height_ratio;
pvr->vert[3].x = display.right;
pvr->vert[3].y = display.top;
pvr->vert[3].u = display.width_ratio;
pvr->vert[3].v = 0.0f;
/* Compile the polygon */
pvr_poly_cxt_txr(&pvr->cxt, mode, fmt,
pvr->vram_width, pvr->vram_height, pvr->vram_tex, PVR_FILTER_BILINEAR);
pvr_poly_compile(&pvr->poly, &pvr->cxt);
return 1;
}
#define pvr_submit_poly( pvr ) { \
pvr_prim(&pvr->poly, sizeof(pvr->poly)); \
pvr_prim(&pvr->vert[0], sizeof(pvr->vert[0])); \
pvr_prim(&pvr->vert[1], sizeof(pvr->vert[1])); \
pvr_prim(&pvr->vert[2], sizeof(pvr->vert[2])); \
pvr_prim(&pvr->vert[3], sizeof(pvr->vert[3])); }
/* Render a single Opaque frame using the PVR */
void pvr_draw_frame( struct pvr_frame *pvr_frame )
{
pvr_wait_ready();
pvr_scene_begin();
pvr_list_begin(PVR_LIST_OP_POLY);
pvr_submit_poly(pvr_frame);
pvr_list_finish();
pvr_scene_finish();
}
/* Render a single Opaque frame using the PVR, DMA enabled */
void pvr_draw_frame_dma( struct pvr_frame *pvr_frame )
{
pvr_scene_begin();
pvr_list_begin(PVR_LIST_OP_POLY);
pvr_submit_poly(pvr_frame);
pvr_list_finish();
pvr_scene_finish();
}

@ -0,0 +1,175 @@
/*
**
** (C) Josh 'PH3NOM' Pearson 2011
**
*/
/*
** To anyone looking at this code:
**
** This driver runs in its own thread on the sh4.
**
** When the AICA driver requests more samples,
** it will signal sndbuf_status=SNDDRV_STATUS_NEEDBUF
** and assign the number of requested samples to snddrv.pcm_needed.
**
** The decoders need to check sndbuf_status,
** when more samples are requested by the driver ** the decoders will loop
** decoding into pcm_buffer untill pcm_bytes==snddrv.pcm_needed
** at that point the decoder signals sndbuf_status=SNDDRV_STATUS_HAVEBUF
**
*/
/*
**
** August 2012
** This module has been updated to call an external callback, rather than
** using the internal snddrv_callback. Use the function snddrv_start_cb().
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <kos/thread.h>
#include "snddrv.h"
static snd_stream_hnd_t shnd;
static kthread_t * snddrv_thd;
static int snddrv_vol = 255;
static snddrv_cb *drv_callback = NULL;
/* Increase the Sound Driver volume */
int snddrv_volume_up()
{
if( snddrv_vol <= 245 )
{
snddrv_vol += 10;
snd_stream_volume(shnd, snddrv_vol);
}
return snddrv_vol;
}
/* Decrease the Sound Driver volume */
int snddrv_volume_down()
{
if( snddrv_vol >= 10 )
{
snddrv_vol -= 10;
snd_stream_volume(shnd, snddrv_vol);
}
return snddrv_vol;
}
/* Exit the Sound Driver */
int snddrv_exit()
{
if( snddrv.drv_status != SNDDRV_STATUS_NULL ) {
snddrv.drv_status = SNDDRV_STATUS_DONE;
snddrv.buf_status = SNDDRV_STATUS_BUFEND;
while( snddrv.drv_status != SNDDRV_STATUS_NULL )
thd_pass();
printf("SNDDRV: Exited\n");
}
memset( snddrv.pcm_buffer, 0, 65536+16384);
snddrv.pcm_bytes = 0;
snddrv.pcm_needed = 0;
SNDDRV_FREE_STRUCT();
return snddrv.drv_status;
}
/* Signal how many samples the AICA needs, then wait for the deocder to produce them */
static void *snddrv_callback(snd_stream_hnd_t hnd, int len, int * actual)
{
/* Signal the Decoder thread how many more samples are needed */
snddrv.pcm_needed = len;
snddrv.buf_status = SNDDRV_STATUS_NEEDBUF;
/* Wait for the samples to be ready */
while( snddrv.buf_status != SNDDRV_STATUS_HAVEBUF && snddrv.buf_status != SNDDRV_STATUS_BUFEND )
thd_pass();
snddrv.pcm_ptr = snddrv.pcm_buffer;
snddrv.pcm_bytes = 0;
*actual = len;
return snddrv.pcm_ptr;
}
void *snddrv_thread(void *ptr)
{
printf("SNDDRV: Rate - %i, Channels - %i\n", snddrv.rate, snddrv.channels);
shnd = snd_stream_alloc((void*)drv_callback, SND_STREAM_BUFFER_MAX/4);
snd_stream_start(shnd, snddrv.rate, snddrv.channels-1);
snddrv.drv_status = SNDDRV_STATUS_STREAMING;
while( snddrv.drv_status != SNDDRV_STATUS_DONE && snddrv.drv_status != SNDDRV_STATUS_ERROR )
{
snd_stream_poll(shnd);
thd_sleep(20);
}
snd_stream_destroy(shnd);
snd_stream_shutdown();
snddrv.drv_status = SNDDRV_STATUS_NULL;
printf("SNDDRV: Finished\n");
}
/* Start the AICA Sound Stream Thread */
int snddrv_start( int rate, int chans )
{
snddrv.rate = rate;
snddrv.channels = chans;
if( snddrv.channels > 2) {
printf("SNDDRV: ERROR - Exceeds maximum channels\n");
return -1;
}
printf("SNDDRV: Creating Driver Thread\n");
drv_callback = (void *)snddrv_callback;
snddrv.drv_status = SNDDRV_STATUS_INITIALIZING;
snd_stream_init();
//snddrv_thd = thd_create( snddrv_thread, NULL );
snddrv_thd = thd_create(0, snddrv_thread, NULL );
return snddrv.drv_status;
}
/* Start the AICA Sound Stream Thread */
int snddrv_start_cb( int rate, int chans, snddrv_cb cb )
{
snddrv.rate = rate;
snddrv.channels = chans;
if( snddrv.channels > 2) {
printf("SNDDRV: ERROR - Exceeds maximum channels\n");
return -1;
}
printf("SNDDRV: Creating Driver Thread\n");
drv_callback = (void*)cb;
snddrv.drv_status = SNDDRV_STATUS_INITIALIZING;
snd_stream_init();
//snddrv_thd = thd_create( snddrv_thread, NULL );
snddrv_thd = thd_create(0, snddrv_thread, NULL );
return snddrv.drv_status;
}

@ -0,0 +1,115 @@
/*
**
** This File is a part of Dreamcast Media Center
** (C) Josh "PH3NOM" Pearson 2011
**
*/
#ifndef SNDDRV_H
#define SNDDRV_H
#include <dc/sound/stream.h>
/* Keep track of things from the Driver side */
#define SNDDRV_STATUS_NULL 0x00
#define SNDDRV_STATUS_INITIALIZING 0x01
#define SNDDRV_STATUS_READY 0x02
#define SNDDRV_STATUS_STREAMING 0x03
#define SNDDRV_STATUS_DONE 0x04
#define SNDDRV_STATUS_ERROR 0x05
/* Keep track of things from the Decoder side */
#define SNDDEC_STATUS_NULL 0x00
#define SNDDEC_STATUS_INITIALIZING 0x01
#define SNDDEC_STATUS_READY 0x02
#define SNDDEC_STATUS_STREAMING 0x03
#define SNDDEC_STATUS_PAUSING 0x04
#define SNDDEC_STATUS_PAUSED 0x05
#define SNDDEC_STATUS_RESUMING 0x06
#define SNDDEC_STATUS_DONE 0x07
#define SNDDEC_STATUS_ERROR 0x08
/* Keep track of the buffer status from both sides*/
#define SNDDRV_STATUS_NEEDBUF 0x00
#define SNDDRV_STATUS_HAVEBUF 0x01
#define SNDDRV_STATUS_BUFEND 0x02
/* This seems to be a good number for file seeking on compressed audio */
#define SEEK_LEN 16384*48
/* Define a callback to be used by the driver */
typedef void * (*snddrv_cb)(snd_stream_hnd_t, int, int*);
/* SNDDRV (C) AICA Audio Driver */
struct snddrv {
int rate;
int channels;
int pcm_bytes;
int pcm_needed;
volatile int drv_status;
volatile int dec_status;
volatile int buf_status;
unsigned char pcm_buffer[65536+16384];
unsigned char *pcm_ptr;
}snddrv;
#define SNDDRV_FREE_STRUCT() { \
snddrv.rate = snddrv.channels = snddrv.drv_status = \
snddrv.dec_status = snddrv.buf_status = 0; }
struct snddrv_song_info {
char *artist[128];
char * title[128];
char * track[128];
char * album[128];
char * genre[128];
char *fname;
volatile int fpos;
volatile float spos;
int fsize;
float slen;
}snd_sinfo;
#define SNDDRV_FREE_SINFO() { \
sq_clr( snd_sinfo.artist, 128 ); \
sq_clr( snd_sinfo.title, 128 ); \
sq_clr( snd_sinfo.track, 128 ); \
sq_clr( snd_sinfo.album, 128 ); \
sq_clr( snd_sinfo.genre, 128 ); \
snd_sinfo.fpos = snd_sinfo.spos = snd_sinfo.fsize = snd_sinfo.slen = 0; }
#define min(a,b) ( (a) < (b) ? (a) : (b) )
#define MAX_CHANNELS 6 /* make this higher to support files with
more channels for LibFAAD */
/* MicroSoft channel definitions */
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#define SPEAKER_RESERVED 0x80000000
/* SNDDRV Function Protocols */
int snddrv_start( int rate, int chans );
int snddrv_exit();
int snddrv_volume_up();
int snddrv_volume_down();
int snddrv_start_cb( int rate, int chans, snddrv_cb cb );
#endif

@ -0,0 +1,44 @@
#! /bin/sh
#automating script for making CD games
DIR=$PWD
PROJECT_NAME="Reaperi_Cycle_V3_Hideout_LastStretch"
SD_NAME="Reaperi_SD"
# go to build directory
# make clean
make clean
make
#elf transform??
#sh-elf-objcopy -R .stack -O binary main.elf output.bin
#scraming process
#$KOS_BASE/utils/scramble/scramble output.bin 1ST_READ.BIN
#creating a copy for SDISO - for somereason it tries to find the 1ST_READ there.
#cp 1ST_READ.bin data/1ST_READ.bin
#creating iso -> -o outputname.cdi / build files path
#mkisofs -C 0,11702 -V Reaperi_Cycle -G IP.BIN -r -J -l -m '*.o' -x $DIR/.git -o ../$PROJECT_NAME.iso $DIR
#creating sdiso -> -o outputname.cdi / build files path
#mkisofs -V Reaperi_Cycle -G IP.BIN -r -J -l -m '*.o' -x $DIR/.git -o ../$SD_NAME.iso $DIR
#mkisofs -C 0,11702 -V DC_GAME -G IP.BIN -m '*.o' -x $DIR/.git -o ../$PROJECT_NAME.iso $DIR
#mkisofs -C 0,45000 -V DC_GAME -G IP.BIN -r -J -l -x $DIR/.git -o ../$PROJECT_NAME.iso $DIR
#mkisofs -C 0,0 -V DC_GAME -G IP.BIN -r -J -l -o ../$PROJECT_NAME.iso $DIR
#transform iso into a CDI
#$KOS_BASE/utils/cdi4dc/cdi4dc ../$PROJECT_NAME.iso ../$PROJECT_NAME.cdi -d > cdi4dc.log
#start the game
sudo arp -s 192.168.0.99 00:d0:f1:03:14:02
sudo ../dc-tool-ip -t dreamcast -c ./ -x dreamroq-player.elf
#lxdream ../$PROJECT_NAME.iso
#reicast ../$PROJECT_NAME.cdi
#redream ../$PROJECT_NAME.cdi
##../redream ../$PROJECT_NAME.cdi

Binary file not shown.
Loading…
Cancel
Save