diff --git a/games-emulation/dosbox/dosbox-0.74-r1.ebuild b/games-emulation/dosbox/dosbox-0.74-r1.ebuild new file mode 100644 index 0000000000000..80989eae06af7 --- /dev/null +++ b/games-emulation/dosbox/dosbox-0.74-r1.ebuild @@ -0,0 +1,51 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=5 +inherit eutils games + +DESCRIPTION="DOS emulator" +HOMEPAGE="http://dosbox.sourceforge.net/" +SRC_URI="mirror://sourceforge/dosbox/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~arm ~ppc ~ppc64 ~sparc ~x86" +IUSE="alsa debug hardened opengl" + +DEPEND="alsa? ( media-libs/alsa-lib ) + debug? ( sys-libs/ncurses:0 ) + opengl? ( virtual/glu virtual/opengl ) + media-libs/libpng:0 + media-libs/libsdl[joystick,video,X] + media-libs/sdl-net + media-libs/sdl-sound" +RDEPEND=${DEPEND} + +PATCHES=( + "${FILESDIR}"/${P}-clang.patch + "${FILESDIR}"/${P}-gcc46.patch + "${FILESDIR}"/${P}-wine-drive-z.patch + "${FILESDIR}"/${P}-wine-filenames.patch +) + +src_prepare() { + epatch -p1 "${PATCHES[@]}" +} + +src_configure() { + egamesconf \ + $(use_enable alsa alsa-midi) \ + $(use_enable !hardened dynamic-core) \ + $(use_enable !hardened dynamic-x86) \ + $(use_enable debug) \ + $(use_enable opengl) +} + +src_install() { + default + make_desktop_entry dosbox DOSBox /usr/share/pixmaps/dosbox.ico + doicon src/dosbox.ico + prepgamesdirs +} diff --git a/games-emulation/dosbox/files/dosbox-0.74-clang.patch b/games-emulation/dosbox/files/dosbox-0.74-clang.patch new file mode 100644 index 0000000000000..df2923f5caf90 --- /dev/null +++ b/games-emulation/dosbox/files/dosbox-0.74-clang.patch @@ -0,0 +1,48 @@ +Gentoo-Bug: https://bugs.gentoo.org/show_bug.cgi?id=449060 + +Two backports from Dosbox SVN needed for clang support: +src/fpu/fpu_instructions_x86.h changes are revision 3841 +src/cpu/core_dynrec/risc_x64.h changes are revision 3894 + +Index: src/fpu/fpu_instructions_x86.h +=================================================================== +--- a/src/fpu/fpu_instructions_x86.h (revision 3840) ++++ b/src/fpu/fpu_instructions_x86.h (revision 3841) +@@ -1161,12 +1161,12 @@ + + static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { + fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); +- FPUD_LOAD(fild,WORD,) ++ FPUD_LOAD(fild,WORD,s) + } + + static void FPU_FLD_I16_EA(PhysPt addr) { + fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); +- FPUD_LOAD_EA(fild,WORD,) ++ FPUD_LOAD_EA(fild,WORD,s) + } + + static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { +@@ -1211,7 +1211,7 @@ + } + + static void FPU_FST_I16(PhysPt addr) { +- FPUD_STORE(fistp,WORD,) ++ FPUD_STORE(fistp,WORD,s) + mem_writew(addr,(Bit16u)fpu.p_regs[8].m1); + } + +Index: src/cpu/core_dynrec/risc_x64.h +=================================================================== +--- a/src/cpu/core_dynrec/risc_x64.h (revision 3893) ++++ b/src/cpu/core_dynrec/risc_x64.h (revision 3894) +@@ -85,7 +85,8 @@ + + static INLINE void gen_reg_memaddr(HostReg reg,void* data) { + Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+5); +- if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { ++// if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { //clang messes itself up on this... ++ if ( (diff>>63) == (diff>>31) ) { //signed bit extend, test to see if value fits in a Bit32s + cache_addb(0x05+(reg<<3)); + // RIP-relative addressing is offset after the instruction + cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); diff --git a/games-emulation/dosbox/files/dosbox-0.74-gcc46.patch b/games-emulation/dosbox/files/dosbox-0.74-gcc46.patch index 16811d47d6404..54cd51bb82bd2 100644 --- a/games-emulation/dosbox/files/dosbox-0.74-gcc46.patch +++ b/games-emulation/dosbox/files/dosbox-0.74-gcc46.patch @@ -1,5 +1,5 @@ ---- include/dos_inc.h.old 2011-04-28 08:46:04.505011354 +0200 -+++ include/dos_inc.h 2011-04-28 08:46:27.104408178 +0200 +--- a/include/dos_inc.h.old 2011-04-28 08:46:04.505011354 +0200 ++++ b/include/dos_inc.h 2011-04-28 08:46:27.104408178 +0200 @@ -21,6 +21,7 @@ #ifndef DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H diff --git a/games-emulation/dosbox/files/dosbox-0.74-wine-drive-z.patch b/games-emulation/dosbox/files/dosbox-0.74-wine-drive-z.patch new file mode 100644 index 0000000000000..848d3e7b2c623 --- /dev/null +++ b/games-emulation/dosbox/files/dosbox-0.74-wine-drive-z.patch @@ -0,0 +1,151 @@ +From Debian (which backported the patch): +https://packages.debian.org/sid/dosbox + +Description: Rewrite mount without arguments to display volume label as well. + Some refactoring of the code. + Add mount -z X, where X is the new virtual drive for the Wine Team. +Origin: upstream, http://sourceforge.net/p/dosbox/code-0/3736/ +Author: Peter Veenstra +Last-Update: 2011-07-23 +--- a/src/dos/dos_programs.cpp ++++ b/src/dos/dos_programs.cpp +@@ -49,27 +49,55 @@ + #endif + + void MSCDEX_SetCDInterface(int intNr, int forceCD); +- ++static Bitu ZDRIVE_NUM = 25; + + class MOUNT : public Program { + public: +- void Run(void) +- { ++ void ListMounts(void) { ++ char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; ++ /* Command uses dta so set it to our internal dta */ ++ RealPt save_dta = dos.dta(); ++ dos.dta(dos.tables.tempdta); ++ DOS_DTA dta(dos.dta()); ++ ++ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); ++ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),"Drive","Type","Label"); ++ for(int p = 0;p < 8;p++) WriteOut("----------"); ++ ++ for (int d = 0;d < DOS_DRIVES;d++) { ++ if (!Drives[d]) continue; ++ ++ char root[4] = {'A'+d,':','\\',0}; ++ bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME); ++ if (ret) { ++ dta.GetResult(name,size,date,time,attr); ++ DOS_FindNext(); //Mark entry as invalid ++ } else name[0] = 0; ++ ++ /* Change 8.3 to 11.0 */ ++ char* dot = strchr(name,'.'); ++ if(dot && (dot - name == 8) ) { ++ name[8] = name[9];name[9] = name[10];name[10] = name[11];name[11] = 0; ++ } ++ ++ root[1] = 0; //This way, the format string can be reused. ++ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),root, Drives[d]->GetInfo(),name); ++ } ++ dos.dta(save_dta); ++ } ++ ++ void Run(void) { + DOS_Drive * newdrive;char drive; + std::string label; + std::string umount; ++ std::string newz; + + //Hack To allow long commandlines + ChangeToLongCmd(); + /* Parse the command line */ + /* if the command line is empty show current mounts */ + if (!cmd->GetCount()) { +- WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1")); +- for (int d=0;dGetInfo()); +- } +- } ++ ListMounts(); + return; + } + +@@ -84,12 +112,12 @@ + if (cmd->FindString("-u",umount,false)) { + umount[0] = toupper(umount[0]); + int i_drive = umount[0]-'A'; +- if(i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { ++ if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) { + switch (DriveManager::UnmountDrive(i_drive)) { + case 0: + Drives[i_drive] = 0; + if(i_drive == DOS_GetDefaultDrive()) +- DOS_SetDrive(toupper('Z') - 'A'); ++ DOS_SetDrive(ZDRIVE_NUM); + WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]); + break; + case 1: +@@ -104,8 +132,46 @@ + } + return; + } +- +- // Show list of cdroms ++ ++ /* Check for moving Z: */ ++ /* Only allowing moving it once. It is merely a convenience added for the wine team */ ++ if (ZDRIVE_NUM == 25 && cmd->FindString("-z", newz,false)) { ++ newz[0] = toupper(newz[0]); ++ int i_newz = newz[0] - 'A'; ++ if (i_newz >= 0 && i_newz < DOS_DRIVES-1 && !Drives[i_newz]) { ++ ZDRIVE_NUM = i_newz; ++ /* remap drives */ ++ Drives[i_newz] = Drives[25]; ++ Drives[25] = 0; ++ DOS_Shell *fs = static_cast(first_shell); //dynamic ? ++ /* Update environment */ ++ std::string line = ""; ++ char ppp[2] = {newz[0],0}; ++ std::string tempenv = ppp; tempenv += ":\\"; ++ if (fs->GetEnvStr("PATH",line)){ ++ std::string::size_type idx = line.find('='); ++ std::string value = line.substr(idx +1 , std::string::npos); ++ while ( (idx = value.find("Z:\\")) != std::string::npos || ++ (idx = value.find("z:\\")) != std::string::npos ) ++ value.replace(idx,3,tempenv); ++ line = value; ++ } ++ if (!line.size()) line = tempenv; ++ fs->SetEnv("PATH",line.c_str()); ++ tempenv += "COMMAND.COM"; ++ fs->SetEnv("COMSPEC",tempenv.c_str()); ++ ++ /* Update batch file if running from Z: (very likely: autoexec) */ ++ if(fs->bf) { ++ std::string &name = fs->bf->filename; ++ if(name.length() >2 && name[0] == 'Z' && name[1] == ':') name[0] = newz[0]; ++ } ++ /* Change the active drive */ ++ if (DOS_GetDefaultDrive() == 25) DOS_SetDrive(i_newz); ++ } ++ return; ++ } ++ /* Show list of cdroms */ + if (cmd->FindExist("-cd",false)) { + int num = SDL_CDNumDrives(); + WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num); +@@ -1347,8 +1413,9 @@ + /*Add Messages */ + + MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n"); ++ MSG_Add("PROGRAM_MOUNT_STATUS_FORMAT","%-5s %-58s %-12s\n"); + MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); +- MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); ++ MSG_Add("PROGRAM_MOUNT_STATUS_1","The currently mounted drives are:\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); + MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n"); + MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n"); diff --git a/games-emulation/dosbox/files/dosbox-0.74-wine-filenames.patch b/games-emulation/dosbox/files/dosbox-0.74-wine-filenames.patch new file mode 100644 index 0000000000000..89e24335bbc90 --- /dev/null +++ b/games-emulation/dosbox/files/dosbox-0.74-wine-filenames.patch @@ -0,0 +1,89 @@ +Description: Be friendly for other open source projects: work with WINE style namemangling. + Patch 3382938 from Andre_H (modified). +Origin: upstream, http://sourceforge.net/p/dosbox/code-0/3743/ +Author: Peter Veenstra +Last-Update: 2011-08-30 +--- a/src/dos/drive_cache.cpp ++++ b/src/dos/drive_cache.cpp +@@ -370,6 +370,60 @@ + return false; + } + ++#define WINE_DRIVE_SUPPORT 1 ++#if WINE_DRIVE_SUPPORT ++//Changes to interact with WINE by supporting their namemangling. ++//The code is rather slow, because orglist is unordered, so it needs to be avoided if possible. ++//Hence the tests in GetLongFileName ++ ++ ++// From the Wine project ++static Bits wine_hash_short_file_name( char* name, char* buffer ) ++{ ++ static const char hash_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; ++ static const char invalid_chars[] = { '*','?','<','>','|','"','+','=',',',';','[',']',' ','\345','~','.',0 }; ++ char* p; ++ char* ext; ++ char* end = name + strlen(name); ++ char* dst; ++ unsigned short hash; ++ int i; ++ ++ // Compute the hash code of the file name ++ for (p = name, hash = 0xbeef; p < end - 1; p++) ++ hash = (hash<<3) ^ (hash>>5) ^ tolower(*p) ^ (tolower(p[1]) << 8); ++ hash = (hash<<3) ^ (hash>>5) ^ tolower(*p); // Last character ++ ++ ++ // Find last dot for start of the extension ++ for (p = name + 1, ext = NULL; p < end - 1; p++) if (*p == '.') ext = p; ++ ++ // Copy first 4 chars, replacing invalid chars with '_' ++ for (i = 4, p = name, dst = buffer; i > 0; i--, p++) ++ { ++ if (p == end || p == ext) break; ++ *dst++ = (*p < 0 || strchr( invalid_chars, *p ) != NULL) ? '_' : toupper(*p); ++ } ++ // Pad to 5 chars with '~' ++ while (i-- >= 0) *dst++ = '~'; ++ ++ // Insert hash code converted to 3 ASCII chars ++ *dst++ = hash_chars[(hash >> 10) & 0x1f]; ++ *dst++ = hash_chars[(hash >> 5) & 0x1f]; ++ *dst++ = hash_chars[hash & 0x1f]; ++ ++ // Copy the first 3 chars of the extension (if any) ++ if (ext) ++ { ++ *dst++ = '.'; ++ for (i = 3, ext++; (i > 0) && ext < end; i--, ext++) ++ *dst++ = (*ext < 0 || strchr( invalid_chars, *ext ) != NULL) ? '_' : toupper(*ext); ++ } ++ ++ return dst - buffer; ++} ++#endif ++ + Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) { + std::vector::size_type filelist_size = curDir->fileList.size(); + if (GCC_UNLIKELY(filelist_size<=0)) return -1; +@@ -390,6 +444,20 @@ + return mid; + }; + } ++#ifdef WINE_DRIVE_SUPPORT ++ if (strlen(shortName) < 8 || shortName[4] != '~' || shortName[5] == '.' || shortName[6] == '.' || shortName[7] == '.') return -1; // not available ++ // else it's most likely a Wine style short name ABCD~###, # = not dot (length at least 8) ++ // The above test is rather strict as the following loop can be really slow if filelist_size is large. ++ char buff[CROSS_LEN]; ++ for (Bits i = 0; i < filelist_size; i++) { ++ res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff); ++ if (!strncmp(shortName,buff,res)) ++ { // Found ++ strcpy(shortName,curDir->fileList[i]->orgname); ++ return i; ++ }; ++ } ++#endif + // not available + return -1; + }