twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

type.go (3649B)


      1 // Copyright 2020 The Ebiten Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package shaderir
     16 
     17 import (
     18 	"fmt"
     19 	"strings"
     20 )
     21 
     22 type Type struct {
     23 	Main   BasicType
     24 	Sub    []Type
     25 	Length int
     26 }
     27 
     28 func (t *Type) Equal(rhs *Type) bool {
     29 	if t.Main != rhs.Main {
     30 		return false
     31 	}
     32 	if t.Length != rhs.Length {
     33 		return false
     34 	}
     35 	if len(t.Sub) != len(rhs.Sub) {
     36 		return false
     37 	}
     38 	for i, s := range t.Sub {
     39 		if !s.Equal(&rhs.Sub[i]) {
     40 			return false
     41 		}
     42 	}
     43 	return true
     44 }
     45 
     46 func (t *Type) String() string {
     47 	switch t.Main {
     48 	case None:
     49 		return "none"
     50 	case Bool:
     51 		return "bool"
     52 	case Int:
     53 		return "int"
     54 	case Float:
     55 		return "float"
     56 	case Vec2:
     57 		return "vec2"
     58 	case Vec3:
     59 		return "vec3"
     60 	case Vec4:
     61 		return "vec4"
     62 	case Mat2:
     63 		return "mat2"
     64 	case Mat3:
     65 		return "mat3"
     66 	case Mat4:
     67 		return "mat4"
     68 	case Array:
     69 		return fmt.Sprintf("%s[%d]", t.Sub[0].String(), t.Length)
     70 	case Struct:
     71 		str := "struct{"
     72 		sub := make([]string, 0, len(t.Sub))
     73 		for _, st := range t.Sub {
     74 			sub = append(sub, st.String())
     75 		}
     76 		str += strings.Join(sub, ",")
     77 		str += "}"
     78 		return str
     79 	default:
     80 		return fmt.Sprintf("?(unknown type: %d)", t)
     81 	}
     82 }
     83 
     84 func (t *Type) FloatNum() int {
     85 	switch t.Main {
     86 	case Float:
     87 		return 1
     88 	case Vec2:
     89 		return 2
     90 	case Vec3:
     91 		return 3
     92 	case Vec4:
     93 		return 4
     94 	case Mat2:
     95 		return 4
     96 	case Mat3:
     97 		return 9
     98 	case Mat4:
     99 		return 16
    100 	case Array:
    101 		return t.Length * t.Sub[0].FloatNum()
    102 	default: // TODO: Parse a struct correctly
    103 		return -1
    104 	}
    105 }
    106 
    107 type BasicType int
    108 
    109 const (
    110 	None BasicType = iota
    111 	Bool
    112 	Int
    113 	Float
    114 	Vec2
    115 	Vec3
    116 	Vec4
    117 	Mat2
    118 	Mat3
    119 	Mat4
    120 	Array
    121 	Struct
    122 )
    123 
    124 func descendantLocalVars(block, target *Block) ([]Type, bool) {
    125 	if block == target {
    126 		return block.LocalVars, true
    127 	}
    128 
    129 	var ts []Type
    130 	for _, s := range block.Stmts {
    131 		for _, b := range s.Blocks {
    132 			if ts2, found := descendantLocalVars(b, target); found {
    133 				n := b.LocalVarIndexOffset - block.LocalVarIndexOffset
    134 				ts = append(ts, block.LocalVars[:n]...)
    135 				ts = append(ts, ts2...)
    136 				return ts, true
    137 			}
    138 		}
    139 	}
    140 	return nil, false
    141 }
    142 
    143 func localVariableType(p *Program, topBlock, block *Block, absidx int) Type {
    144 	// TODO: Rename this function (truly-local variable?)
    145 	var ts []Type
    146 	for _, f := range p.Funcs {
    147 		if f.Block == topBlock {
    148 			ts = append(f.InParams, f.OutParams...)
    149 			break
    150 		}
    151 	}
    152 
    153 	ts2, _ := descendantLocalVars(topBlock, block)
    154 	ts = append(ts, ts2...)
    155 	return ts[absidx]
    156 }
    157 
    158 func (p *Program) LocalVariableType(topBlock, block *Block, idx int) Type {
    159 	switch topBlock {
    160 	case p.VertexFunc.Block:
    161 		na := len(p.Attributes)
    162 		nv := len(p.Varyings)
    163 		switch {
    164 		case idx < na:
    165 			return p.Attributes[idx]
    166 		case idx == na:
    167 			return Type{Main: Vec4}
    168 		case idx < na+nv+1:
    169 			return p.Varyings[idx-na-1]
    170 		default:
    171 			return localVariableType(p, topBlock, block, idx-(na+nv+1))
    172 		}
    173 	case p.FragmentFunc.Block:
    174 		nv := len(p.Varyings)
    175 		switch {
    176 		case idx == 0:
    177 			return Type{Main: Vec4}
    178 		case idx < nv+1:
    179 			return p.Varyings[idx-1]
    180 		case idx == nv+1:
    181 			return Type{Main: Vec4}
    182 		default:
    183 			return localVariableType(p, topBlock, block, idx-(nv+2))
    184 		}
    185 	default:
    186 		return localVariableType(p, topBlock, block, idx)
    187 	}
    188 }