code:
:: slave creation widgets [widget nobr]

/%
 Call as <<StartingGirlsWorkaround>>
%/
<<widget "StartingGirlsWorkaround">>
	<<set $activeSlave = GenerateNewSlave()>>
	<<set $startingGirlCopied = 0>>
	<<set $activeSlave.health = 0>>
	<<set $activeSlave.devotion = 0>>
	<<set $activeSlave.trust = 0>>
	<<set $activeSlave.sexualQuirk = "none">>
	<<set $activeSlave.behavioralQuirk = "none">>
	<<set $activeSlave.fetishKnown = 1>>
	<<if $activeSlave.vagina < 0>>
		<<set $activeSlave.ovaries = 0>>
	<<elseif $activeSlave.vagina < 1>>
		<<set $activeSlave.skill.vaginal = 0>>
	<</if>>
	<<if $activeSlave.anus < 1>>
		<<set $activeSlave.skill.anal = 0>>
	<</if>>

	<<set $activeSlave.actualAge = Number($activeSlave.actualAge) || 18>>
	<<set $activeSlave.devotion = Number($activeSlave.devotion) || 0>>
	<<set $activeSlave.trust = Number($activeSlave.trust) || 0>>
	<<if $activeSlave.indenture >= 0>>
		<<set $activeSlave.indenture = Math.clamp($activeSlave.indenture, 26, 208) || 26>>
	<</if>>
	<<set $activeSlave.height = Math.clamp($activeSlave.height, 85, 274) || 140>>
	<<set $activeSlave.boobs = Math.clamp(Math.trunc($activeSlave.boobs/50)*50, 0, 50000) || 200>>
<</widget>>

/%
 Call as <<SaleDescription>>
%/
<<widget "SaleDescription">>
	<<replace #slaveinfo>>
		<<set $saleDescription = 1>>
		<<include "Long Slave Description">>
	<</replace>>
<</widget>>

<<widget "SlaveCostDescription">>
	<<set $slaveCost = startingSlaveCost($activeSlave)>>
	<<if $slaveCost > $cash>>
	@@.red;This slave will cost ''<<print cashFormat($slaveCost)>>.''

	You only have: <<print cashFormat($cash)>>@@
	<<else>>
	This slave will cost @@.yellowgreen;''<<print cashFormat($slaveCost)>>.''@@

	You have <<print cashFormat($cash)>>.
	<</if>>
<</widget>>
/%
 Call as <<StartingGirlsCost>>
%/
<<widget "StartingGirlsCost">>

<<replace "#cost">>
<<SlaveCostDescription>>
<</replace>>
<<if $cash >= $slaveCost>>
	<<set $activeSlave.actualAge = Number($activeSlave.actualAge) || 18>>
	<<set $activeSlave.devotion = Number($activeSlave.devotion) || 0>>
	<<set $activeSlave.trust = Number($activeSlave.trust) || 0>>
	<<if $activeSlave.indenture >= 0>>
		<<set $activeSlave.indenture = Math.clamp($activeSlave.indenture, 26, 208) || 26>>
	<</if>>
	<<set $activeSlave.height = Math.clamp($activeSlave.height, 85, 274) || 140>>
	<<set $activeSlave.boobs = Math.clamp(Math.trunc($activeSlave.boobs/50)*50, 0, 50000) || 200>>
	<<set $slaveWithoutBonuses = $activeSlave>>
	<<if $PC.career != "engineer">>

		<<link "Add this slave">>
			<<set $returnTo = "Commit Starting Girl", $createRelatedSlave = 0, $applyCareerBonus = 1, $careerBonusApplied = 0>>
			<<set $slaveCost = startingSlaveCost($activeSlave)>>
			<<run cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave)>>
			<<goto "RG AS Dump">>
		<</link>>
		//This will apply your @@.springgreen;career bonus@@ to $him:
		<<if $PC.career == "capitalist">>
			one free level of @@.cyan;prostitution skill.@@
		<<elseif $PC.career == "mercenary">>
			@@.mediumaquamarine;+10 trust.@@
		<<elseif $PC.career == "slaver">>
			@@.hotpink;+10 devotion.@@
		<<elseif $PC.career == "medicine">>
			free @@.lime;basic implants.@@
		<<elseif $PC.career == "celebrity">>
			one free level of @@.cyan;entertainment skill.@@
		<<elseif $PC.career == "gang">>
			@@.green;+5 health@@ and a free level of @@.cyan;combat skill@@
		<<elseif $PC.career == "escort">>
			two free levels of @@.cyan;sex skills,@@ one free level of @@.cyan;prostitution skill,@@ and one free level of @@.cyan;entertainment skill.@@
		<<elseif $PC.career == "servant">>
			@@.mediumaquamarine;+10 trust@@ and @@.hotpink;+10 devotion.@@
		<<elseif $PC.career == "wealth">>
			two free levels of @@.cyan;sex skills.@@
		<<elseif $PC.career == "BlackHat">>
			one free level of @@.cyan;intelligence.@@
		<<else>>
			@@.hotpink;+10 devotion,@@ one free level of @@.cyan;prostitution skill@@ and @@.cyan;entertainment skill,@@ and two free levels of @@.cyan;sex skills.@@
		<</if>>//

		<<link "Add slave without career bonus">>
			<<set $returnTo = "Commit Starting Girl", $createRelatedSlave = 0, $applyCareerBonus = 0, $careerBonusApplied = 0>>
			<<set $slaveCost = startingSlaveCost($activeSlave)>>
			<<run cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave)>>
			<<goto "RG AS Dump">>
		<</link>>
	<<else>>

		<<link "Add slave">>
			<<set $returnTo = "Commit Starting Girl", $createRelatedSlave = 0, $applyCareerBonus = 0, $careerBonusApplied = 0>>
			<<set $slaveCost = startingSlaveCost($activeSlave)>>
			<<run cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave)>>
			<<goto "RG AS Dump">>
		<</link>>

	<</if>>
<<else>>

//You lack the necessary funds to add this slave.//
<</if>>

[[Discard this slave and continue|Acquisition]]
<</widget>>

/%
 Call as <<CustomSlaveAge>>
%/
<<widget "CustomSlaveAge">>
	<<replace #age>>
		<<if $customSlave.age < 3>>2- years old.
		<<elseif $customSlave.age < 5>>3-4 years old.
		<<elseif $customSlave.age < 7>>5-6 years old.
		<<elseif $customSlave.age < 10>>7-9 years old.
		<<elseif $customSlave.age < 13>>10-12 years old.
		<<elseif $customSlave.age < 15>>13-14 years old.
		<<elseif $customSlave.age < 18>>15-17 years old.
		<<elseif $customSlave.age < 20>>18-19 years old.
		<<elseif $customSlave.age < 25 && $retirementAge >= 25>>20-24 years old.
		<<elseif $customSlave.age < 25 && $retirementAge >= 20>>20+ years old.
		<<elseif $customSlave.age < 30 && $retirementAge >= 30>>25-29 years old.
		<<elseif $customSlave.age < 30 && $retirementAge >= 25>>25+ years old.
		<<elseif $customSlave.age < 40 && $retirementAge >= 40>>30-39 years old.
		<<elseif $customSlave.age < 40 && $retirementAge >= 30>>30+ years old.
		<<elseif $customSlave.age < 50 && $retirementAge >= 50>>40-49 years old.
		<<elseif $customSlave.age < 50 && $retirementAge >= 40>>40+ years old.
		<<elseif $customSlave.age < 60 && $retirementAge >= 60>>50-59 years old.
		<<elseif $customSlave.age < 60 && $retirementAge >= 50>>50+ years old.
		<<elseif $customSlave.age < 70 && $retirementAge >= 70>>60-69 years old.
		<<elseif $customSlave.age < 70 && $retirementAge >= 60>>60+ years old.
		<<elseif $customSlave.age < 80 && $retirementAge >= 80>>70-79 years old.
		<<elseif $customSlave.age < 80 && $retirementAge >= 70>>70+ years old.
		<<elseif $customSlave.age < 90 && $retirementAge >= 90>>80-89 years old.
		<<elseif $customSlave.age < 90 && $retirementAge >= 80>>80+ years old.
		<<elseif $customSlave.age < 100 && $retirementAge >= 100>>90-99 years old.
		<<elseif $customSlave.age < 100 && $retirementAge >= 90>>90+ years old.
		<<elseif $customSlave.age < 110 && $retirementAge >= 110>>100-109 years old.
		<<elseif $customSlave.age < 110 && $retirementAge >= 100>>100+ years old.
		<<elseif $customSlave.age < 120 && $retirementAge >= 120>>110-119 years old.
		<<elseif $customSlave.age < 120 && $retirementAge >= 110>>110+ years old.
		<<elseif $customSlave.age < 130 && $retirementAge >= 130>>120-129 years old.
		<<elseif $customSlave.age < 130 && $retirementAge >= 120>>120+ years old.
		<<else>>130+ years old.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveHealth>>
%/
<<widget "CustomSlaveHealth">>
	<<replace #health>>
		<<if $customSlave.health == 0>>Healthy.
		<<else>>Extremely healthy.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveMuscles>>
%/
<<widget "CustomSlaveMuscles">>
	<<replace #muscles>>
		<<if $customSlave.muscles > 95>>
			Ripped.
		<<elseif $customSlave.muscles > 50>>
			Muscular.
		<<elseif $customSlave.muscles > 30>>
			Well built.
		<<elseif $customSlave.muscles > 5>>
			Toned.
		<<elseif $customSlave.muscles > -6>>
			Soft.
		<<elseif $customSlave.muscles > -31>>
			Quite weak.
		<<elseif $customSlave.muscles > -51>>
			Rather weak.
		<<elseif $customSlave.muscles > -96>>
			Very weak.
		<<else>>
			Frail.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveLips>>
%/
<<widget "CustomSlaveLips">>
	<<replace #lips>>
		<<if $customSlave.lips <= 10>>Thin lips.
		<<elseif $customSlave.lips <= 20>>Normal lips.
		<<elseif $customSlave.lips <= 40>>Plush lips.
		<<elseif $customSlave.lips <= 70>>Big lips.
		<<elseif $customSlave.lips <= 95>>Huge lips.
		<<else>>Facepussy.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveVoice>>
%/
<<widget "CustomSlaveVoice">>
	<<replace #voice>>
		<<if $customSlave.voice == 3>>High, girly voice.
		<<elseif $customSlave.voice == 2>>Feminine voice.
		<<elseif $customSlave.voice == 1>>Deep voice.
		<<elseif $customSlave.voice == 0>>Mute.
		<<else>>Voice is unimportant.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveHeight>>
%/
<<widget "CustomSlaveHeight">>
	<<replace #height>>
		<<if $customSlave.heightMod == "greatly below average">>Petite.
		<<elseif $customSlave.heightMod == "below average">>Short.
		<<elseif $customSlave.heightMod == "normal">>Average height.
		<<elseif $customSlave.heightMod == "above average">>Tall.
		<<else>>Very tall.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveWeight>>
%/
<<widget "CustomSlaveWeight">>
	<<replace #weight>>
		<<if $customSlave.weight == -50>>Very thin.
		<<elseif $customSlave.weight == -15>>Thin.
		<<elseif $customSlave.weight == 0>>Average weight.
		<<elseif $customSlave.weight == 15>>Chubby.
		<<elseif $customSlave.weight == 50>>Plump.
		<<elseif $customSlave.weight == 100>>Fat.
		<<elseif $customSlave.weight == 150>>Very Fat.
		<<else>>Immobile.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveFace>>
%/
<<widget "CustomSlaveFace">>
	<<replace #face>>
		<<if $customSlave.face < -40>>Very unattractive face.
		<<elseif $customSlave.face < -10>>Unattractive face.
		<<elseif $customSlave.face <= 10>>Average face.
		<<elseif $customSlave.face <= 40>>Attractive face.
		<<elseif $customSlave.face > 40>>Very attractive face.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveRace>>
%/
<<widget "CustomSlaveRace">>
	<<replace #ethnicity>>
		<<textbox "$customSlave.race" $customSlave.race "Custom Slave">>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveSkin>>
%/
<<widget "CustomSlaveSkin">>
	<<replace #skin>>
		<<textbox "$customSlave.skin" $customSlave.skin "Custom Slave">>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveBoobs>>
%/
<<widget "CustomSlaveBoobs">>
	<<replace #boobs>>
		<<if $customSlave.boobs == 200>>Flat chest.
		<<elseif $customSlave.boobs <= 500>>Healthy breasts.
		<<elseif $customSlave.boobs <= 800>>Big breasts.
		<<elseif $customSlave.boobs <= 1400>>Huge breasts.
		<<elseif $customSlave.boobs <= 2100>>Giant breasts.
		<<else>>Massive breasts.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveButt>>
%/
<<widget "CustomSlaveButt">>
	<<replace #butt>>
		<<if $customSlave.butt == 1>>Flat buttocks.
		<<elseif $customSlave.butt < 4>>Healthy buttocks.
		<<elseif $customSlave.butt < 6>>Huge buttocks.
		<<else>>Massive buttocks.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveSex>>
%/
<<widget "CustomSlaveSex">>
	<<replace #sex>>
		<<if $customSlave.sex == 1>>Female (cock & balls options not applied).
		<<elseif $customSlave.sex == 2>>Male (pussy options not applied).
		<<else>>Futanari (clit options not applied).
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveVirgin>>
%/
<<widget "CustomSlaveVirgin">>
	<<replace #virgin>>
		<<if $customSlave.virgin == 0>>Vaginal virgin.
		<<else>>Virginity not important.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveVagina>>
%/
<<widget "CustomSlaveVagina">>
	<<replace #vagina>>
		<<if $customSlave.vagina == -1>>No vagina.
		<<elseif $customSlave.vagina == 0>>Vaginal virgin.
		<<else>>Normal vagina.
		<</if>>
		<<link "No vagina">>
			<<set $customSlave.vagina = -1, $customSlave.preg = 0, WombFlush($activeSlave), $customSlave.ovaries = 0>>
			<<CustomSlaveVagina>>
		<</link>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveDick>>
%/
<<widget "CustomSlaveDick">>
	<<replace #dick>>
		<<if $customSlave.dick == 0>>No penis.
		<<elseif $customSlave.dick == 2>>Small penis.
		<<else>>Large penis.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveBalls>>
%/
<<widget "CustomSlaveBalls">>
	<<replace #balls>>
		<<if $customSlave.balls == 0>>No testicles.
		<<elseif $customSlave.balls == 2>>Small testicles.
		<<elseif $customSlave.balls == 4>>Large testicles.
		<<else>>Huge Balls.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveClit>>
%/
<<widget "CustomSlaveClit">>
	<<replace #clit>>
		<<if $customSlave.clit == 0>>Normal clitoris.
		<<elseif $customSlave.clit == 1>>Big clitoris.
		<<elseif $customSlave.clit == 3>>Enormous clitoris.
		<<else>>Pseudophallus.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveLabia>>
%/
<<widget "CustomSlaveLabia">>
	<<replace #labia>>
		<<if $customSlave.labia == 0>>Normal labia.
		<<elseif $customSlave.labia == 1>>big labia.
		<<elseif $customSlave.labia == 2>>Huge labia.
		<<else>>Enormous labia.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveClitBalls>>
%/
<<widget "CustomSlaveClitBalls">>
	<<replace #clitballs>>
	<<if $customSlave.dick > 0>>
	<<if $customSlave.balls == 0>>No testicles.<<elseif $customSlave.balls == 2>>Small testicles.<<else>>Large testicles.<</if>>
	<<link "No testicles">>
		<<set $customSlave.balls = 0,$customSlave.clit = 0>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Small testicles">>
		<<set $customSlave.balls = 2,$customSlave.clit = 0>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Large testicles">>
		<<set $customSlave.balls = 4,$customSlave.clit = 0>>
		<<CustomSlaveClitBalls>>
	<</link>>
	<<else>>
	<<if $customSlave.clit == 0>>Normal clitoris.<<elseif $customSlave.clit == 0>>Big clitoris.<<else>>Enormous clitoris.<</if>>
	<<link "Normal clitoris">>
		<<set $customSlave.clit = 0>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Big clitoris">>
		<<set $customSlave.clit = 1>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Enormous clitoris">>
		<<set $customSlave.clit = 2>>
		<<CustomSlaveClitBalls>>
	<</link>>

	<<if $customSlave.labia == 0>>Minimal labia.<<elseif $customSlave.labia == 1>>Normal labia.<<elseif $customSlave.labia == 2>>Huge labia.<<else>>Enormous labia.<</if>>
	<<link "Minimal labia">>
		<<set $customSlave.labia = 0>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Normal labia">>
		<<set $customSlave.labia = 1>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Huge labia">>
		<<set $customSlave.labia = 2>>
		<<CustomSlaveClitBalls>>
	<</link>>
	|
	<<link "Enormous labia">>
		<<set $customSlave.labia = 3>>
		<<CustomSlaveClitBalls>>
	<</link>>
	<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveLube>>
%/
<<widget "CustomSlaveLube">>
	<<replace #lube>>
		<<if $customSlave.vaginaLube == 0>>Dry vagina.
		<<elseif $customSlave.vaginaLube == 1>>Wet vagina.
		<<else>>Sopping wet vagina.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveAnalVirginity>>
%/
<<widget "CustomSlaveAnalVirginity">>
	<<replace #anus>>
		<<if $customSlave.analVirgin == 0>>Anal virgin.
		<<else>>Anal virginity is not important.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveAnus>>
%/
<<widget "CustomSlaveAnus">>
	<<replace #anus>>
		<<if $customSlave.anus == 0>>Anal virgin.
		<<else>>Normal anus.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveSkills>>
%/
<<widget "CustomSlaveSkills">>
	<<replace #skills>>
		<<if $customSlave.skills <= 10>>Sexually unskilled.
		<<elseif $customSlave.skills <= 15>>Basic sex skills.
		<<else>>Sexually skilled.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveWhoreSkills>>
%/
<<widget "CustomSlaveWhoreSkills">>
	<<replace #whoreskills>>
		<<if $customSlave.skill.whore <= 10>>Unskilled at prostitution and entertainment.
		<<elseif $customSlave.skill.whore <= 15>>Basic prostitution and entertainment skills.
		<<else>>Skilled at prostitution and entertainment.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveCombatSkills>>
%/
<<widget "CustomSlaveCombatSkills">>
	<<replace #combatskills>>
		<<if $customSlave.skill.combat == 0>>Unskilled at combat.
		<<else>>Skilled at combat.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveIntelligence>>
%/
<<widget "CustomSlaveIntelligence">>
	<<replace #intelligence>>
		<<if $customSlave.intelligence >= 3>>Brilliant.
		<<elseif $customSlave.intelligence == 2>>Very smart.
		<<elseif $customSlave.intelligence == 1>>Smart.
		<<elseif $customSlave.intelligence == 0>>Average intelligence.
		<<elseif $customSlave.intelligence == -1>>Stupid.
		<<elseif $customSlave.intelligence == -2>>Very stupid.
		<<else>>Moronic.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveEducation>>
%/
<<widget "CustomSlaveEducation">>
	<<replace #education>>
		<<if $customSlave.intelligenceImplant >= 30>>Well educated.
		<<elseif $customSlave.intelligenceImplant >= 15>>Educated.
		<<else>>Uneducated.
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveNationality>>
%/
<<widget "CustomSlaveNationality">>
	<<replace #nationality>>
		Nationality: $customSlave.nationality.
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveEyes>>
%/
<<widget "CustomSlaveEyes">>
	<<replace #eyes>>
		<<if $seeExtreme == 1>>
			<<if $customSlave.eyes == -2>>Blind.
			<<elseif $customSlave.eyes == -1>>Nearsighted.
			<<else>>Normal.
			<</if>>
		<<else>>
			<<if $customSlave.eyes == -1>>Nearsighted.
			<<else>>Normal.
			<</if>>
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveEars>>
%/
<<widget "CustomSlaveEars">>
	<<replace #hears>>
		<<if $seeExtreme == 1>>
			<<if $customSlave.hears == -2>>Deaf.
			<<elseif $customSlave.hears == -1>>Hard of hearing.
			<<else>>Normal.
			<</if>>
		<<else>>
			<<if $customSlave.hears == -1>>Hard of hearing.
			<<else>>Normal.
			<</if>>
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveSmell>>
%/
<<widget "CustomSlaveSmell">>
	<<replace #smelling>>
		<<if $seeExtreme == 1>>
			<<if $customSlave.smells == -1>>None.
			<<else>>Normal.
			<</if>>
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveTaste>>
%/
<<widget "CustomSlaveTaste">>
	<<replace #tasting>>
		<<if $seeExtreme == 1>>
			<<if $customSlave.tastes == -1>>None.
			<<else>>Normal.
			<</if>>
		<</if>>
	<</replace>>
<</widget>>

/%
 Call as <<CustomSlaveAmp>>
%/
<<widget "CustomSlaveAmp">>
	<<replace #amputation>>
		<<if $customSlave.amp == 1>>Limbless.
		<<else>>Limbed.
		<</if>>
	<</replace>>
<</widget>>

/%
	Call as <<MarketName 'market' ['arcology']>>
	If $args[0] is undefined, will generate a kidnapper's market slave.
	If $args[0] is "corporate" and $args[1] is undefined, will use neighboring arcology 1.
%/
<<widget MarketName>>
<<if $args[0]>>
	<<set _market = $args[0]>>
<<else>>
	<<set _market = "kidnappers">>
<</if>>

<<switch _market>>
<<case "corporate">>
	your corporation
<<case "neighbor">>
	<<if $args[1]>>
		<<print $arcologies[$args[1]].name>>
	<<else>>
		<<print $arcologies[1].name>>
	<</if>>
<<case "kidnappers">>
	the Kidnappers' Market
<<case "indentures">>
	the Indentures Market
<<case "hunters">>
	the Runaway Hunters' Market
<<case "raiders">>
	the Raiders' Market
<<case "underage raiders">>
	the Raiders' Black Market
<<case "heap">>
	the Flesh Heap as alive as when you purchased them.
<<case "wetware">>
	the Wetware CPU market
<<case "trainers">>
	the Trainers' Market
<<case "TSS">>
	The Slavegirl School
<<case "GRI">>
	Growth Research Institute
<<case "SCP">>
	St. Claver Preparatory
<<case "LDE">>
	L'école des Enculées
<<case "TGA">>
	The Gymnasium-Academy
<<case "TCR">>
	The Cattle Ranch
<<case "TFS">>
	The Futanari Sisters
<<case HA>>
	The Hippolyta Academy
<<case NUL>>
	Nueva Universidad de Libertad
<<case "low tier criminals" "gangs and smugglers" "white collar" "military prison">>
	the prisoner sale
<<default>>
	Someone messed up. _market is not known.

<</switch>>
<</widget>>

/%
	Call as <<MarketNamePeriod 'market' ['arcology']>>
	If $args[0] is undefined, will generate a kidnapper's market slave.
	If $args[0] is "corporate" and $args[1] is undefined, will use neighboring arcology 1.
%/
<<widget MarketNamePeriod>>
<<if $args[0]>>
	<<set _market = $args[0]>>
<<else>>
	<<set _market = "kidnappers">>
<</if>>

<<switch _market>>
<<case "corporate">>
	your corporation.
<<case "neighbor">>
	<<if $args[1]>>
		<<print $arcologies[$args[1]].name>>.
	<<else>>
		<<print $arcologies[1].name>>.
	<</if>>
<<case "kidnappers">>
	the Kidnappers' Market.
<<case "indentures">>
	the Indentures Market.
<<case "hunters">>
	the Runaway Hunters' Market.
<<case "raiders">>
	the Raiders' Market.
<<case "underage raiders">>
	the Raiders' Black Market.
<<case "heap">>
	the Flesh Heap, alive and not dead.
<<case "wetware">>
	the Wetware CPU market.
<<case "trainers">>
	the Trainers' Market.
<<case "TSS">>
	The Slavegirl School.
<<case "GRI">>
	Growth Research Institute.
<<case "SCP">>
	St. Claver Preparatory.
<<case "LDE">>
	L'école des Enculées.
<<case "TGA">>
	The Gymnasium-Academy.
<<case "TCR">>
	The Cattle Ranch.
<<case "TFS">>
	The Futanari Sisters.
<<case HA>>
	The Hippolyta Academy.
<<case NUL>>
	Nueva Universidad de Libertad.
<<case "low tier criminals" "gangs and smugglers" "white collar" "military prison">>
	the prisoner sale.
<<default>>
	Someone messed up. _market is not known.

<</switch>>
<</widget>>

/%
 Call as <<JFCSlave>>
%/
<<widget "JFCSlave">>
	<<set $activeSlaveOneTimeMinAge = 20>>
	<<set $activeSlaveOneTimeMaxAge = 36>>
	<<set $one_time_age_overrides_pedo_mode = 1>>
	<<set $oneTimeDisableDisability = 1>>
	<<set $activeSlave = GenerateNewSlave("XX")>>
	<<set $activeSlave.weight = random(-30,20), $activeSlave.waist = random(-30,10), $activeSlave.face = random(40,60)>>
	<<if $activeSlave.faceShape == "masculine">>
		<<set $activeSlave.faceShape = "sensual">>
	<</if>>
	<<if $activeSlave.boobShape == "saggy" || $activeSlave.boobShape == "downward-facing">>
		<<set $activeSlave.boobShape = "perky">>
	<</if>>
	<<set $activeSlave.eyes = 1, $activeSlave.hears = 0, $activeSlave.voice = 2>>
	<<set $activeSlave.intelligenceImplant = 30, $activeSlave.intelligence = random(20,100)>>
	<<set $activeSlave.trust = 80, $activeSlave.devotion = 80>>
	<<set $activeSlave.health = random(80,95)>>
	<<set $activeSlave.origin = "The Job Fulfillment Center offered $his contract to fill your request for a ">>
	<<set $activeSlave.origin += $Role>>
	<<set $activeSlave.origin += ".">>
	<<switch $Role>>
	/* Opens security */
		<<case "Lieutenant Colonel">>
			<<set $activeSlave.devotion = random(96,100), $activeSlave.trust = random(96, 100), $activeSlave.energy = random(96,100), $activeSlave.intelligence = 70, $activeSlave.skill.combat = 1>>
			<<set $activeSlave.career = either("a bodyguard", "a bouncer", "a bounty hunter", "a gang member", "a law enforcement officer", "a mercenary", "a prison guard", "a private detective", "a revolutionary", "a security guard", "a soldier", "a street thug", "a transporter", "an assassin", "an enforcer", "in a militia")>>
		<<case "Bodyguard">>
			<<set $activeSlave.devotion = 90, $activeSlave.muscles = random(30,70), $activeSlave.height = Math.round(Height.random($activeSlave, {skew: 3, spread: .2, limitMult: [1, 4]})), $activeSlave.weight = random(-10,10), $activeSlave.teeth = either("normal", "pointy"), $activeSlave.amp = either(-4, -4, 0, 0, 0, 0), $activeSlave.skill.combat = 1>>
			<<set $activeSlave.career = either("a bodyguard", "a kunoichi", "a law enforcement officer", "a military brat", "a revolutionary", "a soldier", "a transporter", "an assassin", "in a militia")>>
		<<case "Wardeness">>
			<<set $activeSlave.energy = random(80,100), $activeSlave.sexualFlaw = either("malicious", "none", "none", "none", "none"), $activeSlave.fetish = "sadist", $activeSlave.fetishStrength = 100, $activeSlave.muscles = random(50,80), $activeSlave.skill.combat = 1>>
			<<set $activeSlave.career = either("a bouncer", "a bounty hunter", "a gang member", "a mercenary", "a prison guard", "a private detective", "a security guard", "a street thug", "an enforcer")>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,6), $activeSlave.balls = random(3,6), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,1,2,2,3)>>
			<</if>>
	/* Closes Security */
	/* Opens management */
		<<case "Headgirl">>
			<<set $activeSlave.devotion = 90, $activeSlave.trust = 100, $activeSlave.fetish = "dom", $activeSlave.fetishStrength = 100, $activeSlave.energy = random(70,90), $activeSlave.intelligence = random(60,100), $activeSlave.skill.entertainment = 100, $activeSlave.skill.whoring = 100, $activeSlave.skill.anal = 100, $activeSlave.skill.oral = 100, $activeSlave.skill.vaginal = 100, $activeSlave.career = either("a lawyer", "a military officer", "a politician")>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,5), $activeSlave.balls = random(3,6), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,2)>>
			<</if>>
			<<set $activeSlave.vagina = random(3,4)>>
			<<if $AgePenalty == 1>>
				<<set $activeSlave.actualAge = random(36,$retirementAge-5)>>
			<<else>>
				<<set $activeSlave.actualAge = random(20,$retirementAge-5)>>
			<</if>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Teacher">>
			<<set $activeSlave.fetish = "dom", $activeSlave.fetishStrength = 100, $activeSlave.energy = random(70,90), $activeSlave.intelligence = 100, $activeSlave.skill.entertainment = 100, $activeSlave.skill.whoring = 100, $activeSlave.skill.anal = 100, $activeSlave.skill.oral = 100, $activeSlave.skill.vaginal = 100, $activeSlave.face = random(41,90), $activeSlave.career = either("a librarian", "a principal", "a private instructor", "a professor", "a scholar", "a scientist", "a teacher", "a teaching assistant")>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,5), $activeSlave.balls = random(3,6), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,1,2,2,3)>>
			<</if>>
			<<set $activeSlave.actualAge = random(36,$retirementAge-3)>>
			<<set $activeSlave.vagina = random(3,4)>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Nurse">>
			<<set $activeSlave.fetish = "dom", $activeSlave.fetishStrength = 100, $activeSlave.muscles = random(6,50), $activeSlave.face = random(41,90), $activeSlave.sexualQuirk = "caring", $activeSlave.career = either("a doctor", "a medic", "a medical student", "a nurse", "a paramedic"), $activeSlave.intelligence = random(40,90)>>
		<<case "Motherly Attendant">>
			<<set $activeSlave.devotion = 90, $activeSlave.trust = 90, $activeSlave.fetish = "submissive", $activeSlave.fetishStrength = 100, $activeSlave.face = random(60,90)>>
			<<set $activeSlave.career = either("a counselor", "a dispatch officer", "a lifeguard", "a masseuse", "a psychologist", "a therapist"), $activeSlave.counter.birthsTotal = random(1,3), $activeSlave.pregKnown = 1, $activeSlave.preg = random(20,35), $activeSlave.pregWeek = $activeSlave.preg, $activeSlave.pregType = 1>>
			<<run SetBellySize($activeSlave)>>
			<<set $activeSlave.actualAge = random(36,$retirementAge-3)>>
			<<set $activeSlave.vagina = random(3,4)>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Attendant">>
			<<set $activeSlave.devotion = 90, $activeSlave.trust = 90, $activeSlave.fetish = "submissive", $activeSlave.fetishStrength = 100, $activeSlave.eyes = either(-2, 1, 1), $activeSlave.preg = 0, $activeSlave.face = random(60,90), $activeSlave.career = either("a counselor", "a masseuse", "a therapist")>>
			<<set $activeSlave.actualAge = random(26,$retirementAge-3)>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Matron">>
			<<set $activeSlave.devotion = 90, $activeSlave.trust = 90, $activeSlave.sexualQuirk = "caring", $activeSlave.eyes = 1, $activeSlave.counter.birthsTotal = random(2,4), $activeSlave.vagina = 3, $activeSlave.face = random(60,90), $activeSlave.career = either( "a nanny", "a practitioner")>>
			<<set $activeSlave.actualAge = random(24,$retirementAge-3)>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Stewardess">>
			<<set $activeSlave.energy = random(70,90), $activeSlave.fetish = "dom", $activeSlave.fetishStrength = 100, $activeSlave.career = either("a barista", "a bartender", "a caregiver", "a charity worker", "a professional bartender", "a secretary", "a wedding planner", "an air hostess", "an estate agent", "an investor", "an office worker")>>
			<<if $AgePenalty == 1>>
				<<set $activeSlave.actualAge = random(36,$retirementAge-5)>>
			<<else>>
				<<set $activeSlave.actualAge = random(20,$retirementAge-5)>>
			<</if>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Milkmaid">>
			<<set $activeSlave.muscles = random(31,60), $activeSlave.skill.oral = random(31,60), $activeSlave.sexualQuirk = "caring", $activeSlave.behavioralQuirk = "funny", $activeSlave.career = either("a cowgirl", "a dairy worker", "a milkmaid", "a farmer's daughter", "a shepherd", "a veterinarian"), $activeSlave.intelligence = random(20,70)>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,5), $activeSlave.balls = random(4,9), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,1,2)>>
			<</if>>
		<<case "Farmer">>
			<<set $activeSlave.devotion = 80, $activeSlave.trust = 80, $activeSlave.health = random(80,95), $activeSlave.muscles = random(41,70), $activeSlave.sexualQuirk = "caring", $activeSlave.career = either("a farmer", "a farmer's daughter", "a rancher", "a farmhand", "a zookeeper"), $activeSlave.intelligenceImplant = 30, $activeSlave.intelligence = random(20,70), $activeSlave.height = Math.round(Height.random($activeSlave, {skew: 3, spread: .2, limitMult: [1, 4]})), $activeSlave.weight = random(0,30)>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,5), $activeSlave.balls = random(4,9), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,1,2)>>
			<</if>>
			<<if $AgePenalty == 1>>
				<<set $activeSlave.actualAge = random(36,$retirementAge-5)>>
			<<else>>
				<<set $activeSlave.actualAge = random(20,$retirementAge-5)>>
			<</if>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
	/* Closes management */
	/* Opens entertain */
		<<case "DJ">>
			<<set $activeSlave.skill.entertainment = 100, $activeSlave.muscles = random(6,30), $activeSlave.face = random(80,100), $activeSlave.career = either("a classical dancer", "a classical musician", "a dancer", "a house DJ", "a musician", "an aspiring pop star")>>
		<<case "Madam">>
			<<set $activeSlave.skill.whoring = 100, $activeSlave.career = either("a business owner", "a manager", "a pimp", "a procuress", "an innkeeper")>>
			<<if $seeDicks > 0>>
				<<set $activeSlave.dick = random(3,5), $activeSlave.balls = random(3,5), $activeSlave.scrotum = $activeSlave.balls, $activeSlave.prostate = either(1,1,1,2)>>
			<</if>>
			<<if $AgePenalty == 1>>
				<<set $activeSlave.actualAge = random(36,$retirementAge-5)>>
			<<else>>
				<<set $activeSlave.actualAge = random(20,$retirementAge-5)>>
			<</if>>
			<<set $activeSlave.physicalAge = $activeSlave.actualAge, $activeSlave.visualAge = $activeSlave.actualAge, $activeSlave.ovaryAge = $activeSlave.actualAge>>
		<<case "Concubine">>
			<<set $activeSlave.prestige = 3, $activeSlave.energy = random(80,100), $activeSlave.skill.entertainment = 100, $activeSlave.skill.whoring = 100, $activeSlave.skill.anal = 100, $activeSlave.skill.oral = 100, $activeSlave.skill.vaginal = 100, $activeSlave.face = 100, $activeSlave.devotion = random(90,95), $activeSlave.trust = random(90,100)>>
		/* Closes Entertain */
		<</switch>>
<</widget>>

/%
 % Shows controls for buying and advancing the queue for buying slaves from a school
 % Arguments: none
 % Call as <<buyingFromMarketControls>>
 %/
<<widget "buyingFromMarketControls">>

[["Decline to purchase " + $him + " and check out another slave"|passage()][$slavesSeen += 1]]
<<if $cash >= $slaveCost>>

[["Buy " + $him + " and check out other slaves to order"|passage()][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave),$newSlaves.push($activeSlave), $introType = "multi", $slavesSeen+=1]]
	<<if $newSlaves.length == 0>>

[["Buy " + $his + " slave contract"|New Slave Intro][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave),$nextButton = "Continue",$nextLink = "AS Dump",$returnTo = "Main"]]
	<<else>>

[["Buy " + $him + " and finish your order of slaves"|Bulk Slave Intro][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave), $newSlaves.push($activeSlave)]]
	<</if>>
<<else>>

//You lack the necessary funds to buy this slave.//
<</if>>
<<if $newSlaves.length > 0>>

[[Finish your order of slaves|Bulk Slave Intro]]
<</if>>

<<if $slaveMarket != "indentures" && $slaveMarket != "neighbor" && $slaveMarket != "heap" && $slaveMarket != "wetware">>
	<<set $applyLaw = 1>>
<</if>>
<<set $saleDescription = 1>><<include "Long Slave Description">>
<</widget>>

/%
 % Shows controls for buying and advancing the queue for buying slaves from a school
 % Arguments:
 % 0: school
 % 1: name for a single slave ("slave", "cow", etc.)
 % 2: name for a bunch of them ("slaves", "cattle", etc.)
 % Call as <<buyingFromSchoolControls $TCR "cow" "cattle">>
 %/
<<widget "buyingFromSchoolControls">>

[["Decline to purchase " + $him + " and check out another " + $args[1]|passage()][$slavesSeen += 1]]
<<if $cash >= $slaveCost>>
	<<set _schoolToBuyFrom = $args[0]>>

[["Buy " + $him + " and check out other " + $args[2] + " to order"|passage()][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave), _schoolToBuyFrom.schoolSale = 0, _schoolToBuyFrom.studentsBought += 1, $newSlaves.push($activeSlave), $introType = "multi", $slavesSeen+=1]]
	<<if $newSlaves.length == 0>>

[["Buy " + $his + " slave contract"|New Slave Intro][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave), _schoolToBuyFrom.schoolSale = 0, _schoolToBuyFrom.studentsBought += 1, $nextButton = "Continue", $nextLink = "AS Dump", $returnTo = "Main"]]
	<<else>>

[["Buy " + $him + " and finish your order of " + $args[2]|Bulk Slave Intro][cashX(forceNeg($slaveCost), "slaveTransfer", $activeSlave), _schoolToBuyFrom.schoolSale = 0, _schoolToBuyFrom.studentsBought += 1, $newSlaves.push($activeSlave)]]
	<</if>>
<<else>>

//You lack the necessary funds to buy this $args[1].//
<</if>>
<<if $newSlaves.length > 0>>

[["Finish your order of " + $args[2]|"Bulk Slave Intro"]]
<</if>>

<<set $saleDescription = 1>><<include "Long Slave Description">>
<</widget>>


code:
branches:
  except:
    - /^travis.*$/

clone_depth: 5

image: Visual Studio 2019

platform:
  - Win32
  - x64

configuration:
  - Debug
  - Release

build:
  project: platform/Windows/eduke32.sln
  parallel: true
  verbosity: minimal

repo_name: orochi/nblood

license: mit


code:
name: Build

on:
  push:
    branches:
      - master
  pull_request: {}

jobs:

  build-windows-x86_64:
    name: "Windows MSYS2 x86_64"
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    steps:
    - uses: actions/checkout@v2
    - uses: msys2/setup-msys2@v2
      with:
        msystem: MINGW64
        update: true
        install: git mingw-w64-x86_64-toolchain make
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools SDLCONFIG=""

  build-windows-i686:
    name: "Windows MSYS2 i686"
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    steps:
    - uses: actions/checkout@v2
    - uses: msys2/setup-msys2@v2
      with:
        msystem: MINGW32
        update: true
        install: git mingw-w64-i686-toolchain make nasm
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools SDLCONFIG=""

  build-linux-gcc:
    name: "Linux GCC"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: install-prerequisites
      run: |
        sudo apt-get update
        sudo apt-get -y install libsdl2-dev libvorbis-dev libflac-dev libvpx-dev libglu1-mesa-dev libgtk2.0-dev
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools

  build-linux-gcc-sdl12:
    name: "Linux GCC SDL 1.2"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: install-prerequisites
      run: |
        sudo apt-get update
        sudo apt-get -y install libsdl1.2-dev libvorbis-dev libflac-dev libvpx-dev libglu1-mesa-dev libgtk2.0-dev
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools SDL_TARGET=1

  build-linux-clang:
    name: "Linux Clang"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: install-prerequisites
      run: |
        sudo apt-get update
        sudo apt-get -y install libsdl2-dev libvorbis-dev libflac-dev libvpx-dev libglu1-mesa-dev libgtk2.0-dev clang
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools CLANG=1

  build-linux-clang-nogl:
    name: "Linux Clang without GL"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: install-prerequisites
      run: |
        sudo apt-get update
        sudo apt-get -y install libsdl2-dev libvorbis-dev libflac-dev libvpx-dev libglu1-mesa-dev libgtk2.0-dev clang
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools CLANG=1 USE_OPENGL=0

  build-linux-clang-nopolymer:
    name: "Linux Clang without Polymer"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: install-prerequisites
      run: |
        sudo apt-get update
        sudo apt-get -y install libsdl2-dev libvorbis-dev libflac-dev libvpx-dev libglu1-mesa-dev libgtk2.0-dev clang
    - name: build
      run: make -j2 duke3d sw blood rr exhumed tools CLANG=1 POLYMER=0

#  build-macos:
#    name: "macOS"
#    runs-on: macos-latest
#    steps:
#    - uses: actions/checkout@v2
#    - name: install-prerequisites
#      run: |
#        brew install sdl2 libogg libvorbis flac libvpx make
#        brew unlink lz4
#    - name: build
#      run: gmake -j2 duke3d sw blood rr exhumed tools


code:
obj/

/eduke32
/mapster32
/voidsw
/wangulator
/ekenbuild
/ekenbuild-editor

/nblood
/rednukem
/rrmapster32
/pcexhumed
/ewitchaven
/etekwar

/arttool
/bsuite
/cacheinfo
/enumdisplay
/generateicon
/getdxdidf
/givedepth
/ivfrate
/kextract
/kgroup
/kmd2tool
/makesdlkeytrans
/map2stl
/md2tool
/mkpalette
/transpal
/unpackssi
/wad2art
/wad2map

apps/
*.exe
/*.dll
*.dylib
*.so
*.elf
*.dol
*.x86
*.x64
*.ppc
/*.app

*.log
*.cache
*.cfg
textures
texturecache
*.index

*.manifest
/*.map
/platform/Windows/*.map
*.pdb
*.iobj
*.ipdb
*.ilk
.vs/
*.VC.db
*.VC.opendb
*.sym
/*.grp
/*.rts
/*.art
/*.con
/platform/Windows/*.con
*.memmap
*.sdf
*.suo
*.opensdf
*.vcxproj.user
*.psess
*.vsp
/platform/Windows/Debug/
/platform/Windows/Release/
/platform/Windows/Build/
/platform/Windows/x64/
/platform/Windows/Win32/
/platform/Windows/ARM64/
*.exp
*.lib
perl.exe.stackdump

xcuserdata/
project.xcworkspace/
*.dSYM/

.vscode

.DS_Store
._*
/source/voidwrap/sdk/

/autoload
/movie
/*.png
/*.MHK
/*.AR_
/*.SMK
/*.WAV
/*.INI
/*.sav
/*.cfg_orig
/*.DEM
/*.DEM_

/platform/Windows/autoload
/platform/Windows/movie
/platform/Windows/*.png
/platform/Windows/*.MHK
/platform/Windows/*.AR_
/platform/Windows/*.SMK
/platform/Windows/*.WAV
/platform/Windows/*.INI
/platform/Windows/*.sav
/platform/Windows/*.cfg_orig
/platform/Windows/*.DEM
/platform/Windows/*.DEM_

path: .gitignore


code:
synthesis:
  script:
    - kickoff_synthesis.sh


code:
### EDuke32 engine & game programming:
  * TerminX
  * Hendricks266
  * pogokeen
  * Plagman
  * Helixhorned

### JFDuke3D by:
  * JonoF

### Uses BUILD Engine technology by:
  * Ken Silverman

### NBlood/Rednukem programming:
  * Nuke.YKT
  * sirlemonhead
  * Hendricks266
  * NY00123
  * NoOne

### NBlood/Rednukem widescreen tiles:
  * Maxi Clouds
  * Fox
  * Dzierzan
  * James Manning

### Autobuilds are provided by
  * oasiz

### NBlood/Rednukem special thanks:
  * Hendricks266, TerminX, NY00123, Fox, MetHy, Striker, oasiz, Mblackwell, Zombie, Marphy Black, SAmik37, meleemario

### NBlood contributors:
  * alexey-lysiuk, CommonLoon102, Jan200101

### PCExhumed programming:
  * sirlemonhead
  * Nuke.YKT
  * NY00123

### PCExhumed startup window banner:
  * Maxi Clouds

### PCExhumed special thanks:
  * Hendricks266, JonoF, NY00123, MetHy, oasiz, Daedolon, NoOne, phredreeke, Lobotomy Software


code:
# OS package maintainers: Please try invoking make with PACKAGE_REPOSITORY=1 to see if that meets your needs before patching out our optimizations entirely.
PACKAGE_REPOSITORY ?= 0

# Are we running from synthesis?
SYNTHESIS := 0

##### Makefile Swiss army knife

override empty :=
override space := $(empty) $(empty)
override comma := ,
override paren_open := (
override paren_close := )

##### Detect platform

ifndef HOSTPLATFORM
    HOSTPLATFORM := UNKNOWN
    ifeq ($(findstring Windows,$(OS)),Windows)
        HOSTPLATFORM := WINDOWS
    else
        uname := $(strip $(shell uname -s))
        ifeq ($(findstring Linux,$(uname)),Linux)
            HOSTPLATFORM := LINUX
        else ifeq ($(findstring BSD,$(uname)),BSD)
            HOSTPLATFORM := BSD
        else ifeq ($(findstring MINGW,$(uname)),MINGW)
            HOSTPLATFORM := WINDOWS
        else ifeq ($(findstring MSYS,$(uname)),MSYS)
            HOSTPLATFORM := WINDOWS
        else ifeq ($(findstring Darwin,$(uname)),Darwin)
            HOSTPLATFORM := DARWIN
        else ifeq ($(findstring BeOS,$(uname)),BeOS)
            HOSTPLATFORM := BEOS
        endif
    endif
endif
ifndef PLATFORM
    PLATFORM := $(HOSTPLATFORM)
endif

ifndef SUBPLATFORM
    SUBPLATFORM :=
    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO))
        SUBPLATFORM := LINUX
    endif
endif

ifeq ($(HOSTPLATFORM),DARWIN)
    DARWINVERSION := $(word 1,$(subst ., ,$(strip $(shell uname -r))))

    DARWIN9 := 0
    DARWIN10 := 0
    ifneq (,$(filter 0 1 2 3 4 5 6 7 8 9 10,$(DARWINVERSION)))
        DARWIN10 := 1
        ifneq (,$(filter 0 1 2 3 4 5 6 7 8 9,$(DARWINVERSION)))
            DARWIN9 := 1
        endif
    endif
endif

HOSTEXESUFFIX :=
ifeq ($(HOSTPLATFORM),WINDOWS)
    HOSTEXESUFFIX := .exe
endif

EXESUFFIX :=
DLLSUFFIX := .so
DOLSUFFIX := .dol
ifeq ($(PLATFORM),DARWIN)
    DLLSUFFIX := .dylib
endif
ifeq ($(PLATFORM),WII)
    EXESUFFIX := .elf
endif
ifeq ($(PLATFORM),WINDOWS)
    EXESUFFIX := .exe
    DLLSUFFIX := .dll
endif

##### Makefile meta-settings

PRETTY_OUTPUT := 1

NULLSTREAM := /dev/null

ifeq ($(HOSTPLATFORM),WINDOWS)
# MSYS2 lets you create files named NUL but has a /dev/null. Go figure.
    ifeq (,$(wildcard /dev/null))
        NULLSTREAM := NUL
    endif
endif

DONT_PRINT := > $(NULLSTREAM) 2>&1
DONT_PRINT_STDERR := 2> $(NULLSTREAM)
DONT_FAIL := ; exit 0
ESCAPE=\\

HAVE_SH := 1
# when no sh.exe is found in PATH on Windows, no path is prepended to it
ifeq (sh.exe,$(SHELL))
    HAVE_SH := 0
endif

define LL
    ls -l $1
endef
define MKDIR
    mkdir -p $1
endef
define RM
    rm -f $(filter-out / *,$1)
endef
define RMDIR
    rm -rf $(filter-out / *,$1)
endef
define CAT
    cat $1
endef
define RAW_ECHO
    echo '$1'
endef

ifeq (0,$(HAVE_SH))
    DONT_FAIL := & rem
    ESCAPE=^

    define LL
        dir $(subst /,\,$1)
    endef
    define MKDIR
        if not exist $(subst /,\,$1) mkdir $(subst /,\,$1)
    endef
    define RM
        del /f /q $(subst /,\,$(filter-out / *,$1)) $(DONT_PRINT_STDERR) $(DONT_FAIL)
    endef
    define RMDIR
        rmdir /s /q $(subst /,\,$(filter-out / *,$1)) $(DONT_PRINT_STDERR) $(DONT_FAIL)
    endef
    define CAT
        type $(subst /,\,$1)
    endef
    define RAW_ECHO
        echo $(subst ",$(ESCAPE)",$(subst $(paren_open),$(ESCAPE)$(paren_open),$(subst $(paren_close),$(ESCAPE)$(paren_close),$1)))
    endef

    # if, printf, exit, and ; are unavailable without sh
    PRETTY_OUTPUT := 0
endif

##### Toolchain setup

CROSS :=
CROSS_SUFFIX :=

CCFULLPATH = $(CC)

ifeq ($(PLATFORM),WII)
    ifeq ($(strip $(DEVKITPPC)),)
        $(error "Please set DEVKITPPC in your environment. export DEVKITPPC := <path to>devkitPPC")
    endif

    ifeq ($(HOSTPLATFORM),WINDOWS)
        override DEVKITPRO := $(subst /c/,C:/,$(DEVKITPRO))
        override DEVKITPPC := $(subst /c/,C:/,$(DEVKITPPC))
    endif

    export PATH := $(DEVKITPPC)/bin:$(PATH)

    CROSS := powerpc-eabi-

    CCFULLPATH = $(DEVKITPPC)/bin/$(CC)
endif

CC := $(CROSS)gcc$(CROSS_SUFFIX)
CXX := $(CROSS)g++$(CROSS_SUFFIX)

ifeq ($(PLATFORM),DARWIN)
    CC := $(CROSS)clang$(CROSS_SUFFIX)
    CXX := $(CROSS)clang++$(CROSS_SUFFIX)
endif

COBJC := $(CC) -x objective-c
COBJCXX := $(CXX) -x objective-c++
L_CC := $(CC)
L_CXX := $(CXX)

AR := $(CROSS)ar$(CROSS_SUFFIX)
RC := $(CROSS)windres$(CROSS_SUFFIX)
RANLIB := $(CROSS)ranlib$(CROSS_SUFFIX)
STRIP := $(CROSS)strip$(CROSS_SUFFIX)

AS := nasm

PKG_CONFIG := pkg-config

ELF2DOL := elf2dol

# Override defaults that absolutely will not work.
ifeq ($(CC),cc)
    override CC := gcc
endif
ifeq ($(AS),as)
    override AS := nasm
endif

ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW))
    CROSS := mipsel-linux-
endif

CLANG := 0
ifeq ($(findstring clang,$(CC) $(MAKECMDGOALS)),clang)
    override CLANG := 1
    CLANGNAME := $(CC)
else
    CLANGNAME := clang
endif
# detect clang symlinked as gcc, as in OS X
CLANG_POTENTIAL_VERSION := $(shell $(CCFULLPATH) --version)
ifeq ($(findstring clang,$(CLANG_POTENTIAL_VERSION)),clang)
    override CLANG := 1
    ifeq ($(findstring Apple,$(CLANG_POTENTIAL_VERSION)),Apple)
        override APPLE_CLANG := 1
        APPLE_CLANG_VER := $(word 4,$(CLANG_POTENTIAL_VERSION))
        override APPLE_CLANG_VER_SPLIT := $(subst ., ,$(APPLE_CLANG_VER))
        APPLE_CLANG_MAJOR := $(word 1,$(APPLE_CLANG_VER_SPLIT))
        APPLE_CLANG_MINOR := $(word 2,$(APPLE_CLANG_VER_SPLIT))
    else
        CLANG_VER := $(word 3,$(CLANG_POTENTIAL_VERSION))
        override CLANG_VER_SPLIT := $(subst ., ,$(CLANG_VER))
        CLANG_MAJOR := $(word 1,$(CLANG_VER_SPLIT))
        CLANG_MINOR := $(word 2,$(CLANG_VER_SPLIT))
    endif
endif

LLD := 0

ifneq (0,$(CLANG))
    override LLD := 1
    CLANGXXNAME := $(subst clang,clang++,$(CLANGNAME))
    override CC := $(CLANGNAME) -x c
    override CXX := $(CLANGXXNAME) -x c++
    override COBJC := $(CLANGNAME) -x objective-c
    override COBJCXX := $(CLANGXXNAME) -x objective-c++
    override L_CC := $(CLANGNAME)
    override L_CXX := $(CLANGXXNAME)
endif

GCC_VER :=
ifeq (0,$(CLANG))
    GCC_VER := $(strip $(shell $(CCFULLPATH) -dumpversion 2>&1))
endif
ifeq (,$(GCC_VER))
    GCC_VER := 4.9.0
endif
override GCC_VER_SPLIT := $(subst ., ,$(GCC_VER))
GCC_MAJOR := $(word 1,$(GCC_VER_SPLIT))
GCC_MINOR := $(word 2,$(GCC_VER_SPLIT))

GCC_PREREQ_4 := 1

ifneq (,$(filter 1 2 3,$(GCC_MAJOR)))
    ifeq (0,$(CLANG))
        GCC_PREREQ_4 := 0
        $(error How do you still have an old GCC in $$(CURRENT_YEAR)?)
    endif
endif

##### Detect machine architecture

BITS := 32

ifeq ($(PLATFORM),WINDOWS)
    ifndef COMPILERTARGET
        COMPILERTARGET := $(strip $(shell $(CC) -dumpmachine))
    endif

    IMPLICIT_ARCH := i386
    ifeq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
        IMPLICIT_ARCH := x86_64
        BITS := 64
    endif
else ifeq ($(PLATFORM),WII)
    IMPLICIT_ARCH := ppc
else
    ifneq ($(ARCH),)
        override ARCH := $(subst i486,i386,$(subst i586,i386,$(subst i686,i386,$(strip $(ARCH)))))
        IMPLICIT_ARCH := $(ARCH)
    else
        IMPLICIT_ARCH := $(subst i486,i386,$(subst i586,i386,$(subst i686,i386,$(strip $(shell uname -m)))))
    endif

    ifeq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
        BITS := 64
    endif
endif

##### Toggles

#  CPLUSPLUS - 1 := enable C++ building
#  RELEASE - 1 := no debugging
#  FORCEDEBUG:
#    1 := Include debug symbols even when generating release code.
#    2 := Also enable sanitizers with Clang. On the C side, make 'sprite' etc. be real arrays.
#  KRANDDEBUG - 1 := include logging of krand() calls for debugging the demo system
#  MEMMAP - 1 := produce .memmap file when linking
#  OPTLEVEL - 0..3 := GCC optimization strategy
#  LTO - 1 := enable link-time optimization

# Optional overrides for text
APPNAME ?=
APPBASENAME ?=

# Build toggles
RELEASE := 1
NOASM := 0
MEMMAP := 0
CPLUSPLUS := 1

# Feature toggles
STANDALONE ?= 0
NETCODE ?= 1
STARTUP_WINDOW ?= 1
RETAIL_MENU ?= 0
POLYMER ?= 1
USE_OPENGL := 1
SDL_STATIC ?= 0

NOONE_EXTENSIONS ?= 1

# Library toggles
HAVE_GTK2 := 1
USE_LIBVPX ?= 1
HAVE_VORBIS := 1
HAVE_FLAC := 1
HAVE_XMP := 1
RENDERTYPE := SDL
SDL_TARGET := 2
USE_PHYSFS := 0

ifneq (0,$(USE_PHYSFS))
    # PhysFS requires this to be off
    override CPLUSPLUS := 0
endif

# Debugging/Build options
FORCEDEBUG := 0
KRANDDEBUG := 0
PROFILER := 0
# Make allocache() a wrapper around malloc()? Useful for debugging
# allocache()-allocated memory accesses with e.g. Valgrind.
# For debugging with Valgrind + GDB, see
# http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
ALLOCACHE_AS_MALLOC := 0
MICROPROFILE := 0

##### Settings overrides and implicit cascades

ifneq (0,$(KRANDDEBUG))
    RELEASE := 0
endif
ifneq (100,$(RELEASE)$(PROFILER)$(ALLOCACHE_AS_MALLOC))
    # so that we have debug symbols
    FORCEDEBUG := 1
endif

ifeq ($(PLATFORM),WINDOWS)
    override HAVE_GTK2 := 0
else ifeq ($(PLATFORM),DARWIN)
    HAVE_GTK2 := 0
else ifeq ($(PLATFORM),WII)
    override USE_OPENGL := 0
    override NETCODE := 0
    override HAVE_GTK2 := 0
    override HAVE_FLAC := 0
    SDL_TARGET := 1
else ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW))
    override USE_OPENGL := 0
    override NOASM := 1
else ifeq ($(PLATFORM),$(filter $(PLATFORM),BEOS))
    override NOASM := 1
endif

ifneq (i386,$(strip $(IMPLICIT_ARCH)))
    override NOASM := 1
endif

ifeq (0,$(USE_OPENGL))
    override POLYMER := 0
    override USE_LIBVPX := 0
endif

ifeq ($(RELEASE),0)
    override STRIP :=
endif
ifneq ($(FORCEDEBUG),0)
    override STRIP :=
endif

DBGLEVEL :=
ifeq ($(RELEASE),0)
    OPTLEVEL := 0

    # see if we can use -Og
    ifeq (1,$(APPLE_CLANG))
      # Apple clang >= 9.0
      ifeq (,$(filter 0 1 2 3 4 5 6 7 8,$(APPLE_CLANG_MAJOR)))
        OPTLEVEL := g
      endif
    else ifeq (1,$(CLANG))
      # clang >= 4.0
      ifeq (,$(filter 0 1 2 3,$(CLANG_MAJOR)))
        OPTLEVEL := g
      endif
    else
      # GCC >= 4.8
      ifeq (,$(filter 0 1 2 3 4,$(GCC_MAJOR)))
        OPTLEVEL := g
      else ifeq (4,$(GCC_MAJOR))
        ifeq (,$(filter 0 1 2 3 4 5 6 7,$(GCC_MINOR)))
          OPTLEVEL := g
        endif
      endif
    endif

    LTO := 0
else
    OPTLEVEL := 2
    LTO := 1
endif

ifeq (0,$(CLANG))
    ifeq (0,$(GCC_PREREQ_4))
        override LTO := 0
    endif
    ifeq (4,$(GCC_MAJOR))
        ifeq ($(PLATFORM),WII)
            ifneq (,$(filter 0 1 2 3 4 5 6 7,$(GCC_MINOR)))
                override LTO := 0
            endif
        else
            ifneq (,$(filter 0 1 2 3 4 5,$(GCC_MINOR)))
                override LTO := 0
            endif
        endif
    endif
endif

########## End Toggles, Begin Construction ##########

##### Instantiate variables

COMMONFLAGS :=
COMPILERFLAGS := -funsigned-char -frounding-math

CSTD := -std=gnu11
CXXSTD := -std=gnu++14
ifneq (0,$(CLANG))
    CSTD := $(subst gnu,c,$(CSTD))
    CXXSTD := $(subst gnu,c,$(CXXSTD))
endif
CONLYFLAGS := $(CSTD)
CXXONLYFLAGS := $(CXXSTD) -fno-exceptions -fno-rtti

ASFLAGS := -s #-g

LINKERFLAGS :=
L_CXXONLYFLAGS :=

LIBS :=
GUI_LIBS :=
LIBDIRS :=

##### Mandatory platform parameters

ASFORMAT := elf$(BITS)
ifeq ($(PLATFORM),WINDOWS)
    LINKERFLAGS += -static -Wl,-subsystem,windows
    COMPILERFLAGS += -DUNDERSCORES
    ASFORMAT := win$(BITS)
    ASFLAGS += -DUNDERSCORES

    ifneq ($(RELEASE),0)
        ifeq ($(FORCEDEBUG),0)
            DYNAMICBASE := -Wl,--dynamicbase
            ifeq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
                DYNAMICBASE := $(DYNAMICBASE),--high-entropy-va
            endif
        endif
    endif
    LINKERFLAGS += -Wl,--enable-auto-import,--nxcompat $(DYNAMICBASE)
    ifneq ($(findstring x86_64,$(COMPILERTARGET)),x86_64)
        LINKERFLAGS += -Wl,--large-address-aware
    endif
else ifeq ($(PLATFORM),DARWIN)
    ifneq ($(ARCH),)
        ifneq ($(findstring -arch,$(ARCH)),-arch)
            override ARCH := -arch $(ARCH)
        endif
    endif
    COMMONFLAGS += $(ARCH)

    ifneq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
        LINKERFLAGS += -read_only_relocs suppress
    endif

    COMPILERFLAGS += -DUNDERSCORES
    ASFORMAT := macho
    ASFLAGS += -DUNDERSCORES

    ifeq ($(findstring x86_64,$(IMPLICIT_ARCH)),x86_64)
        ASFORMAT += 64
    endif
else ifeq ($(PLATFORM),WII)
    LIBOGC_INC := $(DEVKITPRO)/libogc/include
    LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii

    COMMONFLAGS += -mrvl -mcpu=750 -meabi -mhard-float
    LINKERFLAGS += -Wl,--gc-sections
    # -msdata=eabiexport
    COMPILERFLAGS += -DGEKKO -D__POWERPC__ -I$(LIBOGC_INC)
    LIBDIRS += -L$(LIBOGC_LIB)
else ifeq ($(PLATFORM),$(filter $(PLATFORM),DINGOO GCW))
    COMPILERFLAGS += -D__OPENDINGUX__
else ifeq ($(SUBPLATFORM),LINUX)
    # Locate .so files
    LINKERFLAGS += -Wl,-rpath,'$$ORIGIN' -Wl,-z,origin
endif
ASFLAGS += -f $(ASFORMAT)

COMPILERFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0

##### Optimizations

ifndef OPTOPT
    ifeq ($(findstring x86_64, $(IMPLICIT_ARCH)),x86_64)
        ifeq ($(findstring x86_64h, $(IMPLICIT_ARCH)),x86_64h)
            OPTOPT := -march=haswell -msse4.1 -msse4.2 -mpopcnt -mpclmul -mavx -mrdrnd -mf16c -mfsgsbase -mavx2 -maes -mfma -mbmi -mbmi2
            # -mcrc32 -mmovbe
        else
            OPTOPT := -march=core2
        endif
        OPTOPT += -mmmx -msse -msse2 -msse3 -mssse3 -mfpmath=sse
    endif
    ifeq ($(findstring i386, $(IMPLICIT_ARCH)),i386)
        ifeq ($(PLATFORM),DARWIN)
            OPTOPT := -march=nocona -mmmx -msse -msse2 -msse3
        else
            USE_SSE2 := 0
            ifneq (0,$(USE_SSE2))
                OPTOPT := -march=pentium-m
            else
                OPTOPT := -march=pentium3
            endif
            ifneq (0,$(GCC_PREREQ_4))
                OPTOPT += -mtune=generic
                # -mstackrealign
            endif
            OPTOPT += -mmmx -msse -mfpmath=sse
            ifneq (0,$(USE_SSE2))
                OPTOPT += -msse2
            endif
        endif
    endif
    ifeq ($(PLATFORM),WII)
        OPTOPT := -mtune=750
    endif
endif

ifeq ($(PACKAGE_REPOSITORY),0)
    COMMONFLAGS += -O$(OPTLEVEL) $(OPTOPT)
endif

ifneq (0,$(LTO))
    COMPILERFLAGS += -DUSING_LTO
    ifeq (1,$(LTO))
        ifeq (0,$(CLANG))
            COMMONFLAGS += -flto
        else
            COMMONFLAGS += -flto=thin
        endif
    else
        COMMONFLAGS += -flto=$(LTO)
    endif
endif

ifeq (1,$(LLD))
    COMMONFLAGS += -fuse-ld=lld
endif

##### Debugging

ifneq ($(RELEASE)$(FORCEDEBUG),10)
    ifeq ($(PACKAGE_REPOSITORY),0)
        COMMONFLAGS += -g$(DBGLEVEL)
        ifeq (0,$(CLANG))
            ifneq ($(PLATFORM),WII)
                COMMONFLAGS += -fno-omit-frame-pointer
            endif
        endif
    endif
    ifeq ($(SUBPLATFORM),LINUX)
        # This option is needed to allow obtaining backtraces from within a program.
        LIBS += -rdynamic
    endif
endif

ifneq ($(ALLOCACHE_AS_MALLOC),0)
    COMPILERFLAGS += -DDEBUG_ALLOCACHE_AS_MALLOC
endif

# See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
# and https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
# for a list of possible ASan and UBsan options.

ASAN_FLAGS := -fsanitize=address -fsanitize=bounds,enum,float-cast-overflow
ASAN_FLAGS := $(ASAN_FLAGS),signed-integer-overflow,unsigned-integer-overflow
ASAN_FLAGS := $(ASAN_FLAGS),undefined,return,null,pointer-overflow,float-divide-by-zero
#ASAN_FLAGS := $(ASAN_FLAGS) -fsanitize-undefined-trap-on-error

ifeq (0,$(FORCEDEBUG))
    COMPILERFLAGS += -DNDEBUG
else
    COMPILERFLAGS += -DDEBUGGINGAIDS=$(FORCEDEBUG)

    ifeq (2,$(FORCEDEBUG))
        ifneq (0,$(CLANG))
            COMMONFLAGS += $(ASAN_FLAGS)
        else ifneq (,$(filter 1 2 3 4 5 6,$(GCC_MAJOR)))
            ifneq (,$(filter 0 1,$(GCC_MINOR)))
                COMMONFLAGS += $(ASAN_FLAGS)
            endif
        endif
    endif
endif

ifneq (0,$(KRANDDEBUG))
    COMPILERFLAGS += -DKRANDDEBUG=1
endif

ifneq (0,$(PROFILER))
    ifneq ($(PLATFORM),DARWIN)
        LIBS += -lprofiler
    endif
    COMMONFLAGS += -pg
endif

##### -f stuff

ifneq (0,$(GCC_PREREQ_4))
    F_NO_STACK_PROTECTOR := -fno-stack-protector
    ifeq (0,$(CLANG))
        F_JUMP_TABLES := -fjump-tables
    endif
endif

ifeq ($(PLATFORM),DARWIN)
    ifeq (1,$(DARWIN9))
        F_JUMP_TABLES :=
    endif
    ifeq ($(findstring ppc,$(IMPLICIT_ARCH))$(findstring i386,$(IMPLICIT_ARCH)),)
        F_NO_STACK_PROTECTOR :=
    endif
endif

ifeq (0,$(RELEASE))
    F_NO_STACK_PROTECTOR :=
else
    ifeq (0,$(CLANG))
        COMMONFLAGS += -funswitch-loops
    endif

    ifeq (0,$(FORCEDEBUG))
        COMMONFLAGS += -fomit-frame-pointer
    endif
endif

ifneq (0,$(KRANDDEBUG))
    COMMONFLAGS += -fno-inline -fno-inline-functions -fno-inline-functions-called-once
endif

COMMONFLAGS += -fno-strict-aliasing -fno-threadsafe-statics $(F_JUMP_TABLES) $(F_NO_STACK_PROTECTOR)

##### Warnings

W_STRICT_OVERFLOW := -Wno-strict-overflow

ifeq ($(PLATFORM),DARWIN)
    ifneq (0,$(DARWIN9))
        W_STRICT_OVERFLOW :=
    endif
endif

W_UNINITIALIZED := -Wuninitialized
W_GCC_4_1 := -Wno-attributes
W_GCC_4_2 := $(W_STRICT_OVERFLOW)
W_GCC_4_4 := -Wno-unused-result
W_GCC_4_5 := -Wlogical-op -Wcast-qual
W_GCC_6 := -Wduplicated-cond -Wnull-dereference
W_GCC_7 := -Wduplicated-branches
W_GCC_8 := -Warray-bounds=2
W_GCC_9 := -Wmultistatement-macros
W_CLANG := -Wno-unused-value -Wno-parentheses -Wno-unknown-warning-option -Wno-unused-function

ifeq (0,$(CLANG))
    W_CLANG :=

    ifneq (,$(filter 4 5 6 7 8,$(GCC_MAJOR)))
        W_GCC_9 :=
        ifneq (,$(filter 4 5 6 7,$(GCC_MAJOR)))
            W_GCC_8 :=
            ifneq (,$(filter 4 5 6,$(GCC_MAJOR)))
                W_GCC_7 :=
                ifneq (,$(filter 4 5,$(GCC_MAJOR)))
                    W_GCC_6 :=
                endif
            endif
        endif
    endif

    ifeq (0,$(GCC_PREREQ_4))
        W_GCC_9 :=
        W_GCC_8 :=
        W_GCC_7 :=
        W_GCC_6 :=
        W_GCC_4_5 :=
        W_GCC_4_4 :=
        ifeq (0,$(OPTLEVEL))
            W_UNINITIALIZED :=
        endif
        W_GCC_4_2 :=
        W_GCC_4_1 :=
    endif

    ifeq (4,$(GCC_MAJOR))
        ifneq (,$(filter 0 1 2 3 4,$(GCC_MINOR)))
            W_GCC_4_5 :=
            ifneq (,$(filter 0 1 2 3,$(GCC_MINOR)))
                W_GCC_4_4 :=
                ifeq (0,$(OPTLEVEL))
                    W_UNINITIALIZED :=
                endif
                ifneq (,$(filter 0 1,$(GCC_MINOR)))
                    W_GCC_4_2 :=
                    ifeq (0,$(GCC_MINOR))
                        W_GCC_4_1 :=
                    endif
                endif
            endif
        endif
    endif
endif

CONLYWARNS := -Wimplicit -Werror-implicit-function-declaration

CWARNS := -W -Wall \
    -Wextra \
    -Wpointer-arith \
    -Wno-char-subscripts \
    -Wno-missing-braces \
    -Wwrite-strings \
    $(W_UNINITIALIZED) \
    $(W_GCC_4_1) \
    $(W_GCC_4_2) \
    $(W_GCC_4_4) \
    $(W_GCC_4_5) \
    $(W_GCC_6) \
    $(W_GCC_7) \
    $(W_GCC_8) \
    $(W_GCC_9) \
    $(W_CLANG) \
    #-Wstrict-prototypes \
    #-Waggregate-return \
    #-Wcast-align \
    #-Waddress

##### Features

ifneq (,$(APPNAME))
    COMPILERFLAGS += "-DAPPNAME=\"$(APPNAME)\""
endif
ifneq (,$(APPBASENAME))
    COMPILERFLAGS += "-DAPPBASENAME=\"$(APPBASENAME)\""
endif

ifneq (0,$(NOASM))
    COMPILERFLAGS += -DNOASM
endif
ifneq (0,$(MEMMAP))
    ifeq ($(PLATFORM),DARWIN)
        LINKERFLAGS += -Wl,-map -Wl,$@.memmap
    else
        LINKERFLAGS += -Wl,-Map=$@.memmap
    endif
endif

COMPILERFLAGS += -DRENDERTYPE$(RENDERTYPE)=1

ifeq (0,$(NETCODE))
    COMPILERFLAGS += -DNETCODE_DISABLE
endif
ifneq (0,$(STARTUP_WINDOW))
    COMPILERFLAGS += -DSTARTUP_WINDOW
endif
ifneq (0,$(RETAIL_MENU))
    COMPILERFLAGS += -DEDUKE32_RETAIL_MENU
endif
ifneq (0,$(STANDALONE))
    COMPILERFLAGS += -DEDUKE32_STANDALONE
endif
ifneq (0,$(USE_OPENGL))
    COMPILERFLAGS += -DUSE_OPENGL
endif
ifneq (0,$(POLYMER))
    COMPILERFLAGS += -DPOLYMER
endif
ifneq (0,$(NOONE_EXTENSIONS))
    COMPILERFLAGS += -DNOONE_EXTENSIONS
endif

##### External library paths

ifeq ($(PLATFORM),WINDOWS)
    COMPILERFLAGS += -Iplatform/Windows/include -Iplatform/Windows/include/SDL2
    LIBDIRS += -Lplatform/Windows/lib/$(BITS)
else ifeq ($(PLATFORM),DARWIN)
    ifneq ($(shell port --version &>/dev/null; echo $$?),127)
        LIBDIRS += -L/opt/local/lib
        COMPILERFLAGS += -I/opt/local/include
    endif
    ifneq ($(shell brew --version &>/dev/null; echo $$?),127)
        LIBDIRS += -L/usr/local/lib
        COMPILERFLAGS += -I/usr/local/include
    endif
    ifneq ($(shell fink --version &>/dev/null; echo $$?),127)
        LIBDIRS += -L/sw/lib
        COMPILERFLAGS += -I/sw/include
    endif
else ifeq ($(PLATFORM),BSD)
    COMPILERFLAGS += -I/usr/local/include
else ifeq ($(PLATFORM),WII)
    COMPILERFLAGS += -I$(PORTLIBS)/include -Iplatform/Wii/include
    LIBDIRS += -L$(PORTLIBS)/lib -Lplatform/Wii/lib
endif

##### External libraries

ifneq (0,$(USE_LIBVPX))
    COMPILERFLAGS += -DUSE_LIBVPX
    LIBS += -lvpx
endif

ifneq (0,$(HAVE_VORBIS))
    COMPILERFLAGS += -DHAVE_VORBIS
endif
ifneq (0,$(HAVE_FLAC))
    COMPILERFLAGS += -DHAVE_FLAC
endif
ifneq (0,$(HAVE_XMP))
    COMPILERFLAGS += -DHAVE_XMP
endif

ifeq ($(RENDERTYPE),SDL)
    ifeq ($(SDL_TARGET),2)
        SDLCONFIG := sdl2-config
        SDLNAME := SDL2
    else ifeq ($(SDL_TARGET),1)
        SDLCONFIG := sdl-config
        SDLNAME := SDL
        ifeq (0,$(RELEASE))
            COMPILERFLAGS += -DNOSDLPARACHUTE
        endif
    endif

    ifeq ($(PLATFORM), WINDOWS)
        SDLCONFIG :=
    endif

    ifeq ($(PLATFORM),WII)
        SDLCONFIG :=
    endif

    ifneq ($(strip $(SDLCONFIG)),)
        ifeq ($(strip $(shell $(SDLCONFIG) --version $(DONT_PRINT_STDERR))),)
            override SDLCONFIG :=
        endif
    endif

    COMPILERFLAGS += -DSDL_TARGET=$(SDL_TARGET)

    SDL_FRAMEWORK := 0
    ifneq ($(SDL_FRAMEWORK),0)
        ifeq ($(PLATFORM),DARWIN)
            APPLE_FRAMEWORKS := /Library/Frameworks
            LIBDIRS += -F$(APPLE_FRAMEWORKS)
            COMPILERFLAGS += -I$(APPLE_FRAMEWORKS)/$(SDLNAME).framework/Headers
            LIBS += -Wl,-framework,$(SDLNAME) -Wl,-rpath -Wl,"@loader_path/../Frameworks"
        endif
    else
        ifneq ($(SDLCONFIG),)
            ifneq ($(SDL_STATIC),0)
                override SDLCONFIG_LIBS := -Wl,-Bstatic -l$(SDLNAME) -Wl,-Bdynamic $(strip $(subst -l$(SDLNAME),,$(shell $(SDLCONFIG) --static-libs)))
                # for some reason SteamRT has a GCC with --enable-default-pie but its SDL2 has it disabled. WTF?
                LINKERFLAGS += -no-pie
            endif

            SDLCONFIG_CFLAGS := $(strip $(subst -Dmain=SDL_main,,$(shell $(SDLCONFIG) --cflags)))
            SDLCONFIG_LIBS := $(strip $(subst -mwindows,,$(shell $(SDLCONFIG) --libs)))

            COMPILERFLAGS += $(SDLCONFIG_CFLAGS)
            LIBS += $(SDLCONFIG_LIBS)
        else
            ifeq ($(SDL_TARGET),1)
                COMPILERFLAGS += -D_GNU_SOURCE=1
            endif
            COMPILERFLAGS += -D_REENTRANT -DSDL_USEFOLDER
            LIBS += -l$(SDLNAME)
        endif
    endif
endif

ifneq (0,$(HAVE_GTK2))
    ifneq (No,$(shell $(PKG_CONFIG) --exists gtk+-2.0 || echo No))
        COMPILERFLAGS += -DHAVE_GTK2 $(shell $(PKG_CONFIG) --cflags gtk+-2.0)
    else
        override HAVE_GTK2 := 0
    endif
endif

##### System libraries

ifeq ($(PLATFORM),WINDOWS)
    ifneq (0,$(GCC_PREREQ_4))
        L_SSP := -lssp
    endif
    ifeq ($(RENDERTYPE),WIN)
        LIBS += -ldxguid
    else ifeq ($(SDL_TARGET),1)
        LIBS += -ldxguid
    else
        LIBS += -ldxguid_sdl
    endif
    LIBS += -lmingwex -lgdi32 -lcomctl32 -lwinmm $(L_SSP) -lwsock32 -lws2_32 -lshlwapi -luuid -lpsapi -ldinput -limm32 -lversion -lsetupapi -lole32 -loleaut32
    # -lshfolder
else ifeq ($(PLATFORM),WII)
    LIBS += -laesnd_tueidj -lfat -lwiiuse -lbte -lwiikeyboard -logc
else ifeq ($(SUBPLATFORM),LINUX)
    LIBS += -lrt -latomic
endif

ifeq (,$(filter $(PLATFORM),WINDOWS WII))
    ifneq ($(PLATFORM),BSD)
        LIBS += -ldl
    endif
    ifneq ($(PLATFORM),DARWIN)
        LIBS += -pthread
    endif
endif

LIBS += -lm

##### Detect version control revision, if applicable

VC_REV :=
VC_HASH :=
VC_BRANCH :=

-include EDUKE32_REVISION.mak
ifneq (,$(wildcard .git))
    ifeq (,$(VC_REV))
        VC_REV := $(shell git rev-list --count HEAD 2>&1)
    endif
    ifeq (,$(VC_HASH))
        VC_HASH := $(shell git rev-parse --short=9 HEAD 2>&1)
    endif
    ifeq (,$(VC_BRANCH))
        VC_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>&1)
        ifneq (master,$(VC_BRANCH))
            VC_REV := $(VC_REV)[$(VC_BRANCH)]
        endif
    endif
    ifneq (,$(VC_REV)$(VC_HASH)$(VC_REV_CUSTOM))
        REVFLAG := -DREV="r$(VC_REV)-$(VC_HASH)$(VC_REV_CUSTOM)"
    endif
endif

##### Allow standard environment variables to take precedence, to help package maintainers.

ifneq (,$(CFLAGS))
    COMMONFLAGS += $(CFLAGS)
endif
ifneq (,$(CXXFLAGS))
    CXXONLYFLAGS += $(CXXFLAGS)
endif
ifneq (,$(LDFLAGS))
    LINKERFLAGS += $(LDFLAGS)
endif

##### Final assembly of commands

COMPILER_C=$(CC) $(CONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(CONLYWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
COMPILER_CXX=$(CXX) $(CXXONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
COMPILER_OBJC=$(COBJC) $(CONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(CONLYWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
COMPILER_OBJCXX=$(COBJCXX) $(CXXONLYFLAGS) $(COMMONFLAGS) $(CWARNS) $(COMPILERFLAGS) $(CUSTOMOPT)
LINKER=$(L_CXX) $(CXXONLYFLAGS) $(L_CXXONLYFLAGS) $(COMMONFLAGS) $(LINKERFLAGS) $(CUSTOMOPT)
ifneq ($(CPLUSPLUS),0)
    COMPILER_C=$(COMPILER_CXX)
    COMPILER_OBJC=$(COMPILER_OBJCXX)
endif

##### Pretty-printing

ifeq ($(PRETTY_OUTPUT),1)
RECIPE_IF = if
BUILD_STARTED = printf "\033[K\033[1;36mBuilding: \033[0;36m$(MAKE) $(MAKECMDGOALS) -$(MAKEFLAGS)\033[0m\n"
COMPILE_STATUS = printf "\033[K\033[0mBuilding object \033[1m$@\033[0m...\033[0m\r"
COMPILE_OK = printf "\033[K\033[0;32mBuilt object \033[1;32m$@\033[0;32m \033[0m\n"
COMPILE_FAILED = printf "\033[K\033[0;31mFailed building \033[1;31m$@\033[0;31m from\033[0m \033[1;31m$<\033[0;31m!\033[0m\n"; exit 1
RECIPE_RESULT_COMPILE = ; then $(COMPILE_OK); else $(COMPILE_FAILED); fi
ONESTEP_STATUS = printf "\033[K\033[0mBuilding \033[1m$@\033[0m...\033[0m\r"
ONESTEP_OK = printf "\033[K\033[0;32mBuilt \033[1;32m$@\033[0;32m \033[0m\n"
ONESTEP_FAILED = printf "\033[K\033[0;31mFailed building \033[1;31m$@\033[0;31m!\033[0m\n"; exit 1
RECIPE_RESULT_ONESTEP = ; then $(ONESTEP_OK); else $(ONESTEP_FAILED); fi
ARCHIVE_STATUS = printf "\033[K\033[0mCreating library archive \033[1m$@\033[0m...\033[0m\r"
ARCHIVE_OK = printf "\033[K\033[0;32mCreated library archive \033[1;32m$@\033[0;32m \033[0m\n"
ARCHIVE_FAILED = printf "\033[K\033[0;31mFailed creating library archive \033[1;31m$@\033[0;31m from\033[0m \033[1;31m$<\033[0;31m!\033[0m\n"; exit 1
RECIPE_RESULT_ARCHIVE = ; then $(ARCHIVE_OK); else $(ARCHIVE_FAILED); fi
LINK_STATUS = printf "\033[K\033[0;0mLinking \033[1m$@\033[0;0m...\033[0m\r"
LINK_OK = printf "\033[K\033[0;32mLinked \033[1;32m$@\033[0;32m \033[0m\n"
LINK_FAILED = printf "\033[K\033[0;31mFailed linking \033[1;31m$@\033[0;31m!\nIf the build options, environment, or system packages have changed, run '\033[1;31mmake clean\033[0;31m' and try again.\033[0m\n"; exit 1
RECIPE_RESULT_LINK = ; then $(LINK_OK); else $(LINK_FAILED); fi
else
RECIPE_IF =
BUILD_STARTED =
COMPILE_STATUS =
COMPILE_OK = true
COMPILE_FAILED = false; exit 1
RECIPE_RESULT_COMPILE =
ONESTEP_STATUS =
ONESTEP_OK = true
ONESTEP_FAILED = false; exit 1
RECIPE_RESULT_ONESTEP =
ARCHIVE_STATUS =
ARCHIVE_OK = true
ARCHIVE_FAILED = false; exit 1
RECIPE_RESULT_ARCHIVE =
LINK_STATUS =
LINK_OK = true
LINK_FAILED = false; exit 1
RECIPE_RESULT_LINK =
endif