|
401
|
Developer / Technical / Re: The grumpy old programmer room
|
on: February 12, 2009, 01:31:41 AM
|
The fact that CodeWarrior projects are non-diffable binaries actually does seem like a horrible flaw, though.
You can use text project files with more recent versions of CodeWarrior - you have to turn this on in the preferences though, and I need to be in front of it to find out where that is. I'm a big Visual Studio fan, but I'm probably also the only person on my current project who doesn't hate CodeWarrior. The IDE is pretty weird but most things work, and the debugger is good. ProDG is bearable too but the 'every window is every other window all at once' user interface confuses me. I do remember disliking the .NET UI after VC6, but I've come round since - especially now that the C++ compiler is so much stronger than it was.
|
|
|
|
|
402
|
Developer / Technical / Re: opengl interface structuring
|
on: February 11, 2009, 01:10:46 PM
|
I guess I'm coming from habit on platforms (D3D, console) where there isn't an explicit IM API, so if you want that convenience you have to do it yourself. I guess you could call e.g. DrawPrimitiveUP on D3D, but I've found that API to be flaky on various part/driver combinations. The advice I got at the time from the hardware guys was to use vertex buffers. But you could use that as a first implementation and do the VB thing later (or never) if it worked for you. FWIW, here's my current vertex queue implementation. It uses the DISCARD_LOCK paradigm which lets the driver do the multi-buffering for you (they know whether the GPU has finished with a resource or not): void VertexQueue::DrawVertices( const void *vertices, Nat total_count, const Nat stride, const Nat type ) { // Point to the source vertex data. const Nat8 *pv = static_cast<const Nat8*>(vertices);
// Work these out once const Nat granularity = granularity_table[type]; const Nat restart = restart_table[type];
// While there are vertices to render... while ( total_count ) { // How many vertices left in the queue? Nat vertices_left = (queue_size - m_cursor) / stride;
// Which mode are we in? Nat mode = D3DLOCK_NOOVERWRITE;
// Is there space for the minimum number of vertices? if ( vertices_left < (granularity + restart) ) { // No: Reset cursor to start of queue and re-enter loop. m_cursor = 0;
// Change to discard mode mode = D3DLOCK_DISCARD;
// How many vertices left in the queue? vertices_left = queue_size / stride; }
// How many vertices in this pass? Nat count = total_count < vertices_left ? total_count : vertices_left;
// Account for granularity count -= count % granularity;
// Indicate that these vertices have been used total_count -= count;
// Lock the queue if ( m_vb ) { // Attempt to lock VB BYTE *data; if ( S_OK == m_vb->Lock( static_cast<DWORD>(m_cursor), static_cast<DWORD>(count * stride), reinterpret_cast<void**>(&data), static_cast<DWORD>(mode) ) ) { // Copy in data memcpy( data, pv, count * stride );
// Unlock them m_vb->Unlock();
// Apply them if ( S_OK == m_device.SetStreamSource( 0, m_vb, static_cast<UINT>(m_cursor), static_cast<UINT>(stride) ) ) { // How many primitives? const Nat primitive_count = count / granularity - restart;
// Render m_device.DrawPrimitive( static_cast<D3DPRIMITIVETYPE>(type), 0, static_cast<UINT>(primitive_count) ); }
// Update cursor m_cursor += count * stride; } }
// Advance pv pv += stride * count;
// Are there vertices left? if ( total_count ) { // Go back for a restart pv -= restart * stride; total_count += restart; } }
} // VertexQueue::DrawVertices
|
|
|
|
|
403
|
Developer / Technical / Re: The happy programmer room
|
on: February 11, 2009, 03:40:23 AM
|
Tempting... It lists DOS as a supported OS, and the Dos unit even supports interrupts! Regs.AX := MCGAMode; Intr(VideoInt, Regs); {put video into mcga 320*200*256 mode}
I'm getting closer with the TP6 version though - got the gameflow working by skipping some of the sprite loads, and fixed some more memory leaks.
|
|
|
|
|
404
|
Developer / Technical / Re: The happy programmer room
|
on: February 11, 2009, 02:48:34 AM
|
I'm happy: a while ago I recovered some art and code from 15-year-old floppy disks, but unfortunately I hadn't left the project (kind of a Wing Commander demake) in a working state. This evening I got it all in source control, installed DosBox and Turbo Pascal 6, and fixed the worst of the problems. I can now run the front end and in-game executables, but can't chain them together. It's quite tricky to debug since with the IDE running there isn't enough heap to run the game  Still, it was vintage bugfixing fun 
|
|
|
|
|
405
|
Developer / Technical / Re: opengl interface structuring
|
on: February 10, 2009, 05:20:17 PM
|
Using the glBegin/glEnd immediate mode imposes a lot of overhead, but I'd argue that immediate mode rendering is still a good paradigm for UI. You just need to roll your own front end and back it with vertex arrays or similar. The front end could look like glBegin/glVertex/glEnd, or something else. I favour something like: if ( Vertex *pv = renderer.Begin( 4 ) ) { *pv++ = ... // etc.
renderer.End( pv, QUADS ); }
Also good, implies a redundant memory copy but might be better for cache as well as simpler to follow: Vertex quad[4] = { ... }; renderer.DrawQuads( 1, quad );
It's up to your requirements how much back end caching you do though, and what level this happens at. For example, I've had good results buffering text output in terms of font glyphs and generating the quads when the font is Flushed. YMMV, but luckily if you have IM output going through your own front end you can change/optimise the backend later when you know more about what you need.
|
|
|
|
|
406
|
Developer / Technical / Re: Darkness in a 2D platformer
|
on: February 09, 2009, 02:45:15 AM
|
|
I agree with all the suggestions to just draw the black layer.
One tweak though - to avoid having to use a giant mask texture, just create your circular spotlight at roughly the size you want - maybe with a nice fade or whatever. Then set the texture address mode to CLAMP in both directions and draw a screen-size quad with the texture coordinates set to put the spot where you want it. That will handle the region outside the spot's circle nicely.
Multiple spotlights are harder since the blend is destructive. You could use multitexture or compose multiple masks into destination alpha (masking off colour) and then finally unmask colour and blend a black quad over the scene using the destination alpha as the key.
HTH,
Will
|
|
|
|
|
407
|
Community / Jams & Events / Re: Staying in SF
|
on: February 05, 2009, 12:14:48 AM
|
so be sure to ask for a room that lets you sleep.
Past experience suggest that jetlag will ensure I get plenty of sleep, regardless of room. It doesn't say exactly when in the day this will happen though...
|
|
|
|
|
408
|
Community / Jams & Events / Re: Staying in SF
|
on: February 04, 2009, 01:22:16 PM
|
|
I just booked a room at Hotel Union Square. I'm not 100% sure it's where I'll be staying since I'm supposed to be coming in on a booking with one of my clients, but they're taking their time and rooms are drying up...
Am I too old for the indie party?
|
|
|
|
|
409
|
Developer / Technical / Re: The happy programmer room
|
on: February 03, 2009, 04:11:10 PM
|
|
I use shaders a lot in my day job, but it's worth bearing in mind that you can do so much with old skool tech. Just single texture + configurable blend is a good start, and the register combiners on earlier cards are pretty flexible.
Shaders do make it cleaner though, by unifying all this stuff.
|
|
|
|
|
411
|
Developer / Business / Re: What's in a name - do you use your 'real name'?
|
on: January 27, 2009, 11:51:42 PM
|
My Quake name (now used for XBL/PSN) has been "TheManOfBronze" for a decade or so, but on forums I tend go by my real name. It's easier to remember, for one thing, but I do miss people yelling "look out Bronzey" and such in BF1942 
|
|
|
|
|
412
|
Developer / Technical / Re: Post your main function(s)
|
on: January 26, 2009, 12:36:54 PM
|
I don't think it's a function, at least not one you have to define, but it does the same thing as return x.
You're right, it's not a function, just a standard return statement. return(x); is the same as return x; The parentheses are part of the return value expression and basically have no effect when used here since there's no ambiguity in the order of evaluation that you need to resolve. Personally I'd stay away from the usage since it's confusing. 
|
|
|
|
|
413
|
Developer / Technical / Re: What 'installer' software to use?
|
on: January 22, 2009, 03:37:22 PM
|
Cool idea! So if there was such a bundler, TigBox would be much easier to implement since downloaded bundled games would just work and you could concentrate on the DB/download/community stuff. I guess there are two routes: 1) TigBox *becomes* the bundler runtime, and handles all the savegames and stuff. 2) TigBox takes advantage of a bundler which could also be used standalone. I prefer the latter since it's more modular, but I can see the first one might be easier. Cheers, Will
|
|
|
|
|
414
|
Developer / Technical / Re: What 'installer' software to use?
|
on: January 22, 2009, 02:27:47 PM
|
Here you go. It was 200K so I've trimmed various file lists and left the structure. IIRC I started with the wizard and then made changes to suit. It was useful to be able to use one script to service multiple SKUs - testing the installer, Russian vs. multilingual, and an OEM version with cut-down content. Note that we made sure to delete generated files (in our case the log) - this is the usual cause of uninstallers failing to clean up properly. Note also that MUI is the 'modern UI' plugin - this is probably all old hat now. ; Script generated by the HM NIS Edit Script Wizard.
; Define for testing (no content) install ; !define TEST_INSTALLER
; Compressor details !ifdef TEST_INSTALLER SetCompressor zlib !else SetCompressor lzma !endif
CRCCheck off
; MUI 1.67 compatible --------------------------------------------------------- !include "MUI.nsh"
; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
; Language Key !define MUI_LANGDLL_REGISTRY_ROOT "HKLM" !define MUI_LANGDLL_REGISTRY_KEY "Software\ZOO Digital Publishing\Powerdrome\" !define MUI_LANGDLL_REGISTRY_VALUENAME "Language"
; Project settings ----------------------------------------------------------
; File version !define MAJOR_VERSION 1 !define MINOR_VERSION 16
; Russian install vs. Global install. !define RUSSIAN_VERSION
; Leave out some content in OEM version ; !define OEM_VERSION
; HM NIS Edit Wizard helper defines !ifdef OEM_VERSION !define PRODUCT_NAME "Powerdrome OEM" !else !define PRODUCT_NAME "Powerdrome" !endif
!define PRODUCT_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" !define PRODUCT_PUBLISHER "ZOO Digital Publishing" !define PRODUCT_WEB_SITE "http://www.zoodigitalpublishing.com/" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Flux.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Powerdrome" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
VIProductVersion "${MAJOR_VERSION}.0.0.${MINOR_VERSION}" VIAddVersionKey "ProductName" "${PRODUCT_NAME}" VIAddVersionKey "Comments" "Installs Powerdrome" VIAddVersionKey "CompanyName" "Applied Atomics Ltd." VIAddVersionKey "FileDescription" "Powerdrome Installer" VIAddVersionKey "FileVersion" "${MAJOR_VERSION}.${MINOR_VERSION}" VIAddVersionKey "LegalCopyright" "Powerdrome © 2005 Applied Atomics Ltd. All rights reserved. © 2005 ZOO Digital Publishing Limited. ZOO Digital Publishing and the ZOO Digital Publishing logo are trademarks of ZOO Digital Publishing Limited, part of the ZOO Digital Group plc. All rights reserved. Uses Bink Video. © 1997-2005 by RAD Game Tools, Inc."
; Installer UI --------------------------------------------------------------------------
; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !insertmacro MUI_PAGE_LICENSE $(license) ; Where to install !insertmacro MUI_PAGE_DIRECTORY ; Start menu page var ICONS_GROUP !define MUI_STARTMENUPAGE_NODISABLE !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${PRODUCT_PUBLISHER}\${PRODUCT_NAME}" !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}" !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_RUN "$INSTDIR\Powerdrome.exe" !insertmacro MUI_PAGE_FINISH
; Uninstaller pages !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH
; Reserve files !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
!ifdef RUSSIAN_VERSION ; Russian language only !insertmacro MUI_LANGUAGE "Russian" !else !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "Italian" !insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "Spanish" !endif
; License data LicenseLangString license ${LANG_ENGLISH} e_license.txt LicenseLangString license ${LANG_FRENCH} f_license.txt LicenseLangString license ${LANG_ITALIAN} i_license.txt LicenseLangString license ${LANG_GERMAN} g_license.txt LicenseLangString license ${LANG_SPANISH} s_license.txt LicenseLangString license ${LANG_RUSSIAN} r_license.txt
; Reserve this file to make installer faster !insertmacro MUI_RESERVEFILE_LANGDLL
; Setup Function .onInit !insertmacro MUI_LANGDLL_DISPLAY FunctionEnd
; MUI end ------
Name "${PRODUCT_NAME}" OutFile "g:\pd_install\image\Setup.exe" InstallDir "$PROGRAMFILES\${PRODUCT_PUBLISHER}\${PRODUCT_NAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show ShowUnInstDetails show
Section "Game data" SEC01 SectionIn RO SetOutPath "$INSTDIR" SetOverwrite try
File "dbghelp.dll" File "binkw32.dll" File "FApp.dll" File "FCollide.dll" File "FConsole.dll" File "FCore.dll" File "FDiskDeviceWin32.dll" File "FExpression.dll" File "FFile.dll" File "FGraphics.dll" File "FGraphicsDeviceDX9.dll" File "FInput.dll" File "FInputDeviceDX8.dll" File "FLocale.dll" File "Flux.dll" File "Flux.exe" File "FMonitor.dll" File "FMovie.dll" File "FMovieDeviceBink.dll" File "FNetwork.dll" File "FNetworkDeviceDX8.dll" File "FParticle.dll" File "FPlatform.dll" File "FResource.dll" File "FResourceDLL.dll" File "FSceneGraph.dll" File "FSound.dll" File "FSoundDeviceDX9.dll" File "FStorage.dll" File "FStorageDeviceWin32.dll" File "FWindow.dll" File "FWindowDeviceWin32.dll" File "FXML.dll" File "license.txt" File "pClientOnlineManager.dll" File "pClientOnlineManagerWin32.dll" File "Powerdrome.dll" File "Powerdrome.exe" File "msvcp70.dll" File "msvcp60.dll" File "msvcr70.dll"
; When testing, leave out all the content !ifndef TEST_INSTALLER
SetOutPath "$INSTDIR\win32\ai" File "win32\ai\steering_function.fab" SetOutPath "$INSTDIR\win32\attract" File "win32\attract\acer-naim.fab"
... SNIP ...
SetOutPath "$INSTDIR\win32\audio" File "win32\audio\ai_blade_setup.fab" File "win32\audio\effects.fsb" File "win32\audio\effects.xwb" File "win32\audio\effects_im.xwb" File "win32\audio\gui.fsb" !ifdef RUSSIAN_VERSION File "win32\audio\gui_im_russian.xwb" !else File "win32\audio\gui_im.xwb" !endif File "win32\audio\music.fsb" File "win32\audio\music.xwb" File "win32\audio\player_blade_setup.fab" File "win32\audio\radio.fsb" !ifdef RUSSIAN_VERSION File "win32\audio\radio_russian.xwb" !else File "win32\audio\radio.xwb" !endif SetOutPath "$INSTDIR\win32\blades\barracuda" File "win32\blades\barracuda\barracuda_proxy.fab" File "win32\blades\barracuda\barracuda_sim.fab"
... SNIP ... ; Additional blades for full version !ifndef OEM_VERSION
SetOutPath "$INSTDIR\win32\blades\stingray" File "win32\blades\stingray\stingray_proxy.fab" File "win32\blades\stingray\stingray_sim.fab"
... SNIP ...
!endif
; These two icons needed for full and OEM version
SetOutPath "$INSTDIR\win32\gallery\thumbnails" File "win32\gallery\thumbnails\gal_records.fab" File "win32\gallery\thumbnails\gal_replays.fab" ; Gallery content for full version !ifndef OEM_VERSION
SetOutPath "$INSTDIR\win32\gallery\images\characters\Abel_Vorsch" File "win32\gallery\images\characters\Abel_Vorsch\abel_vorsh_01.fab"
... SNIP MANY MANY GALLERY FILES ...
SetOutPath "$INSTDIR\win32\gallery\thumbnails" File "win32\gallery\thumbnails\trailer.fab"
!endif SetOutPath "$INSTDIR\win32\graphics" File "win32\graphics\bums.dat" File "win32\graphics\effects_archive.fab"
SetOutPath "$INSTDIR\win32\graphics\fonts" !ifdef RUSSIAN_VERSION File "win32\graphics\fonts\agency_18_russian.fab" File "win32\graphics\fonts\agency_26_russian.fab" File "win32\graphics\fonts\arial_12_russian.fab" !else File "win32\graphics\fonts\agency_18.fab" File "win32\graphics\fonts\agency_26.fab" File "win32\graphics\fonts\arial_12.fab" !endif File "win32\graphics\fonts\onlineicons.fab"
... SNIP ... ; Standard tracks SetOutPath "$INSTDIR\win32\graphics\sfx\tracks\acer-naim" File "win32\graphics\sfx\tracks\acer-naim\crowd_resources.fab" File "win32\graphics\sfx\tracks\acer-naim\track_resources.fab"
... SNIPPAGE ... ; Full version tracks !ifndef OEM_VERSION
SetOutPath "$INSTDIR\win32\graphics\sfx\tracks\san-keiB" File "win32\graphics\sfx\tracks\san-keiB\crowd_resources.fab" File "win32\graphics\sfx\tracks\san-keiB\track_resources.fab"
... SNIP ...
!endif SetOutPath "$INSTDIR\win32\graphics\sfx" File "win32\graphics\sfx\vignette.fab" File "win32\graphics\sfx\water_droplet.fab" SetOutPath "$INSTDIR\win32\graphics" File "win32\graphics\tarmac_detail.fab" SetOutPath "$INSTDIR\win32" SetOutPath "$INSTDIR\win32\input\configured" SetOutPath "$INSTDIR\win32\input\default" SetOutPath "$INSTDIR\win32\structure" File "win32\structure\championship.xml" File "win32\structure\gallery.xml" SetOutPath "$INSTDIR\win32\text" File "win32\text\credits_english.txt" !ifdef RUSSIAN_VERSION File "win32\text\russian.csv" !else File "win32\text\english.csv" File "win32\text\french.csv" File "win32\text\German.csv" File "win32\text\Italian.csv" File "win32\text\Spanish.csv" !endif ; Standard tracks SetOutPath "$INSTDIR\win32\tracks\acer-naim" File "win32\tracks\acer-naim\acer-naim.fab" File "win32\tracks\acer-naim\tweaks.xml"
... SNIP ... ; Full version tracks !ifndef OEM_VERSION
SetOutPath "$INSTDIR\win32\tracks\san-keib" File "win32\tracks\san-keib\san-keib.fab" File "win32\tracks\san-keib\tweaks.xml"
... SNIP ...
!endif SetOutPath "$INSTDIR\win32" SetOutPath "$INSTDIR\win32\videos" File "win32\videos\zoo.bik" File "win32\videos\secint.bik" File "win32\videos\atomics.bik" File "win32\videos\gallery.bik" File "win32\videos\intro.bik" File "win32\videos\loop.bik" File "win32\videos\multiplay.bik" File "win32\videos\options.bik"
; End of installer test !endif
; Make savegame folder CreateDirectory $INSTDIR\saves ; Tell the launcher where the game is WriteRegStr HKLM "Software\ZOO Digital Publishing\Powerdrome\" "Install Path" $INSTDIR
; Shortcuts !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\$ICONS_GROUP" CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Powerdrome.lnk" "$INSTDIR\Powerdrome.exe" CreateShortCut "$DESKTOP\Powerdrome.lnk" "$INSTDIR\Powerdrome.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd
Section "Documentation" SEC02 SetOverwrite try
; Install documentation SetOutPath "$INSTDIR\manuals" CopyFiles /SILENT "$EXEDIR\manuals\*.pdf" "$INSTDIR\manuals" 512 ; Install readme files SetOutPath "$INSTDIR" !ifdef RUSSIAN_VERSION ; Text readme CopyFiles /SILENT "$EXEDIR\readme_r.txt" "$INSTDIR" 512 !else ; All HTML readmes CopyFiles /SILENT "$EXEDIR\readme*.html" "$INSTDIR" 512 !endif SectionEnd
Section "Updated files" SEC03 SetOverwrite try
; Install extra files from the disk image. Guess at a size. ; This will allow us to patch the installer without resubmitting it. SetOutPath "$INSTDIR" CopyFiles /SILENT "$EXEDIR\update\*.*" "$INSTDIR" 16384
SectionEnd
Section "DirectX 9.0c" SEC04 SetOverwrite try SetOutPath "$INSTDIR\directx" File "directx\*.*" ExecWait '"$INSTDIR\DirectX\dxsetup.exe"' SectionEnd
Section -AdditionalIcons SetOutPath $INSTDIR !insertmacro MUI_STARTMENU_WRITE_BEGIN Application WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd
Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\Flux.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\Flux.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
; Want to ensure we reboot on Win9x
; Need to reboot - easiest to set this for everything. SetRebootFlag true SectionEnd
; Section descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Install Powerdrome game files. (required)" !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Install the Powerdrome game manual in PDF format." !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "Install updated game files. (required)" !insertmacro MUI_DESCRIPTION_TEXT ${SEC04} "Install Microsoft DirectX 9.0c. We recommend leaving this option selected to ensure you have the correct DirectX version." !insertmacro MUI_FUNCTION_DESCRIPTION_END
Function un.onUninstSuccess HideWindow FunctionEnd
Function un.onInit ; Get language !insertmacro MUI_UNGETLANGUAGE FunctionEnd
Section Uninstall !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP Delete "$INSTDIR\${PRODUCT_NAME}.url" Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\dbghelp.dll" Delete "$INSTDIR\flux.log" Delete "$INSTDIR\win32\videos\acer-naimC.bik"
... SNIP ALL THE ASSETS ...
Delete "$INSTDIR\win32\attract\acer-naim.fab" Delete "$INSTDIR\win32\ai\steering_function.fab" Delete "$INSTDIR\Powerdrome.exe" Delete "$INSTDIR\Powerdrome.dll" Delete "$INSTDIR\pClientOnlineManagerWin32.dll" Delete "$INSTDIR\pClientOnlineManager.dll" Delete "$INSTDIR\license.txt" Delete "$INSTDIR\FXML.dll" Delete "$INSTDIR\FWindowDeviceWin32.dll" Delete "$INSTDIR\FWindow.dll" Delete "$INSTDIR\FStorageDeviceWin32.dll" Delete "$INSTDIR\FStorage.dll" Delete "$INSTDIR\FSoundDeviceDX9.dll" Delete "$INSTDIR\FSound.dll" Delete "$INSTDIR\FSceneGraph.dll" Delete "$INSTDIR\FResourceDLL.dll" Delete "$INSTDIR\FResource.dll" Delete "$INSTDIR\FPlatform.dll" Delete "$INSTDIR\FParticle.dll" Delete "$INSTDIR\FNetworkDeviceDX8.dll" Delete "$INSTDIR\FNetwork.dll" Delete "$INSTDIR\FMovieDeviceBink.dll" Delete "$INSTDIR\FMovie.dll" Delete "$INSTDIR\FMonitor.dll" Delete "$INSTDIR\Flux.exe" Delete "$INSTDIR\Flux.dll" Delete "$INSTDIR\FLocale.dll" Delete "$INSTDIR\FInputDeviceDX8.dll" Delete "$INSTDIR\FInput.dll" Delete "$INSTDIR\FGraphicsDeviceDX9.dll" Delete "$INSTDIR\FGraphics.dll" Delete "$INSTDIR\FFile.dll" Delete "$INSTDIR\FExpression.dll" Delete "$INSTDIR\FDiskDeviceWin32.dll" Delete "$INSTDIR\FCore.dll" Delete "$INSTDIR\FConsole.dll" Delete "$INSTDIR\FCollide.dll" Delete "$INSTDIR\FApp.dll" Delete "$INSTDIR\binkw32.dll" Delete "$INSTDIR\msvcp60.dll" Delete "$INSTDIR\msvcr70.dll" Delete "$INSTDIR\msvcp70.dll" Delete "$INSTDIR\win32\graphics\Video*.ini" Delete "$INSTDIR\readme_e.html" Delete "$INSTDIR\readme_f.html" Delete "$INSTDIR\readme_i.html" Delete "$INSTDIR\readme_g.html" Delete "$INSTDIR\readme_s.html" Delete "$INSTDIR\readme_n.html" Delete "$INSTDIR\readme_r.txt" Delete "$INSTDIR\manuals\*.pdf" Delete "$INSTDIR\directx\*.*"
Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" Delete "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" Delete "$DESKTOP\Powerdrome.lnk" Delete "$SMPROGRAMS\$ICONS_GROUP\Powerdrome.lnk" RmDir "$INSTDIR\manuals" RmDir "$INSTDIR\directx"
RMDir "$SMPROGRAMS\$ICONS_GROUP" RMDir "$INSTDIR\win32\videos"
... SNIP ALL THE FOLDERS ...
RMDir "$INSTDIR\win32" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" DeleteRegKey HKLM "Software\ZOO Digital Publishing\Powerdrome" SetAutoClose true SectionEnd
With scripted installers you have a lot of power to make things like upgrades, install-over-existing, etc. just work. You can check registry keys and follow different routes as necessary. Let me know if you have any questions. On the general install vs. folder topic, I thought I was on the side of installers but I'm starting to get persuaded. Properly supporting Vista makes it different again since you should then be writing your temporary files, savegames etc. to the appropriate folders. I wonder if there's scope for an Indie game packager which would bundle up an executable and assets into a single file you could double-click on? When run it could unpack to a temporary folder and run the game, then clean up afterwards. Handling created files and savegames would be interesting though... I know EXE packagers exist, but I'm not sure if they handle the "app creates data" problem gracefully. Cheers, Will
|
|
|
|
|
415
|
Developer / Technical / Re: What 'installer' software to use?
|
on: January 22, 2009, 01:24:57 PM
|
|
NSIS is great. I've used it and (and old version of) Wise on commercial projects and I think I'd stick with NSIS in the future.
I found that I had to delve into the scripting though - the generated installers didn't do enough. If there's interest I can dig out an example script for a game?
|
|
|
|
|
416
|
Developer / Technical / Re: The happy programmer room
|
on: January 22, 2009, 01:19:23 PM
|
|
If you're using Lua it may be worth giving it its own heap - there have been a few mentions on sweng-gamedev that it tends to allocate and free lots of small, odd sized memory chunks leading to fragmentation over time.
|
|
|
|
|
417
|
Developer / Technical / Re: Post your main function(s)
|
on: January 21, 2009, 05:26:22 PM
|
Great idea for a thread! A railway modelling forum I like had a similar one recently where we posted pictures of our workbenches - so much clutter! Here's WinMain from Space Effort. I'm trying to get out of the habit of making obvious comments but it's so ingrained that I'm not having much success yet: /** * Application entrypoint. Configure SIL and kick off the mainloop. */ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { // Configure window graphics::Window::Options options; options.width = 640; options.height = 480; options.resizeable = false; options.title = SIL_LITERAL("Space Effort");
// Set it up. graphics::Window window; if ( window.Initialise( options ) ) { // Create device graphics::Device::Options options; options.max_renderers = 1; options.max_targets = 4; options.max_textures = 256; g_device = new graphics::Device(window); if ( g_device && g_device->Initialise( options ) ) { // Create renderer on the device if ( g_renderer = g_device->CreateRenderer() ) { // Initialise game g_resources = new Resources; if ( g_resources->Initialise() ) { // Execute game game_loop( window );
// Terminate game g_resources->Terminate(); }
// Clean up g_renderer->Delete(); g_renderer = NULL; } }
g_device->Terminate(); SIL_DELETE(g_device); }
return 0;
} // main The gameloop may also be of interest - it's in the same file. Pretty clunky, and uses a Screen abstraction as seen earlier in this thread: /** * Run the main game loop. */ static void game_loop( graphics::Window& window ) { // First frame Frame frame; Zero( frame );
// Hook mouse callback DXUTSetCallbackMouse( &mouse_callback, true );
// Create the world! const Galaxy galaxy(GALAXY_SEED); // Selected system const Galaxy::System *old_packed_system = NULL; const Galaxy::System *packed_system = NULL; const System::Body *packed_planet = NULL;
// Current system and planet (if any) System system(galaxy.systems[0]); Planet planet;
// The player Player player;
// HACK: Start new game player.Reset();
// Create screens IScreen *screens[SCREEN_COUNT] = { NULL, new BootScreen, new TitleScreen, new GalaxyMapScreen(galaxy, packed_system, player), // new SystemMapScreen(system, packed_planet), new PlanetMapScreen(planet, player), new OutdoorScreen(planet, player), };
// Allocate rendertarget graphics::Texture *target = g_device->CreateTarget( 320, 240 );
// Initialise screens for ( int i = 1; i < SCREEN_COUNT; ++i ) { if ( screens[i] ) screens[i]->Initialise(); }
// Start with active boot screen EScreen current_screen = BOOT_SCREEN; screens[current_screen]->Reset();
graphics::Texture *scanlines = g_device->CreateTexture( SIL_LITERAL("resources/raster.png") );
// While the window is open, update it. while ( window.Tick() ) { // If we have a screen... if ( screens[current_screen] ) { // Update frame frame.dt = DXUTGetElapsedTime();
// Don't allow really long frames - they mess things up. if ( frame.dt > 1.0f/20 ) frame.dt = 1.0f/20;
frame.time += frame.dt; ++frame.number;
// Update keys (HACK) update_button( frame.yoke.buttons[Yoke::SELECT], DXUTIsKeyDown( VK_RETURN ) ); update_button( frame.yoke.buttons[Yoke::CANCEL], DXUTIsKeyDown( VK_ESCAPE ) ); update_button( frame.yoke.buttons[Yoke::LEFT], DXUTIsKeyDown( VK_LEFT ) ); update_button( frame.yoke.buttons[Yoke::RIGHT], DXUTIsKeyDown( VK_RIGHT ) ); update_button( frame.yoke.buttons[Yoke::UP], DXUTIsKeyDown( VK_UP ) ); update_button( frame.yoke.buttons[Yoke::DOWN], DXUTIsKeyDown( VK_DOWN ) ); update_button( frame.yoke.buttons[Yoke::LMB], lmb ); update_button( frame.yoke.buttons[Yoke::RMB], rmb ); update_button( frame.yoke.buttons[Yoke::JETS], DXUTIsKeyDown( VK_SPACE ) );
// Update cursor frame.yoke.mouse_x = mouse_x; frame.yoke.mouse_y = mouse_y;
// Is this a big pixel screen? if ( target && screens[current_screen]->BigPixels() ) { // Scale input frame.yoke.mouse_x /= 2; frame.yoke.mouse_y /= 2; }
// Tick current screen const EScreen next_screen = screens[current_screen]->Tick( frame );
// Has the screen changed? if ( next_screen != current_screen ) { // If we're looking at a system on the map, unpack it on screen transition. if ( packed_system && packed_system != old_packed_system ) { system = System( *packed_system ); // Temp: Unpack planet. planet.Generate( system.bodies[0] );
old_packed_system = packed_system; }
// Change current_screen = next_screen;
// If we have one, wake it up. if ( screens[current_screen] ) { screens[current_screen]->Reset(); } else { // Otherwise, time to quit. window.Quit(); } } }
// If we still have a screen, draw it. if ( screens[current_screen] ) { if ( g_device->BeginFrame() ) { // For big pixel screens, capture to render target if ( target && screens[current_screen]->BigPixels() ) g_renderer->SetTarget( target );
// Normal drawing if ( g_renderer->BeginDrawing() ) { screens[current_screen]->Draw(); g_renderer->EndDrawing(); }
// For big pixel screens, copy render target over to double pixels if ( target && screens[current_screen]->BigPixels() ) { g_renderer->SetTarget( NULL );
if ( g_renderer->BeginDrawing() ) { // Draw the doubled pixels g_renderer->SetTexture( target ); graphics::DrawRectangle( *g_renderer, 0, 0, 640, 480 );
// Draw some scanlines with a mite of flicker. g_renderer->SetTexture( scanlines ); g_renderer->SetBlend( graphics::Renderer::ALPHA, graphics::Renderer::ONE_MINUS_ALPHA ); graphics::Colour black(0.0f, 0.0f, 0.0f); const Nat32 argb = black.ARGB(maths::Noise(frame.time * 3, 4) * 0.06f + 0.18f); graphics::DrawTiledRectangle( *g_renderer, 0, 0, 640, 480, *scanlines, argb ); g_renderer->EndDrawing(); } }
g_device->EndFrame(); } } }
// Destroy screens for ( int i = 0; i < SCREEN_COUNT; ++i ) { delete screens[i]; }
// Destroy target if ( target ) target->Delete();
} // game_loop
It's still pretty hacky, but I was in the middle of a big engine tidyup/rewrite and most of the things that should be there as standard were, well, not there. I've just started doing a bit more on the engine so maybe progress will be forthcoming this year... Cheers, Will
|
|
|
|
|
418
|
Community / Bootleg Demakes / Re: Bootleg Demakes: Voting!
|
on: October 06, 2008, 02:59:31 AM
|
O happy day, Space Effort got three votes! Congratulations all, lots of very deserving entries at the top end. (Regarding Effort, I intend to get some gameplay in there *soon* but I'm working on-site on a contract at the moment and it's keeping me pretty busy. Work work work but we all need a hedge against Global Economic Meltdown...) Will
|
|
|
|
|
420
|
Community / Bootleg Demakes / Re: [TECH DEMO 3] Space Effort
|
on: September 28, 2008, 12:35:29 PM
|
Cheers guys! I have some free time coming up in a couple of weeks, which means I might get to do some more work on Effort. I'll post here if/when that happens. The bootup sequence is so awesome. It goes so fast though, we're left with no time to appreciate it!  I see what you mean, but I think that for something like that you want it to be slightly too fast, in order to hide the joins and make people work to read the text if they're really keen. I've been meaning to put some Easter eggs into it - press F1 to continue, POST fail, etc. - but haven't got around to it. I should point out that I didn't waste my valuable compo time on the boot sequence, it was code I had lying around from a couple of years ago. Hope this isn't considered cheating. Also of note - it's all done with alpha blended tris, no shaders required. 
|
|
|
|
|