ALL: Sync with ScummVM - rev. 823c2f899b
This commit is contained in:
parent
368d71cfd5
commit
9ba9c69b3f
241 changed files with 35724 additions and 10087 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -9,6 +9,7 @@ lib*.a
|
||||||
/config.log
|
/config.log
|
||||||
/residualvm
|
/residualvm
|
||||||
/residualvm-static
|
/residualvm-static
|
||||||
|
/ResidualVMDockTilePlugin*
|
||||||
/config.h
|
/config.h
|
||||||
/config.mk
|
/config.mk
|
||||||
/.gdb_history
|
/.gdb_history
|
||||||
|
@ -19,6 +20,7 @@ lib*.a
|
||||||
/MT32_CONTROL.ROM
|
/MT32_CONTROL.ROM
|
||||||
/MT32_PCM.ROM
|
/MT32_PCM.ROM
|
||||||
/ResidualVM.app
|
/ResidualVM.app
|
||||||
|
/residualvm.docktileplugin
|
||||||
/residualvm-ps3.pkg
|
/residualvm-ps3.pkg
|
||||||
/*.ipk
|
/*.ipk
|
||||||
/*.dmg
|
/*.dmg
|
||||||
|
@ -29,6 +31,7 @@ lib*.a
|
||||||
/Icon.*
|
/Icon.*
|
||||||
/*.m4b
|
/*.m4b
|
||||||
/*.lab
|
/*.lab
|
||||||
|
/*.dat
|
||||||
|
|
||||||
/build
|
/build
|
||||||
/staging
|
/staging
|
||||||
|
@ -79,6 +82,7 @@ project.xcworkspace
|
||||||
/test/*.dSYM
|
/test/*.dSYM
|
||||||
|
|
||||||
/devtools/create_project/create_project
|
/devtools/create_project/create_project
|
||||||
|
/devtools/create_translations/create_translations
|
||||||
|
|
||||||
#ignore thumbnails created by windows
|
#ignore thumbnails created by windows
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
@ -113,10 +117,15 @@ ipch/
|
||||||
*.vcxproj*
|
*.vcxproj*
|
||||||
*.bat
|
*.bat
|
||||||
*.tss
|
*.tss
|
||||||
|
*.VC.db
|
||||||
|
|
||||||
#Ignore default Visual Studio build folders
|
#Ignore default Visual Studio build folders
|
||||||
[Dd]ebug*/
|
[Dd]ebug/
|
||||||
[Rr]elease*/
|
[Rr]elease/
|
||||||
|
[Dd]ebug32/
|
||||||
|
[Rr]elease32/
|
||||||
|
[Dd]ebug64/
|
||||||
|
[Rr]elease64/
|
||||||
LLVM32/
|
LLVM32/
|
||||||
LLVM64/
|
LLVM64/
|
||||||
|
|
||||||
|
|
40
.travis.yml
Normal file
40
.travis.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
language:
|
||||||
|
- cpp
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- g++ make
|
||||||
|
- libsdl1.2-dev
|
||||||
|
- libjpeg62-turbo-dev
|
||||||
|
- libmpeg2-4-dev
|
||||||
|
- libogg-dev
|
||||||
|
- libvorbis-dev
|
||||||
|
- libflac-dev
|
||||||
|
- libmad0-dev
|
||||||
|
- libpng-dev
|
||||||
|
- libglew-dev
|
||||||
|
- libtheora-dev
|
||||||
|
- libfaad-dev
|
||||||
|
- libfluidsynth-dev
|
||||||
|
- libfreetype6-dev
|
||||||
|
- zlib1g-dev
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./configure --enable-all-engines --disable-eventrecorder
|
||||||
|
- make -j 2
|
||||||
|
- make test
|
||||||
|
- make devtools
|
274
COPYRIGHT
274
COPYRIGHT
|
@ -59,214 +59,404 @@ Copyright (C) 2001-2016 by the following:
|
||||||
If you have contributed to this project then you deserve to be on this
|
If you have contributed to this project then you deserve to be on this
|
||||||
list. Contact us (see: AUTHORS) and we'll add you.
|
list. Contact us (see: AUTHORS) and we'll add you.
|
||||||
|
|
||||||
Tore Anderson
|
Manuel Alfayate
|
||||||
Torbjorn Andersson
|
Torbjorn Andersson
|
||||||
|
Tore Anderson
|
||||||
|
Matteo Angelino
|
||||||
Chris Apers
|
Chris Apers
|
||||||
|
Adrian Astley
|
||||||
|
Bertrand Augereau
|
||||||
Ori Avtalion
|
Ori Avtalion
|
||||||
Nicolas Bacca
|
Nicolas Bacca
|
||||||
|
Dobo Balazs
|
||||||
|
Daniel Balsom
|
||||||
|
Yotam Barnoy
|
||||||
Fabio Battaglia
|
Fabio Battaglia
|
||||||
|
Vincent Benony
|
||||||
|
Alex Bevilacqua
|
||||||
|
Laurent Blume
|
||||||
Bastien Bouclet
|
Bastien Bouclet
|
||||||
Arnaud Boutonne
|
Arnaud Boutonne
|
||||||
|
Francois-R Boyer
|
||||||
|
Peter Bozso
|
||||||
Jurgen Braam
|
Jurgen Braam
|
||||||
Ralph Brorsen
|
Ralph Brorsen
|
||||||
James Brown
|
James Brown
|
||||||
|
Henry Bush
|
||||||
Stuart Caie
|
Stuart Caie
|
||||||
|
Rainer Canavan
|
||||||
|
Ben Castricum
|
||||||
|
Xiaojun Chen
|
||||||
Jamieson Christian
|
Jamieson Christian
|
||||||
|
Ryan Clark
|
||||||
|
William Claydon
|
||||||
|
Fabien Coeurjoly
|
||||||
Marcus Comstedt
|
Marcus Comstedt
|
||||||
|
David Corrales-Lopez
|
||||||
Paolo Costabel
|
Paolo Costabel
|
||||||
|
Robert Crossfield
|
||||||
Thierry Crozat
|
Thierry Crozat
|
||||||
|
Vyacheslav Dikonov
|
||||||
|
Paul David Doherty
|
||||||
|
Martin Doucha
|
||||||
Ivan Dubrov
|
Ivan Dubrov
|
||||||
Frantisek Dufka
|
Frantisek Dufka
|
||||||
|
Sylvain Dupont
|
||||||
|
Joachim Eberhard
|
||||||
|
Thomas Edvalson
|
||||||
Oystein Eftevaag
|
Oystein Eftevaag
|
||||||
Kovacs Endre Janos
|
|
||||||
David Eriksson
|
David Eriksson
|
||||||
|
Thomas Fach-Pedersen
|
||||||
|
Yaroslav Fedevych
|
||||||
Jerome Fisher
|
Jerome Fisher
|
||||||
|
Hampus Flink
|
||||||
|
Hans-Joerg Frieden
|
||||||
|
Greg Frieger
|
||||||
|
Tom Frost
|
||||||
Stuart George
|
Stuart George
|
||||||
Paul Gilbert
|
Paul Gilbert
|
||||||
|
Jean Marc Gimenez
|
||||||
Robert Goeffringmann
|
Robert Goeffringmann
|
||||||
|
Victor Gonzalez
|
||||||
|
GrajPoPolsku.pl Team
|
||||||
|
Chris Gray
|
||||||
Jonathan Gray
|
Jonathan Gray
|
||||||
|
Tobias Gunkel
|
||||||
Benjamin Haisch
|
Benjamin Haisch
|
||||||
Vincent Hamm
|
Vincent Hamm
|
||||||
|
Ruediger Hanke
|
||||||
|
Matt Hargett
|
||||||
|
Andre Heider
|
||||||
Sven Hesse
|
Sven Hesse
|
||||||
Jochen Hoenicke
|
Jochen Hoenicke
|
||||||
Matthew Hoops
|
Matthew Hoops
|
||||||
Max Horn
|
Max Horn
|
||||||
Travis Howell
|
Travis Howell
|
||||||
Janne Huttunen
|
Janne Huttunen
|
||||||
|
Ravi I.
|
||||||
Felix Jakschitsch
|
Felix Jakschitsch
|
||||||
|
Kovacs Endre Janos
|
||||||
Jeroen Janssen
|
Jeroen Janssen
|
||||||
|
Emmanuel Jeandel
|
||||||
|
Dmitry Jemerov
|
||||||
|
David Jensen
|
||||||
Florian Kagerer
|
Florian Kagerer
|
||||||
|
Keith Kaisershot
|
||||||
Filippos Karapetis
|
Filippos Karapetis
|
||||||
Andreas Karlsson
|
Andreas Karlsson
|
||||||
|
Denis Kasak
|
||||||
|
Chris Kehler
|
||||||
|
Robert Kelsen
|
||||||
Ismail Khatib
|
Ismail Khatib
|
||||||
Oliver Kiehl
|
Oliver Kiehl
|
||||||
Martin Kiewitz
|
Martin Kiewitz
|
||||||
Pawel Kolodziejski
|
Pawel Kolodziejski
|
||||||
|
George Kormendi
|
||||||
Mutwin Kraus
|
Mutwin Kraus
|
||||||
|
Stefan Kristiansson
|
||||||
Andrew Kurushin
|
Andrew Kurushin
|
||||||
|
Daniel ter Laan
|
||||||
|
Hugo Labrande
|
||||||
|
Christopher T. Lansdown
|
||||||
|
Sergey Lapin
|
||||||
Angus Lees
|
Angus Lees
|
||||||
|
Rickard Lind
|
||||||
|
Max Lingua
|
||||||
|
Lubomyr Lisen
|
||||||
|
Ivan Lukyanov
|
||||||
|
Tomas Maidagan
|
||||||
|
Hubert Maier
|
||||||
|
Johannes Manhave
|
||||||
|
Lothar Serra Mari
|
||||||
|
Vicent Marti
|
||||||
Claudio Matsuoka
|
Claudio Matsuoka
|
||||||
Thomas Mayer
|
Thomas Mayer
|
||||||
|
Robert Megone
|
||||||
|
Vladimir Menshakov
|
||||||
Alyssa Milburn
|
Alyssa Milburn
|
||||||
Neil Millstone
|
Neil Millstone
|
||||||
|
Dark Minister
|
||||||
Gregory Montoir
|
Gregory Montoir
|
||||||
|
Peter Moraliyski
|
||||||
|
Carl Muckenhoupt
|
||||||
|
Alejandro Gomez de la Munoza
|
||||||
|
Sean Murray
|
||||||
Kostas Nakos
|
Kostas Nakos
|
||||||
Mikesch Nepomuk
|
Mikesch Nepomuk
|
||||||
|
Jeremy Newman
|
||||||
|
Anders Baden Nielsen
|
||||||
|
Juha Niemimaki
|
||||||
|
Walter van Niftrik
|
||||||
Nicolas Noble
|
Nicolas Noble
|
||||||
|
Steffen Nyeland
|
||||||
|
Rune Orsval
|
||||||
|
Chris Page
|
||||||
Willem Jan Palenstijn
|
Willem Jan Palenstijn
|
||||||
|
Stefan Parviainen
|
||||||
|
Solomon Peachy
|
||||||
Lars Persson
|
Lars Persson
|
||||||
Joost Peters
|
Joost Peters
|
||||||
Tim Phillips
|
Tim Phillips
|
||||||
|
Robey Pointer
|
||||||
|
Jordi Vilalta Prat
|
||||||
|
Magnus Reftel
|
||||||
|
Christoph Reichenbach
|
||||||
|
George Reid
|
||||||
|
Klaus Reimer
|
||||||
|
Andreas Roever
|
||||||
Edward Rudd
|
Edward Rudd
|
||||||
|
Toni Saarela
|
||||||
|
Kari Salminen
|
||||||
Eugene Sandulenko
|
Eugene Sandulenko
|
||||||
|
Santiago G. Sanz
|
||||||
|
Simon Sawatzki
|
||||||
|
Daniel Schepler
|
||||||
|
Dominik Scherer
|
||||||
Johannes Schickel
|
Johannes Schickel
|
||||||
|
Luc Schrijvers
|
||||||
|
Zbynik Schwarz
|
||||||
Keith Scroggins
|
Keith Scroggins
|
||||||
|
Dan Serban
|
||||||
|
Lars Skovlund
|
||||||
|
Paul Smedley
|
||||||
|
Colin Snover
|
||||||
|
Tarek Soliman
|
||||||
|
Einar Johan T. Somaaen
|
||||||
|
Andre Souza
|
||||||
|
Robert Spalek
|
||||||
|
Rink Springer
|
||||||
Won Star
|
Won Star
|
||||||
|
Markus Strangl
|
||||||
Ludvig Strigeus
|
Ludvig Strigeus
|
||||||
Fedor Strizhniou
|
Fedor Strizhniou
|
||||||
David Symonds
|
David Symonds
|
||||||
Jordi Vilalta
|
Rainer De Temple
|
||||||
|
Julien Templier
|
||||||
|
Sean Terrell
|
||||||
|
Tobia Tesan
|
||||||
|
Scott Thomas
|
||||||
|
David Turner
|
||||||
|
Lionel Ulmer
|
||||||
|
Mikel Iturbe Urretxa
|
||||||
|
Hugues Valois
|
||||||
|
Petr Vyhnak
|
||||||
|
Chris Warren-Smith
|
||||||
Robin Watts
|
Robin Watts
|
||||||
|
Lukasz Watka
|
||||||
|
David Weinehall
|
||||||
|
Fredrik Wendel
|
||||||
John Willis
|
John Willis
|
||||||
|
Anton Yarcev
|
||||||
|
Bas Zoetekouw
|
||||||
Jezar
|
Jezar
|
||||||
n0p
|
n0p
|
||||||
peres
|
peres
|
||||||
Quietust
|
Quietust
|
||||||
|
ScummBR Team
|
||||||
|
Raina
|
||||||
|
|
||||||
|
|
||||||
Patches contributed by:
|
Patches contributed by:
|
||||||
|
|
||||||
Laura Abbott "sageofminerva"
|
Laura Abbott "sageofminerva"
|
||||||
Vikram Aggarwal "youngelf"
|
Vikram Aggarwal "youngelf"
|
||||||
the rara avis "theraraavis"
|
Norbert Bajko
|
||||||
|
Giovanni Bajo
|
||||||
|
Matan Bareket
|
||||||
Dieter Baron "dillo"
|
Dieter Baron "dillo"
|
||||||
|
Kevin Becker
|
||||||
Alban Bedel "albeu"
|
Alban Bedel "albeu"
|
||||||
Bodo Bellut "bellut"
|
Bodo Bellut "bellut"
|
||||||
Bramvandijk "bramvandijk"
|
Nagy Bendeguz
|
||||||
Andreas Bierfert "awjb"
|
Andreas Bierfert "awjb"
|
||||||
|
Kaustav Biswas
|
||||||
Elio Blanca "eblanca76"
|
Elio Blanca "eblanca76"
|
||||||
|
Martin Bohm
|
||||||
David Breakey "dbreakey"
|
David Breakey "dbreakey"
|
||||||
|
Michael du Breuil "WickedShell"
|
||||||
|
Michael Brown
|
||||||
Robert Buchholz "prendi"
|
Robert Buchholz "prendi"
|
||||||
Rainer Canavan "canavan"
|
Sander Buskens
|
||||||
|
Giulio Camuffo
|
||||||
|
Kevin Carnes
|
||||||
Mathieu Carot "yokna"
|
Mathieu Carot "yokna"
|
||||||
Stefano Ceccherini "jackburton"
|
Stefano Ceccherini "jackburton"
|
||||||
Travis S Coady "theealien"
|
Travis S Coady "theealien"
|
||||||
Josh Coalson "jcoalson"
|
Josh Coalson "jcoalson"
|
||||||
|
Curt Coder
|
||||||
Thomas Combeleran "hibernatus"
|
Thomas Combeleran "hibernatus"
|
||||||
|
Patrick Combet
|
||||||
Kees Cook "keescook"
|
Kees Cook "keescook"
|
||||||
Carlos Corbacho "cathectic"
|
Carlos Corbacho "cathectic"
|
||||||
|
Andrea Corna
|
||||||
Roberto Costa "fiix76"
|
Roberto Costa "fiix76"
|
||||||
dc france "erwan2004"
|
Eric Culp
|
||||||
dewt "mncl"
|
Alexander Dergunov
|
||||||
Martin Doucha "next_ghost"
|
Alexandre Detiste
|
||||||
|
Roman Donchenko
|
||||||
|
Heather Douglass
|
||||||
Michael Drueing "doc_wagon"
|
Michael Drueing "doc_wagon"
|
||||||
Michael du Breuil "WickedShell"
|
|
||||||
dubsdj
|
|
||||||
Matthew Duggan "stauff1"
|
Matthew Duggan "stauff1"
|
||||||
|
Barry Duncan
|
||||||
Olivier Duverne "richiefs"
|
Olivier Duverne "richiefs"
|
||||||
Andrei Dziahel "develop7"
|
Andrei Dziahel "develop7"
|
||||||
John Eckerdal "johneck"
|
John Eckerdal "johneck"
|
||||||
Thomas Fach-Pedersen "madm00se"
|
Abdeselam El-Haman
|
||||||
Florent "flobo"
|
Henrik Engqvist
|
||||||
Florob "florob"
|
|
||||||
Mike Frysinger "vapier"
|
Mike Frysinger "vapier"
|
||||||
|
Bence Gazder
|
||||||
Chris Gelatt "kreeblah"
|
Chris Gelatt "kreeblah"
|
||||||
Jens Georg "phako"
|
Jens Georg "phako"
|
||||||
Nicolas George "cigaes"
|
Nicolas George "cigaes"
|
||||||
|
Martin Gerhardy
|
||||||
Jonathan Gevaryahu "lord_nightmare"
|
Jonathan Gevaryahu "lord_nightmare"
|
||||||
|
Boris Gnezdilov
|
||||||
Tobias Gruetzmacher "tobig"
|
Tobias Gruetzmacher "tobig"
|
||||||
Damien Guard "damienguard"
|
Damien Guard "damienguard"
|
||||||
Tobias Gunkel "tobigun"
|
|
||||||
Matti Hamalainen "ccrtnsp"
|
Matti Hamalainen "ccrtnsp"
|
||||||
Matt Hargett "matt_hargett"
|
Lauri Harsila
|
||||||
Stefan Haubenthal "polluks"
|
Stefan Haubenthal "polluks"
|
||||||
|
Gavin Hayler
|
||||||
Alexander Holler "holler"
|
Alexander Holler "holler"
|
||||||
|
Enrico Horn
|
||||||
Falk Hueffner "mellum"
|
Falk Hueffner "mellum"
|
||||||
Casey Hutchinson "nnooiissee"
|
Casey Hutchinson "nnooiissee"
|
||||||
j0tt
|
Tomas Jakobsson
|
||||||
Gregor Jasny "gjasny"
|
Gregor Jasny "gjasny"
|
||||||
Jellby "jellby"
|
|
||||||
Joerg "macdrega"
|
|
||||||
Matt Johnson "mattjon"
|
Matt Johnson "mattjon"
|
||||||
Nicolas Joly "njoly"
|
Nicolas Joly "njoly"
|
||||||
KeithS "keithscr"
|
Yusuke Kamiyamane
|
||||||
|
Martin Kennedy
|
||||||
|
Stephen Kennedy
|
||||||
Sam Kenny "sam_k"
|
Sam Kenny "sam_k"
|
||||||
Koen Kooi "koenkooi"
|
Koen Kooi "koenkooi"
|
||||||
|
Christoph Korn
|
||||||
|
Christian Krause
|
||||||
|
Till Kresslein
|
||||||
Zygmunt Krynicki "zygoon"
|
Zygmunt Krynicki "zygoon"
|
||||||
Janne Kujanpaa "jukuja"
|
Janne Kujanpaa "jukuja"
|
||||||
|
Neeraj Kumar
|
||||||
|
Oleksiy Kurochko
|
||||||
Jay Lanagan "r0ni"
|
Jay Lanagan "r0ni"
|
||||||
Norbert Lange "nolange"
|
Norbert Lange "nolange"
|
||||||
Manuel Lauss "mlau2"
|
Manuel Lauss "mlau2"
|
||||||
Rolf Leggewie "leggewie"
|
Rolf Leggewie "leggewie"
|
||||||
|
Jim Leiterman
|
||||||
|
Matt Lewandowsky
|
||||||
|
Chenbo Li
|
||||||
|
Rob Loach
|
||||||
Duncan Lock "dflock"
|
Duncan Lock "dflock"
|
||||||
Mark Lodato "itsr0y"
|
Mark Lodato "itsr0y"
|
||||||
Fridvin Logi "phillip_j_fry"
|
Fridvin Logi "phillip_j_fry"
|
||||||
Lostech "lostech"
|
Michael Lojkovic
|
||||||
|
Borja Lorente Escobar
|
||||||
Georg Lukas "ge0rg"
|
Georg Lukas "ge0rg"
|
||||||
|
Artem Lukoyanov
|
||||||
Michael Madsen "pidgeot"
|
Michael Madsen "pidgeot"
|
||||||
|
Matthias Mailander
|
||||||
|
Narek Mailian
|
||||||
|
Christoph Mallon
|
||||||
|
Engin Manap
|
||||||
Dmitry Marakasov "amdmi3"
|
Dmitry Marakasov "amdmi3"
|
||||||
Alejandro Marzini "vgvgf"
|
Alejandro Marzini "vgvgf"
|
||||||
Connor McLeod "mcleod2032"
|
Connor McLeod "mcleod2032"
|
||||||
Mickey McMurray "metafox"
|
Mickey McMurray "metafox"
|
||||||
Vladimir Menshakov "megath"
|
|
||||||
Adam Metcalf "gamblore"
|
Adam Metcalf "gamblore"
|
||||||
|
Nicola Mettifogo
|
||||||
Frank Meyering "frank_m24"
|
Frank Meyering "frank_m24"
|
||||||
Gael Le Migno "kilobug"
|
Gael Le Migno "kilobug"
|
||||||
|
Etienne Millon
|
||||||
Andy Molloy "maloi"
|
Andy Molloy "maloi"
|
||||||
Sean Murrau "lightcast"
|
Omer Mor
|
||||||
Armin Mueller "arm_in"
|
Armin Mueller "arm_in"
|
||||||
|
Sean Murrau "lightcast"
|
||||||
Andrea Musuruane "musuruan"
|
Andrea Musuruane "musuruan"
|
||||||
KO Myung-Hun "lvzuufx"
|
KO Myung-Hun "lvzuufx"
|
||||||
Markus Napp "meist3r"
|
Markus Napp "meist3r"
|
||||||
Peter Naulls "pnaulls"
|
Peter Naulls "pnaulls"
|
||||||
Christian Neumair "mannythegnome"
|
Christian Neumair "mannythegnome"
|
||||||
Nicos "anarxia"
|
Hannes Niederhausen
|
||||||
Juha Niemimaki "capehill"
|
|
||||||
Markus Niemisto "niemisto"
|
Markus Niemisto "niemisto"
|
||||||
ole
|
Bastien Nocera
|
||||||
|
Jody Northup
|
||||||
|
Julian Ospald
|
||||||
|
Christopher Page
|
||||||
Chris Paras "paras_rasmatazz"
|
Chris Paras "paras_rasmatazz"
|
||||||
Aubin Paul "outlyer"
|
Aubin Paul "outlyer"
|
||||||
|
Michael Pearce
|
||||||
Vincent Pelletier "subdino"
|
Vincent Pelletier "subdino"
|
||||||
phi1
|
Jussi Pitkanen
|
||||||
Pix2 "pix2"
|
|
||||||
Carsten Pohl "carstenpohl"
|
Carsten Pohl "carstenpohl"
|
||||||
|
Tony Puccinelli
|
||||||
Markus Pyykko "mankeli"
|
Markus Pyykko "mankeli"
|
||||||
Richard "trinity78"
|
Rodrigo Rebello
|
||||||
Felix Riemann "kirschsaft"
|
Alexander Reim
|
||||||
Thomas Richter "thorfdbg"
|
Thomas Richter "thorfdbg"
|
||||||
|
Felix Riemann "kirschsaft"
|
||||||
Timo Roehling "t1m0"
|
Timo Roehling "t1m0"
|
||||||
Andreas Roever "roever"
|
|
||||||
Jonathan Rogers "jonner"
|
Jonathan Rogers "jonner"
|
||||||
|
Enrico Rolfi
|
||||||
|
Doron Rosenberg
|
||||||
Marek Roth "logicdeluxe"
|
Marek Roth "logicdeluxe"
|
||||||
|
David Russo
|
||||||
Uwe Ryssel "uweryssel"
|
Uwe Ryssel "uweryssel"
|
||||||
Simon Sawatzki "simsaw"
|
|
||||||
Scarlatti "escarlate"
|
|
||||||
Daniel Schepler "dschepler"
|
|
||||||
Florian Schmitt "fatpenguin"
|
Florian Schmitt "fatpenguin"
|
||||||
Mark Schreiber "mark7"
|
Mark Schreiber "mark7"
|
||||||
Ben Shadwick "benshadwick"
|
Ben Shadwick "benshadwick"
|
||||||
|
Rodrigo Silva
|
||||||
Jean-Yves Simon "lethalwp"
|
Jean-Yves Simon "lethalwp"
|
||||||
Andrej Sinicyn "andrej4000"
|
Andrej Sinicyn "andrej4000"
|
||||||
Andre Souza "luke_br"
|
Dmitry Smirnov
|
||||||
spookypeanut "spookypeanut"
|
|
||||||
Steve Stavropoulos "isnothere"
|
Steve Stavropoulos "isnothere"
|
||||||
Daniel Steinberger "amorphousshape"
|
Daniel Steinberger "amorphousshape"
|
||||||
Sven Strothoff "dataslayer"
|
Sven Strothoff "dataslayer"
|
||||||
Andrea Suatoni "mrhandler"
|
Andrea Suatoni "mrhandler"
|
||||||
tbcarey
|
Max Tabachenko
|
||||||
Tim "tipabu"
|
DOSBox Team
|
||||||
|
Sarien Team
|
||||||
|
Joel Teichroeb
|
||||||
|
Jimmi Thogersen
|
||||||
|
Alexander Tkachov
|
||||||
|
Pino Toscano
|
||||||
Luigi Toscano "ltosky"
|
Luigi Toscano "ltosky"
|
||||||
Xavier Trochu "xtrochu"
|
Xavier Trochu "xtrochu"
|
||||||
|
Vasyl Tsvirkunov
|
||||||
Michal Tulacek "tutchek"
|
Michal Tulacek "tutchek"
|
||||||
Michael Udaltsov "cccp99"
|
Michael Udaltsov "cccp99"
|
||||||
|
Joni Vahamaki
|
||||||
Kristof Vansant "lupusbe"
|
Kristof Vansant "lupusbe"
|
||||||
|
Aaryaman Vasishta
|
||||||
Tim Walters "realmz"
|
Tim Walters "realmz"
|
||||||
David Weinehall "weine"
|
|
||||||
Eric A. Welsh "eweish42"
|
Eric A. Welsh "eweish42"
|
||||||
Yudhi Widyatama "yudhi97"
|
Yudhi Widyatama "yudhi97"
|
||||||
|
Jakub Wilk
|
||||||
|
Kieron Wilkinson
|
||||||
Robert Wohlrab "moshroum"
|
Robert Wohlrab "moshroum"
|
||||||
Xanathar "xanathar"
|
James Woodcock
|
||||||
Grant Yeager "glo_kidd"
|
Grant Yeager "glo_kidd"
|
||||||
Benjamin W. Zale "junior_aepi"
|
Benjamin W. Zale "junior_aepi"
|
||||||
Yotam Barnoy "bluddy"
|
Kamil Zbrog
|
||||||
Tom Frost "TomFrost"
|
Michal Ziabkowski
|
||||||
|
Bramvandijk "bramvandijk"
|
||||||
|
Canadacow
|
||||||
|
countingpine
|
||||||
|
Damien
|
||||||
|
dc france "erwan2004"
|
||||||
|
dewt "mncl"
|
||||||
|
dubsdj
|
||||||
|
Florent "flobo"
|
||||||
|
Florob "florob"
|
||||||
|
j0tt
|
||||||
|
Jellby "jellby"
|
||||||
|
Joerg "macdrega"
|
||||||
|
Lostech "lostech"
|
||||||
|
Nicos "anarxia"
|
||||||
|
ole
|
||||||
|
phi1
|
||||||
|
Pix2 "pix2"
|
||||||
|
Richard "trinity78"
|
||||||
|
Scarlatti "escarlate"
|
||||||
|
the rara avis "theraraavis"
|
||||||
|
Tim "tipabu"
|
||||||
|
vandalo
|
||||||
|
Xanathar "xanathar"
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio/softsynth/emumidi.h"
|
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
#include "audio/decoders/3do.h"
|
#include "audio/decoders/3do.h"
|
||||||
#include "audio/decoders/raw.h"
|
|
||||||
#include "audio/decoders/adpcm_intern.h"
|
#include "audio/decoders/adpcm_intern.h"
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
|
@ -31,19 +31,12 @@
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "common/substream.h"
|
#include "common/stream.h"
|
||||||
|
|
||||||
#include "audio/audiostream.h"
|
#include "audio/audiostream.h"
|
||||||
#include "audio/decoders/raw.h"
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
class SeekableReadStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
class SeekableAudioStream;
|
|
||||||
|
|
||||||
// amount of bytes to be used within the decoder classes as buffers
|
// amount of bytes to be used within the decoder classes as buffers
|
||||||
#define AUDIO_3DO_CACHE_SIZE 1024
|
#define AUDIO_3DO_CACHE_SIZE 1024
|
||||||
|
|
||||||
|
|
|
@ -320,10 +320,11 @@ int MS_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||||
_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
|
_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[0], (data >> 4) & 0x0f);
|
||||||
_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
|
_decodedSamples[_decodedSampleCount++] = decodeMS(&_status.ch[_channels - 1], data & 0x0f);
|
||||||
}
|
}
|
||||||
|
_decodedSampleIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (1 - (count - 1)) ensures that _decodedSamples acts as a FIFO of depth 2
|
// _decodedSamples acts as a FIFO of depth 2 or 4;
|
||||||
buffer[samples] = _decodedSamples[1 - (_decodedSampleCount - 1)];
|
buffer[samples] = _decodedSamples[_decodedSampleIndex++];
|
||||||
_decodedSampleCount--;
|
_decodedSampleCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +434,7 @@ int16 Ima_ADPCMStream::decodeIMA(byte code, int channel) {
|
||||||
return samp;
|
return samp;
|
||||||
}
|
}
|
||||||
|
|
||||||
RewindableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, ADPCMType type, int rate, int channels, uint32 blockAlign) {
|
SeekableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, ADPCMType type, int rate, int channels, uint32 blockAlign) {
|
||||||
// If size is 0, report the entire size of the stream
|
// If size is 0, report the entire size of the stream
|
||||||
if (!size)
|
if (!size)
|
||||||
size = stream->size();
|
size = stream->size();
|
||||||
|
|
|
@ -45,7 +45,7 @@ class SeekableReadStream;
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
class PacketizedAudioStream;
|
class PacketizedAudioStream;
|
||||||
class RewindableAudioStream;
|
class SeekableAudioStream;
|
||||||
|
|
||||||
// There are several types of ADPCM encoding, only some are supported here
|
// There are several types of ADPCM encoding, only some are supported here
|
||||||
// For all the different encodings, refer to:
|
// For all the different encodings, refer to:
|
||||||
|
@ -74,7 +74,7 @@ enum ADPCMType {
|
||||||
* @param blockAlign block alignment ???
|
* @param blockAlign block alignment ???
|
||||||
* @return a new RewindableAudioStream, or NULL, if an error occurred
|
* @return a new RewindableAudioStream, or NULL, if an error occurred
|
||||||
*/
|
*/
|
||||||
RewindableAudioStream *makeADPCMStream(
|
SeekableAudioStream *makeADPCMStream(
|
||||||
Common::SeekableReadStream *stream,
|
Common::SeekableReadStream *stream,
|
||||||
DisposeAfterUse::Flag disposeAfterUse,
|
DisposeAfterUse::Flag disposeAfterUse,
|
||||||
uint32 size, ADPCMType type,
|
uint32 size, ADPCMType type,
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
class ADPCMStream : public RewindableAudioStream {
|
class ADPCMStream : public SeekableAudioStream {
|
||||||
protected:
|
protected:
|
||||||
Common::DisposablePtr<Common::SeekableReadStream> _stream;
|
Common::DisposablePtr<Common::SeekableReadStream> _stream;
|
||||||
int32 _startpos;
|
int32 _startpos;
|
||||||
|
@ -67,6 +67,8 @@ public:
|
||||||
virtual int getRate() const { return _rate; }
|
virtual int getRate() const { return _rate; }
|
||||||
|
|
||||||
virtual bool rewind();
|
virtual bool rewind();
|
||||||
|
virtual bool seek(const Timestamp &where) { return false; }
|
||||||
|
virtual Timestamp getLength() const { return -1; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This table is used by some ADPCM variants (IMA and OKI) to adjust the
|
* This table is used by some ADPCM variants (IMA and OKI) to adjust the
|
||||||
|
@ -207,6 +209,7 @@ public:
|
||||||
error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM");
|
error("MS_ADPCMStream(): blockAlign isn't specified for MS ADPCM");
|
||||||
memset(&_status, 0, sizeof(_status));
|
memset(&_status, 0, sizeof(_status));
|
||||||
_decodedSampleCount = 0;
|
_decodedSampleCount = 0;
|
||||||
|
_decodedSampleIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
|
virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
|
||||||
|
@ -218,6 +221,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 _decodedSampleCount;
|
uint8 _decodedSampleCount;
|
||||||
|
uint8 _decodedSampleIndex;
|
||||||
int16 _decodedSamples[4];
|
int16 _decodedSamples[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,8 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
|
||||||
foundSSND = true;
|
foundSSND = true;
|
||||||
/* uint32 offset = */ stream->readUint32BE();
|
/* uint32 offset = */ stream->readUint32BE();
|
||||||
/* uint32 blockAlign = */ stream->readUint32BE();
|
/* uint32 blockAlign = */ stream->readUint32BE();
|
||||||
|
if (dataStream)
|
||||||
|
delete dataStream;
|
||||||
dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
|
dataStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + length - 8, disposeAfterUse);
|
||||||
break;
|
break;
|
||||||
case MKTAG('F', 'V', 'E', 'R'):
|
case MKTAG('F', 'V', 'E', 'R'):
|
||||||
|
@ -154,7 +156,7 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
debug(1, "Skipping AIFF '%s' chunk", tag2str(tag));
|
debug(1, "Skipping AIFF '%s' chunk", tag2str(tag));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->seek(pos + length + (length & 1)); // ensure we're also word-aligned
|
stream->seek(pos + length + (length & 1)); // ensure we're also word-aligned
|
||||||
|
@ -203,7 +205,7 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
|
||||||
if (codec == MKTAG('s', 'o', 'w', 't'))
|
if (codec == MKTAG('s', 'o', 'w', 't'))
|
||||||
rawFlags |= Audio::FLAG_LITTLE_ENDIAN;
|
rawFlags |= Audio::FLAG_LITTLE_ENDIAN;
|
||||||
|
|
||||||
return makeRawStream(dataStream, rate, rawFlags);
|
return makeRawStream(dataStream, rate, rawFlags);
|
||||||
}
|
}
|
||||||
case MKTAG('i', 'm', 'a', '4'):
|
case MKTAG('i', 'm', 'a', '4'):
|
||||||
// TODO: Use QT IMA ADPCM
|
// TODO: Use QT IMA ADPCM
|
||||||
|
@ -212,7 +214,7 @@ RewindableAudioStream *makeAIFFStream(Common::SeekableReadStream *stream, Dispos
|
||||||
case MKTAG('Q', 'D', 'M', '2'):
|
case MKTAG('Q', 'D', 'M', '2'):
|
||||||
// TODO: Need to figure out how to integrate this
|
// TODO: Need to figure out how to integrate this
|
||||||
// (But hopefully never needed)
|
// (But hopefully never needed)
|
||||||
warning("Unhandled AIFF-C QDM2 compression");
|
warning("Unhandled AIFF-C QDM2 compression");
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'D', 'P', '4'):
|
case MKTAG('A', 'D', 'P', '4'):
|
||||||
// ADP4 on 3DO
|
// ADP4 on 3DO
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
* - sword25
|
* - sword25
|
||||||
* - touche
|
* - touche
|
||||||
* - tucker
|
* - tucker
|
||||||
|
* - wintermute
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef AUDIO_VORBIS_H
|
#ifndef AUDIO_VORBIS_H
|
||||||
|
|
|
@ -158,7 +158,7 @@ bool loadWAVFromStream(Common::SeekableReadStream &stream, int &size, int &rate,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RewindableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
|
SeekableAudioStream *makeWAVStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) {
|
||||||
int size, rate;
|
int size, rate;
|
||||||
byte flags;
|
byte flags;
|
||||||
uint16 type;
|
uint16 type;
|
||||||
|
|
|
@ -56,7 +56,7 @@ class SeekableReadStream;
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
class RewindableAudioStream;
|
class SeekableAudioStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to load a WAVE from the given seekable stream. Returns true if
|
* Try to load a WAVE from the given seekable stream. Returns true if
|
||||||
|
@ -82,9 +82,9 @@ extern bool loadWAVFromStream(
|
||||||
*
|
*
|
||||||
* @param stream the SeekableReadStream from which to read the WAVE data
|
* @param stream the SeekableReadStream from which to read the WAVE data
|
||||||
* @param disposeAfterUse whether to delete the stream after use
|
* @param disposeAfterUse whether to delete the stream after use
|
||||||
* @return a new RewindableAudioStream, or NULL, if an error occurred
|
* @return a new SeekableAudioStream, or NULL, if an error occurred
|
||||||
*/
|
*/
|
||||||
RewindableAudioStream *makeWAVStream(
|
SeekableAudioStream *makeWAVStream(
|
||||||
Common::SeekableReadStream *stream,
|
Common::SeekableReadStream *stream,
|
||||||
DisposeAfterUse::Flag disposeAfterUse);
|
DisposeAfterUse::Flag disposeAfterUse);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
#include "audio/fmopl.h"
|
#include "audio/fmopl.h"
|
||||||
#include "audio/softsynth/emumidi.h"
|
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
|
|
|
@ -140,10 +140,7 @@ MidiDriver_MT32::MidiDriver_MT32(Audio::Mixer *mixer) : MidiDriver_Emulated(mixe
|
||||||
}
|
}
|
||||||
_reportHandler = NULL;
|
_reportHandler = NULL;
|
||||||
_synth = NULL;
|
_synth = NULL;
|
||||||
// Unfortunately bugs in the emulator cause inaccurate tuning
|
_outputRate = 0;
|
||||||
// at rates other than 32KHz, thus we produce data at 32KHz and
|
|
||||||
// rely on Mixer to convert.
|
|
||||||
_outputRate = 32000; //_mixer->getOutputRate();
|
|
||||||
_initializing = false;
|
_initializing = false;
|
||||||
|
|
||||||
// Initialized in open()
|
// Initialized in open()
|
||||||
|
@ -180,7 +177,6 @@ int MidiDriver_MT32::open() {
|
||||||
if (_isOpen)
|
if (_isOpen)
|
||||||
return MERR_ALREADY_OPEN;
|
return MERR_ALREADY_OPEN;
|
||||||
|
|
||||||
MidiDriver_Emulated::open();
|
|
||||||
_reportHandler = new MT32Emu::ReportHandlerScummVM();
|
_reportHandler = new MT32Emu::ReportHandlerScummVM();
|
||||||
_synth = new MT32Emu::Synth(_reportHandler);
|
_synth = new MT32Emu::Synth(_reportHandler);
|
||||||
|
|
||||||
|
@ -212,6 +208,18 @@ int MidiDriver_MT32::open() {
|
||||||
double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
|
double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
|
||||||
_synth->setOutputGain(1.0f * gain);
|
_synth->setOutputGain(1.0f * gain);
|
||||||
_synth->setReverbOutputGain(0.68f * gain);
|
_synth->setReverbOutputGain(0.68f * gain);
|
||||||
|
// We let the synthesizer play MIDI messages immediately. Our MIDI
|
||||||
|
// handling is synchronous to sample generation. This makes delaying MIDI
|
||||||
|
// events result in odd sound output in some cases. For example, the
|
||||||
|
// shattering window in the Indiana Jones and the Fate of Atlantis intro
|
||||||
|
// will sound like a bell if we use any delay here.
|
||||||
|
// Bug #6242 "AUDIO: Built-In MT-32 MUNT Produces Wrong Sounds".
|
||||||
|
_synth->setMIDIDelayMode(MT32Emu::MIDIDelayMode_IMMEDIATE);
|
||||||
|
|
||||||
|
// We need to report the sample rate MUNT renders at as sample rate of our
|
||||||
|
// AudioStream.
|
||||||
|
_outputRate = _synth->getStereoOutputSampleRate();
|
||||||
|
MidiDriver_Emulated::open();
|
||||||
|
|
||||||
_initializing = false;
|
_initializing = false;
|
||||||
|
|
||||||
|
|
199
backends/audiocd/audiocd-stream.cpp
Normal file
199
backends/audiocd/audiocd-stream.cpp
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/audiocd/audiocd-stream.h"
|
||||||
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
AudioCDStream::AudioCDStream() : _buffer(), _frame(0), _bufferPos(0), _bufferFrame(0), _forceStop(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCDStream::~AudioCDStream() {
|
||||||
|
// Stop the timer; the subclass needs to do this,
|
||||||
|
// so this is just a last resort.
|
||||||
|
stopTimer();
|
||||||
|
|
||||||
|
// Clear any buffered frames
|
||||||
|
emptyQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AudioCDStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||||
|
int samples = 0;
|
||||||
|
|
||||||
|
// See if any data is left first
|
||||||
|
while (_bufferPos < kSamplesPerFrame && samples < numSamples)
|
||||||
|
buffer[samples++] = _buffer[_bufferPos++];
|
||||||
|
|
||||||
|
// Bail out if done
|
||||||
|
if (endOfData())
|
||||||
|
return samples;
|
||||||
|
|
||||||
|
while (samples < numSamples && !endOfData()) {
|
||||||
|
if (!readNextFrame())
|
||||||
|
return samples;
|
||||||
|
|
||||||
|
// Copy the samples over
|
||||||
|
for (_bufferPos = 0; _bufferPos < kSamplesPerFrame && samples < numSamples;)
|
||||||
|
buffer[samples++] = _buffer[_bufferPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioCDStream::readNextFrame() {
|
||||||
|
// Fetch a frame from the queue
|
||||||
|
int16 *buffer;
|
||||||
|
|
||||||
|
{
|
||||||
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
|
// Nothing we can do if it's empty
|
||||||
|
if (_bufferQueue.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
buffer = _bufferQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(_buffer, buffer, kSamplesPerFrame * 2);
|
||||||
|
delete[] buffer;
|
||||||
|
_frame++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioCDStream::endOfData() const {
|
||||||
|
return !shouldForceStop() && getStartFrame() + _frame >= getEndFrame() && _bufferPos == kSamplesPerFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioCDStream::seek(const Audio::Timestamp &where) {
|
||||||
|
// Stop the timer
|
||||||
|
stopTimer();
|
||||||
|
|
||||||
|
// Clear anything out of the queue
|
||||||
|
emptyQueue();
|
||||||
|
|
||||||
|
// Convert to the frame number
|
||||||
|
// Really not much else needed
|
||||||
|
_bufferPos = kSamplesPerFrame;
|
||||||
|
_frame = where.convertToFramerate(kFramesPerSecond).totalNumberOfFrames();
|
||||||
|
_bufferFrame = _frame;
|
||||||
|
|
||||||
|
// Start the timer again
|
||||||
|
startTimer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::Timestamp AudioCDStream::getLength() const {
|
||||||
|
return Audio::Timestamp(0, getEndFrame() - getStartFrame(), kFramesPerSecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::timerProc(void *refCon) {
|
||||||
|
static_cast<AudioCDStream *>(refCon)->onTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::onTimer() {
|
||||||
|
// The goal here is to do as much work in this timer instead
|
||||||
|
// of doing it in the readBuffer() call, which is the mixer.
|
||||||
|
|
||||||
|
// If we're done, bail.
|
||||||
|
if (shouldForceStop() || getStartFrame() + _bufferFrame >= getEndFrame())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get a quick count of the number of items in the queue
|
||||||
|
// We don't care that much; we only need a quick estimate
|
||||||
|
_mutex.lock();
|
||||||
|
uint32 queueCount = _bufferQueue.size();
|
||||||
|
_mutex.unlock();
|
||||||
|
|
||||||
|
// If we have enough audio buffered, bail out
|
||||||
|
if (queueCount >= kBufferThreshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (!shouldForceStop() && queueCount < kBufferThreshold && getStartFrame() + _bufferFrame < getEndFrame()) {
|
||||||
|
int16 *buffer = new int16[kSamplesPerFrame];
|
||||||
|
|
||||||
|
// Figure out the MSF of the frame we're looking for
|
||||||
|
int frame = _bufferFrame + getStartFrame();
|
||||||
|
|
||||||
|
// Request to read that frame
|
||||||
|
if (!readFrame(frame, buffer)) {
|
||||||
|
warning("Failed to read CD audio");
|
||||||
|
forceStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_bufferFrame++;
|
||||||
|
|
||||||
|
// Now push the buffer onto the queue
|
||||||
|
Common::StackLock lock(_mutex);
|
||||||
|
_bufferQueue.push(buffer);
|
||||||
|
queueCount = _bufferQueue.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::startTimer(bool fillBuffer) {
|
||||||
|
_forceStop = false;
|
||||||
|
if (fillBuffer) {
|
||||||
|
onTimer();
|
||||||
|
}
|
||||||
|
g_system->getTimerManager()->installTimerProc(timerProc, 10 * 1000, this, "AudioCDStream");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::stopTimer() {
|
||||||
|
forceStop();
|
||||||
|
g_system->getTimerManager()->removeTimerProc(timerProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::emptyQueue() {
|
||||||
|
while (!_bufferQueue.empty())
|
||||||
|
delete[] _bufferQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioCDStream::shouldForceStop() const {
|
||||||
|
Common::StackLock lock(_forceStopMutex);
|
||||||
|
return _forceStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioCDStream::forceStop() {
|
||||||
|
Common::StackLock lock(_forceStopMutex);
|
||||||
|
_forceStop = true;
|
||||||
|
}
|
108
backends/audiocd/audiocd-stream.h
Normal file
108
backends/audiocd/audiocd-stream.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BACKENDS_AUDIOCD_AUDIOCD_STREAM_H
|
||||||
|
#define BACKENDS_AUDIOCD_AUDIOCD_STREAM_H
|
||||||
|
|
||||||
|
#include "audio/audiostream.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
|
#include "common/queue.h"
|
||||||
|
#include "common/timer.h"
|
||||||
|
|
||||||
|
class AudioCDStream : public Audio::SeekableAudioStream {
|
||||||
|
public:
|
||||||
|
AudioCDStream();
|
||||||
|
~AudioCDStream();
|
||||||
|
|
||||||
|
int readBuffer(int16 *buffer, const int numSamples);
|
||||||
|
bool isStereo() const { return true; }
|
||||||
|
int getRate() const { return 44100; }
|
||||||
|
bool endOfData() const;
|
||||||
|
bool seek(const Audio::Timestamp &where);
|
||||||
|
Audio::Timestamp getLength() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual uint getStartFrame() const = 0;
|
||||||
|
virtual uint getEndFrame() const = 0;
|
||||||
|
virtual bool readFrame(int frame, int16 *buffer) = 0;
|
||||||
|
|
||||||
|
void startTimer(bool fillBuffer = false);
|
||||||
|
void stopTimer();
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kBytesPerFrame = 2352,
|
||||||
|
kSamplesPerFrame = kBytesPerFrame / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kSecondsPerMinute = 60,
|
||||||
|
kFramesPerSecond = 75
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Keep about a second's worth of audio in the buffer
|
||||||
|
kBufferThreshold = kFramesPerSecond
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
int16 _buffer[kSamplesPerFrame];
|
||||||
|
int _frame;
|
||||||
|
uint _bufferPos;
|
||||||
|
|
||||||
|
Common::Queue<int16 *> _bufferQueue;
|
||||||
|
int _bufferFrame;
|
||||||
|
Common::Mutex _mutex;
|
||||||
|
|
||||||
|
bool _forceStop;
|
||||||
|
bool shouldForceStop() const;
|
||||||
|
void forceStop();
|
||||||
|
Common::Mutex _forceStopMutex;
|
||||||
|
|
||||||
|
bool readNextFrame();
|
||||||
|
static void timerProc(void *refCon);
|
||||||
|
void onTimer();
|
||||||
|
void emptyQueue();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -48,26 +48,31 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Emulated playback functions
|
* Initialize the specified CD drive for audio playback.
|
||||||
* Engines should call these functions. Not all platforms
|
* @return true if the CD drive was inited successfully
|
||||||
* support cd playback, and these functions should try to
|
|
||||||
* emulate it.
|
|
||||||
*/
|
*/
|
||||||
//@{
|
virtual bool open() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the currently open CD drive
|
||||||
|
*/
|
||||||
|
virtual void close() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start audio CD playback
|
* Start audio CD playback
|
||||||
* @param track the track to play.
|
* @param track the track to play.
|
||||||
* @param numLoops how often playback should be repeated (-1 = infinitely often).
|
* @param numLoops how often playback should be repeated (<=0 means infinitely often).
|
||||||
* @param startFrame the frame at which playback should start (75 frames = 1 second).
|
* @param startFrame the frame at which playback should start (75 frames = 1 second).
|
||||||
* @param duration the number of frames to play.
|
* @param duration the number of frames to play.
|
||||||
* @param only_emulate determines if the track should be emulated only
|
* @param onlyEmulate determines if the track should be emulated only
|
||||||
|
* @note The @c onlyEmulate parameter is deprecated.
|
||||||
|
* @return @c true if the track started playing, @c false otherwise
|
||||||
*/
|
*/
|
||||||
virtual void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false) = 0;
|
virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get if audio is being played.
|
* Get if audio is being played.
|
||||||
* @return true if CD or emulated audio is playing
|
* @return true if CD audio is playing
|
||||||
*/
|
*/
|
||||||
virtual bool isPlaying() const = 0;
|
virtual bool isPlaying() const = 0;
|
||||||
|
|
||||||
|
@ -82,12 +87,12 @@ public:
|
||||||
virtual void setBalance(int8 balance) = 0;
|
virtual void setBalance(int8 balance) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop CD or emulated audio playback.
|
* Stop audio playback.
|
||||||
*/
|
*/
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update CD or emulated audio status.
|
* Update audio status.
|
||||||
*/
|
*/
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
|
@ -96,50 +101,6 @@ public:
|
||||||
* @return a Status struct with playback data.
|
* @return a Status struct with playback data.
|
||||||
*/
|
*/
|
||||||
virtual Status getStatus() const = 0;
|
virtual Status getStatus() const = 0;
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Real CD audio methods
|
|
||||||
* These functions should be called from the emulated
|
|
||||||
* ones if they can't emulate the audio playback.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the specified CD drive for audio playback.
|
|
||||||
* @param drive the drive id
|
|
||||||
* @return true if the CD drive was inited successfully
|
|
||||||
*/
|
|
||||||
virtual bool openCD(int drive) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Poll CD status.
|
|
||||||
* @return true if CD audio is playing
|
|
||||||
*/
|
|
||||||
virtual bool pollCD() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start CD audio playback.
|
|
||||||
* @param track the track to play.
|
|
||||||
* @param num_loops how often playback should be repeated (-1 = infinitely often).
|
|
||||||
* @param start_frame the frame at which playback should start (75 frames = 1 second).
|
|
||||||
* @param duration the number of frames to play.
|
|
||||||
*/
|
|
||||||
virtual void playCD(int track, int num_loops, int start_frame, int duration) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop CD audio playback.
|
|
||||||
*/
|
|
||||||
virtual void stopCD() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update CD audio status.
|
|
||||||
*/
|
|
||||||
virtual void updateCD() = 0;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "backends/audiocd/default/default-audiocd.h"
|
#include "backends/audiocd/default/default-audiocd.h"
|
||||||
#include "audio/audiostream.h"
|
#include "audio/audiostream.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
|
||||||
DefaultAudioCDManager::DefaultAudioCDManager() {
|
DefaultAudioCDManager::DefaultAudioCDManager() {
|
||||||
|
@ -37,7 +38,25 @@ DefaultAudioCDManager::DefaultAudioCDManager() {
|
||||||
assert(_mixer);
|
assert(_mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool only_emulate) {
|
DefaultAudioCDManager::~DefaultAudioCDManager() {
|
||||||
|
// Subclasses should call close as well
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DefaultAudioCDManager::open() {
|
||||||
|
// For emulation, opening is always valid
|
||||||
|
close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultAudioCDManager::close() {
|
||||||
|
// Only need to stop for emulation
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) {
|
||||||
|
stop();
|
||||||
|
|
||||||
if (numLoops != 0 || startFrame != 0) {
|
if (numLoops != 0 || startFrame != 0) {
|
||||||
_cd.track = track;
|
_cd.track = track;
|
||||||
_cd.numLoops = numLoops;
|
_cd.numLoops = numLoops;
|
||||||
|
@ -55,9 +74,6 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du
|
||||||
for (int i = 0; !stream && i < 2; ++i)
|
for (int i = 0; !stream && i < 2; ++i)
|
||||||
stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]);
|
stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]);
|
||||||
|
|
||||||
// Stop any currently playing emulated track
|
|
||||||
_mixer->stopHandle(_handle);
|
|
||||||
|
|
||||||
if (stream != 0) {
|
if (stream != 0) {
|
||||||
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
|
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
|
||||||
Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : stream->getLength();
|
Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : stream->getLength();
|
||||||
|
@ -70,12 +86,11 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du
|
||||||
_emulating = true;
|
_emulating = true;
|
||||||
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
|
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
|
||||||
Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance);
|
Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance);
|
||||||
} else {
|
return true;
|
||||||
_emulating = false;
|
|
||||||
if (!only_emulate)
|
|
||||||
playCD(track, numLoops, startFrame, duration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultAudioCDManager::stop() {
|
void DefaultAudioCDManager::stop() {
|
||||||
|
@ -83,52 +98,32 @@ void DefaultAudioCDManager::stop() {
|
||||||
// Audio CD emulation
|
// Audio CD emulation
|
||||||
_mixer->stopHandle(_handle);
|
_mixer->stopHandle(_handle);
|
||||||
_emulating = false;
|
_emulating = false;
|
||||||
} else {
|
|
||||||
// Real Audio CD
|
|
||||||
stopCD();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultAudioCDManager::isPlaying() const {
|
bool DefaultAudioCDManager::isPlaying() const {
|
||||||
if (_emulating) {
|
// Audio CD emulation
|
||||||
// Audio CD emulation
|
if (_emulating)
|
||||||
return _mixer->isSoundHandleActive(_handle);
|
return _mixer->isSoundHandleActive(_handle);
|
||||||
} else {
|
|
||||||
// Real Audio CD
|
// The default class only handles emulation
|
||||||
return pollCD();
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultAudioCDManager::setVolume(byte volume) {
|
void DefaultAudioCDManager::setVolume(byte volume) {
|
||||||
_cd.volume = volume;
|
_cd.volume = volume;
|
||||||
if (_emulating) {
|
|
||||||
// Audio CD emulation
|
|
||||||
if (_mixer->isSoundHandleActive(_handle))
|
|
||||||
_mixer->setChannelVolume(_handle, _cd.volume);
|
|
||||||
} else {
|
|
||||||
// Real Audio CD
|
|
||||||
|
|
||||||
// Unfortunately I can't implement this atm
|
// Audio CD emulation
|
||||||
// since SDL doesn't seem to offer an interface method for this.
|
if (_emulating && isPlaying())
|
||||||
|
_mixer->setChannelVolume(_handle, _cd.volume);
|
||||||
// g_system->setVolumeCD(_cd.volume);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultAudioCDManager::setBalance(int8 balance) {
|
void DefaultAudioCDManager::setBalance(int8 balance) {
|
||||||
_cd.balance = balance;
|
_cd.balance = balance;
|
||||||
if (_emulating) {
|
|
||||||
// Audio CD emulation
|
|
||||||
if (isPlaying())
|
|
||||||
_mixer->setChannelBalance(_handle, _cd.balance);
|
|
||||||
} else {
|
|
||||||
// Real Audio CD
|
|
||||||
|
|
||||||
// Unfortunately I can't implement this atm
|
// Audio CD emulation
|
||||||
// since SDL doesn't seem to offer an interface method for this.
|
if (_emulating && isPlaying())
|
||||||
|
_mixer->setChannelBalance(_handle, _cd.balance);
|
||||||
// g_system->setBalanceCD(_cd.balance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultAudioCDManager::update() {
|
void DefaultAudioCDManager::update() {
|
||||||
|
@ -142,8 +137,6 @@ void DefaultAudioCDManager::update() {
|
||||||
// or not.
|
// or not.
|
||||||
_emulating = false;
|
_emulating = false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
updateCD();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,3 +145,21 @@ DefaultAudioCDManager::Status DefaultAudioCDManager::getStatus() const {
|
||||||
info.playing = isPlaying();
|
info.playing = isPlaying();
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DefaultAudioCDManager::openRealCD() {
|
||||||
|
Common::String cdrom = ConfMan.get("cdrom");
|
||||||
|
|
||||||
|
// Try to parse it as an int
|
||||||
|
char *endPos;
|
||||||
|
int drive = strtol(cdrom.c_str(), &endPos, 0);
|
||||||
|
|
||||||
|
// If not an integer, treat as a drive path
|
||||||
|
if (endPos == cdrom.c_str())
|
||||||
|
return openCD(cdrom);
|
||||||
|
|
||||||
|
if (drive < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return openCD(drive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,29 +26,48 @@
|
||||||
#include "backends/audiocd/audiocd.h"
|
#include "backends/audiocd/audiocd.h"
|
||||||
#include "audio/mixer.h"
|
#include "audio/mixer.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
class String;
|
||||||
|
} // End of namespace Common
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default audio cd manager. Implements emulation of audio cd playback.
|
* The default audio cd manager. Implements emulation of audio cd playback.
|
||||||
*/
|
*/
|
||||||
class DefaultAudioCDManager : public AudioCDManager {
|
class DefaultAudioCDManager : public AudioCDManager {
|
||||||
public:
|
public:
|
||||||
DefaultAudioCDManager();
|
DefaultAudioCDManager();
|
||||||
virtual ~DefaultAudioCDManager() {}
|
virtual ~DefaultAudioCDManager();
|
||||||
|
|
||||||
void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false);
|
virtual bool open();
|
||||||
void stop();
|
virtual void close();
|
||||||
bool isPlaying() const;
|
virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);
|
||||||
void setVolume(byte volume);
|
virtual void stop();
|
||||||
void setBalance(int8 balance);
|
virtual bool isPlaying() const;
|
||||||
void update();
|
virtual void setVolume(byte volume);
|
||||||
|
virtual void setBalance(int8 balance);
|
||||||
|
virtual void update();
|
||||||
virtual Status getStatus() const; // Subclasses should override for better status results
|
virtual Status getStatus() const; // Subclasses should override for better status results
|
||||||
|
|
||||||
virtual bool openCD(int drive) { return false; }
|
|
||||||
virtual void updateCD() {}
|
|
||||||
virtual bool pollCD() const { return false; }
|
|
||||||
virtual void playCD(int track, int num_loops, int start_frame, int duration) {}
|
|
||||||
virtual void stopCD() {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Open a CD using the cdrom config variable
|
||||||
|
*/
|
||||||
|
bool openRealCD();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a CD using the specified drive index
|
||||||
|
* @param drive The index of the drive
|
||||||
|
* @note The index is implementation-defined, but 0 is always the best choice
|
||||||
|
*/
|
||||||
|
virtual bool openCD(int drive) { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a CD from a specific drive
|
||||||
|
* @param drive The name of the drive/path
|
||||||
|
* @note The drive parameter is platform-specific
|
||||||
|
*/
|
||||||
|
virtual bool openCD(const Common::String &drive) { return false; }
|
||||||
|
|
||||||
Audio::SoundHandle _handle;
|
Audio::SoundHandle _handle;
|
||||||
bool _emulating;
|
bool _emulating;
|
||||||
|
|
||||||
|
|
471
backends/audiocd/linux/linux-audiocd.cpp
Normal file
471
backends/audiocd/linux/linux-audiocd.cpp
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Enable all forbidden symbols to allow us to include and use necessary APIs.
|
||||||
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||||
|
|
||||||
|
#include "backends/audiocd/linux/linux-audiocd.h"
|
||||||
|
|
||||||
|
#ifdef USE_LINUXCD
|
||||||
|
|
||||||
|
#include "backends/audiocd/audiocd-stream.h"
|
||||||
|
#include "backends/audiocd/default/default-audiocd.h"
|
||||||
|
#include "common/array.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/cdrom.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kLeadoutTrack = 0xAA
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kBytesPerFrame = 2352,
|
||||||
|
kSamplesPerFrame = kBytesPerFrame / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kSecondsPerMinute = 60,
|
||||||
|
kFramesPerSecond = 75
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Keep about a second's worth of audio in the buffer
|
||||||
|
kBufferThreshold = kFramesPerSecond
|
||||||
|
};
|
||||||
|
|
||||||
|
static int getFrameCount(const cdrom_msf0 &msf) {
|
||||||
|
int time = msf.minute;
|
||||||
|
time *= kSecondsPerMinute;
|
||||||
|
time += msf.second;
|
||||||
|
time *= kFramesPerSecond;
|
||||||
|
time += msf.frame;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to convert an error code into a human-readable message
|
||||||
|
static Common::String getErrorMessage(int errorCode) {
|
||||||
|
char buf[256];
|
||||||
|
buf[0] = 0;
|
||||||
|
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
// glibc sucks
|
||||||
|
return Common::String(strerror_r(errorCode, buf, sizeof(buf)));
|
||||||
|
#else
|
||||||
|
strerror_r(errorCode, buf, sizeof(buf));
|
||||||
|
return Common::String(buf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinuxAudioCDStream : public AudioCDStream {
|
||||||
|
public:
|
||||||
|
LinuxAudioCDStream(int fd, const cdrom_tocentry &startEntry, const cdrom_tocentry &endEntry);
|
||||||
|
~LinuxAudioCDStream();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint getStartFrame() const;
|
||||||
|
uint getEndFrame() const;
|
||||||
|
bool readFrame(int frame, int16 *buffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _fd;
|
||||||
|
const cdrom_tocentry &_startEntry, &_endEntry;
|
||||||
|
};
|
||||||
|
|
||||||
|
LinuxAudioCDStream::LinuxAudioCDStream(int fd, const cdrom_tocentry &startEntry, const cdrom_tocentry &endEntry) :
|
||||||
|
_fd(fd), _startEntry(startEntry), _endEntry(endEntry) {
|
||||||
|
// We fill the buffer here already to prevent any out of sync issues due
|
||||||
|
// to the CD not yet having spun up.
|
||||||
|
startTimer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxAudioCDStream::~LinuxAudioCDStream() {
|
||||||
|
stopTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDStream::readFrame(int frame, int16 *buffer) {
|
||||||
|
// Create the argument
|
||||||
|
union {
|
||||||
|
cdrom_msf msf;
|
||||||
|
char buffer[kBytesPerFrame];
|
||||||
|
} arg;
|
||||||
|
|
||||||
|
int seconds = frame / kFramesPerSecond;
|
||||||
|
frame %= kFramesPerSecond;
|
||||||
|
int minutes = seconds / kSecondsPerMinute;
|
||||||
|
seconds %= kSecondsPerMinute;
|
||||||
|
|
||||||
|
// Request to read that frame
|
||||||
|
// We don't use CDROMREADAUDIO, as it seems to cause kernel
|
||||||
|
// panics on ejecting discs. Probably bad to eject the disc
|
||||||
|
// while playing, but at least let's try to prevent that case.
|
||||||
|
arg.msf.cdmsf_min0 = minutes;
|
||||||
|
arg.msf.cdmsf_sec0 = seconds;
|
||||||
|
arg.msf.cdmsf_frame0 = frame;
|
||||||
|
// The "end" part is irrelevant (why isn't cdrom_msf0 the type
|
||||||
|
// instead?)
|
||||||
|
|
||||||
|
if (ioctl(_fd, CDROMREADRAW, &arg) < 0) {
|
||||||
|
warning("Failed to CD read audio: %s", getErrorMessage(errno).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer, arg.buffer, kBytesPerFrame);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint LinuxAudioCDStream::getStartFrame() const {
|
||||||
|
return getFrameCount(_startEntry.cdte_addr.msf);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint LinuxAudioCDStream::getEndFrame() const {
|
||||||
|
return getFrameCount(_endEntry.cdte_addr.msf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class LinuxAudioCDManager : public DefaultAudioCDManager {
|
||||||
|
public:
|
||||||
|
LinuxAudioCDManager();
|
||||||
|
~LinuxAudioCDManager();
|
||||||
|
|
||||||
|
bool open();
|
||||||
|
void close();
|
||||||
|
bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool openCD(int drive);
|
||||||
|
bool openCD(const Common::String &drive);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Device {
|
||||||
|
Device(const Common::String &n, dev_t d) : name(n), device(d) {}
|
||||||
|
Common::String name;
|
||||||
|
dev_t device;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Common::Array<Device> DeviceList;
|
||||||
|
DeviceList scanDevices();
|
||||||
|
bool tryAddDrive(DeviceList &devices, const Common::String &drive);
|
||||||
|
bool tryAddDrive(DeviceList &devices, const Common::String &drive, dev_t device);
|
||||||
|
bool tryAddDrive(DeviceList &devices, dev_t device);
|
||||||
|
bool tryAddPath(DeviceList &devices, const Common::String &path);
|
||||||
|
bool tryAddGamePath(DeviceList &devices);
|
||||||
|
bool loadTOC();
|
||||||
|
static bool hasDevice(const DeviceList &devices, dev_t device);
|
||||||
|
|
||||||
|
int _fd;
|
||||||
|
cdrom_tochdr _tocHeader;
|
||||||
|
Common::Array<cdrom_tocentry> _tocEntries;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool isTrayEmpty(int errorNumber) {
|
||||||
|
switch (errorNumber) {
|
||||||
|
case EIO:
|
||||||
|
case ENOENT:
|
||||||
|
case EINVAL:
|
||||||
|
#ifdef ENOMEDIUM
|
||||||
|
case ENOMEDIUM:
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxAudioCDManager::LinuxAudioCDManager() {
|
||||||
|
_fd = -1;
|
||||||
|
memset(&_tocHeader, 0, sizeof(_tocHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxAudioCDManager::~LinuxAudioCDManager() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::open() {
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (openRealCD())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return DefaultAudioCDManager::open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxAudioCDManager::close() {
|
||||||
|
DefaultAudioCDManager::close();
|
||||||
|
|
||||||
|
if (_fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
::close(_fd);
|
||||||
|
memset(&_tocHeader, 0, sizeof(_tocHeader));
|
||||||
|
_tocEntries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::openCD(int drive) {
|
||||||
|
DeviceList devices = scanDevices();
|
||||||
|
if (drive >= (int)devices.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_fd = ::open(devices[drive].name.c_str(), O_RDONLY | O_NONBLOCK, 0);
|
||||||
|
if (_fd < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!loadTOC()) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::openCD(const Common::String &drive) {
|
||||||
|
DeviceList devices;
|
||||||
|
if (!tryAddDrive(devices, drive) && !tryAddPath(devices, drive))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_fd = ::open(devices[0].name.c_str(), O_RDONLY | O_NONBLOCK, 0);
|
||||||
|
if (_fd < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!loadTOC()) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) {
|
||||||
|
// Prefer emulation
|
||||||
|
if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If we're set to only emulate, or have no CD drive, return here
|
||||||
|
if (onlyEmulate || _fd < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// HACK: For now, just assume that track number is right
|
||||||
|
// That only works because ScummVM uses the wrong track number anyway
|
||||||
|
|
||||||
|
if (track >= (int)_tocEntries.size() - 1) {
|
||||||
|
warning("No such track %d", track);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bail if the track isn't an audio track
|
||||||
|
if ((_tocEntries[track].cdte_ctrl & 0x04) != 0) {
|
||||||
|
warning("Track %d is not audio", track);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the AudioStream and play it
|
||||||
|
debug(1, "Playing CD track %d", track);
|
||||||
|
|
||||||
|
Audio::SeekableAudioStream *audioStream = new LinuxAudioCDStream(_fd, _tocEntries[track], _tocEntries[track + 1]);
|
||||||
|
|
||||||
|
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
|
||||||
|
Audio::Timestamp end = (duration == 0) ? audioStream->getLength() : Audio::Timestamp(0, startFrame + duration, 75);
|
||||||
|
|
||||||
|
// Fake emulation since we're really playing an AudioStream
|
||||||
|
_emulating = true;
|
||||||
|
|
||||||
|
_mixer->playStream(
|
||||||
|
Audio::Mixer::kMusicSoundType,
|
||||||
|
&_handle,
|
||||||
|
Audio::makeLoopingAudioStream(audioStream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops),
|
||||||
|
-1,
|
||||||
|
_cd.volume,
|
||||||
|
_cd.balance,
|
||||||
|
DisposeAfterUse::YES,
|
||||||
|
true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxAudioCDManager::DeviceList LinuxAudioCDManager::scanDevices() {
|
||||||
|
DeviceList devices;
|
||||||
|
|
||||||
|
// Try to use the game's path first as the device
|
||||||
|
tryAddGamePath(devices);
|
||||||
|
|
||||||
|
// Try adding the default CD-ROM
|
||||||
|
tryAddDrive(devices, "/dev/cdrom");
|
||||||
|
|
||||||
|
// TODO: Try others?
|
||||||
|
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, const Common::String &drive) {
|
||||||
|
struct stat stbuf;
|
||||||
|
if (stat(drive.c_str(), &stbuf) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Must be a character or block device
|
||||||
|
if (!S_ISCHR(stbuf.st_mode) && !S_ISBLK(stbuf.st_mode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return tryAddDrive(devices, drive, stbuf.st_rdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, const Common::String &drive, dev_t device) {
|
||||||
|
if (hasDevice(devices, device))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Try opening the device and seeing if it is a CD-ROM drve
|
||||||
|
int fd = ::open(drive.c_str(), O_RDONLY | O_NONBLOCK, 0);
|
||||||
|
if (fd >= 0) {
|
||||||
|
cdrom_subchnl info;
|
||||||
|
info.cdsc_format = CDROM_MSF;
|
||||||
|
|
||||||
|
bool isCD = ioctl(fd, CDROMSUBCHNL, &info) == 0 || isTrayEmpty(errno);
|
||||||
|
::close(fd);
|
||||||
|
if (isCD) {
|
||||||
|
devices.push_back(Device(drive, device));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, dev_t device) {
|
||||||
|
// Construct the block name
|
||||||
|
// TODO: libblkid's blkid_devno_to_devname is exactly what we look for.
|
||||||
|
// This requires an external dependency though.
|
||||||
|
Common::String name = Common::String::format("/dev/block/%d:%d", major(device), minor(device));
|
||||||
|
|
||||||
|
return tryAddDrive(devices, name, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::tryAddPath(DeviceList &devices, const Common::String &path) {
|
||||||
|
struct stat stbuf;
|
||||||
|
if (stat(path.c_str(), &stbuf) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return tryAddDrive(devices, stbuf.st_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::tryAddGamePath(DeviceList &devices) {
|
||||||
|
if (!ConfMan.hasKey("path"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return tryAddPath(devices, ConfMan.get("path"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::loadTOC() {
|
||||||
|
if (_fd < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ioctl(_fd, CDROMREADTOCHDR, &_tocHeader) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
debug(4, "CD: Start Track: %d, End Track %d", _tocHeader.cdth_trk0, _tocHeader.cdth_trk1);
|
||||||
|
|
||||||
|
for (int i = _tocHeader.cdth_trk0; i <= _tocHeader.cdth_trk1; i++) {
|
||||||
|
cdrom_tocentry entry;
|
||||||
|
memset(&entry, 0, sizeof(entry));
|
||||||
|
entry.cdte_track = i;
|
||||||
|
entry.cdte_format = CDROM_MSF;
|
||||||
|
|
||||||
|
if (ioctl(_fd, CDROMREADTOCENTRY, &entry) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
debug("Entry:");
|
||||||
|
debug("\tTrack: %d", entry.cdte_track);
|
||||||
|
debug("\tAdr: %d", entry.cdte_adr);
|
||||||
|
debug("\tCtrl: %d", entry.cdte_ctrl);
|
||||||
|
debug("\tFormat: %d", entry.cdte_format);
|
||||||
|
debug("\tMSF: %d:%d:%d", entry.cdte_addr.msf.minute, entry.cdte_addr.msf.second, entry.cdte_addr.msf.frame);
|
||||||
|
debug("\tMode: %d\n", entry.cdte_datamode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_tocEntries.push_back(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the leadout so we can get the length of the last frame
|
||||||
|
cdrom_tocentry entry;
|
||||||
|
memset(&entry, 0, sizeof(entry));
|
||||||
|
entry.cdte_track = kLeadoutTrack;
|
||||||
|
entry.cdte_format = CDROM_MSF;
|
||||||
|
|
||||||
|
if (ioctl(_fd, CDROMREADTOCENTRY, &entry) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
debug("Lead out:");
|
||||||
|
debug("\tTrack: %d", entry.cdte_track);
|
||||||
|
debug("\tAdr: %d", entry.cdte_adr);
|
||||||
|
debug("\tCtrl: %d", entry.cdte_ctrl);
|
||||||
|
debug("\tFormat: %d", entry.cdte_format);
|
||||||
|
debug("\tMSF: %d:%d:%d", entry.cdte_addr.msf.minute, entry.cdte_addr.msf.second, entry.cdte_addr.msf.frame);
|
||||||
|
debug("\tMode: %d\n", entry.cdte_datamode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_tocEntries.push_back(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxAudioCDManager::hasDevice(const DeviceList &devices, dev_t device) {
|
||||||
|
for (DeviceList::const_iterator it = devices.begin(); it != devices.end(); it++)
|
||||||
|
if (it->device == device)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCDManager *createLinuxAudioCDManager() {
|
||||||
|
return new LinuxAudioCDManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_LINUXCD
|
62
backends/audiocd/linux/linux-audiocd.h
Normal file
62
backends/audiocd/linux/linux-audiocd.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BACKENDS_AUDIOCD_LINUX_H
|
||||||
|
#define BACKENDS_AUDIOCD_LINUX_H
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
|
#ifdef USE_LINUXCD
|
||||||
|
|
||||||
|
class AudioCDManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an audio CD manager using the Linux CDROM API
|
||||||
|
*/
|
||||||
|
AudioCDManager *createLinuxAudioCDManager();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
306
backends/audiocd/macosx/macosx-audiocd.cpp
Normal file
306
backends/audiocd/macosx/macosx-audiocd.cpp
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef MACOSX
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
|
#include "audio/audiostream.h"
|
||||||
|
#include "audio/decoders/aiff.h"
|
||||||
|
#include "audio/timestamp.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/fs.h"
|
||||||
|
#include "common/hashmap.h"
|
||||||
|
#include "common/textconsole.h"
|
||||||
|
#include "backends/audiocd/default/default-audiocd.h"
|
||||||
|
#include "backends/audiocd/macosx/macosx-audiocd.h"
|
||||||
|
#include "backends/fs/stdiostream.h"
|
||||||
|
|
||||||
|
// Partially based on SDL's code
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mac OS X audio cd manager. Implements real audio cd playback.
|
||||||
|
*/
|
||||||
|
class MacOSXAudioCDManager : public DefaultAudioCDManager {
|
||||||
|
public:
|
||||||
|
MacOSXAudioCDManager() {}
|
||||||
|
~MacOSXAudioCDManager();
|
||||||
|
|
||||||
|
bool open();
|
||||||
|
void close();
|
||||||
|
bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool openCD(int drive);
|
||||||
|
bool openCD(const Common::String &drive);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Drive {
|
||||||
|
Drive(const Common::String &m, const Common::String &d, const Common::String &f) :
|
||||||
|
mountPoint(m), deviceName(d), fsType(f) {}
|
||||||
|
|
||||||
|
Common::String mountPoint;
|
||||||
|
Common::String deviceName;
|
||||||
|
Common::String fsType;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Common::Array<Drive> DriveList;
|
||||||
|
DriveList detectAllDrives();
|
||||||
|
DriveList detectCDDADrives();
|
||||||
|
|
||||||
|
bool findTrackNames(const Common::String &drivePath);
|
||||||
|
|
||||||
|
Common::HashMap<uint, Common::String> _trackMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
MacOSXAudioCDManager::~MacOSXAudioCDManager() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacOSXAudioCDManager::open() {
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (openRealCD())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return DefaultAudioCDManager::open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the base disk number of device name.
|
||||||
|
* Returns -1 if mount point is not /dev/disk*
|
||||||
|
*/
|
||||||
|
static int findBaseDiskNumber(const Common::String &diskName) {
|
||||||
|
if (!diskName.hasPrefix("/dev/disk"))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const char *startPtr = diskName.c_str() + 9;
|
||||||
|
char *endPtr;
|
||||||
|
int baseDiskNumber = strtol(startPtr, &endPtr, 10);
|
||||||
|
if (startPtr == endPtr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return baseDiskNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacOSXAudioCDManager::openCD(int drive) {
|
||||||
|
DriveList allDrives = detectAllDrives();
|
||||||
|
if (allDrives.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DriveList cddaDrives;
|
||||||
|
|
||||||
|
// Try to get the volume related to the game's path
|
||||||
|
if (ConfMan.hasKey("path")) {
|
||||||
|
Common::String gamePath = ConfMan.get("path");
|
||||||
|
struct statfs gamePathStat;
|
||||||
|
if (statfs(gamePath.c_str(), &gamePathStat) == 0) {
|
||||||
|
int baseDiskNumber = findBaseDiskNumber(gamePathStat.f_mntfromname);
|
||||||
|
if (baseDiskNumber >= 0) {
|
||||||
|
// Look for a CDDA drive with the same base disk number
|
||||||
|
for (uint32 i = 0; i < allDrives.size(); i++) {
|
||||||
|
if (allDrives[i].fsType == "cddafs" && findBaseDiskNumber(allDrives[i].deviceName) == baseDiskNumber) {
|
||||||
|
debug(1, "Preferring drive '%s'", allDrives[i].mountPoint.c_str());
|
||||||
|
cddaDrives.push_back(allDrives[i]);
|
||||||
|
allDrives.remove_at(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the remaining CDDA drives to the CDDA list
|
||||||
|
for (uint32 i = 0; i < allDrives.size(); i++)
|
||||||
|
if (allDrives[i].fsType == "cddafs")
|
||||||
|
cddaDrives.push_back(allDrives[i]);
|
||||||
|
|
||||||
|
if (drive >= (int)cddaDrives.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
debug(1, "Using '%s' as the CD drive", cddaDrives[drive].mountPoint.c_str());
|
||||||
|
|
||||||
|
return findTrackNames(cddaDrives[drive].mountPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacOSXAudioCDManager::openCD(const Common::String &drive) {
|
||||||
|
DriveList drives = detectAllDrives();
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < drives.size(); i++) {
|
||||||
|
if (drives[i].fsType != "cddafs")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (drives[i].mountPoint == drive || drives[i].deviceName == drive) {
|
||||||
|
debug(1, "Using '%s' as the CD drive", drives[i].mountPoint.c_str());
|
||||||
|
return findTrackNames(drives[i].mountPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacOSXAudioCDManager::close() {
|
||||||
|
DefaultAudioCDManager::close();
|
||||||
|
_trackMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Some crazy high number that we'll never actually hit
|
||||||
|
kMaxDriveCount = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
MacOSXAudioCDManager::DriveList MacOSXAudioCDManager::detectAllDrives() {
|
||||||
|
// Fetch the lists of drives
|
||||||
|
struct statfs driveStats[kMaxDriveCount];
|
||||||
|
int foundDrives = getfsstat(driveStats, sizeof(driveStats), MNT_WAIT);
|
||||||
|
if (foundDrives <= 0)
|
||||||
|
return DriveList();
|
||||||
|
|
||||||
|
DriveList drives;
|
||||||
|
for (int i = 0; i < foundDrives; i++)
|
||||||
|
drives.push_back(Drive(driveStats[i].f_mntonname, driveStats[i].f_mntfromname, driveStats[i].f_fstypename));
|
||||||
|
|
||||||
|
return drives;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacOSXAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) {
|
||||||
|
// Prefer emulation
|
||||||
|
if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If we're set to only emulate, or have no CD drive, return here
|
||||||
|
if (onlyEmulate || !_trackMap.contains(track))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!numLoops && !startFrame)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Now load the AIFF track from the name
|
||||||
|
Common::String fileName = _trackMap[track];
|
||||||
|
Common::SeekableReadStream *stream = StdioStream::makeFromPath(fileName.c_str(), false);
|
||||||
|
|
||||||
|
if (!stream) {
|
||||||
|
warning("Failed to open track '%s'", fileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::AudioStream *audioStream = Audio::makeAIFFStream(stream, DisposeAfterUse::YES);
|
||||||
|
if (!audioStream) {
|
||||||
|
warning("Track '%s' is not an AIFF track", fileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(audioStream);
|
||||||
|
if (!seekStream) {
|
||||||
|
warning("Track '%s' is not seekable", fileName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
|
||||||
|
Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : seekStream->getLength();
|
||||||
|
|
||||||
|
// Fake emulation since we're really playing an AIFF file
|
||||||
|
_emulating = true;
|
||||||
|
|
||||||
|
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
|
||||||
|
Audio::makeLoopingAudioStream(seekStream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacOSXAudioCDManager::findTrackNames(const Common::String &drivePath) {
|
||||||
|
Common::FSNode directory(drivePath);
|
||||||
|
|
||||||
|
if (!directory.exists()) {
|
||||||
|
warning("Directory '%s' does not exist", drivePath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!directory.isDirectory()) {
|
||||||
|
warning("'%s' is not a directory", drivePath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::FSList children;
|
||||||
|
if (!directory.getChildren(children, Common::FSNode::kListFilesOnly)) {
|
||||||
|
warning("Failed to find children for '%s'", drivePath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < children.size(); i++) {
|
||||||
|
if (!children[i].isDirectory()) {
|
||||||
|
Common::String fileName = children[i].getName();
|
||||||
|
|
||||||
|
if (fileName.hasSuffix(".aiff") || fileName.hasSuffix(".cdda")) {
|
||||||
|
uint j = 0;
|
||||||
|
|
||||||
|
// Search for the track ID in the file name.
|
||||||
|
for (; j < fileName.size() && !Common::isDigit(fileName[j]); j++)
|
||||||
|
;
|
||||||
|
|
||||||
|
const char *trackIDString = fileName.c_str() + j;
|
||||||
|
char *endPtr = nullptr;
|
||||||
|
long trackID = strtol(trackIDString, &endPtr, 10);
|
||||||
|
|
||||||
|
if (trackIDString != endPtr && trackID > 0 && trackID < UINT_MAX) {
|
||||||
|
_trackMap[trackID - 1] = drivePath + '/' + fileName;
|
||||||
|
} else {
|
||||||
|
warning("Invalid track file name: '%s'", fileName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCDManager *createMacOSXAudioCDManager() {
|
||||||
|
return new MacOSXAudioCDManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MACOSX
|
61
backends/audiocd/macosx/macosx-audiocd.h
Normal file
61
backends/audiocd/macosx/macosx-audiocd.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BACKENDS_AUDIOCD_MACOSX_H
|
||||||
|
#define BACKENDS_AUDIOCD_MACOSX_H
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
|
#ifdef MACOSX
|
||||||
|
|
||||||
|
class AudioCDManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an audio CD manager for Mac OS X
|
||||||
|
*/
|
||||||
|
AudioCDManager *createMacOSXAudioCDManager();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //
|
|
@ -43,10 +43,16 @@ SdlAudioCDManager::SdlAudioCDManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
SdlAudioCDManager::~SdlAudioCDManager() {
|
SdlAudioCDManager::~SdlAudioCDManager() {
|
||||||
if (_cdrom) {
|
close();
|
||||||
SDL_CDStop(_cdrom);
|
}
|
||||||
SDL_CDClose(_cdrom);
|
|
||||||
}
|
bool SdlAudioCDManager::open() {
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (openRealCD())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return DefaultAudioCDManager::open();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlAudioCDManager::openCD(int drive) {
|
bool SdlAudioCDManager::openCD(int drive) {
|
||||||
|
@ -67,44 +73,69 @@ bool SdlAudioCDManager::openCD(int drive) {
|
||||||
return (_cdrom != NULL);
|
return (_cdrom != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlAudioCDManager::stopCD() {
|
void SdlAudioCDManager::close() {
|
||||||
|
DefaultAudioCDManager::close();
|
||||||
|
|
||||||
|
if (_cdrom) {
|
||||||
|
SDL_CDStop(_cdrom);
|
||||||
|
SDL_CDClose(_cdrom);
|
||||||
|
_cdrom = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SdlAudioCDManager::stop() {
|
||||||
|
DefaultAudioCDManager::stop();
|
||||||
|
|
||||||
// Stop CD Audio in 1/10th of a second
|
// Stop CD Audio in 1/10th of a second
|
||||||
_cdStopTime = SDL_GetTicks() + 100;
|
_cdStopTime = SDL_GetTicks() + 100;
|
||||||
_cdNumLoops = 0;
|
_cdNumLoops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlAudioCDManager::playCD(int track, int num_loops, int start_frame, int duration) {
|
bool SdlAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) {
|
||||||
if (!num_loops && !start_frame)
|
// Prefer emulation
|
||||||
return;
|
if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!_cdrom)
|
// If we're set to only emulate, or have no CD, return here
|
||||||
return;
|
if (onlyEmulate || !_cdrom)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!numLoops && !startFrame)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// FIXME: Explain this.
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
duration += 5;
|
duration += 5;
|
||||||
|
|
||||||
_cdTrack = track;
|
_cdTrack = track;
|
||||||
_cdNumLoops = num_loops;
|
_cdNumLoops = numLoops;
|
||||||
_cdStartFrame = start_frame;
|
_cdStartFrame = startFrame;
|
||||||
|
|
||||||
SDL_CDStatus(_cdrom);
|
SDL_CDStatus(_cdrom);
|
||||||
if (start_frame == 0 && duration == 0)
|
if (startFrame == 0 && duration == 0)
|
||||||
SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);
|
SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);
|
||||||
else
|
else
|
||||||
SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration);
|
SDL_CDPlayTracks(_cdrom, track, startFrame, 0, duration);
|
||||||
_cdDuration = duration;
|
_cdDuration = duration;
|
||||||
_cdStopTime = 0;
|
_cdStopTime = 0;
|
||||||
_cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS;
|
_cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlAudioCDManager::pollCD() const {
|
bool SdlAudioCDManager::isPlaying() const {
|
||||||
|
if (DefaultAudioCDManager::isPlaying())
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!_cdrom)
|
if (!_cdrom)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING));
|
return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlAudioCDManager::updateCD() {
|
void SdlAudioCDManager::update() {
|
||||||
|
DefaultAudioCDManager::update();
|
||||||
|
|
||||||
if (!_cdrom)
|
if (!_cdrom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,15 @@ public:
|
||||||
SdlAudioCDManager();
|
SdlAudioCDManager();
|
||||||
virtual ~SdlAudioCDManager();
|
virtual ~SdlAudioCDManager();
|
||||||
|
|
||||||
|
virtual bool open();
|
||||||
|
virtual void close();
|
||||||
|
virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);
|
||||||
|
virtual void stop();
|
||||||
|
virtual bool isPlaying() const;
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool openCD(int drive);
|
virtual bool openCD(int drive);
|
||||||
virtual void updateCD();
|
|
||||||
virtual bool pollCD() const;
|
|
||||||
virtual void playCD(int track, int num_loops, int start_frame, int duration);
|
|
||||||
virtual void stopCD();
|
|
||||||
|
|
||||||
SDL_CD *_cdrom;
|
SDL_CD *_cdrom;
|
||||||
int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration;
|
int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration;
|
||||||
|
|
362
backends/audiocd/win32/msvc/ntddcdrm.h
Normal file
362
backends/audiocd/win32/msvc/ntddcdrm.h
Normal file
|
@ -0,0 +1,362 @@
|
||||||
|
/**
|
||||||
|
* @file ntddcdrm.h
|
||||||
|
* Copyright 2012, 2013 MinGW.org project
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
/* Created by Casper S. Hornstrup <chorns@users.sourceforge.net> */
|
||||||
|
#ifndef __NTDDCDRM_H
|
||||||
|
#define __NTDDCDRM_H
|
||||||
|
#if 0 // Added to make MSVC happy.
|
||||||
|
#pragma GCC system_header
|
||||||
|
#include <_mingw.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CDROM IOCTL interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // Added to make MSVC happy.
|
||||||
|
#include "ntddk.h"
|
||||||
|
#include "ntddstor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_CHECK_VERIFY \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_FIND_NEW_DEVICES \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_GET_CONTROL \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_GET_LAST_SESSION \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_GET_VOLUME \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_PAUSE_AUDIO \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_PLAY_AUDIO_MSF \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_RAW_READ \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_READ_Q_CHANNEL \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_READ_TOC \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_READ_TOC_EX \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_RESUME_AUDIO \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_SEEK_AUDIO_MSF \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_SET_VOLUME \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_SIMBAD \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
#define IOCTL_CDROM_STOP_AUDIO \
|
||||||
|
CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXIMUM_NUMBER_TRACKS 100
|
||||||
|
#define MAXIMUM_CDROM_SIZE 804
|
||||||
|
#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2
|
||||||
|
|
||||||
|
typedef struct _TRACK_DATA {
|
||||||
|
UCHAR Reserved;
|
||||||
|
UCHAR Control : 4;
|
||||||
|
UCHAR Adr : 4;
|
||||||
|
UCHAR TrackNumber;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Address[4];
|
||||||
|
} TRACK_DATA, *PTRACK_DATA;
|
||||||
|
|
||||||
|
/* CDROM_DISK_DATA.DiskData flags */
|
||||||
|
#define CDROM_DISK_AUDIO_TRACK 0x00000001
|
||||||
|
#define CDROM_DISK_DATA_TRACK 0x00000002
|
||||||
|
|
||||||
|
typedef struct _CDROM_DISK_DATA {
|
||||||
|
ULONG DiskData;
|
||||||
|
} CDROM_DISK_DATA, *PCDROM_DISK_DATA;
|
||||||
|
|
||||||
|
typedef struct _CDROM_PLAY_AUDIO_MSF {
|
||||||
|
UCHAR StartingM;
|
||||||
|
UCHAR StartingS;
|
||||||
|
UCHAR StartingF;
|
||||||
|
UCHAR EndingM;
|
||||||
|
UCHAR EndingS;
|
||||||
|
UCHAR EndingF;
|
||||||
|
} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF;
|
||||||
|
|
||||||
|
/* CDROM_READ_TOC_EX.Format constants */
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04
|
||||||
|
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05
|
||||||
|
|
||||||
|
typedef struct _CDROM_READ_TOC_EX {
|
||||||
|
UCHAR Format : 4;
|
||||||
|
UCHAR Reserved1 : 3;
|
||||||
|
UCHAR Msf : 1;
|
||||||
|
UCHAR SessionTrack;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
UCHAR Reserved3;
|
||||||
|
} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX;
|
||||||
|
|
||||||
|
typedef struct _CDROM_SEEK_AUDIO_MSF {
|
||||||
|
UCHAR M;
|
||||||
|
UCHAR S;
|
||||||
|
UCHAR F;
|
||||||
|
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
|
||||||
|
|
||||||
|
/* CDROM_SUB_Q_DATA_FORMAT.Format constants */
|
||||||
|
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
|
||||||
|
#define IOCTL_CDROM_CURRENT_POSITION 0x01
|
||||||
|
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
|
||||||
|
#define IOCTL_CDROM_TRACK_ISRC 0x03
|
||||||
|
|
||||||
|
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
|
||||||
|
UCHAR Format;
|
||||||
|
UCHAR Track;
|
||||||
|
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
|
||||||
|
|
||||||
|
typedef struct _CDROM_TOC {
|
||||||
|
UCHAR Length[2];
|
||||||
|
UCHAR FirstTrack;
|
||||||
|
UCHAR LastTrack;
|
||||||
|
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
|
||||||
|
} CDROM_TOC, *PCDROM_TOC;
|
||||||
|
|
||||||
|
#define CDROM_TOC_SIZE sizeof(CDROM_TOC)
|
||||||
|
|
||||||
|
typedef struct _CDROM_TOC_ATIP_DATA_BLOCK {
|
||||||
|
UCHAR CdrwReferenceSpeed : 3;
|
||||||
|
UCHAR Reserved3 : 1;
|
||||||
|
UCHAR WritePower : 3;
|
||||||
|
UCHAR True1 : 1;
|
||||||
|
UCHAR Reserved4 : 6;
|
||||||
|
UCHAR UnrestrictedUse : 1;
|
||||||
|
UCHAR Reserved5 : 1;
|
||||||
|
UCHAR A3Valid : 1;
|
||||||
|
UCHAR A2Valid : 1;
|
||||||
|
UCHAR A1Valid : 1;
|
||||||
|
UCHAR Reserved6 : 3;
|
||||||
|
UCHAR IsCdrw : 1;
|
||||||
|
UCHAR True2 : 1;
|
||||||
|
UCHAR Reserved7;
|
||||||
|
UCHAR LeadInMsf[3];
|
||||||
|
UCHAR Reserved8;
|
||||||
|
UCHAR LeadOutMsf[3];
|
||||||
|
UCHAR Reserved9;
|
||||||
|
UCHAR A1Values[3];
|
||||||
|
UCHAR Reserved10;
|
||||||
|
UCHAR A2Values[3];
|
||||||
|
UCHAR Reserved11;
|
||||||
|
UCHAR A3Values[3];
|
||||||
|
UCHAR Reserved12;
|
||||||
|
} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK;
|
||||||
|
|
||||||
|
#if 0 // Added to make MSVC happy.
|
||||||
|
typedef struct _CDROM_TOC_ATIP_DATA {
|
||||||
|
UCHAR Length[2];
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0];
|
||||||
|
CDROM_TOC_ATIP_DATA_BLOCK Descriptors[1];
|
||||||
|
} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CDROM_TOC_CD_TEXT_DATA_BLOCK.PackType constants */
|
||||||
|
#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80
|
||||||
|
#define CDROM_CD_TEXT_PACK_PERFORMER 0x81
|
||||||
|
#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82
|
||||||
|
#define CDROM_CD_TEXT_PACK_COMPOSER 0x83
|
||||||
|
#define CDROM_CD_TEXT_PACK_ARRANGER 0x84
|
||||||
|
#define CDROM_CD_TEXT_PACK_MESSAGES 0x85
|
||||||
|
#define CDROM_CD_TEXT_PACK_DISC_ID 0x86
|
||||||
|
#define CDROM_CD_TEXT_PACK_GENRE 0x87
|
||||||
|
#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88
|
||||||
|
#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89
|
||||||
|
#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e
|
||||||
|
#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f
|
||||||
|
|
||||||
|
#if 0 // Added to make MSVC happy.
|
||||||
|
typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK {
|
||||||
|
UCHAR PackType;
|
||||||
|
UCHAR TrackNumber : 7;
|
||||||
|
UCHAR ExtensionFlag : 1;
|
||||||
|
UCHAR SequenceNumber;
|
||||||
|
UCHAR CharacterPosition : 4;
|
||||||
|
UCHAR BlockNumber : 3;
|
||||||
|
UCHAR Unicode : 1;
|
||||||
|
_ANONYMOUS_UNION union {
|
||||||
|
UCHAR Text[12];
|
||||||
|
WCHAR WText[6];
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
UCHAR CRC[2];
|
||||||
|
} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK;
|
||||||
|
|
||||||
|
typedef struct _CDROM_TOC_CD_TEXT_DATA {
|
||||||
|
UCHAR Length[2];
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0];
|
||||||
|
} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CDROM_TOC_FULL_TOC_DATA_BLOCK.Adr constants */
|
||||||
|
#define ADR_NO_MODE_INFORMATION 0x0
|
||||||
|
#define ADR_ENCODES_CURRENT_POSITION 0x1
|
||||||
|
#define ADR_ENCODES_MEDIA_CATALOG 0x2
|
||||||
|
#define ADR_ENCODES_ISRC 0x3
|
||||||
|
|
||||||
|
typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK {
|
||||||
|
UCHAR SessionNumber;
|
||||||
|
UCHAR Control : 4;
|
||||||
|
UCHAR Adr : 4;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Point;
|
||||||
|
UCHAR MsfExtra[3];
|
||||||
|
UCHAR Zero;
|
||||||
|
UCHAR Msf[3];
|
||||||
|
} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK;
|
||||||
|
|
||||||
|
#if 0 // Added to make MSVC happy.
|
||||||
|
typedef struct _CDROM_TOC_FULL_TOC_DATA {
|
||||||
|
UCHAR Length[2];
|
||||||
|
UCHAR FirstCompleteSession;
|
||||||
|
UCHAR LastCompleteSession;
|
||||||
|
CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0];
|
||||||
|
} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA;
|
||||||
|
|
||||||
|
typedef struct _CDROM_TOC_PMA_DATA {
|
||||||
|
UCHAR Length[2];
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0];
|
||||||
|
} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SUB_Q_HEADER.AudioStatus constants */
|
||||||
|
#define AUDIO_STATUS_NOT_SUPPORTED 0x00
|
||||||
|
#define AUDIO_STATUS_IN_PROGRESS 0x11
|
||||||
|
#define AUDIO_STATUS_PAUSED 0x12
|
||||||
|
#define AUDIO_STATUS_PLAY_COMPLETE 0x13
|
||||||
|
#define AUDIO_STATUS_PLAY_ERROR 0x14
|
||||||
|
#define AUDIO_STATUS_NO_STATUS 0x15
|
||||||
|
|
||||||
|
typedef struct _SUB_Q_HEADER {
|
||||||
|
UCHAR Reserved;
|
||||||
|
UCHAR AudioStatus;
|
||||||
|
UCHAR DataLength[2];
|
||||||
|
} SUB_Q_HEADER, *PSUB_Q_HEADER;
|
||||||
|
|
||||||
|
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
|
||||||
|
SUB_Q_HEADER Header;
|
||||||
|
UCHAR FormatCode;
|
||||||
|
UCHAR Reserved[3];
|
||||||
|
UCHAR Reserved1 : 7;
|
||||||
|
UCHAR Mcval :1;
|
||||||
|
UCHAR MediaCatalog[15];
|
||||||
|
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
|
||||||
|
|
||||||
|
typedef struct _SUB_Q_TRACK_ISRC {
|
||||||
|
SUB_Q_HEADER Header;
|
||||||
|
UCHAR FormatCode;
|
||||||
|
UCHAR Reserved0;
|
||||||
|
UCHAR Track;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Reserved2 : 7;
|
||||||
|
UCHAR Tcval : 1;
|
||||||
|
UCHAR TrackIsrc[15];
|
||||||
|
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
|
||||||
|
|
||||||
|
typedef struct _SUB_Q_CURRENT_POSITION {
|
||||||
|
SUB_Q_HEADER Header;
|
||||||
|
UCHAR FormatCode;
|
||||||
|
UCHAR Control : 4;
|
||||||
|
UCHAR ADR : 4;
|
||||||
|
UCHAR TrackNumber;
|
||||||
|
UCHAR IndexNumber;
|
||||||
|
UCHAR AbsoluteAddress[4];
|
||||||
|
UCHAR TrackRelativeAddress[4];
|
||||||
|
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
|
||||||
|
|
||||||
|
typedef union _SUB_Q_CHANNEL_DATA {
|
||||||
|
SUB_Q_CURRENT_POSITION CurrentPosition;
|
||||||
|
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
|
||||||
|
SUB_Q_TRACK_ISRC TrackIsrc;
|
||||||
|
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
|
||||||
|
|
||||||
|
/* CDROM_AUDIO_CONTROL.LbaFormat constants */
|
||||||
|
#define AUDIO_WITH_PREEMPHASIS 0x1
|
||||||
|
#define DIGITAL_COPY_PERMITTED 0x2
|
||||||
|
#define AUDIO_DATA_TRACK 0x4
|
||||||
|
#define TWO_FOUR_CHANNEL_AUDIO 0x8
|
||||||
|
|
||||||
|
typedef struct _CDROM_AUDIO_CONTROL {
|
||||||
|
UCHAR LbaFormat;
|
||||||
|
USHORT LogicalBlocksPerSecond;
|
||||||
|
} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL;
|
||||||
|
|
||||||
|
typedef struct _VOLUME_CONTROL {
|
||||||
|
UCHAR PortVolume[4];
|
||||||
|
} VOLUME_CONTROL, *PVOLUME_CONTROL;
|
||||||
|
|
||||||
|
typedef enum _TRACK_MODE_TYPE {
|
||||||
|
YellowMode2,
|
||||||
|
XAForm2,
|
||||||
|
CDDA
|
||||||
|
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
|
||||||
|
|
||||||
|
typedef struct __RAW_READ_INFO {
|
||||||
|
LARGE_INTEGER DiskOffset;
|
||||||
|
ULONG SectorCount;
|
||||||
|
TRACK_MODE_TYPE TrackMode;
|
||||||
|
} RAW_READ_INFO, *PRAW_READ_INFO;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NTDDCDRM_H */
|
388
backends/audiocd/win32/win32-audiocd.cpp
Normal file
388
backends/audiocd/win32/win32-audiocd.cpp
Normal file
|
@ -0,0 +1,388 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one...
|
||||||
|
|
||||||
|
#include "backends/audiocd/win32/win32-audiocd.h"
|
||||||
|
|
||||||
|
#include "audio/audiostream.h"
|
||||||
|
#include "backends/audiocd/audiocd-stream.h"
|
||||||
|
#include "backends/audiocd/default/default-audiocd.h"
|
||||||
|
#include "common/array.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
|
#include "common/queue.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/timer.h"
|
||||||
|
|
||||||
|
#include <winioctl.h>
|
||||||
|
#if _MSC_VER < 1900
|
||||||
|
// WORKAROUND: Older versions of MSVC might not supply DDK headers by default.
|
||||||
|
// Visual Studio 2015 contains the required headers. We use a compatability
|
||||||
|
// header from MinGW's w32api for all older versions.
|
||||||
|
// TODO: Limit this to the Visual Studio versions which actually require this.
|
||||||
|
#include "msvc/ntddcdrm.h"
|
||||||
|
#elif defined(__MINGW32__) && !defined(__MINGW64__)
|
||||||
|
// Classic MinGW uses non standard paths for DDK headers.
|
||||||
|
#include <ddk/ntddcdrm.h>
|
||||||
|
#else
|
||||||
|
#include <ntddcdrm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Win32AudioCDStream : public AudioCDStream {
|
||||||
|
public:
|
||||||
|
Win32AudioCDStream(HANDLE handle, const TRACK_DATA &startEntry, const TRACK_DATA &endEntry);
|
||||||
|
~Win32AudioCDStream();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint getStartFrame() const;
|
||||||
|
uint getEndFrame() const;
|
||||||
|
bool readFrame(int frame, int16 *buffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE _driveHandle;
|
||||||
|
const TRACK_DATA &_startEntry, &_endEntry;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// The CD-ROM pre-gap is 2s
|
||||||
|
kPreGapFrames = kFramesPerSecond * 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static int getFrameCount(const TRACK_DATA &data) {
|
||||||
|
int time = data.Address[1];
|
||||||
|
time *= kSecondsPerMinute;
|
||||||
|
time += data.Address[2];
|
||||||
|
time *= kFramesPerSecond;
|
||||||
|
time += data.Address[3];
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Win32AudioCDStream::Win32AudioCDStream(HANDLE handle, const TRACK_DATA &startEntry, const TRACK_DATA &endEntry) :
|
||||||
|
_driveHandle(handle), _startEntry(startEntry), _endEntry(endEntry) {
|
||||||
|
// We fill the buffer here already to prevent any out of sync issues due
|
||||||
|
// to the CD not yet having spun up.
|
||||||
|
startTimer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32AudioCDStream::~Win32AudioCDStream() {
|
||||||
|
stopTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Win32AudioCDStream::getStartFrame() const {
|
||||||
|
return getFrameCount(_startEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint Win32AudioCDStream::getEndFrame() const {
|
||||||
|
return getFrameCount(_endEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDStream::readFrame(int frame, int16 *buffer) {
|
||||||
|
// Request to read that frame
|
||||||
|
RAW_READ_INFO readAudio;
|
||||||
|
memset(&readAudio, 0, sizeof(readAudio));
|
||||||
|
readAudio.DiskOffset.QuadPart = (frame - kPreGapFrames) * 2048;
|
||||||
|
readAudio.SectorCount = 1;
|
||||||
|
readAudio.TrackMode = CDDA;
|
||||||
|
|
||||||
|
DWORD bytesReturned;
|
||||||
|
return DeviceIoControl(
|
||||||
|
_driveHandle,
|
||||||
|
IOCTL_CDROM_RAW_READ,
|
||||||
|
&readAudio,
|
||||||
|
sizeof(readAudio),
|
||||||
|
buffer,
|
||||||
|
kBytesPerFrame,
|
||||||
|
&bytesReturned,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Win32AudioCDManager : public DefaultAudioCDManager {
|
||||||
|
public:
|
||||||
|
Win32AudioCDManager();
|
||||||
|
~Win32AudioCDManager();
|
||||||
|
|
||||||
|
bool open();
|
||||||
|
void close();
|
||||||
|
bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool openCD(int drive);
|
||||||
|
bool openCD(const Common::String &drive);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool loadTOC();
|
||||||
|
|
||||||
|
typedef Common::Array<char> DriveList;
|
||||||
|
DriveList detectDrives();
|
||||||
|
bool tryAddDrive(char drive, DriveList &drives);
|
||||||
|
|
||||||
|
HANDLE _driveHandle;
|
||||||
|
int _firstTrack, _lastTrack;
|
||||||
|
Common::Array<TRACK_DATA> _tocEntries;
|
||||||
|
};
|
||||||
|
|
||||||
|
Win32AudioCDManager::Win32AudioCDManager() {
|
||||||
|
_driveHandle = INVALID_HANDLE_VALUE;
|
||||||
|
_firstTrack = _lastTrack = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32AudioCDManager::~Win32AudioCDManager() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::open() {
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (openRealCD())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return DefaultAudioCDManager::open();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::openCD(int drive) {
|
||||||
|
// Fetch the drive list
|
||||||
|
DriveList drives = detectDrives();
|
||||||
|
if (drive >= (int)drives.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
debug(1, "Opening CD drive %c:\\", drives[drive]);
|
||||||
|
|
||||||
|
// Construct the drive path and try to open it
|
||||||
|
Common::String drivePath = Common::String::format("\\\\.\\%c:", drives[drive]);
|
||||||
|
_driveHandle = CreateFileA(drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if (_driveHandle == INVALID_HANDLE_VALUE) {
|
||||||
|
warning("Failed to open drive %c:\\, error %d", drives[drive], (int)GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loadTOC()) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::openCD(const Common::String &drive) {
|
||||||
|
// Just some bounds checking
|
||||||
|
if (drive.empty() || drive.size() > 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Common::isAlpha(drive[0]) || drive[1] != ':')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (drive[2] != 0 && drive[2] != '\\')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DriveList drives;
|
||||||
|
if (!tryAddDrive(toupper(drive[0]), drives))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Construct the drive path and try to open it
|
||||||
|
Common::String drivePath = Common::String::format("\\\\.\\%c:", drives[0]);
|
||||||
|
_driveHandle = CreateFileA(drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if (_driveHandle == INVALID_HANDLE_VALUE) {
|
||||||
|
warning("Failed to open drive %c:\\, error %d", drives[0], (int)GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loadTOC()) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32AudioCDManager::close() {
|
||||||
|
DefaultAudioCDManager::close();
|
||||||
|
|
||||||
|
if (_driveHandle != INVALID_HANDLE_VALUE) {
|
||||||
|
CloseHandle(_driveHandle);
|
||||||
|
_driveHandle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_firstTrack = _lastTrack = 0;
|
||||||
|
_tocEntries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) {
|
||||||
|
// Prefer emulation
|
||||||
|
if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If we're set to only emulate, or have no CD drive, return here
|
||||||
|
if (onlyEmulate || _driveHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// HACK: For now, just assume that track number is right
|
||||||
|
// That only works because ScummVM uses the wrong track number anyway
|
||||||
|
|
||||||
|
if (track >= (int)_tocEntries.size() - 1) {
|
||||||
|
warning("No such track %d", track);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bail if the track isn't an audio track
|
||||||
|
if ((_tocEntries[track].Control & 0x04) != 0) {
|
||||||
|
warning("Track %d is not audio", track);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the AudioStream and play it
|
||||||
|
debug(1, "Playing CD track %d", track);
|
||||||
|
|
||||||
|
Audio::SeekableAudioStream *audioStream = new Win32AudioCDStream(_driveHandle, _tocEntries[track], _tocEntries[track + 1]);
|
||||||
|
|
||||||
|
Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);
|
||||||
|
Audio::Timestamp end = (duration == 0) ? audioStream->getLength() : Audio::Timestamp(0, startFrame + duration, 75);
|
||||||
|
|
||||||
|
// Fake emulation since we're really playing an AudioStream
|
||||||
|
_emulating = true;
|
||||||
|
|
||||||
|
_mixer->playStream(
|
||||||
|
Audio::Mixer::kMusicSoundType,
|
||||||
|
&_handle,
|
||||||
|
Audio::makeLoopingAudioStream(audioStream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops),
|
||||||
|
-1,
|
||||||
|
_cd.volume,
|
||||||
|
_cd.balance,
|
||||||
|
DisposeAfterUse::YES,
|
||||||
|
true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::loadTOC() {
|
||||||
|
CDROM_READ_TOC_EX tocRequest;
|
||||||
|
memset(&tocRequest, 0, sizeof(tocRequest));
|
||||||
|
tocRequest.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
|
||||||
|
tocRequest.Msf = 1;
|
||||||
|
tocRequest.SessionTrack = 0;
|
||||||
|
|
||||||
|
DWORD bytesReturned;
|
||||||
|
CDROM_TOC tocData;
|
||||||
|
bool result = DeviceIoControl(
|
||||||
|
_driveHandle,
|
||||||
|
IOCTL_CDROM_READ_TOC_EX,
|
||||||
|
&tocRequest,
|
||||||
|
sizeof(tocRequest),
|
||||||
|
&tocData,
|
||||||
|
sizeof(tocData),
|
||||||
|
&bytesReturned,
|
||||||
|
NULL);
|
||||||
|
if (!result) {
|
||||||
|
debug("Failed to query the CD TOC: %d", (int)GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_firstTrack = tocData.FirstTrack;
|
||||||
|
_lastTrack = tocData.LastTrack;
|
||||||
|
#if 0
|
||||||
|
debug("First Track: %d", tocData.FirstTrack);
|
||||||
|
debug("Last Track: %d", tocData.LastTrack);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < (bytesReturned - 4) / sizeof(TRACK_DATA); i++)
|
||||||
|
_tocEntries.push_back(tocData.TrackData[i]);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (uint32 i = 0; i < _tocEntries.size(); i++) {
|
||||||
|
const TRACK_DATA &entry = _tocEntries[i];
|
||||||
|
debug("Entry:");
|
||||||
|
debug("\tTrack: %d", entry.TrackNumber);
|
||||||
|
debug("\tAdr: %d", entry.Adr);
|
||||||
|
debug("\tCtrl: %d", entry.Control);
|
||||||
|
debug("\tMSF: %d:%d:%d\n", entry.Address[1], entry.Address[2], entry.Address[3]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32AudioCDManager::DriveList Win32AudioCDManager::detectDrives() {
|
||||||
|
DriveList drives;
|
||||||
|
|
||||||
|
// Try to get the game path's drive
|
||||||
|
char gameDrive = 0;
|
||||||
|
if (ConfMan.hasKey("path")) {
|
||||||
|
Common::String gamePath = ConfMan.get("path");
|
||||||
|
char fullPath[MAX_PATH];
|
||||||
|
DWORD result = GetFullPathNameA(gamePath.c_str(), sizeof(fullPath), fullPath, 0);
|
||||||
|
|
||||||
|
if (result > 0 && result < sizeof(fullPath) && Common::isAlpha(fullPath[0]) && fullPath[1] == ':' && tryAddDrive(toupper(fullPath[0]), drives))
|
||||||
|
gameDrive = drives[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try adding the rest of the drives
|
||||||
|
for (char drive = 'A'; drive <= 'Z'; drive++)
|
||||||
|
if (drive != gameDrive)
|
||||||
|
tryAddDrive(drive, drives);
|
||||||
|
|
||||||
|
return drives;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32AudioCDManager::tryAddDrive(char drive, DriveList &drives) {
|
||||||
|
Common::String drivePath = Common::String::format("%c:\\", drive);
|
||||||
|
|
||||||
|
// Ensure it's an actual CD drive
|
||||||
|
if (GetDriveTypeA(drivePath.c_str()) != DRIVE_CDROM)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
debug(2, "Detected drive %c:\\ as a CD drive", drive);
|
||||||
|
drives.push_back(drive);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCDManager *createWin32AudioCDManager() {
|
||||||
|
return new Win32AudioCDManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WIN32
|
60
backends/audiocd/win32/win32-audiocd.h
Normal file
60
backends/audiocd/win32/win32-audiocd.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Original license header:
|
||||||
|
*
|
||||||
|
* Cabal - Legacy Game Implementations
|
||||||
|
*
|
||||||
|
* Cabal is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BACKENDS_AUDIOCD_WIN32_H
|
||||||
|
#define BACKENDS_AUDIOCD_WIN32_H
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
class AudioCDManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an AudioCDManager using the Win32 API
|
||||||
|
*/
|
||||||
|
AudioCDManager *createWin32AudioCDManager();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -121,7 +121,7 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
|
||||||
Common::KeyCode key = SDLToOSystemKeycode(sdlKey);
|
Common::KeyCode key = SDLToOSystemKeycode(sdlKey);
|
||||||
|
|
||||||
if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) {
|
if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) {
|
||||||
return key - SDLK_F1 + Common::ASCII_F1;
|
return key - Common::KEYCODE_F1 + Common::ASCII_F1;
|
||||||
} else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) {
|
} else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) {
|
||||||
return key - Common::KEYCODE_KP0 + '0';
|
return key - Common::KEYCODE_KP0 + '0';
|
||||||
} else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
|
} else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
|
||||||
|
@ -531,15 +531,17 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||||
|
|
||||||
SDLModToOSystemKeyFlags(SDL_GetModState(), event);
|
SDLModToOSystemKeyFlags(SDL_GetModState(), event);
|
||||||
|
|
||||||
|
SDLKey sdlKeycode = obtainKeycode(ev.key.keysym);
|
||||||
|
|
||||||
// Handle scroll lock as a key modifier
|
// Handle scroll lock as a key modifier
|
||||||
if (ev.key.keysym.sym == SDLK_SCROLLOCK)
|
if (sdlKeycode == SDLK_SCROLLOCK)
|
||||||
_scrollLock = !_scrollLock;
|
_scrollLock = !_scrollLock;
|
||||||
|
|
||||||
if (_scrollLock)
|
if (_scrollLock)
|
||||||
event.kbd.flags |= Common::KBD_SCRL;
|
event.kbd.flags |= Common::KBD_SCRL;
|
||||||
|
|
||||||
// Ctrl-m toggles mouse capture
|
// Ctrl-m toggles mouse capture
|
||||||
if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') {
|
if (event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'm') {
|
||||||
if (_graphicsManager) {
|
if (_graphicsManager) {
|
||||||
_graphicsManager->getWindow()->toggleMouseGrab();
|
_graphicsManager->getWindow()->toggleMouseGrab();
|
||||||
}
|
}
|
||||||
|
@ -548,26 +550,26 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||||
|
|
||||||
#if defined(MACOSX)
|
#if defined(MACOSX)
|
||||||
// On Macintosh, Cmd-Q quits
|
// On Macintosh, Cmd-Q quits
|
||||||
if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') {
|
if ((ev.key.keysym.mod & KMOD_META) && sdlKeycode == 'q') {
|
||||||
event.type = Common::EVENT_QUIT;
|
event.type = Common::EVENT_QUIT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif defined(POSIX)
|
#elif defined(POSIX)
|
||||||
// On other *nix systems, Control-Q quits
|
// On other *nix systems, Control-Q quits
|
||||||
if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'q') {
|
if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'q') {
|
||||||
event.type = Common::EVENT_QUIT;
|
event.type = Common::EVENT_QUIT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Ctrl-z and Alt-X quit
|
// Ctrl-z quits
|
||||||
if ((event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'z') || (event.kbd.hasFlags(Common::KBD_ALT) && ev.key.keysym.sym == 'x')) {
|
if ((event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'z')) {
|
||||||
event.type = Common::EVENT_QUIT;
|
event.type = Common::EVENT_QUIT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// On Windows, also use the default Alt-F4 quit combination
|
// On Windows, also use the default Alt-F4 quit combination
|
||||||
if ((ev.key.keysym.mod & KMOD_ALT) && ev.key.keysym.sym == SDLK_F4) {
|
if ((ev.key.keysym.mod & KMOD_ALT) && sdlKeycode == SDLK_F4) {
|
||||||
event.type = Common::EVENT_QUIT;
|
event.type = Common::EVENT_QUIT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +577,7 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Ctrl-u toggles mute
|
// Ctrl-u toggles mute
|
||||||
if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') {
|
if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'u') {
|
||||||
event.type = Common::EVENT_MUTE;
|
event.type = Common::EVENT_MUTE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -584,8 +586,8 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
event.type = Common::EVENT_KEYDOWN;
|
event.type = Common::EVENT_KEYDOWN;
|
||||||
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
|
event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode);
|
||||||
event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym));
|
event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -594,6 +596,7 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
|
||||||
if (remapKey(ev, event))
|
if (remapKey(ev, event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
SDLKey sdlKeycode = obtainKeycode(ev.key.keysym);
|
||||||
SDLMod mod = SDL_GetModState();
|
SDLMod mod = SDL_GetModState();
|
||||||
|
|
||||||
// Check if this is an event handled by handleKeyDown(), and stop if it is
|
// Check if this is an event handled by handleKeyDown(), and stop if it is
|
||||||
|
@ -601,35 +604,30 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
|
||||||
// Check if the Ctrl key is down, so that we can trap cases where the
|
// Check if the Ctrl key is down, so that we can trap cases where the
|
||||||
// user has the Ctrl key down, and has just released a special key
|
// user has the Ctrl key down, and has just released a special key
|
||||||
if (mod & KMOD_CTRL) {
|
if (mod & KMOD_CTRL) {
|
||||||
if (ev.key.keysym.sym == 'm' || // Ctrl-m toggles mouse capture
|
if (sdlKeycode == 'm' || // Ctrl-m toggles mouse capture
|
||||||
#if defined(MACOSX)
|
#if defined(MACOSX)
|
||||||
// Meta - Q, handled below
|
// Meta - Q, handled below
|
||||||
#elif defined(POSIX)
|
#elif defined(POSIX)
|
||||||
ev.key.keysym.sym == 'q' || // On other *nix systems, Control-Q quits
|
sdlKeycode == 'q' || // On other *nix systems, Control-Q quits
|
||||||
#else
|
#else
|
||||||
ev.key.keysym.sym == 'z' || // Ctrl-z quit
|
sdlKeycode == 'z' || // Ctrl-z quit
|
||||||
#endif
|
#endif
|
||||||
ev.key.keysym.sym == 'u') // Ctrl-u toggles mute
|
sdlKeycode == 'u') // Ctrl-u toggles mute
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same for other keys (Meta and Alt)
|
// Same for other keys (Meta and Alt)
|
||||||
#if defined(MACOSX)
|
#if defined(MACOSX)
|
||||||
if ((mod & KMOD_META) && ev.key.keysym.sym == 'q')
|
if ((mod & KMOD_META) && sdlKeycode == 'q')
|
||||||
return false; // On Macintosh, Cmd-Q quits
|
return false; // On Macintosh, Cmd-Q quits
|
||||||
#elif defined(POSIX)
|
|
||||||
// Control Q has already been handled above
|
|
||||||
#else
|
|
||||||
if ((mod & KMOD_ALT) && ev.key.keysym.sym == 'x')
|
|
||||||
return false; // Alt-x quit
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we reached here, this isn't an event handled by handleKeyDown(), thus
|
// If we reached here, this isn't an event handled by handleKeyDown(), thus
|
||||||
// continue normally
|
// continue normally
|
||||||
|
|
||||||
event.type = Common::EVENT_KEYUP;
|
event.type = Common::EVENT_KEYUP;
|
||||||
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
|
event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode);
|
||||||
event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, 0);
|
event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, 0);
|
||||||
|
|
||||||
// Ctrl-Alt-<key> will change the GFX mode
|
// Ctrl-Alt-<key> will change the GFX mode
|
||||||
SDLModToOSystemKeyFlags(mod, event);
|
SDLModToOSystemKeyFlags(mod, event);
|
||||||
|
@ -887,10 +885,63 @@ bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDLKey SdlEventSource::obtainKeycode(const SDL_keysym keySym) {
|
||||||
|
#if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(WIN32) && !defined(_WIN32_WCE)
|
||||||
|
// WORKAROUND: SDL 1.2 on Windows does not use the user configured keyboard layout,
|
||||||
|
// resulting in "keySym.sym" values to always be those expected for an US keyboard.
|
||||||
|
// For example, SDL returns SDLK_Q when pressing the 'A' key on an AZERTY keyboard.
|
||||||
|
// This defeats the purpose of keycodes which is to be able to refer to a key without
|
||||||
|
// knowing where it is physically located.
|
||||||
|
// We work around this issue by querying the currently active Windows keyboard layout
|
||||||
|
// using the scancode provided by SDL.
|
||||||
|
|
||||||
|
if (keySym.sym >= SDLK_0 && keySym.sym <= SDLK_9) {
|
||||||
|
// The keycode returned by SDL is kept for the number keys.
|
||||||
|
// Querying the keyboard layout for those would return the base key values
|
||||||
|
// for AZERTY keyboards, which are not numbers. For example, SDLK_1 would
|
||||||
|
// map to SDLK_AMPERSAND. This is theoretically correct but practically unhelpful,
|
||||||
|
// because it makes it impossible to handle key combinations such as "ctrl-1".
|
||||||
|
return keySym.sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vk = MapVirtualKey(keySym.scancode, MAPVK_VSC_TO_VK);
|
||||||
|
if (vk) {
|
||||||
|
int ch = (MapVirtualKey(vk, MAPVK_VK_TO_CHAR) & 0x7FFF);
|
||||||
|
// The top bit of the result of MapVirtualKey with MAPVK_VSC_TO_VK signals
|
||||||
|
// a dead key was pressed. In that case we keep the value of the accent alone.
|
||||||
|
if (ch) {
|
||||||
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
|
// Windows returns uppercase ASCII whereas SDL expects lowercase
|
||||||
|
return (SDLKey)(SDLK_a + (ch - 'A'));
|
||||||
|
} else {
|
||||||
|
return (SDLKey)ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return keySym.sym;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
|
uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
SDL_Event events[2];
|
SDL_Event events[2];
|
||||||
|
|
||||||
|
// Update the event queue here to give SDL a chance to insert TEXTINPUT
|
||||||
|
// events for KEYDOWN events. Otherwise we have a high chance that on
|
||||||
|
// Windows the TEXTINPUT event is not in the event queue at this point.
|
||||||
|
// In this case we will get two events with ascii values due to mapKey
|
||||||
|
// and dispatchSDLEvent. This results in nasty double input of characters
|
||||||
|
// in the GUI.
|
||||||
|
//
|
||||||
|
// FIXME: This is all a bit fragile because in mapKey we derive the ascii
|
||||||
|
// value from the key code if no unicode value is given. This is legacy
|
||||||
|
// behavior and should be removed anyway. If that is removed, we might not
|
||||||
|
// even need to do this peeking here but instead can rely on the
|
||||||
|
// SDL_TEXTINPUT case in dispatchSDLEvent to introduce keydown/keyup with
|
||||||
|
// proper ASCII values (but with KEYCODE_INVALID as keycode).
|
||||||
|
SDL_PumpEvents();
|
||||||
|
|
||||||
// In SDL2, the unicode field has been removed from the keysym struct.
|
// In SDL2, the unicode field has been removed from the keysym struct.
|
||||||
// Instead a SDL_TEXTINPUT event is generated on key combinations that
|
// Instead a SDL_TEXTINPUT event is generated on key combinations that
|
||||||
// generates unicode.
|
// generates unicode.
|
||||||
|
|
|
@ -150,6 +150,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
uint32 obtainUnicode(const SDL_keysym keySym);
|
uint32 obtainUnicode(const SDL_keysym keySym);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the keycode for the specified key sym.
|
||||||
|
*/
|
||||||
|
SDLKey obtainKeycode(const SDL_keysym keySym);
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
/**
|
/**
|
||||||
* Whether _fakeKeyUp contains an event we need to send.
|
* Whether _fakeKeyUp contains an event we need to send.
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
#define INCL_DOS
|
#define INCL_DOS
|
||||||
|
@ -251,4 +252,67 @@ Common::WriteStream *POSIXFilesystemNode::createWriteStream() {
|
||||||
return StdioStream::makeFromPath(getPath(), true);
|
return StdioStream::makeFromPath(getPath(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Posix {
|
||||||
|
|
||||||
|
bool assureDirectoryExists(const Common::String &dir, const char *prefix) {
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
// Check whether the prefix exists if one is supplied.
|
||||||
|
if (prefix) {
|
||||||
|
if (stat(prefix, &sb) != 0) {
|
||||||
|
return false;
|
||||||
|
} else if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain absolute path.
|
||||||
|
Common::String path;
|
||||||
|
if (prefix) {
|
||||||
|
path = prefix;
|
||||||
|
path += '/';
|
||||||
|
path += dir;
|
||||||
|
} else {
|
||||||
|
path = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = Common::normalizePath(path, '/');
|
||||||
|
|
||||||
|
const Common::String::iterator end = path.end();
|
||||||
|
Common::String::iterator cur = path.begin();
|
||||||
|
if (*cur == '/')
|
||||||
|
++cur;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (cur + 1 != end) {
|
||||||
|
if (*cur != '/') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is kind of ugly and against the purpose of Common::String to
|
||||||
|
// insert 0s inside, but this is just for a local string and
|
||||||
|
// simplifies the code a lot.
|
||||||
|
*cur = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mkdir(path.c_str(), 0755) != 0) {
|
||||||
|
if (errno == EEXIST) {
|
||||||
|
if (stat(path.c_str(), &sb) != 0) {
|
||||||
|
return false;
|
||||||
|
} else if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*cur = '/';
|
||||||
|
} while (cur++ != end);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Posix
|
||||||
|
|
||||||
#endif //#if defined(POSIX)
|
#endif //#if defined(POSIX)
|
||||||
|
|
|
@ -81,4 +81,18 @@ private:
|
||||||
virtual void setFlags();
|
virtual void setFlags();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Posix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assure that a directory path exists.
|
||||||
|
*
|
||||||
|
* @param dir The path which is required to exist.
|
||||||
|
* @param prefix An (optional) prefix which should not be created if non existent.
|
||||||
|
* prefix is prepended to dir if supplied.
|
||||||
|
* @return true in case the directoy exists (or was created), false otherwise.
|
||||||
|
*/
|
||||||
|
bool assureDirectoryExists(const Common::String &dir, const char *prefix = nullptr);
|
||||||
|
|
||||||
|
} // End of namespace Posix
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -185,6 +185,9 @@ MusicDevices WindowsMusicPlugin::getDevices() const {
|
||||||
deviceNames.push_back(tmp.szPname);
|
deviceNames.push_back(tmp.szPname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Limit us to the number of actually retrieved devices.
|
||||||
|
numDevs = deviceNames.size();
|
||||||
|
|
||||||
// Check for non-unique device names. This may happen if someone has devices with identical
|
// Check for non-unique device names. This may happen if someone has devices with identical
|
||||||
// names (e. g. more than one USB device of the exact same hardware type). It seems that this
|
// names (e. g. more than one USB device of the exact same hardware type). It seems that this
|
||||||
// does happen in reality sometimes. We generate index numbers for these devices.
|
// does happen in reality sometimes. We generate index numbers for these devices.
|
||||||
|
|
|
@ -3,6 +3,7 @@ MODULE := backends
|
||||||
MODULE_OBJS := \
|
MODULE_OBJS := \
|
||||||
base-backend.o \
|
base-backend.o \
|
||||||
modular-backend.o \
|
modular-backend.o \
|
||||||
|
audiocd/audiocd-stream.o \
|
||||||
audiocd/default/default-audiocd.o \
|
audiocd/default/default-audiocd.o \
|
||||||
events/default/default-events.o \
|
events/default/default-events.o \
|
||||||
fs/abstract-fs.o \
|
fs/abstract-fs.o \
|
||||||
|
@ -90,6 +91,7 @@ endif
|
||||||
|
|
||||||
ifdef MACOSX
|
ifdef MACOSX
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
|
audiocd/macosx/macosx-audiocd.o \
|
||||||
midi/coreaudio.o \
|
midi/coreaudio.o \
|
||||||
midi/coremidi.o \
|
midi/coremidi.o \
|
||||||
updates/macosx/macosx-updates.o \
|
updates/macosx/macosx-updates.o \
|
||||||
|
@ -98,11 +100,13 @@ endif
|
||||||
|
|
||||||
ifdef WIN32
|
ifdef WIN32
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
|
audiocd/win32/win32-audiocd.o \
|
||||||
fs/windows/windows-fs.o \
|
fs/windows/windows-fs.o \
|
||||||
fs/windows/windows-fs-factory.o \
|
fs/windows/windows-fs-factory.o \
|
||||||
midi/windows.o \
|
midi/windows.o \
|
||||||
plugins/win32/win32-provider.o \
|
plugins/win32/win32-provider.o \
|
||||||
saves/windows/windows-saves.o \
|
saves/windows/windows-saves.o \
|
||||||
|
updates/win32/win32-updates.o \
|
||||||
taskbar/win32/win32-taskbar.o
|
taskbar/win32/win32-taskbar.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -121,6 +125,11 @@ MODULE_OBJS += \
|
||||||
events/ps3sdl/ps3sdl-events.o
|
events/ps3sdl/ps3sdl-events.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef USE_LINUXCD
|
||||||
|
MODULE_OBJS += \
|
||||||
|
audiocd/linux/linux-audiocd.o
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(BACKEND),tizen)
|
ifeq ($(BACKEND),tizen)
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
timer/tizen/timer.o
|
timer/tizen/timer.o
|
||||||
|
|
|
@ -24,13 +24,44 @@
|
||||||
|
|
||||||
#if defined(__amigaos4__)
|
#if defined(__amigaos4__)
|
||||||
|
|
||||||
|
#include "backends/fs/amigaos4/amigaos4-fs.h"
|
||||||
#include "backends/platform/sdl/amigaos/amigaos.h"
|
#include "backends/platform/sdl/amigaos/amigaos.h"
|
||||||
#include "backends/plugins/sdl/sdl-provider.h"
|
#include "backends/plugins/sdl/sdl-provider.h"
|
||||||
#include "base/main.h"
|
#include "base/main.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Set up a stack cookie to avoid crashes due to too few stack set by users
|
// The following will gather the application name and add the install path
|
||||||
|
// to a variable in AmigaOS4's ENV(ARC) system. It will be placed in AppPaths
|
||||||
|
// so that ScummVM can become AmiUpdate aware
|
||||||
|
const char *const appname = "ResidualVM";
|
||||||
|
|
||||||
|
BPTR lock;
|
||||||
|
APTR oldwin;
|
||||||
|
|
||||||
|
// Obtain a lock to the home directory
|
||||||
|
if ((lock = IDOS->GetProgramDir())) {
|
||||||
|
TEXT progpath[2048];
|
||||||
|
TEXT apppath[1024] = "AppPaths";
|
||||||
|
|
||||||
|
if (IDOS->DevNameFromLock(lock,
|
||||||
|
progpath,
|
||||||
|
sizeof(progpath),
|
||||||
|
DN_FULLPATH)) {
|
||||||
|
|
||||||
|
// Stop any "Insert volume..." type requesters
|
||||||
|
oldwin = IDOS->SetProcWindow((APTR)-1);
|
||||||
|
|
||||||
|
// Finally, set the variable to the path the executable was run from
|
||||||
|
IDOS->AddPart( apppath, appname, 1024);
|
||||||
|
IDOS->SetVar( apppath, progpath, -1, GVF_GLOBAL_ONLY|GVF_SAVE_VAR );
|
||||||
|
|
||||||
|
// Turn system requesters back on
|
||||||
|
IDOS->SetProcWindow( oldwin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a stack cookie to avoid crashes from a stack set too low
|
||||||
static const char *stack_cookie __attribute__((used)) = "$STACK: 600000";
|
static const char *stack_cookie __attribute__((used)) = "$STACK: 600000";
|
||||||
|
|
||||||
// Create our OSystem instance
|
// Create our OSystem instance
|
||||||
|
@ -44,7 +75,7 @@ int main(int argc, char *argv[]) {
|
||||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Invoke the actual ScummVM main entry point:
|
// Invoke the actual ScummVM main entry point
|
||||||
int res = scummvm_main(argc, argv);
|
int res = scummvm_main(argc, argv);
|
||||||
|
|
||||||
// Free OSystem
|
// Free OSystem
|
||||||
|
|
|
@ -10,6 +10,17 @@ amigaosdist: $(EXECUTABLE)
|
||||||
ifdef DIST_FILES_ENGINEDATA
|
ifdef DIST_FILES_ENGINEDATA
|
||||||
cp $(DIST_FILES_ENGINEDATA) $(AMIGAOSPATH)/extras/
|
cp $(DIST_FILES_ENGINEDATA) $(AMIGAOSPATH)/extras/
|
||||||
endif
|
endif
|
||||||
|
cat ${srcdir}/README | sed -f ${srcdir}/dists/amiga/convertRM.sed > README.conv
|
||||||
|
# AmigaOS's shell is not happy with indented comments, thus don't do it.
|
||||||
|
# AREXX seems to have problems when ${srcdir} is '.'. It will break with a
|
||||||
|
# "Program not found" error. Therefore we copy the script to the cwd and
|
||||||
|
# remove it again, once it has finished.
|
||||||
|
cp ${srcdir}/dists/amiga/RM2AG.rx .
|
||||||
|
rx RM2AG.rx README.conv
|
||||||
|
cp README.guide $(AMIGAOSPATH)
|
||||||
|
rm RM2AG.rx
|
||||||
|
rm README.conv
|
||||||
|
rm README.guide
|
||||||
cp $(DIST_FILES_DOCS) $(AMIGAOSPATH)
|
cp $(DIST_FILES_DOCS) $(AMIGAOSPATH)
|
||||||
|
|
||||||
# Special target to cross create an AmigaOS snapshot installation
|
# Special target to cross create an AmigaOS snapshot installation
|
||||||
|
|
|
@ -27,9 +27,10 @@
|
||||||
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
|
|
||||||
#include "backends/platform/sdl/macosx/macosx.h"
|
#include "backends/audiocd/macosx/macosx-audiocd.h"
|
||||||
#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h"
|
#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h"
|
||||||
#include "backends/platform/sdl/macosx/appmenu_osx.h"
|
#include "backends/platform/sdl/macosx/appmenu_osx.h"
|
||||||
|
#include "backends/platform/sdl/macosx/macosx.h"
|
||||||
#include "backends/updates/macosx/macosx-updates.h"
|
#include "backends/updates/macosx/macosx-updates.h"
|
||||||
#include "backends/taskbar/macosx/macosx-taskbar.h"
|
#include "backends/taskbar/macosx/macosx-taskbar.h"
|
||||||
|
|
||||||
|
@ -170,4 +171,8 @@ Common::String OSystem_MacOSX::getSystemLanguage() const {
|
||||||
#endif // USE_DETECTLANG
|
#endif // USE_DETECTLANG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioCDManager *OSystem_MacOSX::createAudioCDManager() {
|
||||||
|
return createMacOSXAudioCDManager();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,11 @@ public:
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void initBackend();
|
virtual void initBackend();
|
||||||
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
|
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Override createAudioCDManager() to get our Mac-specific
|
||||||
|
// version.
|
||||||
|
virtual AudioCDManager *createAudioCDManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3)
|
#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(ANDROIDSDL)
|
||||||
|
|
||||||
#include "backends/platform/sdl/posix/posix.h"
|
#include "backends/platform/sdl/posix/posix.h"
|
||||||
#include "backends/plugins/sdl/sdl-provider.h"
|
#include "backends/plugins/sdl/sdl-provider.h"
|
||||||
|
|
|
@ -33,14 +33,18 @@
|
||||||
#include "backends/platform/sdl/posix/posix.h"
|
#include "backends/platform/sdl/posix/posix.h"
|
||||||
#include "backends/saves/posix/posix-saves.h"
|
#include "backends/saves/posix/posix-saves.h"
|
||||||
#include "backends/fs/posix/posix-fs-factory.h"
|
#include "backends/fs/posix/posix-fs-factory.h"
|
||||||
|
#include "backends/fs/posix/posix-fs.h"
|
||||||
#include "backends/taskbar/unity/unity-taskbar.h"
|
#include "backends/taskbar/unity/unity-taskbar.h"
|
||||||
|
|
||||||
|
#ifdef USE_LINUXCD
|
||||||
|
#include "backends/audiocd/linux/linux-audiocd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName)
|
OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName)
|
||||||
:
|
:
|
||||||
_baseConfigName(baseConfigName) {
|
_baseConfigName(baseConfigName) {
|
||||||
|
@ -82,11 +86,54 @@ bool OSystem_POSIX::hasFeature(Feature f) {
|
||||||
Common::String OSystem_POSIX::getDefaultConfigFileName() {
|
Common::String OSystem_POSIX::getDefaultConfigFileName() {
|
||||||
Common::String configFile;
|
Common::String configFile;
|
||||||
|
|
||||||
// On POSIX type systems, by default we store the config file inside
|
Common::String prefix;
|
||||||
// to the HOME directory of the user.
|
#ifdef MACOSX
|
||||||
const char *home = getenv("HOME");
|
prefix = getenv("HOME");
|
||||||
if (home != NULL && (strlen(home) + 1 + _baseConfigName.size()) < MAXPATHLEN) {
|
#elif !defined(SAMSUNGTV)
|
||||||
configFile = Common::String::format("%s/%s", home, _baseConfigName.c_str());
|
const char *envVar;
|
||||||
|
// Our old configuration file path for POSIX systems was ~/.residualvmrc.
|
||||||
|
// If that file exists, we still use it.
|
||||||
|
envVar = getenv("HOME");
|
||||||
|
if (envVar && *envVar) {
|
||||||
|
configFile = envVar;
|
||||||
|
configFile += '/';
|
||||||
|
configFile += ".residualvmrc";
|
||||||
|
|
||||||
|
if (configFile.size() < MAXPATHLEN) {
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(configFile.c_str(), &sb) == 0) {
|
||||||
|
return configFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On POSIX systems we follow the XDG Base Directory Specification for
|
||||||
|
// where to store files. The version we based our code upon can be found
|
||||||
|
// over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
|
||||||
|
envVar = getenv("XDG_CONFIG_HOME");
|
||||||
|
if (!envVar || !*envVar) {
|
||||||
|
envVar = getenv("HOME");
|
||||||
|
if (!envVar) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Posix::assureDirectoryExists(".config", envVar)) {
|
||||||
|
prefix = envVar;
|
||||||
|
prefix += "/.config";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prefix = envVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prefix.empty() && Posix::assureDirectoryExists("residualvm", prefix.c_str())) {
|
||||||
|
prefix += "/residualvm";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!prefix.empty() && (prefix.size() + 1 + _baseConfigName.size()) < MAXPATHLEN) {
|
||||||
|
configFile = prefix;
|
||||||
|
configFile += '/';
|
||||||
|
configFile += _baseConfigName;
|
||||||
} else {
|
} else {
|
||||||
configFile = _baseConfigName;
|
configFile = _baseConfigName;
|
||||||
}
|
}
|
||||||
|
@ -99,58 +146,43 @@ Common::WriteStream *OSystem_POSIX::createLogFile() {
|
||||||
// of a failure, we know that no log file is open.
|
// of a failure, we know that no log file is open.
|
||||||
_logFilePath.clear();
|
_logFilePath.clear();
|
||||||
|
|
||||||
const char *home = getenv("HOME");
|
const char *prefix = nullptr;
|
||||||
if (home == NULL)
|
Common::String logFile;
|
||||||
return 0;
|
|
||||||
|
|
||||||
Common::String logFile(home);
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
logFile += "/Library";
|
prefix = getenv("HOME");
|
||||||
#else
|
if (prefix == nullptr) {
|
||||||
logFile += "/.residualvm";
|
|
||||||
#endif
|
|
||||||
#ifdef SAMSUNGTV
|
|
||||||
logFile = "/mtd_ram";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct stat sb;
|
|
||||||
|
|
||||||
// Check whether the dir exists
|
|
||||||
if (stat(logFile.c_str(), &sb) == -1) {
|
|
||||||
// The dir does not exist, or stat failed for some other reason.
|
|
||||||
if (errno != ENOENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If the problem was that the path pointed to nothing, try
|
|
||||||
// to create the dir.
|
|
||||||
if (mkdir(logFile.c_str(), 0755) != 0)
|
|
||||||
return 0;
|
|
||||||
} else if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
// Path is no directory. Oops
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MACOSX
|
logFile = "Library/Logs";
|
||||||
logFile += "/Logs";
|
#elif SAMSUNGTV
|
||||||
|
prefix = nullptr;
|
||||||
|
logFile = "/mtd_ram";
|
||||||
#else
|
#else
|
||||||
logFile += "/logs";
|
// On POSIX systems we follow the XDG Base Directory Specification for
|
||||||
|
// where to store files. The version we based our code upon can be found
|
||||||
|
// over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
|
||||||
|
prefix = getenv("XDG_CACHE_HOME");
|
||||||
|
if (prefix == nullptr || !*prefix) {
|
||||||
|
prefix = getenv("HOME");
|
||||||
|
if (prefix == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile = ".cache/";
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile += "residualvm/logs";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check whether the dir exists
|
if (!Posix::assureDirectoryExists(logFile, prefix)) {
|
||||||
if (stat(logFile.c_str(), &sb) == -1) {
|
|
||||||
// The dir does not exist, or stat failed for some other reason.
|
|
||||||
if (errno != ENOENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If the problem was that the path pointed to nothing, try
|
|
||||||
// to create the dir.
|
|
||||||
if (mkdir(logFile.c_str(), 0755) != 0)
|
|
||||||
return 0;
|
|
||||||
} else if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
// Path is no directory. Oops
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefix) {
|
||||||
|
logFile = Common::String::format("%s/%s", prefix, logFile.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
logFile += "/residualvm.log";
|
logFile += "/residualvm.log";
|
||||||
|
|
||||||
Common::FSNode file(logFile);
|
Common::FSNode file(logFile);
|
||||||
|
@ -212,4 +244,12 @@ bool OSystem_POSIX::displayLogFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AudioCDManager *OSystem_POSIX::createAudioCDManager() {
|
||||||
|
#ifdef USE_LINUXCD
|
||||||
|
return createLinuxAudioCDManager();
|
||||||
|
#else
|
||||||
|
return OSystem_SDL::createAudioCDManager();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
class OSystem_POSIX : public OSystem_SDL {
|
class OSystem_POSIX : public OSystem_SDL {
|
||||||
public:
|
public:
|
||||||
// Let the subclasses be able to change _baseConfigName in the constructor
|
// Let the subclasses be able to change _baseConfigName in the constructor
|
||||||
OSystem_POSIX(Common::String baseConfigName = ".residualvmrc");
|
OSystem_POSIX(Common::String baseConfigName = "residualvm.ini");
|
||||||
virtual ~OSystem_POSIX() {}
|
virtual ~OSystem_POSIX() {}
|
||||||
|
|
||||||
virtual bool hasFeature(Feature f);
|
virtual bool hasFeature(Feature f);
|
||||||
|
@ -59,6 +59,8 @@ protected:
|
||||||
virtual Common::String getDefaultConfigFileName();
|
virtual Common::String getDefaultConfigFileName();
|
||||||
|
|
||||||
virtual Common::WriteStream *createLogFile();
|
virtual Common::WriteStream *createLogFile();
|
||||||
|
|
||||||
|
virtual AudioCDManager *createAudioCDManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,21 @@ typedef struct { int FAKE; } FAKE_FILE;
|
||||||
#define strncasecmp FAKE_strncasecmp
|
#define strncasecmp FAKE_strncasecmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_exit)
|
||||||
|
#undef exit
|
||||||
|
#define exit FAKE_exit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_abort)
|
||||||
|
#undef abort
|
||||||
|
#define abort FAKE_abort
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_system)
|
||||||
|
#undef system
|
||||||
|
#define system FAKE_system
|
||||||
|
#endif
|
||||||
|
|
||||||
// HACK: SDL might include windows.h which defines its own ARRAYSIZE.
|
// HACK: SDL might include windows.h which defines its own ARRAYSIZE.
|
||||||
// However, we want to use the version from common/util.h. Thus, we make sure
|
// However, we want to use the version from common/util.h. Thus, we make sure
|
||||||
// that we actually have this definition after including the SDL headers.
|
// that we actually have this definition after including the SDL headers.
|
||||||
|
@ -129,7 +144,7 @@ typedef struct { int FAKE; } FAKE_FILE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// In a moment of brilliance Xlib.h included by SDL_syswm.h #defines the
|
// In a moment of brilliance Xlib.h included by SDL_syswm.h #defines the
|
||||||
// following names. In a moment of mental breakdown, which occured upon
|
// following names. In a moment of mental breakdown, which occurred upon
|
||||||
// gazing at Xlib.h, LordHoto decided to undefine them to prevent havoc.
|
// gazing at Xlib.h, LordHoto decided to undefine them to prevent havoc.
|
||||||
#ifdef Status
|
#ifdef Status
|
||||||
#undef Status
|
#undef Status
|
||||||
|
@ -163,6 +178,21 @@ typedef struct { int FAKE; } FAKE_FILE;
|
||||||
#define strncasecmp FORBIDDEN_SYMBOL_REPLACEMENT
|
#define strncasecmp FORBIDDEN_SYMBOL_REPLACEMENT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_exit)
|
||||||
|
#undef exit
|
||||||
|
#define exit(a) FORBIDDEN_SYMBOL_REPLACEMENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_abort)
|
||||||
|
#undef abort
|
||||||
|
#define abort() FORBIDDEN_SYMBOL_REPLACEMENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_system)
|
||||||
|
#undef system
|
||||||
|
#define system(a) FORBIDDEN_SYMBOL_REPLACEMENT
|
||||||
|
#endif
|
||||||
|
|
||||||
// SDL 2 has major API changes. We redefine constants which got renamed to
|
// SDL 2 has major API changes. We redefine constants which got renamed to
|
||||||
// ease the transition. This is sometimes dangerous because the values changed
|
// ease the transition. This is sometimes dangerous because the values changed
|
||||||
// too!
|
// too!
|
||||||
|
|
|
@ -49,9 +49,10 @@
|
||||||
#include "backends/timer/sdl/sdl-timer.h"
|
#include "backends/timer/sdl/sdl-timer.h"
|
||||||
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
|
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
|
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
|
||||||
#include "graphics/opengl/context.h"
|
//#include "graphics/cursorman.h" // ResidualVM
|
||||||
|
#include "graphics/opengl/context.h" // ResidualVM specific
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <time.h> // for getTimeAndDate()
|
#include <time.h> // for getTimeAndDate()
|
||||||
|
@ -169,10 +170,12 @@ void OSystem_SDL::initBackend() {
|
||||||
// is not active by this point.
|
// is not active by this point.
|
||||||
debug(1, "Using SDL Video Driver \"%s\"", sdlDriverName);
|
debug(1, "Using SDL Video Driver \"%s\"", sdlDriverName);
|
||||||
|
|
||||||
|
// ResidualVM specific code start
|
||||||
detectDesktopResolution();
|
detectDesktopResolution();
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
detectFramebufferSupport();
|
detectFramebufferSupport();
|
||||||
#endif
|
#endif
|
||||||
|
// ResidualVM specific code end
|
||||||
|
|
||||||
// Create the default event source, in case a custom backend
|
// Create the default event source, in case a custom backend
|
||||||
// manager didn't provide one yet.
|
// manager didn't provide one yet.
|
||||||
|
@ -203,15 +206,7 @@ void OSystem_SDL::initBackend() {
|
||||||
_timerManager = new SdlTimerManager();
|
_timerManager = new SdlTimerManager();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_audiocdManager == 0) {
|
_audiocdManager = createAudioCDManager();
|
||||||
// Audio CD support was removed with SDL 2.0
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
_audiocdManager = new DefaultAudioCDManager();
|
|
||||||
#else
|
|
||||||
_audiocdManager = new SdlAudioCDManager();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup a custom program icon.
|
// Setup a custom program icon.
|
||||||
_window->setupIcon();
|
_window->setupIcon();
|
||||||
|
@ -345,6 +340,7 @@ void OSystem_SDL::setWindowCaption(const char *caption) {
|
||||||
_window->setWindowCaption(cap);
|
_window->setWindowCaption(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResidualVM specific code
|
||||||
void OSystem_SDL::setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) {
|
void OSystem_SDL::setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) {
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
bool switchedManager = false;
|
bool switchedManager = false;
|
||||||
|
@ -374,6 +370,7 @@ void OSystem_SDL::setupScreen(uint screenW, uint screenH, bool fullscreen, bool
|
||||||
void OSystem_SDL::launcherInitSize(uint w, uint h) {
|
void OSystem_SDL::launcherInitSize(uint w, uint h) {
|
||||||
setupScreen(w, h, false, false);
|
setupScreen(w, h, false, false);
|
||||||
}
|
}
|
||||||
|
// End of ResidualVM specific code
|
||||||
|
|
||||||
void OSystem_SDL::quit() {
|
void OSystem_SDL::quit() {
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -531,6 +528,15 @@ Common::TimerManager *OSystem_SDL::getTimerManager() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioCDManager *OSystem_SDL::createAudioCDManager() {
|
||||||
|
// Audio CD support was removed with SDL 2.0
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
return new DefaultAudioCDManager();
|
||||||
|
#else
|
||||||
|
return new SdlAudioCDManager();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ResidualVM specific code
|
// ResidualVM specific code
|
||||||
bool OSystem_SDL::hasFeature(Feature f) {
|
bool OSystem_SDL::hasFeature(Feature f) {
|
||||||
if (f == kFeatureSideTextures)
|
if (f == kFeatureSideTextures)
|
||||||
|
|
|
@ -83,6 +83,7 @@ public:
|
||||||
|
|
||||||
// ResidualVM specific code
|
// ResidualVM specific code
|
||||||
virtual void setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) override;
|
virtual void setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) override;
|
||||||
|
// ResidualVM specific code
|
||||||
virtual void launcherInitSize(uint w, uint h) override;
|
virtual void launcherInitSize(uint w, uint h) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -119,6 +120,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void initSDL();
|
virtual void initSDL();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the audio CD manager
|
||||||
|
*/
|
||||||
|
virtual AudioCDManager *createAudioCDManager();
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
virtual Common::WriteStream *createLogFile() { return 0; }
|
virtual Common::WriteStream *createLogFile() { return 0; }
|
||||||
Backends::Log::Log *_logger;
|
Backends::Log::Log *_logger;
|
||||||
|
|
|
@ -44,7 +44,12 @@ int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpC
|
||||||
SDL_SetModuleHandle(GetModuleHandle(NULL));
|
SDL_SetModuleHandle(GetModuleHandle(NULL));
|
||||||
#endif
|
#endif
|
||||||
// HACK: __argc, __argv are broken and return zero when using mingwrt 4.0+ on MinGW
|
// HACK: __argc, __argv are broken and return zero when using mingwrt 4.0+ on MinGW
|
||||||
#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64__)
|
// HACK: MinGW-w64 based toolchains neither feature _argc nor _argv. The 32 bit
|
||||||
|
// incarnation only defines __MINGW32__. This leads to build breakage due to
|
||||||
|
// missing declarations. Luckily MinGW-w64 based toolchains define
|
||||||
|
// __MINGW64_VERSION_foo macros inside _mingw.h, which is included from all
|
||||||
|
// system headers. Thus we abuse that to detect them.
|
||||||
|
#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||||
return main(_argc, _argv);
|
return main(_argc, _argv);
|
||||||
#else
|
#else
|
||||||
return main(__argc, __argv);
|
return main(__argc, __argv);
|
||||||
|
|
|
@ -35,11 +35,13 @@
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
#include "backends/audiocd/win32/win32-audiocd.h"
|
||||||
#include "backends/platform/sdl/win32/win32.h"
|
#include "backends/platform/sdl/win32/win32.h"
|
||||||
#include "backends/platform/sdl/win32/win32-window.h"
|
#include "backends/platform/sdl/win32/win32-window.h"
|
||||||
#include "backends/saves/windows/windows-saves.h"
|
#include "backends/saves/windows/windows-saves.h"
|
||||||
#include "backends/fs/windows/windows-fs-factory.h"
|
#include "backends/fs/windows/windows-fs-factory.h"
|
||||||
#include "backends/taskbar/win32/win32-taskbar.h"
|
#include "backends/taskbar/win32/win32-taskbar.h"
|
||||||
|
#include "backends/updates/win32/win32-updates.h"
|
||||||
|
|
||||||
#include "common/memstream.h"
|
#include "common/memstream.h"
|
||||||
|
|
||||||
|
@ -81,6 +83,11 @@ void OSystem_Win32::initBackend() {
|
||||||
if (_savefileManager == 0)
|
if (_savefileManager == 0)
|
||||||
_savefileManager = new WindowsSaveFileManager();
|
_savefileManager = new WindowsSaveFileManager();
|
||||||
|
|
||||||
|
#if defined(USE_SPARKLE)
|
||||||
|
// Initialize updates manager
|
||||||
|
_updateManager = new Win32UpdateManager();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Invoke parent implementation of this method
|
// Invoke parent implementation of this method
|
||||||
OSystem_SDL::initBackend();
|
OSystem_SDL::initBackend();
|
||||||
}
|
}
|
||||||
|
@ -318,4 +325,8 @@ void OSystem_Win32::addSysArchivesToSearchSet(Common::SearchSet &s, int priority
|
||||||
OSystem_SDL::addSysArchivesToSearchSet(s, priority);
|
OSystem_SDL::addSysArchivesToSearchSet(s, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioCDManager *OSystem_Win32::createAudioCDManager() {
|
||||||
|
return createWin32AudioCDManager();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,10 @@ protected:
|
||||||
|
|
||||||
virtual Common::String getDefaultConfigFileName();
|
virtual Common::String getDefaultConfigFileName();
|
||||||
virtual Common::WriteStream *createLogFile();
|
virtual Common::WriteStream *createLogFile();
|
||||||
|
|
||||||
|
// Override createAudioCDManager() to get our Mac-specific
|
||||||
|
// version.
|
||||||
|
virtual AudioCDManager *createAudioCDManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
debug("Failed loading plugin '%s' (error code %d)", _filename.c_str(), (int32) GetLastError());
|
debug("Failed loading plugin '%s' (error code %d)", _filename.c_str(), (int32) GetLastError());
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
debug(1, "Success loading plugin '%s', handle %08X", _filename.c_str(), (uint32) _dlHandle);
|
debug(1, "Success loading plugin '%s', handle %p", _filename.c_str(), _dlHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DynamicPlugin::loadPlugin();
|
return DynamicPlugin::loadPlugin();
|
||||||
|
|
|
@ -60,22 +60,15 @@ void DefaultSaveFileManager::checkPath(const Common::FSNode &dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::StringArray DefaultSaveFileManager::listSavefiles(const Common::String &pattern) {
|
Common::StringArray DefaultSaveFileManager::listSavefiles(const Common::String &pattern) {
|
||||||
Common::String savePathName = getSavePath();
|
// Assure the savefile name cache is up-to-date.
|
||||||
checkPath(Common::FSNode(savePathName));
|
assureCached(getSavePath());
|
||||||
if (getError().getCode() != Common::kNoError)
|
if (getError().getCode() != Common::kNoError)
|
||||||
return Common::StringArray();
|
return Common::StringArray();
|
||||||
|
|
||||||
// recreate FSNode since checkPath may have changed/created the directory
|
|
||||||
Common::FSNode savePath(savePathName);
|
|
||||||
|
|
||||||
Common::FSDirectory dir(savePath);
|
|
||||||
Common::ArchiveMemberList savefiles;
|
|
||||||
Common::StringArray results;
|
Common::StringArray results;
|
||||||
Common::String search(pattern);
|
for (SaveFileCache::const_iterator file = _saveFileCache.begin(), end = _saveFileCache.end(); file != end; ++file) {
|
||||||
|
if (file->_key.matchString(pattern, true)) {
|
||||||
if (dir.listMatchingMembers(savefiles, search) > 0) {
|
results.push_back(file->_key);
|
||||||
for (Common::ArchiveMemberList::const_iterator file = savefiles.begin(); file != savefiles.end(); ++file) {
|
|
||||||
results.push_back((*file)->getName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,68 +76,81 @@ Common::StringArray DefaultSaveFileManager::listSavefiles(const Common::String &
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String &filename) {
|
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String &filename) {
|
||||||
// Ensure that the savepath is valid. If not, generate an appropriate error.
|
// Assure the savefile name cache is up-to-date.
|
||||||
Common::String savePathName = getSavePath();
|
assureCached(getSavePath());
|
||||||
checkPath(Common::FSNode(savePathName));
|
|
||||||
if (getError().getCode() != Common::kNoError)
|
if (getError().getCode() != Common::kNoError)
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
// recreate FSNode since checkPath may have changed/created the directory
|
SaveFileCache::const_iterator file = _saveFileCache.find(filename);
|
||||||
Common::FSNode savePath(savePathName);
|
if (file == _saveFileCache.end()) {
|
||||||
|
return nullptr;
|
||||||
Common::FSNode file = savePath.getChild(filename);
|
} else {
|
||||||
if (!file.exists())
|
// Open the file for loading.
|
||||||
return 0;
|
Common::SeekableReadStream *sf = file->_value.createReadStream();
|
||||||
|
return Common::wrapCompressedReadStream(sf);
|
||||||
// Open the file for reading
|
}
|
||||||
Common::SeekableReadStream *sf = file.createReadStream();
|
|
||||||
|
|
||||||
return Common::wrapCompressedReadStream(sf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String &filename, bool compress) {
|
Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String &filename, bool compress) {
|
||||||
// Ensure that the savepath is valid. If not, generate an appropriate error.
|
// Assure the savefile name cache is up-to-date.
|
||||||
Common::String savePathName = getSavePath();
|
const Common::String savePathName = getSavePath();
|
||||||
checkPath(Common::FSNode(savePathName));
|
assureCached(savePathName);
|
||||||
if (getError().getCode() != Common::kNoError)
|
if (getError().getCode() != Common::kNoError)
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
// recreate FSNode since checkPath may have changed/created the directory
|
// Obtain node.
|
||||||
Common::FSNode savePath(savePathName);
|
SaveFileCache::const_iterator file = _saveFileCache.find(filename);
|
||||||
|
Common::FSNode fileNode;
|
||||||
|
|
||||||
Common::FSNode file = savePath.getChild(filename);
|
// If the file did not exist before, we add it to the cache.
|
||||||
|
if (file == _saveFileCache.end()) {
|
||||||
|
const Common::FSNode savePath(savePathName);
|
||||||
|
fileNode = savePath.getChild(filename);
|
||||||
|
} else {
|
||||||
|
fileNode = file->_value;
|
||||||
|
}
|
||||||
|
|
||||||
// Open the file for saving
|
// Open the file for saving.
|
||||||
Common::WriteStream *sf = file.createWriteStream();
|
Common::WriteStream *const sf = fileNode.createWriteStream();
|
||||||
|
Common::OutSaveFile *const result = compress ? Common::wrapCompressedWriteStream(sf) : sf;
|
||||||
|
|
||||||
return compress ? Common::wrapCompressedWriteStream(sf) : sf;
|
// Add file to cache now that it exists.
|
||||||
|
_saveFileCache[filename] = Common::FSNode(fileNode.getPath());
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) {
|
bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) {
|
||||||
Common::String savePathName = getSavePath();
|
// Assure the savefile name cache is up-to-date.
|
||||||
checkPath(Common::FSNode(savePathName));
|
assureCached(getSavePath());
|
||||||
if (getError().getCode() != Common::kNoError)
|
if (getError().getCode() != Common::kNoError)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// recreate FSNode since checkPath may have changed/created the directory
|
// Obtain node if exists.
|
||||||
Common::FSNode savePath(savePathName);
|
SaveFileCache::const_iterator file = _saveFileCache.find(filename);
|
||||||
|
if (file == _saveFileCache.end()) {
|
||||||
Common::FSNode file = savePath.getChild(filename);
|
|
||||||
|
|
||||||
// FIXME: remove does not exist on all systems. If your port fails to
|
|
||||||
// compile because of this, please let us know (scummvm-devel or Fingolfin).
|
|
||||||
// There is a nicely portable workaround, too: Make this method overloadable.
|
|
||||||
if (remove(file.getPath().c_str()) != 0) {
|
|
||||||
#ifndef _WIN32_WCE
|
|
||||||
if (errno == EACCES)
|
|
||||||
setError(Common::kWritePermissionDenied, "Search or write permission denied: "+file.getName());
|
|
||||||
|
|
||||||
if (errno == ENOENT)
|
|
||||||
setError(Common::kPathDoesNotExist, "removeSavefile: '"+file.getName()+"' does not exist or path is invalid");
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
const Common::FSNode fileNode = file->_value;
|
||||||
|
// Remove from cache, this invalidates the 'file' iterator.
|
||||||
|
_saveFileCache.erase(file);
|
||||||
|
file = _saveFileCache.end();
|
||||||
|
|
||||||
|
// FIXME: remove does not exist on all systems. If your port fails to
|
||||||
|
// compile because of this, please let us know (scummvm-devel).
|
||||||
|
// There is a nicely portable workaround, too: Make this method overloadable.
|
||||||
|
if (remove(fileNode.getPath().c_str()) != 0) {
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
if (errno == EACCES)
|
||||||
|
setError(Common::kWritePermissionDenied, "Search or write permission denied: "+fileNode.getName());
|
||||||
|
|
||||||
|
if (errno == ENOENT)
|
||||||
|
setError(Common::kPathDoesNotExist, "removeSavefile: '"+fileNode.getName()+"' does not exist or path is invalid");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,4 +177,43 @@ Common::String DefaultSaveFileManager::getSavePath() const {
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultSaveFileManager::assureCached(const Common::String &savePathName) {
|
||||||
|
// Check that path exists and is usable.
|
||||||
|
checkPath(Common::FSNode(savePathName));
|
||||||
|
|
||||||
|
if (_cachedDirectory == savePathName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveFileCache.clear();
|
||||||
|
_cachedDirectory.clear();
|
||||||
|
|
||||||
|
if (getError().getCode() != Common::kNoError) {
|
||||||
|
warning("DefaultSaveFileManager::assureCached: Can not cache path '%s': '%s'", savePathName.c_str(), getErrorDesc().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FSNode can cache its members, thus create it after checkPath to reflect
|
||||||
|
// actual file system state.
|
||||||
|
const Common::FSNode savePath(savePathName);
|
||||||
|
|
||||||
|
Common::FSList children;
|
||||||
|
if (!savePath.getChildren(children, Common::FSNode::kListFilesOnly)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the savefile name cache.
|
||||||
|
for (Common::FSList::const_iterator file = children.begin(), end = children.end(); file != end; ++file) {
|
||||||
|
if (_saveFileCache.contains(file->getName())) {
|
||||||
|
warning("DefaultSaveFileManager::assureCached: Name clash when building cache, ignoring file '%s'", file->getName().c_str());
|
||||||
|
} else {
|
||||||
|
_saveFileCache[file->getName()] = *file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only now store that we cached 'savePathName' to indicate we successfully
|
||||||
|
// cached the directory.
|
||||||
|
_cachedDirectory = savePathName;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
|
#include "common/hashmap.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a default savefile manager implementation for common platforms.
|
* Provides a default savefile manager implementation for common platforms.
|
||||||
|
@ -54,6 +55,30 @@ protected:
|
||||||
* Sets the internal error and error message accordingly.
|
* Sets the internal error and error message accordingly.
|
||||||
*/
|
*/
|
||||||
virtual void checkPath(const Common::FSNode &dir);
|
virtual void checkPath(const Common::FSNode &dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assure that the given save path is cached.
|
||||||
|
*
|
||||||
|
* @param savePathName String representation of save path to cache.
|
||||||
|
*/
|
||||||
|
void assureCached(const Common::String &savePathName);
|
||||||
|
|
||||||
|
typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SaveFileCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache of all the save files in the currently cached directory.
|
||||||
|
*
|
||||||
|
* Modify with caution because we only re-cache when the save path changed!
|
||||||
|
* This needs to be updated inside at least openForSaving and
|
||||||
|
* removeSavefile.
|
||||||
|
*/
|
||||||
|
SaveFileCache _saveFileCache;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The currently cached directory.
|
||||||
|
*/
|
||||||
|
Common::String _cachedDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,16 +21,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Enable getenv, mkdir and time.h stuff
|
// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
|
||||||
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv
|
// Also with clock() in sys/time.h in some Mac OS X SDKs.
|
||||||
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
|
|
||||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h //On IRIX, sys/stat.h includes sys/time.h
|
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h //On IRIX, sys/stat.h includes sys/time.h
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
#if defined(POSIX) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
#if defined(POSIX) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
||||||
|
|
||||||
#include "backends/saves/posix/posix-saves.h"
|
#include "backends/saves/posix/posix-saves.h"
|
||||||
|
#include "backends/fs/posix/posix-fs.h"
|
||||||
|
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
|
@ -41,26 +44,70 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef MACOSX
|
|
||||||
#define DEFAULT_SAVE_PATH "Documents/ResidualVM Savegames"
|
|
||||||
#else
|
|
||||||
#define DEFAULT_SAVE_PATH ".residualvm"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
POSIXSaveFileManager::POSIXSaveFileManager() {
|
POSIXSaveFileManager::POSIXSaveFileManager() {
|
||||||
// Register default savepath based on HOME
|
// Register default savepath.
|
||||||
#if defined(SAMSUNGTV)
|
#if defined(SAMSUNGTV)
|
||||||
ConfMan.registerDefault("savepath", "/mtd_wiselink/residualvm savegames");
|
ConfMan.registerDefault("savepath", "/mtd_wiselink/residualvm savegames");
|
||||||
#else
|
#else
|
||||||
Common::String savePath;
|
Common::String savePath;
|
||||||
|
|
||||||
|
#if defined(MACOSX)
|
||||||
const char *home = getenv("HOME");
|
const char *home = getenv("HOME");
|
||||||
if (home && *home && strlen(home) < MAXPATHLEN) {
|
if (home && *home && strlen(home) < MAXPATHLEN) {
|
||||||
savePath = home;
|
savePath = home;
|
||||||
savePath += "/" DEFAULT_SAVE_PATH;
|
savePath += "/Documents/ResidualVM Savegames";
|
||||||
|
|
||||||
ConfMan.registerDefault("savepath", savePath);
|
ConfMan.registerDefault("savepath", savePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
const char *envVar;
|
||||||
|
|
||||||
|
// Previously we placed our default savepath in HOME. If the directory
|
||||||
|
// still exists, we will use it for backwards compatability.
|
||||||
|
envVar = getenv("HOME");
|
||||||
|
if (envVar && *envVar) {
|
||||||
|
savePath = envVar;
|
||||||
|
savePath += "/.residualvm";
|
||||||
|
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(savePath.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) {
|
||||||
|
savePath.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savePath.empty()) {
|
||||||
|
Common::String prefix;
|
||||||
|
|
||||||
|
// On POSIX systems we follow the XDG Base Directory Specification for
|
||||||
|
// where to store files. The version we based our code upon can be found
|
||||||
|
// over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
|
||||||
|
envVar = getenv("XDG_DATA_HOME");
|
||||||
|
if (!envVar || !*envVar) {
|
||||||
|
envVar = getenv("HOME");
|
||||||
|
if (envVar && *envVar) {
|
||||||
|
prefix = envVar;
|
||||||
|
savePath = ".local/share/";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prefix = envVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our default save path is '$XDG_DATA_HOME/residualvm/saves'
|
||||||
|
savePath += "residualvm/saves";
|
||||||
|
|
||||||
|
if (!Posix::assureDirectoryExists(savePath, prefix.c_str())) {
|
||||||
|
savePath.clear();
|
||||||
|
} else {
|
||||||
|
savePath = prefix + '/' + savePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!savePath.empty() && savePath.size() < MAXPATHLEN) {
|
||||||
|
ConfMan.registerDefault("savepath", savePath);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// The user can override the savepath with the SCUMMVM_SAVEPATH
|
// The user can override the savepath with the SCUMMVM_SAVEPATH
|
||||||
// environment variable. This is weaker than a --savepath on the
|
// environment variable. This is weaker than a --savepath on the
|
||||||
// command line, but overrides the default savepath.
|
// command line, but overrides the default savepath.
|
||||||
|
|
125
backends/taskbar/macosx/dockplugin/dockplugin.m
Normal file
125
backends/taskbar/macosx/dockplugin/dockplugin.m
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface ScummVMDockTilePlugIn : NSObject <NSDockTilePlugIn> {
|
||||||
|
NSMenu *recentGamesMenu;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface StartGameMenuItem : NSMenuItem {
|
||||||
|
NSString *game;
|
||||||
|
}
|
||||||
|
- (IBAction) startGame;
|
||||||
|
- (NSMenuItem*)initWithGame:(NSString *)gameId description:(NSString*)desc icon:(NSString*)iconFile;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ScummVMDockTilePlugIn
|
||||||
|
|
||||||
|
- (id)init {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
recentGamesMenu = nil;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[recentGamesMenu release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)setDockTile:(NSDockTile *)dockTile {
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMenu*)dockMenu {
|
||||||
|
// Get the list or recent games
|
||||||
|
CFPreferencesAppSynchronize(CFSTR("org.residualvm.residaulvm"));
|
||||||
|
NSArray *array = CFPreferencesCopyAppValue(CFSTR("recentGames"), CFSTR("org.residualvm.residualvm"));
|
||||||
|
if (array == nil)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
// Create the menu
|
||||||
|
if (recentGamesMenu == nil)
|
||||||
|
recentGamesMenu = [[NSMenu alloc] init];
|
||||||
|
else
|
||||||
|
[recentGamesMenu removeAllItems];
|
||||||
|
|
||||||
|
NSEnumerator *enumerator = [array objectEnumerator];
|
||||||
|
NSDictionary *recentGame;
|
||||||
|
while (recentGame = [enumerator nextObject]) {
|
||||||
|
NSString *gameId = [recentGame valueForKey:@"game"];
|
||||||
|
NSString *desc = [recentGame valueForKey:@"description"];
|
||||||
|
NSString *iconFile = [recentGame valueForKey:@"icon"];
|
||||||
|
|
||||||
|
StartGameMenuItem *menuItem = [[StartGameMenuItem alloc] initWithGame:gameId description:desc icon:iconFile];
|
||||||
|
[recentGamesMenu addItem:menuItem];
|
||||||
|
[menuItem release];
|
||||||
|
}
|
||||||
|
|
||||||
|
return recentGamesMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation StartGameMenuItem
|
||||||
|
|
||||||
|
- (NSMenuItem*)initWithGame:(NSString *)gameId description:(NSString*)desc icon:(NSString*)iconFile {
|
||||||
|
self = [super initWithTitle:(desc == nil ? gameId : desc) action:@selector(startGame) keyEquivalent:@""];
|
||||||
|
[self setTarget:self];
|
||||||
|
|
||||||
|
if (iconFile != nil) {
|
||||||
|
NSImage *image = [[NSImage alloc] initWithContentsOfFile:iconFile];
|
||||||
|
[self setImage:image];
|
||||||
|
[image release];
|
||||||
|
}
|
||||||
|
|
||||||
|
game = gameId;
|
||||||
|
[game retain];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[game release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction) startGame {
|
||||||
|
NSLog(@"Starting Game %@...", game);
|
||||||
|
|
||||||
|
NSString *scummVMPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"org.residualvm.residualvm"];
|
||||||
|
if (scummVMPath == nil) {
|
||||||
|
NSLog(@"Cannot find ResidualVM.app!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Start ScummVM.app with the game ID as argument
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:scummVMPath];
|
||||||
|
NSMutableDictionary *args = [[NSMutableDictionary alloc] init];
|
||||||
|
[args setObject:[NSArray arrayWithObject:game] forKey:NSWorkspaceLaunchConfigurationArguments];
|
||||||
|
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:url options:NSWorkspaceLaunchDefault configuration:args error:nil];
|
||||||
|
[args release];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -37,6 +37,7 @@ public:
|
||||||
virtual void setProgressValue(int completed, int total);
|
virtual void setProgressValue(int completed, int total);
|
||||||
virtual void setProgressState(TaskbarProgressState state);
|
virtual void setProgressState(TaskbarProgressState state);
|
||||||
virtual void setCount(int count);
|
virtual void setCount(int count);
|
||||||
|
virtual void addRecent(const Common::String &name, const Common::String &description);
|
||||||
virtual void notifyError();
|
virtual void notifyError();
|
||||||
virtual void clearError();
|
virtual void clearError();
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
// NSDockTile was introduced with Mac OS X 10.5.
|
// NSDockTile was introduced with Mac OS X 10.5.
|
||||||
// Try provide backward compatibility by avoiding NSDockTile symbols.
|
// Try provide backward compatibility by avoiding NSDockTile symbols.
|
||||||
|
|
||||||
// TODO: Implement recent list, maybe as a custom menu on dock tile when app is not running
|
|
||||||
// See Dock Tile plug-in at https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/CreatingaDockTilePlug-in/CreatingaDockTilePlug-in.html
|
|
||||||
|
|
||||||
#include "backends/taskbar/macosx/macosx-taskbar.h"
|
#include "backends/taskbar/macosx/macosx-taskbar.h"
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
|
@ -39,6 +36,9 @@
|
||||||
#include <AppKit/NSApplication.h>
|
#include <AppKit/NSApplication.h>
|
||||||
#include <AppKit/NSImage.h>
|
#include <AppKit/NSImage.h>
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
|
#include <Foundation/NSDictionary.h>
|
||||||
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSUserDefaults.h>
|
||||||
#include <AppKit/NSImageView.h>
|
#include <AppKit/NSImageView.h>
|
||||||
#include <AppKit/NSColor.h>
|
#include <AppKit/NSColor.h>
|
||||||
#include <AppKit/NSBezierPath.h>
|
#include <AppKit/NSBezierPath.h>
|
||||||
|
@ -120,7 +120,7 @@ void MacOSXTaskbarManager::setOverlayIcon(const Common::String &name, const Comm
|
||||||
initOverlayIconView();
|
initOverlayIconView();
|
||||||
|
|
||||||
CFStringRef imageFile = CFStringCreateWithCString(0, path.c_str(), kCFStringEncodingASCII);
|
CFStringRef imageFile = CFStringCreateWithCString(0, path.c_str(), kCFStringEncodingASCII);
|
||||||
NSImage* image = [[NSImage alloc] initWithContentsOfFile:(NSString *)imageFile];
|
NSImage *image = [[NSImage alloc] initWithContentsOfFile:(NSString *)imageFile];
|
||||||
[_overlayIconView setImage:image];
|
[_overlayIconView setImage:image];
|
||||||
[image release];
|
[image release];
|
||||||
CFRelease(imageFile);
|
CFRelease(imageFile);
|
||||||
|
@ -234,5 +234,64 @@ return (path); \
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacOSXTaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
|
||||||
|
//warning("[MacOSXTaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str());
|
||||||
|
|
||||||
|
if (_dockTile == nil)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Store the game, description and icon in user preferences.
|
||||||
|
// The NSDockTilePlugin will retrieve them there to list them in the dock tile menu.
|
||||||
|
|
||||||
|
CFStringRef gameName = CFStringCreateWithCString(0, name.c_str(), kCFStringEncodingASCII);
|
||||||
|
CFStringRef desc = CFStringCreateWithCString(0, description.c_str(), kCFStringEncodingASCII);
|
||||||
|
|
||||||
|
// First build the dictionary for this game.
|
||||||
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||||
|
[dict setObject:(NSString *)gameName forKey:@"game"];
|
||||||
|
[dict setObject:(NSString *)desc forKey:@"description"];
|
||||||
|
|
||||||
|
// Icon
|
||||||
|
Common::String iconPath = getIconPath(name);
|
||||||
|
if (!iconPath.empty()) {
|
||||||
|
CFStringRef icon = CFStringCreateWithCString(0, iconPath.c_str(), kCFStringEncodingASCII);
|
||||||
|
[dict setObject:(NSString *)icon forKey:@"icon"];
|
||||||
|
CFRelease(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current list of recent items and update it.
|
||||||
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
|
NSArray *oldArray = [defaults arrayForKey:@"recentGames"];
|
||||||
|
if (oldArray == nil) {
|
||||||
|
[defaults setObject:[NSArray arrayWithObject:dict] forKey:@"recentGames"];
|
||||||
|
} else {
|
||||||
|
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray];
|
||||||
|
// Insert the new game at the start
|
||||||
|
[newArray insertObject:dict atIndex:0];
|
||||||
|
// If the game was already present in the array, remove it
|
||||||
|
for (unsigned int i = 1 ; i < [newArray count] ; ++i) {
|
||||||
|
NSDictionary *oldDict = [newArray objectAtIndex:i];
|
||||||
|
if (oldDict == nil)
|
||||||
|
continue;
|
||||||
|
NSString *oldGame = [oldDict valueForKey:@"game"];
|
||||||
|
if (oldGame != nil && [oldGame isEqualToString:(NSString*)gameName]) {
|
||||||
|
[newArray removeObjectAtIndex:i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// And make sure we limit the size of the array to 5 games
|
||||||
|
if ([newArray count] > 5)
|
||||||
|
[newArray removeLastObject];
|
||||||
|
[defaults setObject:newArray forKey:@"recentGames"];
|
||||||
|
[newArray release];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally release the dictionary
|
||||||
|
[dict release];
|
||||||
|
CFRelease(gameName);
|
||||||
|
CFRelease(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,8 +28,22 @@
|
||||||
|
|
||||||
#if defined(WIN32) && defined(USE_TASKBAR)
|
#if defined(WIN32) && defined(USE_TASKBAR)
|
||||||
|
|
||||||
|
// HACK: To get __MINGW64_VERSION_foo defines we need to manually include
|
||||||
|
// _mingw.h in this file because we do not include any system headers at this
|
||||||
|
// point on purpose. The defines are required to detect whether this is a
|
||||||
|
// classic MinGW toolchain or a MinGW-w64 based one.
|
||||||
|
#if defined(__MINGW32__)
|
||||||
|
#include <_mingw.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Needed for taskbar functions
|
// Needed for taskbar functions
|
||||||
#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64__)
|
// HACK: MinGW-w64 based toolchains include the symbols we require in their
|
||||||
|
// headers. The 32 bit incarnation only defines __MINGW32__. This leads to
|
||||||
|
// build breakage due to clashes with our compat header. Luckily MinGW-w64
|
||||||
|
// based toolchains define __MINGW64_VERSION_foo macros inside _mingw.h,
|
||||||
|
// which is included from all system headers. Thus we abuse that to detect
|
||||||
|
// them.
|
||||||
|
#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||||
#include "backends/taskbar/win32/mingw-compat.h"
|
#include "backends/taskbar/win32/mingw-compat.h"
|
||||||
#else
|
#else
|
||||||
// We use functionality introduced with Win7 in this file.
|
// We use functionality introduced with Win7 in this file.
|
||||||
|
@ -71,7 +85,7 @@ const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0
|
||||||
|
|
||||||
Win32TaskbarManager::Win32TaskbarManager(SdlWindow *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
|
Win32TaskbarManager::Win32TaskbarManager(SdlWindow *window) : _window(window), _taskbar(NULL), _count(0), _icon(NULL) {
|
||||||
// Do nothing if not running on Windows 7 or later
|
// Do nothing if not running on Windows 7 or later
|
||||||
if (!isWin7OrLater())
|
if (!confirmWindowsVersion(10, 0) && !confirmWindowsVersion(6, 1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
|
@ -386,14 +400,14 @@ BOOL VerifyVersionInfoFunc(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwType
|
||||||
return verifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
|
return verifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Win32TaskbarManager::isWin7OrLater() {
|
bool Win32TaskbarManager::confirmWindowsVersion(uint majorVersion, uint minorVersion) {
|
||||||
OSVERSIONINFOEX versionInfo;
|
OSVERSIONINFOEX versionInfo;
|
||||||
DWORDLONG conditionMask = 0;
|
DWORDLONG conditionMask = 0;
|
||||||
|
|
||||||
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
|
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||||
versionInfo.dwMajorVersion = 6;
|
versionInfo.dwMajorVersion = majorVersion;
|
||||||
versionInfo.dwMinorVersion = 1;
|
versionInfo.dwMinorVersion = minorVersion;
|
||||||
|
|
||||||
conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
conditionMask = VerSetConditionMaskFunc(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
|
|
@ -64,7 +64,7 @@ private:
|
||||||
Common::String getIconPath(Common::String target);
|
Common::String getIconPath(Common::String target);
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
bool isWin7OrLater();
|
bool confirmWindowsVersion(uint majorVersion, uint minorVersion);
|
||||||
LPWSTR ansiToUnicode(const char *s);
|
LPWSTR ansiToUnicode(const char *s);
|
||||||
HWND getHwnd();
|
HWND getHwnd();
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,8 +39,10 @@ public:
|
||||||
virtual void setAutomaticallyChecksForUpdates(UpdateState state);
|
virtual void setAutomaticallyChecksForUpdates(UpdateState state);
|
||||||
virtual UpdateState getAutomaticallyChecksForUpdates();
|
virtual UpdateState getAutomaticallyChecksForUpdates();
|
||||||
|
|
||||||
virtual void setUpdateCheckInterval(UpdateInterval interval);
|
virtual void setUpdateCheckInterval(int interval);
|
||||||
virtual UpdateInterval getUpdateCheckInterval();
|
virtual int getUpdateCheckInterval();
|
||||||
|
|
||||||
|
virtual bool getLastUpdateCheckTimeAndDate(TimeDate &t);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,14 +23,18 @@
|
||||||
// Disable symbol overrides so that we can use system headers.
|
// Disable symbol overrides so that we can use system headers.
|
||||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
#include "backends/updates/macosx/macosx-updates.h"
|
#include "backends/updates/macosx/macosx-updates.h"
|
||||||
|
|
||||||
#ifdef USE_SPARKLE
|
#ifdef USE_SPARKLE
|
||||||
#include "common/translation.h"
|
#include "common/translation.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#include <Sparkle/Sparkle.h>
|
#include <Sparkle/Sparkle.h>
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
SUUpdater *sparkleUpdater;
|
SUUpdater *sparkleUpdater;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,14 +49,22 @@ SUUpdater *sparkleUpdater;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
MacOSXUpdateManager::MacOSXUpdateManager() {
|
MacOSXUpdateManager::MacOSXUpdateManager() {
|
||||||
|
NSBundle* mainBundle = [NSBundle mainBundle];
|
||||||
|
|
||||||
|
NSString *version = [mainBundle objectForInfoDictionaryKey:(__bridge NSString *)kCFBundleVersionKey];
|
||||||
|
if (!version || [version isEqualToString:@""]) {
|
||||||
|
warning("Running not in bundle, skipping Sparkle initialization");
|
||||||
|
|
||||||
|
sparkleUpdater = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSMenuItem *menuItem = [[NSApp mainMenu] itemAtIndex:0];
|
NSMenuItem *menuItem = [[NSApp mainMenu] itemAtIndex:0];
|
||||||
NSMenu *applicationMenu = [menuItem submenu];
|
NSMenu *applicationMenu = [menuItem submenu];
|
||||||
|
|
||||||
// Init Sparkle
|
// Init Sparkle
|
||||||
sparkleUpdater = [SUUpdater sharedUpdater];
|
sparkleUpdater = [SUUpdater sharedUpdater];
|
||||||
|
|
||||||
NSBundle* mainBundle = [NSBundle mainBundle];
|
|
||||||
|
|
||||||
NSString* feedbackURL = [mainBundle objectForInfoDictionaryKey:@"SUFeedURL"];
|
NSString* feedbackURL = [mainBundle objectForInfoDictionaryKey:@"SUFeedURL"];
|
||||||
|
|
||||||
// Set appcast URL
|
// Set appcast URL
|
||||||
|
@ -74,11 +86,13 @@ MacOSXUpdateManager::MacOSXUpdateManager() {
|
||||||
// Finally give up our references to the objects
|
// Finally give up our references to the objects
|
||||||
[menuItem release];
|
[menuItem release];
|
||||||
|
|
||||||
// Enable automatic update checking once a day (alternatively use
|
if (!ConfMan.hasKey("updates_check")
|
||||||
// checkForUpdates() here to check for updates on every startup)
|
|| ConfMan.getInt("updates_check") == Common::UpdateManager::kUpdateIntervalNotSupported) {
|
||||||
// TODO: Should be removed when an update settings gui is implemented
|
setAutomaticallyChecksForUpdates(kUpdateStateDisabled);
|
||||||
setAutomaticallyChecksForUpdates(kUpdateStateEnabled);
|
} else {
|
||||||
setUpdateCheckInterval(kUpdateIntervalOneDay);
|
setAutomaticallyChecksForUpdates(kUpdateStateEnabled);
|
||||||
|
setUpdateCheckInterval(normalizeInterval(ConfMan.getInt("updates_check")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MacOSXUpdateManager::~MacOSXUpdateManager() {
|
MacOSXUpdateManager::~MacOSXUpdateManager() {
|
||||||
|
@ -86,6 +100,9 @@ MacOSXUpdateManager::~MacOSXUpdateManager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacOSXUpdateManager::checkForUpdates() {
|
void MacOSXUpdateManager::checkForUpdates() {
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
[sparkleUpdater checkForUpdatesInBackground];
|
[sparkleUpdater checkForUpdatesInBackground];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,24 +110,38 @@ void MacOSXUpdateManager::setAutomaticallyChecksForUpdates(UpdateManager::Update
|
||||||
if (state == kUpdateStateNotSupported)
|
if (state == kUpdateStateNotSupported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
[sparkleUpdater setAutomaticallyChecksForUpdates:(state == kUpdateStateEnabled ? YES : NO)];
|
[sparkleUpdater setAutomaticallyChecksForUpdates:(state == kUpdateStateEnabled ? YES : NO)];
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::UpdateManager::UpdateState MacOSXUpdateManager::getAutomaticallyChecksForUpdates() {
|
Common::UpdateManager::UpdateState MacOSXUpdateManager::getAutomaticallyChecksForUpdates() {
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return kUpdateStateDisabled;
|
||||||
|
|
||||||
if ([sparkleUpdater automaticallyChecksForUpdates])
|
if ([sparkleUpdater automaticallyChecksForUpdates])
|
||||||
return kUpdateStateEnabled;
|
return kUpdateStateEnabled;
|
||||||
else
|
else
|
||||||
return kUpdateStateDisabled;
|
return kUpdateStateDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacOSXUpdateManager::setUpdateCheckInterval(UpdateInterval interval) {
|
void MacOSXUpdateManager::setUpdateCheckInterval(int interval) {
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
if (interval == kUpdateIntervalNotSupported)
|
if (interval == kUpdateIntervalNotSupported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
interval = normalizeInterval(interval);
|
||||||
|
|
||||||
[sparkleUpdater setUpdateCheckInterval:(NSTimeInterval)interval];
|
[sparkleUpdater setUpdateCheckInterval:(NSTimeInterval)interval];
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::UpdateManager::UpdateInterval MacOSXUpdateManager::getUpdateCheckInterval() {
|
int MacOSXUpdateManager::getUpdateCheckInterval() {
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return kUpdateIntervalOneDay;
|
||||||
|
|
||||||
// This is kind of a hack but necessary, as the value stored by Sparkle
|
// This is kind of a hack but necessary, as the value stored by Sparkle
|
||||||
// might have been changed outside of ScummVM (in which case we return the
|
// might have been changed outside of ScummVM (in which case we return the
|
||||||
// default interval of one day)
|
// default interval of one day)
|
||||||
|
@ -128,4 +159,30 @@ Common::UpdateManager::UpdateInterval MacOSXUpdateManager::getUpdateCheckInterva
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MacOSXUpdateManager::getLastUpdateCheckTimeAndDate(TimeDate &t) {
|
||||||
|
if (sparkleUpdater == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
NSDate *date = [sparkleUpdater lastUpdateCheckDate];
|
||||||
|
#ifdef MAC_OS_X_VERSION_10_10
|
||||||
|
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||||
|
NSDateComponents *components = [gregorian components:(NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:date];
|
||||||
|
#else
|
||||||
|
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
|
||||||
|
NSDateComponents *components = [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
t.tm_wday = [components weekday];
|
||||||
|
t.tm_year = [components year];
|
||||||
|
t.tm_mon = [components month];
|
||||||
|
t.tm_mday = [components day];
|
||||||
|
t.tm_hour = [components hour];
|
||||||
|
t.tm_min = [components minute];
|
||||||
|
t.tm_sec = [components second];
|
||||||
|
|
||||||
|
[gregorian release];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
132
backends/updates/win32/win32-updates.cpp
Normal file
132
backends/updates/win32/win32-updates.cpp
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Disable symbol overrides so that we can use system headers.
|
||||||
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "backends/updates/win32/win32-updates.h"
|
||||||
|
|
||||||
|
#ifdef USE_SPARKLE
|
||||||
|
#include "common/translation.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <winsparkle.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sparkle is a software update framework for Mac OS X which uses appcasts for
|
||||||
|
* release information. Appcasts are RSS-like XML feeds which contain information
|
||||||
|
* about the most current version at the time. If a new version is available, the
|
||||||
|
* user is presented the release-notes/changes/fixes and is asked if he wants to
|
||||||
|
* update, and if yes the Sparkle framework downloads a signed update package
|
||||||
|
* from the server and automatically installs and restarts the software.
|
||||||
|
* More detailed information is available at the following address:
|
||||||
|
* http://sparkle.andymatuschak.org/
|
||||||
|
*
|
||||||
|
* WinSparkle is a heavily (to the point of being its almost-port) inspired by the
|
||||||
|
* Sparkle framework originally by Andy Matuschak that became the de facto standard
|
||||||
|
* for software updates on OS X.
|
||||||
|
* More detailed information is available at the following address:
|
||||||
|
* https://winsparkle.org/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Win32UpdateManager::Win32UpdateManager() {
|
||||||
|
const char *appcastUrl = "https://www.residualvm.org/appcasts/macosx/release.xml";
|
||||||
|
|
||||||
|
win_sparkle_set_appcast_url(appcastUrl);
|
||||||
|
win_sparkle_init();
|
||||||
|
|
||||||
|
if (!ConfMan.hasKey("updates_check")
|
||||||
|
|| ConfMan.getInt("updates_check") == Common::UpdateManager::kUpdateIntervalNotSupported) {
|
||||||
|
setAutomaticallyChecksForUpdates(kUpdateStateDisabled);
|
||||||
|
} else {
|
||||||
|
setAutomaticallyChecksForUpdates(kUpdateStateEnabled);
|
||||||
|
setUpdateCheckInterval(normalizeInterval(ConfMan.getInt("updates_check")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32UpdateManager::~Win32UpdateManager() {
|
||||||
|
win_sparkle_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UpdateManager::checkForUpdates() {
|
||||||
|
win_sparkle_check_update_with_ui();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UpdateManager::setAutomaticallyChecksForUpdates(UpdateManager::UpdateState state) {
|
||||||
|
if (state == kUpdateStateNotSupported)
|
||||||
|
return;
|
||||||
|
|
||||||
|
win_sparkle_set_automatic_check_for_updates(state == kUpdateStateEnabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::UpdateManager::UpdateState Win32UpdateManager::getAutomaticallyChecksForUpdates() {
|
||||||
|
if (win_sparkle_get_automatic_check_for_updates() == 1)
|
||||||
|
return kUpdateStateEnabled;
|
||||||
|
else
|
||||||
|
return kUpdateStateDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UpdateManager::setUpdateCheckInterval(int interval) {
|
||||||
|
if (interval == kUpdateIntervalNotSupported)
|
||||||
|
return;
|
||||||
|
|
||||||
|
interval = normalizeInterval(interval);
|
||||||
|
|
||||||
|
win_sparkle_set_update_check_interval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Win32UpdateManager::getUpdateCheckInterval() {
|
||||||
|
// This is kind of a hack but necessary, as the value stored by Sparkle
|
||||||
|
// might have been changed outside of ScummVM (in which case we return the
|
||||||
|
// default interval of one day)
|
||||||
|
|
||||||
|
int updateInterval = win_sparkle_get_update_check_interval();
|
||||||
|
switch (updateInterval) {
|
||||||
|
case kUpdateIntervalOneDay:
|
||||||
|
case kUpdateIntervalOneWeek:
|
||||||
|
case kUpdateIntervalOneMonth:
|
||||||
|
return updateInterval;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Return the default value (one day)
|
||||||
|
return kUpdateIntervalOneDay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32UpdateManager::getLastUpdateCheckTimeAndDate(TimeDate &t) {
|
||||||
|
time_t updateTime = win_sparkle_get_last_check_time();
|
||||||
|
tm *ut = localtime(&updateTime);
|
||||||
|
|
||||||
|
t.tm_wday = ut->tm_wday;
|
||||||
|
t.tm_year = ut->tm_year;
|
||||||
|
t.tm_mon = ut->tm_mon;
|
||||||
|
t.tm_mday = ut->tm_mday;
|
||||||
|
t.tm_hour = ut->tm_hour;
|
||||||
|
t.tm_min = ut->tm_min;
|
||||||
|
t.tm_sec = ut->tm_sec;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
50
backends/updates/win32/win32-updates.h
Normal file
50
backends/updates/win32/win32-updates.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BACKENDS_UPDATES_WIN32_H
|
||||||
|
#define BACKENDS_UPDATES_WIN32_H
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(USE_SPARKLE)
|
||||||
|
|
||||||
|
#include "common/updates.h"
|
||||||
|
|
||||||
|
class Win32UpdateManager : public Common::UpdateManager {
|
||||||
|
public:
|
||||||
|
Win32UpdateManager();
|
||||||
|
virtual ~Win32UpdateManager();
|
||||||
|
|
||||||
|
virtual void checkForUpdates();
|
||||||
|
|
||||||
|
virtual void setAutomaticallyChecksForUpdates(UpdateState state);
|
||||||
|
virtual UpdateState getAutomaticallyChecksForUpdates();
|
||||||
|
|
||||||
|
virtual void setUpdateCheckInterval(int interval);
|
||||||
|
virtual int getUpdateCheckInterval();
|
||||||
|
|
||||||
|
virtual bool getLastUpdateCheckTimeAndDate(TimeDate &t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BACKENDS_UPDATES_WIN32_H
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
#include "audio/musicplugin.h"
|
#include "audio/musicplugin.h"
|
||||||
|
|
||||||
#include "graphics/renderer.h"
|
#include "graphics/renderer.h" // ResidualVM
|
||||||
|
|
||||||
#define DETECTOR_TESTING_HACK
|
#define DETECTOR_TESTING_HACK
|
||||||
#define UPGRADE_ALL_TARGETS_HACK
|
#define UPGRADE_ALL_TARGETS_HACK
|
||||||
|
@ -59,7 +59,7 @@ static const char USAGE_STRING[] =
|
||||||
;
|
;
|
||||||
|
|
||||||
// DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :)
|
// DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :)
|
||||||
#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) || defined(__DS__)
|
#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) || defined(__DS__) || defined(__3DS__)
|
||||||
static const char HELP_STRING[] = "NoUsageString"; // save more data segment space
|
static const char HELP_STRING[] = "NoUsageString"; // save more data segment space
|
||||||
#else
|
#else
|
||||||
static const char HELP_STRING[] =
|
static const char HELP_STRING[] =
|
||||||
|
@ -99,8 +99,9 @@ static const char HELP_STRING[] =
|
||||||
" -u, --dump-scripts Enable script dumping if a directory called 'dumps'\n"
|
" -u, --dump-scripts Enable script dumping if a directory called 'dumps'\n"
|
||||||
" exists in the current directory\n"
|
" exists in the current directory\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --cdrom=NUM CD drive to play CD audio from (default: 0 = first\n"
|
" --cdrom=DRIVE CD drive to play CD audio from; can either be a\n"
|
||||||
" drive)\n"
|
" drive, path, or numeric index (default: 0 = best\n"
|
||||||
|
" choice drive)\n"
|
||||||
" --joystick[=NUM] Enable joystick input (default: 0 = first joystick)\n"
|
" --joystick[=NUM] Enable joystick input (default: 0 = first joystick)\n"
|
||||||
" --platform=WORD Specify platform of game (allowed values: 2gs, 3do,\n"
|
" --platform=WORD Specify platform of game (allowed values: 2gs, 3do,\n"
|
||||||
" acorn, amiga, atari, c64, fmtowns, nes, mac, pc, pc98,\n"
|
" acorn, amiga, atari, c64, fmtowns, nes, mac, pc, pc98,\n"
|
||||||
|
@ -339,6 +340,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||||
// We defer checking whether this is a valid target to a later point.
|
// We defer checking whether this is a valid target to a later point.
|
||||||
return s;
|
return s;
|
||||||
} else {
|
} else {
|
||||||
|
// On MacOS X prior to 10.9 the OS is sometimes adding a -psn_X_XXXXXX argument (where X are digits)
|
||||||
|
// to pass the process serial number. We need to ignore it to avoid an error.
|
||||||
|
#ifdef MACOSX
|
||||||
|
if (strncmp(s, "-psn_", 5) == 0)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool isLongCmd = (s[0] == '-' && s[1] == '-');
|
bool isLongCmd = (s[0] == '-' && s[1] == '-');
|
||||||
|
|
||||||
|
@ -489,7 +496,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||||
|
|
||||||
DO_LONG_OPTION("gamma")
|
DO_LONG_OPTION("gamma")
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
// ResidualVM specific start
|
||||||
DO_LONG_OPTION("renderer")
|
DO_LONG_OPTION("renderer")
|
||||||
Graphics::RendererType renderer = Graphics::parseRendererTypeCode(option);
|
Graphics::RendererType renderer = Graphics::parseRendererTypeCode(option);
|
||||||
if (renderer == Graphics::kRendererTypeDefault)
|
if (renderer == Graphics::kRendererTypeDefault)
|
||||||
|
@ -497,6 +504,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION_BOOL("show-fps")
|
DO_LONG_OPTION_BOOL("show-fps")
|
||||||
|
// ResidualVM specific end
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION("savepath")
|
DO_LONG_OPTION("savepath")
|
||||||
|
|
|
@ -75,6 +75,9 @@
|
||||||
#include "gui/launcher.h"
|
#include "gui/launcher.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UPDATES
|
||||||
|
#include "gui/updates-dialog.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool launcherDialog() {
|
static bool launcherDialog() {
|
||||||
|
|
||||||
|
@ -134,9 +137,26 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
|
||||||
Common::Error err = Common::kNoError;
|
Common::Error err = Common::kNoError;
|
||||||
Engine *engine = 0;
|
Engine *engine = 0;
|
||||||
|
|
||||||
|
// Disabled in ResidualVM:
|
||||||
|
#if 0//defined(SDL_BACKEND) && defined(USE_OPENGL) && defined(USE_RGB_COLOR)
|
||||||
|
// HACK: We set up the requested graphics mode setting here to allow the
|
||||||
|
// backend to switch from Surface SDL to OpenGL if necessary. This is
|
||||||
|
// needed because otherwise the g_system->getSupportedFormats might return
|
||||||
|
// bad values.
|
||||||
|
g_system->beginGFXTransaction();
|
||||||
|
g_system->setGraphicsMode(ConfMan.get("gfx_mode").c_str());
|
||||||
|
if (g_system->endGFXTransaction() != OSystem::kTransactionSuccess) {
|
||||||
|
warning("Switching graphics mode to '%s' failed", ConfMan.get("gfx_mode").c_str());
|
||||||
|
return Common::kUnknownError;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Verify that the game path refers to an actual directory
|
// Verify that the game path refers to an actual directory
|
||||||
if (!(dir.exists() && dir.isDirectory()))
|
if (!dir.exists()) {
|
||||||
|
err = Common::kPathDoesNotExist;
|
||||||
|
} else if (!dir.isDirectory()) {
|
||||||
err = Common::kPathNotDirectory;
|
err = Common::kPathNotDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the game engine
|
// Create the game engine
|
||||||
if (err.getCode() == Common::kNoError) {
|
if (err.getCode() == Common::kNoError) {
|
||||||
|
@ -370,7 +390,8 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
|
||||||
if (settings.contains("debugflags")) {
|
if (settings.contains("debugflags")) {
|
||||||
specialDebug = settings["debugflags"];
|
specialDebug = settings["debugflags"];
|
||||||
settings.erase("debugflags");
|
settings.erase("debugflags");
|
||||||
}
|
} else if (ConfMan.hasKey("debugflags"))
|
||||||
|
specialDebug = ConfMan.get("debugflags");
|
||||||
|
|
||||||
PluginManager::instance().init();
|
PluginManager::instance().init();
|
||||||
PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager
|
PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager
|
||||||
|
@ -446,6 +467,13 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
|
||||||
// Now as the event manager is created, setup the keymapper
|
// Now as the event manager is created, setup the keymapper
|
||||||
setupKeymapper(system);
|
setupKeymapper(system);
|
||||||
|
|
||||||
|
#ifdef USE_UPDATES
|
||||||
|
if (!ConfMan.hasKey("updates_check")) {
|
||||||
|
GUI::UpdatesDialog dlg;
|
||||||
|
dlg.runModal();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Unless a game was specified, show the launcher dialog
|
// Unless a game was specified, show the launcher dialog
|
||||||
if (0 == ConfMan.getActiveDomain())
|
if (0 == ConfMan.getActiveDomain())
|
||||||
launcherDialog();
|
launcherDialog();
|
||||||
|
|
|
@ -141,9 +141,6 @@ public:
|
||||||
#if defined(USE_TIMIDITY)
|
#if defined(USE_TIMIDITY)
|
||||||
LINK_PLUGIN(TIMIDITY)
|
LINK_PLUGIN(TIMIDITY)
|
||||||
#endif
|
#endif
|
||||||
#if PLUGIN_ENABLED_STATIC(STARK)
|
|
||||||
LINK_PLUGIN(STARK)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pl;
|
return pl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
* header file, analog to internal_version.h, maybe called svn_rev.h or so.)
|
* header file, analog to internal_version.h, maybe called svn_rev.h or so.)
|
||||||
*
|
*
|
||||||
* Drawback: This only works on systems which can run suitable scripts as part
|
* Drawback: This only works on systems which can run suitable scripts as part
|
||||||
* of the build proces (so I guess Visual C++ would be out of the game here?
|
* of the build process (so I guess Visual C++ would be out of the game here?
|
||||||
* I don't know VC enough to be sure). And of course it must be robust enough
|
* I don't know VC enough to be sure). And of course it must be robust enough
|
||||||
* to properly work in exports (i.e. release tar balls etc.).
|
* to properly work in exports (i.e. release tar balls etc.).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -270,5 +270,26 @@ T gcd(T a, T b) {
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replacement algorithm for iterables.
|
||||||
|
*
|
||||||
|
* Replaces all occurrences of "original" in [begin, end) with occurrences of "replaced".
|
||||||
|
*
|
||||||
|
* @param[in, out] begin: First element to be examined.
|
||||||
|
* @param[in] end: Last element in the seubsection. Not examined.
|
||||||
|
* @param[in] original: Elements to be replaced.
|
||||||
|
* @param[in] replaced: Element to replace occurrences of "original".
|
||||||
|
*
|
||||||
|
* @note Usage examples and unit tests may be found in "test/common/algorithm.h"
|
||||||
|
*/
|
||||||
|
template<class It, class Dat>
|
||||||
|
void replace(It begin, It end, const Dat &original, const Dat &replaced) {
|
||||||
|
for (; begin != end; ++begin) {
|
||||||
|
if (*begin == original) {
|
||||||
|
*begin = replaced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,7 +48,7 @@ int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern)
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
|
|
||||||
ArchiveMemberList::const_iterator it = allNames.begin();
|
ArchiveMemberList::const_iterator it = allNames.begin();
|
||||||
for ( ; it != allNames.end(); ++it) {
|
for (; it != allNames.end(); ++it) {
|
||||||
// TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though...
|
// TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though...
|
||||||
// For our use case case-insensitive is probably what we want to have though.
|
// For our use case case-insensitive is probably what we want to have though.
|
||||||
if ((*it)->getName().matchString(pattern, true, true)) {
|
if ((*it)->getName().matchString(pattern, true, true)) {
|
||||||
|
@ -64,7 +64,7 @@ int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern)
|
||||||
|
|
||||||
SearchSet::ArchiveNodeList::iterator SearchSet::find(const String &name) {
|
SearchSet::ArchiveNodeList::iterator SearchSet::find(const String &name) {
|
||||||
ArchiveNodeList::iterator it = _list.begin();
|
ArchiveNodeList::iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
if (it->_name == name)
|
if (it->_name == name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ SearchSet::ArchiveNodeList::iterator SearchSet::find(const String &name) {
|
||||||
|
|
||||||
SearchSet::ArchiveNodeList::const_iterator SearchSet::find(const String &name) const {
|
SearchSet::ArchiveNodeList::const_iterator SearchSet::find(const String &name) const {
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
if (it->_name == name)
|
if (it->_name == name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -81,13 +81,13 @@ SearchSet::ArchiveNodeList::const_iterator SearchSet::find(const String &name) c
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Keep the nodes sorted according to descending priorities.
|
Keep the nodes sorted according to descending priorities.
|
||||||
In case two or node nodes have the same priority, insertion
|
In case two or node nodes have the same priority, insertion
|
||||||
order prevails.
|
order prevails.
|
||||||
*/
|
*/
|
||||||
void SearchSet::insert(const Node &node) {
|
void SearchSet::insert(const Node &node) {
|
||||||
ArchiveNodeList::iterator it = _list.begin();
|
ArchiveNodeList::iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
if (it->_priority < node._priority)
|
if (it->_priority < node._priority)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -131,8 +131,7 @@ void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPa
|
||||||
++sep;
|
++sep;
|
||||||
if (sep != origPattern.end())
|
if (sep != origPattern.end())
|
||||||
nextPattern = String(sep, origPattern.end());
|
nextPattern = String(sep, origPattern.end());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pattern = origPattern;
|
pattern = origPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +210,7 @@ bool SearchSet::hasFile(const String &name) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
if (it->_arc->hasFile(name))
|
if (it->_arc->hasFile(name))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -223,7 +222,7 @@ int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &patter
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
|
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it)
|
for (; it != _list.end(); ++it)
|
||||||
matches += it->_arc->listMatchingMembers(list, pattern);
|
matches += it->_arc->listMatchingMembers(list, pattern);
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
|
@ -233,7 +232,7 @@ int SearchSet::listMembers(ArchiveMemberList &list) const {
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
|
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it)
|
for (; it != _list.end(); ++it)
|
||||||
matches += it->_arc->listMembers(list);
|
matches += it->_arc->listMembers(list);
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
|
@ -244,7 +243,7 @@ const ArchiveMemberPtr SearchSet::getMember(const String &name) const {
|
||||||
return ArchiveMemberPtr();
|
return ArchiveMemberPtr();
|
||||||
|
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
if (it->_arc->hasFile(name))
|
if (it->_arc->hasFile(name))
|
||||||
return it->_arc->getMember(name);
|
return it->_arc->getMember(name);
|
||||||
}
|
}
|
||||||
|
@ -257,7 +256,7 @@ SeekableReadStream *SearchSet::createReadStreamForMember(const String &name) con
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ArchiveNodeList::const_iterator it = _list.begin();
|
ArchiveNodeList::const_iterator it = _list.begin();
|
||||||
for ( ; it != _list.end(); ++it) {
|
for (; it != _list.end(); ++it) {
|
||||||
SeekableReadStream *stream = it->_arc->createReadStreamForMember(name);
|
SeekableReadStream *stream = it->_arc->createReadStreamForMember(name);
|
||||||
if (stream)
|
if (stream)
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -268,7 +267,7 @@ SeekableReadStream *SearchSet::createReadStreamForMember(const String &name) con
|
||||||
|
|
||||||
|
|
||||||
SearchManager::SearchManager() {
|
SearchManager::SearchManager() {
|
||||||
clear(); // Force a reset
|
clear(); // Force a reset
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchManager::clear() {
|
void SearchManager::clear() {
|
||||||
|
|
|
@ -141,6 +141,12 @@ public:
|
||||||
insert_aux(_storage + idx, array.begin(), array.end());
|
insert_aux(_storage + idx, array.begin(), array.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts element before pos.
|
||||||
|
*/
|
||||||
|
void insert(iterator pos, const T &element) {
|
||||||
|
insert_aux(pos, &element, &element + 1);
|
||||||
|
}
|
||||||
|
|
||||||
T remove_at(size_type idx) {
|
T remove_at(size_type idx) {
|
||||||
assert(idx < _size);
|
assert(idx < _size);
|
||||||
|
@ -187,6 +193,14 @@ public:
|
||||||
_capacity = 0;
|
_capacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterator erase(iterator pos) {
|
||||||
|
copy(pos + 1, _storage + _size, pos);
|
||||||
|
_size--;
|
||||||
|
// We also need to destroy the last object properly here.
|
||||||
|
_storage[_size].~T();
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return (_size == 0);
|
return (_size == 0);
|
||||||
}
|
}
|
||||||
|
@ -347,6 +361,87 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Double linked list with sorted nodes.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class SortedArray : public Array<T> {
|
||||||
|
public:
|
||||||
|
typedef T *iterator;
|
||||||
|
typedef uint size_type;
|
||||||
|
|
||||||
|
SortedArray(int (*comparator)(const void *, const void *)) {
|
||||||
|
_comparator = comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts element at the sorted position.
|
||||||
|
*/
|
||||||
|
void insert(const T &element) {
|
||||||
|
if (!this->_size) {
|
||||||
|
this->insert_aux(this->_storage, &element, &element + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
T *where = bsearchMin(element);
|
||||||
|
|
||||||
|
if (where > this->_storage + this->_size)
|
||||||
|
Array<T>::push_back(element);
|
||||||
|
else
|
||||||
|
Array<T>::insert(where, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
T &operator[](size_type idx) {
|
||||||
|
error("Operation []= not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_at(size_type idx, const T &element) {
|
||||||
|
error("Operation insert_at(idx, element) not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_at(size_type idx, const Array<T> &array) {
|
||||||
|
error("Operation insert_at(idx, array) not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(iterator pos, const T &element) {
|
||||||
|
error("Operation insert(pos, elemnet) not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const T &element) {
|
||||||
|
error("Operation push_back(element) not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const Array<T> &array) {
|
||||||
|
error("Operation push_back(array) not allowed with SortedArray");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Based on code Copyright (C) 2008-2009 Ksplice, Inc.
|
||||||
|
// Author: Tim Abbott <tabbott@ksplice.com>
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
T *bsearchMin(void *key) {
|
||||||
|
uint start_ = 0, end_ = this->_size;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
while (start_ < end_) {
|
||||||
|
uint mid = start_ + (end_ - start_) / 2;
|
||||||
|
|
||||||
|
result = this->_comparator(key, this->_storage[mid]);
|
||||||
|
if (result < 0)
|
||||||
|
end_ = mid;
|
||||||
|
else if (result > 0)
|
||||||
|
start_ = mid + 1;
|
||||||
|
else
|
||||||
|
return &this->_storage[mid];
|
||||||
|
}
|
||||||
|
|
||||||
|
return &this->_storage[start_];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int (*_comparator)(const void *, const void *);
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -470,7 +470,7 @@ bool decompressDCL(ReadStream *src, byte *dest, uint32 packedSize, uint32 unpack
|
||||||
// Read source into memory
|
// Read source into memory
|
||||||
src->read(sourceBufferPtr, packedSize);
|
src->read(sourceBufferPtr, packedSize);
|
||||||
|
|
||||||
Common::MemoryReadStream *sourceStream = new MemoryReadStream(sourceBufferPtr, packedSize, DisposeAfterUse::NO);
|
Common::MemoryReadStream *sourceStream = new MemoryReadStream(sourceBufferPtr, packedSize, DisposeAfterUse::YES);
|
||||||
Common::MemoryWriteStream *targetStream = new MemoryWriteStream(dest, unpackedSize);
|
Common::MemoryWriteStream *targetStream = new MemoryWriteStream(dest, unpackedSize);
|
||||||
|
|
||||||
success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
|
success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
|
||||||
|
|
|
@ -64,6 +64,7 @@ const struct GameOpt {
|
||||||
{ GUIO_RENDERPC9801, "pc9801" },
|
{ GUIO_RENDERPC9801, "pc9801" },
|
||||||
{ GUIO_RENDERAPPLE2GS, "2gs" },
|
{ GUIO_RENDERAPPLE2GS, "2gs" },
|
||||||
{ GUIO_RENDERATARIST, "atari" },
|
{ GUIO_RENDERATARIST, "atari" },
|
||||||
|
{ GUIO_RENDERMACINTOSH, "macintosh" },
|
||||||
|
|
||||||
{ GUIO_GAMEOPTIONS1, "gameOption1" },
|
{ GUIO_GAMEOPTIONS1, "gameOption1" },
|
||||||
{ GUIO_GAMEOPTIONS2, "gameOption2" },
|
{ GUIO_GAMEOPTIONS2, "gameOption2" },
|
||||||
|
@ -73,6 +74,7 @@ const struct GameOpt {
|
||||||
{ GUIO_GAMEOPTIONS6, "gameOption6" },
|
{ GUIO_GAMEOPTIONS6, "gameOption6" },
|
||||||
{ GUIO_GAMEOPTIONS7, "gameOption7" },
|
{ GUIO_GAMEOPTIONS7, "gameOption7" },
|
||||||
{ GUIO_GAMEOPTIONS8, "gameOption8" },
|
{ GUIO_GAMEOPTIONS8, "gameOption8" },
|
||||||
|
{ GUIO_GAMEOPTIONS9, "gameOption9" },
|
||||||
|
|
||||||
{ GUIO_NONE, 0 }
|
{ GUIO_NONE, 0 }
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#define GUIO_RENDERPC9801 "\040"
|
#define GUIO_RENDERPC9801 "\040"
|
||||||
#define GUIO_RENDERAPPLE2GS "\041"
|
#define GUIO_RENDERAPPLE2GS "\041"
|
||||||
#define GUIO_RENDERATARIST "\042"
|
#define GUIO_RENDERATARIST "\042"
|
||||||
|
#define GUIO_RENDERMACINTOSH "\043"
|
||||||
|
|
||||||
// Special GUIO flags for the AdvancedDetector's caching of game specific
|
// Special GUIO flags for the AdvancedDetector's caching of game specific
|
||||||
// options.
|
// options.
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
#define GUIO_GAMEOPTIONS6 "\055"
|
#define GUIO_GAMEOPTIONS6 "\055"
|
||||||
#define GUIO_GAMEOPTIONS7 "\056"
|
#define GUIO_GAMEOPTIONS7 "\056"
|
||||||
#define GUIO_GAMEOPTIONS8 "\057"
|
#define GUIO_GAMEOPTIONS8 "\057"
|
||||||
|
#define GUIO_GAMEOPTIONS9 "\058"
|
||||||
|
|
||||||
#define GUIO0() (GUIO_NONE)
|
#define GUIO0() (GUIO_NONE)
|
||||||
#define GUIO1(a) (a)
|
#define GUIO1(a) (a)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "common/md5.h"
|
#include "common/md5.h"
|
||||||
#include "common/substream.h"
|
#include "common/substream.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
#include "common/archive.h"
|
||||||
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
|
@ -261,6 +262,76 @@ bool MacResManager::exists(const String &fileName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacResManager::listFiles(StringArray &files, const String &pattern) {
|
||||||
|
// Base names discovered so far.
|
||||||
|
typedef HashMap<String, bool, IgnoreCase_Hash, IgnoreCase_EqualTo> BaseNameSet;
|
||||||
|
BaseNameSet baseNames;
|
||||||
|
|
||||||
|
// List files itself.
|
||||||
|
ArchiveMemberList memberList;
|
||||||
|
SearchMan.listMatchingMembers(memberList, pattern);
|
||||||
|
SearchMan.listMatchingMembers(memberList, pattern + ".rsrc");
|
||||||
|
SearchMan.listMatchingMembers(memberList, pattern + ".bin");
|
||||||
|
SearchMan.listMatchingMembers(memberList, constructAppleDoubleName(pattern));
|
||||||
|
|
||||||
|
for (ArchiveMemberList::const_iterator i = memberList.begin(), end = memberList.end(); i != end; ++i) {
|
||||||
|
String filename = (*i)->getName();
|
||||||
|
|
||||||
|
// For raw resource forks and MacBinary files we strip the extension
|
||||||
|
// here to obtain a valid base name.
|
||||||
|
int lastDotPos = filename.size() - 1;
|
||||||
|
for (; lastDotPos >= 0; --lastDotPos) {
|
||||||
|
if (filename[lastDotPos] == '.') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastDotPos != -1) {
|
||||||
|
const char *extension = filename.c_str() + lastDotPos + 1;
|
||||||
|
bool removeExtension = false;
|
||||||
|
|
||||||
|
// TODO: Should we really keep filenames suggesting raw resource
|
||||||
|
// forks or MacBinary files but not being such around? This might
|
||||||
|
// depend on the pattern the client requests...
|
||||||
|
if (!scumm_stricmp(extension, "rsrc")) {
|
||||||
|
SeekableReadStream *stream = (*i)->createReadStream();
|
||||||
|
removeExtension = stream && isRawFork(*stream);
|
||||||
|
delete stream;
|
||||||
|
} else if (!scumm_stricmp(extension, "bin")) {
|
||||||
|
SeekableReadStream *stream = (*i)->createReadStream();
|
||||||
|
removeExtension = stream && isMacBinary(*stream);
|
||||||
|
delete stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeExtension) {
|
||||||
|
filename.erase(lastDotPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip AppleDouble '._' prefix if applicable.
|
||||||
|
bool isAppleDoubleName = false;
|
||||||
|
const String filenameAppleDoubleStripped = disassembleAppleDoubleName(filename, &isAppleDoubleName);
|
||||||
|
|
||||||
|
if (isAppleDoubleName) {
|
||||||
|
SeekableReadStream *stream = (*i)->createReadStream();
|
||||||
|
if (stream->readUint32BE() == 0x00051607) {
|
||||||
|
filename = filenameAppleDoubleStripped;
|
||||||
|
}
|
||||||
|
// TODO: Should we really keep filenames suggesting AppleDouble
|
||||||
|
// but not being AppleDouble around? This might depend on the
|
||||||
|
// pattern the client requests...
|
||||||
|
delete stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
baseNames[filename] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append resulting base names to list to indicate found files.
|
||||||
|
for (BaseNameSet::const_iterator i = baseNames.begin(), end = baseNames.end(); i != end; ++i) {
|
||||||
|
files.push_back(i->_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MacResManager::loadFromAppleDouble(SeekableReadStream &stream) {
|
bool MacResManager::loadFromAppleDouble(SeekableReadStream &stream) {
|
||||||
if (stream.readUint32BE() != 0x00051607) // tag
|
if (stream.readUint32BE() != 0x00051607) // tag
|
||||||
return false;
|
return false;
|
||||||
|
@ -314,6 +385,18 @@ bool MacResManager::isMacBinary(SeekableReadStream &stream) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MacResManager::isRawFork(SeekableReadStream &stream) {
|
||||||
|
// TODO: Is there a better way to detect whether this is a raw fork?
|
||||||
|
const uint32 dataOffset = stream.readUint32BE();
|
||||||
|
const uint32 mapOffset = stream.readUint32BE();
|
||||||
|
const uint32 dataLength = stream.readUint32BE();
|
||||||
|
const uint32 mapLength = stream.readUint32BE();
|
||||||
|
|
||||||
|
return !stream.eos() && !stream.err()
|
||||||
|
&& dataOffset < (uint32)stream.size() && dataOffset + dataLength <= (uint32)stream.size()
|
||||||
|
&& mapOffset < (uint32)stream.size() && mapOffset + mapLength <= (uint32)stream.size();
|
||||||
|
}
|
||||||
|
|
||||||
bool MacResManager::loadFromMacBinary(SeekableReadStream &stream) {
|
bool MacResManager::loadFromMacBinary(SeekableReadStream &stream) {
|
||||||
byte infoHeader[MBI_INFOHDR];
|
byte infoHeader[MBI_INFOHDR];
|
||||||
stream.read(infoHeader, MBI_INFOHDR);
|
stream.read(infoHeader, MBI_INFOHDR);
|
||||||
|
@ -592,4 +675,32 @@ String MacResManager::constructAppleDoubleName(String name) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String MacResManager::disassembleAppleDoubleName(String name, bool *isAppleDouble) {
|
||||||
|
if (isAppleDouble) {
|
||||||
|
*isAppleDouble = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove "._" before the last portion of a path name.
|
||||||
|
for (int i = name.size() - 1; i >= 0; --i) {
|
||||||
|
if (i == 0) {
|
||||||
|
if (name.size() > 2 && name[0] == '.' && name[1] == '_') {
|
||||||
|
name.erase(0, 2);
|
||||||
|
if (isAppleDouble) {
|
||||||
|
*isAppleDouble = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (name[i] == '/') {
|
||||||
|
if ((uint)(i + 2) < name.size() && name[i + 1] == '.' && name[i + 2] == '_') {
|
||||||
|
name.erase(i + 1, 2);
|
||||||
|
if (isAppleDouble) {
|
||||||
|
*isAppleDouble = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
|
#include "common/str-array.h"
|
||||||
|
|
||||||
#ifndef COMMON_MACRESMAN_H
|
#ifndef COMMON_MACRESMAN_H
|
||||||
#define COMMON_MACRESMAN_H
|
#define COMMON_MACRESMAN_H
|
||||||
|
@ -81,6 +82,16 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool exists(const String &fileName);
|
static bool exists(const String &fileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all filenames matching pattern for opening with open().
|
||||||
|
*
|
||||||
|
* @param files Array containing all matching filenames discovered. Only
|
||||||
|
* adds to the list.
|
||||||
|
* @param pattern Pattern to match against. Taking String::matchPattern's
|
||||||
|
* format.
|
||||||
|
*/
|
||||||
|
static void listFiles(StringArray &files, const String &pattern);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the Mac data/resource fork pair.
|
* Close the Mac data/resource fork pair.
|
||||||
*/
|
*/
|
||||||
|
@ -176,6 +187,7 @@ private:
|
||||||
bool loadFromAppleDouble(SeekableReadStream &stream);
|
bool loadFromAppleDouble(SeekableReadStream &stream);
|
||||||
|
|
||||||
static String constructAppleDoubleName(String name);
|
static String constructAppleDoubleName(String name);
|
||||||
|
static String disassembleAppleDoubleName(String name, bool *isAppleDouble);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given stream is in the MacBinary format.
|
* Check if the given stream is in the MacBinary format.
|
||||||
|
@ -183,6 +195,13 @@ private:
|
||||||
*/
|
*/
|
||||||
static bool isMacBinary(SeekableReadStream &stream);
|
static bool isMacBinary(SeekableReadStream &stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do a sanity check whether the given stream is a raw resource fork.
|
||||||
|
*
|
||||||
|
* @param stream Stream object to check. Will not preserve its position.
|
||||||
|
*/
|
||||||
|
static bool isRawFork(SeekableReadStream &stream);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kResForkNone = 0,
|
kResForkNone = 0,
|
||||||
kResForkRaw,
|
kResForkRaw,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "common/stream.h"
|
#include "common/stream.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ public:
|
||||||
* that grows as it's written to.
|
* that grows as it's written to.
|
||||||
*/
|
*/
|
||||||
class MemoryWriteStreamDynamic : public WriteStream {
|
class MemoryWriteStreamDynamic : public WriteStream {
|
||||||
private:
|
protected:
|
||||||
uint32 _capacity;
|
uint32 _capacity;
|
||||||
uint32 _size;
|
uint32 _size;
|
||||||
byte *_ptr;
|
byte *_ptr;
|
||||||
|
@ -170,7 +171,7 @@ private:
|
||||||
|
|
||||||
byte *old_data = _data;
|
byte *old_data = _data;
|
||||||
|
|
||||||
_capacity = new_len + 32;
|
_capacity = MAX(new_len + 32, _capacity * 2);
|
||||||
_data = (byte *)malloc(_capacity);
|
_data = (byte *)malloc(_capacity);
|
||||||
_ptr = _data + _pos;
|
_ptr = _data + _pos;
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,16 @@ MODULE_OBJS += \
|
||||||
recorderfile.o
|
recorderfile.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# ResidualVM specific
|
||||||
ifdef USE_ICONV
|
ifdef USE_ICONV
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
iconv.o
|
iconv.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef USE_UPDATES
|
||||||
|
MODULE_OBJS += \
|
||||||
|
updates.o
|
||||||
|
endif
|
||||||
|
|
||||||
# Include common rules
|
# Include common rules
|
||||||
include $(srcdir)/rules.mk
|
include $(srcdir)/rules.mk
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Common {
|
||||||
|
|
||||||
const PlatformDescription g_platforms[] = {
|
const PlatformDescription g_platforms[] = {
|
||||||
{ "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
|
{ "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
|
||||||
|
{ "apple2", "apple2", "apple2", "Apple II", kPlatformApple2 },
|
||||||
{ "3do", "3do", "3do", "3DO", kPlatform3DO },
|
{ "3do", "3do", "3do", "3DO", kPlatform3DO },
|
||||||
{ "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
|
{ "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
|
||||||
{ "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
|
{ "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
|
||||||
|
|
|
@ -50,6 +50,7 @@ enum Platform {
|
||||||
kPlatformSegaCD,
|
kPlatformSegaCD,
|
||||||
kPlatform3DO,
|
kPlatform3DO,
|
||||||
kPlatformPCEngine,
|
kPlatformPCEngine,
|
||||||
|
kPlatformApple2,
|
||||||
kPlatformApple2GS,
|
kPlatformApple2GS,
|
||||||
kPlatformPC98,
|
kPlatformPC98,
|
||||||
kPlatformWii,
|
kPlatformWii,
|
||||||
|
|
|
@ -84,6 +84,8 @@ public:
|
||||||
int getNumerator() const { return _num; }
|
int getNumerator() const { return _num; }
|
||||||
int getDenominator() const { return _denom; }
|
int getDenominator() const { return _denom; }
|
||||||
|
|
||||||
|
bool isOne() const { return _num == _denom; }
|
||||||
|
|
||||||
void debugPrint(int debuglevel = 0, const char *caption = "Rational:") const;
|
void debugPrint(int debuglevel = 0, const char *caption = "Rational:") const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
#include "graphics/scaler.h"
|
#include "graphics/scaler.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_EVENTRECORDER
|
||||||
|
|
||||||
#define RECORD_VERSION 1
|
#define RECORD_VERSION 1
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
@ -714,3 +716,5 @@ void PlaybackFile::checkRecordedMD5() {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // ENABLE_EVENTRECORDER
|
||||||
|
|
|
@ -163,7 +163,8 @@ struct Rect {
|
||||||
*
|
*
|
||||||
* @param r the rectangle to check
|
* @param r the rectangle to check
|
||||||
*
|
*
|
||||||
* @return true if the given rectangle is inside the rectangle, false otherwise
|
* @return true if the given rectangle has a non-empty intersection with
|
||||||
|
* this rectangle, false otherwise
|
||||||
*/
|
*/
|
||||||
bool intersects(const Rect &r) const {
|
bool intersects(const Rect &r) const {
|
||||||
return (left < r.right) && (r.left < right) && (top < r.bottom) && (r.top < bottom);
|
return (left < r.right) && (r.left < right) && (top < r.bottom) && (r.top < bottom);
|
||||||
|
|
|
@ -43,6 +43,7 @@ const RenderModeDescription g_renderModes[] = {
|
||||||
{ "pc9801", _s("PC-9801 (16 Colors)"), kRenderPC9801 },
|
{ "pc9801", _s("PC-9801 (16 Colors)"), kRenderPC9801 },
|
||||||
{ "2gs", "Apple IIgs", kRenderApple2GS },
|
{ "2gs", "Apple IIgs", kRenderApple2GS },
|
||||||
{ "atari", "Atari ST", kRenderAtariST },
|
{ "atari", "Atari ST", kRenderAtariST },
|
||||||
|
{ "macintosh", "Macintosh", kRenderMacintosh },
|
||||||
{0, 0, kRenderDefault}
|
{0, 0, kRenderDefault}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,7 +66,8 @@ static const RenderGUIOMapping s_renderGUIOMapping[] = {
|
||||||
{ kRenderPC9821, GUIO_RENDERPC9821 },
|
{ kRenderPC9821, GUIO_RENDERPC9821 },
|
||||||
{ kRenderPC9801, GUIO_RENDERPC9801 },
|
{ kRenderPC9801, GUIO_RENDERPC9801 },
|
||||||
{ kRenderApple2GS, GUIO_RENDERAPPLE2GS },
|
{ kRenderApple2GS, GUIO_RENDERAPPLE2GS },
|
||||||
{ kRenderAtariST, GUIO_RENDERATARIST }
|
{ kRenderAtariST, GUIO_RENDERATARIST },
|
||||||
|
{ kRenderMacintosh, GUIO_RENDERMACINTOSH }
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
|
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
|
||||||
|
|
|
@ -47,7 +47,8 @@ enum RenderMode {
|
||||||
kRenderPC9821 = 8,
|
kRenderPC9821 = 8,
|
||||||
kRenderPC9801 = 9,
|
kRenderPC9801 = 9,
|
||||||
kRenderApple2GS = 10,
|
kRenderApple2GS = 10,
|
||||||
kRenderAtariST = 11
|
kRenderAtariST = 11,
|
||||||
|
kRenderMacintosh = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderModeDescription {
|
struct RenderModeDescription {
|
||||||
|
|
|
@ -56,6 +56,12 @@ typedef WriteStream OutSaveFile;
|
||||||
* i.e. typically save states, but also configuration files and similar
|
* i.e. typically save states, but also configuration files and similar
|
||||||
* things.
|
* things.
|
||||||
*
|
*
|
||||||
|
* Savefile names represent SaveFiles. These names are case insensitive, that
|
||||||
|
* means a name of "Kq1.000" represents the same savefile as "kq1.000". In
|
||||||
|
* addition, SaveFileManager does not allow for names which contain path
|
||||||
|
* separators like '/' or '\'. This is because we do not support directories
|
||||||
|
* in SaveFileManager.
|
||||||
|
*
|
||||||
* While not declared as a singleton, it is effectively used as such,
|
* While not declared as a singleton, it is effectively used as such,
|
||||||
* with OSystem::getSavefileManager returning a pointer to the single
|
* with OSystem::getSavefileManager returning a pointer to the single
|
||||||
* SaveFileManager instances to be used.
|
* SaveFileManager instances to be used.
|
||||||
|
@ -115,49 +121,56 @@ public:
|
||||||
* exports from the Quest for Glory series. QfG5 is a 3D game and won't be
|
* exports from the Quest for Glory series. QfG5 is a 3D game and won't be
|
||||||
* supported by ScummVM.
|
* supported by ScummVM.
|
||||||
*
|
*
|
||||||
* @param name the name of the savefile
|
* @param name The name of the savefile.
|
||||||
* @param compress toggles whether to compress the resulting save file
|
* @param compress Toggles whether to compress the resulting save file
|
||||||
* (default) or not.
|
* (default) or not.
|
||||||
* @return pointer to an OutSaveFile, or NULL if an error occurred.
|
* @return Pointer to an OutSaveFile, or NULL if an error occurred.
|
||||||
*/
|
*/
|
||||||
virtual OutSaveFile *openForSaving(const String &name, bool compress = true) = 0;
|
virtual OutSaveFile *openForSaving(const String &name, bool compress = true) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the file with the specified name in the given directory for loading.
|
* Open the file with the specified name in the given directory for loading.
|
||||||
* @param name the name of the savefile
|
*
|
||||||
* @return pointer to an InSaveFile, or NULL if an error occurred.
|
* @param name The name of the savefile.
|
||||||
|
* @return Pointer to an InSaveFile, or NULL if an error occurred.
|
||||||
*/
|
*/
|
||||||
virtual InSaveFile *openForLoading(const String &name) = 0;
|
virtual InSaveFile *openForLoading(const String &name) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given savefile from the system.
|
* Removes the given savefile from the system.
|
||||||
* @param name the name of the savefile to be removed.
|
*
|
||||||
|
* @param name The name of the savefile to be removed.
|
||||||
* @return true if no error occurred, false otherwise.
|
* @return true if no error occurred, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool removeSavefile(const String &name) = 0;
|
virtual bool removeSavefile(const String &name) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames the given savefile.
|
* Renames the given savefile.
|
||||||
* @param oldName Old name.
|
*
|
||||||
* @param newName New name.
|
* @param oldName Old name.
|
||||||
|
* @param newName New name.
|
||||||
* @return true if no error occurred. false otherwise.
|
* @return true if no error occurred. false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool renameSavefile(const String &oldName, const String &newName);
|
virtual bool renameSavefile(const String &oldName, const String &newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the given savefile.
|
* Copy the given savefile.
|
||||||
* @param oldName Old name.
|
*
|
||||||
* @param newName New name.
|
* @param oldName Old name.
|
||||||
|
* @param newName New name.
|
||||||
* @return true if no error occurred. false otherwise.
|
* @return true if no error occurred. false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool copySavefile(const String &oldName, const String &newName);
|
virtual bool copySavefile(const String &oldName, const String &newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a list of available savegames with a given DOS-style pattern,
|
* List available savegames matching a given pattern.
|
||||||
* also known as "glob" in the POSIX world. Refer to the Common::matchString()
|
*
|
||||||
* function to learn about the precise pattern format.
|
* Our pattern format is based on DOS paterns, also known as "glob" in the
|
||||||
* @param pattern Pattern to match. Wildcards like * or ? are available.
|
* POSIX world. Please refer to the Common::matchString() function to learn
|
||||||
* @return list of strings for all present file names.
|
* about the precise pattern format.
|
||||||
|
*
|
||||||
|
* @param pattern Pattern to match. Wildcards like * or ? are available.
|
||||||
|
* @return List of strings for all present file names.
|
||||||
* @see Common::matchString()
|
* @see Common::matchString()
|
||||||
*/
|
*/
|
||||||
virtual StringArray listSavefiles(const String &pattern) = 0;
|
virtual StringArray listSavefiles(const String &pattern) = 0;
|
||||||
|
|
|
@ -215,6 +215,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Now we need to adjust some settings when running tests
|
||||||
|
#ifdef COMPILING_TESTS
|
||||||
|
#undef ENABLE_EVENTRECORDER
|
||||||
|
#endif
|
||||||
|
|
||||||
// In the following we configure various targets, in particular those
|
// In the following we configure various targets, in particular those
|
||||||
// which can't use our "configure" tool and hence don't use config.h.
|
// which can't use our "configure" tool and hence don't use config.h.
|
||||||
|
@ -251,6 +255,7 @@
|
||||||
|
|
||||||
#if defined(__DC__) || \
|
#if defined(__DC__) || \
|
||||||
defined(__DS__) || \
|
defined(__DS__) || \
|
||||||
|
defined(__3DS__) || \
|
||||||
defined(__GP32__) || \
|
defined(__GP32__) || \
|
||||||
defined(IPHONE) || \
|
defined(IPHONE) || \
|
||||||
defined(__PLAYSTATION2__) || \
|
defined(__PLAYSTATION2__) || \
|
||||||
|
@ -367,7 +372,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STRINGBUFLEN
|
#ifndef STRINGBUFLEN
|
||||||
#if defined(__N64__) || defined(__DS__)
|
#if defined(__N64__) || defined(__DS__) || defined(__3DS__)
|
||||||
#define STRINGBUFLEN 256
|
#define STRINGBUFLEN 256
|
||||||
#else
|
#else
|
||||||
#define STRINGBUFLEN 1024
|
#define STRINGBUFLEN 1024
|
||||||
|
|
|
@ -75,7 +75,7 @@ void String::initWithCStr(const char *str, uint32 len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const String &str)
|
String::String(const String &str)
|
||||||
: _size(str._size) {
|
: _size(str._size) {
|
||||||
if (str.isStorageIntern()) {
|
if (str.isStorageIntern()) {
|
||||||
// String in internal storage: just copy it
|
// String in internal storage: just copy it
|
||||||
memcpy(_storage, str._storage, _builtinCapacity);
|
memcpy(_storage, str._storage, _builtinCapacity);
|
||||||
|
@ -91,7 +91,7 @@ String::String(const String &str)
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(char c)
|
String::String(char c)
|
||||||
: _size(0), _str(_storage) {
|
: _size(0), _str(_storage) {
|
||||||
|
|
||||||
_storage[0] = c;
|
_storage[0] = c;
|
||||||
_storage[1] = 0;
|
_storage[1] = 0;
|
||||||
|
@ -132,24 +132,19 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) {
|
||||||
if (!isShared && new_size < curCapacity)
|
if (!isShared && new_size < curCapacity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isShared && new_size < _builtinCapacity) {
|
// We need to allocate storage on the heap!
|
||||||
// We share the storage, but there is enough internal storage: Use that.
|
|
||||||
newStorage = _storage;
|
|
||||||
newCapacity = _builtinCapacity;
|
|
||||||
} else {
|
|
||||||
// We need to allocate storage on the heap!
|
|
||||||
|
|
||||||
// Compute a suitable new capacity limit
|
// Compute a suitable new capacity limit
|
||||||
// If the current capacity is sufficient we use the same capacity
|
// If the current capacity is sufficient we use the same capacity
|
||||||
if (new_size < curCapacity)
|
if (new_size < curCapacity)
|
||||||
newCapacity = curCapacity;
|
newCapacity = curCapacity;
|
||||||
else
|
else
|
||||||
newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
|
newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
|
||||||
|
|
||||||
|
// Allocate new storage
|
||||||
|
newStorage = new char[newCapacity];
|
||||||
|
assert(newStorage);
|
||||||
|
|
||||||
// Allocate new storage
|
|
||||||
newStorage = new char[newCapacity];
|
|
||||||
assert(newStorage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy old data if needed, elsewise reset the new storage.
|
// Copy old data if needed, elsewise reset the new storage.
|
||||||
if (keep_old) {
|
if (keep_old) {
|
||||||
|
@ -444,6 +439,58 @@ uint String::hash() const {
|
||||||
return hashit(c_str());
|
return hashit(c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void String::replace(uint32 pos, uint32 count, const String &str) {
|
||||||
|
replace(pos, count, str, 0, str._size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(uint32 pos, uint32 count, const char *str) {
|
||||||
|
replace(pos, count, str, 0, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(iterator begin_, iterator end_, const String &str) {
|
||||||
|
replace(begin_ - _str, end_ - begin_, str._str, 0, str._size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(iterator begin_, iterator end_, const char *str) {
|
||||||
|
replace(begin_ - _str, end_ - begin_, str, 0, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(uint32 posOri, uint32 countOri, const String &str,
|
||||||
|
uint32 posDest, uint32 countDest) {
|
||||||
|
replace(posOri, countOri, str._str, posDest, countDest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(uint32 posOri, uint32 countOri, const char *str,
|
||||||
|
uint32 posDest, uint32 countDest) {
|
||||||
|
|
||||||
|
ensureCapacity(_size + countDest - countOri, true);
|
||||||
|
|
||||||
|
// Prepare string for the replaced text.
|
||||||
|
if (countOri < countDest) {
|
||||||
|
uint32 offset = countDest - countOri; ///< Offset to copy the characters
|
||||||
|
uint32 newSize = _size + offset;
|
||||||
|
_size = newSize;
|
||||||
|
|
||||||
|
// Push the old characters to the end of the string
|
||||||
|
for (uint32 i = _size; i >= posOri + countDest; i--)
|
||||||
|
_str[i] = _str[i - offset];
|
||||||
|
|
||||||
|
} else if (countOri > countDest){
|
||||||
|
uint32 offset = countOri - countDest; ///< Number of positions that we have to pull back
|
||||||
|
|
||||||
|
// Pull the remainder string back
|
||||||
|
for (uint32 i = posOri + countDest; i < _size; i++)
|
||||||
|
_str[i] = _str[i + offset];
|
||||||
|
|
||||||
|
_size -= offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the replaced part of the string
|
||||||
|
for (uint32 i = 0; i < countDest; i++)
|
||||||
|
_str[posOri + i] = str[posDest + i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
String String::format(const char *fmt, ...) {
|
String String::format(const char *fmt, ...) {
|
||||||
String output;
|
String output;
|
||||||
|
|
52
common/str.h
52
common/str.h
|
@ -46,6 +46,17 @@ namespace Common {
|
||||||
class String {
|
class String {
|
||||||
public:
|
public:
|
||||||
static const uint32 npos = 0xFFFFFFFF;
|
static const uint32 npos = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
typedef char value_type;
|
||||||
|
/**
|
||||||
|
* Unsigned version of the underlying type. This can be used to cast
|
||||||
|
* individual string characters to bigger integer types without sign
|
||||||
|
* extension happening.
|
||||||
|
*/
|
||||||
|
typedef unsigned char unsigned_type;
|
||||||
|
typedef char * iterator;
|
||||||
|
typedef const char * const_iterator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* The size of the internal storage. Increasing this means less heap
|
* The size of the internal storage. Increasing this means less heap
|
||||||
|
@ -222,6 +233,38 @@ public:
|
||||||
void trim();
|
void trim();
|
||||||
|
|
||||||
uint hash() const;
|
uint hash() const;
|
||||||
|
|
||||||
|
/**@{
|
||||||
|
* Functions to replace some amount of chars with chars from some other string.
|
||||||
|
*
|
||||||
|
* @note The implementation follows that of the STL's std::string:
|
||||||
|
* http://www.cplusplus.com/reference/string/string/replace/
|
||||||
|
*
|
||||||
|
* @param pos Starting position for the replace in the original string.
|
||||||
|
* @param count Number of chars to replace from the original string.
|
||||||
|
* @param str Source of the new chars.
|
||||||
|
* @param posOri Same as pos
|
||||||
|
* @param countOri Same as count
|
||||||
|
* @param posDest Initial position to read str from.
|
||||||
|
* @param countDest Number of chars to read from str. npos by default.
|
||||||
|
*/
|
||||||
|
// Replace 'count' bytes, starting from 'pos' with str.
|
||||||
|
void replace(uint32 pos, uint32 count, const String &str);
|
||||||
|
// The same as above, but accepts a C-like array of characters.
|
||||||
|
void replace(uint32 pos, uint32 count, const char *str);
|
||||||
|
// Replace the characters in [begin, end) with str._str.
|
||||||
|
void replace(iterator begin, iterator end, const String &str);
|
||||||
|
// Replace the characters in [begin, end) with str.
|
||||||
|
void replace(iterator begin, iterator end, const char *str);
|
||||||
|
// Replace _str[posOri, posOri + countOri) with
|
||||||
|
// str._str[posDest, posDest + countDest)
|
||||||
|
void replace(uint32 posOri, uint32 countOri, const String &str,
|
||||||
|
uint32 posDest, uint32 countDest);
|
||||||
|
// Replace _str[posOri, posOri + countOri) with
|
||||||
|
// str[posDest, posDest + countDest)
|
||||||
|
void replace(uint32 posOri, uint32 countOri, const char *str,
|
||||||
|
uint32 posDest, uint32 countDest);
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print formatted data into a String object. Similar to sprintf,
|
* Print formatted data into a String object. Similar to sprintf,
|
||||||
|
@ -238,15 +281,6 @@ public:
|
||||||
static String vformat(const char *fmt, va_list args);
|
static String vformat(const char *fmt, va_list args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef char value_type;
|
|
||||||
/**
|
|
||||||
* Unsigned version of the underlying type. This can be used to cast
|
|
||||||
* individual string characters to bigger integer types without sign
|
|
||||||
* extension happening.
|
|
||||||
*/
|
|
||||||
typedef unsigned char unsigned_type;
|
|
||||||
typedef char * iterator;
|
|
||||||
typedef const char * const_iterator;
|
|
||||||
|
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
// Since the user could potentially
|
// Since the user could potentially
|
||||||
|
|
|
@ -672,6 +672,7 @@ public:
|
||||||
* Return a Graphics::PixelBuffer representing the framebuffer.
|
* Return a Graphics::PixelBuffer representing the framebuffer.
|
||||||
* The caller can then perform arbitrary graphics transformations
|
* The caller can then perform arbitrary graphics transformations
|
||||||
* on the framebuffer (blitting, scrolling, etc.).
|
* on the framebuffer (blitting, scrolling, etc.).
|
||||||
|
* !!! ResidualVM specific method: !!!
|
||||||
*/
|
*/
|
||||||
virtual Graphics::PixelBuffer getScreenPixelBuffer() = 0;
|
virtual Graphics::PixelBuffer getScreenPixelBuffer() = 0;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ public:
|
||||||
virtual void addRecent(const String &name, const String &description) {}
|
virtual void addRecent(const String &name, const String &description) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the user an error occured through the taskbar icon
|
* Notifies the user an error occurred through the taskbar icon
|
||||||
*
|
*
|
||||||
* This will for example show the taskbar icon as red (using progress of 100% and an error state)
|
* This will for example show the taskbar icon as red (using progress of 100% and an error state)
|
||||||
* on Windows, and set the launcher icon in the urgent state on Unity
|
* on Windows, and set the launcher icon in the urgent state on Unity
|
||||||
|
|
|
@ -41,7 +41,7 @@ void setErrorHandler(ErrorHandler handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
|
|
||||||
#ifndef DISABLE_TEXT_CONSOLE
|
#ifndef DISABLE_TEXT_CONSOLE
|
||||||
|
|
68
common/updates.cpp
Normal file
68
common/updates.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/updates.h"
|
||||||
|
#include "common/translation.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
static const int updateIntervals[] = {
|
||||||
|
UpdateManager::kUpdateIntervalNotSupported,
|
||||||
|
UpdateManager::kUpdateIntervalOneDay,
|
||||||
|
UpdateManager::kUpdateIntervalOneWeek,
|
||||||
|
UpdateManager::kUpdateIntervalOneMonth,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
const int *UpdateManager::getUpdateIntervals() {
|
||||||
|
return updateIntervals;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UpdateManager::normalizeInterval(int interval) {
|
||||||
|
const int *val = updateIntervals;
|
||||||
|
|
||||||
|
while (*val != -1) {
|
||||||
|
if (*val >= interval)
|
||||||
|
return *val;
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val[-1]; // Return maximal acceptable value
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *UpdateManager::updateIntervalToString(int interval) {
|
||||||
|
switch (interval) {
|
||||||
|
case kUpdateIntervalNotSupported:
|
||||||
|
return _("Never");
|
||||||
|
case kUpdateIntervalOneDay:
|
||||||
|
return _("Daily");
|
||||||
|
case kUpdateIntervalOneWeek:
|
||||||
|
return _("Weekly");
|
||||||
|
case kUpdateIntervalOneMonth:
|
||||||
|
return _("Monthly");
|
||||||
|
default:
|
||||||
|
return _("<Bad value>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Common
|
|
@ -20,8 +20,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BACKENDS_UPDATES_ABSTRACT_H
|
#ifndef COMMON_UPDATES_H
|
||||||
#define BACKENDS_UPDATES_ABSTRACT_H
|
#define COMMON_UPDATES_H
|
||||||
|
|
||||||
#if defined(USE_UPDATES)
|
#if defined(USE_UPDATES)
|
||||||
|
|
||||||
|
@ -85,18 +85,50 @@ public:
|
||||||
*
|
*
|
||||||
* @param interval The interval.
|
* @param interval The interval.
|
||||||
*/
|
*/
|
||||||
virtual void setUpdateCheckInterval(UpdateInterval interval) {}
|
virtual void setUpdateCheckInterval(int interval) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the update check interval.
|
* Gets the update check interval.
|
||||||
*
|
*
|
||||||
* @return the update check interval.
|
* @return the update check interval.
|
||||||
*/
|
*/
|
||||||
virtual UpdateInterval getUpdateCheckInterval() { return kUpdateIntervalNotSupported; }
|
virtual int getUpdateCheckInterval() { return kUpdateIntervalNotSupported; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets last update check time
|
||||||
|
*
|
||||||
|
* @param t TimeDate struct to fill out
|
||||||
|
* @return flag indicating success
|
||||||
|
*/
|
||||||
|
virtual bool getLastUpdateCheckTimeAndDate(TimeDate &t) { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns list of supported uptate intervals.
|
||||||
|
* Ending with '-1' which is not acceptable value.
|
||||||
|
*
|
||||||
|
* @return list of integer values representing update intervals in seconds.
|
||||||
|
*/
|
||||||
|
static const int *getUpdateIntervals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns string representation of a given interval.
|
||||||
|
*
|
||||||
|
* @param interval The interval.
|
||||||
|
* @return pointer to localized string of given interval.
|
||||||
|
*/
|
||||||
|
static const char *updateIntervalToString(int interval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rounds up the given interval to acceptable value.
|
||||||
|
*
|
||||||
|
* @param interval The interval.
|
||||||
|
* @return rounded up interval
|
||||||
|
*/
|
||||||
|
static int normalizeInterval(int interval);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // BACKENDS_UPDATES_ABSTRACT_H
|
#endif // COMMON_UPDATES_H
|
||||||
|
|
143
config.guess
vendored
143
config.guess
vendored
|
@ -1,8 +1,8 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Attempt to guess a canonical system name.
|
# Attempt to guess a canonical system name.
|
||||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2014-11-04'
|
timestamp='2016-04-02'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by
|
# under the terms of the GNU General Public License as published by
|
||||||
|
@ -27,7 +27,7 @@ timestamp='2014-11-04'
|
||||||
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
||||||
#
|
#
|
||||||
# You can get the latest version of this script from:
|
# You can get the latest version of this script from:
|
||||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
||||||
#
|
#
|
||||||
# Please send patches to <config-patches@gnu.org>.
|
# Please send patches to <config-patches@gnu.org>.
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ version="\
|
||||||
GNU config.guess ($timestamp)
|
GNU config.guess ($timestamp)
|
||||||
|
|
||||||
Originally written by Per Bothner.
|
Originally written by Per Bothner.
|
||||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
Copyright 1992-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
# Note: NetBSD doesn't particularly care about the vendor
|
# Note: NetBSD doesn't particularly care about the vendor
|
||||||
# portion of the name. We always set it to "unknown".
|
# portion of the name. We always set it to "unknown".
|
||||||
sysctl="sysctl -n hw.machine_arch"
|
sysctl="sysctl -n hw.machine_arch"
|
||||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
||||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
/sbin/$sysctl 2>/dev/null || \
|
||||||
|
/usr/sbin/$sysctl 2>/dev/null || \
|
||||||
|
echo unknown)`
|
||||||
case "${UNAME_MACHINE_ARCH}" in
|
case "${UNAME_MACHINE_ARCH}" in
|
||||||
armeb) machine=armeb-unknown ;;
|
armeb) machine=armeb-unknown ;;
|
||||||
arm*) machine=arm-unknown ;;
|
arm*) machine=arm-unknown ;;
|
||||||
sh3el) machine=shl-unknown ;;
|
sh3el) machine=shl-unknown ;;
|
||||||
sh3eb) machine=sh-unknown ;;
|
sh3eb) machine=sh-unknown ;;
|
||||||
sh5el) machine=sh5le-unknown ;;
|
sh5el) machine=sh5le-unknown ;;
|
||||||
|
earmv*)
|
||||||
|
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
|
||||||
|
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
|
||||||
|
machine=${arch}${endian}-unknown
|
||||||
|
;;
|
||||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||||
esac
|
esac
|
||||||
# The Operating System including object format, if it has switched
|
# The Operating System including object format, if it has switched
|
||||||
# to ELF recently, or will in the future.
|
# to ELF recently, or will in the future.
|
||||||
case "${UNAME_MACHINE_ARCH}" in
|
case "${UNAME_MACHINE_ARCH}" in
|
||||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
| grep -q __ELF__
|
| grep -q __ELF__
|
||||||
|
@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
os=netbsd
|
os=netbsd
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
# Determine ABI tags.
|
||||||
|
case "${UNAME_MACHINE_ARCH}" in
|
||||||
|
earm*)
|
||||||
|
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
|
||||||
|
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
# The OS release
|
# The OS release
|
||||||
# Debian GNU/NetBSD machines have a different userland, and
|
# Debian GNU/NetBSD machines have a different userland, and
|
||||||
# thus, need a distinct triplet. However, they do not need
|
# thus, need a distinct triplet. However, they do not need
|
||||||
|
@ -207,13 +221,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
release='-gnu'
|
release='-gnu'
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||||
# contains redundant information, the shorter form:
|
# contains redundant information, the shorter form:
|
||||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||||
echo "${machine}-${os}${release}"
|
echo "${machine}-${os}${release}${abi}"
|
||||||
exit ;;
|
exit ;;
|
||||||
*:Bitrig:*:*)
|
*:Bitrig:*:*)
|
||||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||||
|
@ -223,6 +237,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
*:LibertyBSD:*:*)
|
||||||
|
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
|
||||||
|
echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
|
||||||
|
exit ;;
|
||||||
*:ekkoBSD:*:*)
|
*:ekkoBSD:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
|
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -235,6 +253,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
*:MirBSD:*:*)
|
*:MirBSD:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
|
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
*:Sortix:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-sortix
|
||||||
|
exit ;;
|
||||||
alpha:OSF1:*:*)
|
alpha:OSF1:*:*)
|
||||||
case $UNAME_RELEASE in
|
case $UNAME_RELEASE in
|
||||||
*4.0)
|
*4.0)
|
||||||
|
@ -251,42 +272,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
|
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
|
||||||
case "$ALPHA_CPU_TYPE" in
|
case "$ALPHA_CPU_TYPE" in
|
||||||
"EV4 (21064)")
|
"EV4 (21064)")
|
||||||
UNAME_MACHINE="alpha" ;;
|
UNAME_MACHINE=alpha ;;
|
||||||
"EV4.5 (21064)")
|
"EV4.5 (21064)")
|
||||||
UNAME_MACHINE="alpha" ;;
|
UNAME_MACHINE=alpha ;;
|
||||||
"LCA4 (21066/21068)")
|
"LCA4 (21066/21068)")
|
||||||
UNAME_MACHINE="alpha" ;;
|
UNAME_MACHINE=alpha ;;
|
||||||
"EV5 (21164)")
|
"EV5 (21164)")
|
||||||
UNAME_MACHINE="alphaev5" ;;
|
UNAME_MACHINE=alphaev5 ;;
|
||||||
"EV5.6 (21164A)")
|
"EV5.6 (21164A)")
|
||||||
UNAME_MACHINE="alphaev56" ;;
|
UNAME_MACHINE=alphaev56 ;;
|
||||||
"EV5.6 (21164PC)")
|
"EV5.6 (21164PC)")
|
||||||
UNAME_MACHINE="alphapca56" ;;
|
UNAME_MACHINE=alphapca56 ;;
|
||||||
"EV5.7 (21164PC)")
|
"EV5.7 (21164PC)")
|
||||||
UNAME_MACHINE="alphapca57" ;;
|
UNAME_MACHINE=alphapca57 ;;
|
||||||
"EV6 (21264)")
|
"EV6 (21264)")
|
||||||
UNAME_MACHINE="alphaev6" ;;
|
UNAME_MACHINE=alphaev6 ;;
|
||||||
"EV6.7 (21264A)")
|
"EV6.7 (21264A)")
|
||||||
UNAME_MACHINE="alphaev67" ;;
|
UNAME_MACHINE=alphaev67 ;;
|
||||||
"EV6.8CB (21264C)")
|
"EV6.8CB (21264C)")
|
||||||
UNAME_MACHINE="alphaev68" ;;
|
UNAME_MACHINE=alphaev68 ;;
|
||||||
"EV6.8AL (21264B)")
|
"EV6.8AL (21264B)")
|
||||||
UNAME_MACHINE="alphaev68" ;;
|
UNAME_MACHINE=alphaev68 ;;
|
||||||
"EV6.8CX (21264D)")
|
"EV6.8CX (21264D)")
|
||||||
UNAME_MACHINE="alphaev68" ;;
|
UNAME_MACHINE=alphaev68 ;;
|
||||||
"EV6.9A (21264/EV69A)")
|
"EV6.9A (21264/EV69A)")
|
||||||
UNAME_MACHINE="alphaev69" ;;
|
UNAME_MACHINE=alphaev69 ;;
|
||||||
"EV7 (21364)")
|
"EV7 (21364)")
|
||||||
UNAME_MACHINE="alphaev7" ;;
|
UNAME_MACHINE=alphaev7 ;;
|
||||||
"EV7.9 (21364A)")
|
"EV7.9 (21364A)")
|
||||||
UNAME_MACHINE="alphaev79" ;;
|
UNAME_MACHINE=alphaev79 ;;
|
||||||
esac
|
esac
|
||||||
# A Pn.n version is a patched version.
|
# A Pn.n version is a patched version.
|
||||||
# A Vn.n version is a released version.
|
# A Vn.n version is a released version.
|
||||||
# A Tn.n version is a released field test version.
|
# A Tn.n version is a released field test version.
|
||||||
# A Xn.n version is an unreleased experimental baselevel.
|
# A Xn.n version is an unreleased experimental baselevel.
|
||||||
# 1.2 uses "1.2" for uname -r.
|
# 1.2 uses "1.2" for uname -r.
|
||||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
|
||||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||||
exitcode=$?
|
exitcode=$?
|
||||||
trap '' 0
|
trap '' 0
|
||||||
|
@ -359,16 +380,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
exit ;;
|
exit ;;
|
||||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
SUN_ARCH="i386"
|
SUN_ARCH=i386
|
||||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||||
# This test works for both compilers.
|
# This test works for both compilers.
|
||||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||||
grep IS_64BIT_ARCH >/dev/null
|
grep IS_64BIT_ARCH >/dev/null
|
||||||
then
|
then
|
||||||
SUN_ARCH="x86_64"
|
SUN_ARCH=x86_64
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
|
@ -393,7 +414,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
exit ;;
|
exit ;;
|
||||||
sun*:*:4.2BSD:*)
|
sun*:*:4.2BSD:*)
|
||||||
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
|
||||||
case "`/bin/arch`" in
|
case "`/bin/arch`" in
|
||||||
sun3)
|
sun3)
|
||||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||||
|
@ -618,13 +639,13 @@ EOF
|
||||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||||
case "${sc_cpu_version}" in
|
case "${sc_cpu_version}" in
|
||||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
|
||||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
|
||||||
532) # CPU_PA_RISC2_0
|
532) # CPU_PA_RISC2_0
|
||||||
case "${sc_kernel_bits}" in
|
case "${sc_kernel_bits}" in
|
||||||
32) HP_ARCH="hppa2.0n" ;;
|
32) HP_ARCH=hppa2.0n ;;
|
||||||
64) HP_ARCH="hppa2.0w" ;;
|
64) HP_ARCH=hppa2.0w ;;
|
||||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
|
||||||
esac ;;
|
esac ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
@ -663,11 +684,11 @@ EOF
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
(CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||||
fi ;;
|
fi ;;
|
||||||
esac
|
esac
|
||||||
if [ ${HP_ARCH} = "hppa2.0w" ]
|
if [ ${HP_ARCH} = hppa2.0w ]
|
||||||
then
|
then
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
|
|
||||||
|
@ -680,12 +701,12 @@ EOF
|
||||||
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
|
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
|
||||||
# => hppa64-hp-hpux11.23
|
# => hppa64-hp-hpux11.23
|
||||||
|
|
||||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||||
grep -q __LP64__
|
grep -q __LP64__
|
||||||
then
|
then
|
||||||
HP_ARCH="hppa2.0w"
|
HP_ARCH=hppa2.0w
|
||||||
else
|
else
|
||||||
HP_ARCH="hppa64"
|
HP_ARCH=hppa64
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||||
|
@ -790,14 +811,14 @@ EOF
|
||||||
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||||
exit ;;
|
exit ;;
|
||||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
|
||||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
|
||||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||||
exit ;;
|
exit ;;
|
||||||
5000:UNIX_System_V:4.*:*)
|
5000:UNIX_System_V:4.*:*)
|
||||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
|
||||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
|
||||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||||
|
@ -879,7 +900,7 @@ EOF
|
||||||
exit ;;
|
exit ;;
|
||||||
*:GNU/*:*:*)
|
*:GNU/*:*:*)
|
||||||
# other systems with GNU libc and userland
|
# other systems with GNU libc and userland
|
||||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:Minix:*:*)
|
i*86:Minix:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-minix
|
echo ${UNAME_MACHINE}-pc-minix
|
||||||
|
@ -902,7 +923,7 @@ EOF
|
||||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||||
esac
|
esac
|
||||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
arc:Linux:*:* | arceb:Linux:*:*)
|
arc:Linux:*:* | arceb:Linux:*:*)
|
||||||
|
@ -933,6 +954,9 @@ EOF
|
||||||
crisv32:Linux:*:*)
|
crisv32:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
e2k:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
|
exit ;;
|
||||||
frv:Linux:*:*)
|
frv:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -945,6 +969,9 @@ EOF
|
||||||
ia64:Linux:*:*)
|
ia64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
k1om:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
|
exit ;;
|
||||||
m32r*:Linux:*:*)
|
m32r*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -1021,7 +1048,7 @@ EOF
|
||||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
x86_64:Linux:*:*)
|
x86_64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
xtensa*:Linux:*:*)
|
xtensa*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
|
@ -1100,7 +1127,7 @@ EOF
|
||||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||||
# the processor, so we play safe by assuming i586.
|
# the processor, so we play safe by assuming i586.
|
||||||
# Note: whatever this is, it MUST be the same as what config.sub
|
# Note: whatever this is, it MUST be the same as what config.sub
|
||||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
# prints for the "djgpp" host, or else GDB configure will decide that
|
||||||
# this is a cross-build.
|
# this is a cross-build.
|
||||||
echo i586-pc-msdosdjgpp
|
echo i586-pc-msdosdjgpp
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -1249,6 +1276,9 @@ EOF
|
||||||
SX-8R:SUPER-UX:*:*)
|
SX-8R:SUPER-UX:*:*)
|
||||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
SX-ACE:SUPER-UX:*:*)
|
||||||
|
echo sxace-nec-superux${UNAME_RELEASE}
|
||||||
|
exit ;;
|
||||||
Power*:Rhapsody:*:*)
|
Power*:Rhapsody:*:*)
|
||||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -1262,9 +1292,9 @@ EOF
|
||||||
UNAME_PROCESSOR=powerpc
|
UNAME_PROCESSOR=powerpc
|
||||||
fi
|
fi
|
||||||
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
||||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||||
grep IS_64BIT_ARCH >/dev/null
|
grep IS_64BIT_ARCH >/dev/null
|
||||||
then
|
then
|
||||||
case $UNAME_PROCESSOR in
|
case $UNAME_PROCESSOR in
|
||||||
|
@ -1286,7 +1316,7 @@ EOF
|
||||||
exit ;;
|
exit ;;
|
||||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||||
UNAME_PROCESSOR=`uname -p`
|
UNAME_PROCESSOR=`uname -p`
|
||||||
if test "$UNAME_PROCESSOR" = "x86"; then
|
if test "$UNAME_PROCESSOR" = x86; then
|
||||||
UNAME_PROCESSOR=i386
|
UNAME_PROCESSOR=i386
|
||||||
UNAME_MACHINE=pc
|
UNAME_MACHINE=pc
|
||||||
fi
|
fi
|
||||||
|
@ -1317,7 +1347,7 @@ EOF
|
||||||
# "uname -m" is not consistent, so use $cputype instead. 386
|
# "uname -m" is not consistent, so use $cputype instead. 386
|
||||||
# is converted to i386 for consistency with other x86
|
# is converted to i386 for consistency with other x86
|
||||||
# operating systems.
|
# operating systems.
|
||||||
if test "$cputype" = "386"; then
|
if test "$cputype" = 386; then
|
||||||
UNAME_MACHINE=i386
|
UNAME_MACHINE=i386
|
||||||
else
|
else
|
||||||
UNAME_MACHINE="$cputype"
|
UNAME_MACHINE="$cputype"
|
||||||
|
@ -1359,7 +1389,7 @@ EOF
|
||||||
echo i386-pc-xenix
|
echo i386-pc-xenix
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:skyos:*:*)
|
i*86:skyos:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
|
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:rdos:*:*)
|
i*86:rdos:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-rdos
|
echo ${UNAME_MACHINE}-pc-rdos
|
||||||
|
@ -1370,6 +1400,9 @@ EOF
|
||||||
x86_64:VMkernel:*:*)
|
x86_64:VMkernel:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-esx
|
echo ${UNAME_MACHINE}-unknown-esx
|
||||||
exit ;;
|
exit ;;
|
||||||
|
amd64:Isilon\ OneFS:*:*)
|
||||||
|
echo x86_64-unknown-onefs
|
||||||
|
exit ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
|
@ -1379,9 +1412,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||||
the operating system you are using. It is advised that you
|
the operating system you are using. It is advised that you
|
||||||
download the most up to date version of the config scripts from
|
download the most up to date version of the config scripts from
|
||||||
|
|
||||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
||||||
and
|
and
|
||||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
||||||
|
|
||||||
If the version you run ($0) is already up to date, please
|
If the version you run ($0) is already up to date, please
|
||||||
send the following data and any information you think might be
|
send the following data and any information you think might be
|
||||||
|
|
38
config.sub
vendored
38
config.sub
vendored
|
@ -1,8 +1,8 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script.
|
||||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2014-12-03'
|
timestamp='2016-03-30'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by
|
# under the terms of the GNU General Public License as published by
|
||||||
|
@ -33,7 +33,7 @@ timestamp='2014-12-03'
|
||||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||||
|
|
||||||
# You can get the latest version of this script from:
|
# You can get the latest version of this script from:
|
||||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
||||||
|
|
||||||
# This file is supposed to be the same for all GNU packages
|
# This file is supposed to be the same for all GNU packages
|
||||||
# and recognize all the CPU types, system types and aliases
|
# and recognize all the CPU types, system types and aliases
|
||||||
|
@ -53,8 +53,7 @@ timestamp='2014-12-03'
|
||||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||||
|
|
||||||
usage="\
|
usage="\
|
||||||
Usage: $0 [OPTION] CPU-MFR-OPSYS
|
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
|
||||||
$0 [OPTION] ALIAS
|
|
||||||
|
|
||||||
Canonicalize a configuration name.
|
Canonicalize a configuration name.
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
GNU config.sub ($timestamp)
|
||||||
|
|
||||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
Copyright 1992-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
@ -117,7 +116,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||||
case $maybe_os in
|
case $maybe_os in
|
||||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||||
kopensolaris*-gnu* | \
|
kopensolaris*-gnu* | \
|
||||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||||
os=-$maybe_os
|
os=-$maybe_os
|
||||||
|
@ -255,12 +254,13 @@ case $basic_machine in
|
||||||
| arc | arceb \
|
| arc | arceb \
|
||||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||||
| avr | avr32 \
|
| avr | avr32 \
|
||||||
|
| ba \
|
||||||
| be32 | be64 \
|
| be32 | be64 \
|
||||||
| bfin \
|
| bfin \
|
||||||
| c4x | c8051 | clipper \
|
| c4x | c8051 | clipper \
|
||||||
| d10v | d30v | dlx | dsp16xx \
|
| d10v | d30v | dlx | dsp16xx \
|
||||||
| epiphany \
|
| e2k | epiphany \
|
||||||
| fido | fr30 | frv \
|
| fido | fr30 | frv | ft32 \
|
||||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| hexagon \
|
| hexagon \
|
||||||
| i370 | i860 | i960 | ia64 \
|
| i370 | i860 | i960 | ia64 \
|
||||||
|
@ -305,7 +305,7 @@ case $basic_machine in
|
||||||
| riscv32 | riscv64 \
|
| riscv32 | riscv64 \
|
||||||
| rl78 | rx \
|
| rl78 | rx \
|
||||||
| score \
|
| score \
|
||||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||||
| sh64 | sh64le \
|
| sh64 | sh64le \
|
||||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||||
|
@ -376,12 +376,13 @@ case $basic_machine in
|
||||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||||
| avr-* | avr32-* \
|
| avr-* | avr32-* \
|
||||||
|
| ba-* \
|
||||||
| be32-* | be64-* \
|
| be32-* | be64-* \
|
||||||
| bfin-* | bs2000-* \
|
| bfin-* | bs2000-* \
|
||||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||||
| d10v-* | d30v-* | dlx-* \
|
| d10v-* | d30v-* | dlx-* \
|
||||||
| elxsi-* \
|
| e2k-* | elxsi-* \
|
||||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||||
| h8300-* | h8500-* \
|
| h8300-* | h8500-* \
|
||||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||||
|
@ -428,12 +429,13 @@ case $basic_machine in
|
||||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||||
| pyramid-* \
|
| pyramid-* \
|
||||||
|
| riscv32-* | riscv64-* \
|
||||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||||
| sparclite-* \
|
| sparclite-* \
|
||||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
|
||||||
| tahoe-* \
|
| tahoe-* \
|
||||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||||
| tile*-* \
|
| tile*-* \
|
||||||
|
@ -518,6 +520,9 @@ case $basic_machine in
|
||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
os=-aros
|
os=-aros
|
||||||
;;
|
;;
|
||||||
|
asmjs)
|
||||||
|
basic_machine=asmjs-unknown
|
||||||
|
;;
|
||||||
aux)
|
aux)
|
||||||
basic_machine=m68k-apple
|
basic_machine=m68k-apple
|
||||||
os=-aux
|
os=-aux
|
||||||
|
@ -1373,11 +1378,11 @@ case $os in
|
||||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||||
| -sym* | -kopensolaris* | -plan9* \
|
| -sym* | -kopensolaris* | -plan9* \
|
||||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||||
| -aos* | -aros* \
|
| -aos* | -aros* | -cloudabi* | -sortix* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||||
| -bitrig* | -openbsd* | -solidbsd* \
|
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
||||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
|
@ -1393,7 +1398,8 @@ case $os in
|
||||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
|
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
||||||
|
| -onefs* | -tirtos*)
|
||||||
# Remember, each alternative MUST END IN *, to match a version number.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
-qnx*)
|
||||||
|
@ -1525,6 +1531,8 @@ case $os in
|
||||||
;;
|
;;
|
||||||
-nacl*)
|
-nacl*)
|
||||||
;;
|
;;
|
||||||
|
-ios)
|
||||||
|
;;
|
||||||
-none)
|
-none)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
538
configure
vendored
538
configure
vendored
|
@ -132,6 +132,7 @@ _timidity=no
|
||||||
_zlib=auto
|
_zlib=auto
|
||||||
_mpeg2=auto
|
_mpeg2=auto
|
||||||
_sparkle=auto
|
_sparkle=auto
|
||||||
|
_osxdockplugin=auto
|
||||||
_jpeg=auto
|
_jpeg=auto
|
||||||
_png=auto
|
_png=auto
|
||||||
_theoradec=auto
|
_theoradec=auto
|
||||||
|
@ -165,10 +166,12 @@ _bink=yes
|
||||||
_vkeybd=no
|
_vkeybd=no
|
||||||
_keymapper=no
|
_keymapper=no
|
||||||
_eventrec=no
|
_eventrec=no
|
||||||
|
# GUI translation options
|
||||||
_translation=yes
|
_translation=yes
|
||||||
# Default platform settings
|
# Default platform settings
|
||||||
_backend=sdl
|
_backend=sdl
|
||||||
_16bit=auto
|
_16bit=auto
|
||||||
|
_highres=auto
|
||||||
_savegame_timestamp=auto
|
_savegame_timestamp=auto
|
||||||
_dynamic_modules=no
|
_dynamic_modules=no
|
||||||
_elf_loader=no
|
_elf_loader=no
|
||||||
|
@ -188,6 +191,8 @@ _stagingpath="staging"
|
||||||
_win32path="C:/residualvm"
|
_win32path="C:/residualvm"
|
||||||
_amigaospath="Games:ResidualVM"
|
_amigaospath="Games:ResidualVM"
|
||||||
_staticlibpath=
|
_staticlibpath=
|
||||||
|
_xcodetoolspath=
|
||||||
|
_sparklepath=
|
||||||
_sdlconfig=sdl-config
|
_sdlconfig=sdl-config
|
||||||
_freetypeconfig=freetype-config
|
_freetypeconfig=freetype-config
|
||||||
_sdlpath="$PATH"
|
_sdlpath="$PATH"
|
||||||
|
@ -208,6 +213,7 @@ add_feature 16bit "16bit color" "_16bit"
|
||||||
add_feature faad "libfaad" "_faad"
|
add_feature faad "libfaad" "_faad"
|
||||||
add_feature flac "FLAC" "_flac"
|
add_feature flac "FLAC" "_flac"
|
||||||
add_feature freetype2 "FreeType2" "_freetype2"
|
add_feature freetype2 "FreeType2" "_freetype2"
|
||||||
|
add_feature highres "high resolution" "_highres"
|
||||||
add_feature mad "MAD" "_mad"
|
add_feature mad "MAD" "_mad"
|
||||||
add_feature jpeg "JPEG" "_jpeg"
|
add_feature jpeg "JPEG" "_jpeg"
|
||||||
add_feature png "PNG" "_png"
|
add_feature png "PNG" "_png"
|
||||||
|
@ -443,7 +449,7 @@ get_system_exe_extension() {
|
||||||
arm-riscos)
|
arm-riscos)
|
||||||
_exeext=",ff8"
|
_exeext=",ff8"
|
||||||
;;
|
;;
|
||||||
dreamcast | ds | gamecube | n64 | ps2 | psp | wii)
|
3ds | dreamcast | ds | gamecube | n64 | ps2 | psp | wii)
|
||||||
_exeext=".elf"
|
_exeext=".elf"
|
||||||
;;
|
;;
|
||||||
gph-linux)
|
gph-linux)
|
||||||
|
@ -600,7 +606,7 @@ engine_enable() {
|
||||||
parent=`get_subengine_parent ${engine}`
|
parent=`get_subengine_parent ${engine}`
|
||||||
if test `get_engine_build ${parent}` = "no" ; then
|
if test `get_engine_build ${parent}` = "no" ; then
|
||||||
set_var _engine_${parent}_build "yes"
|
set_var _engine_${parent}_build "yes"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$opt" = "static" -o "$opt" = "dynamic" -o "$opt" = "yes" ; then
|
if test "$opt" = "static" -o "$opt" = "dynamic" -o "$opt" = "yes" ; then
|
||||||
|
@ -811,12 +817,6 @@ get_subengines_build_string() {
|
||||||
echo "$subengine_string"
|
echo "$subengine_string"
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Greet user
|
|
||||||
#
|
|
||||||
echo "Running ResidualVM configure..."
|
|
||||||
echo "Configure run on" `date` > $TMPLOG
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check any parameters we received
|
# Check any parameters we received
|
||||||
#
|
#
|
||||||
|
@ -877,7 +877,7 @@ Game engines:
|
||||||
--disable-all-engines disable all engines
|
--disable-all-engines disable all engines
|
||||||
--enable-engine=<engine name>[,<engine name>...] enable engine(s) listed
|
--enable-engine=<engine name>[,<engine name>...] enable engine(s) listed
|
||||||
--disable-engine=<engine name>[,<engine name>...] disable engine(s) listed
|
--disable-engine=<engine name>[,<engine name>...] disable engine(s) listed
|
||||||
--enable-engine-static=<engine name>[,<engine name>...]
|
--enable-engine-static=<engine name>[,<engine name>...]
|
||||||
enable engine(s) listed as static builtin (when plugins are enabled)
|
enable engine(s) listed as static builtin (when plugins are enabled)
|
||||||
--enable-engine-dynamic=<engine name>[,<engine name>...]
|
--enable-engine-dynamic=<engine name>[,<engine name>...]
|
||||||
enable engine(s) listed as dynamic plugin (when plugins are enabled)
|
enable engine(s) listed as dynamic plugin (when plugins are enabled)
|
||||||
|
@ -953,8 +953,10 @@ Optional Libraries:
|
||||||
installed (optional)
|
installed (optional)
|
||||||
--disable-fluidsynth disable fluidsynth MIDI driver [autodetect]
|
--disable-fluidsynth disable fluidsynth MIDI driver [autodetect]
|
||||||
|
|
||||||
--with-sparkle-prefix=DIR Prefix where sparkle is installed (Mac OS X only - optional)
|
--with-sparkle-prefix=DIR Prefix where sparkle is installed (OS X/Windows only - optional)
|
||||||
--disable-sparkle disable sparkle automatic update support [Mac OS X only - autodetect]
|
--disable-sparkle disable sparkle automatic update support [OS X/Windows only - autodetect]
|
||||||
|
|
||||||
|
--disable-osx-dock-plugin disable the NSDockTilePlugin support [Mac OS X only - autodetect]
|
||||||
|
|
||||||
--with-sdl-prefix=DIR Prefix where the sdl-config script is
|
--with-sdl-prefix=DIR Prefix where the sdl-config script is
|
||||||
installed (optional)
|
installed (optional)
|
||||||
|
@ -993,9 +995,25 @@ EOF
|
||||||
fi
|
fi
|
||||||
done # for parm in ...
|
done # for parm in ...
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# If we're not showing help, greet the user and start the log file
|
||||||
|
#
|
||||||
|
echo "Running ResidualVM configure..."
|
||||||
|
echo "Configure run on" `date` > $TMPLOG
|
||||||
|
cat >> $TMPLOG <<EOF
|
||||||
|
Invocation command line was:
|
||||||
|
$0 $@
|
||||||
|
Saved environment variables:
|
||||||
|
LDFLAGS="$SAVED_LDFLAGS" CXX="$SAVED_CXX" CXXFLAGS="$SAVED_CXXFLAGS" CPPFLAGS="$SAVED_CPPFLAGS" ASFLAGS="$SAVED_ASFLAGS" WINDRESFLAGS="$SAVED_WINDRESFLAGS" SDL_CONFIG="$SAVED_SDL_CONFIG"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
for ac_option in $@; do
|
for ac_option in $@; do
|
||||||
case "$ac_option" in
|
case "$ac_option" in
|
||||||
# --disable-16bit) _16bit=no ;; #ResidualVM: not supported
|
# --disable-16bit) _16bit=no ;; #ResidualVM: not supported
|
||||||
|
# --enable-highres) _highres=yes ;; #ResidualVM: not supported
|
||||||
|
# --disable-highres) _highres=no ;; #ResidualVM: not supported
|
||||||
--disable-savegame-timestamp) _savegame_timestamp=no ;;
|
--disable-savegame-timestamp) _savegame_timestamp=no ;;
|
||||||
# --disable-scalers) _build_scalers=no ;; #ResidualVM: not supported
|
# --disable-scalers) _build_scalers=no ;; #ResidualVM: not supported
|
||||||
# --disable-hq-scalers) _build_hq_scalers=no ;; #ResidualVM: not supported
|
# --disable-hq-scalers) _build_hq_scalers=no ;; #ResidualVM: not supported
|
||||||
|
@ -1019,6 +1037,8 @@ for ac_option in $@; do
|
||||||
--disable-zlib) _zlib=no ;;
|
--disable-zlib) _zlib=no ;;
|
||||||
--enable-sparkle) _sparkle=yes ;;
|
--enable-sparkle) _sparkle=yes ;;
|
||||||
--disable-sparkle) _sparkle=no ;;
|
--disable-sparkle) _sparkle=no ;;
|
||||||
|
--enable-osx-dock-plugin) _osxdockplugin=yes;;
|
||||||
|
--disable-osx-dock-plugin) _osxdockplugin=no;;
|
||||||
--enable-nasm) _nasm=yes ;;
|
--enable-nasm) _nasm=yes ;;
|
||||||
--disable-nasm) _nasm=no ;;
|
--disable-nasm) _nasm=no ;;
|
||||||
--enable-mpeg2) _mpeg2=yes ;;
|
--enable-mpeg2) _mpeg2=yes ;;
|
||||||
|
@ -1141,8 +1161,7 @@ for ac_option in $@; do
|
||||||
;;
|
;;
|
||||||
--with-sparkle-prefix=*)
|
--with-sparkle-prefix=*)
|
||||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||||
SPARKLE_CFLAGS="-F$arg"
|
_sparklepath=$arg
|
||||||
SPARKLE_LIBS="-F$arg"
|
|
||||||
;;
|
;;
|
||||||
--with-readline-prefix=*)
|
--with-readline-prefix=*)
|
||||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||||
|
@ -1225,6 +1244,9 @@ for ac_option in $@; do
|
||||||
--with-staticlib-prefix=*)
|
--with-staticlib-prefix=*)
|
||||||
_staticlibpath=`echo $ac_option | cut -d '=' -f 2`
|
_staticlibpath=`echo $ac_option | cut -d '=' -f 2`
|
||||||
;;
|
;;
|
||||||
|
--with-xcodetools-path=*)
|
||||||
|
_xcodetoolspath=`echo $ac_option | cut -d '=' -f 2`
|
||||||
|
;;
|
||||||
--host=*)
|
--host=*)
|
||||||
_host=`echo $ac_option | cut -d '=' -f 2`
|
_host=`echo $ac_option | cut -d '=' -f 2`
|
||||||
;;
|
;;
|
||||||
|
@ -1289,6 +1311,11 @@ get_system_exe_extension $guessed_host
|
||||||
NATIVEEXEEXT=$_exeext
|
NATIVEEXEEXT=$_exeext
|
||||||
|
|
||||||
case $_host in
|
case $_host in
|
||||||
|
3ds)
|
||||||
|
_host_os=3ds
|
||||||
|
_host_cpu=arm
|
||||||
|
_host_alias=arm-none-eabi
|
||||||
|
;;
|
||||||
android | android-arm | android-v7a | android-arm-v7a | ouya)
|
android | android-arm | android-v7a | android-arm-v7a | ouya)
|
||||||
_host_os=android
|
_host_os=android
|
||||||
_host_cpu=arm
|
_host_cpu=arm
|
||||||
|
@ -1304,6 +1331,26 @@ android-x86)
|
||||||
_host_cpu=i686
|
_host_cpu=i686
|
||||||
_host_alias=i686-linux-android
|
_host_alias=i686-linux-android
|
||||||
;;
|
;;
|
||||||
|
androidsdl-armeabi | androidsdl-armeabi-v7a)
|
||||||
|
_host_os=androidsdl
|
||||||
|
_host_cpu=arm
|
||||||
|
_host_alias=arm-linux-androideabi
|
||||||
|
;;
|
||||||
|
androidsdl-arm64-v8a)
|
||||||
|
_host_os=androidsdl
|
||||||
|
_host_cpu=aarch64
|
||||||
|
_host_alias=aarch64-linux-android
|
||||||
|
;;
|
||||||
|
androidsdl-mips)
|
||||||
|
_host_os=androidsdl
|
||||||
|
_host_cpu=mipsel
|
||||||
|
_host_alias=mipsel-linux-android
|
||||||
|
;;
|
||||||
|
androidsdl-x86)
|
||||||
|
_host_os=androidsdl
|
||||||
|
_host_cpu=i686
|
||||||
|
_host_alias=i686-linux-android
|
||||||
|
;;
|
||||||
arm-riscos)
|
arm-riscos)
|
||||||
_host_os=riscos
|
_host_os=riscos
|
||||||
_host_cpu=arm
|
_host_cpu=arm
|
||||||
|
@ -1313,7 +1360,7 @@ raspberrypi)
|
||||||
_host_cpu=arm
|
_host_cpu=arm
|
||||||
# This tuple is the one used by the official Rpi toolchain.
|
# This tuple is the one used by the official Rpi toolchain.
|
||||||
# It may change in the future.
|
# It may change in the future.
|
||||||
_host_alias=bcm2708hardfp
|
_host_alias=arm-linux-gnueabihf
|
||||||
;;
|
;;
|
||||||
caanoo)
|
caanoo)
|
||||||
_host_os=gph-linux
|
_host_os=gph-linux
|
||||||
|
@ -1570,7 +1617,7 @@ android)
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
ds | gamecube | wii)
|
3ds | ds | gamecube | wii)
|
||||||
if test -z "$DEVKITPRO"; then
|
if test -z "$DEVKITPRO"; then
|
||||||
echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>"
|
echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -1826,7 +1873,7 @@ if test "$have_gcc" = yes ; then
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
# newlib-based system include files suppress non-C89 function
|
# newlib-based system include files suppress non-C89 function
|
||||||
# declarations under __STRICT_ANSI__
|
# declarations under __STRICT_ANSI__
|
||||||
amigaos* | android | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince )
|
3ds | amigaos* | android | androidsdl | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
append_var CXXFLAGS "-ansi"
|
append_var CXXFLAGS "-ansi"
|
||||||
|
@ -1862,7 +1909,7 @@ echo $_use_cxx11
|
||||||
# However, some platforms use GNU extensions in system header files, so
|
# However, some platforms use GNU extensions in system header files, so
|
||||||
# for these we must not use -pedantic.
|
# for these we must not use -pedantic.
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
android | gamecube | psp | tizen | wii | webos)
|
android | androidsdl | gamecube | psp | tizen | wii | webos)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# ICC does not support pedantic, while GCC and clang do.
|
# ICC does not support pedantic, while GCC and clang do.
|
||||||
|
@ -2126,6 +2173,27 @@ esac
|
||||||
echo_n "Checking hosttype... "
|
echo_n "Checking hosttype... "
|
||||||
echo $_host_os
|
echo $_host_os
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
|
3ds)
|
||||||
|
_optimization_level=-O2
|
||||||
|
append_var DEFINES "-D__3DS__"
|
||||||
|
append_var DEFINES "-DARM"
|
||||||
|
append_var DEFINES "-DARM11"
|
||||||
|
append_var CXXFLAGS "-march=armv6k"
|
||||||
|
append_var CXXFLAGS "-mtune=mpcore"
|
||||||
|
append_var CXXFLAGS "-mword-relocations"
|
||||||
|
append_var CXXFLAGS "-mfloat-abi=hard"
|
||||||
|
append_var CXXFLAGS "-ffunction-sections"
|
||||||
|
append_var CXXFLAGS "-fomit-frame-pointer"
|
||||||
|
append_var CXXFLAGS "-I$DEVKITPRO/libctru/include"
|
||||||
|
append_var CXXFLAGS "-I$DEVKITPRO/portlibs/3ds/include"
|
||||||
|
if test "$_dynamic_modules" = no ; then
|
||||||
|
append_var LDFLAGS "-Wl,--gc-sections"
|
||||||
|
else
|
||||||
|
append_var LDFLAGS "-Wl,--no-gc-sections"
|
||||||
|
fi
|
||||||
|
append_var LDFLAGS "-L$DEVKITPRO/portlibs/3ds/lib"
|
||||||
|
append_var LIBS "-lcitro3d -lctru"
|
||||||
|
;;
|
||||||
amigaos*)
|
amigaos*)
|
||||||
append_var LDFLAGS "-Wl,--export-dynamic"
|
append_var LDFLAGS "-Wl,--export-dynamic"
|
||||||
append_var LDFLAGS "-L/sdk/local/newlib/lib"
|
append_var LDFLAGS "-L/sdk/local/newlib/lib"
|
||||||
|
@ -2280,7 +2348,7 @@ case $_host_os in
|
||||||
|
|
||||||
LDFLAGS="-L${macport_prefix}/lib $LDFLAGS"
|
LDFLAGS="-L${macport_prefix}/lib $LDFLAGS"
|
||||||
CXXFLAGS="-I${macport_prefix}/include $CXXFLAGS"
|
CXXFLAGS="-I${macport_prefix}/include $CXXFLAGS"
|
||||||
|
|
||||||
if test -z "$_staticlibpath"; then
|
if test -z "$_staticlibpath"; then
|
||||||
_staticlibpath=${macport_prefix}
|
_staticlibpath=${macport_prefix}
|
||||||
echo "Set staticlib-prefix to ${_staticlibpath}"
|
echo "Set staticlib-prefix to ${_staticlibpath}"
|
||||||
|
@ -2342,6 +2410,17 @@ case $_host_os in
|
||||||
echo "Could not determine prefix for static libraries"
|
echo "Could not determine prefix for static libraries"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# If _xcodetoolspath is not set yet use xcode-select to get the path
|
||||||
|
if test -z "$_xcodetoolspath"; then
|
||||||
|
_xcodetoolspath=`xcode-select -print-path`/Tools
|
||||||
|
if test -d "$_xcodetoolspath"; then
|
||||||
|
echo "Set xcodetools-path to ${_xcodetoolspath}"
|
||||||
|
else
|
||||||
|
_xcodetoolspath=
|
||||||
|
echo "Could not determine path for Xcode Tools"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
dreamcast)
|
dreamcast)
|
||||||
append_var DEFINES "-D__DC__"
|
append_var DEFINES "-D__DC__"
|
||||||
|
@ -2435,6 +2514,10 @@ case $_host_os in
|
||||||
mint*)
|
mint*)
|
||||||
append_var DEFINES "-DSYSTEM_NOT_SUPPORTING_D_TYPE"
|
append_var DEFINES "-DSYSTEM_NOT_SUPPORTING_D_TYPE"
|
||||||
;;
|
;;
|
||||||
|
msys)
|
||||||
|
echo ERROR: Using the MSYS shell in msys mode is not supported. Please use the MSYS shell in mingw mode instead.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
n64)
|
n64)
|
||||||
append_var DEFINES "-D__N64__"
|
append_var DEFINES "-D__N64__"
|
||||||
append_var DEFINES "-DLIMIT_FPS"
|
append_var DEFINES "-DLIMIT_FPS"
|
||||||
|
@ -2550,6 +2633,18 @@ if test -n "$_host"; then
|
||||||
# Cross-compiling mode - add your target here if needed
|
# Cross-compiling mode - add your target here if needed
|
||||||
echo "Cross-compiling to $_host"
|
echo "Cross-compiling to $_host"
|
||||||
case "$_host" in
|
case "$_host" in
|
||||||
|
3ds)
|
||||||
|
append_var DEFINES "-DDISABLE_FANCY_THEMES"
|
||||||
|
append_var DEFINES "-DDISABLE_SID"
|
||||||
|
append_var DEFINES "-DDISABLE_NES_APU"
|
||||||
|
_backend="3ds"
|
||||||
|
_build_scalers=no
|
||||||
|
_vkeybd=yes
|
||||||
|
_mt32emu=no
|
||||||
|
# Should use Tremor instead of Vorbis
|
||||||
|
_vorbis=no
|
||||||
|
_port_mk="backends/platform/3ds/3ds.mk"
|
||||||
|
;;
|
||||||
android | android-arm | android-v7a | android-arm-v7a | android-mips | android-x86 | ouya)
|
android | android-arm | android-v7a | android-arm-v7a | android-mips | android-x86 | ouya)
|
||||||
# we link a .so as default
|
# we link a .so as default
|
||||||
append_var LDFLAGS "-shared"
|
append_var LDFLAGS "-shared"
|
||||||
|
@ -2563,6 +2658,15 @@ if test -n "$_host"; then
|
||||||
_mt32emu=no
|
_mt32emu=no
|
||||||
_timidity=no
|
_timidity=no
|
||||||
;;
|
;;
|
||||||
|
androidsdl | androidsdl-armeabi | androidsdl-armeabi-v7a | androidsdl-mips | androidsdl-x86 | androidsdl-arm64-v8a)
|
||||||
|
DEFINES="$DEFINES -DANDROIDSDL"
|
||||||
|
_unix=yes
|
||||||
|
_seq_midi=no
|
||||||
|
_mt32emu=no
|
||||||
|
_timidity=no
|
||||||
|
_backend="androidsdl"
|
||||||
|
_port_mk="backends/platform/androidsdl/androidsdl.mk"
|
||||||
|
;;
|
||||||
arm-linux|arm*-linux-gnueabi|arm-*-linux)
|
arm-linux|arm*-linux-gnueabi|arm-*-linux)
|
||||||
;;
|
;;
|
||||||
arm-riscos|linupy)
|
arm-riscos|linupy)
|
||||||
|
@ -2601,7 +2705,7 @@ if test -n "$_host"; then
|
||||||
_mt32emu=no
|
_mt32emu=no
|
||||||
_optimization_level=-O3
|
_optimization_level=-O3
|
||||||
# Disable alsa midi to get the port build on OpenDingux toolchain
|
# Disable alsa midi to get the port build on OpenDingux toolchain
|
||||||
_alsa=no
|
_alsa=no
|
||||||
_vkeybd=yes
|
_vkeybd=yes
|
||||||
_build_hq_scalers=no
|
_build_hq_scalers=no
|
||||||
_keymapper=no
|
_keymapper=no
|
||||||
|
@ -2628,14 +2732,15 @@ if test -n "$_host"; then
|
||||||
_eventrec=no
|
_eventrec=no
|
||||||
_build_scalers=no
|
_build_scalers=no
|
||||||
_build_hq_scalers=no
|
_build_hq_scalers=no
|
||||||
# We prefer SDL2 on the Raspberry Pi: acceleration now depends on it
|
# We prefer SDL2 on the Raspberry Pi: acceleration now depends on it
|
||||||
# since SDL2 manages dispmanx/GLES2 very well internally.
|
# since SDL2 manages dispmanx/GLES2 very well internally.
|
||||||
# SDL1 is bit-rotten on this platform.
|
# SDL1 is bit-rotten on this platform.
|
||||||
_sdlconfig=sdl2-config
|
_sdlconfig=sdl2-config
|
||||||
# OpenGL(ES) support is mature enough as to be the best option on
|
# OpenGL ES support is mature enough as to be the best option on
|
||||||
# the Raspberry Pi, so it's enabled by default.
|
# the Raspberry Pi, so it's enabled by default.
|
||||||
_opengl=yes
|
# The Raspberry Pi always supports OpenGL ES 2.0 contexts, thus we
|
||||||
_opengles=yes
|
# take advantage of those.
|
||||||
|
_opengl_mode=gles2
|
||||||
;;
|
;;
|
||||||
dreamcast)
|
dreamcast)
|
||||||
append_var DEFINES "-DDISABLE_DEFAULT_SAVEFILEMANAGER"
|
append_var DEFINES "-DDISABLE_DEFAULT_SAVEFILEMANAGER"
|
||||||
|
@ -2656,7 +2761,11 @@ if test -n "$_host"; then
|
||||||
_build_scalers=no
|
_build_scalers=no
|
||||||
_mad=yes
|
_mad=yes
|
||||||
_zlib=yes
|
_zlib=yes
|
||||||
add_line_to_config_mk 'ronindir = /usr/local/ronin'
|
if test -z "$RONINDIR"; then
|
||||||
|
add_line_to_config_mk "ronindir := /usr/local/ronin"
|
||||||
|
else
|
||||||
|
add_line_to_config_mk "ronindir := $RONINDIR"
|
||||||
|
fi
|
||||||
_port_mk="backends/platform/dc/dreamcast.mk"
|
_port_mk="backends/platform/dc/dreamcast.mk"
|
||||||
;;
|
;;
|
||||||
ds)
|
ds)
|
||||||
|
@ -2689,22 +2798,22 @@ if test -n "$_host"; then
|
||||||
add_line_to_config_h "/* #define DEBUG_WII_GDB */"
|
add_line_to_config_h "/* #define DEBUG_WII_GDB */"
|
||||||
add_line_to_config_h "#define USE_WII_DI"
|
add_line_to_config_h "#define USE_WII_DI"
|
||||||
;;
|
;;
|
||||||
gcw0)
|
gcw0)
|
||||||
append_var DEFINES "-DDINGUX -DGCW0"
|
_sysroot=`$CXX --print-sysroot`
|
||||||
|
_sdlpath=$_sysroot/usr/bin
|
||||||
|
append_var DEFINES "-DDINGUX -DGCW0 -DGUI_ONLY_FULLSCREEN"
|
||||||
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
||||||
append_var CXXFLAGS "-mips32"
|
append_var CXXFLAGS "-mips32"
|
||||||
_backend="dingux"
|
_backend="dingux"
|
||||||
_mt32emu=no
|
|
||||||
_optimization_level=-O3
|
|
||||||
# Disable alsa midi to get the port build on OpenDingux toolchain
|
|
||||||
_alsa=no
|
_alsa=no
|
||||||
_vkeybd=yes
|
_mt32emu=no
|
||||||
_build_hq_scalers=no
|
|
||||||
_keymapper=yes
|
|
||||||
# Force disable vorbis on dingux, it has terrible performance compared to tremor
|
|
||||||
_vorbis=no
|
|
||||||
# Force disable seq on dingux, no way to use it and it would get enabled by default with configure
|
|
||||||
_seq_midi=no
|
_seq_midi=no
|
||||||
|
_timidity=no
|
||||||
|
_build_scalers=no
|
||||||
|
_optimization_level=-O3
|
||||||
|
_vkeybd=yes
|
||||||
|
_keymapper=yes
|
||||||
|
_vorbis=no
|
||||||
_port_mk="backends/platform/dingux/dingux.mk"
|
_port_mk="backends/platform/dingux/dingux.mk"
|
||||||
;;
|
;;
|
||||||
gp2x)
|
gp2x)
|
||||||
|
@ -2746,11 +2855,8 @@ if test -n "$_host"; then
|
||||||
;;
|
;;
|
||||||
ios7)
|
ios7)
|
||||||
append_var DEFINES "-DIPHONE"
|
append_var DEFINES "-DIPHONE"
|
||||||
append_var CFLAGS "-Wno-shift-count-overflow"
|
|
||||||
append_var CXXFLAGS "-Wno-shift-count-overflow"
|
|
||||||
_backend="ios7"
|
_backend="ios7"
|
||||||
_build_scalers=no
|
_build_scalers=no
|
||||||
_mt32emu=no
|
|
||||||
_seq_midi=no
|
_seq_midi=no
|
||||||
_timidity=no
|
_timidity=no
|
||||||
;;
|
;;
|
||||||
|
@ -2767,7 +2873,7 @@ if test -n "$_host"; then
|
||||||
append_var INCLUDES "-I/usr/X11R6/include"
|
append_var INCLUDES "-I/usr/X11R6/include"
|
||||||
append_var LIBS "-lX11"
|
append_var LIBS "-lX11"
|
||||||
append_var LIBS "-L/usr/lib"
|
append_var LIBS "-L/usr/lib"
|
||||||
|
|
||||||
_backend="maemo"
|
_backend="maemo"
|
||||||
_vkeybd=yes
|
_vkeybd=yes
|
||||||
_keymapper=yes
|
_keymapper=yes
|
||||||
|
@ -2960,6 +3066,8 @@ if test -n "$_host"; then
|
||||||
_mt32emu=no
|
_mt32emu=no
|
||||||
_timidity=no
|
_timidity=no
|
||||||
_vkeybd=yes
|
_vkeybd=yes
|
||||||
|
# Tizen relies on the OpenGL ES output thus we always enable it.
|
||||||
|
_opengl_mode=gles
|
||||||
;;
|
;;
|
||||||
webos)
|
webos)
|
||||||
_backend="webos"
|
_backend="webos"
|
||||||
|
@ -3005,12 +3113,16 @@ fi
|
||||||
# Backend related stuff
|
# Backend related stuff
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
|
3ds)
|
||||||
|
;;
|
||||||
android)
|
android)
|
||||||
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
||||||
append_var CXXFLAGS "-Wa,--noexecstack"
|
append_var CXXFLAGS "-Wa,--noexecstack"
|
||||||
append_var LDFLAGS "-Wl,-z,noexecstack"
|
append_var LDFLAGS "-Wl,-z,noexecstack"
|
||||||
append_var INCLUDES "-I$ANDROID_NDK/sources/cxx-stl/system/include"
|
append_var INCLUDES "-I$ANDROID_NDK/sources/cxx-stl/system/include"
|
||||||
;;
|
;;
|
||||||
|
androidsdl)
|
||||||
|
;;
|
||||||
dc)
|
dc)
|
||||||
append_var INCLUDES '-I$(srcdir)/backends/platform/dc'
|
append_var INCLUDES '-I$(srcdir)/backends/platform/dc'
|
||||||
append_var INCLUDES '-isystem $(ronindir)/include'
|
append_var INCLUDES '-isystem $(ronindir)/include'
|
||||||
|
@ -3107,6 +3219,8 @@ case $_backend in
|
||||||
append_var LDFLAGS "-shared"
|
append_var LDFLAGS "-shared"
|
||||||
append_var LDFLAGS "-fpic"
|
append_var LDFLAGS "-fpic"
|
||||||
;;
|
;;
|
||||||
|
sdl)
|
||||||
|
;;
|
||||||
tizen)
|
tizen)
|
||||||
# dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included
|
# dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included
|
||||||
append_var DEFINES "-DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT"
|
append_var DEFINES "-DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT"
|
||||||
|
@ -3155,8 +3269,6 @@ case $_backend in
|
||||||
append_var DEFINES "-DSDL_BACKEND"
|
append_var DEFINES "-DSDL_BACKEND"
|
||||||
add_line_to_config_mk "SDL_BACKEND = 1"
|
add_line_to_config_mk "SDL_BACKEND = 1"
|
||||||
;;
|
;;
|
||||||
sdl)
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "support for $_backend backend not implemented in configure script yet"
|
echo "support for $_backend backend not implemented in configure script yet"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -3168,7 +3280,7 @@ append_var MODULES "backends/platform/$_backend"
|
||||||
# Setup SDL specifics for SDL based backends
|
# Setup SDL specifics for SDL based backends
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
dingux | gph | linuxmoto | maemo | openpandora | samsungtv | sdl)
|
androidsdl | dingux | gph | linuxmoto | maemo | openpandora | samsungtv | sdl)
|
||||||
find_sdlconfig
|
find_sdlconfig
|
||||||
append_var INCLUDES "`$_sdlconfig --prefix="$_sdlpath" --cflags`"
|
append_var INCLUDES "`$_sdlconfig --prefix="$_sdlpath" --cflags`"
|
||||||
append_var LIBS "`$_sdlconfig --prefix="$_sdlpath" --libs`"
|
append_var LIBS "`$_sdlconfig --prefix="$_sdlpath" --libs`"
|
||||||
|
@ -3191,7 +3303,7 @@ esac
|
||||||
# Enable 16bit support only for backends which support it
|
# Enable 16bit support only for backends which support it
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
android | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii)
|
3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii)
|
||||||
if test "$_16bit" = auto ; then
|
if test "$_16bit" = auto ; then
|
||||||
_16bit=yes
|
_16bit=yes
|
||||||
else
|
else
|
||||||
|
@ -3203,6 +3315,26 @@ case $_backend in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable High resolution engines (>320x240) support only for backends which support it
|
||||||
|
#
|
||||||
|
case $_host in
|
||||||
|
gcw0)
|
||||||
|
if test "$_highres" = yes ; then
|
||||||
|
_highres=yes
|
||||||
|
else
|
||||||
|
_highres=no
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test "$_highres" = no ; then
|
||||||
|
_highres=no
|
||||||
|
else
|
||||||
|
_highres=yes
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
#
|
#
|
||||||
# Enable Event Recorder only for backends that support it
|
# Enable Event Recorder only for backends that support it
|
||||||
#
|
#
|
||||||
|
@ -3250,7 +3382,7 @@ case $_host_os in
|
||||||
amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince)
|
amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince)
|
||||||
_posix=no
|
_posix=no
|
||||||
;;
|
;;
|
||||||
android | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos)
|
3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos)
|
||||||
_posix=yes
|
_posix=yes
|
||||||
;;
|
;;
|
||||||
os2-emx*)
|
os2-emx*)
|
||||||
|
@ -3515,6 +3647,11 @@ define_in_config_if_yes "$_mt32emu" 'USE_MT32EMU'
|
||||||
#
|
#
|
||||||
define_in_config_if_yes "$_16bit" 'USE_RGB_COLOR'
|
define_in_config_if_yes "$_16bit" 'USE_RGB_COLOR'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check whether High resolution graphics support is requested
|
||||||
|
#
|
||||||
|
define_in_config_if_yes "$_highres" 'USE_HIGHRES'
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check whether save games use the current time as default description
|
# Check whether save games use the current time as default description
|
||||||
#
|
#
|
||||||
|
@ -3873,39 +4010,100 @@ echo "$_mpeg2"
|
||||||
#
|
#
|
||||||
# Check for Sparkle if updates support is enabled
|
# Check for Sparkle if updates support is enabled
|
||||||
#
|
#
|
||||||
echocheck "Sparkle"
|
#
|
||||||
if test "$_updates" = no; then
|
# Check is NSDockTilePlugIn protocol is supported
|
||||||
_sparkle=no
|
#
|
||||||
else
|
case $_host_os in
|
||||||
if test "$_sparkle" = auto ; then
|
darwin*)
|
||||||
_sparkle=no
|
echocheck "Sparkle"
|
||||||
cat > $TMPC << EOF
|
if test "$_updates" = no; then
|
||||||
|
_sparkle=no
|
||||||
|
else
|
||||||
|
if test ! -z $_sparklepath ; then
|
||||||
|
SPARKLE_CFLAGS="-F$_sparklepath"
|
||||||
|
SPARKLE_LIBS="-F$_sparklepath"
|
||||||
|
fi
|
||||||
|
if test "$_sparkle" = auto ; then
|
||||||
|
_sparkle=no
|
||||||
|
cat > $TMPC << EOF
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#include <Sparkle/Sparkle.h>
|
#include <Sparkle/Sparkle.h>
|
||||||
int main(void) { SUUpdater *updater = [SUUpdater sharedUpdater]; return 0; }
|
int main(void) { SUUpdater *updater = [SUUpdater sharedUpdater]; return 0; }
|
||||||
EOF
|
EOF
|
||||||
cc_check $SPARKLE_CFLAGS $SPARKLE_LIBS -framework Sparkle -ObjC++ -lobjc && _sparkle=yes
|
cc_check $SPARKLE_CFLAGS $SPARKLE_LIBS -framework Sparkle -ObjC++ -lobjc && _sparkle=yes
|
||||||
fi
|
fi
|
||||||
if test "$_sparkle" = yes ; then
|
if test "$_sparkle" = yes ; then
|
||||||
append_var LIBS "$SPARKLE_LIBS -framework Sparkle"
|
append_var LIBS "$SPARKLE_LIBS -framework Sparkle"
|
||||||
append_var INCLUDES "$SPARKLE_CFLAGS"
|
append_var INCLUDES "$SPARKLE_CFLAGS"
|
||||||
fi
|
fi
|
||||||
define_in_config_if_yes "$_sparkle" 'USE_SPARKLE'
|
define_in_config_if_yes "$_sparkle" 'USE_SPARKLE'
|
||||||
fi
|
fi
|
||||||
echo "$_sparkle"
|
echo "$_sparkle"
|
||||||
|
;;
|
||||||
|
mingw*)
|
||||||
|
echocheck "Sparkle"
|
||||||
|
if test "$_updates" = no; then
|
||||||
|
_sparkle=no
|
||||||
|
else
|
||||||
|
if test ! -z $_sparklepath ; then
|
||||||
|
SPARKLE_CFLAGS="-I$_sparklepath/include"
|
||||||
|
SPARKLE_LIBS="-L$_sparklepath/Release -L$_sparklepath/x64/Release"
|
||||||
|
fi
|
||||||
|
if test "$_sparkle" = auto ; then
|
||||||
|
_sparkle=no
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <winsparkle.h>
|
||||||
|
int main(void) { win_sparkle_get_update_check_interval(); return 0; }
|
||||||
|
EOF
|
||||||
|
cc_check $SPARKLE_CFLAGS $SPARKLE_LIBS -lWinSparkle && _sparkle=yes
|
||||||
|
fi
|
||||||
|
if test "$_sparkle" = yes ; then
|
||||||
|
append_var LIBS "$SPARKLE_LIBS -lWinSparkle"
|
||||||
|
append_var INCLUDES "$SPARKLE_CFLAGS"
|
||||||
|
fi
|
||||||
|
define_in_config_if_yes "$_sparkle" 'USE_SPARKLE'
|
||||||
|
fi
|
||||||
|
echo "$_sparkle"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_sparkle=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for FluidSynth
|
# Check is NSDockTilePlugIn protocol is supported
|
||||||
|
#
|
||||||
|
case $_host_os in
|
||||||
|
darwin*)
|
||||||
|
# NSDockTilePlugIn was added in OS X 10.6, so will not be available when compiling on older OS X versions.
|
||||||
|
echocheck "DockTilePlugin"
|
||||||
|
if test "$_osxdockplugin" = auto ; then
|
||||||
|
_osxdockplugin=no
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
@interface ScummVMDockTilePlugIn : NSObject <NSDockTilePlugIn> {
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
EOF
|
||||||
|
cc_check -c -ObjC++ && _osxdockplugin=yes
|
||||||
|
fi
|
||||||
|
define_in_config_if_yes "$_osxdockplugin" 'USE_DOCKTILEPLUGIN'
|
||||||
|
echo "$_osxdockplugin"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_osxdockplugin=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check for FluidSynth
|
||||||
#
|
#
|
||||||
echocheck "FluidSynth"
|
echocheck "FluidSynth"
|
||||||
|
|
||||||
append_var FLUIDSYNTH_LIBS "-lfluidsynth"
|
append_var FLUIDSYNTH_LIBS "-lfluidsynth"
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
mingw*)
|
mingw*)
|
||||||
# NOTE: Windows builds use an older FluidSynth version (1.0.9)
|
FLUIDSYNTH_STATIC_LIBS="$FLUIDSYNTH_LIBS -lglib-2.0 -lintl -liconv -lws2_32 -lole32 -lshlwapi -lpcre -ldsound -lwinmm"
|
||||||
# which doesn't require glib, to avoid bundling the complete glib
|
|
||||||
# libraries with Windows builds.
|
|
||||||
FLUIDSYNTH_STATIC_LIBS="$FLUIDSYNTH_LIBS -ldsound -lwinmm"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
darwin*)
|
darwin*)
|
||||||
|
@ -4138,87 +4336,7 @@ EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
define_in_config_if_yes "$_glew" "USE_GLEW"
|
define_in_config_if_yes "$_glew" "USE_GLEW"
|
||||||
# ResidualVM specific end <-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for iconv
|
|
||||||
#
|
|
||||||
echo_n "Checking whether iconv.h is present... "
|
|
||||||
if test "$_iconv" = auto ; then
|
|
||||||
_iconv=no
|
|
||||||
cat > $TMPC << EOF
|
|
||||||
#include <iconv.h>
|
|
||||||
int main(int, char **) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
cc_check $ICONV_CFLAGS $ICONV_LIBS && _iconv=yes
|
|
||||||
fi
|
|
||||||
|
|
||||||
create_iconv_test() {
|
|
||||||
cat > $TMPC << EOF
|
|
||||||
#include <iconv.h>
|
|
||||||
int main(int, char **) {
|
|
||||||
iconv_t iconv = iconv_open("UTF-32", "SJIS");
|
|
||||||
iconv_close(iconv);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
echo "$_iconv"
|
|
||||||
|
|
||||||
if test "$_iconv" = yes ; then
|
|
||||||
echo_n "Checking whether iconv needs linking against libiconv... "
|
|
||||||
|
|
||||||
needs_iconvlib='auto'
|
|
||||||
create_iconv_test
|
|
||||||
cc_check $ICONV_CFLAGS $ICONV_LIBS -liconv && needs_iconvlib='yes'
|
|
||||||
# We do check linking without -liconv here too, just in case
|
|
||||||
# it would fail otherwise too
|
|
||||||
create_iconv_test
|
|
||||||
cc_check $ICONV_CFLAGS $ICONV_LIBS && needs_iconvlib='no'
|
|
||||||
|
|
||||||
if test "$needs_iconvlib" = auto ; then
|
|
||||||
_iconv=no
|
|
||||||
echo "does not link at all"
|
|
||||||
else
|
|
||||||
if test "$needs_iconvlib" = yes ; then
|
|
||||||
append_var ICONV_LIBS "-liconv"
|
|
||||||
fi
|
|
||||||
echo "$needs_iconvlib"
|
|
||||||
|
|
||||||
echo_n "Checking signature of iconv... "
|
|
||||||
uses_const=no
|
|
||||||
|
|
||||||
cat > $TMPC << EOF
|
|
||||||
#include <iconv.h>
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
iconv_t iconvP;
|
|
||||||
const char **inbuf = 0;
|
|
||||||
iconv(iconvP, inbuf, 0, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
cc_check $ICONV_CFLAGS $ICONV_LIBS && uses_const=yes
|
|
||||||
|
|
||||||
if test "$uses_const" = yes ; then
|
|
||||||
echo "iconv_t, const char **, size_t *, char **, size_t *"
|
|
||||||
else
|
|
||||||
echo "iconv_t, char **, size_t *, char **, size_t *"
|
|
||||||
fi
|
|
||||||
|
|
||||||
define_in_config_if_yes "$uses_const" 'ICONV_USES_CONST'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$_iconv" = yes ; then
|
|
||||||
append_var LIBS "$ICONV_LIBS"
|
|
||||||
append_var INCLUDES "$ICONV_CFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echocheck "iconv"
|
|
||||||
define_in_config_if_yes "$_iconv" 'USE_ICONV'
|
|
||||||
echo "$_iconv"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for OpenGL (ES)
|
# Check for OpenGL (ES)
|
||||||
|
@ -4239,7 +4357,6 @@ case $_backend in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# ResidualVM specific start ->
|
|
||||||
if test "$_opengl" = auto ; then
|
if test "$_opengl" = auto ; then
|
||||||
_opengl=no
|
_opengl=no
|
||||||
if test "$_backend" = "sdl" || test "$_backend" = "android"; then
|
if test "$_backend" = "sdl" || test "$_backend" = "android"; then
|
||||||
|
@ -4340,19 +4457,10 @@ EOF
|
||||||
fi
|
fi
|
||||||
cc_check_clean
|
cc_check_clean
|
||||||
fi
|
fi
|
||||||
# ResidualVM specific end <-
|
|
||||||
|
|
||||||
case $_host_os in
|
|
||||||
tizen)
|
|
||||||
# components live in non-standard locations so just assume sane SDK
|
|
||||||
_opengl=yes
|
|
||||||
_opengles=yes
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if test "$_opengles" = "yes" ; then
|
if test "$_opengles" = "yes" ; then
|
||||||
echo "yes (OpenGL ES)"
|
echo "yes (OpenGL ES)"
|
||||||
# ResidualVM specific start here ->
|
|
||||||
elif test "$_opengles2" = "yes" ; then
|
elif test "$_opengles2" = "yes" ; then
|
||||||
echo "yes (OpenGL ES2)"
|
echo "yes (OpenGL ES2)"
|
||||||
else
|
else
|
||||||
|
@ -4369,8 +4477,112 @@ define_in_config_if_yes "$_opengl" "USE_OPENGL"
|
||||||
define_in_config_if_yes "$_opengles" "USE_GLES"
|
define_in_config_if_yes "$_opengles" "USE_GLES"
|
||||||
define_in_config_if_yes "$_opengles2" "USE_GLES2"
|
define_in_config_if_yes "$_opengles2" "USE_GLES2"
|
||||||
define_in_config_if_yes "$_opengl_shaders" "USE_OPENGL_SHADERS"
|
define_in_config_if_yes "$_opengl_shaders" "USE_OPENGL_SHADERS"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check for iconv
|
||||||
|
#
|
||||||
|
echo_n "Checking whether iconv.h is present... "
|
||||||
|
if test "$_iconv" = auto ; then
|
||||||
|
_iconv=no
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <iconv.h>
|
||||||
|
int main(int, char **) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
cc_check $ICONV_CFLAGS $ICONV_LIBS && _iconv=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
create_iconv_test() {
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <iconv.h>
|
||||||
|
int main(int, char **) {
|
||||||
|
iconv_t iconv = iconv_open("UTF-32", "SJIS");
|
||||||
|
iconv_close(iconv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
echo "$_iconv"
|
||||||
|
|
||||||
|
if test "$_iconv" = yes ; then
|
||||||
|
echo_n "Checking whether iconv needs linking against libiconv... "
|
||||||
|
|
||||||
|
needs_iconvlib='auto'
|
||||||
|
create_iconv_test
|
||||||
|
cc_check $ICONV_CFLAGS $ICONV_LIBS -liconv && needs_iconvlib='yes'
|
||||||
|
# We do check linking without -liconv here too, just in case
|
||||||
|
# it would fail otherwise too
|
||||||
|
create_iconv_test
|
||||||
|
cc_check $ICONV_CFLAGS $ICONV_LIBS && needs_iconvlib='no'
|
||||||
|
|
||||||
|
if test "$needs_iconvlib" = auto ; then
|
||||||
|
_iconv=no
|
||||||
|
echo "does not link at all"
|
||||||
|
else
|
||||||
|
if test "$needs_iconvlib" = yes ; then
|
||||||
|
append_var ICONV_LIBS "-liconv"
|
||||||
|
fi
|
||||||
|
echo "$needs_iconvlib"
|
||||||
|
|
||||||
|
echo_n "Checking signature of iconv... "
|
||||||
|
uses_const=no
|
||||||
|
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <iconv.h>
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
iconv_t iconvP;
|
||||||
|
const char **inbuf = 0;
|
||||||
|
iconv(iconvP, inbuf, 0, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
cc_check $ICONV_CFLAGS $ICONV_LIBS && uses_const=yes
|
||||||
|
|
||||||
|
if test "$uses_const" = yes ; then
|
||||||
|
echo "iconv_t, const char **, size_t *, char **, size_t *"
|
||||||
|
else
|
||||||
|
echo "iconv_t, char **, size_t *, char **, size_t *"
|
||||||
|
fi
|
||||||
|
|
||||||
|
define_in_config_if_yes "$uses_const" 'ICONV_USES_CONST'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$_iconv" = yes ; then
|
||||||
|
append_var LIBS "$ICONV_LIBS"
|
||||||
|
append_var INCLUDES "$ICONV_CFLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echocheck "iconv"
|
||||||
|
define_in_config_if_yes "$_iconv" 'USE_ICONV'
|
||||||
|
echo "$_iconv"
|
||||||
# ResidualVM specific ends here <-
|
# ResidualVM specific ends here <-
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check for Linux CD-ROM support
|
||||||
|
#
|
||||||
|
case $_host_os in
|
||||||
|
*linux*)
|
||||||
|
echocheck "Linux CD-ROM"
|
||||||
|
linuxcd=no
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <linux/cdrom.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
int main(void) {
|
||||||
|
int x = CDROMREADAUDIO;
|
||||||
|
dev_t dev;
|
||||||
|
return major(dev) + x;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
cc_check && linuxcd=yes
|
||||||
|
define_in_config_if_yes "$linuxcd" 'USE_LINUXCD'
|
||||||
|
echo "$linuxcd"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for nasm
|
# Check for nasm
|
||||||
#
|
#
|
||||||
|
@ -4605,6 +4817,10 @@ if test "$_16bit" = yes ; then
|
||||||
: # residualvm not use it
|
: # residualvm not use it
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$_highres" = yes ; then
|
||||||
|
: # residualvm not use it
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$_savegame_timestamp" = yes ; then
|
if test "$_savegame_timestamp" = yes ; then
|
||||||
echo_n ", savegame timestamp"
|
echo_n ", savegame timestamp"
|
||||||
fi
|
fi
|
||||||
|
@ -4618,7 +4834,7 @@ if test "$_build_scalers" = yes ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_mt32emu" = yes ; then
|
if test "$_mt32emu" = yes ; then
|
||||||
echo_n ", MT-32 emu"
|
echo_n ", MT-32 emulator"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$_text_console" = yes ; then
|
if test "$_text_console" = yes ; then
|
||||||
|
@ -4644,6 +4860,14 @@ fi
|
||||||
# after all of CXXFLAGS, LDFLAGS, LIBS etc. have been setup
|
# after all of CXXFLAGS, LDFLAGS, LIBS etc. have been setup
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
|
3ds)
|
||||||
|
if test "$_freetype2" = yes -a "$_png" = yes; then
|
||||||
|
append_var LIBS "-lpng"
|
||||||
|
fi
|
||||||
|
if test "$_tremor" = yes -o "$_flac" = yes; then
|
||||||
|
append_var LIBS "-logg"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
android)
|
android)
|
||||||
# ssp at this point so the cxxtests link
|
# ssp at this point so the cxxtests link
|
||||||
if test "$_debug_build" = yes; then
|
if test "$_debug_build" = yes; then
|
||||||
|
@ -4875,6 +5099,8 @@ STAGINGPATH=$_stagingpath
|
||||||
WIN32PATH=$_win32path
|
WIN32PATH=$_win32path
|
||||||
AMIGAOSPATH=$_amigaospath
|
AMIGAOSPATH=$_amigaospath
|
||||||
STATICLIBPATH=$_staticlibpath
|
STATICLIBPATH=$_staticlibpath
|
||||||
|
XCODETOOLSPATH=$_xcodetoolspath
|
||||||
|
SPARKLEPATH=$_sparklepath
|
||||||
SDLCONFIG=$_sdlconfig
|
SDLCONFIG=$_sdlconfig
|
||||||
|
|
||||||
ABI := $ABI
|
ABI := $ABI
|
||||||
|
|
324
devtools/create_project/cmake.cpp
Normal file
324
devtools/create_project/cmake.cpp
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "cmake.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace CreateProjectTool {
|
||||||
|
|
||||||
|
CMakeProvider::CMakeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
|
||||||
|
: ProjectProvider(global_warnings, project_warnings, version) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const CMakeProvider::Library *CMakeProvider::getLibraryFromFeature(const char *feature) const {
|
||||||
|
static const Library s_libraries[] = {
|
||||||
|
{ "sdl", "FindSDL", "SDL", "SDL_INCLUDE_DIR", "SDL_LIBRARY", 0 },
|
||||||
|
{ "sdl2", 0, "SDL2", "SDL2_INCLUDE_DIRS", "SDL2_LIBRARIES", 0 },
|
||||||
|
{ "freetype", "FindFreetype", "Freetype", "FREETYPE_INCLUDE_DIRS", "FREETYPE_LIBRARIES", 0 },
|
||||||
|
{ "libz", "FindZLIB", "ZLIB", "ZLIB_INCLUDE_DIRS", "ZLIB_LIBRARIES", 0 },
|
||||||
|
{ "png", "FindPNG", "PNG", "PNG_INCLUDE_DIRS", "PNG_LIBRARIES", 0 },
|
||||||
|
{ "jpeg", "FindJPEG", "JPEG", "JPEG_INCLUDE_DIRS", "JPEG_LIBRARIES", 0 },
|
||||||
|
{ "mpeg2", "FindMPEG2", "MPEG2", "MPEG2_INCLUDE_DIRS", "MPEG2_mpeg2_LIBRARY", 0 },
|
||||||
|
{ "flac", 0, 0, 0, 0, "FLAC" },
|
||||||
|
{ "mad", 0, 0, 0, 0, "mad" },
|
||||||
|
{ "vorbis", 0, 0, 0, 0, "vorbisfile vorbis ogg" },
|
||||||
|
{ "theora", 0, 0, 0, 0, "theoradec" },
|
||||||
|
{ "fluidsynth",0, 0, 0, 0, "fluidsynth" },
|
||||||
|
{ "faad", 0, 0, 0, 0, "faad" }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(s_libraries) / sizeof(s_libraries[0]); i++) {
|
||||||
|
if (std::strcmp(feature, s_libraries[i].feature) == 0) {
|
||||||
|
return &s_libraries[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::createWorkspace(const BuildSetup &setup) {
|
||||||
|
std::string filename = setup.outputDir + "/CMakeLists.txt";
|
||||||
|
std::ofstream workspace(filename.c_str());
|
||||||
|
if (!workspace)
|
||||||
|
error("Could not open \"" + filename + "\" for writing");
|
||||||
|
|
||||||
|
workspace << "cmake_minimum_required(VERSION 3.2)\n"
|
||||||
|
"project(" << setup.projectDescription << ")\n\n";
|
||||||
|
|
||||||
|
workspace << "# Define the engines and subengines\n";
|
||||||
|
writeEngines(setup, workspace);
|
||||||
|
writeSubEngines(setup, workspace);
|
||||||
|
workspace << "# Generate options for the engines\n";
|
||||||
|
writeEngineOptions(workspace);
|
||||||
|
|
||||||
|
workspace << "include_directories(${" << setup.projectDescription << "_SOURCE_DIR} ${" << setup.projectDescription << "_SOURCE_DIR}/engines\n"
|
||||||
|
"$ENV{"<<LIBS_DEFINE<<"}/include)\n\n";
|
||||||
|
|
||||||
|
workspace << "# Libraries and features\n";
|
||||||
|
writeFeatureLibSearch(workspace, setup.useSDL2 ? "sdl2" : "sdl");
|
||||||
|
for (FeatureList::const_iterator i = setup.features.begin(), end = setup.features.end(); i != end; ++i) {
|
||||||
|
if (!i->enable || featureExcluded(i->name)) continue;
|
||||||
|
|
||||||
|
writeFeatureLibSearch(workspace, i->name);
|
||||||
|
workspace << "add_definitions(-D" << i->define << ")\n";
|
||||||
|
}
|
||||||
|
workspace << "\n";
|
||||||
|
|
||||||
|
writeWarnings(workspace);
|
||||||
|
writeDefines(setup, workspace);
|
||||||
|
workspace << "# Generate definitions for the engines\n";
|
||||||
|
writeEngineDefinitions(workspace);
|
||||||
|
|
||||||
|
workspace << "# Generate \"engines/plugins_table.h\"\n";
|
||||||
|
writeGeneratePluginsTable(workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeFeatureLibSearch(std::ofstream &workspace, const char *feature) const {
|
||||||
|
const Library *library = getLibraryFromFeature(feature);
|
||||||
|
if (library) {
|
||||||
|
if (library->module) {
|
||||||
|
workspace << "Include(" << library->module << ")\n";
|
||||||
|
}
|
||||||
|
if (library->package) {
|
||||||
|
workspace << "Find_Package(" << library->package << " REQUIRED)\n";
|
||||||
|
}
|
||||||
|
if (library->includesVar) {
|
||||||
|
workspace << "include_directories(${" << library->includesVar << "})\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeEngines(const BuildSetup &setup, std::ofstream &workspace) const {
|
||||||
|
workspace << "set(ENGINES";
|
||||||
|
for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
|
||||||
|
// We ignore all sub engines here because they require special handling.
|
||||||
|
if (!i->enable || isSubEngine(i->name, setup.engines)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string engineName;
|
||||||
|
std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
|
||||||
|
|
||||||
|
workspace << " " << engineName;
|
||||||
|
}
|
||||||
|
workspace << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeSubEngines(const BuildSetup &setup, std::ofstream &workspace) const {
|
||||||
|
for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
|
||||||
|
// We ignore all sub engines here because they are handled in the inner loop
|
||||||
|
if (!i->enable || isSubEngine(i->name, setup.engines) || i->subEngines.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string engineName;
|
||||||
|
std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
|
||||||
|
|
||||||
|
workspace << "set(SUB_ENGINES_" << engineName;
|
||||||
|
for (StringList::const_iterator j = i->subEngines.begin(), subEnd = i->subEngines.end(); j != subEnd; ++j) {
|
||||||
|
const EngineDesc &subEngine = findEngineDesc(*j, setup.engines);
|
||||||
|
if (!subEngine.enable) continue;
|
||||||
|
|
||||||
|
std::string subEngineName;
|
||||||
|
std::transform(j->begin(), j->end(), std::back_inserter(subEngineName), toupper);
|
||||||
|
|
||||||
|
workspace << " " << subEngineName;
|
||||||
|
}
|
||||||
|
workspace << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::createProjectFile(const std::string &name, const std::string &, const BuildSetup &setup, const std::string &moduleDir,
|
||||||
|
const StringList &includeList, const StringList &excludeList) {
|
||||||
|
|
||||||
|
const std::string projectFile = setup.outputDir + "/CMakeLists.txt";
|
||||||
|
std::ofstream project(projectFile.c_str(), std::ofstream::out | std::ofstream::app);
|
||||||
|
if (!project)
|
||||||
|
error("Could not open \"" + projectFile + "\" for writing");
|
||||||
|
|
||||||
|
if (name == setup.projectName) {
|
||||||
|
project << "add_executable(" << name << "\n";
|
||||||
|
} else {
|
||||||
|
std::string engineName;
|
||||||
|
std::transform(name.begin(), name.end(), std::back_inserter(engineName), toupper);
|
||||||
|
|
||||||
|
project << "if (ENABLE_" << engineName << ")\n";
|
||||||
|
project << "add_library(" << name << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string modulePath;
|
||||||
|
if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) {
|
||||||
|
modulePath = moduleDir.substr(setup.srcDir.size());
|
||||||
|
if (!modulePath.empty() && modulePath.at(0) == '/')
|
||||||
|
modulePath.erase(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modulePath.size())
|
||||||
|
addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath);
|
||||||
|
else
|
||||||
|
addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix);
|
||||||
|
|
||||||
|
|
||||||
|
project << ")\n";
|
||||||
|
if (name != setup.projectName) {
|
||||||
|
project << "endif()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
project << "# Libraries\n";
|
||||||
|
if (name == setup.projectName) {
|
||||||
|
const Library *sdlLibrary = getLibraryFromFeature(setup.useSDL2 ? "sdl2" : "sdl");
|
||||||
|
project << "target_link_libraries(" << name << " ${" << sdlLibrary->librariesVar << "})\n";
|
||||||
|
|
||||||
|
for (FeatureList::const_iterator i = setup.features.begin(), end = setup.features.end(); i != end; ++i) {
|
||||||
|
if (!i->enable || featureExcluded(i->name)) continue;
|
||||||
|
|
||||||
|
const Library *library = getLibraryFromFeature(i->name);
|
||||||
|
if (!library) continue;
|
||||||
|
|
||||||
|
if (library->librariesVar) {
|
||||||
|
project << "target_link_libraries(" << name << " ${" << library->librariesVar << "})\n";
|
||||||
|
} else {
|
||||||
|
project << "target_link_libraries(" << name << " " << library->libraries << ")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project << "if (WIN32)\n";
|
||||||
|
project << " target_sources(" << name << " PUBLIC dists/" << name << ".rc)\n";
|
||||||
|
project << " target_link_libraries(" << name << " winmm)\n";
|
||||||
|
project << "endif()\n";
|
||||||
|
project << "\n";
|
||||||
|
|
||||||
|
project << "# Engines libraries handling\n";
|
||||||
|
writeEnginesLibrariesHandling(setup, project);
|
||||||
|
|
||||||
|
project << "set_property(TARGET " << name << " PROPERTY CXX_STANDARD 11)\n";
|
||||||
|
project << "set_property(TARGET " << name << " PROPERTY CXX_STANDARD_REQUIRED ON)\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeWarnings(std::ofstream &output) const {
|
||||||
|
output << "SET (CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}";
|
||||||
|
for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) {
|
||||||
|
output << " " << *i;
|
||||||
|
}
|
||||||
|
output << "\")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeDefines(const BuildSetup &setup, std::ofstream &output) const {
|
||||||
|
output << "if (WIN32)\n";
|
||||||
|
output << " add_definitions(-DWIN32)\n";
|
||||||
|
output << "else()\n";
|
||||||
|
output << " add_definitions(-DPOSIX)\n";
|
||||||
|
output << "endif()\n";
|
||||||
|
|
||||||
|
output << "if (CMAKE_SIZEOF_VOID_P MATCHES 8)\n";
|
||||||
|
output << " add_definitions(-DSCUMM_64BITS)\n";
|
||||||
|
output << "endif()\n";
|
||||||
|
|
||||||
|
output << "add_definitions(-DSDL_BACKEND)\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
|
||||||
|
const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) {
|
||||||
|
|
||||||
|
for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) {
|
||||||
|
const FileNode *node = *i;
|
||||||
|
|
||||||
|
if (!node->children.empty()) {
|
||||||
|
writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/');
|
||||||
|
} else {
|
||||||
|
std::string name, ext;
|
||||||
|
splitFilename(node->name, name, ext);
|
||||||
|
projectFile << "\t" << filePrefix + node->name << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CMakeProvider::getProjectExtension() {
|
||||||
|
return ".txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeEngineOptions(std::ofstream &workspace) const {
|
||||||
|
workspace << "foreach(ENGINE IN LISTS ENGINES)\n";
|
||||||
|
workspace << " OPTION(ENABLE_${ENGINE} \"Enable ${ENGINE}\" ON)\n";
|
||||||
|
workspace << "endforeach(ENGINE)\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeGeneratePluginsTable(std::ofstream &workspace) const {
|
||||||
|
workspace << "file(REMOVE \"engines/plugins_table.h\")\n";
|
||||||
|
workspace << "file(APPEND \"engines/plugins_table.h\" \"/* This file is automatically generated by CMake */\\n\")\n";
|
||||||
|
workspace << "foreach(ENGINE IN LISTS ENGINES)\n";
|
||||||
|
workspace << " if (ENABLE_${ENGINE})\n";
|
||||||
|
workspace << " file(APPEND \"engines/plugins_table.h\" \"#if PLUGIN_ENABLED_STATIC(${ENGINE})\\n\")\n";
|
||||||
|
workspace << " file(APPEND \"engines/plugins_table.h\" \"LINK_PLUGIN(${ENGINE})\\n\")\n";
|
||||||
|
workspace << " file(APPEND \"engines/plugins_table.h\" \"#endif\\n\")\n";
|
||||||
|
workspace << " endif()\n";
|
||||||
|
workspace << "endforeach()\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeEnginesLibrariesHandling(const BuildSetup &setup, std::ofstream &workspace) const {
|
||||||
|
workspace << "foreach(ENGINE IN LISTS ENGINES)\n";
|
||||||
|
workspace << " if (ENABLE_${ENGINE})\n";
|
||||||
|
workspace << " string(TOLOWER ${ENGINE} ENGINE_LIB)\n\n";
|
||||||
|
workspace << " # Enable C++11\n";
|
||||||
|
workspace << " set_property(TARGET ${ENGINE_LIB} PROPERTY CXX_STANDARD 11)\n";
|
||||||
|
workspace << " set_property(TARGET ${ENGINE_LIB} PROPERTY CXX_STANDARD_REQUIRED ON)\n\n";
|
||||||
|
workspace << " # Link against the engine\n";
|
||||||
|
workspace << " target_link_libraries("<< setup.projectName <<" ${ENGINE_LIB})\n";
|
||||||
|
workspace << " endif()\n";
|
||||||
|
workspace << "endforeach()\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeProvider::writeEngineDefinitions(std::ofstream &workspace) const {
|
||||||
|
workspace << "foreach(ENGINE IN LISTS ENGINES)\n";
|
||||||
|
workspace << " if (ENABLE_${ENGINE})\n";
|
||||||
|
workspace << " add_definitions(-DENABLE_${ENGINE})\n";
|
||||||
|
workspace << " foreach(SUB_ENGINE IN LISTS SUB_ENGINES_${ENGINE})\n";
|
||||||
|
workspace << " add_definitions(-DENABLE_${SUB_ENGINE})\n";;
|
||||||
|
workspace << " endforeach(SUB_ENGINE)\n";
|
||||||
|
workspace << " endif()\n";
|
||||||
|
workspace << "endforeach()\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMakeProvider::featureExcluded(const char *name) const {
|
||||||
|
return std::strcmp(name, "nasm") == 0 ||
|
||||||
|
std::strcmp(name, "updates") == 0 ; // NASM is not supported for now
|
||||||
|
}
|
||||||
|
|
||||||
|
const EngineDesc &CMakeProvider::findEngineDesc(const std::string &name, const EngineDescList &engines) const {
|
||||||
|
for (EngineDescList::const_iterator i = engines.begin(), end = engines.end(); i != end; ++i) {
|
||||||
|
if (i->name == name) {
|
||||||
|
return *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
error("Unable to find requested engine");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of CreateProjectTool namespace
|
85
devtools/create_project/cmake.h
Normal file
85
devtools/create_project/cmake.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TOOLS_CREATE_PROJECT_CMAKE_H
|
||||||
|
#define TOOLS_CREATE_PROJECT_CMAKE_H
|
||||||
|
|
||||||
|
#include "create_project.h"
|
||||||
|
|
||||||
|
namespace CreateProjectTool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ProjectProvider used to generate CMake project descriptions
|
||||||
|
*
|
||||||
|
* Generated CMake projects are minimal, and will only work with GCC.
|
||||||
|
*/
|
||||||
|
class CMakeProvider : public ProjectProvider {
|
||||||
|
public:
|
||||||
|
CMakeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void createWorkspace(const BuildSetup &setup);
|
||||||
|
|
||||||
|
void createOtherBuildFiles(const BuildSetup &) {}
|
||||||
|
|
||||||
|
void addResourceFiles(const BuildSetup &setup, StringList &includeList, StringList &excludeList) {}
|
||||||
|
|
||||||
|
void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir,
|
||||||
|
const StringList &includeList, const StringList &excludeList);
|
||||||
|
|
||||||
|
void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation,
|
||||||
|
const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix);
|
||||||
|
|
||||||
|
const char *getProjectExtension();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* CMake properties for a library required by a feature
|
||||||
|
*/
|
||||||
|
struct Library {
|
||||||
|
const char *feature;
|
||||||
|
const char *module;
|
||||||
|
const char *package;
|
||||||
|
const char *includesVar;
|
||||||
|
const char *librariesVar;
|
||||||
|
const char *libraries;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Library *getLibraryFromFeature(const char *feature) const;
|
||||||
|
|
||||||
|
void writeWarnings(std::ofstream &output) const;
|
||||||
|
void writeDefines(const BuildSetup &setup, std::ofstream &output) const;
|
||||||
|
void writeEngines(const BuildSetup &setup, std::ofstream &workspace) const;
|
||||||
|
void writeSubEngines(const BuildSetup &setup, std::ofstream &workspace) const;
|
||||||
|
void writeEngineOptions(std::ofstream &workspace) const;
|
||||||
|
void writeGeneratePluginsTable(std::ofstream &workspace) const;
|
||||||
|
void writeEnginesLibrariesHandling(const BuildSetup &setup, std::ofstream &workspace) const;
|
||||||
|
void writeEngineDefinitions(std::ofstream &workspace) const;
|
||||||
|
void writeFeatureLibSearch(std::ofstream &workspace, const char *feature) const;
|
||||||
|
bool featureExcluded(const char *name) const;
|
||||||
|
const EngineDesc &findEngineDesc(const std::string &name, const EngineDescList &engines) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of CreateProjectTool namespace
|
||||||
|
|
||||||
|
#endif // TOOLS_CREATE_PROJECT_CMAKE_H
|
23
devtools/create_project/cmake/CMakeLists.txt
Normal file
23
devtools/create_project/cmake/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
project(create_project)
|
||||||
|
|
||||||
|
|
||||||
|
set(SOURCE_FILES
|
||||||
|
../cmake.cpp
|
||||||
|
../cmake.h
|
||||||
|
../codeblocks.cpp
|
||||||
|
../codeblocks.h
|
||||||
|
../create_project.cpp
|
||||||
|
../create_project.h
|
||||||
|
../msbuild.cpp
|
||||||
|
../msbuild.h
|
||||||
|
../msvc.cpp
|
||||||
|
../msvc.h
|
||||||
|
../visualstudio.cpp
|
||||||
|
../visualstudio.h
|
||||||
|
../xcode.cpp
|
||||||
|
../xcode.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(create_project ${SOURCE_FILES})
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "create_project.h"
|
#include "create_project.h"
|
||||||
|
|
||||||
|
#include "cmake.h"
|
||||||
#include "codeblocks.h"
|
#include "codeblocks.h"
|
||||||
#include "msvc.h"
|
#include "msvc.h"
|
||||||
#include "visualstudio.h"
|
#include "visualstudio.h"
|
||||||
|
@ -53,7 +54,7 @@
|
||||||
#define USE_WIN32_API
|
#define USE_WIN32_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WIN32_API
|
#if (defined(_WIN32) || defined(WIN32))
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -83,10 +84,18 @@ std::string unifyPath(const std::string &path);
|
||||||
* @param exe Name of the executable.
|
* @param exe Name of the executable.
|
||||||
*/
|
*/
|
||||||
void displayHelp(const char *exe);
|
void displayHelp(const char *exe);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a list of options to enable or disable GCC warnings
|
||||||
|
*
|
||||||
|
* @param globalWarnings Resulting list of warnings
|
||||||
|
*/
|
||||||
|
void addGCCWarnings(StringList &globalWarnings);
|
||||||
} // End of anonymous namespace
|
} // End of anonymous namespace
|
||||||
|
|
||||||
enum ProjectType {
|
enum ProjectType {
|
||||||
kProjectNone,
|
kProjectNone,
|
||||||
|
kProjectCMake,
|
||||||
kProjectCodeBlocks,
|
kProjectCodeBlocks,
|
||||||
kProjectMSVC,
|
kProjectMSVC,
|
||||||
kProjectXcode
|
kProjectXcode
|
||||||
|
@ -125,7 +134,6 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
ProjectType projectType = kProjectNone;
|
ProjectType projectType = kProjectNone;
|
||||||
int msvcVersion = 12;
|
int msvcVersion = 12;
|
||||||
bool useSDL2 = false;
|
|
||||||
|
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
@ -142,6 +150,14 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
} else if (!std::strcmp(argv[i], "--cmake")) {
|
||||||
|
if (projectType != kProjectNone) {
|
||||||
|
std::cerr << "ERROR: You cannot pass more than one project type!\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
projectType = kProjectCMake;
|
||||||
|
|
||||||
} else if (!std::strcmp(argv[i], "--codeblocks")) {
|
} else if (!std::strcmp(argv[i], "--codeblocks")) {
|
||||||
if (projectType != kProjectNone) {
|
if (projectType != kProjectNone) {
|
||||||
std::cerr << "ERROR: You cannot pass more than one project type!\n";
|
std::cerr << "ERROR: You cannot pass more than one project type!\n";
|
||||||
|
@ -269,7 +285,7 @@ int main(int argc, char *argv[]) {
|
||||||
} else if (!std::strcmp(argv[i], "--tests")) {
|
} else if (!std::strcmp(argv[i], "--tests")) {
|
||||||
setup.tests = true;
|
setup.tests = true;
|
||||||
} else if (!std::strcmp(argv[i], "--sdl2")) {
|
} else if (!std::strcmp(argv[i], "--sdl2")) {
|
||||||
useSDL2 = true;
|
setup.useSDL2 = true;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n";
|
std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -335,10 +351,7 @@ int main(int argc, char *argv[]) {
|
||||||
StringList featureDefines = getFeatureDefines(setup.features);
|
StringList featureDefines = getFeatureDefines(setup.features);
|
||||||
setup.defines.splice(setup.defines.begin(), featureDefines);
|
setup.defines.splice(setup.defines.begin(), featureDefines);
|
||||||
|
|
||||||
// Windows only has support for the SDL backend, so we hardcode it here (along with winmm)
|
if (projectType == kProjectXcode) {
|
||||||
if (projectType != kProjectXcode) {
|
|
||||||
setup.defines.push_back("WIN32");
|
|
||||||
} else {
|
|
||||||
setup.defines.push_back("POSIX");
|
setup.defines.push_back("POSIX");
|
||||||
// Define both MACOSX, and IPHONE, but only one of them will be associated to the
|
// Define both MACOSX, and IPHONE, but only one of them will be associated to the
|
||||||
// correct target by the Xcode project provider.
|
// correct target by the Xcode project provider.
|
||||||
|
@ -347,13 +360,42 @@ int main(int argc, char *argv[]) {
|
||||||
// the files, according to the target.
|
// the files, according to the target.
|
||||||
setup.defines.push_back("MACOSX");
|
setup.defines.push_back("MACOSX");
|
||||||
setup.defines.push_back("IPHONE");
|
setup.defines.push_back("IPHONE");
|
||||||
|
} else if (projectType == kProjectMSVC || projectType == kProjectCodeBlocks) {
|
||||||
|
// Windows only has support for the SDL backend, so we hardcode it here (along with winmm)
|
||||||
|
setup.defines.push_back("WIN32");
|
||||||
|
} else {
|
||||||
|
// As a last resort, select the backend files to build based on the platform used to build create_project.
|
||||||
|
// This is broken when cross compiling.
|
||||||
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
|
setup.defines.push_back("WIN32");
|
||||||
|
#else
|
||||||
|
setup.defines.push_back("POSIX");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool updatesEnabled = false;
|
||||||
|
for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) {
|
||||||
|
if (i->enable && !strcmp(i->name, "updates"))
|
||||||
|
updatesEnabled = true;
|
||||||
|
}
|
||||||
|
if (updatesEnabled) {
|
||||||
|
setup.defines.push_back("USE_SPARKLE");
|
||||||
|
if (projectType != kProjectXcode)
|
||||||
|
setup.libraries.push_back("winsparkle");
|
||||||
|
else
|
||||||
|
setup.libraries.push_back("sparkle");
|
||||||
|
}
|
||||||
|
|
||||||
setup.defines.push_back("SDL_BACKEND");
|
setup.defines.push_back("SDL_BACKEND");
|
||||||
if (!useSDL2) {
|
if (!setup.useSDL2) {
|
||||||
cout << "\nLinking to SDL 1.2\n\n";
|
cout << "\nBuilding against SDL 1.2\n\n";
|
||||||
setup.libraries.push_back("sdl");
|
setup.libraries.push_back("sdl");
|
||||||
} else {
|
} else {
|
||||||
cout << "\nLinking to SDL 2.0\n\n";
|
cout << "\nBuilding against SDL 2.0\n\n";
|
||||||
|
// TODO: This also defines USE_SDL2 in the preprocessor, we don't do
|
||||||
|
// this in our configure/make based build system. Adapt create_project
|
||||||
|
// to replicate this behavior.
|
||||||
|
setup.defines.push_back("USE_SDL2");
|
||||||
setup.libraries.push_back("sdl2");
|
setup.libraries.push_back("sdl2");
|
||||||
}
|
}
|
||||||
setup.libraries.push_back("winmm");
|
setup.libraries.push_back("winmm");
|
||||||
|
@ -380,49 +422,25 @@ int main(int argc, char *argv[]) {
|
||||||
std::cerr << "ERROR: No project type has been specified!\n";
|
std::cerr << "ERROR: No project type has been specified!\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
case kProjectCMake:
|
||||||
|
if (setup.devTools || setup.tests) {
|
||||||
|
std::cerr << "ERROR: Building tools or tests is not supported for the CMake project type!\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addGCCWarnings(globalWarnings);
|
||||||
|
|
||||||
|
provider = new CreateProjectTool::CMakeProvider(globalWarnings, projectWarnings);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case kProjectCodeBlocks:
|
case kProjectCodeBlocks:
|
||||||
if (setup.devTools || setup.tests) {
|
if (setup.devTools || setup.tests) {
|
||||||
std::cerr << "ERROR: Building tools or tests is not supported for the CodeBlocks project type!\n";
|
std::cerr << "ERROR: Building tools or tests is not supported for the CodeBlocks project type!\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
addGCCWarnings(globalWarnings);
|
||||||
// Code::Blocks is using GCC behind the scenes, so we need to pass a list
|
|
||||||
// of options to enable or disable warnings
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// -Wall
|
|
||||||
// enable all warnings
|
|
||||||
//
|
|
||||||
// -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder
|
|
||||||
// disable annoying and not-so-useful warnings
|
|
||||||
//
|
|
||||||
// -Wpointer-arith -Wcast-qual -Wcast-align
|
|
||||||
// -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
|
|
||||||
// enable even more warnings...
|
|
||||||
//
|
|
||||||
// -fno-rtti -fno-exceptions -fcheck-new
|
|
||||||
// disable RTTI and exceptions, and enable checking of pointers returned
|
|
||||||
// by "new"
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
globalWarnings.push_back("-Wall");
|
|
||||||
globalWarnings.push_back("-Wno-long-long");
|
|
||||||
globalWarnings.push_back("-Wno-multichar");
|
|
||||||
globalWarnings.push_back("-Wno-unknown-pragmas");
|
|
||||||
globalWarnings.push_back("-Wno-reorder");
|
|
||||||
globalWarnings.push_back("-Wpointer-arith");
|
|
||||||
globalWarnings.push_back("-Wcast-qual");
|
|
||||||
globalWarnings.push_back("-Wcast-align");
|
|
||||||
globalWarnings.push_back("-Wshadow");
|
|
||||||
globalWarnings.push_back("-Wimplicit");
|
|
||||||
globalWarnings.push_back("-Wnon-virtual-dtor");
|
|
||||||
globalWarnings.push_back("-Wwrite-strings");
|
|
||||||
// The following are not warnings at all... We should consider adding them to
|
|
||||||
// a different list of parameters.
|
|
||||||
globalWarnings.push_back("-fno-exceptions");
|
|
||||||
globalWarnings.push_back("-fcheck-new");
|
|
||||||
|
|
||||||
provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings);
|
provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings);
|
||||||
|
|
||||||
|
@ -636,6 +654,7 @@ void displayHelp(const char *exe) {
|
||||||
" Additionally there are the following switches for changing various settings:\n"
|
" Additionally there are the following switches for changing various settings:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Project specific settings:\n"
|
"Project specific settings:\n"
|
||||||
|
" --cmake build CMake project files\n"
|
||||||
" --codeblocks build Code::Blocks project files\n"
|
" --codeblocks build Code::Blocks project files\n"
|
||||||
" --msvc build Visual Studio project files\n"
|
" --msvc build Visual Studio project files\n"
|
||||||
" --xcode build XCode project files\n"
|
" --xcode build XCode project files\n"
|
||||||
|
@ -690,6 +709,41 @@ void displayHelp(const char *exe) {
|
||||||
cout.setf(std::ios_base::right, std::ios_base::adjustfield);
|
cout.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addGCCWarnings(StringList &globalWarnings) {
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// -Wall
|
||||||
|
// enable all warnings
|
||||||
|
//
|
||||||
|
// -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder
|
||||||
|
// disable annoying and not-so-useful warnings
|
||||||
|
//
|
||||||
|
// -Wpointer-arith -Wcast-qual -Wcast-align
|
||||||
|
// -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
|
||||||
|
// enable even more warnings...
|
||||||
|
//
|
||||||
|
// -fno-exceptions -fcheck-new
|
||||||
|
// disable exceptions, and enable checking of pointers returned by "new"
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
globalWarnings.push_back("-Wall");
|
||||||
|
globalWarnings.push_back("-Wno-long-long");
|
||||||
|
globalWarnings.push_back("-Wno-multichar");
|
||||||
|
globalWarnings.push_back("-Wno-unknown-pragmas");
|
||||||
|
globalWarnings.push_back("-Wno-reorder");
|
||||||
|
globalWarnings.push_back("-Wpointer-arith");
|
||||||
|
globalWarnings.push_back("-Wcast-qual");
|
||||||
|
globalWarnings.push_back("-Wcast-align");
|
||||||
|
globalWarnings.push_back("-Wshadow");
|
||||||
|
globalWarnings.push_back("-Wnon-virtual-dtor");
|
||||||
|
globalWarnings.push_back("-Wwrite-strings");
|
||||||
|
// The following are not warnings at all... We should consider adding them to
|
||||||
|
// a different list of parameters.
|
||||||
|
globalWarnings.push_back("-fno-exceptions");
|
||||||
|
globalWarnings.push_back("-fcheck-new");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the configure.engine file of a given engine directory and return a
|
* Parse the configure.engine file of a given engine directory and return a
|
||||||
* list of all defined engines.
|
* list of all defined engines.
|
||||||
|
@ -937,12 +991,12 @@ const Feature s_features[] = {
|
||||||
// Libraries
|
// Libraries
|
||||||
{ "libz", "USE_ZLIB", "zlib", true, "zlib (compression) support" },
|
{ "libz", "USE_ZLIB", "zlib", true, "zlib (compression) support" },
|
||||||
{ "mad", "USE_MAD", "libmad", true, "libmad (MP3) support" },
|
{ "mad", "USE_MAD", "libmad", true, "libmad (MP3) support" },
|
||||||
{ "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", false, "Ogg Vorbis support" },
|
{ "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", false, "Ogg Vorbis support" }, // ResidualVM change
|
||||||
{ "flac", "USE_FLAC", "libFLAC_static win_utf8_io_static", false, "FLAC support" },
|
{ "flac", "USE_FLAC", "libFLAC_static win_utf8_io_static", false, "FLAC support" }, // ResidualVM change
|
||||||
{ "png", "USE_PNG", "libpng", false, "libpng support" },
|
{ "png", "USE_PNG", "libpng", false, "libpng support" },
|
||||||
{ "faad", "USE_FAAD", "libfaad", false, "AAC support" },
|
{ "faad", "USE_FAAD", "libfaad", false, "AAC support" },
|
||||||
{ "mpeg2", "USE_MPEG2", "libmpeg2", true, "MPEG-2 support" },
|
{ "mpeg2", "USE_MPEG2", "libmpeg2", true, "MPEG-2 support" }, // ResidualVM change
|
||||||
{ "theora", "USE_THEORADEC", "libtheora_static", false, "Theora decoding support" },
|
{ "theora", "USE_THEORADEC", "libtheora_static", false, "Theora decoding support" }, // ResidualVM change
|
||||||
{ "freetype", "USE_FREETYPE2", "freetype", true, "FreeType support" },
|
{ "freetype", "USE_FREETYPE2", "freetype", true, "FreeType support" },
|
||||||
{ "jpeg", "USE_JPEG", "jpeg-static", true, "libjpeg support" },
|
{ "jpeg", "USE_JPEG", "jpeg-static", true, "libjpeg support" },
|
||||||
{"fluidsynth", "USE_FLUIDSYNTH", "libfluidsynth", true, "FluidSynth support" },
|
{"fluidsynth", "USE_FLUIDSYNTH", "libfluidsynth", true, "FluidSynth support" },
|
||||||
|
@ -952,29 +1006,22 @@ const Feature s_features[] = {
|
||||||
{ "scalers", "USE_SCALERS", "", true, "Scalers" },
|
{ "scalers", "USE_SCALERS", "", true, "Scalers" },
|
||||||
{ "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" },
|
{ "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" },
|
||||||
{ "16bit", "USE_RGB_COLOR", "", true, "16bit color support" },
|
{ "16bit", "USE_RGB_COLOR", "", true, "16bit color support" },
|
||||||
{ "mt32emu", "USE_MT32EMU", "", false, "integrated MT-32 emulator" },
|
{ "mt32emu", "USE_MT32EMU", "", false, "integrated MT-32 emulator" }, // ResidualVM change
|
||||||
{ "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
|
{ "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
|
||||||
{ "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" },
|
{ "opengl", "USE_OPENGL", "", true, "OpenGL support" },
|
||||||
|
{ "opengles", "USE_GLES", "", true, "forced OpenGL ES mode" },
|
||||||
{ "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
|
{ "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
|
||||||
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
|
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
|
||||||
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
|
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
|
||||||
{ "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"},
|
{ "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"},
|
||||||
{ "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"},
|
{ "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"},
|
||||||
|
{ "updates", "USE_UPDATES", "", false, "Updates support"},
|
||||||
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there
|
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there
|
||||||
// is just no current way of properly detecting this...
|
// is just no current way of properly detecting this...
|
||||||
};
|
};
|
||||||
|
|
||||||
const Tool s_tools[] = {
|
const Tool s_tools[] = {
|
||||||
{ "create_drascula", true},
|
|
||||||
{ "create_hugo", true},
|
|
||||||
{ "create_kyradat", true},
|
|
||||||
{ "create_lure", true},
|
|
||||||
{ "create_neverhood", true},
|
|
||||||
{ "create_teenagent", true},
|
|
||||||
{ "create_tony", true},
|
|
||||||
{ "create_toon", true},
|
|
||||||
{ "create_translations", true},
|
{ "create_translations", true},
|
||||||
{ "qtable", true}
|
|
||||||
};
|
};
|
||||||
} // End of anonymous namespace
|
} // End of anonymous namespace
|
||||||
|
|
||||||
|
@ -1156,7 +1203,7 @@ bool compareNodes(const FileNode *l, const FileNode *r) {
|
||||||
|
|
||||||
FileList listDirectory(const std::string &dir) {
|
FileList listDirectory(const std::string &dir) {
|
||||||
FileList result;
|
FileList result;
|
||||||
#ifdef USE_WIN32_API
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
WIN32_FIND_DATA fileInformation;
|
WIN32_FIND_DATA fileInformation;
|
||||||
HANDLE fileHandle = FindFirstFile((dir + "/*").c_str(), &fileInformation);
|
HANDLE fileHandle = FindFirstFile((dir + "/*").c_str(), &fileInformation);
|
||||||
|
|
||||||
|
@ -1359,7 +1406,7 @@ void ProjectProvider::createProject(BuildSetup &setup) {
|
||||||
in.push_back(setup.srcDir + "/COPYING.FREEFONT");
|
in.push_back(setup.srcDir + "/COPYING.FREEFONT");
|
||||||
in.push_back(setup.srcDir + "/COPYRIGHT");
|
in.push_back(setup.srcDir + "/COPYRIGHT");
|
||||||
in.push_back(setup.srcDir + "/NEWS");
|
in.push_back(setup.srcDir + "/NEWS");
|
||||||
in.push_back(setup.srcDir + "/README.md");
|
in.push_back(setup.srcDir + "/README.md"); // ResidualVM change
|
||||||
in.push_back(setup.srcDir + "/TODO");
|
in.push_back(setup.srcDir + "/TODO");
|
||||||
|
|
||||||
// Create the main project file.
|
// Create the main project file.
|
||||||
|
|
|
@ -229,15 +229,17 @@ struct BuildSetup {
|
||||||
StringList testDirs; ///< List of all folders containing tests
|
StringList testDirs; ///< List of all folders containing tests
|
||||||
|
|
||||||
bool devTools; ///< Generate project files for the tools
|
bool devTools; ///< Generate project files for the tools
|
||||||
bool tests; ///< Generate project files for the tests
|
bool tests; ///< Generate project files for the tests
|
||||||
bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder
|
bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder
|
||||||
bool createInstaller; ///< Create NSIS installer after the build
|
bool createInstaller; ///< Create NSIS installer after the build
|
||||||
|
bool useSDL2; ///< Whether to use SDL2 or not.
|
||||||
|
|
||||||
BuildSetup() {
|
BuildSetup() {
|
||||||
devTools = false;
|
devTools = false;
|
||||||
tests = false;
|
tests = false;
|
||||||
runBuildEvents = false;
|
runBuildEvents = false;
|
||||||
createInstaller = false;
|
createInstaller = false;
|
||||||
|
useSDL2 = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
MODULE := devtools/create_project
|
MODULE := devtools/create_project
|
||||||
|
|
||||||
MODULE_OBJS := \
|
MODULE_OBJS := \
|
||||||
|
cmake.o \
|
||||||
create_project.o \
|
create_project.o \
|
||||||
codeblocks.o \
|
codeblocks.o \
|
||||||
msvc.o \
|
msvc.o \
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue