diff -urN gnuboy-1.0.3-orig/Makefile.qtopia gnuboy-1.0.3/Makefile.qtopia --- gnuboy-1.0.3-orig/Makefile.qtopia Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/Makefile.qtopia Thu Dec 27 08:46:18 2001 @@ -0,0 +1,75 @@ +################ +# +# Makefile for Qtopia port of gnuboy +# +# To use this file, uncomment the following lines to match the +# built type you are trying to achive. This file should support +# standard Qt, Qtopia x86 and Qtopia ARM +# +# CC +# CXX +# CXXFLAGS +# SYS_INCS +# QTOPIA_LIBS +# +# Mike Pilone +# +################ + + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin + +CC = arm-linux-gcc +CXX = arm-linux-g++ +#CC = gcc +#CXX = g++ + +LD = $(CXX) +AS = $(CC) +INSTALL = /usr/bin/install -c + +# Something in the experimental flags makes the ARM compile crash +CFLAGS_EXPERIMENTAL = -O3 -DALLOW_UNALIGNED_IO -fstrength-reduce -fthread-jumps -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -fexpensive-optimizations -fforce-mem -fforce-addr -fomit-frame-pointer + +CFLAGS = -pipe -ansi -pedantic -Wall -Wno-implicit -Wno-long-long +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -DQT_QWS_EBX -DQWS -DQT_QWS_CUSTOM +#CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +LDFLAGS = $(CFLAGS) +ASFLAGS = $(CFLAGS) + +TARGETS = qtopiagnuboy + +ASM_OBJS = asm/i386/cpu.o asm/i386/lcd.o asm/i386/refresh.s + +SYS_DEFS = -DHAVE_CONFIG_H -DIS_LITTLE_ENDIAN -DIS_LINUX +SYS_OBJS = sys/nix/nix.o +#SYS_INCS = -I/usr/local/include -I/usr/X11R6/include -I./sys/nix -I/usr/lib/qt2/include +SYS_INCS = -I/usr/local/include -I./sys/nix -I/opt/Qtopia/include + +QTOPIA_OBJS = sys/qtopia/qtopia.o sys/qtopia/mainwidget.o sys/qtopia/mainwindow.o sys/oss/oss.o +#QTOPIA_LIBS = -L/usr/lib/qt2/lib -lqt +QTOPIA_LIBS = -L/opt/Qtopia/sharp/lib -lqpe -lqte +#QTOPIA_LIBS = -L/opt/Qtopia/lib -lqpe -lqte + +all: $(TARGETS) + +include Rules + +qtopiagnuboy: $(OBJS) $(SYS_OBJS) $(QTOPIA_OBJS) + $(LD) $(LDFLAGS) $(OBJS) $(SYS_OBJS) $(QTOPIA_OBJS) -o $@ $(QTOPIA_LIBS) + +install: all + $(INSTALL) -d $(bindir) + $(INSTALL) -m 755 $(TARGETS) $(bindir) + +clean: + rm -f *gnuboy gmon.out *.o sys/*.o sys/*/*.o asm/*/*.o + +distclean: clean + rm -f config.* sys/nix/config.h Makefile + + + + diff -urN gnuboy-1.0.3-orig/README-qtopia gnuboy-1.0.3/README-qtopia --- gnuboy-1.0.3-orig/README-qtopia Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/README-qtopia Thu Dec 27 08:57:21 2001 @@ -0,0 +1,34 @@ +This is a patched version of GnuBoy to work on TrollTech's Qtopia +environment (IPAQ and Zaurus PDAs). + +Currently the patch supports running a single game from the command +line. The default key bindings are: + + D-Pad: 4 directions + Enter: Start + Space: Select + L : B button + J : A button + +In the future the keys will be customizable. + +The emulator needs speed increases. One possiblity is to reimplement some +of the common CPU emulation functions in assembly as was done on x86. +If anyone is willing to do this for the ARM please let me know. + +Scalling does work, but because of the CPU load it creates the scale +is currently hard coded to 1. This can be changed in sys/qtopia/qtopia.cpp + +This patch is based on the work of GnuBoy which can be found at: +http://gnuboy.unix-fu.org (when the page is up!). + +This patch is released under the GPL as requested by the authors of GnuBoy. + +-Mike Pilone + + + +PS: I heard rumors that GB ROMs can be found here: + http://www.edgeemu.com/gbromsm.shtml + but as always, you can't legally use the ROM unless you own the + original. diff -urN gnuboy-1.0.3-orig/Rules gnuboy-1.0.3/Rules --- gnuboy-1.0.3-orig/Rules Sat Sep 29 15:18:26 2001 +++ gnuboy-1.0.3/Rules Thu Dec 27 09:15:14 2001 @@ -10,12 +10,16 @@ INCS = -I. MYCC = $(CC) $(CFLAGS) $(INCS) $(SYS_INCS) $(SYS_DEFS) +MYCXX = $(CXX) $(CXXFLAGS) $(INCS) $(SYS_INCS) $(SYS_DEFS) MYAS = $(AS) $(ASFLAGS) $(INCS) $(SYS_INCS) $(SYS_DEFS) main.o: Version .c.o: $(MYCC) -c $< -o $@ + +.cpp.o: + $(MYCXX) -c $< -o $@ .s.o: $(MYAS) -c $< -o $@ diff -urN gnuboy-1.0.3-orig/qpe/apps/Games/qtopiagnuboy.desktop gnuboy-1.0.3/qpe/apps/Games/qtopiagnuboy.desktop --- gnuboy-1.0.3-orig/qpe/apps/Games/qtopiagnuboy.desktop Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/qpe/apps/Games/qtopiagnuboy.desktop Thu Dec 27 09:07:18 2001 @@ -0,0 +1,6 @@ +[Desktop Entry] +Comment=GnuBoy GameBoy Emulator +Exec=qtopiagnuboy +Icon=GnuBoy +Type=Application +Name=Qtopia GnuBoy Binary files gnuboy-1.0.3-orig/qpe/pics/.xvpics/GnuBoy.png and gnuboy-1.0.3/qpe/pics/.xvpics/GnuBoy.png differ Binary files gnuboy-1.0.3-orig/qpe/pics/GnuBoy.png and gnuboy-1.0.3/qpe/pics/GnuBoy.png differ diff -urN gnuboy-1.0.3-orig/qtopiagnuboy.control gnuboy-1.0.3/qtopiagnuboy.control --- gnuboy-1.0.3-orig/qtopiagnuboy.control Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/qtopiagnuboy.control Thu Dec 27 09:06:07 2001 @@ -0,0 +1,9 @@ +Files: bin/qtopiagnuboy apps/Games/qtopiagnuboy.desktop pics/GnuBoy.png +Priority: optional +Section: qpe/games +Maintainer: Mike Pilone +Architecture: arm +Arch: iPAQ +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: GnuBoy GameBoy Emulator diff -urN gnuboy-1.0.3-orig/sys/qtopia/mainwidget.cpp gnuboy-1.0.3/sys/qtopia/mainwidget.cpp --- gnuboy-1.0.3-orig/sys/qtopia/mainwidget.cpp Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/sys/qtopia/mainwidget.cpp Thu Dec 27 08:46:03 2001 @@ -0,0 +1,76 @@ +#include + +#include + +extern int keymap[]; + +#include "mainwidget.h" + +MainWidget::MainWidget(QWidget *parent) + : QWidget(parent, "MainWidget"), m_Keymap(10000) + { + m_Keymap.fill(0); + m_Keymap[(int)Qt::Key_Escape] = K_ESC; + m_Keymap[(int)Qt::Key_Left] = K_LEFT; + m_Keymap[(int)Qt::Key_Right] = K_RIGHT; + m_Keymap[(int)Qt::Key_Up] = K_UP; + m_Keymap[(int)Qt::Key_Down] = K_DOWN; + m_Keymap[(int)Qt::Key_Enter] = K_ENTER; + m_Keymap[(int)Qt::Key_Return] = K_ENTER; // start + m_Keymap[Qt::Key_L] = (int)'s'; // b + m_Keymap[Qt::Key_J] = (int)'d'; // a + m_Keymap[Qt::Key_Space] = K_SPACE; // select + } + +MainWidget::~MainWidget() +{ +} + +void MainWidget::keyPressEvent(QKeyEvent *e) +{ + //printf("MainWidget::keyPressEvent: %d\n", e->key()); + + event_t ev; + int keyCode = m_Keymap[e->key()]; + + if (keyCode != 0) + { + ev.type = EV_PRESS; + ev.code = keyCode; + ev_postevent(&ev); + } + else + printf("MainWidget::keyPressEvent: couldn't map\n"); + + e->accept(); + QWidget::keyPressEvent(e); +} + +void MainWidget::keyReleaseEvent(QKeyEvent *e) +{ + //printf("MainWidget::keyReleaseEvent: %d\n", e->key()); + + event_t ev; + + ev.type = EV_RELEASE; + ev.code = m_Keymap[e->key()]; + ev_postevent(&ev); + + e->accept(); + QWidget::keyReleaseEvent(e); +} + +void MainWidget::closeEvent(QCloseEvent *e) +{ + printf("MainWidget::closeEvent\n"); + + // Trying to exit, tell the emulator + event_t ev; + ev.type = EV_PRESS; + ev.code = K_ESC; + + ev_postevent(&ev); + + e->ignore(); + QWidget::closeEvent(e); +} diff -urN gnuboy-1.0.3-orig/sys/qtopia/mainwidget.h gnuboy-1.0.3/sys/qtopia/mainwidget.h --- gnuboy-1.0.3-orig/sys/qtopia/mainwidget.h Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/sys/qtopia/mainwidget.h Thu Dec 27 08:46:03 2001 @@ -0,0 +1,30 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H + +#include +#include + +extern "C" { +#include "input.h" +} + +class QCloseEvent; +class QKeyEvent; +class MainWidget : public QWidget +{ + public: + MainWidget(QWidget *parent); + ~MainWidget(); + + protected: + virtual void keyPressEvent(QKeyEvent *e); + virtual void keyReleaseEvent(QKeyEvent *e); + virtual void closeEvent(QCloseEvent *e); + + private: + void _postEvent(event_t *e, int keyCode); + + QArray m_Keymap; +}; + +#endif diff -urN gnuboy-1.0.3-orig/sys/qtopia/mainwindow.cpp gnuboy-1.0.3/sys/qtopia/mainwindow.cpp --- gnuboy-1.0.3-orig/sys/qtopia/mainwindow.cpp Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/sys/qtopia/mainwindow.cpp Thu Dec 27 08:46:03 2001 @@ -0,0 +1,30 @@ +#include + +#include + +#include "mainwidget.h" +#include "mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), m_DisplayWidget(NULL) +{ + m_DisplayWidget = new MainWidget(this); + + m_DisplayWidget->setBackgroundColor(black); + m_DisplayWidget->setFocus(); + + setCentralWidget(m_DisplayWidget); +} + +MainWindow::~MainWindow() + { + } + +void MainWindow::closeEvent(QCloseEvent *e) +{ + if (m_DisplayWidget) + m_DisplayWidget->close(); + + e->ignore(); + QMainWindow::closeEvent(e); +} diff -urN gnuboy-1.0.3-orig/sys/qtopia/mainwindow.h gnuboy-1.0.3/sys/qtopia/mainwindow.h --- gnuboy-1.0.3-orig/sys/qtopia/mainwindow.h Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/sys/qtopia/mainwindow.h Thu Dec 27 08:46:03 2001 @@ -0,0 +1,22 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QCloseEvent; +class MainWindow : public QMainWindow +{ + public: + MainWindow(QWidget *parent); + ~MainWindow(); + + QWidget *displayWidget() { return m_DisplayWidget; } + + protected: + virtual void closeEvent(QCloseEvent *e); + + private: + QWidget *m_DisplayWidget; +}; + +#endif diff -urN gnuboy-1.0.3-orig/sys/qtopia/qtopia.cpp gnuboy-1.0.3/sys/qtopia/qtopia.cpp --- gnuboy-1.0.3-orig/sys/qtopia/qtopia.cpp Wed Dec 31 19:00:00 1969 +++ gnuboy-1.0.3/sys/qtopia/qtopia.cpp Thu Dec 27 08:46:03 2001 @@ -0,0 +1,233 @@ +#include +#include +#include + +#ifdef QWS +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" + +extern "C" { +#include "fb.h" +#include "rc.h" +} + +static char * argv[1] = { "qtopiagnuboy" }; +static int argc = 1; +struct fb fb; + +// Set the scalling here. Just be aware that scalling takes a lot of CPU! +static float scale = 1; + + +#ifdef QWS +static QPEApplication qtopia_app(argc, argv); +#else +static QApplication qtopia_app(argc, argv); +#endif + +static QImage qtopia_image(160, 144, 32, 0, QImage::LittleEndian); +static MainWindow qtopia_window(NULL); +static QPainter qtopia_display_painter; +static QWidget *qtopia_display; + + +rcvar_t vid_exports[] = { + RCV_END +}; + +rcvar_t joy_exports[] = { + RCV_END +}; + +extern "C" { + +void vid_resize() +{ + printf("vid_resize\n"); +} + +void vid_preinit() +{ + //printf("vid_preinit\n"); + + qtopia_display = qtopia_window.displayWidget(); + qtopia_app.setMainWidget(&qtopia_window); + +#ifdef QWS + qtopia_window.showMaximized(); +#else + qtopia_window.setGeometry(0, 0, 240, 320); + qtopia_window.show(); +#endif +} + +void vid_init() +{ + //printf("vid_init\n"); + + int red_length, green_length, blue_length; + int red_offset, green_offset, blue_offset; + + fb.w = qtopia_image.width(); + fb.h = qtopia_image.height(); + fb.pitch = qtopia_image.bytesPerLine(); + fb.ptr = qtopia_image.bits(); + + fb.pelsize = qtopia_image.depth() / 8; + fb.indexed = (qtopia_image.depth() == 8) ? 1 : 0; + + // Magic 'make work' code copied from thinlib + switch (qtopia_image.depth()) + { + case 8: + red_length = 0; + green_length = 0; + blue_length = 0; + red_offset = 0; + green_offset = 0; + blue_offset = 0; + break; + + case 16: + red_length = 5; + green_length = 6; + blue_length = 5; + red_offset = 11; + green_offset = 5; + blue_offset = 0; + break; + + case 32: + red_length = 8; + green_length = 8; + blue_length = 8; + red_offset = 16; + green_offset = 8; + blue_offset = 0; + break; + + case 15: + case 24: + default: + printf("i don't know what to do with %d bpp mode", + qtopia_image.depth()); + abort(); + break; + } + + fb.cc[0].r = 8 - red_length; + fb.cc[1].r = 8 - green_length; + fb.cc[2].r = 8 - blue_length; + fb.cc[0].l = red_offset; + fb.cc[1].l = green_offset; + fb.cc[2].l = blue_offset; + + fb.enabled = 1; + fb.dirty = 0; +} + +void vid_close() +{ + printf("vid_close\n"); + + // if the main window is still showing, hide it + if (qtopia_window.isVisible()) + qtopia_window.hide(); +} + +void vid_end() +{ + //printf("vid_end\n"); + + static int skipThisEvent = 0; + + // Try to lighten the load on the CPU. This might make things too jittery + if (skipThisEvent < 3) + { + skipThisEvent++; + return; + } + + skipThisEvent = 0; + int x = 0; + int y = 0; + QImage image; + + if (scale != 1) + { + int newWidth = (int)(qtopia_image.width() * scale); + int newHeight = (int)(qtopia_image.height() * scale); + + image = qtopia_image.smoothScale(newWidth, newHeight); + } + else + { + // This shouldn't cost anything since Qt does shared memory + image = qtopia_image; + } + + // Center the image + x = qtopia_display->width() / 2; + x = x - image.width() / 2; + + y = qtopia_display->height() / 2; + y = y - image.height() / 2; + + qtopia_display_painter.begin(qtopia_display); + qtopia_display_painter.drawImage(x, y, image); + qtopia_display_painter.end(); +} + +void vid_settitle(char *title) +{ + printf("vid_settitle\n"); + + QString caption("Qtopia GnuBoy: "); + caption += title; + + qtopia_window.setCaption(caption); +} + +void vid_setpal(int i, int r, int g, int b) +{ + printf("vid_setpal\n"); + + // This doesn't seem to actually work. Maybe someone who understands + // graphics and fix this. -mike + qtopia_image.setColor(i, qRgb(r, g, b)); +} + +void vid_begin() +{ + //printf("vid_begin\n"); +} + +void ev_poll() +{ + //printf("ev_poll"); + + static bool skipThisEvent = true; + + // QApp will process multiple events at the same time, so it + // should be ok to skip every other call to process events. + // Hopefully this will buy us some speed. + + if (!skipThisEvent) + qApp->processEvents(); + + skipThisEvent = !skipThisEvent; + +} + +}