Skip to content

Commit

Permalink
fixing file cases #2
Browse files Browse the repository at this point in the history
  • Loading branch information
skyrim committed Aug 9, 2018
1 parent 3af285b commit 4b9ec70
Show file tree
Hide file tree
Showing 24 changed files with 5,668 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/Array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Array {
static indexOf<T>(a: T[], what: T): T[] {
let result: T[] = []

for (let i = 0; i < a.length; ++i) {
if (a[i] === what) {
result.push(a[i])
}
}

return result
}

static find<T>(a: T[], f: (what: T) => boolean): T | undefined {
for (let i = 0; i < a.length; ++i) {
if (f(a[i])) {
return a[i]
}
}

return undefined
}

static filter<T>(a: T[], f: (what: T) => boolean): T[] {
let result: T[] = []

for (let i = 0; i < a.length; ++i) {
if (f(a[i])) {
result.push(a[i])
}
}

return result
}
}

export { Array }
190 changes: 190 additions & 0 deletions src/BitReader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
class BitView {
static scratch = new DataView(new ArrayBuffer(8))

private view: Uint8Array

constructor(buffer: ArrayBuffer) {
this.view = new Uint8Array(buffer, 0, buffer.byteLength)
}

getBits(offset: number, bits: number, signed = false) {
let available = this.view.length * 8 - offset

if (bits > available) {
throw new Error('Bits out of bounds')
}

let value = 0
for (let i = 0; i < bits; ) {
let remaining = bits - i
let bitOffset = offset & 7
let currentByte = this.view[offset >> 3]

// the max number of bits we can read from the current byte
let read = Math.min(remaining, 8 - bitOffset)

// create a mask with the correct bit width
let mask = (1 << read) - 1
// shift bits we want to the start of the byte and mask of the rest
let readBits = (currentByte >> bitOffset) & mask
value |= readBits << i

offset += read
i += read
}

if (signed) {
// If we're not working with a full 32 bits, check the
// imaginary MSB for this bit count and convert to a
// valid 32-bit signed value if set.
if (bits !== 32 && value & (1 << (bits - 1))) {
value |= -1 ^ ((1 << bits) - 1)
}

return value
}

return value >>> 0
}

getInt8(offset: number) {
return this.getBits(offset, 8, true)
}

getUint8(offset: number) {
return this.getBits(offset, 8, false)
}

getInt16(offset: number) {
return this.getBits(offset, 16, true)
}

getUint16(offset: number) {
return this.getBits(offset, 16, false)
}

getInt32(offset: number) {
return this.getBits(offset, 32, true)
}

getUint32(offset: number) {
return this.getBits(offset, 32, false)
}

getFloat32(offset: number) {
BitView.scratch.setUint32(0, this.getUint32(offset))
return BitView.scratch.getFloat32(0)
}

getFloat64(offset: number) {
BitView.scratch.setUint32(0, this.getUint32(offset))
// DataView offset is in bytes.
BitView.scratch.setUint32(4, this.getUint32(offset + 32))
return BitView.scratch.getFloat64(0)
}
}

class BitStream {
private view: BitView
index: number

constructor(source: ArrayBuffer) {
this.view = new BitView(source)
this.index = 0
}

readBits(bits: number, signed = false) {
let val = this.view.getBits(this.index, bits, signed)
this.index += bits
return val
}

readInt8() {
let val = this.view.getInt8(this.index)
this.index += 8
return val
}

readUint8() {
let val = this.view.getUint8(this.index)
this.index += 8
return val
}

readInt16() {
let val = this.view.getInt16(this.index)
this.index += 16
return val
}

readUint16() {
let val = this.view.getUint16(this.index)
this.index += 16
return val
}

readInt32() {
let val = this.view.getInt32(this.index)
this.index += 32
return val
}

readUint32() {
let val = this.view.getUint32(this.index)
this.index += 32
return val
}

readFloat32() {
let val = this.view.getFloat32(this.index)
this.index += 32
return val
}

readFloat64() {
let val = this.view.getFloat64(this.index)
this.index += 64
return val
}

readString(bytes = 0, utf8 = false) {
let i = 0
let chars = []
let append = true

// Read while we still have space available, or until we've
// hit the fixed byte length passed in.
while (!bytes || (bytes && i < bytes)) {
let c = this.readUint8()

// Stop appending chars once we hit 0x00
if (c === 0x00) {
append = false

// If we don't have a fixed length to read, break out now.
if (!bytes) {
break
}
}
if (append) {
chars.push(c)
}

i++
}

let string = String.fromCharCode.apply(null, chars)
if (utf8) {
try {
// https://stackoverflow.com/a/17192845
return decodeURIComponent(string)
} catch (e) {
return string
}
} else {
return string
}
}
}

export { BitView, BitStream }
159 changes: 159 additions & 0 deletions src/Entities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import * as THREE from 'three'

const isInvisible = (entity: any) => {
const INVISIBLE_ENTITIES = [
'target_cdaudio',
'trigger_auto',
'trigger_autosave',
'trigger_camera',
'trigger_cdaudio',
'trigger_changelevel',
'trigger_changetarget',
'trigger_counter',
'trigger_endsection',
'trigger_gravity',
'trigger_hurt',
'trigger_monsterjump',
'trigger_multiple',
'trigger_once',
'trigger_push',
'trigger_relay',
'trigger_teleport',
'trigger_transition',
'func_bomb_target',
'func_buyzone',
'func_ladder'
]

for (let i = 0; i < INVISIBLE_ENTITIES.length; ++i) {
if (INVISIBLE_ENTITIES[i] === entity.classname) {
return true
}
}

return false
}

class Entities {
list: any[]

constructor() {
this.list = []
}

clear() {
this.list.length = 0
}

initialize(entities: any[], resources: any) {
this.clear()

entities.forEach(e => {
let t = {
meta: e,
model: null
}

switch (e.classname) {
case 'worldspawn': {
let model = resources.models[0]
let materials = model.material
materials.forEach((m: any, idx: number) => {
if (m.map.name.charAt(0) === '{') {
let data = Uint8Array.from(m.map.image.data)
for (let i = 3; i < data.length; i += 4) {
data[i] = 255
}

let w = m.map.image.width
let h = m.map.image.height

let newTexture = new THREE.DataTexture(
data,
w,
h,
THREE.RGBAFormat,
THREE.UnsignedByteType,
THREE.Texture.DEFAULT_MAPPING,
THREE.RepeatWrapping,
THREE.RepeatWrapping,
THREE.LinearFilter,
THREE.LinearMipMapLinearFilter
)

newTexture.name = m.map.name
newTexture.premultiplyAlpha = true
newTexture.anisotropy = m.map.anisotropy
newTexture.generateMipmaps = true
newTexture.repeat.y = -1
newTexture.needsUpdate = true

let newMaterial = new THREE.MeshLambertMaterial({
map: newTexture,
transparent: false,
visible: m.visible
})

model.material[idx] = newMaterial
}
})
t.model = model

break
}

default: {
if (typeof e.model === 'number' && !isInvisible(e)) {
let model = resources.models[e.model].clone()
model.rotation.order = 'ZXY'
if (e.origin) {
model.position.x = e.origin[0]
model.position.y = e.origin[1]
model.position.z = e.origin[2]
if (e.angles) {
model.rotation.x = (e.angles[0] * Math.PI) / 180
model.rotation.y = (e.angles[2] * Math.PI) / 180
model.rotation.z = (e.angles[1] * Math.PI) / 180
}
}

if (e.rendermode === 0) {
e.renderamt = 255
}

if (e.rendermode !== 4 && e.renderamt < 255) {
let materials = model.material
materials.forEach((m: any) => {
model.renderOrder = 1
m.depthWrite = false
m.alphaTest = 0.05
m.opacity = e.renderamt / 255
})
}

if (e.rendermode === 5) {
let materials = model.material
materials.forEach((m: any) => {
model.renderOrder = 1
m.depthWrite = false
m.blending = THREE.AdditiveBlending
})
}

t.model = model
} else if (
typeof e.model === 'string' &&
e.model.indexOf('.spr') > -1
) {
console.log(e.model)
}
break
}
}

this.list.push(t)
})
}
}

export { Entities }

0 comments on commit 4b9ec70

Please sign in to comment.