Port for SEGA Dreamcast

svn-id: r3550
This commit is contained in:
Marcus Comstedt 2002-02-02 15:44:27 +00:00
parent de621c06e2
commit 352a7e17e1
13 changed files with 1191 additions and 0 deletions

2
dc/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
scummvm
sound

43
dc/Makefile Normal file
View File

@ -0,0 +1,43 @@
# $Header$
ronindir = /usr/local/ronin
VPATH = ..
CC = sh-elf-g++ -ml -m4-single-only
CFLAGS = -O1 -Wno-multichar
DEFINES = -D__DC__ -DNONSTANDARD_PORT -DUSE_ADLIB
LDFLAGS := -Wl,-Ttext,0x8c010000 -nostartfiles ronin/crt0.o
INCLUDES:= -I./ -I../ -I../sound
CPPFLAGS= $(DEFINES) $(INCLUDES)
LIBS = ronin/libronin.a -lm
INCS = scumm.h scummsys.h stdafx.h portdefs.h dc.h
OBJS = actor.o boxes.o costume.o gfx.o object.o resource.o \
saveload.o script.o scummvm.o sound.o string.o \
sys.o verbs.o script_v1.o script_v2.o debug.o gui.o \
sound/imuse.o sound/fmopl.o sound/adlib.o sound/gmidi.o debugrl.o \
akos.o dcmain.o display.o audio.o input.o selector.o icon.o label.o
.cpp.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
all: scummvm
scummvm: $(OBJS) ronin
$(CC) $(LDFLAGS) -o $(@) $(OBJS) $(LIBS)
$(OBJS): Makefile sound/.create ronin
sound/.create:
mkdir sound && touch $@
ronin:
ln -s $(ronindir) $@
clean:
rm -f $(OBJS) scummvm
check:
$(OBJS): $(INCS)

42
dc/audio.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "stdafx.h"
#include "scumm.h"
#include "dc.h"
#include <ronin/soundcommon.h>
EXTERN_C void *memcpy4(void *s1, const void *s2, unsigned int n);
void checkSound(Scumm *s)
{
int n;
int curr_ring_buffer_samples;
if(read_sound_int(&SOUNDSTATUS->mode) != MODE_PLAY)
start_sound();
curr_ring_buffer_samples = read_sound_int(&SOUNDSTATUS->ring_length);
n = read_sound_int(&SOUNDSTATUS->samplepos);
if((n-=fillpos)<0)
n += curr_ring_buffer_samples;
n = ADJUST_BUFFER_SIZE(n-10);
if(n<100)
return;
s->mixWaves((short*)temp_sound_buffer, n);
if(fillpos+n > curr_ring_buffer_samples) {
int r = curr_ring_buffer_samples - fillpos;
memcpy4(RING_BUF+fillpos, temp_sound_buffer, SAMPLES_TO_BYTES(r));
fillpos = 0;
n -= r;
memcpy4(RING_BUF, temp_sound_buffer+r, SAMPLES_TO_BYTES(n));
} else {
memcpy4(RING_BUF+fillpos, temp_sound_buffer, SAMPLES_TO_BYTES(n));
}
if((fillpos += n) >= curr_ring_buffer_samples)
fillpos = 0;
}

7
dc/dc.h Normal file
View File

@ -0,0 +1,7 @@
extern void checkSound(Scumm *s);
extern void handleInput(struct mapledev *pad, int16 &mouse_x, int16 &mouse_y,
byte &leftBtnPressed, byte &rightBtnPressed,
int &keyPressed);
extern bool selectGame(Scumm *s, char *&);

91
dc/dcmain.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "stdafx.h"
#include "scumm.h"
#include "gui.h"
#include "sound.h"
#include "dc.h"
Scumm scumm;
ScummDebugger debugger;
Gui gui;
SoundEngine sound;
SOUND_DRIVER_TYPE snd_driv;
void waitForTimer(Scumm *s, int time)
{
if(time<0)
return;
unsigned int start = Timer();
unsigned int devpoll = start+USEC_TO_TIMER(25000);
unsigned int t;
int oldmousex = s->mouse.x, oldmousey = s->mouse.y;
time = (((unsigned int)time)*100000U)>>11;
int mask = getimask();
while(((int)((t = Timer())-start))<time)
if(((int)(t-devpoll))>0) {
setimask(15);
checkSound(s);
handleInput(locked_get_pads(), s->mouse.x, s->mouse.y,
s->_leftBtnPressed, s->_rightBtnPressed, s->_keyPressed);
setimask(mask);
devpoll += USEC_TO_TIMER(17000);
if(s->mouse.x != oldmousex || s->mouse.y != oldmousey) {
updateScreen(s);
oldmousex = s->mouse.x;
oldmousey = s->mouse.y;
}
}
}
static char *argv[] = { "scummvm", NULL, NULL };
static int argc = 2;
int main()
{
int delta,tmp;
int last_time, new_time;
#ifndef NOSERIAL
serial_init(57600);
usleep(2000000);
printf("Serial OK\r\n");
#endif
cdfs_init();
maple_init();
dc_setup_ta();
init_arm();
if(!selectGame(&scumm, argv[1]))
exit(0);
sound.initialize(&scumm, &snd_driv);
printf("Sound initalized.\n");
scumm._gui = &gui;
scumm.scummMain(argc, argv);
printf("scummMain called.\n");
gui.init(&scumm);
last_time = Timer();
delta = 0;
do {
updateScreen(&scumm);
new_time = Timer();
waitForTimer(&scumm, delta * 15 - ((new_time - last_time)<<11)/100000);
last_time = Timer();
if (gui._active) {
gui.loop();
delta = 5;
} else {
delta = scumm.scummLoop(delta);
}
} while(1);
printf("All done. Returning to menu.\n");
exit(0);
}

267
dc/display.cpp Normal file
View File

@ -0,0 +1,267 @@
#include "stdafx.h"
#include "scumm.h"
#include "dc.h"
#define SCREEN_W 320
#define SCREEN_H 200
#define MOUSE_W 64
#define MOUSE_H 64
#define NUM_BUFFERS 4
#define QACR0 (*(volatile unsigned int *)(void *)0xff000038)
#define QACR1 (*(volatile unsigned int *)(void *)0xff00003c)
static unsigned char *screen = NULL;
static unsigned short *mouse = NULL;
static void *screen_tx[NUM_BUFFERS] = { NULL, };
static void *mouse_tx[NUM_BUFFERS] = { NULL, };
static int current_buffer = 0;
static int shakePos = 0;
unsigned short palette[256];
#define COPYPIXEL(n) do { \
unsigned short _tmp = pal[*s++]; \
d[n] = _tmp|(pal[*s++]<<16); \
} while(0)
static void texture_memcpy64_pal(void *dest, void *src, int cnt, unsigned short *pal)
{
unsigned char *s = (unsigned char *)src;
unsigned int *d = (unsigned int *)(void *)
(0xe0000000 | (((unsigned long)dest) & 0x03ffffc0));
QACR0 = ((0xa4000000>>26)<<2)&0x1c;
QACR1 = ((0xa4000000>>26)<<2)&0x1c;
while(cnt--) {
COPYPIXEL(0);
COPYPIXEL(1);
COPYPIXEL(2);
COPYPIXEL(3);
asm("pref @%0" : : "r" (s+4*16));
COPYPIXEL(4);
COPYPIXEL(5);
COPYPIXEL(6);
COPYPIXEL(7);
asm("pref @%0" : : "r" (d));
d += 8;
COPYPIXEL(0);
COPYPIXEL(1);
COPYPIXEL(2);
COPYPIXEL(3);
asm("pref @%0" : : "r" (s+4*16));
COPYPIXEL(4);
COPYPIXEL(5);
COPYPIXEL(6);
COPYPIXEL(7);
asm("pref @%0" : : "r" (d));
d += 8;
}
}
void commit_dummy_transpoly()
{
struct polygon_list mypoly;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA|
TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA;
mypoly.texture = 0;
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
}
void updatePalette(Scumm *s)
{
int first = s->_palDirtyMin;
int num = s->_palDirtyMax - first + 1;
unsigned char *src = s->_currentPalette;
unsigned short *dst = palette + first;
src += first*3;
if(num>0)
while( num-- ) {
*dst++ = ((src[0]<<7)&0x7c00)|
((src[1]<<2)&0x03e0)|
((src[2]>>3)&0x001f);
src += 3;
}
}
void blitToScreen(Scumm *s, unsigned char *src, int x, int y, int w, int h)
{
unsigned char *dst = screen + y*SCREEN_W + x;
do {
memcpy(dst, src, w);
dst += SCREEN_W;
src += SCREEN_W;
} while (--h);
}
void setShakePos(Scumm *s, int shake_pos)
{
shakePos = shake_pos;
}
void updateScreen(Scumm *s)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
unsigned short *dst = (unsigned short *)screen_tx[current_buffer];
unsigned char *src = screen;
// while((*((volatile unsigned int *)(void*)0xa05f810c) & 0x3ff) != 200);
// *((volatile unsigned int *)(void*)0xa05f8040) = 0xff0000;
if(s->_palDirtyMax != -1) {
updatePalette(s);
}
for( int y = 0; y<SCREEN_H; y++ )
{
texture_memcpy64_pal( dst, src, SCREEN_W>>5, palette );
src += SCREEN_W;
dst += SCREEN_W;
}
// *((volatile unsigned int *)(void*)0xa05f8040) = 0x00ff00;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_TEXTURE_REPLACE|
TA_POLYMODE2_U_SIZE_512|TA_POLYMODE2_V_SIZE_512;
mypoly.texture = TA_TEXTUREMODE_ARGB1555|TA_TEXTUREMODE_NON_TWIDDLED|
TA_TEXTUREMODE_STRIDE|TA_TEXTUREMODE_ADDRESS(screen_tx[current_buffer]);
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_begin_frame();
// *((volatile unsigned int *)(void*)0xa05f8040) = 0x0000ff;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.colour = 0;
myvertex.z = 0.5;
myvertex.u = 0.0;
myvertex.v = 0.0;
myvertex.x = 0.0;
myvertex.y = shakePos*2.0;
ta_commit_list(&myvertex);
myvertex.x = SCREEN_W*2.0;
myvertex.u = SCREEN_W/512.0;
ta_commit_list(&myvertex);
myvertex.x = 0.0;
myvertex.y += SCREEN_H*2.0;
myvertex.u = 0.0;
myvertex.v = SCREEN_H/512.0;
ta_commit_list(&myvertex);
myvertex.x = SCREEN_W*2.0;
myvertex.u = SCREEN_W/512.0;
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
ta_commit_end();
// *((volatile unsigned int *)(void*)0xa05f8040) = 0xffff00;
s->drawMouse();
// *((volatile unsigned int *)(void*)0xa05f8040) = 0xff00ff;
ta_commit_frame();
current_buffer++;
current_buffer &= NUM_BUFFERS-1;
// *((volatile unsigned int *)(void*)0xa05f8040) = 0x0;
}
void drawMouse(Scumm *s, int xdraw, int ydraw, int w, int h,
unsigned char *buf, bool visible)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
unsigned short *dst = (unsigned short *)mouse_tx[current_buffer];
int y=0;
if(visible && w<=MOUSE_W && h<=MOUSE_H)
for(int y=0; y<h; y++) {
int x;
for(x=0; x<w; x++)
if(*buf == 0xff) {
*dst++ = 0;
buf++;
} else
*dst++ = palette[*buf++]|0x8000;
dst += MOUSE_W-x;
}
else
w = h = 0;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA|
TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_TEXTURE_REPLACE|
TA_POLYMODE2_U_SIZE_64|TA_POLYMODE2_V_SIZE_64;
mypoly.texture = TA_TEXTUREMODE_ARGB1555|TA_TEXTUREMODE_NON_TWIDDLED|
TA_TEXTUREMODE_ADDRESS(mouse_tx[current_buffer]);
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.colour = 0xffff00;
myvertex.z = 0.25;
myvertex.u = 0.0;
myvertex.v = 0.0;
myvertex.x = xdraw*2.0;
myvertex.y = (ydraw+shakePos)*2.0;
ta_commit_list(&myvertex);
myvertex.x += w*2.0;
myvertex.u = w*(1.0/MOUSE_W);
ta_commit_list(&myvertex);
myvertex.x = xdraw*2.0;
myvertex.y += h*2.0;
myvertex.u = 0.0;
myvertex.v = h*(1.0/MOUSE_H);
ta_commit_list(&myvertex);
myvertex.x += w*2.0;
myvertex.u = w*(1.0/MOUSE_W);
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
}
void initGraphics(Scumm *s, bool fullScreen)
{
ta_sync();
if(!screen)
screen = new unsigned char[SCREEN_W*SCREEN_H];
for(int i=0; i<NUM_BUFFERS; i++)
if(!screen_tx[i])
screen_tx[i] = ta_txalloc(SCREEN_W*SCREEN_H*2);
for(int i=0; i<NUM_BUFFERS; i++)
if(!mouse_tx[i])
mouse_tx[i] = ta_txalloc(MOUSE_W*MOUSE_H*2);
current_buffer = 0;
shakePos = 0;
*(volatile unsigned int *)(0xa05f80e4) = SCREEN_W/32; //stride
// dc_reset_screen(0, 0);
}

184
dc/icon.cpp Normal file
View File

@ -0,0 +1,184 @@
#include <ronin/ronin.h>
#include <string.h>
#include "icon.h"
void Icon::create_texture()
{
static char tt[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
64, 65, 68, 69, 80, 81, 84, 85 };
unsigned short *tex = (unsigned short *)ta_txalloc(512);
unsigned short *linebase;
unsigned char *src = bitmap+sizeof(bitmap)-17;
for(int y=0; y<16; y++) {
linebase = tex + (tt[y]<<1);
for(int x=0; x<16; x++, --src)
linebase[tt[x]] = src[16]|(src[0]<<8);
src -= 16;
}
texture = tex;
}
void Icon::set_palette(int pal)
{
unsigned int (*hwpal)[64][16] = (unsigned int (*)[64][16])0xa05f9000;
for(int n = 0; n<16; n++)
(*hwpal)[pal][n] = palette[n];
}
void Icon::draw(float x1, float y1, float x2, float y2, int pal)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA|
TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA|
TA_POLYMODE2_TEXTURE_REPLACE|TA_POLYMODE2_U_SIZE_32|TA_POLYMODE2_V_SIZE_32;
mypoly.texture = TA_TEXTUREMODE_CLUT4|TA_TEXTUREMODE_CLUTBANK4(pal)|
TA_TEXTUREMODE_ADDRESS(texture);
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.colour = 0;
myvertex.z = 0.5;
myvertex.u = 0.0;
myvertex.v = 1.0;
myvertex.x = x1;
myvertex.y = y1;
ta_commit_list(&myvertex);
myvertex.x = x2;
myvertex.v = 0.0;
ta_commit_list(&myvertex);
myvertex.x = x1;
myvertex.y = y2;
myvertex.u = 1.0;
myvertex.v = 1.0;
ta_commit_list(&myvertex);
myvertex.x = x2;
myvertex.v = 0.0;
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
}
int Icon::find_unused_pixel()
{
int use[16];
memset(use, 0, sizeof(use));
for(int n=0; n<32*32/2; n++) {
unsigned char pix = bitmap[n];
use[pix&0xf]++;
use[pix>>4]++;
}
for(int i=0; i<16; i++)
if(!use[i])
return i;
return -1;
}
bool Icon::load_image2(void *data, int len)
{
struct {
int size, w, h;
short pla, bitcnt;
int comp, sizeimg, xres, yres, used, imp;
} hdr;
if(len < 40)
return false;
memcpy(&hdr, data, 40);
if(hdr.size != 40 || hdr.sizeimg<=0 || hdr.w<0 || hdr.h<0 ||
hdr.bitcnt<0 || hdr.used<0)
return false;
if(!hdr.used)
hdr.used = 1<<hdr.bitcnt;
hdr.h >>= 1;
if(hdr.size + (hdr.used<<2) + hdr.sizeimg > len ||
hdr.sizeimg < ((hdr.w*hdr.h*(1+hdr.bitcnt)+7)>>3))
return false;
if(hdr.w != 32 || hdr.h != 32 || hdr.bitcnt != 4 || hdr.used > 16)
return false;
memcpy(palette, ((char *)data)+hdr.size, hdr.used<<2);
memcpy(bitmap, ((char *)data)+hdr.size+(hdr.used<<2), 32*32/2);
for(int i=0; i<16; i++)
palette[i] |= 0xff000000;
for(int i=hdr.used; i<16; i++)
palette[i] = 0;
int unused = find_unused_pixel();
if(unused >= 0) {
unsigned char *mask =
((unsigned char *)data)+hdr.size+(hdr.used<<2)+32*32/2;
unsigned char *pix = bitmap;
for(int y=0; y<32; y++)
for(int x=0; x<32/8; x++) {
unsigned char mbits = *mask++;
for(int z=0; z<4; z++) {
unsigned char pbits = *pix;
if(mbits & 64) pbits = (pbits & ~0xf) | unused;
if(mbits & 128) pbits = (pbits & 0xf) | (unused << 4);
*pix++ = pbits;
mbits <<= 2;
}
}
palette[unused] = 0;
}
return true;
}
bool Icon::load_image1(void *data, int len, int offs)
{
struct {
char w, h, colors, rsrv;
short pla, bitcnt;
int bytes, offs;
} hdr;
if(len < offs+16)
return false;
memcpy(&hdr, ((char *)data)+offs, 16);
if(hdr.bytes > 0 && hdr.offs >= 0 && hdr.offs+hdr.bytes <= len)
return load_image2(((char *)data)+hdr.offs, hdr.bytes);
else
return false;
}
bool Icon::load(void *data, int len, int offs)
{
struct { short rsrv, type, cnt; } hdr;
memset(bitmap, 0, sizeof(bitmap));
memset(palette, 0, sizeof(palette));
texture = NULL;
if(len < offs+6)
return false;
memcpy(&hdr, ((char *)data)+offs, 6);
if(hdr.type != 1 || hdr.cnt < 1 || offs+6+(hdr.cnt<<4) > len)
return false;
for(int i=0; i<hdr.cnt; i++)
if(load_image1(data, len, offs+6+(i<<4)))
return true;
return false;
}
bool Icon::load(const char *filename)
{
char buf[2048];
int fd;
if((fd = open(filename, O_RDONLY))>=0) {
int sz;
sz = read(fd, buf, sizeof(buf));
close(fd);
if(sz>0)
return load(buf, sz);
}
return false;
}

19
dc/icon.h Normal file
View File

@ -0,0 +1,19 @@
class Icon
{
private:
unsigned char bitmap[32*32/2];
unsigned int palette[16];
void *texture;
int find_unused_pixel();
bool load_image1(void *data, int len, int offs);
bool load_image2(void *data, int len);
public:
bool load(void *data, int len, int offs = 0);
bool load(const char *filename);
void create_texture();
void set_palette(int pal);
void draw(float x1, float y1, float x2, float y2, int pal);
};

95
dc/input.cpp Normal file
View File

@ -0,0 +1,95 @@
#include "stdafx.h"
#include "scumm.h"
#include "dc.h"
void handleInput(struct mapledev *pad, int16 &mouse_x, int16 &mouse_y,
byte &leftBtnPressed, byte &rightBtnPressed, int &keyPressed)
{
int lmb=0, rmb=0, newkey=0;
static int lastkey = 0;
for(int i=0; i<4; i++, pad++)
if(pad->func & MAPLE_FUNC_CONTROLLER) {
int buttons = pad->cond.controller.buttons;
if(!(buttons & 0x060e)) exit(0);
if(!(buttons & 4)) lmb++;
if(!(buttons & 2)) rmb++;
if(!(buttons & 8)) newkey = 319;
else if(!(buttons & 512)) newkey = ' ';
else if(!(buttons & 1024)) newkey = '0';
if(!(buttons & 128)) mouse_x++;
if(!(buttons & 64)) mouse_x--;
if(!(buttons & 32)) mouse_y++;
if(!(buttons & 16)) mouse_y--;
mouse_x += ((int)pad->cond.controller.joyx-128)>>4;
mouse_y += ((int)pad->cond.controller.joyy-128)>>4;
} else if(pad->func & MAPLE_FUNC_MOUSE) {
int buttons = pad->cond.mouse.buttons;
if(!(buttons & 4)) lmb++;
if(!(buttons & 2)) rmb++;
if(!(buttons & 8)) newkey = 319;
mouse_x += pad->cond.mouse.axis1;
mouse_y += pad->cond.mouse.axis2;
pad->cond.mouse.axis1 = 0;
pad->cond.mouse.axis2 = 0;
} else if(pad->func & MAPLE_FUNC_KEYBOARD) {
for(int p=0; p<6; p++) {
int shift = pad->cond.kbd.shift;
int key = pad->cond.kbd.key[p];
if(shift & 0x08) lmb++;
if(shift & 0x80) rmb++;
if(key >= 4 && key <= 0x1d)
newkey = key+((shift & 0x22)? ('A'-4) : ('a'-4));
else if(key >= 0x1e && key <= 0x26)
newkey = key+((shift & 0x22)? ('!'-0x1e) : ('1'-0x1e));
else if(key >= 0x59 && key <= 0x61)
newkey = key+('1'-0x59);
else if(key >= 0x3a && key <= 0x43)
newkey = key+(315-0x3a);
else switch(key) {
case 0x27: case 0x62:
newkey = ((shift & 0x22)? '~' : '0'); break;
case 0x28: case 0x58:
newkey = 13; break;
case 0x29:
newkey = 27; break;
case 0x2a:
newkey = 8; break;
case 0x2b:
newkey = 9; break;
case 0x2c:
newkey = ' '; break;
case 0x4f:
mouse_x++; break;
case 0x50:
mouse_x--; break;
case 0x51:
mouse_y++; break;
case 0x52:
mouse_y--; break;
}
}
}
if(lmb)
leftBtnPressed |= msClicked|msDown;
else
leftBtnPressed &= ~msDown;
if(rmb)
rightBtnPressed |= msClicked|msDown;
else
rightBtnPressed &= ~msDown;
if(!newkey)
lastkey = 0;
else if(newkey != lastkey)
keyPressed = lastkey = newkey;
}

109
dc/label.cpp Normal file
View File

@ -0,0 +1,109 @@
#include <ronin/ronin.h>
#include <string.h>
#include "label.h"
static void *get_romfont_address()
{
void *ret;
__asm__("jsr @%1; mov #0,r1; mov r0,%0" :
"=r" (ret) : "r" (*(void **)0x8c0000b4) :
"pr", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7");
return ret;
}
static void draw_char(unsigned short *dst, int mod, int c, void *font_base)
{
unsigned char *src;
int i, j;
if(c<=32 || c>255 || (c>=127 && c<160)) c=160;
if(c<128) c -= 32; else c -= 64;
src = c*36 + (unsigned char *)font_base;
for(i=0; i<12; i++) {
int n = (src[0]<<16)|(src[1]<<8)|src[2];
for(j=0; j<12; j++, n<<=1)
if(n & (1<<23)) {
dst[j] = 0xffff;
dst[j+1] = 0xffff;
dst[j+2] = 0xa108;
dst[j+mod] = 0xa108;
dst[j+mod+1] = 0xa108;
}
dst += mod;
for(j=0; j<12; j++, n<<=1)
if(n & (1<<23)) {
dst[j] = 0xffff;
dst[j+1] = 0xffff;
dst[j+2] = 0xa108;
dst[j+mod] = 0xa108;
dst[j+mod+1] = 0xa108;
}
dst += mod;
src += 3;
}
}
void Label::create_texture(const char *text)
{
void *font = get_romfont_address();
int l = strlen(text);
if(l>64) l=64;
int w = 14*l;
for(tex_u=TA_POLYMODE2_U_SIZE_8, u=8; u<w; u<<=1, tex_u += 1<<3);
int tsz = u*32;
unsigned short *tex = (unsigned short *)ta_txalloc(tsz*2);
for(int i=0; i<tsz; i++)
tex[i] = 0;
int p=l*14;
while(l>0)
draw_char(tex+(p-=14), u, text[--l], font);
texture = tex;
}
void Label::draw(float x, float y, unsigned int argb)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA|
TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA|
TA_POLYMODE2_TEXTURE_MODULATE|TA_POLYMODE2_V_SIZE_32|tex_u;
mypoly.texture = TA_TEXTUREMODE_ARGB1555|TA_TEXTUREMODE_NON_TWIDDLED|
TA_TEXTUREMODE_ADDRESS(texture);
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.colour = argb;
myvertex.z = 0.5;
myvertex.u = 0.0;
myvertex.v = 0.0;
myvertex.x = x;
myvertex.y = y;
ta_commit_list(&myvertex);
myvertex.x = x+u;
myvertex.u = 1.0;
ta_commit_list(&myvertex);
myvertex.x = x;
myvertex.y = y+25.0;
myvertex.u = 0.0;
myvertex.v = 25.0/32.0;
ta_commit_list(&myvertex);
myvertex.x = x+u;
myvertex.u = 1.0;
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
}

10
dc/label.h Normal file
View File

@ -0,0 +1,10 @@
class Label
{
private:
void *texture;
int tex_u, u;
public:
void create_texture(const char *text);
void draw(float x, float y, unsigned int argb = 0xffffffff);
};

9
dc/portdefs.h Normal file
View File

@ -0,0 +1,9 @@
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <ronin/ronin.h>

313
dc/selector.cpp Normal file
View File

@ -0,0 +1,313 @@
#include "stdafx.h"
#include "scumm.h"
#include "dc.h"
#include "icon.h"
#include "label.h"
#define MAX_GAMES 100
#define MAX_DIR 100
void draw_solid_quad(float x1, float y1, float x2, float y2,
int c0, int c1, int c2, int c3)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|
TA_CMD_POLYGON_GOURAUD_SHADING;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED;
mypoly.texture = 0;
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.z = 0.5;
myvertex.u = 0.0;
myvertex.v = 0.0;
myvertex.colour = c0;
myvertex.x = x1;
myvertex.y = y1;
ta_commit_list(&myvertex);
myvertex.colour = c1;
myvertex.x = x2;
ta_commit_list(&myvertex);
myvertex.colour = c2;
myvertex.x = x1;
myvertex.y = y2;
ta_commit_list(&myvertex);
myvertex.colour = c3;
myvertex.x = x2;
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
}
void draw_trans_quad(float x1, float y1, float x2, float y2,
int c0, int c1, int c2, int c3)
{
struct polygon_list mypoly;
struct packed_colour_vertex_list myvertex;
mypoly.cmd =
TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST|
TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|
TA_CMD_POLYGON_GOURAUD_SHADING;
mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE;
mypoly.mode2 =
TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA|
TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA;
mypoly.texture = 0;
mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0;
ta_commit_list(&mypoly);
myvertex.cmd = TA_CMD_VERTEX;
myvertex.ocolour = 0;
myvertex.z = 0.5;
myvertex.u = 0.0;
myvertex.v = 0.0;
myvertex.colour = c0;
myvertex.x = x1;
myvertex.y = y1;
ta_commit_list(&myvertex);
myvertex.colour = c1;
myvertex.x = x2;
ta_commit_list(&myvertex);
myvertex.colour = c2;
myvertex.x = x1;
myvertex.y = y2;
ta_commit_list(&myvertex);
myvertex.colour = c3;
myvertex.x = x2;
myvertex.cmd |= TA_CMD_VERTEX_EOS;
ta_commit_list(&myvertex);
}
struct Game
{
char dir[256];
char filename_base[256];
char text[256];
Icon icon;
Label label;
};
struct Dir
{
char name[256];
char deficon[256];
};
static Game the_game;
static bool isGame(const char *fn, char *base)
{
int l = strlen(fn);
if(l>4 && (!strcasecmp(fn+l-4, ".000") ||
!strcasecmp(fn+l-4, ".SM0"))) {
strcpy(base, fn);
base[l-4]='\0';
return true;
}
return false;
}
static void checkName(Scumm *s, Game &game)
{
s->_exe_name = game.filename_base;
if(s->detectGame()) {
char *n = s->getGameName();
strcpy(game.text, n);
free(n);
} else
strcpy(game.text, game.filename_base);
s->_exe_name = NULL;
}
static bool isIcon(const char *fn)
{
int l = strlen(fn);
if(l>4 && !strcasecmp(fn+l-4, ".ICO"))
return true;
else
return false;
}
static bool loadIcon(Game &game, Dir *dirs, int num_dirs)
{
char icofn[520];
sprintf(icofn, "%s%s.ICO", game.dir, game.filename_base);
if(game.icon.load(icofn))
return true;
for(int i=0; i<num_dirs; i++)
if(!strcmp(dirs[i].name, game.dir) &&
dirs[i].deficon[0]) {
sprintf(icofn, "%s%s", game.dir, dirs[i].deficon);
if(game.icon.load(icofn))
return true;
break;
}
return false;
}
static void makeDefIcon(Icon &icon)
{
icon.load(NULL, 0);
}
static int findGames(Scumm *s, Game *games, int max)
{
Dir *dirs = new Dir[MAX_DIR];
int curr_game = 0, curr_dir = 0, num_dirs = 1;
strcpy(dirs[0].name, "/");
while(curr_game < max && curr_dir < num_dirs) {
dirs[curr_dir].deficon[0] = '\0';
DIR *dirp = opendir(dirs[curr_dir++].name);
if(dirp) {
struct dirent *entry;
while((entry = readdir(dirp)))
if(entry->d_size < 0) {
if(num_dirs < MAX_DIR) {
strcpy(dirs[num_dirs].name, dirs[curr_dir-1].name);
if(strlen(dirs[num_dirs].name)+strlen(entry->d_name)<255) {
strcat(dirs[num_dirs].name, entry->d_name);
strcat(dirs[num_dirs].name, "/");
num_dirs++;
}
}
} else
if(isIcon(entry->d_name))
strcpy(dirs[curr_dir-1].deficon, entry->d_name);
else if(curr_game < max &&
isGame(entry->d_name, games[curr_game].filename_base)) {
strcpy(games[curr_game].dir, dirs[curr_dir-1].name);
checkName(s, games[curr_game]);
curr_game++;
}
closedir(dirp);
}
}
for(int i=0; i<curr_game; i++)
if(!loadIcon(games[i], dirs, num_dirs))
makeDefIcon(games[i].icon);
delete dirs;
return curr_game;
}
int gameMenu(Game *games, int num_games)
{
int top_game = 0, selector_pos = 0;
int16 mousex = 0, mousey = 0;
if(!num_games)
return -1;
for(;;) {
ta_begin_frame();
draw_solid_quad(20.0, 20.0, 620.0, 460.0,
0xff0000, 0x00ff00, 0x0000ff, 0xffffff);
ta_commit_end();
float y = 40.0;
for(int i=top_game, cnt=0; cnt<10 && i<num_games; i++, cnt++) {
int pal = 48+(i&15);
games[i].icon.set_palette(pal);
games[i].icon.draw(50.0, y, 82.0, y+32.0, pal);
if(cnt == selector_pos)
draw_trans_quad(100.0, y, 590.0, y+32.0,
0x7000ff00, 0x7000ff00, 0x7000ff00, 0x7000ff00);
games[i].label.draw(104.0, y+4.0, (cnt == selector_pos?
0xffffff00 : 0xffffffff));
y += 40.0;
}
ta_commit_frame();
byte lmb=0, rmb=0;
int key=0;
int mask = getimask();
setimask(15);
handleInput(locked_get_pads(), mousex, mousey, lmb, rmb, key);
setimask(mask);
if(lmb || key==13 || key==319)
return top_game + selector_pos;
if(mousey>=16) {
if(selector_pos + top_game + 1 < num_games)
if(++selector_pos >= 10) {
--selector_pos;
++top_game;
}
mousey -= 16;
} else if(mousey<=-16) {
if(selector_pos + top_game > 0)
if(--selector_pos < 0) {
++selector_pos;
--top_game;
}
mousey += 16;
}
}
}
bool selectGame(Scumm *s, char *&ret)
{
Game *games = new Game[MAX_GAMES];
int num_games = findGames(s, games, MAX_GAMES);
int selected;
ta_sync();
void *mark = ta_txmark();
for(int i=0; i<num_games; i++) {
games[i].icon.create_texture();
games[i].label.create_texture(games[i].text);
}
selected = gameMenu(games, num_games);
ta_sync();
ta_txrelease(mark);
if(selected >= num_games)
selected = -1;
if(selected >= 0)
the_game = games[selected];
delete games;
if(selected>=0) {
chdir(the_game.dir);
ret = the_game.filename_base;
return true;
} else
return false;
}