mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-22 04:01:23 +00:00
Port for SEGA Dreamcast
svn-id: r3550
This commit is contained in:
parent
de621c06e2
commit
352a7e17e1
2
dc/.cvsignore
Normal file
2
dc/.cvsignore
Normal file
@ -0,0 +1,2 @@
|
||||
scummvm
|
||||
sound
|
43
dc/Makefile
Normal file
43
dc/Makefile
Normal 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
42
dc/audio.cpp
Normal 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
7
dc/dc.h
Normal 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
91
dc/dcmain.cpp
Normal 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
267
dc/display.cpp
Normal 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
184
dc/icon.cpp
Normal 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
19
dc/icon.h
Normal 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
95
dc/input.cpp
Normal 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
109
dc/label.cpp
Normal 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
10
dc/label.h
Normal 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
9
dc/portdefs.h
Normal 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
313
dc/selector.cpp
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user